Commit e304e483 authored by bashi@chromium.org's avatar bashi@chromium.org

Named getter of HTMLAllCollection etc should be nullable

According to the spec[1,2,3], named getter of HTMLAllCollection, HTMLFormControlsCollection and HTMLOptionsCollection should be nullable.

This CL also adds layout tests for nullable arguments.

[1] https://html.spec.whatwg.org/multipage/infrastructure.html#the-htmlallcollection-interface
[2] https://html.spec.whatwg.org/multipage/infrastructure.html#the-htmlformcontrolscollection-interface
[3] https://html.spec.whatwg.org/multipage/infrastructure.html#htmlallcollection

BUG=430337

Review URL: https://codereview.chromium.org/692993003

git-svn-id: svn://svn.chromium.org/blink/trunk@185108 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent 76f7cf3a
...@@ -12,6 +12,7 @@ PASS document.all['foo'].length is 2 ...@@ -12,6 +12,7 @@ PASS document.all['foo'].length is 2
PASS document.all['foo'][0] is elements[0] PASS document.all['foo'][0] is elements[0]
PASS document.all['foo'][1] is elements[1] PASS document.all['foo'][1] is elements[1]
PASS elements[0].parentNode.removeChild(elements[0]); document.all['foo'] is elements[1] PASS elements[0].parentNode.removeChild(elements[0]); document.all['foo'] is elements[1]
PASS document.all['no-such-element'] is undefined.
form.elements form.elements
PASS form.elements instanceof HTMLFormControlsCollection is true PASS form.elements instanceof HTMLFormControlsCollection is true
...@@ -27,6 +28,7 @@ PASS form.elements['foo'][0] is elements[0] ...@@ -27,6 +28,7 @@ PASS form.elements['foo'][0] is elements[0]
PASS form.elements['foo'][1] is elements[1] PASS form.elements['foo'][1] is elements[1]
PASS form.removeChild(elements[0]); form.elements['foo'] is elements[1] PASS form.removeChild(elements[0]); form.elements['foo'] is elements[1]
PASS removeTestElements(); form.elements.length is 0 PASS removeTestElements(); form.elements.length is 0
PASS form.elements['no-such-element'] is undefined.
select.options select.options
PASS form.appendChild(createElementWithId('select', 'bar')); form.elements.length is 1 PASS form.appendChild(createElementWithId('select', 'bar')); form.elements.length is 1
...@@ -44,6 +46,7 @@ PASS select.options['foo'][1] is elements[1] ...@@ -44,6 +46,7 @@ PASS select.options['foo'][1] is elements[1]
PASS select.removeChild(elements[0]); select.options['foo'] is elements[1] PASS select.removeChild(elements[0]); select.options['foo'] is elements[1]
PASS select.innerHTML = ''; select.options.length is 0 PASS select.innerHTML = ''; select.options.length is 0
PASS removeTestElements(); form.elements.length is 0 PASS removeTestElements(); form.elements.length is 0
PASS select.options['no-such-element'] is undefined.
document.images document.images
PASS document.images.length is 0 PASS document.images.length is 0
......
...@@ -37,6 +37,7 @@ shouldBe("document.all['foo'].length", "2"); ...@@ -37,6 +37,7 @@ shouldBe("document.all['foo'].length", "2");
shouldBe("document.all['foo'][0]", "elements[0]"); shouldBe("document.all['foo'][0]", "elements[0]");
shouldBe("document.all['foo'][1]", "elements[1]"); shouldBe("document.all['foo'][1]", "elements[1]");
shouldBe("elements[0].parentNode.removeChild(elements[0]); document.all['foo']", 'elements[1]'); shouldBe("elements[0].parentNode.removeChild(elements[0]); document.all['foo']", 'elements[1]');
shouldBeUndefined("document.all['no-such-element']");
debug(""); debug("");
var form = document.querySelector('form'); var form = document.querySelector('form');
...@@ -54,6 +55,7 @@ shouldBe("form.elements['foo'][0]", "elements[0]"); ...@@ -54,6 +55,7 @@ shouldBe("form.elements['foo'][0]", "elements[0]");
shouldBe("form.elements['foo'][1]", "elements[1]"); shouldBe("form.elements['foo'][1]", "elements[1]");
shouldBe("form.removeChild(elements[0]); form.elements['foo']", "elements[1]"); shouldBe("form.removeChild(elements[0]); form.elements['foo']", "elements[1]");
shouldBe("removeTestElements(); form.elements.length", "0"); shouldBe("removeTestElements(); form.elements.length", "0");
shouldBeUndefined("form.elements['no-such-element']");
debug(""); debug("");
debug("select.options"); debug("select.options");
...@@ -72,6 +74,7 @@ shouldBe("select.options['foo'][1]", "elements[1]"); ...@@ -72,6 +74,7 @@ shouldBe("select.options['foo'][1]", "elements[1]");
shouldBe("select.removeChild(elements[0]); select.options['foo']", "elements[1]"); shouldBe("select.removeChild(elements[0]); select.options['foo']", "elements[1]");
shouldBe("select.innerHTML = ''; select.options.length", "0"); shouldBe("select.innerHTML = ''; select.options.length", "0");
shouldBe("removeTestElements(); form.elements.length", "0"); shouldBe("removeTestElements(); form.elements.length", "0");
shouldBeUndefined("select.options['no-such-element']");
debug(""); debug("");
function testFirstItemReturnsFirstMatch(collection, initialLength, elementNames, attributes) { function testFirstItemReturnsFirstMatch(collection, initialLength, elementNames, attributes) {
......
...@@ -50,6 +50,20 @@ PASS unionTypesTest.doubleOrStringDefaultNullArg(undefined) is "null is passed" ...@@ -50,6 +50,20 @@ PASS unionTypesTest.doubleOrStringDefaultNullArg(undefined) is "null is passed"
PASS unionTypesTest.doubleOrStringDefaultNullArg(null) is "null is passed" PASS unionTypesTest.doubleOrStringDefaultNullArg(null) is "null is passed"
PASS unionTypesTest.doubleOrStringDefaultNullArg(3.14) is "double is passed: 3.14" PASS unionTypesTest.doubleOrStringDefaultNullArg(3.14) is "double is passed: 3.14"
PASS unionTypesTest.doubleOrStringDefaultNullArg("foo") is "string is passed: foo" PASS unionTypesTest.doubleOrStringDefaultNullArg("foo") is "string is passed: foo"
Tests for nullable method arguments
PASS unionTypesTest.nodeListOrElementOrNullArg(undefined) is "null or undefined is passed"
PASS unionTypesTest.nodeListOrElementOrNullArg(null) is "null or undefined is passed"
PASS unionTypesTest.nodeListOrElementOrNullArg(nodeList) is "nodelist is passed"
PASS unionTypesTest.nodeListOrElementOrNullArg(element) is "element is passed"
PASS unionTypesTest.nodeListOrElementOrNullArg(3.14) threw exception TypeError: Failed to execute 'nodeListOrElementOrNullArg' on 'UnionTypesTest': Not a valid union member..
PASS unionTypesTest.nodeListOrElementOrNullArg("foo") threw exception TypeError: Failed to execute 'nodeListOrElementOrNullArg' on 'UnionTypesTest': Not a valid union member..
PASS unionTypesTest.nodeListOrElementOrNullArg({}) threw exception TypeError: Failed to execute 'nodeListOrElementOrNullArg' on 'UnionTypesTest': Not a valid union member..
PASS unionTypesTest.nodeListOrElementOrNullArg([]) threw exception TypeError: Failed to execute 'nodeListOrElementOrNullArg' on 'UnionTypesTest': Not a valid union member..
PASS unionTypesTest.nodeListOrElementArg(undefined) threw exception TypeError: Failed to execute 'nodeListOrElementArg' on 'UnionTypesTest': Not a valid union member..
PASS unionTypesTest.nodeListOrElementArg(null) threw exception TypeError: Failed to execute 'nodeListOrElementArg' on 'UnionTypesTest': Not a valid union member..
PASS unionTypesTest.nodeListOrElementArg(nodeList) is "nodelist is passed"
PASS unionTypesTest.nodeListOrElementArg(element) is "element is passed"
PASS successfullyParsed is true PASS successfullyParsed is true
TEST COMPLETE TEST COMPLETE
......
...@@ -3,6 +3,9 @@ ...@@ -3,6 +3,9 @@
<script> <script>
description('IDL union types unittests'); description('IDL union types unittests');
var element = document.createElement('div');
var nodeList = document.querySelectorAll('script');
if (window.internals) { if (window.internals) {
// The conversion rule prefers string over double, hence a value which // The conversion rule prefers string over double, hence a value which
// is neither double nor string will be converted using ToString(). // is neither double nor string will be converted using ToString().
...@@ -68,6 +71,21 @@ if (window.internals) { ...@@ -68,6 +71,21 @@ if (window.internals) {
shouldBeEqualToString('unionTypesTest.doubleOrStringDefaultNullArg(null)', 'null is passed'); shouldBeEqualToString('unionTypesTest.doubleOrStringDefaultNullArg(null)', 'null is passed');
shouldBeEqualToString('unionTypesTest.doubleOrStringDefaultNullArg(3.14)', 'double is passed: 3.14'); shouldBeEqualToString('unionTypesTest.doubleOrStringDefaultNullArg(3.14)', 'double is passed: 3.14');
shouldBeEqualToString('unionTypesTest.doubleOrStringDefaultNullArg("foo")', 'string is passed: foo'); shouldBeEqualToString('unionTypesTest.doubleOrStringDefaultNullArg("foo")', 'string is passed: foo');
debug('');
debug('Tests for nullable method arguments');
shouldBeEqualToString('unionTypesTest.nodeListOrElementOrNullArg(undefined)', 'null or undefined is passed');
shouldBeEqualToString('unionTypesTest.nodeListOrElementOrNullArg(null)', 'null or undefined is passed');
shouldBeEqualToString('unionTypesTest.nodeListOrElementOrNullArg(nodeList)', 'nodelist is passed');
shouldBeEqualToString('unionTypesTest.nodeListOrElementOrNullArg(element)', 'element is passed');
shouldThrow('unionTypesTest.nodeListOrElementOrNullArg(3.14)');
shouldThrow('unionTypesTest.nodeListOrElementOrNullArg("foo")');
shouldThrow('unionTypesTest.nodeListOrElementOrNullArg({})');
shouldThrow('unionTypesTest.nodeListOrElementOrNullArg([])');
shouldThrow('unionTypesTest.nodeListOrElementArg(undefined)');
shouldThrow('unionTypesTest.nodeListOrElementArg(null)');
shouldBeEqualToString('unionTypesTest.nodeListOrElementArg(nodeList)', 'nodelist is passed');
shouldBeEqualToString('unionTypesTest.nodeListOrElementArg(element)', 'element is passed');
} }
</script> </script>
...@@ -34,6 +34,6 @@ ...@@ -34,6 +34,6 @@
readonly attribute unsigned long length; readonly attribute unsigned long length;
[ImplementedAs=item] getter Element (unsigned long index); [ImplementedAs=item] getter Element (unsigned long index);
[Custom] Element item([Default=Undefined] optional unsigned long index); [Custom] Element item([Default=Undefined] optional unsigned long index);
// FIXME: This should return an (HTMLCollection or Element) union. // FIXME: This should return an (HTMLCollection or Element)? union.
[ImplementedAs=namedGetter] getter (NodeList or Element) namedItem(DOMString name); [ImplementedAs=namedGetter] getter (NodeList or Element)? namedItem(DOMString name);
}; };
...@@ -24,5 +24,5 @@ ...@@ -24,5 +24,5 @@
SetWrapperReferenceFrom=ownerNode, SetWrapperReferenceFrom=ownerNode,
] interface HTMLFormControlsCollection : HTMLCollection { ] interface HTMLFormControlsCollection : HTMLCollection {
[ImplementedAs=item] getter Node (unsigned long index); [ImplementedAs=item] getter Node (unsigned long index);
[ImplementedAs=namedGetter] getter (RadioNodeList or Element) namedItem(DOMString name); // shadows inherited namedItem() [ImplementedAs=namedGetter] getter (RadioNodeList or Element)? namedItem(DOMString name); // shadows inherited namedItem()
}; };
...@@ -29,7 +29,7 @@ ...@@ -29,7 +29,7 @@
[RaisesException, TypeChecking=Interface] setter HTMLOptionElement (unsigned long index, HTMLOptionElement? value); [RaisesException, TypeChecking=Interface] setter HTMLOptionElement (unsigned long index, HTMLOptionElement? value);
// FIXME: The spec and firefox return an Element (the first matching Element). // FIXME: The spec and firefox return an Element (the first matching Element).
[ImplementedAs=namedGetter] getter (NodeList or Element) namedItem(DOMString name); [ImplementedAs=namedGetter] getter (NodeList or Element)? namedItem(DOMString name);
[Custom, RaisesException] void add([Default=Undefined] optional HTMLOptionElement option, optional unsigned long index); [Custom, RaisesException] void add([Default=Undefined] optional HTMLOptionElement option, optional unsigned long index);
void remove(unsigned long index); void remove(unsigned long index);
......
...@@ -76,4 +76,22 @@ String UnionTypesTest::doubleOrStringSequenceArg(Vector<DoubleOrString>& sequenc ...@@ -76,4 +76,22 @@ String UnionTypesTest::doubleOrStringSequenceArg(Vector<DoubleOrString>& sequenc
return doubleOrStringArrayArg(sequence); return doubleOrStringArrayArg(sequence);
} }
String UnionTypesTest::nodeListOrElementArg(NodeListOrElement& nodeListOrElement)
{
ASSERT(!nodeListOrElement.isNull());
return nodeListOrElementOrNullArg(nodeListOrElement);
}
String UnionTypesTest::nodeListOrElementOrNullArg(NodeListOrElement& nodeListOrElementOrNull)
{
if (nodeListOrElementOrNull.isNull())
return "null or undefined is passed";
if (nodeListOrElementOrNull.isNodeList())
return "nodelist is passed";
if (nodeListOrElementOrNull.isElement())
return "element is passed";
ASSERT_NOT_REACHED();
return String();
}
} }
...@@ -26,6 +26,9 @@ public: ...@@ -26,6 +26,9 @@ public:
String doubleOrStringArrayArg(Vector<DoubleOrString>&); String doubleOrStringArrayArg(Vector<DoubleOrString>&);
String doubleOrStringSequenceArg(Vector<DoubleOrString>&); String doubleOrStringSequenceArg(Vector<DoubleOrString>&);
String nodeListOrElementArg(NodeListOrElement&);
String nodeListOrElementOrNullArg(NodeListOrElement&);
void trace(Visitor*) { } void trace(Visitor*) { }
private: private:
......
...@@ -12,6 +12,10 @@ ...@@ -12,6 +12,10 @@
[ImplementedAs=doubleOrStringArg] DOMString doubleOrStringDefaultDoubleArg(optional (double or DOMString) arg = 3.14); [ImplementedAs=doubleOrStringArg] DOMString doubleOrStringDefaultDoubleArg(optional (double or DOMString) arg = 3.14);
[ImplementedAs=doubleOrStringArg] DOMString doubleOrStringDefaultStringArg(optional (double or DOMString) arg = "foo"); [ImplementedAs=doubleOrStringArg] DOMString doubleOrStringDefaultStringArg(optional (double or DOMString) arg = "foo");
[ImplementedAs=doubleOrStringArg] DOMString doubleOrStringDefaultNullArg(optional (double or DOMString)? arg = null); [ImplementedAs=doubleOrStringArg] DOMString doubleOrStringDefaultNullArg(optional (double or DOMString)? arg = null);
DOMString doubleOrStringArrayArg((double or DOMString)[] arg); DOMString doubleOrStringArrayArg((double or DOMString)[] arg);
DOMString doubleOrStringSequenceArg(sequence<(double or DOMString)> arg); DOMString doubleOrStringSequenceArg(sequence<(double or DOMString)> arg);
DOMString nodeListOrElementArg((NodeList or Element) arg);
DOMString nodeListOrElementOrNullArg((NodeList or Element)? arg);
}; };
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment