summaryrefslogtreecommitdiffstats
path: root/dom/imptests/html
diff options
context:
space:
mode:
authorMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
committerMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
commit5f8de423f190bbb79a62f804151bc24824fa32d8 (patch)
tree10027f336435511475e392454359edea8e25895d /dom/imptests/html
parent49ee0794b5d912db1f95dce6eb52d781dc210db5 (diff)
downloadUXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.gz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.lz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.xz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.zip
Add m-esr52 at 52.6.0
Diffstat (limited to 'dom/imptests/html')
-rw-r--r--dom/imptests/html/dom/common.js1087
-rw-r--r--dom/imptests/html/dom/test_interface-objects.html45
-rw-r--r--dom/imptests/html/dom/test_interfaces.html455
-rw-r--r--dom/imptests/html/html/browsers/the-window-object/test_window-named-properties.html69
-rw-r--r--dom/imptests/html/html/dom/documents/dta/test_nameditem-06.html104
-rw-r--r--dom/imptests/html/html/dom/elements/global-attributes/reftest-stylo.list59
-rw-r--r--dom/imptests/html/html/dom/elements/global-attributes/reftest.list56
-rw-r--r--dom/imptests/html/js/builtins/test_WeakMap.prototype-properties.html103
-rw-r--r--dom/imptests/html/mochitest.ini24
-rw-r--r--dom/imptests/html/typedarrays/test_constructors.html48
-rw-r--r--dom/imptests/html/webgl/common.js13
-rw-r--r--dom/imptests/html/webgl/test_bufferSubData.html26
-rw-r--r--dom/imptests/html/webgl/test_compressedTexImage2D.html30
-rw-r--r--dom/imptests/html/webgl/test_compressedTexSubImage2D.html30
-rw-r--r--dom/imptests/html/webgl/test_texImage2D.html20
-rw-r--r--dom/imptests/html/webgl/test_texSubImage2D.html20
-rw-r--r--dom/imptests/html/webgl/test_uniformMatrixNfv.html33
17 files changed, 2222 insertions, 0 deletions
diff --git a/dom/imptests/html/dom/common.js b/dom/imptests/html/dom/common.js
new file mode 100644
index 000000000..dc7528a9a
--- /dev/null
+++ b/dom/imptests/html/dom/common.js
@@ -0,0 +1,1087 @@
+"use strict";
+// Written by Aryeh Gregor <ayg@aryeh.name>
+
+// TODO: iframes, contenteditable/designMode
+
+// Everything is done in functions in this test harness, so we have to declare
+// all the variables before use to make sure they can be reused.
+var selection;
+var testDiv, paras, detachedDiv, detachedPara1, detachedPara2,
+ foreignDoc, foreignPara1, foreignPara2, xmlDoc, xmlElement,
+ detachedXmlElement, detachedTextNode, foreignTextNode,
+ detachedForeignTextNode, xmlTextNode, detachedXmlTextNode,
+ processingInstruction, detachedProcessingInstruction, comment,
+ detachedComment, foreignComment, detachedForeignComment, xmlComment,
+ detachedXmlComment, docfrag, foreignDocfrag, xmlDocfrag, doctype,
+ foreignDoctype, xmlDoctype;
+var testRangesShort, testRanges, testPoints, testNodesShort, testNodes;
+
+function setupRangeTests() {
+ selection = getSelection();
+ testDiv = document.querySelector("#test");
+ if (testDiv) {
+ testDiv.parentNode.removeChild(testDiv);
+ }
+ testDiv = document.createElement("div");
+ testDiv.id = "test";
+ document.body.insertBefore(testDiv, document.body.firstChild);
+
+ paras = [];
+ paras.push(document.createElement("p"));
+ paras[0].setAttribute("id", "a");
+ // Test some diacritics, to make sure browsers are using code units here
+ // and not something like grapheme clusters.
+ paras[0].textContent = "A\u0308b\u0308c\u0308d\u0308e\u0308f\u0308g\u0308h\u0308\n";
+ testDiv.appendChild(paras[0]);
+
+ paras.push(document.createElement("p"));
+ paras[1].setAttribute("id", "b");
+ paras[1].setAttribute("style", "display:none");
+ paras[1].textContent = "Ijklmnop\n";
+ testDiv.appendChild(paras[1]);
+
+ paras.push(document.createElement("p"));
+ paras[2].setAttribute("id", "c");
+ paras[2].textContent = "Qrstuvwx";
+ testDiv.appendChild(paras[2]);
+
+ paras.push(document.createElement("p"));
+ paras[3].setAttribute("id", "d");
+ paras[3].setAttribute("style", "display:none");
+ paras[3].textContent = "Yzabcdef";
+ testDiv.appendChild(paras[3]);
+
+ paras.push(document.createElement("p"));
+ paras[4].setAttribute("id", "e");
+ paras[4].setAttribute("style", "display:none");
+ paras[4].textContent = "Ghijklmn";
+ testDiv.appendChild(paras[4]);
+
+ detachedDiv = document.createElement("div");
+ detachedPara1 = document.createElement("p");
+ detachedPara1.appendChild(document.createTextNode("Opqrstuv"));
+ detachedPara2 = document.createElement("p");
+ detachedPara2.appendChild(document.createTextNode("Wxyzabcd"));
+ detachedDiv.appendChild(detachedPara1);
+ detachedDiv.appendChild(detachedPara2);
+
+ // Opera doesn't automatically create a doctype for a new HTML document,
+ // contrary to spec. It also doesn't let you add doctypes to documents
+ // after the fact through any means I've tried. So foreignDoc in Opera
+ // will have no doctype, foreignDoctype will be null, and Opera will fail
+ // some tests somewhat mysteriously as a result.
+ foreignDoc = document.implementation.createHTMLDocument("");
+ foreignPara1 = foreignDoc.createElement("p");
+ foreignPara1.appendChild(foreignDoc.createTextNode("Efghijkl"));
+ foreignPara2 = foreignDoc.createElement("p");
+ foreignPara2.appendChild(foreignDoc.createTextNode("Mnopqrst"));
+ foreignDoc.body.appendChild(foreignPara1);
+ foreignDoc.body.appendChild(foreignPara2);
+
+ // Now we get to do really silly stuff, which nobody in the universe is
+ // ever going to actually do, but the spec defines behavior, so too bad.
+ // Testing is fun!
+ xmlDoctype = document.implementation.createDocumentType("qorflesnorf", "abcde", "x\"'y");
+ xmlDoc = document.implementation.createDocument(null, null, xmlDoctype);
+ detachedXmlElement = xmlDoc.createElement("everyone-hates-hyphenated-element-names");
+ detachedTextNode = document.createTextNode("Uvwxyzab");
+ detachedForeignTextNode = foreignDoc.createTextNode("Cdefghij");
+ detachedXmlTextNode = xmlDoc.createTextNode("Klmnopqr");
+ // PIs only exist in XML documents, so don't bother with document or
+ // foreignDoc.
+ detachedProcessingInstruction = xmlDoc.createProcessingInstruction("whippoorwill", "chirp chirp chirp");
+ detachedComment = document.createComment("Stuvwxyz");
+ // Hurrah, we finally got to "z" at the end!
+ detachedForeignComment = foreignDoc.createComment("אריה יהודה");
+ detachedXmlComment = xmlDoc.createComment("בן חיים אליעזר");
+
+ // We should also test with document fragments that actually contain stuff
+ // . . . but, maybe later.
+ docfrag = document.createDocumentFragment();
+ foreignDocfrag = foreignDoc.createDocumentFragment();
+ xmlDocfrag = xmlDoc.createDocumentFragment();
+
+ xmlElement = xmlDoc.createElement("igiveuponcreativenames");
+ xmlTextNode = xmlDoc.createTextNode("do re mi fa so la ti");
+ xmlElement.appendChild(xmlTextNode);
+ processingInstruction = xmlDoc.createProcessingInstruction("somePI", 'Did you know that ":syn sync fromstart" is very useful when using vim to edit large amounts of JavaScript embedded in HTML?');
+ xmlDoc.appendChild(xmlElement);
+ xmlDoc.appendChild(processingInstruction);
+ xmlComment = xmlDoc.createComment("I maliciously created a comment that will break incautious XML serializers, but Firefox threw an exception, so all I got was this lousy T-shirt");
+ xmlDoc.appendChild(xmlComment);
+
+ comment = document.createComment("Alphabet soup?");
+ testDiv.appendChild(comment);
+
+ foreignComment = foreignDoc.createComment('"Commenter" and "commentator" mean different things. I\'ve seen non-native speakers trip up on this.');
+ foreignDoc.appendChild(foreignComment);
+ foreignTextNode = foreignDoc.createTextNode("I admit that I harbor doubts about whether we really need so many things to test, but it's too late to stop now.");
+ foreignDoc.body.appendChild(foreignTextNode);
+
+ doctype = document.doctype;
+ foreignDoctype = foreignDoc.doctype;
+
+ testRangesShort = [
+ // Various ranges within the text node children of different
+ // paragraphs. All should be valid.
+ "[paras[0].firstChild, 0, paras[0].firstChild, 0]",
+ "[paras[0].firstChild, 0, paras[0].firstChild, 1]",
+ "[paras[0].firstChild, 2, paras[0].firstChild, 8]",
+ "[paras[0].firstChild, 2, paras[0].firstChild, 9]",
+ "[paras[1].firstChild, 0, paras[1].firstChild, 0]",
+ "[paras[1].firstChild, 2, paras[1].firstChild, 9]",
+ "[detachedPara1.firstChild, 0, detachedPara1.firstChild, 0]",
+ "[detachedPara1.firstChild, 2, detachedPara1.firstChild, 8]",
+ "[foreignPara1.firstChild, 0, foreignPara1.firstChild, 0]",
+ "[foreignPara1.firstChild, 2, foreignPara1.firstChild, 8]",
+ // Now try testing some elements, not just text nodes.
+ "[document.documentElement, 0, document.documentElement, 1]",
+ "[document.documentElement, 0, document.documentElement, 2]",
+ "[document.documentElement, 1, document.documentElement, 2]",
+ "[document.head, 1, document.head, 1]",
+ "[document.body, 4, document.body, 5]",
+ "[foreignDoc.documentElement, 0, foreignDoc.documentElement, 1]",
+ "[paras[0], 0, paras[0], 1]",
+ "[detachedPara1, 0, detachedPara1, 1]",
+ // Now try some ranges that span elements.
+ "[paras[0].firstChild, 0, paras[1].firstChild, 0]",
+ "[paras[0].firstChild, 0, paras[1].firstChild, 8]",
+ "[paras[0].firstChild, 3, paras[3], 1]",
+ // How about something that spans a node and its descendant?
+ "[paras[0], 0, paras[0].firstChild, 7]",
+ "[testDiv, 2, paras[4], 1]",
+ // Then a few more interesting things just for good measure.
+ "[document, 0, document, 1]",
+ "[document, 0, document, 2]",
+ "[comment, 2, comment, 3]",
+ "[testDiv, 0, comment, 5]",
+ "[foreignDoc, 1, foreignComment, 2]",
+ "[foreignDoc.body, 0, foreignTextNode, 36]",
+ "[xmlDoc, 1, xmlComment, 0]",
+ "[detachedTextNode, 0, detachedTextNode, 8]",
+ "[detachedForeignTextNode, 0, detachedForeignTextNode, 8]",
+ "[detachedXmlTextNode, 0, detachedXmlTextNode, 8]",
+ "[detachedComment, 3, detachedComment, 4]",
+ "[detachedForeignComment, 0, detachedForeignComment, 1]",
+ "[detachedXmlComment, 2, detachedXmlComment, 6]",
+ "[docfrag, 0, docfrag, 0]",
+ ];
+
+ testRanges = testRangesShort.concat([
+ "[paras[1].firstChild, 0, paras[1].firstChild, 1]",
+ "[paras[1].firstChild, 2, paras[1].firstChild, 8]",
+ "[detachedPara1.firstChild, 0, detachedPara1.firstChild, 1]",
+ "[foreignPara1.firstChild, 0, foreignPara1.firstChild, 1]",
+ "[foreignDoc.head, 1, foreignDoc.head, 1]",
+ "[foreignDoc.body, 0, foreignDoc.body, 0]",
+ "[paras[0], 0, paras[0], 0]",
+ "[detachedPara1, 0, detachedPara1, 0]",
+ "[testDiv, 1, paras[2].firstChild, 5]",
+ "[document.documentElement, 1, document.body, 0]",
+ "[foreignDoc.documentElement, 1, foreignDoc.body, 0]",
+ "[document, 1, document, 2]",
+ "[paras[2].firstChild, 4, comment, 2]",
+ "[paras[3], 1, comment, 8]",
+ "[foreignDoc, 0, foreignDoc, 0]",
+ "[xmlDoc, 0, xmlDoc, 0]",
+ "[detachedForeignTextNode, 7, detachedForeignTextNode, 7]",
+ "[detachedXmlTextNode, 7, detachedXmlTextNode, 7]",
+ "[detachedComment, 5, detachedComment, 5]",
+ "[detachedForeignComment, 4, detachedForeignComment, 4]",
+ "[foreignDocfrag, 0, foreignDocfrag, 0]",
+ "[xmlDocfrag, 0, xmlDocfrag, 0]",
+ ]);
+
+ testPoints = [
+ // Various positions within the page, some invalid. Remember that
+ // paras[0] is visible, and paras[1] is display: none.
+ "[paras[0].firstChild, -1]",
+ "[paras[0].firstChild, 0]",
+ "[paras[0].firstChild, 1]",
+ "[paras[0].firstChild, 2]",
+ "[paras[0].firstChild, 8]",
+ "[paras[0].firstChild, 9]",
+ "[paras[0].firstChild, 10]",
+ "[paras[0].firstChild, 65535]",
+ "[paras[1].firstChild, -1]",
+ "[paras[1].firstChild, 0]",
+ "[paras[1].firstChild, 1]",
+ "[paras[1].firstChild, 2]",
+ "[paras[1].firstChild, 8]",
+ "[paras[1].firstChild, 9]",
+ "[paras[1].firstChild, 10]",
+ "[paras[1].firstChild, 65535]",
+ "[detachedPara1.firstChild, 0]",
+ "[detachedPara1.firstChild, 1]",
+ "[detachedPara1.firstChild, 8]",
+ "[detachedPara1.firstChild, 9]",
+ "[foreignPara1.firstChild, 0]",
+ "[foreignPara1.firstChild, 1]",
+ "[foreignPara1.firstChild, 8]",
+ "[foreignPara1.firstChild, 9]",
+ // Now try testing some elements, not just text nodes.
+ "[document.documentElement, -1]",
+ "[document.documentElement, 0]",
+ "[document.documentElement, 1]",
+ "[document.documentElement, 2]",
+ "[document.documentElement, 7]",
+ "[document.head, 1]",
+ "[document.body, 3]",
+ "[foreignDoc.documentElement, 0]",
+ "[foreignDoc.documentElement, 1]",
+ "[foreignDoc.head, 0]",
+ "[foreignDoc.body, 1]",
+ "[paras[0], 0]",
+ "[paras[0], 1]",
+ "[paras[0], 2]",
+ "[paras[1], 0]",
+ "[paras[1], 1]",
+ "[paras[1], 2]",
+ "[detachedPara1, 0]",
+ "[detachedPara1, 1]",
+ "[testDiv, 0]",
+ "[testDiv, 3]",
+ // Then a few more interesting things just for good measure.
+ "[document, -1]",
+ "[document, 0]",
+ "[document, 1]",
+ "[document, 2]",
+ "[document, 3]",
+ "[comment, -1]",
+ "[comment, 0]",
+ "[comment, 4]",
+ "[comment, 96]",
+ "[foreignDoc, 0]",
+ "[foreignDoc, 1]",
+ "[foreignComment, 2]",
+ "[foreignTextNode, 0]",
+ "[foreignTextNode, 36]",
+ "[xmlDoc, -1]",
+ "[xmlDoc, 0]",
+ "[xmlDoc, 1]",
+ "[xmlDoc, 5]",
+ "[xmlComment, 0]",
+ "[xmlComment, 4]",
+ "[processingInstruction, 0]",
+ "[processingInstruction, 5]",
+ "[processingInstruction, 9]",
+ "[detachedTextNode, 0]",
+ "[detachedTextNode, 8]",
+ "[detachedForeignTextNode, 0]",
+ "[detachedForeignTextNode, 8]",
+ "[detachedXmlTextNode, 0]",
+ "[detachedXmlTextNode, 8]",
+ "[detachedProcessingInstruction, 12]",
+ "[detachedComment, 3]",
+ "[detachedComment, 5]",
+ "[detachedForeignComment, 0]",
+ "[detachedForeignComment, 4]",
+ "[detachedXmlComment, 2]",
+ "[docfrag, 0]",
+ "[foreignDocfrag, 0]",
+ "[xmlDocfrag, 0]",
+ "[doctype, 0]",
+ "[doctype, -17]",
+ "[doctype, 1]",
+ "[foreignDoctype, 0]",
+ "[xmlDoctype, 0]",
+ ];
+
+ testNodesShort = [
+ "paras[0]",
+ "paras[0].firstChild",
+ "paras[1].firstChild",
+ "foreignPara1",
+ "foreignPara1.firstChild",
+ "detachedPara1",
+ "detachedPara1.firstChild",
+ "document",
+ "detachedDiv",
+ "foreignDoc",
+ "foreignPara2",
+ "xmlDoc",
+ "xmlElement",
+ "detachedTextNode",
+ "foreignTextNode",
+ "processingInstruction",
+ "detachedProcessingInstruction",
+ "comment",
+ "detachedComment",
+ "docfrag",
+ "doctype",
+ "foreignDoctype",
+ ];
+
+ testNodes = testNodesShort.concat([
+ "paras[1]",
+ "detachedPara2",
+ "detachedPara2.firstChild",
+ "testDiv",
+ "detachedXmlElement",
+ "detachedForeignTextNode",
+ "xmlTextNode",
+ "detachedXmlTextNode",
+ "xmlComment",
+ "foreignComment",
+ "detachedForeignComment",
+ "detachedXmlComment",
+ "foreignDocfrag",
+ "xmlDocfrag",
+ "xmlDoctype",
+ ]);
+}
+if ("setup" in window) {
+ setup(setupRangeTests);
+} else {
+ // Presumably we're running from within an iframe or something
+ setupRangeTests();
+}
+
+/**
+ * The "length" of a node as defined by the Ranges section of DOM4.
+ */
+function nodeLength(node) {
+ // "The length of a node node depends on node:
+ //
+ // "DocumentType
+ // "0."
+ if (node.nodeType == Node.DOCUMENT_TYPE_NODE) {
+ return 0;
+ }
+ // "Text
+ // "ProcessingInstruction
+ // "Comment
+ // "Its length attribute value."
+ // Browsers don't historically support the length attribute on
+ // ProcessingInstruction, so to avoid spurious failures, do
+ // node.data.length instead of node.length.
+ if (node.nodeType == Node.TEXT_NODE || node.nodeType == Node.PROCESSING_INSTRUCTION_NODE || node.nodeType == Node.COMMENT_NODE) {
+ return node.data.length;
+ }
+ // "Any other node
+ // "Its number of children."
+ return node.childNodes.length;
+}
+
+/**
+ * Returns the furthest ancestor of a Node as defined by the spec.
+ */
+function furthestAncestor(node) {
+ var root = node;
+ while (root.parentNode != null) {
+ root = root.parentNode;
+ }
+ return root;
+}
+
+/**
+ * "The ancestor containers of a Node are the Node itself and all its
+ * ancestors."
+ *
+ * Is node1 an ancestor container of node2?
+ */
+function isAncestorContainer(node1, node2) {
+ return node1 == node2 ||
+ (node2.compareDocumentPosition(node1) & Node.DOCUMENT_POSITION_CONTAINS);
+}
+
+/**
+ * Returns the first Node that's after node in tree order, or null if node is
+ * the last Node.
+ */
+function nextNode(node) {
+ if (node.hasChildNodes()) {
+ return node.firstChild;
+ }
+ return nextNodeDescendants(node);
+}
+
+/**
+ * Returns the last Node that's before node in tree order, or null if node is
+ * the first Node.
+ */
+function previousNode(node) {
+ if (node.previousSibling) {
+ node = node.previousSibling;
+ while (node.hasChildNodes()) {
+ node = node.lastChild;
+ }
+ return node;
+ }
+ return node.parentNode;
+}
+
+/**
+ * Returns the next Node that's after node and all its descendants in tree
+ * order, or null if node is the last Node or an ancestor of it.
+ */
+function nextNodeDescendants(node) {
+ while (node && !node.nextSibling) {
+ node = node.parentNode;
+ }
+ if (!node) {
+ return null;
+ }
+ return node.nextSibling;
+}
+
+/**
+ * Returns the ownerDocument of the Node, or the Node itself if it's a
+ * Document.
+ */
+function ownerDocument(node) {
+ return node.nodeType == Node.DOCUMENT_NODE
+ ? node
+ : node.ownerDocument;
+}
+
+/**
+ * Returns true if ancestor is an ancestor of descendant, false otherwise.
+ */
+function isAncestor(ancestor, descendant) {
+ if (!ancestor || !descendant) {
+ return false;
+ }
+ while (descendant && descendant != ancestor) {
+ descendant = descendant.parentNode;
+ }
+ return descendant == ancestor;
+}
+
+/**
+ * Returns true if ancestor is an inclusive ancestor of descendant, false
+ * otherwise.
+ */
+function isInclusiveAncestor(ancestor, descendant) {
+ return ancestor === descendant || isAncestor(ancestor, descendant);
+}
+
+/**
+ * Returns true if descendant is a descendant of ancestor, false otherwise.
+ */
+function isDescendant(descendant, ancestor) {
+ return isAncestor(ancestor, descendant);
+}
+
+/**
+ * Returns true if descendant is an inclusive descendant of ancestor, false
+ * otherwise.
+ */
+function isInclusiveDescendant(descendant, ancestor) {
+ return descendant === ancestor || isDescendant(descendant, ancestor);
+}
+
+/**
+ * The position of two boundary points relative to one another, as defined by
+ * the spec.
+ */
+function getPosition(nodeA, offsetA, nodeB, offsetB) {
+ // "If node A is the same as node B, return equal if offset A equals offset
+ // B, before if offset A is less than offset B, and after if offset A is
+ // greater than offset B."
+ if (nodeA == nodeB) {
+ if (offsetA == offsetB) {
+ return "equal";
+ }
+ if (offsetA < offsetB) {
+ return "before";
+ }
+ if (offsetA > offsetB) {
+ return "after";
+ }
+ }
+
+ // "If node A is after node B in tree order, compute the position of (node
+ // B, offset B) relative to (node A, offset A). If it is before, return
+ // after. If it is after, return before."
+ if (nodeB.compareDocumentPosition(nodeA) & Node.DOCUMENT_POSITION_FOLLOWING) {
+ var pos = getPosition(nodeB, offsetB, nodeA, offsetA);
+ if (pos == "before") {
+ return "after";
+ }
+ if (pos == "after") {
+ return "before";
+ }
+ }
+
+ // "If node A is an ancestor of node B:"
+ if (nodeB.compareDocumentPosition(nodeA) & Node.DOCUMENT_POSITION_CONTAINS) {
+ // "Let child equal node B."
+ var child = nodeB;
+
+ // "While child is not a child of node A, set child to its parent."
+ while (child.parentNode != nodeA) {
+ child = child.parentNode;
+ }
+
+ // "If the index of child is less than offset A, return after."
+ if (indexOf(child) < offsetA) {
+ return "after";
+ }
+ }
+
+ // "Return before."
+ return "before";
+}
+
+/**
+ * "contained" as defined by DOM Range: "A Node node is contained in a range
+ * range if node's furthest ancestor is the same as range's root, and (node, 0)
+ * is after range's start, and (node, length of node) is before range's end."
+ */
+function isContained(node, range) {
+ var pos1 = getPosition(node, 0, range.startContainer, range.startOffset);
+ var pos2 = getPosition(node, nodeLength(node), range.endContainer, range.endOffset);
+
+ return furthestAncestor(node) == furthestAncestor(range.startContainer)
+ && pos1 == "after"
+ && pos2 == "before";
+}
+
+/**
+ * "partially contained" as defined by DOM Range: "A Node is partially
+ * contained in a range if it is an ancestor container of the range's start but
+ * not its end, or vice versa."
+ */
+function isPartiallyContained(node, range) {
+ var cond1 = isAncestorContainer(node, range.startContainer);
+ var cond2 = isAncestorContainer(node, range.endContainer);
+ return (cond1 && !cond2) || (cond2 && !cond1);
+}
+
+/**
+ * Index of a node as defined by the spec.
+ */
+function indexOf(node) {
+ if (!node.parentNode) {
+ // No preceding sibling nodes, right?
+ return 0;
+ }
+ var i = 0;
+ while (node != node.parentNode.childNodes[i]) {
+ i++;
+ }
+ return i;
+}
+
+/**
+ * extractContents() implementation, following the spec. If an exception is
+ * supposed to be thrown, will return a string with the name (e.g.,
+ * "HIERARCHY_REQUEST_ERR") instead of a document fragment. It might also
+ * return an arbitrary human-readable string if a condition is hit that implies
+ * a spec bug.
+ */
+function myExtractContents(range) {
+ // "If the context object's detached flag is set, raise an
+ // INVALID_STATE_ERR exception and abort these steps."
+ try {
+ range.collapsed;
+ } catch (e) {
+ return "INVALID_STATE_ERR";
+ }
+
+ // "Let frag be a new DocumentFragment whose ownerDocument is the same as
+ // the ownerDocument of the context object's start node."
+ var ownerDoc = range.startContainer.nodeType == Node.DOCUMENT_NODE
+ ? range.startContainer
+ : range.startContainer.ownerDocument;
+ var frag = ownerDoc.createDocumentFragment();
+
+ // "If the context object's start and end are the same, abort this method,
+ // returning frag."
+ if (range.startContainer == range.endContainer
+ && range.startOffset == range.endOffset) {
+ return frag;
+ }
+
+ // "Let original start node, original start offset, original end node, and
+ // original end offset be the context object's start and end nodes and
+ // offsets, respectively."
+ var originalStartNode = range.startContainer;
+ var originalStartOffset = range.startOffset;
+ var originalEndNode = range.endContainer;
+ var originalEndOffset = range.endOffset;
+
+ // "If original start node and original end node are the same, and they are
+ // a Text or Comment node:"
+ if (range.startContainer == range.endContainer
+ && (range.startContainer.nodeType == Node.TEXT_NODE
+ || range.startContainer.nodeType == Node.COMMENT_NODE)) {
+ // "Let clone be the result of calling cloneNode(false) on original
+ // start node."
+ var clone = originalStartNode.cloneNode(false);
+
+ // "Set the data of clone to the result of calling
+ // substringData(original start offset, original end offset − original
+ // start offset) on original start node."
+ clone.data = originalStartNode.substringData(originalStartOffset,
+ originalEndOffset - originalStartOffset);
+
+ // "Append clone as the last child of frag."
+ frag.appendChild(clone);
+
+ // "Call deleteData(original start offset, original end offset −
+ // original start offset) on original start node."
+ originalStartNode.deleteData(originalStartOffset,
+ originalEndOffset - originalStartOffset);
+
+ // "Abort this method, returning frag."
+ return frag;
+ }
+
+ // "Let common ancestor equal original start node."
+ var commonAncestor = originalStartNode;
+
+ // "While common ancestor is not an ancestor container of original end
+ // node, set common ancestor to its own parent."
+ while (!isAncestorContainer(commonAncestor, originalEndNode)) {
+ commonAncestor = commonAncestor.parentNode;
+ }
+
+ // "If original start node is an ancestor container of original end node,
+ // let first partially contained child be null."
+ var firstPartiallyContainedChild;
+ if (isAncestorContainer(originalStartNode, originalEndNode)) {
+ firstPartiallyContainedChild = null;
+ // "Otherwise, let first partially contained child be the first child of
+ // common ancestor that is partially contained in the context object."
+ } else {
+ for (var i = 0; i < commonAncestor.childNodes.length; i++) {
+ if (isPartiallyContained(commonAncestor.childNodes[i], range)) {
+ firstPartiallyContainedChild = commonAncestor.childNodes[i];
+ break;
+ }
+ }
+ if (!firstPartiallyContainedChild) {
+ throw "Spec bug: no first partially contained child!";
+ }
+ }
+
+ // "If original end node is an ancestor container of original start node,
+ // let last partially contained child be null."
+ var lastPartiallyContainedChild;
+ if (isAncestorContainer(originalEndNode, originalStartNode)) {
+ lastPartiallyContainedChild = null;
+ // "Otherwise, let last partially contained child be the last child of
+ // common ancestor that is partially contained in the context object."
+ } else {
+ for (var i = commonAncestor.childNodes.length - 1; i >= 0; i--) {
+ if (isPartiallyContained(commonAncestor.childNodes[i], range)) {
+ lastPartiallyContainedChild = commonAncestor.childNodes[i];
+ break;
+ }
+ }
+ if (!lastPartiallyContainedChild) {
+ throw "Spec bug: no last partially contained child!";
+ }
+ }
+
+ // "Let contained children be a list of all children of common ancestor
+ // that are contained in the context object, in tree order."
+ //
+ // "If any member of contained children is a DocumentType, raise a
+ // HIERARCHY_REQUEST_ERR exception and abort these steps."
+ var containedChildren = [];
+ for (var i = 0; i < commonAncestor.childNodes.length; i++) {
+ if (isContained(commonAncestor.childNodes[i], range)) {
+ if (commonAncestor.childNodes[i].nodeType
+ == Node.DOCUMENT_TYPE_NODE) {
+ return "HIERARCHY_REQUEST_ERR";
+ }
+ containedChildren.push(commonAncestor.childNodes[i]);
+ }
+ }
+
+ // "If original start node is an ancestor container of original end node,
+ // set new node to original start node and new offset to original start
+ // offset."
+ var newNode, newOffset;
+ if (isAncestorContainer(originalStartNode, originalEndNode)) {
+ newNode = originalStartNode;
+ newOffset = originalStartOffset;
+ // "Otherwise:"
+ } else {
+ // "Let reference node equal original start node."
+ var referenceNode = originalStartNode;
+
+ // "While reference node's parent is not null and is not an ancestor
+ // container of original end node, set reference node to its parent."
+ while (referenceNode.parentNode
+ && !isAncestorContainer(referenceNode.parentNode, originalEndNode)) {
+ referenceNode = referenceNode.parentNode;
+ }
+
+ // "Set new node to the parent of reference node, and new offset to one
+ // plus the index of reference node."
+ newNode = referenceNode.parentNode;
+ newOffset = 1 + indexOf(referenceNode);
+ }
+
+ // "If first partially contained child is a Text or Comment node:"
+ if (firstPartiallyContainedChild
+ && (firstPartiallyContainedChild.nodeType == Node.TEXT_NODE
+ || firstPartiallyContainedChild.nodeType == Node.COMMENT_NODE)) {
+ // "Let clone be the result of calling cloneNode(false) on original
+ // start node."
+ var clone = originalStartNode.cloneNode(false);
+
+ // "Set the data of clone to the result of calling substringData() on
+ // original start node, with original start offset as the first
+ // argument and (length of original start node − original start offset)
+ // as the second."
+ clone.data = originalStartNode.substringData(originalStartOffset,
+ nodeLength(originalStartNode) - originalStartOffset);
+
+ // "Append clone as the last child of frag."
+ frag.appendChild(clone);
+
+ // "Call deleteData() on original start node, with original start
+ // offset as the first argument and (length of original start node −
+ // original start offset) as the second."
+ originalStartNode.deleteData(originalStartOffset,
+ nodeLength(originalStartNode) - originalStartOffset);
+ // "Otherwise, if first partially contained child is not null:"
+ } else if (firstPartiallyContainedChild) {
+ // "Let clone be the result of calling cloneNode(false) on first
+ // partially contained child."
+ var clone = firstPartiallyContainedChild.cloneNode(false);
+
+ // "Append clone as the last child of frag."
+ frag.appendChild(clone);
+
+ // "Let subrange be a new Range whose start is (original start node,
+ // original start offset) and whose end is (first partially contained
+ // child, length of first partially contained child)."
+ var subrange = ownerDoc.createRange();
+ subrange.setStart(originalStartNode, originalStartOffset);
+ subrange.setEnd(firstPartiallyContainedChild,
+ nodeLength(firstPartiallyContainedChild));
+
+ // "Let subfrag be the result of calling extractContents() on
+ // subrange."
+ var subfrag = myExtractContents(subrange);
+
+ // "For each child of subfrag, in order, append that child to clone as
+ // its last child."
+ for (var i = 0; i < subfrag.childNodes.length; i++) {
+ clone.appendChild(subfrag.childNodes[i]);
+ }
+ }
+
+ // "For each contained child in contained children, append contained child
+ // as the last child of frag."
+ for (var i = 0; i < containedChildren.length; i++) {
+ frag.appendChild(containedChildren[i]);
+ }
+
+ // "If last partially contained child is a Text or Comment node:"
+ if (lastPartiallyContainedChild
+ && (lastPartiallyContainedChild.nodeType == Node.TEXT_NODE
+ || lastPartiallyContainedChild.nodeType == Node.COMMENT_NODE)) {
+ // "Let clone be the result of calling cloneNode(false) on original
+ // end node."
+ var clone = originalEndNode.cloneNode(false);
+
+ // "Set the data of clone to the result of calling substringData(0,
+ // original end offset) on original end node."
+ clone.data = originalEndNode.substringData(0, originalEndOffset);
+
+ // "Append clone as the last child of frag."
+ frag.appendChild(clone);
+
+ // "Call deleteData(0, original end offset) on original end node."
+ originalEndNode.deleteData(0, originalEndOffset);
+ // "Otherwise, if last partially contained child is not null:"
+ } else if (lastPartiallyContainedChild) {
+ // "Let clone be the result of calling cloneNode(false) on last
+ // partially contained child."
+ var clone = lastPartiallyContainedChild.cloneNode(false);
+
+ // "Append clone as the last child of frag."
+ frag.appendChild(clone);
+
+ // "Let subrange be a new Range whose start is (last partially
+ // contained child, 0) and whose end is (original end node, original
+ // end offset)."
+ var subrange = ownerDoc.createRange();
+ subrange.setStart(lastPartiallyContainedChild, 0);
+ subrange.setEnd(originalEndNode, originalEndOffset);
+
+ // "Let subfrag be the result of calling extractContents() on
+ // subrange."
+ var subfrag = myExtractContents(subrange);
+
+ // "For each child of subfrag, in order, append that child to clone as
+ // its last child."
+ for (var i = 0; i < subfrag.childNodes.length; i++) {
+ clone.appendChild(subfrag.childNodes[i]);
+ }
+ }
+
+ // "Set the context object's start and end to (new node, new offset)."
+ range.setStart(newNode, newOffset);
+ range.setEnd(newNode, newOffset);
+
+ // "Return frag."
+ return frag;
+}
+
+/**
+ * insertNode() implementation, following the spec. If an exception is meant
+ * to be thrown, will return a string with the expected exception name, for
+ * instance "HIERARCHY_REQUEST_ERR".
+ */
+function myInsertNode(range, node) {
+ // "If range's start node is either a ProcessingInstruction or Comment
+ // node, or a Text node whose parent is null, throw an
+ // "HierarchyRequestError" exception and terminate these steps."
+ if (range.startContainer.nodeType == Node.PROCESSING_INSTRUCTION_NODE
+ || range.startContainer.nodeType == Node.COMMENT_NODE
+ || (range.startContainer.nodeType == Node.TEXT_NODE
+ && !range.startContainer.parentNode)) {
+ return "HIERARCHY_REQUEST_ERR";
+ }
+
+ // "Let referenceNode be null."
+ var referenceNode = null;
+
+ // "If range's start node is a Text node, set referenceNode to that Text node."
+ if (range.startContainer.nodeType == Node.TEXT_NODE) {
+ referenceNode = range.startContainer;
+
+ // "Otherwise, set referenceNode to the child of start node whose index is
+ // start offset, and null if there is no such child."
+ } else {
+ if (range.startOffset < range.startContainer.childNodes.length) {
+ referenceNode = range.startContainer.childNodes[range.startOffset];
+ } else {
+ referenceNode = null;
+ }
+ }
+
+ // "Let parent be range's start node if referenceNode is null, and
+ // referenceNode's parent otherwise."
+ var parent_ = referenceNode === null ? range.startContainer :
+ referenceNode.parentNode;
+
+ // "Ensure pre-insertion validity of node into parent before
+ // referenceNode."
+ var error = ensurePreInsertionValidity(node, parent_, referenceNode);
+ if (error) {
+ return error;
+ }
+
+ // "If range's start node is a Text node, set referenceNode to the result
+ // of splitting it with offset range's start offset."
+ if (range.startContainer.nodeType == Node.TEXT_NODE) {
+ referenceNode = range.startContainer.splitText(range.startOffset);
+ }
+
+ // "If node is referenceNode, set referenceNode to its next sibling."
+ if (node == referenceNode) {
+ referenceNode = referenceNode.nextSibling;
+ }
+
+ // "If node's parent is not null, remove node from its parent."
+ if (node.parentNode) {
+ node.parentNode.removeChild(node);
+ }
+
+ // "Let newOffset be parent's length if referenceNode is null, and
+ // referenceNode's index otherwise."
+ var newOffset = referenceNode === null ? nodeLength(parent_) :
+ indexOf(referenceNode);
+
+ // "Increase newOffset by node's length if node is a DocumentFragment node,
+ // and one otherwise."
+ newOffset += node.nodeType == Node.DOCUMENT_FRAGMENT_NODE ?
+ nodeLength(node) : 1;
+
+ // "Pre-insert node into parent before referenceNode."
+ parent_.insertBefore(node, referenceNode);
+
+ // "If range's start and end are the same, set range's end to (parent,
+ // newOffset)."
+ if (range.startContainer == range.endContainer
+ && range.startOffset == range.endOffset) {
+ range.setEnd(parent_, newOffset);
+ }
+}
+
+// To make filter() calls more readable
+function isElement(node) {
+ return node.nodeType == Node.ELEMENT_NODE;
+}
+
+function isText(node) {
+ return node.nodeType == Node.TEXT_NODE;
+}
+
+function isDoctype(node) {
+ return node.nodeType == Node.DOCUMENT_TYPE_NODE;
+}
+
+function ensurePreInsertionValidity(node, parent_, child) {
+ // "If parent is not a Document, DocumentFragment, or Element node, throw a
+ // HierarchyRequestError."
+ if (parent_.nodeType != Node.DOCUMENT_NODE
+ && parent_.nodeType != Node.DOCUMENT_FRAGMENT_NODE
+ && parent_.nodeType != Node.ELEMENT_NODE) {
+ return "HIERARCHY_REQUEST_ERR";
+ }
+
+ // "If node is a host-including inclusive ancestor of parent, throw a
+ // HierarchyRequestError."
+ //
+ // XXX Does not account for host
+ if (isInclusiveAncestor(node, parent_)) {
+ return "HIERARCHY_REQUEST_ERR";
+ }
+
+ // "If child is not null and its parent is not parent, throw a NotFoundError
+ // exception."
+ if (child && child.parentNode != parent_) {
+ return "NOT_FOUND_ERR";
+ }
+
+ // "If node is not a DocumentFragment, DocumentType, Element, Text,
+ // ProcessingInstruction, or Comment node, throw a HierarchyRequestError."
+ if (node.nodeType != Node.DOCUMENT_FRAGMENT_NODE
+ && node.nodeType != Node.DOCUMENT_TYPE_NODE
+ && node.nodeType != Node.ELEMENT_NODE
+ && node.nodeType != Node.TEXT_NODE
+ && node.nodeType != Node.PROCESSING_INSTRUCTION_NODE
+ && node.nodeType != Node.COMMENT_NODE) {
+ return "HIERARCHY_REQUEST_ERR";
+ }
+
+ // "If either node is a Text node and parent is a document, or node is a
+ // doctype and parent is not a document, throw a HierarchyRequestError."
+ if ((node.nodeType == Node.TEXT_NODE
+ && parent_.nodeType == Node.DOCUMENT_NODE)
+ || (node.nodeType == Node.DOCUMENT_TYPE_NODE
+ && parent_.nodeType != Node.DOCUMENT_NODE)) {
+ return "HIERARCHY_REQUEST_ERR";
+ }
+
+ // "If parent is a document, and any of the statements below, switched on
+ // node, are true, throw a HierarchyRequestError."
+ if (parent_.nodeType == Node.DOCUMENT_NODE) {
+ switch (node.nodeType) {
+ case Node.DOCUMENT_FRAGMENT_NODE:
+ // "If node has more than one element child or has a Text node
+ // child. Otherwise, if node has one element child and either
+ // parent has an element child, child is a doctype, or child is not
+ // null and a doctype is following child."
+ if ([].filter.call(node.childNodes, isElement).length > 1) {
+ return "HIERARCHY_REQUEST_ERR";
+ }
+
+ if ([].some.call(node.childNodes, isText)) {
+ return "HIERARCHY_REQUEST_ERR";
+ }
+
+ if ([].filter.call(node.childNodes, isElement).length == 1) {
+ if ([].some.call(parent_.childNodes, isElement)) {
+ return "HIERARCHY_REQUEST_ERR";
+ }
+
+ if (child && child.nodeType == Node.DOCUMENT_TYPE_NODE) {
+ return "HIERARCHY_REQUEST_ERR";
+ }
+
+ if (child && [].slice.call(parent_.childNodes, indexOf(child) + 1)
+ .filter(isDoctype)) {
+ return "HIERARCHY_REQUEST_ERR";
+ }
+ }
+ break;
+
+ case Node.ELEMENT_NODE:
+ // "parent has an element child, child is a doctype, or child is
+ // not null and a doctype is following child."
+ if ([].some.call(parent_.childNodes, isElement)) {
+ return "HIERARCHY_REQUEST_ERR";
+ }
+
+ if (child.nodeType == Node.DOCUMENT_TYPE_NODE) {
+ return "HIERARCHY_REQUEST_ERR";
+ }
+
+ if (child && [].slice.call(parent_.childNodes, indexOf(child) + 1)
+ .filter(isDoctype)) {
+ return "HIERARCHY_REQUEST_ERR";
+ }
+ break;
+
+ case Node.DOCUMENT_TYPE_NODE:
+ // "parent has a doctype child, an element is preceding child, or
+ // child is null and parent has an element child."
+ if ([].some.call(parent_.childNodes, isDoctype)) {
+ return "HIERARCHY_REQUEST_ERR";
+ }
+
+ if (child && [].slice.call(parent_.childNodes, 0, indexOf(child))
+ .some(isElement)) {
+ return "HIERARCHY_REQUEST_ERR";
+ }
+
+ if (!child && [].some.call(parent_.childNodes, isElement)) {
+ return "HIERARCHY_REQUEST_ERR";
+ }
+ break;
+ }
+ }
+}
+
+/**
+ * Asserts that two nodes are equal, in the sense of isEqualNode(). If they
+ * aren't, tries to print a relatively informative reason why not. TODO: Move
+ * this to testharness.js?
+ */
+function assertNodesEqual(actual, expected, msg) {
+ if (!actual.isEqualNode(expected)) {
+ msg = "Actual and expected mismatch for " + msg + ". ";
+
+ while (actual && expected) {
+ assert_true(actual.nodeType === expected.nodeType
+ && actual.nodeName === expected.nodeName
+ && actual.nodeValue === expected.nodeValue
+ && actual.childNodes.length === expected.childNodes.length,
+ "First differing node: expected " + format_value(expected)
+ + ", got " + format_value(actual));
+ actual = nextNode(actual);
+ expected = nextNode(expected);
+ }
+
+ assert_unreached("DOMs were not equal but we couldn't figure out why");
+ }
+}
+
+/**
+ * Given a DOMException, return the name (e.g., "HIERARCHY_REQUEST_ERR").
+ */
+function getDomExceptionName(e) {
+ var ret = null;
+ for (var prop in e) {
+ if (/^[A-Z_]+_ERR$/.test(prop) && e[prop] == e.code) {
+ return prop;
+ }
+ }
+
+ throw "Exception seems to not be a DOMException? " + e;
+}
+
+/**
+ * Given an array of endpoint data [start container, start offset, end
+ * container, end offset], returns a Range with those endpoints.
+ */
+function rangeFromEndpoints(endpoints) {
+ // If we just use document instead of the ownerDocument of endpoints[0],
+ // WebKit will throw on setStart/setEnd. This is a WebKit bug, but it's in
+ // range, not selection, so we don't want to fail anything for it.
+ var range = ownerDocument(endpoints[0]).createRange();
+ range.setStart(endpoints[0], endpoints[1]);
+ range.setEnd(endpoints[2], endpoints[3]);
+ return range;
+}
diff --git a/dom/imptests/html/dom/test_interface-objects.html b/dom/imptests/html/dom/test_interface-objects.html
new file mode 100644
index 000000000..0e2bf1acd
--- /dev/null
+++ b/dom/imptests/html/dom/test_interface-objects.html
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<title>Interfaces</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<script>
+function testInterfaceDeletable(iface) {
+ test(function() {
+ assert_true(!!window[iface], "Interface should exist.")
+ assert_true(delete window[iface], "The delete operator should return true.")
+ assert_equals(window[iface], undefined, "Interface should be gone.")
+ }, "Should be able to delete " + iface + ".")
+}
+var interfaces = [
+ "Event",
+ "CustomEvent",
+ "EventTarget",
+ "Node",
+ "Document",
+ "DOMImplementation",
+ "DocumentFragment",
+ "ProcessingInstruction",
+ "DocumentType",
+ "Element",
+ "Attr",
+ "CharacterData",
+ "Text",
+ "Comment",
+ "NodeIterator",
+ "TreeWalker",
+ "NodeFilter",
+ "NodeList",
+ "HTMLCollection",
+ "DOMStringList",
+ "DOMTokenList",
+ ];
+test(function() {
+ for (var p in window) {
+ interfaces.forEach(function(i) {
+ assert_not_equals(p, i)
+ })
+ }
+}, "Interface objects properties should not be Enumerable")
+interfaces.forEach(testInterfaceDeletable);
+</script>
diff --git a/dom/imptests/html/dom/test_interfaces.html b/dom/imptests/html/dom/test_interfaces.html
new file mode 100644
index 000000000..9299ec8b7
--- /dev/null
+++ b/dom/imptests/html/dom/test_interfaces.html
@@ -0,0 +1,455 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>DOM IDL tests</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script src=/resources/WebIDLParser.js></script>
+<script src=/resources/idlharness.js></script>
+
+<h1>DOM IDL tests</h1>
+<div id=log></div>
+
+<script type=text/plain>
+[Constructor(DOMString name)]
+interface DOMError {
+ readonly attribute DOMString name;
+};
+
+[Constructor(DOMString type, optional EventInit eventInitDict)]
+interface Event {
+ readonly attribute DOMString type;
+ readonly attribute EventTarget? target;
+ readonly attribute EventTarget? currentTarget;
+
+ const unsigned short NONE = 0;
+ const unsigned short CAPTURING_PHASE = 1;
+ const unsigned short AT_TARGET = 2;
+ const unsigned short BUBBLING_PHASE = 3;
+ readonly attribute unsigned short eventPhase;
+
+ void stopPropagation();
+ void stopImmediatePropagation();
+
+ readonly attribute boolean bubbles;
+ readonly attribute boolean cancelable;
+ void preventDefault();
+ readonly attribute boolean defaultPrevented;
+
+ [Unforgeable] readonly attribute boolean isTrusted;
+ readonly attribute /* DOMTimeStamp */ unsigned long long timeStamp;
+
+ void initEvent(DOMString type, boolean bubbles, boolean cancelable);
+};
+
+dictionary EventInit {
+ boolean bubbles = false;
+ boolean cancelable = false;
+};
+
+[Constructor(DOMString type, optional CustomEventInit eventInitDict)]
+interface CustomEvent : Event {
+ readonly attribute any detail;
+
+ void initCustomEvent(DOMString type, boolean bubbles, boolean cancelable, any details);
+};
+
+dictionary CustomEventInit : EventInit {
+ any detail = null;
+};
+
+interface EventTarget {
+ void addEventListener(DOMString type, EventListener? callback, optional boolean capture);
+ void removeEventListener(DOMString type, EventListener? callback, optional boolean capture);
+ boolean dispatchEvent(Event event);
+};
+
+[Callback]
+interface EventListener {
+ void handleEvent(Event event);
+};
+
+[NoInterfaceObject]
+interface ParentNode {
+ readonly attribute HTMLCollection children;
+ readonly attribute Element? firstElementChild;
+ readonly attribute Element? lastElementChild;
+ readonly attribute unsigned long childElementCount;
+
+ void prepend((Node or DOMString)... nodes);
+ void append((Node or DOMString)... nodes);
+};
+Document implements ParentNode;
+DocumentFragment implements ParentNode;
+Element implements ParentNode;
+
+[NoInterfaceObject]
+interface ChildNode {
+ void before((Node or DOMString)... nodes);
+ void after((Node or DOMString)... nodes);
+ void replace((Node or DOMString)... nodes);
+ void remove();
+};
+DocumentType implements ChildNode;
+Element implements ChildNode;
+CharacterData implements ChildNode;
+
+[NoInterfaceObject]
+interface NonDocumentTypeChildNode {
+ readonly attribute Element? previousElementSibling;
+ readonly attribute Element? nextElementSibling;
+};
+Element implements NonDocumentTypeChildNode;
+CharacterData implements NonDocumentTypeChildNode;
+
+[Constructor(MutationCallback callback)]
+interface MutationObserver {
+ void observe(Node target, MutationObserverInit options);
+ void disconnect();
+ sequence<MutationRecord> takeRecords();
+};
+
+callback MutationCallback = void (sequence<MutationRecord> mutations, MutationObserver observer);
+
+dictionary MutationObserverInit {
+ boolean childList = false;
+ boolean attributes = false;
+ boolean characterData = false;
+ boolean subtree = false;
+ boolean attributeOldValue = false;
+ boolean characterDataOldValue = false;
+ sequence<DOMString> attributeFilter;
+};
+
+interface MutationRecord {
+ readonly attribute DOMString type;
+ readonly attribute Node target;
+ readonly attribute NodeList addedNodes;
+ readonly attribute NodeList removedNodes;
+ readonly attribute Node? previousSibling;
+ readonly attribute Node? nextSibling;
+ readonly attribute DOMString? attributeName;
+ readonly attribute DOMString? attributeNamespace;
+ readonly attribute DOMString? oldValue;
+};
+
+interface Node : EventTarget {
+ const unsigned short ELEMENT_NODE = 1;
+ const unsigned short ATTRIBUTE_NODE = 2; // historical
+ const unsigned short TEXT_NODE = 3;
+ const unsigned short CDATA_SECTION_NODE = 4; // historical
+ const unsigned short ENTITY_REFERENCE_NODE = 5; // historical
+ const unsigned short ENTITY_NODE = 6; // historical
+ const unsigned short PROCESSING_INSTRUCTION_NODE = 7;
+ const unsigned short COMMENT_NODE = 8;
+ const unsigned short DOCUMENT_NODE = 9;
+ const unsigned short DOCUMENT_TYPE_NODE = 10;
+ const unsigned short DOCUMENT_FRAGMENT_NODE = 11;
+ const unsigned short NOTATION_NODE = 12; // historical
+ readonly attribute unsigned short nodeType;
+ readonly attribute DOMString nodeName;
+
+ readonly attribute DOMString? baseURI;
+
+ readonly attribute Document? ownerDocument;
+ readonly attribute Node? parentNode;
+ readonly attribute Element? parentElement;
+ boolean hasChildNodes();
+ readonly attribute NodeList childNodes;
+ readonly attribute Node? firstChild;
+ readonly attribute Node? lastChild;
+ readonly attribute Node? previousSibling;
+ readonly attribute Node? nextSibling;
+
+ attribute DOMString? nodeValue;
+ attribute DOMString? textContent;
+ void normalize();
+
+ Node cloneNode(optional boolean deep);
+ boolean isEqualNode(Node? node);
+
+ const unsigned short DOCUMENT_POSITION_DISCONNECTED = 0x01;
+ const unsigned short DOCUMENT_POSITION_PRECEDING = 0x02;
+ const unsigned short DOCUMENT_POSITION_FOLLOWING = 0x04;
+ const unsigned short DOCUMENT_POSITION_CONTAINS = 0x08;
+ const unsigned short DOCUMENT_POSITION_CONTAINED_BY = 0x10;
+ const unsigned short DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC = 0x20;
+ unsigned short compareDocumentPosition(Node other);
+ boolean contains(Node? other);
+
+ DOMString? lookupPrefix(DOMString? namespace);
+ DOMString? lookupNamespaceURI(DOMString? prefix);
+ boolean isDefaultNamespace(DOMString? namespace);
+
+ Node insertBefore(Node node, Node? child);
+ Node appendChild(Node node);
+ Node replaceChild(Node node, Node child);
+ Node removeChild(Node child);
+};
+
+[Constructor]
+interface Document : Node {
+ readonly attribute DOMImplementation implementation;
+ readonly attribute DOMString URL;
+ readonly attribute DOMString documentURI;
+ readonly attribute DOMString compatMode;
+ readonly attribute DOMString characterSet;
+ readonly attribute DOMString contentType;
+
+ readonly attribute DocumentType? doctype;
+ readonly attribute Element? documentElement;
+ HTMLCollection getElementsByTagName(DOMString localName);
+ HTMLCollection getElementsByTagNameNS(DOMString? namespace, DOMString localName);
+ HTMLCollection getElementsByClassName(DOMString classNames);
+ Element? getElementById(DOMString elementId);
+
+ Element createElement(DOMString localName);
+ Element createElementNS(DOMString? namespace, DOMString qualifiedName);
+ DocumentFragment createDocumentFragment();
+ Text createTextNode(DOMString data);
+ Comment createComment(DOMString data);
+ ProcessingInstruction createProcessingInstruction(DOMString target, DOMString data);
+
+ Node importNode(Node node, optional boolean deep);
+ Node adoptNode(Node node);
+
+ Event createEvent(DOMString interface);
+
+ Range createRange();
+
+ // NodeFilter.SHOW_ALL = 0xFFFFFFFF
+ NodeIterator createNodeIterator(Node root, optional unsigned long whatToShow, optional NodeFilter? filter);
+ TreeWalker createTreeWalker(Node root, optional unsigned long whatToShow, optional NodeFilter? filter);
+};
+
+interface XMLDocument : Document {};
+
+interface DOMImplementation {
+ DocumentType createDocumentType(DOMString qualifiedName, DOMString publicId, DOMString systemId);
+ XMLDocument createDocument(DOMString? namespace, [TreatNullAs=EmptyString] DOMString qualifiedName, optional DocumentType? doctype = null);
+ Document createHTMLDocument(optional DOMString title);
+
+ boolean hasFeature(DOMString feature, [TreatNullAs=EmptyString] DOMString version);
+};
+
+[Constructor]
+interface DocumentFragment : Node {
+};
+
+interface DocumentType : Node {
+ readonly attribute DOMString name;
+ readonly attribute DOMString publicId;
+ readonly attribute DOMString systemId;
+};
+
+interface Element : Node {
+ readonly attribute DOMString? namespaceURI;
+ readonly attribute DOMString? prefix;
+ readonly attribute DOMString localName;
+ readonly attribute DOMString tagName;
+
+ attribute DOMString id;
+ attribute DOMString className;
+ [PutForwards=value]
+ readonly attribute DOMTokenList classList;
+
+ readonly attribute Attr[] attributes;
+ DOMString? getAttribute(DOMString name);
+ DOMString? getAttributeNS(DOMString? namespace, DOMString localName);
+ void setAttribute(DOMString name, DOMString value);
+ void setAttributeNS(DOMString? namespace, DOMString name, DOMString value);
+ void removeAttribute(DOMString name);
+ void removeAttributeNS(DOMString? namespace, DOMString localName);
+ boolean hasAttribute(DOMString name);
+ boolean hasAttributeNS(DOMString? namespace, DOMString localName);
+
+ HTMLCollection getElementsByTagName(DOMString localName);
+ HTMLCollection getElementsByTagNameNS(DOMString? namespace, DOMString localName);
+ HTMLCollection getElementsByClassName(DOMString classNames);
+};
+
+interface Attr {
+ readonly attribute DOMString localName;
+ attribute DOMString value;
+
+ readonly attribute DOMString name;
+ readonly attribute DOMString? namespaceURI;
+ readonly attribute DOMString? prefix;
+};
+
+interface CharacterData : Node {
+ [TreatNullAs=EmptyString] attribute DOMString data;
+ readonly attribute unsigned long length;
+ DOMString substringData(unsigned long offset, unsigned long count);
+ void appendData(DOMString data);
+ void insertData(unsigned long offset, DOMString data);
+ void deleteData(unsigned long offset, unsigned long count);
+ void replaceData(unsigned long offset, unsigned long count, DOMString data);
+};
+
+[Constructor(optional DOMString data)]
+interface Text : CharacterData {
+ Text splitText(unsigned long offset);
+ readonly attribute DOMString wholeText;
+};
+
+interface ProcessingInstruction : CharacterData {
+ readonly attribute DOMString target;
+};
+
+[Constructor(optional DOMString data)]
+interface Comment : CharacterData {
+};
+
+[Constructor]
+interface Range {
+ readonly attribute Node startContainer;
+ readonly attribute unsigned long startOffset;
+ readonly attribute Node endContainer;
+ readonly attribute unsigned long endOffset;
+ readonly attribute boolean collapsed;
+ readonly attribute Node commonAncestorContainer;
+
+ void setStart(Node refNode, unsigned long offset);
+ void setEnd(Node refNode, unsigned long offset);
+ void setStartBefore(Node refNode);
+ void setStartAfter(Node refNode);
+ void setEndBefore(Node refNode);
+ void setEndAfter(Node refNode);
+ void collapse(optional boolean toStart = false);
+ void selectNode(Node refNode);
+ void selectNodeContents(Node refNode);
+
+ const unsigned short START_TO_START = 0;
+ const unsigned short START_TO_END = 1;
+ const unsigned short END_TO_END = 2;
+ const unsigned short END_TO_START = 3;
+ short compareBoundaryPoints(unsigned short how, Range sourceRange);
+
+ void deleteContents();
+ DocumentFragment extractContents();
+ DocumentFragment cloneContents();
+ void insertNode(Node node);
+ void surroundContents(Node newParent);
+
+ Range cloneRange();
+ void detach();
+
+ boolean isPointInRange(Node node, unsigned long offset);
+ short comparePoint(Node node, unsigned long offset);
+
+ boolean intersectsNode(Node node);
+
+ stringifier;
+};
+
+interface NodeIterator {
+ readonly attribute Node root;
+ readonly attribute Node? referenceNode;
+ readonly attribute boolean pointerBeforeReferenceNode;
+ readonly attribute unsigned long whatToShow;
+ readonly attribute NodeFilter? filter;
+
+ Node? nextNode();
+ Node? previousNode();
+
+ void detach();
+};
+
+interface TreeWalker {
+ readonly attribute Node root;
+ readonly attribute unsigned long whatToShow;
+ readonly attribute NodeFilter? filter;
+ attribute Node currentNode;
+
+ Node? parentNode();
+ Node? firstChild();
+ Node? lastChild();
+ Node? previousSibling();
+ Node? nextSibling();
+ Node? previousNode();
+ Node? nextNode();
+};
+
+[Callback]
+interface NodeFilter {
+ // Constants for acceptNode()
+ const unsigned short FILTER_ACCEPT = 1;
+ const unsigned short FILTER_REJECT = 2;
+ const unsigned short FILTER_SKIP = 3;
+
+ // Constants for whatToShow
+ const unsigned long SHOW_ALL = 0xFFFFFFFF;
+ const unsigned long SHOW_ELEMENT = 0x1;
+ const unsigned long SHOW_ATTRIBUTE = 0x2; // historical
+ const unsigned long SHOW_TEXT = 0x4;
+ const unsigned long SHOW_CDATA_SECTION = 0x8; // historical
+ const unsigned long SHOW_ENTITY_REFERENCE = 0x10; // historical
+ const unsigned long SHOW_ENTITY = 0x20; // historical
+ const unsigned long SHOW_PROCESSING_INSTRUCTION = 0x40;
+ const unsigned long SHOW_COMMENT = 0x80;
+ const unsigned long SHOW_DOCUMENT = 0x100;
+ const unsigned long SHOW_DOCUMENT_TYPE = 0x200;
+ const unsigned long SHOW_DOCUMENT_FRAGMENT = 0x400;
+ const unsigned long SHOW_NOTATION = 0x800; // historical
+
+ unsigned short acceptNode(Node node);
+};
+
+[ArrayClass]
+interface NodeList {
+ getter Node? item(unsigned long index);
+ readonly attribute unsigned long length;
+};
+
+interface HTMLCollection {
+ readonly attribute unsigned long length;
+ getter Element? item(unsigned long index);
+ getter object? namedItem(DOMString name); // only returns Element
+};
+
+interface DOMTokenList {
+ readonly attribute unsigned long length;
+ getter DOMString? item(unsigned long index);
+ boolean contains(DOMString token);
+ void add(DOMString... tokens);
+ void remove(DOMString... tokens);
+ boolean toggle(DOMString token, optional boolean force);
+ stringifier;
+ attribute DOMString value;
+};
+</script>
+<script>
+"use strict";
+var xmlDoc, detachedRange, element;
+var idlArray;
+setup(function() {
+ xmlDoc = document.implementation.createDocument(null, "", null);
+ detachedRange = document.createRange();
+ detachedRange.detach();
+ element = xmlDoc.createElementNS(null, "test");
+ element.setAttribute("bar", "baz");
+
+ idlArray = new IdlArray();
+ idlArray.add_idls(document.querySelector("script[type=text\\/plain]").textContent);
+ idlArray.add_objects({
+ Event: ['document.createEvent("Event")', 'new Event("foo")'],
+ CustomEvent: ['new CustomEvent("foo")'],
+ XMLDocument: ['xmlDoc'],
+ DOMImplementation: ['document.implementation'],
+ DocumentFragment: ['document.createDocumentFragment()'],
+ DocumentType: ['document.doctype'],
+ Element: ['element'],
+ Attr: ['document.querySelector("[id]").attributes[0]'],
+ Text: ['document.createTextNode("abc")'],
+ ProcessingInstruction: ['xmlDoc.createProcessingInstruction("abc", "def")'],
+ Comment: ['document.createComment("abc")'],
+ Range: ['document.createRange()', 'detachedRange'],
+ NodeIterator: ['document.createNodeIterator(document.body, NodeFilter.SHOW_ALL, null, false)'],
+ TreeWalker: ['document.createTreeWalker(document.body, NodeFilter.SHOW_ALL, null, false)'],
+ NodeList: ['document.querySelectorAll("script")'],
+ HTMLCollection: ['document.body.children'],
+ DOMTokenList: ['document.body.classList'],
+ });
+});
+idlArray.test();
+</script>
diff --git a/dom/imptests/html/html/browsers/the-window-object/test_window-named-properties.html b/dom/imptests/html/html/browsers/the-window-object/test_window-named-properties.html
new file mode 100644
index 000000000..b01e24da9
--- /dev/null
+++ b/dom/imptests/html/html/browsers/the-window-object/test_window-named-properties.html
@@ -0,0 +1,69 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Changes to named properties of the window object</title>
+<link rel="author" title="Ms2ger" href="ms2ger@gmail.com">
+<link rel="author" title="Boris Zbarsky" href="bzbarsky@mit.edu">
+<link rel="help" href="http://www.whatwg.org/html/#window">
+<link rel="help" href="http://www.whatwg.org/html/#dom-window-nameditem">
+<link rel="help" href="http://dev.w3.org/2006/webapi/WebIDL/#named-properties-object">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<iframe name="bar"></iframe>
+<iframe name="constructor"></iframe>
+<script>
+function assert_data_propdesc(pd, Writable, Enumerable, Configurable) {
+ assert_equals(typeof pd, "object");
+ assert_equals(pd.writable, Writable);
+ assert_equals(pd.enumerable, Enumerable);
+ assert_equals(pd.configurable, Configurable);
+}
+test(function() {
+ assert_true("bar" in window, "bar not in window");
+ assert_equals(window["bar"],
+ document.getElementsByTagName("iframe")[0].contentWindow);
+}, "Static name");
+test(function() {
+ assert_true("bar" in Window.prototype, "bar in Window.prototype");
+ assert_false(Window.prototype.hasOwnProperty("bar"), "Window.prototype.hasOwnProperty(\"bar\")");
+
+ var gsp = Object.getPrototypeOf(Object.getPrototypeOf(window));
+ assert_true("bar" in gsp, "bar in gsp");
+ assert_true(gsp.hasOwnProperty("bar"), "gsp.hasOwnProperty(\"bar\")");
+ assert_data_propdesc(Object.getOwnPropertyDescriptor(gsp, "bar"),
+ true, false, true);
+}, "Static name on the prototype");
+test(function() {
+ assert_equals(window.constructor, Window);
+ assert_false(window.hasOwnProperty("constructor"), "window.constructor should not be an own property.");
+
+ var proto = Object.getPrototypeOf(window);
+ assert_equals(proto.constructor, Window);
+ assert_true("constructor" in proto, "constructor in proto");
+ assert_data_propdesc(Object.getOwnPropertyDescriptor(proto, "constructor"),
+ true, false, true);
+
+ var gsp = Object.getPrototypeOf(proto);
+ assert_true("constructor" in gsp, "constructor in gsp");
+ assert_false(gsp.hasOwnProperty("constructor"), "gsp.hasOwnProperty(\"constructor\")");
+ assert_equals(Object.getOwnPropertyDescriptor(gsp, "constructor"), undefined)
+}, "constructor");
+var t = async_test("Dynamic name")
+var t2 = async_test("Ghost name")
+t.step(function() {
+ var iframe = document.getElementsByTagName("iframe")[0];
+ iframe.setAttribute("src", "data:text/html,<script>window.name='foo'<\/script>");
+ iframe.onload = function() {
+ t.step(function() {
+ assert_true("foo" in window, "foo not in window");
+ assert_equals(window["foo"], iframe.contentWindow);
+ });
+ t.done();
+ t2.step(function() {
+ assert_false("bar" in window, "bar still in window");
+ assert_equals(window["bar"], undefined);
+ });
+ t2.done();
+ };
+});
+</script>
diff --git a/dom/imptests/html/html/dom/documents/dta/test_nameditem-06.html b/dom/imptests/html/html/dom/documents/dta/test_nameditem-06.html
new file mode 100644
index 000000000..3fd3d474a
--- /dev/null
+++ b/dom/imptests/html/html/dom/documents/dta/test_nameditem-06.html
@@ -0,0 +1,104 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Named items: imgs</title>
+<link rel="author" title="Ms2ger" href="mailto:ms2ger@gmail.com">
+<link rel="help" href="http://www.whatwg.org/html/#dom-document-nameditem">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<div id="test">
+<img name=test1>
+
+<img name=test2>
+<img name=test2>
+
+<img id=test3>
+
+<img id=test4>
+<img id=test4>
+
+<img name=test5>
+<img id=test5>
+
+<img id=test6>
+<img name=test6>
+
+<img id=test7 name=fail>
+
+<img name=test8 id=fail>
+</div>
+<script>
+test(function() {
+ var img = document.getElementsByTagName("img")[0];
+ assert_equals(img.name, "test1");
+
+ assert_true("test1" in document, '"test1" in document should be true');
+ assert_equals(document.test1, img);
+}, "If there is one img, it should be returned (name)");
+
+test(function() {
+ var img1 = document.getElementsByTagName("img")[1];
+ assert_equals(img1.name, "test2");
+ var img2 = document.getElementsByTagName("img")[2];
+ assert_equals(img2.name, "test2");
+
+ assert_true("test2" in document, '"test2" in document should be true');
+ var collection = document.test2;
+ assert_class_string(collection, "HTMLCollection", "collection should be an HTMLCollection");
+ assert_array_equals(collection, [img1, img2]);
+}, "If there are two imgs, a collection should be returned. (name)");
+
+test(function() {
+ var img = document.getElementsByTagName("img")[3];
+ assert_equals(img.id, "test3");
+
+ assert_false("test3" in document, '"test3" in document should be false');
+ assert_equals(document.test3, undefined);
+}, "If there is one img, it should not be returned (id)");
+
+test(function() {
+ var img1 = document.getElementsByTagName("img")[4];
+ assert_equals(img1.id, "test4");
+ var img2 = document.getElementsByTagName("img")[5];
+ assert_equals(img2.id, "test4");
+
+ assert_false("test4" in document, '"test4" in document should be false');
+ assert_equals(document.test4, undefined);
+}, "If there are two imgs, nothing should be returned. (id)");
+
+test(function() {
+ var img1 = document.getElementsByTagName("img")[6];
+ assert_equals(img1.name, "test5");
+ var img2 = document.getElementsByTagName("img")[7];
+ assert_equals(img2.id, "test5");
+
+ assert_true("test5" in document, '"test5" in document should be true');
+ assert_equals(document.test5, img1);
+}, "If there are two imgs, the one with a name should be returned. (name and id)");
+
+test(function() {
+ var img1 = document.getElementsByTagName("img")[8];
+ assert_equals(img1.id, "test6");
+ var img2 = document.getElementsByTagName("img")[9];
+ assert_equals(img2.name, "test6");
+
+ assert_true("test6" in document, '"test6" in document should be true');
+ assert_equals(document.test6, img2);
+}, "If there are two imgs, the one with a name should be returned. (id and name)");
+
+test(function() {
+ var img = document.getElementsByTagName("img")[10];
+ assert_equals(img.id, "test7");
+
+ assert_true("test7" in document, '"test7" in document should be true');
+ assert_equals(document.test7, img);
+}, "A name should affect getting an img by id");
+
+test(function() {
+ var img = document.getElementsByTagName("img")[11];
+ assert_equals(img.name, "test8");
+
+ assert_true("test8" in document, '"test8" in document should be true');
+ assert_equals(document.test8, img);
+}, "An id shouldn't affect getting an img by name");
+</script>
diff --git a/dom/imptests/html/html/dom/elements/global-attributes/reftest-stylo.list b/dom/imptests/html/html/dom/elements/global-attributes/reftest-stylo.list
new file mode 100644
index 000000000..4e76b8532
--- /dev/null
+++ b/dom/imptests/html/html/dom/elements/global-attributes/reftest-stylo.list
@@ -0,0 +1,59 @@
+# DO NOT EDIT! This is a auto-generated temporary list for Stylo testing
+# THIS FILE IS AUTOGENERATED BY importTestsuite.py - DO NOT EDIT
+
+== dir_auto-contained-bdi-L.html dir_auto-contained-bdi-L.html
+== dir_auto-contained-bdi-R.html dir_auto-contained-bdi-R.html
+== dir_auto-contained-dir_auto-L.html dir_auto-contained-dir_auto-L.html
+== dir_auto-contained-dir_auto-R.html dir_auto-contained-dir_auto-R.html
+== dir_auto-contained-dir-L.html dir_auto-contained-dir-L.html
+== dir_auto-contained-dir-R.html dir_auto-contained-dir-R.html
+== dir_auto-contained-L.html dir_auto-contained-L.html
+== dir_auto-contained-R.html dir_auto-contained-R.html
+== dir_auto-contained-script-L.html dir_auto-contained-script-L.html
+== dir_auto-contained-script-R.html dir_auto-contained-script-R.html
+== dir_auto-contained-style-L.html dir_auto-contained-style-L.html
+== dir_auto-contained-style-R.html dir_auto-contained-style-R.html
+== dir_auto-contained-textarea-L.html dir_auto-contained-textarea-L.html
+== dir_auto-contained-textarea-R.html dir_auto-contained-textarea-R.html
+== dir_auto-EN-L.html dir_auto-EN-L.html
+== dir_auto-EN-R.html dir_auto-EN-R.html
+== dir_auto-input-EN-L.html dir_auto-input-EN-L.html
+== dir_auto-input-EN-R.html dir_auto-input-EN-R.html
+== dir_auto-input-L.html dir_auto-input-L.html
+== dir_auto-input-N-EN.html dir_auto-input-N-EN.html
+== dir_auto-input-N-EN-L.html dir_auto-input-N-EN-L.html
+== dir_auto-input-N-EN-R.html dir_auto-input-N-EN-R.html
+== dir_auto-input-N-L.html dir_auto-input-N-L.html
+== dir_auto-input-N-R.html dir_auto-input-N-R.html
+== dir_auto-input-R.html dir_auto-input-R.html
+== dir_auto-input-script-EN-L.html dir_auto-input-script-EN-L.html
+== dir_auto-input-script-EN-R.html dir_auto-input-script-EN-R.html
+== dir_auto-input-script-L.html dir_auto-input-script-L.html
+== dir_auto-input-script-N-EN.html dir_auto-input-script-N-EN.html
+== dir_auto-input-script-N-EN-L.html dir_auto-input-script-N-EN-L.html
+== dir_auto-input-script-N-EN-R.html dir_auto-input-script-N-EN-R.html
+== dir_auto-input-script-N-L.html dir_auto-input-script-N-L.html
+== dir_auto-input-script-N-R.html dir_auto-input-script-N-R.html
+== dir_auto-input-script-R.html dir_auto-input-script-R.html
+== dir_auto-isolate.html dir_auto-isolate.html
+== dir_auto-L.html dir_auto-L.html
+== dir_auto-N-EN.html dir_auto-N-EN.html
+== dir_auto-N-EN-L.html dir_auto-N-EN-L.html
+== dir_auto-N-EN-R.html dir_auto-N-EN-R.html
+== dir_auto-N-L.html dir_auto-N-L.html
+== dir_auto-N-R.html dir_auto-N-R.html
+== dir_auto-pre-mixed.html dir_auto-pre-mixed.html
+== dir_auto-pre-N-between-Rs.html dir_auto-pre-N-between-Rs.html
+== dir_auto-pre-N-EN.html dir_auto-pre-N-EN.html
+== dir_auto-R.html dir_auto-R.html
+== dir_auto-textarea-mixed.html dir_auto-textarea-mixed.html
+fails-if(B2G||Mulet||(Android&&asyncPan)) == dir_auto-textarea-N-between-Rs.html dir_auto-textarea-N-between-Rs.html
+# B2G scrollbar on opposite side
+== dir_auto-textarea-N-EN.html dir_auto-textarea-N-EN.html
+== dir_auto-textarea-script-mixed.html dir_auto-textarea-script-mixed.html
+fails-if(B2G||Mulet||(Android&&asyncPan)) == dir_auto-textarea-script-N-between-Rs.html dir_auto-textarea-script-N-between-Rs.html
+# B2G scrollbar on reference only
+== dir_auto-textarea-script-N-EN.html dir_auto-textarea-script-N-EN.html
+== lang-xyzzy.html lang-xyzzy.html
+== lang-xmllang-01.html lang-xmllang-01.html
+== style-01.html style-01.html
diff --git a/dom/imptests/html/html/dom/elements/global-attributes/reftest.list b/dom/imptests/html/html/dom/elements/global-attributes/reftest.list
new file mode 100644
index 000000000..a58929e92
--- /dev/null
+++ b/dom/imptests/html/html/dom/elements/global-attributes/reftest.list
@@ -0,0 +1,56 @@
+# THIS FILE IS AUTOGENERATED BY importTestsuite.py - DO NOT EDIT
+
+== dir_auto-contained-bdi-L.html dir_auto-contained-bdi-L-ref.html
+== dir_auto-contained-bdi-R.html dir_auto-contained-bdi-R-ref.html
+== dir_auto-contained-dir_auto-L.html dir_auto-contained-dir_auto-L-ref.html
+== dir_auto-contained-dir_auto-R.html dir_auto-contained-dir_auto-R-ref.html
+== dir_auto-contained-dir-L.html dir_auto-contained-dir-L-ref.html
+== dir_auto-contained-dir-R.html dir_auto-contained-dir-R-ref.html
+== dir_auto-contained-L.html dir_auto-contained-L-ref.html
+== dir_auto-contained-R.html dir_auto-contained-R-ref.html
+== dir_auto-contained-script-L.html dir_auto-contained-script-L-ref.html
+== dir_auto-contained-script-R.html dir_auto-contained-script-R-ref.html
+== dir_auto-contained-style-L.html dir_auto-contained-style-L-ref.html
+== dir_auto-contained-style-R.html dir_auto-contained-style-R-ref.html
+== dir_auto-contained-textarea-L.html dir_auto-contained-textarea-L-ref.html
+== dir_auto-contained-textarea-R.html dir_auto-contained-textarea-R-ref.html
+== dir_auto-EN-L.html dir_auto-EN-L-ref.html
+== dir_auto-EN-R.html dir_auto-EN-R-ref.html
+== dir_auto-input-EN-L.html dir_auto-input-EN-L-ref.html
+== dir_auto-input-EN-R.html dir_auto-input-EN-R-ref.html
+== dir_auto-input-L.html dir_auto-input-L-ref.html
+== dir_auto-input-N-EN.html dir_auto-input-N-EN-ref.html
+== dir_auto-input-N-EN-L.html dir_auto-input-N-EN-L-ref.html
+== dir_auto-input-N-EN-R.html dir_auto-input-N-EN-R-ref.html
+== dir_auto-input-N-L.html dir_auto-input-N-L-ref.html
+== dir_auto-input-N-R.html dir_auto-input-N-R-ref.html
+== dir_auto-input-R.html dir_auto-input-R-ref.html
+== dir_auto-input-script-EN-L.html dir_auto-input-script-EN-L-ref.html
+== dir_auto-input-script-EN-R.html dir_auto-input-script-EN-R-ref.html
+== dir_auto-input-script-L.html dir_auto-input-script-L-ref.html
+== dir_auto-input-script-N-EN.html dir_auto-input-script-N-EN-ref.html
+== dir_auto-input-script-N-EN-L.html dir_auto-input-script-N-EN-L-ref.html
+== dir_auto-input-script-N-EN-R.html dir_auto-input-script-N-EN-R-ref.html
+== dir_auto-input-script-N-L.html dir_auto-input-script-N-L-ref.html
+== dir_auto-input-script-N-R.html dir_auto-input-script-N-R-ref.html
+== dir_auto-input-script-R.html dir_auto-input-script-R-ref.html
+== dir_auto-isolate.html dir_auto-isolate-ref.html
+== dir_auto-L.html dir_auto-L-ref.html
+== dir_auto-N-EN.html dir_auto-N-EN-ref.html
+== dir_auto-N-EN-L.html dir_auto-N-EN-L-ref.html
+== dir_auto-N-EN-R.html dir_auto-N-EN-R-ref.html
+== dir_auto-N-L.html dir_auto-N-L-ref.html
+== dir_auto-N-R.html dir_auto-N-R-ref.html
+== dir_auto-pre-mixed.html dir_auto-pre-mixed-ref.html
+== dir_auto-pre-N-between-Rs.html dir_auto-pre-N-between-Rs-ref.html
+== dir_auto-pre-N-EN.html dir_auto-pre-N-EN-ref.html
+== dir_auto-R.html dir_auto-R-ref.html
+== dir_auto-textarea-mixed.html dir_auto-textarea-mixed-ref.html
+fails-if(Android&&asyncPan) == dir_auto-textarea-N-between-Rs.html dir_auto-textarea-N-between-Rs-ref.html
+== dir_auto-textarea-N-EN.html dir_auto-textarea-N-EN-ref.html
+== dir_auto-textarea-script-mixed.html dir_auto-textarea-script-mixed-ref.html
+fails-if(Android&&asyncPan) == dir_auto-textarea-script-N-between-Rs.html dir_auto-textarea-script-N-between-Rs-ref.html
+== dir_auto-textarea-script-N-EN.html dir_auto-textarea-script-N-EN-ref.html
+== lang-xyzzy.html lang-xyzzy-ref.html
+== lang-xmllang-01.html lang-xmllang-01-ref.html
+== style-01.html style-01-ref.html
diff --git a/dom/imptests/html/js/builtins/test_WeakMap.prototype-properties.html b/dom/imptests/html/js/builtins/test_WeakMap.prototype-properties.html
new file mode 100644
index 000000000..0bdb6bb86
--- /dev/null
+++ b/dom/imptests/html/js/builtins/test_WeakMap.prototype-properties.html
@@ -0,0 +1,103 @@
+<!doctype html>
+<title>WeakMap.prototype</title>
+<link rel=author href=mailto:Ms2ger@gmail.com title=Ms2ger>
+<link rel=help href=http://people.mozilla.org/~jorendorff/es6-draft.html#sec-15.15.5>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<div id=log></div>
+<script>
+function assert_propdesc(obj, prop, Writable, Enumerable, Configurable) {
+ var propdesc = Object.getOwnPropertyDescriptor(obj, prop);
+ assert_equals(typeof propdesc, "object");
+ assert_equals(propdesc.writable, Writable, "[[Writable]]");
+ assert_equals(propdesc.enumerable, Enumerable, "[[Enumerable]]");
+ assert_equals(propdesc.configurable, Configurable, "[[Configurable]]");
+}
+
+function test_length(fun, expected) {
+ test(function() {
+ assert_propdesc(WeakMap.prototype[fun], "length", false, false, false);
+ assert_equals(WeakMap.prototype[fun].length, expected);
+ }, "WeakMap.prototype." + fun + ".length")
+}
+
+function test_thisval(fun, args) {
+ // Step 1-2
+ test(function() {
+ assert_throws(new TypeError(), function() {
+ WeakMap.prototype[fun].apply(null, args);
+ });
+ assert_throws(new TypeError(), function() {
+ WeakMap.prototype[fun].apply(undefined, args);
+ });
+ }, "WeakMap.prototype." + fun + ": ToObject on this")
+ // Step 3
+ test(function() {
+ assert_throws(new TypeError(), function() {
+ WeakMap.prototype[fun].apply({}, args);
+ });
+ }, "WeakMap.prototype." + fun + ": this has no [[WeakMapData]] internal property")
+}
+
+// In every case, the length property of a built-in Function object described
+// in this clause has the attributes { [[Writable]]: false, [[Enumerable]]:
+// false, [[Configurable]]: false }. Every other property described in this
+// clause has the attributes { [[Writable]]: true, [[Enumerable]]: false,
+// [[Configurable]]: true } unless otherwise specified.
+
+test(function() {
+ assert_equals(Object.getPrototypeOf(WeakMap.prototype), Object.prototype);
+}, "The value of the [[Prototype]] internal property of the WeakMap prototype object is the standard built-in Object prototype object (15.2.4).")
+
+// 15.15.5.1 WeakMap.prototype.constructor
+test(function() {
+ assert_equals(WeakMap.prototype.constructor, WeakMap);
+ assert_propdesc(WeakMap.prototype, "constructor", true, false, true);
+}, "The initial value of WeakMap.prototype.constructor is the built-in WeakMap constructor.")
+
+// 15.15.5.2 WeakMap.prototype.delete ( key )
+test(function() {
+ assert_propdesc(WeakMap.prototype, "delete", true, false, true);
+ test_length("delete", 1);
+ // Step 1-3
+ test_thisval("delete", [{}]);
+}, "WeakMap.prototype.delete")
+
+// 15.15.5.3 WeakMap.prototype.get ( key )
+test(function() {
+ assert_propdesc(WeakMap.prototype, "get", true, false, true);
+ test_length("get", 1);
+ // Step 1-3
+ test_thisval("get", [{}]);
+
+ // Step 8
+ test(function() {
+ var wm = new WeakMap();
+ var key = {};
+ var res = wm.get({}, {});
+ assert_equals(res, undefined);
+ }, "WeakMap.prototype.get: return undefined");
+}, "WeakMap.prototype.get")
+
+// 15.14.5.4 Map.prototype.has ( key )
+test(function() {
+ assert_propdesc(WeakMap.prototype, "has", true, false, true);
+ test_length("has", 1);
+ // Step 1-3
+ test_thisval("has", [{}]);
+}, "WeakMap.prototype.has")
+
+// 15.14.5.5 Map.prototype.set ( key , value )
+test(function() {
+ assert_propdesc(WeakMap.prototype, "set", true, false, true);
+ test_length("set", 2);
+ // Step 1-3
+ test_thisval("set", [{}, {}]);
+}, "WeakMap.prototype.set")
+
+// 15.15.5.6 Map.prototype.@@toStringTag
+test(function() {
+ assert_class_string(new WeakMap(), "WeakMap");
+ assert_class_string(WeakMap.prototype, "WeakMap");
+}, "WeakMap.prototype.@@toStringTag")
+</script>
diff --git a/dom/imptests/html/mochitest.ini b/dom/imptests/html/mochitest.ini
new file mode 100644
index 000000000..87b958f0e
--- /dev/null
+++ b/dom/imptests/html/mochitest.ini
@@ -0,0 +1,24 @@
+# THIS FILE IS AUTOGENERATED BY importTestsuite.py - DO NOT EDIT
+[DEFAULT]
+support-files =
+ webgl/common.js
+
+[typedarrays/test_constructors.html]
+[webgl/test_bufferSubData.html]
+subsuite = gpu
+skip-if = toolkit == 'android' #android(WebGL)
+[webgl/test_compressedTexImage2D.html]
+subsuite = gpu
+skip-if = toolkit == 'android' #android(WebGL)
+[webgl/test_compressedTexSubImage2D.html]
+subsuite = gpu
+skip-if = true # Bug 1226336
+[webgl/test_texImage2D.html]
+subsuite = gpu
+skip-if = toolkit == 'android' #android(WebGL)
+[webgl/test_texSubImage2D.html]
+subsuite = gpu
+skip-if = toolkit == 'android' #android(WebGL)
+[webgl/test_uniformMatrixNfv.html]
+subsuite = gpu
+skip-if = toolkit == 'android' #android(WebGL)
diff --git a/dom/imptests/html/typedarrays/test_constructors.html b/dom/imptests/html/typedarrays/test_constructors.html
new file mode 100644
index 000000000..60e0dc8fe
--- /dev/null
+++ b/dom/imptests/html/typedarrays/test_constructors.html
@@ -0,0 +1,48 @@
+<!doctype html>
+<title>Typed Array constructors</title>
+<link rel=author href=mailto:Ms2ger@gmail.com title=Ms2ger>
+<link rel=help href=https://www.khronos.org/registry/typedarray/specs/latest/#7>
+<link rel=help href=http://dev.w3.org/2006/webapi/WebIDL/#dfn-overload-resolution-algorithm>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+
+<div id=log></div>
+<script>
+var args = [
+ /* numbers */
+ [NaN, 0], [+Infinity, 0], [-Infinity, 0], [+0, 0], [-0, 0], // Step 2
+ [-0.4, 0], [-0.9, 0], [1.1, 1], [2.9, 2], // Step 3
+ [1, 1], [-0xF1000000, 0xF000000], // Step 4
+ /* strings */
+ ["1", 1], ["1e2", 100],
+ /* null, undefined, booleans */
+ [undefined, 0], [null, 0], [false, 0], [true, 1],
+ /* objects */
+ [{}, 0], [{ length: 2, 0: 0, 1: 0 }, 0], [[0, 0], 2]
+];
+var interfaces = [
+ "Int8Array", "Uint8Array", "Uint8ClampedArray", "Int16Array", "Uint16Array",
+ "Int32Array", "Uint32Array", "Float32Array", "Float64Array"
+];
+
+test(function() {
+ interfaces.concat(["ArrayBuffer", "DataView"]).forEach(function(i) {
+ test(function() {
+ // XXX The spec is wrong here.
+ assert_throws(new TypeError(), function() {
+ new window[i]();
+ });
+ }, "Constructing interface " + i + " with no arguments should throw.");
+ });
+ interfaces.forEach(function(i) {
+ args.forEach(function(arg, j) {
+ var input = arg[0], expected = arg[1];
+ test(function() {
+ var ta = new window[i](input);
+ assert_equals(ta.length, expected);
+ }, "The argument " + format_value(input) + " (" + j + ") should be interpreted as " +
+ expected + " for interface " + i + ".");
+ });
+ });
+});
+</script>
diff --git a/dom/imptests/html/webgl/common.js b/dom/imptests/html/webgl/common.js
new file mode 100644
index 000000000..416c21ce9
--- /dev/null
+++ b/dom/imptests/html/webgl/common.js
@@ -0,0 +1,13 @@
+function getGl() {
+ var c = document.createElement("canvas");
+ var gl = c.getContext("experimental-webgl");
+ assert_true(!!gl, "Should be able to get a context.");
+ return gl;
+}
+
+function shouldGenerateGLError(cx, glError, fn) {
+ test(function() {
+ fn();
+ assert_equals(cx.getError(), glError);
+ }, "Calling " + fn + " should generate a " + glError + " error.");
+}
diff --git a/dom/imptests/html/webgl/test_bufferSubData.html b/dom/imptests/html/webgl/test_bufferSubData.html
new file mode 100644
index 000000000..a97df9062
--- /dev/null
+++ b/dom/imptests/html/webgl/test_bufferSubData.html
@@ -0,0 +1,26 @@
+<!doctype html>
+<title>bufferSubData</title>
+<link rel=author href=mailto:Ms2ger@gmail.com title=Ms2ger>
+<link rel=help href=https://www.khronos.org/registry/webgl/specs/latest/#5.14.5>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script src=common.js></script>
+
+<div id=log></div>
+<script>
+test(function() {
+ var gl = getGl();
+ assert_equals(gl.getError(), WebGLRenderingContext.NO_ERROR);
+
+ var b = gl.createBuffer();
+ gl.bindBuffer(gl.ARRAY_BUFFER, b);
+
+ var a = new Float32Array(1);
+ gl.bufferData(gl.ARRAY_BUFFER, a, gl.STATIC_DRAW);
+
+ var nan = 0 / 0;
+ gl.bufferSubData(gl.ARRAY_BUFFER, nan, a);
+
+ assert_equals(gl.getError(), WebGLRenderingContext.NO_ERROR);
+});
+</script>
diff --git a/dom/imptests/html/webgl/test_compressedTexImage2D.html b/dom/imptests/html/webgl/test_compressedTexImage2D.html
new file mode 100644
index 000000000..b0a031add
--- /dev/null
+++ b/dom/imptests/html/webgl/test_compressedTexImage2D.html
@@ -0,0 +1,30 @@
+<!doctype html>
+<title>compressedTexImage2D</title>
+<link rel=author href=mailto:Ms2ger@gmail.com title=Ms2ger>
+<link rel=help href=https://www.khronos.org/registry/webgl/specs/latest/#5.14.8>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script src=common.js></script>
+
+<div id=log></div>
+<script>
+test(function() {
+ var COMPRESSED_RGB_S3TC_DXT1_EXT = 0x83F0;
+ var gl = getGl();
+
+ var tex = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, tex);
+
+ shouldGenerateGLError(gl, gl.INVALID_ENUM, function() {
+ gl.compressedTexImage2D(gl.TEXTURE_2D, 0, COMPRESSED_RGB_S3TC_DXT1_EXT, 4, 4, 0, new Uint8Array(8));
+ });
+ shouldGenerateGLError(gl, gl.INVALID_ENUM, function() {
+ gl.compressedTexImage2D(gl.TEXTURE_2D, 0, COMPRESSED_RGB_S3TC_DXT1_EXT, 4, 4, 0, new Uint8Array(8), null);
+ });
+ test(function() {
+ assert_throws(new TypeError(), function() {
+ gl.compressedTexImage2D(gl.TEXTURE_2D, 0, COMPRESSED_RGB_S3TC_DXT1_EXT, 4, 4, 0);
+ });
+ }, "Should throw a TypeError when passing too few arguments.");
+});
+</script>
diff --git a/dom/imptests/html/webgl/test_compressedTexSubImage2D.html b/dom/imptests/html/webgl/test_compressedTexSubImage2D.html
new file mode 100644
index 000000000..539f9e17f
--- /dev/null
+++ b/dom/imptests/html/webgl/test_compressedTexSubImage2D.html
@@ -0,0 +1,30 @@
+<!doctype html>
+<title>compressedTexSubImage2D</title>
+<link rel=author href=mailto:Ms2ger@gmail.com title=Ms2ger>
+<link rel=help href=https://www.khronos.org/registry/webgl/specs/latest/#5.14.8>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script src=common.js></script>
+
+<div id=log></div>
+<script>
+test(function() {
+ var COMPRESSED_RGB_S3TC_DXT1_EXT = 0x83F0;
+ var gl = getGl();
+
+ var tex = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, tex);
+
+ shouldGenerateGLError(gl, gl.INVALID_ENUM, function() {
+ gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, 10, 10, COMPRESSED_RGB_S3TC_DXT1_EXT, new Uint8Array(8));
+ });
+ shouldGenerateGLError(gl, gl.INVALID_ENUM, function() {
+ gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, 10, 10, COMPRESSED_RGB_S3TC_DXT1_EXT, new Uint8Array(8), null);
+ });
+ test(function() {
+ assert_throws(new TypeError(), function() {
+ gl.compressedTexSubImage2D(gl.TEXTURE_2D, 0, 0, 0, 10, 10, COMPRESSED_RGB_S3TC_DXT1_EXT);
+ });
+ }, "Should throw a TypeError when passing too few arguments.");
+});
+</script>
diff --git a/dom/imptests/html/webgl/test_texImage2D.html b/dom/imptests/html/webgl/test_texImage2D.html
new file mode 100644
index 000000000..2f769160d
--- /dev/null
+++ b/dom/imptests/html/webgl/test_texImage2D.html
@@ -0,0 +1,20 @@
+<!doctype html>
+<title>texImage2D</title>
+<link rel=author href=mailto:Ms2ger@gmail.com title=Ms2ger>
+<link rel=help href=https://www.khronos.org/registry/webgl/specs/latest/#5.14.8>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script src=common.js></script>
+
+<div id=log></div>
+<script>
+test(function() {
+ var gl = getGl();
+ assert_throws(new TypeError(), function() {
+ gl.texImage2D(0, 0, 0, 0, 0, window);
+ });
+ assert_throws(new TypeError(), function() {
+ gl.texImage2D(0, 0, 0, 0, 0, { get width() { throw 7 }, get height() { throw 7 }, data: new Uint8ClampedArray(10) });
+ });
+});
+</script>
diff --git a/dom/imptests/html/webgl/test_texSubImage2D.html b/dom/imptests/html/webgl/test_texSubImage2D.html
new file mode 100644
index 000000000..294b30c76
--- /dev/null
+++ b/dom/imptests/html/webgl/test_texSubImage2D.html
@@ -0,0 +1,20 @@
+<!doctype html>
+<title>texSubImage2D</title>
+<link rel=author href=mailto:Ms2ger@gmail.com title=Ms2ger>
+<link rel=help href=https://www.khronos.org/registry/webgl/specs/latest/#5.14.8>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script src=common.js></script>
+
+<div id=log></div>
+<script>
+test(function() {
+ var gl = getGl();
+ assert_throws(new TypeError(), function() {
+ gl.texSubImage2D(0, 0, 0, 0, 0, 0, window);
+ });
+ assert_throws(new TypeError(), function() {
+ gl.texSubImage2D(0, 0, 0, 0, 0, 0, { get width() { throw 7 }, get height() { throw 7 }, data: new Uint8ClampedArray(10) });
+ });
+});
+</script>
diff --git a/dom/imptests/html/webgl/test_uniformMatrixNfv.html b/dom/imptests/html/webgl/test_uniformMatrixNfv.html
new file mode 100644
index 000000000..f75cbcb99
--- /dev/null
+++ b/dom/imptests/html/webgl/test_uniformMatrixNfv.html
@@ -0,0 +1,33 @@
+<!doctype html>
+<title>uniformMatrix*fv</title>
+<link rel=author href=mailto:Ms2ger@gmail.com title=Ms2ger>
+<link rel=help href=https://www.khronos.org/registry/webgl/specs/latest/#WebGLRenderingContext>
+<link rel=help href=http://dev.w3.org/2006/webapi/WebIDL/#es-boolean>
+<link rel=help href=http://es5.github.com/#x9.2>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script src=common.js></script>
+
+<div id=log></div>
+<script id="vshader" type="x-shader/x-vertex">
+uniform mat2 m2;
+uniform mat3 m3;
+uniform mat4 m4;
+</script>
+<script>
+var floatArray = function(n) {
+ var a = [];
+ for (var i = 0; i < n; ++i) {
+ a.push(1);
+ }
+ return a;
+};
+[2, 3, 4].forEach(function(n) {
+ test(function() {
+ var gl = getGl();
+ var f = "uniformMatrix" + n + "fv";
+ var loc = gl.getUniformLocation(gl.createProgram(), "m" + n);
+ gl[f](loc, { valueOf: function() { throw "Error"; } }, floatArray(n));
+ }, "Should not throw for " + n);
+});
+</script>