Diff
Modified: trunk/LayoutTests/ChangeLog (211023 => 211024)
--- trunk/LayoutTests/ChangeLog 2017-01-22 05:19:17 UTC (rev 211023)
+++ trunk/LayoutTests/ChangeLog 2017-01-22 05:48:28 UTC (rev 211024)
@@ -1,5 +1,33 @@
2017-01-21 Chris Dumez <[email protected]>
+ _javascript_ for-of does not work on a lot of collection types (e.g. HTMLCollection)
+ https://bugs.webkit.org/show_bug.cgi?id=167091
+
+ Reviewed by Darin Adler.
+
+ * fast/dom/FileList-iterator-expected.txt: Added.
+ * fast/dom/FileList-iterator.html: Added.
+ * fast/dom/collection-iterators-expected.txt: Added.
+ * fast/dom/collection-iterators.html: Added.
+ * fast/events/touch/ios/touchlist-iterator-expected.txt: Added.
+ * fast/events/touch/ios/touchlist-iterator.html: Added.
+ Add layout test coverage for all types that gained an iterator.
+
+ * fast/dom/document-all-undefined-expected.txt: Added.
+ * fast/dom/document-all-undefined.html: Added.
+ Add layout test to cover the fact that HTMLAllCollection masquerades as
+ undefined, as per:
+ - https://html.spec.whatwg.org/multipage/obsolete.html#dom-document-all
+
+ * inspector/model/remote-object-get-properties-expected.txt:
+ Rebaseline now that there is an extra Symbol.iterator property.
+
+ * platform/wk2/TestExpectations:
+ Skip that requires beginDragWithFiles() as this is unimplemented in
+ WebKitTestRunner.
+
+2017-01-21 Chris Dumez <[email protected]>
+
innerText should replace existing text node
https://bugs.webkit.org/show_bug.cgi?id=167116
Added: trunk/LayoutTests/fast/dom/FileList-iterator-expected.txt (0 => 211024)
--- trunk/LayoutTests/fast/dom/FileList-iterator-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/dom/FileList-iterator-expected.txt 2017-01-22 05:48:28 UTC (rev 211024)
@@ -0,0 +1,17 @@
+
+Tests that FileList objects have an iterator.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS fileList.__proto__ is FileList.prototype
+PASS Symbol.iterator in fileList is true
+PASS forOfSucceeded is true
+PASS 'entries' in fileList is false
+PASS 'keys' in fileList is false
+PASS 'forEach' in fileList is false
+PASS 'values' in fileList is false
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Added: trunk/LayoutTests/fast/dom/FileList-iterator.html (0 => 211024)
--- trunk/LayoutTests/fast/dom/FileList-iterator.html (rev 0)
+++ trunk/LayoutTests/fast/dom/FileList-iterator.html 2017-01-22 05:48:28 UTC (rev 211024)
@@ -0,0 +1,50 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<script src=""
+</head>
+<body>
+<input type="file" _ondrop_="dropped(event)"></input>
+<div id="console"></div>
+<script>
+description("Tests that FileList objects have an iterator.");
+jsTestIsAsync = true;
+
+function runTest()
+{
+ var inputElement = document.getElementsByTagName('input')[0];
+ eventSender.beginDragWithFiles(['test.txt']);
+ eventSender.mouseMoveTo(inputElement.offsetLeft + inputElement.offsetWidth / 2,
+ inputElement.offsetTop + inputElement.offsetHeight / 2);
+ eventSender.mouseUp();
+}
+
+function dropped(event)
+{
+ fileList = event.dataTransfer.files;
+ shouldBe("fileList.__proto__", "FileList.prototype");
+ shouldBeTrue("Symbol.iterator in fileList");
+ forOfSucceeded = false;
+ try {
+ for (var file of fileList) { }
+ forOfSucceeded = true;
+ } catch (e) {
+ forOfSucceeded = false;
+ }
+ shouldBeTrue("forOfSucceeded");
+
+ shouldBeFalse("'entries' in fileList");
+ shouldBeFalse("'keys' in fileList");
+ shouldBeFalse("'forEach' in fileList");
+ shouldBeFalse("'values' in fileList");
+
+ finishJSTest();
+}
+
+runTest();
+
+</script>
+<script src=""
+</body>
+</html>
Added: trunk/LayoutTests/fast/dom/collection-iterators-expected.txt (0 => 211024)
--- trunk/LayoutTests/fast/dom/collection-iterators-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/dom/collection-iterators-expected.txt 2017-01-22 05:48:28 UTC (rev 211024)
@@ -0,0 +1,214 @@
+Tests that interfaces with an indexed getter and an integer-type length attribute get an iterator.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+* AudioTrackList
+PASS obj.__proto__ is AudioTrackList.prototype
+PASS Symbol.iterator in obj is true
+PASS for..of did not throw an exception
+PASS 'entries' in obj is false
+PASS 'keys' in obj is false
+PASS 'forEach' in obj is false
+PASS 'values' in obj is false
+
+* ClientRectList
+PASS obj.__proto__ is ClientRectList.prototype
+PASS Symbol.iterator in obj is true
+PASS for..of did not throw an exception
+PASS 'entries' in obj is false
+PASS 'keys' in obj is false
+PASS 'forEach' in obj is false
+PASS 'values' in obj is false
+
+* CSSRuleList
+PASS obj.__proto__ is CSSRuleList.prototype
+PASS Symbol.iterator in obj is true
+PASS for..of did not throw an exception
+PASS 'entries' in obj is false
+PASS 'keys' in obj is false
+PASS 'forEach' in obj is false
+PASS 'values' in obj is false
+
+* CSSStyleDeclaration
+PASS obj.__proto__ is CSSStyleDeclaration.prototype
+PASS Symbol.iterator in obj is true
+PASS for..of did not throw an exception
+PASS 'entries' in obj is false
+PASS 'keys' in obj is false
+PASS 'forEach' in obj is false
+PASS 'values' in obj is false
+
+* CSSValueList
+PASS obj.__proto__ is CSSValueList.prototype
+PASS Symbol.iterator in obj is true
+PASS for..of did not throw an exception
+PASS 'entries' in obj is false
+PASS 'keys' in obj is false
+PASS 'forEach' in obj is false
+PASS 'values' in obj is false
+
+* MimeTypeArray
+PASS obj.__proto__ is MimeTypeArray.prototype
+PASS Symbol.iterator in obj is true
+PASS for..of did not throw an exception
+PASS 'entries' in obj is false
+PASS 'keys' in obj is false
+PASS 'forEach' in obj is false
+PASS 'values' in obj is false
+
+* WebKitNamedFlowCollection
+PASS Symbol.iterator in obj is true
+PASS for..of did not throw an exception
+PASS 'entries' in obj is false
+PASS 'keys' in obj is false
+PASS 'forEach' in obj is false
+PASS 'values' in obj is false
+
+* Plugin
+PASS obj.__proto__ is Plugin.prototype
+PASS Symbol.iterator in obj is true
+PASS for..of did not throw an exception
+PASS 'entries' in obj is false
+PASS 'keys' in obj is false
+PASS 'forEach' in obj is false
+PASS 'values' in obj is false
+
+* PluginArray
+PASS obj.__proto__ is PluginArray.prototype
+PASS Symbol.iterator in obj is true
+PASS for..of did not throw an exception
+PASS 'entries' in obj is false
+PASS 'keys' in obj is false
+PASS 'forEach' in obj is false
+PASS 'values' in obj is false
+
+* DOMStringList
+PASS obj.__proto__ is DOMStringList.prototype
+PASS Symbol.iterator in obj is true
+PASS for..of did not throw an exception
+PASS 'entries' in obj is false
+PASS 'keys' in obj is false
+PASS 'forEach' in obj is false
+PASS 'values' in obj is false
+
+* HTMLAllCollection
+PASS obj.__proto__ is HTMLAllCollection.prototype
+PASS Symbol.iterator in obj is true
+PASS for..of did not throw an exception
+PASS 'entries' in obj is false
+PASS 'keys' in obj is false
+PASS 'forEach' in obj is false
+PASS 'values' in obj is false
+
+* HTMLCollection
+PASS obj.__proto__ is HTMLCollection.prototype
+PASS Symbol.iterator in obj is true
+PASS for..of did not throw an exception
+PASS 'entries' in obj is false
+PASS 'keys' in obj is false
+PASS 'forEach' in obj is false
+PASS 'values' in obj is false
+
+* HTMLFormElement
+PASS obj.__proto__ is HTMLFormElement.prototype
+PASS Symbol.iterator in obj is true
+PASS for..of did not throw an exception
+PASS 'entries' in obj is false
+PASS 'keys' in obj is false
+PASS 'forEach' in obj is false
+PASS 'values' in obj is false
+
+* HTMLOptionsCollection
+PASS obj.__proto__ is HTMLOptionsCollection.prototype
+PASS Symbol.iterator in obj is true
+PASS for..of did not throw an exception
+PASS 'entries' in obj is false
+PASS 'keys' in obj is false
+PASS 'forEach' in obj is false
+PASS 'values' in obj is false
+
+* HTMLSelectElement
+PASS obj.__proto__ is HTMLSelectElement.prototype
+PASS Symbol.iterator in obj is true
+PASS for..of did not throw an exception
+PASS 'entries' in obj is false
+PASS 'keys' in obj is false
+PASS 'forEach' in obj is false
+PASS 'values' in obj is false
+
+* MediaList
+PASS obj.__proto__ is MediaList.prototype
+PASS Symbol.iterator in obj is true
+PASS for..of did not throw an exception
+PASS 'entries' in obj is false
+PASS 'keys' in obj is false
+PASS 'forEach' in obj is false
+PASS 'values' in obj is false
+
+* NamedNodeMap
+PASS obj.__proto__ is NamedNodeMap.prototype
+PASS Symbol.iterator in obj is true
+PASS for..of did not throw an exception
+PASS 'entries' in obj is false
+PASS 'keys' in obj is false
+PASS 'forEach' in obj is false
+PASS 'values' in obj is false
+
+* SourceBufferList
+PASS obj.__proto__ is SourceBufferList.prototype
+PASS Symbol.iterator in obj is true
+PASS for..of did not throw an exception
+PASS 'entries' in obj is false
+PASS 'keys' in obj is false
+PASS 'forEach' in obj is false
+PASS 'values' in obj is false
+
+* StyleSheetList
+PASS obj.__proto__ is StyleSheetList.prototype
+PASS Symbol.iterator in obj is true
+PASS for..of did not throw an exception
+PASS 'entries' in obj is false
+PASS 'keys' in obj is false
+PASS 'forEach' in obj is false
+PASS 'values' in obj is false
+
+* TextTrackCueList
+PASS obj.__proto__ is TextTrackCueList.prototype
+PASS Symbol.iterator in obj is true
+PASS for..of did not throw an exception
+PASS 'entries' in obj is false
+PASS 'keys' in obj is false
+PASS 'forEach' in obj is false
+PASS 'values' in obj is false
+
+* TextTrackList
+PASS obj.__proto__ is TextTrackList.prototype
+PASS Symbol.iterator in obj is true
+PASS for..of did not throw an exception
+PASS 'entries' in obj is false
+PASS 'keys' in obj is false
+PASS 'forEach' in obj is false
+PASS 'values' in obj is false
+
+* VideoTrackList
+PASS obj.__proto__ is VideoTrackList.prototype
+PASS Symbol.iterator in obj is true
+PASS for..of did not throw an exception
+PASS 'entries' in obj is false
+PASS 'keys' in obj is false
+PASS 'forEach' in obj is false
+PASS 'values' in obj is false
+
+* VTTRegionList
+PASS Symbol.iterator in obj is true
+PASS for..of did not throw an exception
+PASS 'entries' in obj is false
+PASS 'keys' in obj is false
+PASS 'forEach' in obj is false
+PASS 'values' in obj is false
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Added: trunk/LayoutTests/fast/dom/collection-iterators.html (0 => 211024)
--- trunk/LayoutTests/fast/dom/collection-iterators.html (rev 0)
+++ trunk/LayoutTests/fast/dom/collection-iterators.html 2017-01-22 05:48:28 UTC (rev 211024)
@@ -0,0 +1,71 @@
+<!DOCTYPE html>
+<html>
+<head>
+<style media="screen and (min-width: 480px)">
+body {
+ background-position: 10px 20px;
+}
+</style>
+</head>
+<body>
+<script src=""
+<script>
+description("Tests that interfaces with an indexed getter and an integer-type length attribute get an iterator.");
+
+function checkHasIterator(interfaceName, _obj)
+{
+ obj = _obj;
+ debug("* " + interfaceName);
+ if (interfaceName in window)
+ shouldBe("obj.__proto__", "" + interfaceName + ".prototype");
+ shouldBeTrue("Symbol.iterator in obj");
+ forOfSuccess = true;
+ try {
+ for (var p of obj) { }
+ } catch (e) {
+ debug("Exception: " + e);
+ forOfSuccess = false;
+ }
+ if (forOfSuccess)
+ testPassed("for..of did not throw an exception");
+ else
+ testFailed("for..of threw an exception");
+
+ shouldBeFalse("'entries' in obj");
+ shouldBeFalse("'keys' in obj");
+ shouldBeFalse("'forEach' in obj");
+ shouldBeFalse("'values' in obj");
+
+ debug("");
+}
+
+var media = document.createElement("video");
+checkHasIterator("AudioTrackList", media.audioTracks);
+checkHasIterator("ClientRectList", document.body.getClientRects());
+checkHasIterator("CSSRuleList", window.getMatchedCSSRules(document.body));
+checkHasIterator("CSSStyleDeclaration", window.getComputedStyle(document.body));
+checkHasIterator("CSSValueList", window.getComputedStyle(document.body).getPropertyCSSValue('background-position'));
+checkHasIterator("MimeTypeArray", navigator.mimeTypes);
+checkHasIterator("WebKitNamedFlowCollection", document.webkitGetNamedFlows());
+if (navigator.plugins.length)
+ checkHasIterator("Plugin", navigator.plugins[0]);
+checkHasIterator("PluginArray", navigator.plugins);
+checkHasIterator("DOMStringList", location.ancestorOrigins);
+checkHasIterator("HTMLAllCollection", document.all);
+checkHasIterator("HTMLCollection", document.getElementsByTagName("body"));
+checkHasIterator("HTMLFormElement", document.createElement("form"));
+checkHasIterator("HTMLOptionsCollection", document.createElement("select").options);
+checkHasIterator("HTMLSelectElement", document.createElement("select"));
+checkHasIterator("MediaList", document.getElementsByTagName("style")[0].sheet.media);
+checkHasIterator("NamedNodeMap", document.body.attributes);
+if ('SourceBufferList' in window)
+ checkHasIterator("SourceBufferList", (new MediaSource()).sourceBuffers);
+checkHasIterator("StyleSheetList", document.styleSheets);
+checkHasIterator("TextTrackCueList", document.createElement("video").addTextTrack("subtitles").cues);
+checkHasIterator("TextTrackList", media.textTracks);
+checkHasIterator("VideoTrackList", media.videoTracks);
+checkHasIterator("VTTRegionList", document.createElement("video").addTextTrack("subtitles").regions);
+</script>
+<script src=""
+</body>
+</html>
Added: trunk/LayoutTests/fast/dom/document-all-undefined-expected.txt (0 => 211024)
--- trunk/LayoutTests/fast/dom/document-all-undefined-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/dom/document-all-undefined-expected.txt 2017-01-22 05:48:28 UTC (rev 211024)
@@ -0,0 +1,15 @@
+Tests that document.all masquerades as undefined.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS ToBoolean() returned false for document.all
+PASS document.all == undefined is true
+PASS document.all === undefined is false
+PASS document.all == null is true
+PASS document.all === null is false
+PASS typeof document.all is "undefined"
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Added: trunk/LayoutTests/fast/dom/document-all-undefined.html (0 => 211024)
--- trunk/LayoutTests/fast/dom/document-all-undefined.html (rev 0)
+++ trunk/LayoutTests/fast/dom/document-all-undefined.html 2017-01-22 05:48:28 UTC (rev 211024)
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<html>
+<body>
+<script src=""
+<script>
+description("Tests that document.all masquerades as undefined.");
+
+if (document.all)
+ testFailed("ToBoolean() should return false for document.all");
+else
+ testPassed("ToBoolean() returned false for document.all");
+
+shouldBeTrue("document.all == undefined");
+shouldBeFalse("document.all === undefined");
+shouldBeTrue("document.all == null");
+shouldBeFalse("document.all === null");
+shouldBeEqualToString("typeof document.all", "undefined");
+</script>
+<script src=""
+</body>
+</html>
Added: trunk/LayoutTests/fast/events/touch/ios/touchlist-iterator-expected.txt (0 => 211024)
--- trunk/LayoutTests/fast/events/touch/ios/touchlist-iterator-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/events/touch/ios/touchlist-iterator-expected.txt 2017-01-22 05:48:28 UTC (rev 211024)
@@ -0,0 +1,15 @@
+Tests that TouchList objects have an iterator
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS Symbol.iterator in touchList is true
+PASS touch is touch1
+PASS 'entries' in touchList is false
+PASS 'keys' in touchList is false
+PASS 'forEach' in touchList is false
+PASS 'values' in touchList is false
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Added: trunk/LayoutTests/fast/events/touch/ios/touchlist-iterator.html (0 => 211024)
--- trunk/LayoutTests/fast/events/touch/ios/touchlist-iterator.html (rev 0)
+++ trunk/LayoutTests/fast/events/touch/ios/touchlist-iterator.html 2017-01-22 05:48:28 UTC (rev 211024)
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<html>
+<body>
+<script src=""
+<script>
+description("Tests that TouchList objects have an iterator");
+
+var touch1 = new Touch(window, document.body, 1, 2, 3, 4);
+var touchList = new TouchList(touch1);
+shouldBeTrue("Symbol.iterator in touchList");
+for (var touch of touchList) {
+ shouldBe("touch", "touch1");
+}
+
+shouldBeFalse("'entries' in touchList");
+shouldBeFalse("'keys' in touchList");
+shouldBeFalse("'forEach' in touchList");
+shouldBeFalse("'values' in touchList");
+</script>
+<script src=""
+</body>
+</html>
Modified: trunk/LayoutTests/inspector/model/remote-object-get-properties-expected.txt (211023 => 211024)
--- trunk/LayoutTests/inspector/model/remote-object-get-properties-expected.txt 2017-01-22 05:19:17 UTC (rev 211023)
+++ trunk/LayoutTests/inspector/model/remote-object-get-properties-expected.txt 2017-01-22 05:48:28 UTC (rev 211024)
@@ -529,6 +529,7 @@
remove
item
namedItem
+ Symbol(Symbol.iterator)
toString
toLocaleString
valueOf
Added: trunk/LayoutTests/platform/ios-simulator/fast/dom/collection-iterators-expected.txt (0 => 211024)
--- trunk/LayoutTests/platform/ios-simulator/fast/dom/collection-iterators-expected.txt (rev 0)
+++ trunk/LayoutTests/platform/ios-simulator/fast/dom/collection-iterators-expected.txt 2017-01-22 05:48:28 UTC (rev 211024)
@@ -0,0 +1,196 @@
+Tests that interfaces with an indexed getter and an integer-type length attribute get an iterator.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+* AudioTrackList
+PASS obj.__proto__ is AudioTrackList.prototype
+PASS Symbol.iterator in obj is true
+PASS for..of did not throw an exception
+PASS 'entries' in obj is false
+PASS 'keys' in obj is false
+PASS 'forEach' in obj is false
+PASS 'values' in obj is false
+
+* ClientRectList
+PASS obj.__proto__ is ClientRectList.prototype
+PASS Symbol.iterator in obj is true
+PASS for..of did not throw an exception
+PASS 'entries' in obj is false
+PASS 'keys' in obj is false
+PASS 'forEach' in obj is false
+PASS 'values' in obj is false
+
+* CSSRuleList
+PASS obj.__proto__ is CSSRuleList.prototype
+PASS Symbol.iterator in obj is true
+PASS for..of did not throw an exception
+PASS 'entries' in obj is false
+PASS 'keys' in obj is false
+PASS 'forEach' in obj is false
+PASS 'values' in obj is false
+
+* CSSStyleDeclaration
+PASS obj.__proto__ is CSSStyleDeclaration.prototype
+PASS Symbol.iterator in obj is true
+PASS for..of did not throw an exception
+PASS 'entries' in obj is false
+PASS 'keys' in obj is false
+PASS 'forEach' in obj is false
+PASS 'values' in obj is false
+
+* CSSValueList
+PASS obj.__proto__ is CSSValueList.prototype
+PASS Symbol.iterator in obj is true
+PASS for..of did not throw an exception
+PASS 'entries' in obj is false
+PASS 'keys' in obj is false
+PASS 'forEach' in obj is false
+PASS 'values' in obj is false
+
+* MimeTypeArray
+PASS obj.__proto__ is MimeTypeArray.prototype
+PASS Symbol.iterator in obj is true
+PASS for..of did not throw an exception
+PASS 'entries' in obj is false
+PASS 'keys' in obj is false
+PASS 'forEach' in obj is false
+PASS 'values' in obj is false
+
+* WebKitNamedFlowCollection
+PASS Symbol.iterator in obj is true
+PASS for..of did not throw an exception
+PASS 'entries' in obj is false
+PASS 'keys' in obj is false
+PASS 'forEach' in obj is false
+PASS 'values' in obj is false
+
+* PluginArray
+PASS obj.__proto__ is PluginArray.prototype
+PASS Symbol.iterator in obj is true
+PASS for..of did not throw an exception
+PASS 'entries' in obj is false
+PASS 'keys' in obj is false
+PASS 'forEach' in obj is false
+PASS 'values' in obj is false
+
+* DOMStringList
+PASS obj.__proto__ is DOMStringList.prototype
+PASS Symbol.iterator in obj is true
+PASS for..of did not throw an exception
+PASS 'entries' in obj is false
+PASS 'keys' in obj is false
+PASS 'forEach' in obj is false
+PASS 'values' in obj is false
+
+* HTMLAllCollection
+PASS obj.__proto__ is HTMLAllCollection.prototype
+PASS Symbol.iterator in obj is true
+PASS for..of did not throw an exception
+PASS 'entries' in obj is false
+PASS 'keys' in obj is false
+PASS 'forEach' in obj is false
+PASS 'values' in obj is false
+
+* HTMLCollection
+PASS obj.__proto__ is HTMLCollection.prototype
+PASS Symbol.iterator in obj is true
+PASS for..of did not throw an exception
+PASS 'entries' in obj is false
+PASS 'keys' in obj is false
+PASS 'forEach' in obj is false
+PASS 'values' in obj is false
+
+* HTMLFormElement
+PASS obj.__proto__ is HTMLFormElement.prototype
+PASS Symbol.iterator in obj is true
+PASS for..of did not throw an exception
+PASS 'entries' in obj is false
+PASS 'keys' in obj is false
+PASS 'forEach' in obj is false
+PASS 'values' in obj is false
+
+* HTMLOptionsCollection
+PASS obj.__proto__ is HTMLOptionsCollection.prototype
+PASS Symbol.iterator in obj is true
+PASS for..of did not throw an exception
+PASS 'entries' in obj is false
+PASS 'keys' in obj is false
+PASS 'forEach' in obj is false
+PASS 'values' in obj is false
+
+* HTMLSelectElement
+PASS obj.__proto__ is HTMLSelectElement.prototype
+PASS Symbol.iterator in obj is true
+PASS for..of did not throw an exception
+PASS 'entries' in obj is false
+PASS 'keys' in obj is false
+PASS 'forEach' in obj is false
+PASS 'values' in obj is false
+
+* MediaList
+PASS obj.__proto__ is MediaList.prototype
+PASS Symbol.iterator in obj is true
+PASS for..of did not throw an exception
+PASS 'entries' in obj is false
+PASS 'keys' in obj is false
+PASS 'forEach' in obj is false
+PASS 'values' in obj is false
+
+* NamedNodeMap
+PASS obj.__proto__ is NamedNodeMap.prototype
+PASS Symbol.iterator in obj is true
+PASS for..of did not throw an exception
+PASS 'entries' in obj is false
+PASS 'keys' in obj is false
+PASS 'forEach' in obj is false
+PASS 'values' in obj is false
+
+* StyleSheetList
+PASS obj.__proto__ is StyleSheetList.prototype
+PASS Symbol.iterator in obj is true
+PASS for..of did not throw an exception
+PASS 'entries' in obj is false
+PASS 'keys' in obj is false
+PASS 'forEach' in obj is false
+PASS 'values' in obj is false
+
+* TextTrackCueList
+PASS obj.__proto__ is TextTrackCueList.prototype
+PASS Symbol.iterator in obj is true
+PASS for..of did not throw an exception
+PASS 'entries' in obj is false
+PASS 'keys' in obj is false
+PASS 'forEach' in obj is false
+PASS 'values' in obj is false
+
+* TextTrackList
+PASS obj.__proto__ is TextTrackList.prototype
+PASS Symbol.iterator in obj is true
+PASS for..of did not throw an exception
+PASS 'entries' in obj is false
+PASS 'keys' in obj is false
+PASS 'forEach' in obj is false
+PASS 'values' in obj is false
+
+* VideoTrackList
+PASS obj.__proto__ is VideoTrackList.prototype
+PASS Symbol.iterator in obj is true
+PASS for..of did not throw an exception
+PASS 'entries' in obj is false
+PASS 'keys' in obj is false
+PASS 'forEach' in obj is false
+PASS 'values' in obj is false
+
+* VTTRegionList
+PASS Symbol.iterator in obj is true
+PASS for..of did not throw an exception
+PASS 'entries' in obj is false
+PASS 'keys' in obj is false
+PASS 'forEach' in obj is false
+PASS 'values' in obj is false
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Modified: trunk/LayoutTests/platform/wk2/TestExpectations (211023 => 211024)
--- trunk/LayoutTests/platform/wk2/TestExpectations 2017-01-22 05:19:17 UTC (rev 211023)
+++ trunk/LayoutTests/platform/wk2/TestExpectations 2017-01-22 05:48:28 UTC (rev 211024)
@@ -599,6 +599,7 @@
# https://bugs.webkit.org/show_bug.cgi?id=64285
editing/pasteboard/file-drag-to-editable.html
editing/pasteboard/file-input-files-access.html
+fast/dom/FileList-iterator.html
fast/dom/Window/window-postmessage-clone-frames.html
fast/dom/Window/window-postmessage-clone.html
fast/events/data-transfer-files-attribute-identity.html
Modified: trunk/Source/_javascript_Core/ChangeLog (211023 => 211024)
--- trunk/Source/_javascript_Core/ChangeLog 2017-01-22 05:19:17 UTC (rev 211023)
+++ trunk/Source/_javascript_Core/ChangeLog 2017-01-22 05:48:28 UTC (rev 211024)
@@ -1,3 +1,39 @@
+2017-01-21 Chris Dumez <[email protected]>
+
+ _javascript_ for-of does not work on a lot of collection types (e.g. HTMLCollection)
+ https://bugs.webkit.org/show_bug.cgi?id=167091
+
+ Reviewed by Darin Adler.
+
+ Update Array methods to throw a TypeError when (this === null || this === undefined)
+ instead of when (this == null). This is because (this == null) returns true for types
+ that masquerades as undefined (such as document.all) and this prevented use of the
+ Array API on such types. The specification only stays to use ToObject(), which throws
+ when the input is undefined or null.
+
+ The corresponding specification is at:
+ - https://www.ecma-international.org/ecma-262/7.0/index.html#sec-array.prototype.values
+ - https://www.ecma-international.org/ecma-262/7.0/index.html#sec-toobject
+
+ * builtins/ArrayPrototype.js:
+ (values):
+ (keys):
+ (entries):
+ (reduce):
+ (reduceRight):
+ (every):
+ (forEach):
+ (filter):
+ (map):
+ (some):
+ (fill):
+ (find):
+ (findIndex):
+ (includes):
+ (sort):
+ (concatSlowPath):
+ (copyWithin):
+
2017-01-21 Yusuke Suzuki <[email protected]>
[JSC] export JSC::importModule API for WebCore dynamic import
Modified: trunk/Source/_javascript_Core/builtins/ArrayPrototype.js (211023 => 211024)
--- trunk/Source/_javascript_Core/builtins/ArrayPrototype.js 2017-01-22 05:19:17 UTC (rev 211023)
+++ trunk/Source/_javascript_Core/builtins/ArrayPrototype.js 2017-01-22 05:48:28 UTC (rev 211024)
@@ -39,7 +39,7 @@
{
"use strict";
- if (this == null)
+ if (this === null || this === @undefined)
@throwTypeError("Array.prototype.values requires that |this| not be null or undefined");
return new @createArrayIterator(@Object(this), "value", @arrayIteratorValueNext);
@@ -49,7 +49,7 @@
{
"use strict";
- if (this == null)
+ if (this === null || this === @undefined)
@throwTypeError("Array.prototype.keys requires that |this| not be null or undefined");
return new @createArrayIterator(@Object(this), "key", @arrayIteratorKeyNext);
@@ -59,7 +59,7 @@
{
"use strict";
- if (this == null)
+ if (this === null || this === @undefined)
@throwTypeError("Array.prototype.entries requires that |this| not be null or undefined");
return new @createArrayIterator(@Object(this), "key+value", @arrayIteratorKeyValueNext);
@@ -69,7 +69,7 @@
{
"use strict";
- if (this == null)
+ if (this === null || this === @undefined)
@throwTypeError("Array.prototype.reduce requires that |this| not be null or undefined");
var array = @Object(this);
@@ -105,7 +105,7 @@
{
"use strict";
- if (this == null)
+ if (this === null || this === @undefined)
@throwTypeError("Array.prototype.reduceRight requires that |this| not be null or undefined");
var array = @Object(this);
@@ -141,7 +141,7 @@
{
"use strict";
- if (this == null)
+ if (this === null || this === @undefined)
@throwTypeError("Array.prototype.every requires that |this| not be null or undefined");
var array = @Object(this);
@@ -166,7 +166,7 @@
{
"use strict";
- if (this == null)
+ if (this === null || this === @undefined)
@throwTypeError("Array.prototype.forEach requires that |this| not be null or undefined");
var array = @Object(this);
@@ -187,7 +187,7 @@
{
"use strict";
- if (this == null)
+ if (this === null || this === @undefined)
@throwTypeError("Array.prototype.filter requires that |this| not be null or undefined");
var array = @Object(this);
@@ -236,7 +236,7 @@
{
"use strict";
- if (this == null)
+ if (this === null || this === @undefined)
@throwTypeError("Array.prototype.map requires that |this| not be null or undefined");
var array = @Object(this);
@@ -282,7 +282,7 @@
{
"use strict";
- if (this == null)
+ if (this === null || this === @undefined)
@throwTypeError("Array.prototype.some requires that |this| not be null or undefined");
var array = @Object(this);
@@ -305,7 +305,7 @@
{
"use strict";
- if (this == null)
+ if (this === null || this === @undefined)
@throwTypeError("Array.prototype.fill requires that |this| not be null or undefined");
var array = @Object(this);
@@ -345,7 +345,7 @@
{
"use strict";
- if (this == null)
+ if (this === null || this === @undefined)
@throwTypeError("Array.prototype.find requires that |this| not be null or undefined");
var array = @Object(this);
@@ -367,7 +367,7 @@
{
"use strict";
- if (this == null)
+ if (this === null || this === @undefined)
@throwTypeError("Array.prototype.findIndex requires that |this| not be null or undefined");
var array = @Object(this);
@@ -388,7 +388,7 @@
{
"use strict";
- if (this == null)
+ if (this === null || this === @undefined)
@throwTypeError("Array.prototype.includes requires that |this| not be null or undefined");
var array = @Object(this);
@@ -625,7 +625,7 @@
bucketSort(array, 0, strings, 0);
}
- if (this == null)
+ if (this === null || this === @undefined)
@throwTypeError("Array.prototype.sort requires that |this| not be null or undefined");
var array = @Object(this);
@@ -651,7 +651,7 @@
{
"use strict";
- if (this == null)
+ if (this === null || this === @undefined)
@throwTypeError("Array.prototype.concat requires that |this| not be null or undefined");
var currentElement = @Object(this);
@@ -741,7 +741,7 @@
return (maybeNegativeZero < positive) ? maybeNegativeZero : positive;
}
- if (this == null)
+ if (this === null || this === @undefined)
@throwTypeError("Array.copyWithin requires that |this| not be null or undefined");
var array = @Object(this);
Modified: trunk/Source/WebCore/ChangeLog (211023 => 211024)
--- trunk/Source/WebCore/ChangeLog 2017-01-22 05:19:17 UTC (rev 211023)
+++ trunk/Source/WebCore/ChangeLog 2017-01-22 05:48:28 UTC (rev 211024)
@@ -1,5 +1,37 @@
2017-01-21 Chris Dumez <[email protected]>
+ _javascript_ for-of does not work on a lot of collection types (e.g. HTMLCollection)
+ https://bugs.webkit.org/show_bug.cgi?id=167091
+
+ Reviewed by Darin Adler.
+
+ As per the Web IDL specification [1], https://heycam.github.io/webidl/#es-iterator
+ an interface should get an iterator if it has:
+ - an indexed property getter and an integer-typed attribute named "length".
+
+ We now comply with this part of the Web IDL specification. This adds an iterator
+ to the following interfaces:
+ - AudioTrackList, ClientRectList, CSSRuleList, CSSStyleDeclaration, CSSValueList,
+ MimeTypeArray, WebKitNamedFlowCollection, Plugin, PluginArray, DOMStringList,
+ FileList, HTMLAllCollection, HTMLCollection, HTMLFormElement, HTMLOptionsCollection,
+ HTMLSelectElement, MediaList, NamedNodeMap, SourceBufferList, StyleSheetList,
+ TextTrackCueList, TextTrackList, TouchList, VideoTrackList, VTTRegionList.
+
+ As a result, it is now possible to use `for ... of` for those types.
+
+ Tests: fast/dom/FileList-iterator.html
+ fast/dom/collection-iterators.html
+ fast/dom/document-all-undefined.html
+ fast/events/touch/ios/touchlist-iterator.html
+
+ * bindings/scripts/CodeGeneratorJS.pm:
+ (GetAttributeWithName):
+ (InterfaceNeedsIterator):
+ (GenerateImplementation):
+ (addIterableProperties):
+
+2017-01-21 Chris Dumez <[email protected]>
+
innerText should replace existing text node
https://bugs.webkit.org/show_bug.cgi?id=167116
Modified: trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm (211023 => 211024)
--- trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm 2017-01-22 05:19:17 UTC (rev 211023)
+++ trunk/Source/WebCore/bindings/scripts/CodeGeneratorJS.pm 2017-01-22 05:48:28 UTC (rev 211024)
@@ -2967,6 +2967,29 @@
return "DOMJIT::IDLResultTypeFilter<${IDLType}>::value";
}
+sub GetAttributeWithName
+{
+ my ($interface, $attributeName) = @_;
+
+ foreach my $attribute (@{$interface->attributes}) {
+ return $attribute if $attribute->name eq $attributeName;
+ }
+}
+
+# https://heycam.github.io/webidl/#es-iterator
+sub InterfaceNeedsIterator
+{
+ my ($interface) = @_;
+
+ return 1 if $interface->iterable;
+ if (GetIndexedGetterFunction($interface)) {
+ my $lengthAttribute = GetAttributeWithName($interface, "length");
+ return 1 if $lengthAttribute and $codeGenerator->IsIntegerType($lengthAttribute->type);
+ }
+ # FIXME: This should return 1 for maplike and setlike once we support them.
+ return 0;
+}
+
sub GenerateImplementation
{
my ($object, $interface, $enumerations, $dictionaries) = @_;
@@ -3320,9 +3343,16 @@
push(@implContent, "#endif\n") if $conditionalString;
}
- if ($interface->iterable) {
- addIterableProperties($interface, $className);
+ if (InterfaceNeedsIterator($interface)) {
+ if (IsKeyValueIterableInterface($interface)) {
+ my $functionName = GetFunctionName($interface, $className, @{$interface->iterable->functions}[0]);
+ push(@implContent, " putDirect(vm, vm.propertyNames->iteratorSymbol, JSFunction::create(vm, globalObject(), 0, ASCIILiteral(\"[Symbol.Iterator]\"), $functionName), DontEnum);\n");
+ } else {
+ AddToImplIncludes("<builtins/BuiltinNames.h>");
+ push(@implContent, " putDirect(vm, vm.propertyNames->iteratorSymbol, globalObject()->arrayPrototype()->getDirect(vm, vm.propertyNames->builtinNames().valuesPrivateName()), DontEnum);\n");
+ }
}
+ push(@implContent, " addValueIterableMethods(*globalObject(), *this);\n") if $interface->iterable and !IsKeyValueIterableInterface($interface);
addUnscopableProperties($interface);
@@ -5158,24 +5188,6 @@
}
}
-sub addIterableProperties()
-{
- my $interface = shift;
- my $className = shift;
-
- if (NeedsRuntimeCheck($interface->iterable)) {
- my $enable_function = GetRuntimeEnableFunctionName($interface->iterable);
- push(@implContent, " if (${enable_function}())\n ");
- }
-
- if (IsKeyValueIterableInterface($interface)) {
- my $functionName = GetFunctionName($interface, $className, @{$interface->iterable->functions}[0]);
- push(@implContent, " putDirect(vm, vm.propertyNames->iteratorSymbol, JSFunction::create(vm, globalObject(), 0, ASCIILiteral(\"[Symbol.Iterator]\"), $functionName), DontEnum);\n");
- } else {
- push(@implContent, " addValueIterableMethods(*globalObject(), *this);\n");
- }
-}
-
my %nativeType = (
"ByteString" => "String",
"DOMString" => "String",
Modified: trunk/Source/WebCore/bindings/scripts/test/JS/JSTestNode.cpp (211023 => 211024)
--- trunk/Source/WebCore/bindings/scripts/test/JS/JSTestNode.cpp 2017-01-22 05:19:17 UTC (rev 211023)
+++ trunk/Source/WebCore/bindings/scripts/test/JS/JSTestNode.cpp 2017-01-22 05:48:28 UTC (rev 211024)
@@ -144,8 +144,7 @@
VM::DeletePropertyModeScope scope(vm, VM::DeletePropertyMode::IgnoreConfigurable);
JSObject::deleteProperty(this, globalObject()->globalExec(), propertyName);
}
- if (RuntimeEnabledFeatures::sharedFeatures().domIteratorEnabled())
- putDirect(vm, vm.propertyNames->iteratorSymbol, JSFunction::create(vm, globalObject(), 0, ASCIILiteral("[Symbol.Iterator]"), jsTestNodePrototypeFunctionSymbolIterator), DontEnum);
+ putDirect(vm, vm.propertyNames->iteratorSymbol, JSFunction::create(vm, globalObject(), 0, ASCIILiteral("[Symbol.Iterator]"), jsTestNodePrototypeFunctionSymbolIterator), DontEnum);
}
const ClassInfo JSTestNode::s_info = { "TestNode", &Base::s_info, 0, CREATE_METHOD_TABLE(JSTestNode) };
Modified: trunk/Source/WebCore/bindings/scripts/test/JS/JSTestObj.cpp (211023 => 211024)
--- trunk/Source/WebCore/bindings/scripts/test/JS/JSTestObj.cpp 2017-01-22 05:19:17 UTC (rev 211023)
+++ trunk/Source/WebCore/bindings/scripts/test/JS/JSTestObj.cpp 2017-01-22 05:48:28 UTC (rev 211024)
@@ -54,6 +54,7 @@
#include "Settings.h"
#include "URL.h"
#include "WebCoreJSClientData.h"
+#include <builtins/BuiltinNames.h>
#include <inspector/ScriptArguments.h>
#include <inspector/ScriptCallStackFactory.h>
#include <runtime/Error.h>
@@ -1897,6 +1898,7 @@
#endif
putDirect(vm, static_cast<JSVMClientData*>(vm.clientData)->builtinNames().privateMethodPrivateName(), JSFunction::create(vm, globalObject(), 0, String(), jsTestObjPrototypeFunctionPrivateMethod), ReadOnly | DontEnum);
putDirect(vm, static_cast<JSVMClientData*>(vm.clientData)->builtinNames().publicAndPrivateMethodPrivateName(), JSFunction::create(vm, globalObject(), 0, String(), jsTestObjPrototypeFunctionPublicAndPrivateMethod), ReadOnly | DontEnum);
+ putDirect(vm, vm.propertyNames->iteratorSymbol, globalObject()->arrayPrototype()->getDirect(vm, vm.propertyNames->builtinNames().valuesPrivateName()), DontEnum);
addValueIterableMethods(*globalObject(), *this);
JSObject& unscopables = *constructEmptyObject(globalObject()->globalExec(), globalObject()->nullPrototypeObjectStructure());
unscopables.putDirect(vm, Identifier::fromString(&vm, "voidMethod"), jsBoolean(true));