From 43a97878ce14b72f0981164f87f2e35e14151312 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 11:22:09 +0200 Subject: Adding upstream version 110.0.1. Signed-off-by: Daniel Baumann --- testing/web-platform/tests/dom/META.yml | 5 + .../tests/dom/abort/AbortSignal.any.js | 40 + .../dom/abort/abort-signal-any.tentative.any.js | 4 + .../tests/dom/abort/abort-signal-timeout.html | 19 + .../tests/dom/abort/crashtests/timeout-close.html | 22 + testing/web-platform/tests/dom/abort/event.any.js | 190 ++++ .../tests/dom/abort/reason-constructor.html | 12 + .../dom/abort/resources/abort-signal-any-tests.js | 185 ++++ .../tests/dom/attributes-are-nodes.html | 55 + .../collections/HTMLCollection-as-prototype.html | 29 + .../dom/collections/HTMLCollection-delete.html | 45 + .../dom/collections/HTMLCollection-empty-name.html | 65 ++ .../dom/collections/HTMLCollection-iterator.html | 45 + .../HTMLCollection-live-mutations.window.js | 93 ++ .../dom/collections/HTMLCollection-own-props.html | 109 ++ .../HTMLCollection-supported-property-indices.html | 179 ++++ .../HTMLCollection-supported-property-names.html | 135 +++ .../domstringmap-supported-property-names.html | 54 + .../namednodemap-supported-property-names.html | 30 + testing/web-platform/tests/dom/common.js | 1083 ++++++++++++++++++++ testing/web-platform/tests/dom/constants.js | 11 + .../web-platform/tests/dom/eventPathRemoved.html | 16 + .../dom/events/AddEventListenerOptions-once.any.js | 96 ++ .../events/AddEventListenerOptions-passive.any.js | 134 +++ .../events/AddEventListenerOptions-signal.any.js | 143 +++ .../dom/events/Body-FrameSet-Event-Handlers.html | 123 +++ .../web-platform/tests/dom/events/CustomEvent.html | 35 + .../tests/dom/events/Event-cancelBubble.html | 132 +++ .../tests/dom/events/Event-constants.html | 23 + .../tests/dom/events/Event-constructors.any.js | 120 +++ .../Event-defaultPrevented-after-dispatch.html | 44 + .../tests/dom/events/Event-defaultPrevented.html | 55 + .../dom/events/Event-dispatch-bubble-canceled.html | 59 ++ .../dom/events/Event-dispatch-bubbles-false.html | 98 ++ .../dom/events/Event-dispatch-bubbles-true.html | 108 ++ .../tests/dom/events/Event-dispatch-click.html | 369 +++++++ .../dom/events/Event-dispatch-click.tentative.html | 78 ++ .../dom/events/Event-dispatch-detached-click.html | 20 + .../Event-dispatch-detached-input-and-change.html | 190 ++++ .../events/Event-dispatch-handlers-changed.html | 91 ++ .../events/Event-dispatch-listener-order.window.js | 20 + .../Event-dispatch-multiple-cancelBubble.html | 51 + .../Event-dispatch-multiple-stopPropagation.html | 51 + .../dom/events/Event-dispatch-omitted-capture.html | 70 ++ .../Event-dispatch-on-disabled-elements.html | 251 +++++ .../dom/events/Event-dispatch-order-at-target.html | 31 + .../tests/dom/events/Event-dispatch-order.html | 26 + .../dom/events/Event-dispatch-other-document.html | 23 + .../events/Event-dispatch-propagation-stopped.html | 59 ++ .../dom/events/Event-dispatch-redispatch.html | 124 +++ .../tests/dom/events/Event-dispatch-reenter.html | 66 ++ .../dom/events/Event-dispatch-target-moved.html | 73 ++ .../dom/events/Event-dispatch-target-removed.html | 72 ++ .../tests/dom/events/Event-dispatch-throwing.html | 51 + .../dom/events/Event-init-while-dispatching.html | 83 ++ .../tests/dom/events/Event-initEvent.html | 136 +++ .../tests/dom/events/Event-isTrusted.any.js | 11 + .../tests/dom/events/Event-propagation.html | 48 + .../tests/dom/events/Event-returnValue.html | 64 ++ .../dom/events/Event-stopImmediatePropagation.html | 34 + .../Event-stopPropagation-cancel-bubbling.html | 20 + .../dom/events/Event-subclasses-constructors.html | 179 ++++ .../events/Event-timestamp-cross-realm-getter.html | 27 + .../events/Event-timestamp-high-resolution.html | 16 + .../Event-timestamp-high-resolution.https.html | 16 + .../events/Event-timestamp-safe-resolution.html | 49 + .../tests/dom/events/Event-type-empty.html | 35 + .../web-platform/tests/dom/events/Event-type.html | 22 + .../EventListener-addEventListener.sub.window.js | 9 + .../EventListener-handleEvent-cross-realm.html | 75 ++ .../dom/events/EventListener-handleEvent.html | 102 ++ .../EventListener-incumbent-global-1.sub.html | 20 + .../EventListener-incumbent-global-2.sub.html | 20 + ...ntListener-incumbent-global-subframe-1.sub.html | 13 + ...ntListener-incumbent-global-subframe-2.sub.html | 13 + ...tListener-incumbent-global-subsubframe.sub.html | 20 + .../dom/events/EventListener-invoke-legacy.html | 66 ++ .../dom/events/EventListenerOptions-capture.html | 98 ++ .../EventTarget-add-listener-platform-object.html | 32 + .../events/EventTarget-add-remove-listener.any.js | 21 + .../dom/events/EventTarget-addEventListener.any.js | 9 + .../dom/events/EventTarget-constructible.any.js | 62 ++ .../EventTarget-dispatchEvent-returnvalue.html | 71 ++ .../dom/events/EventTarget-dispatchEvent.html | 104 ++ .../events/EventTarget-removeEventListener.any.js | 8 + .../dom/events/EventTarget-this-of-listener.html | 182 ++++ .../tests/dom/events/KeyEvent-initKeyEvent.html | 23 + .../tests/dom/events/event-disabled-dynamic.html | 21 + .../tests/dom/events/event-global-extra.window.js | 90 ++ ...till-set-when-coercing-beforeunload-result.html | 23 + ...still-set-when-reporting-exception-onerror.html | 43 + ...-global-set-before-handleEvent-lookup.window.js | 19 + .../tests/dom/events/event-global.html | 117 +++ .../tests/dom/events/event-global.worker.js | 14 + .../dom/events/focus-event-document-move.html | 33 + .../tests/dom/events/keypress-dispatch-crash.html | 15 + .../legacy-pre-activation-behavior.window.js | 10 + .../tests/dom/events/mouse-event-retarget.html | 26 + ...vents-at-clicking-editable-content-in-link.html | 80 ++ ...-passive-mousewheel-event-listener-on-body.html | 19 + ...n-passive-mousewheel-event-listener-on-div.html | 35 + ...sive-mousewheel-event-listener-on-document.html | 19 + ...-passive-mousewheel-event-listener-on-root.html | 19 + ...assive-mousewheel-event-listener-on-window.html | 19 + ...n-passive-touchmove-event-listener-on-body.html | 25 + ...on-passive-touchmove-event-listener-on-div.html | 25 + ...ssive-touchmove-event-listener-on-document.html | 25 + ...n-passive-touchmove-event-listener-on-root.html | 25 + ...passive-touchmove-event-listener-on-window.html | 25 + ...-passive-touchstart-event-listener-on-body.html | 25 + ...n-passive-touchstart-event-listener-on-div.html | 25 + ...sive-touchstart-event-listener-on-document.html | 25 + ...-passive-touchstart-event-listener-on-root.html | 25 + ...assive-touchstart-event-listener-on-window.html | 25 + .../non-passive-wheel-event-listener-on-body.html | 18 + .../non-passive-wheel-event-listener-on-div.html | 34 + ...n-passive-wheel-event-listener-on-document.html | 18 + .../non-passive-wheel-event-listener-on-root.html | 18 + ...non-passive-wheel-event-listener-on-window.html | 18 + .../passive-mousewheel-event-listener-on-body.html | 19 + .../passive-mousewheel-event-listener-on-div.html | 35 + ...sive-mousewheel-event-listener-on-document.html | 19 + .../passive-mousewheel-event-listener-on-root.html | 19 + ...assive-mousewheel-event-listener-on-window.html | 19 + .../passive-touchmove-event-listener-on-body.html | 25 + .../passive-touchmove-event-listener-on-div.html | 25 + ...ssive-touchmove-event-listener-on-document.html | 25 + .../passive-touchmove-event-listener-on-root.html | 25 + ...passive-touchmove-event-listener-on-window.html | 25 + .../passive-touchstart-event-listener-on-body.html | 25 + .../passive-touchstart-event-listener-on-div.html | 25 + ...sive-touchstart-event-listener-on-document.html | 25 + .../passive-touchstart-event-listener-on-root.html | 25 + ...assive-touchstart-event-listener-on-window.html | 25 + .../passive-wheel-event-listener-on-body.html | 18 + .../passive-wheel-event-listener-on-div.html | 34 + .../passive-wheel-event-listener-on-document.html | 18 + .../passive-wheel-event-listener-on-root.html | 18 + .../passive-wheel-event-listener-on-window.html | 18 + .../resources/scrolling.js | 34 + .../resources/touching.js | 34 + .../resources/wait-for.js | 15 + .../synthetic-events-cancelable.html | 34 + .../tests/dom/events/passive-by-default.html | 50 + .../tests/dom/events/relatedTarget.window.js | 81 ++ ...event-listener-null-browsing-context-crash.html | 16 + .../tests/dom/events/resources/empty-document.html | 3 + .../events/resources/event-global-extra-frame.html | 9 + ...et-when-coercing-beforeunload-result-frame.html | 6 + .../resources/prefixed-animation-event-tests.js | 366 +++++++ .../tests/dom/events/scrolling/iframe-chains.html | 48 + ...ut-text-scroll-event-when-using-arrow-keys.html | 71 ++ .../dom/events/scrolling/overscroll-deltas.html | 85 ++ .../overscroll-event-fired-to-document.html | 62 ++ ...-fired-to-element-with-overscroll-behavior.html | 92 ++ ...overscroll-event-fired-to-scrolled-element.html | 65 ++ .../overscroll-event-fired-to-window.html | 52 + .../tests/dom/events/scrolling/scroll_support.js | 163 +++ ...-fired-after-sequence-of-scrolls.tentative.html | 63 ++ .../scrollend-event-fired-after-snap.html | 87 ++ ...ollend-event-fired-for-programmatic-scroll.html | 135 +++ .../scrollend-event-fired-for-scrollIntoView.html | 124 +++ .../scrollend-event-fired-to-document.html | 70 ++ ...-fired-to-element-with-overscroll-behavior.html | 102 ++ .../scrollend-event-fired-to-scrolled-element.html | 68 ++ .../scrolling/scrollend-event-fired-to-window.html | 55 + .../scrolling/scrollend-event-for-user-scroll.html | 199 ++++ ...scrollend-event-handler-content-attributes.html | 108 ++ ...ot-fired-after-removing-scroller.tentative.html | 84 ++ .../tests/dom/events/shadow-relatedTarget.html | 30 + .../dom/events/webkit-animation-end-event.html | 20 + .../events/webkit-animation-iteration-event.html | 23 + .../dom/events/webkit-animation-start-event.html | 20 + .../dom/events/webkit-transition-end-event.html | 21 + testing/web-platform/tests/dom/historical.html | 222 ++++ .../tests/dom/idlharness-shadowrealm.window.js | 2 + testing/web-platform/tests/dom/idlharness.any.js | 25 + .../web-platform/tests/dom/idlharness.window.js | 52 + .../web-platform/tests/dom/interface-objects.html | 46 + .../tests/dom/lists/DOMTokenList-Iterable.html | 34 + .../DOMTokenList-coverage-for-attributes.html | 55 + .../tests/dom/lists/DOMTokenList-iteration.html | 71 ++ .../tests/dom/lists/DOMTokenList-stringifier.html | 25 + .../tests/dom/lists/DOMTokenList-value.html | 24 + testing/web-platform/tests/dom/lists/README.md | 1 + .../tests/dom/nodes/CharacterData-appendChild.html | 34 + .../tests/dom/nodes/CharacterData-appendData.html | 70 ++ .../tests/dom/nodes/CharacterData-data.html | 82 ++ .../tests/dom/nodes/CharacterData-deleteData.html | 95 ++ .../tests/dom/nodes/CharacterData-insertData.html | 90 ++ .../tests/dom/nodes/CharacterData-remove.html | 24 + .../tests/dom/nodes/CharacterData-replaceData.html | 163 +++ .../dom/nodes/CharacterData-substringData.html | 137 +++ .../tests/dom/nodes/CharacterData-surrogates.html | 74 ++ .../tests/dom/nodes/ChildNode-after.html | 166 +++ .../tests/dom/nodes/ChildNode-before.html | 166 +++ .../tests/dom/nodes/ChildNode-remove.js | 30 + .../tests/dom/nodes/ChildNode-replaceWith.html | 110 ++ .../tests/dom/nodes/Comment-Text-constructor.js | 77 ++ .../tests/dom/nodes/Comment-constructor.html | 11 + ...eDocument-with-null-browsing-context-crash.html | 13 + .../nodes/DOMImplementation-createDocument.html | 170 +++ .../DOMImplementation-createDocumentType.html | 123 +++ ...LDocument-with-null-browsing-context-crash.html | 13 + ...eateHTMLDocument-with-saved-implementation.html | 16 + .../DOMImplementation-createHTMLDocument.html | 96 ++ .../nodes/DOMImplementation-createHTMLDocument.js | 25 + .../dom/nodes/DOMImplementation-hasFeature.html | 155 +++ .../nodes/Document-Element-getElementsByTagName.js | 208 ++++ .../Document-Element-getElementsByTagNameNS.js | 143 +++ .../web-platform/tests/dom/nodes/Document-URL.html | 18 + .../tests/dom/nodes/Document-adoptNode.html | 50 + .../Document-characterSet-normalization-1.html | 157 +++ .../Document-characterSet-normalization-2.html | 179 ++++ .../tests/dom/nodes/Document-constructor-svg.svg | 46 + .../tests/dom/nodes/Document-constructor-xml.xml | 49 + .../tests/dom/nodes/Document-constructor.html | 56 + .../contentType/contenttype_bmp.html | 15 + .../contentType/contenttype_css.html | 15 + .../contentType/contenttype_datauri_02.html | 15 + .../contentType/contenttype_gif.html | 15 + .../contentType/contenttype_html.html | 15 + .../contentType/contenttype_javascripturi.html | 16 + .../contentType/contenttype_jpg.html | 15 + .../contentType/contenttype_mimeheader_01.html | 15 + .../contentType/contenttype_mimeheader_02.html | 15 + .../contentType/contenttype_png.html | 15 + .../contentType/contenttype_txt.html | 15 + .../contentType/contenttype_xml.html | 15 + .../contentType/createDocument.html | 11 + .../contentType/createHTMLDocument.html | 11 + .../contentType/xhr_responseType_document.html | 18 + .../nodes/Document-contentType/resources/blob.htm | 1 + .../nodes/Document-contentType/resources/blob.txt | 1 + .../nodes/Document-contentType/resources/blob.xml | 2 + .../nodes/Document-contentType/resources/lib.js | 1 + .../nodes/Document-contentType/resources/style.css | 12 + .../dom/nodes/Document-contentType/resources/t.bmp | Bin 0 -> 30054 bytes .../dom/nodes/Document-contentType/resources/t.gif | Bin 0 -> 148 bytes .../dom/nodes/Document-contentType/resources/t.jpg | Bin 0 -> 361 bytes .../dom/nodes/Document-contentType/resources/t.png | Bin 0 -> 228 bytes .../support/contenttype_setter.py | 20 + .../tests/dom/nodes/Document-createAttribute.html | 55 + .../nodes/Document-createCDATASection-xhtml.xhtml | 22 + .../dom/nodes/Document-createCDATASection.html | 16 + .../nodes/Document-createComment-createTextNode.js | 22 + .../tests/dom/nodes/Document-createComment.html | 21 + .../bare_mathml.html | 1 + .../bare_mathml.svg | 1 + .../bare_mathml.xhtml | 1 + .../bare_mathml.xml | 1 + .../bare_svg.html | 1 + .../bare_svg.svg | 1 + .../bare_svg.xhtml | 1 + .../bare_svg.xml | 1 + .../bare_xhtml.html | 1 + .../bare_xhtml.svg | 1 + .../bare_xhtml.xhtml | 1 + .../bare_xhtml.xml | 1 + .../empty.html | 0 .../empty.svg | 0 .../empty.xhtml | 0 .../empty.xml | 0 .../generate.py | 80 ++ .../mathml.html | 1 + .../mathml.svg | 1 + .../mathml.xhtml | 1 + .../mathml.xml | 1 + .../minimal_html.html | 1 + .../minimal_html.svg | 1 + .../minimal_html.xhtml | 1 + .../minimal_html.xml | 1 + .../svg.html | 1 + .../Document-createElement-namespace-tests/svg.svg | 1 + .../svg.xhtml | 1 + .../Document-createElement-namespace-tests/svg.xml | 1 + .../xhtml.html | 1 + .../xhtml.svg | 1 + .../xhtml.xhtml | 1 + .../xhtml.xml | 1 + .../xhtml_ns_changed.html | 7 + .../xhtml_ns_changed.svg | 7 + .../xhtml_ns_changed.xhtml | 7 + .../xhtml_ns_changed.xml | 7 + .../xhtml_ns_removed.html | 7 + .../xhtml_ns_removed.svg | 7 + .../xhtml_ns_removed.xhtml | 7 + .../xhtml_ns_removed.xml | 7 + .../nodes/Document-createElement-namespace.html | 117 +++ .../tests/dom/nodes/Document-createElement.html | 158 +++ .../tests/dom/nodes/Document-createElementNS.html | 224 ++++ .../tests/dom/nodes/Document-createElementNS.js | 189 ++++ .../Document-createEvent-touchevent.window.js | 12 + .../dom/nodes/Document-createEvent.https.html | 170 +++ .../tests/dom/nodes/Document-createEvent.js | 22 + ...ocument-createProcessingInstruction-xhtml.xhtml | 15 + .../Document-createProcessingInstruction.html | 11 + .../nodes/Document-createProcessingInstruction.js | 39 + .../tests/dom/nodes/Document-createTextNode.html | 21 + .../tests/dom/nodes/Document-createTreeWalker.html | 42 + .../tests/dom/nodes/Document-doctype.html | 21 + .../tests/dom/nodes/Document-getElementById.html | 350 +++++++ .../dom/nodes/Document-getElementsByClassName.html | 26 + .../Document-getElementsByTagName-xhtml.xhtml | 104 ++ .../dom/nodes/Document-getElementsByTagName.html | 11 + .../dom/nodes/Document-getElementsByTagNameNS.html | 11 + .../tests/dom/nodes/Document-implementation.html | 20 + .../tests/dom/nodes/Document-importNode.html | 67 ++ .../dom/nodes/DocumentFragment-constructor.html | 22 + .../dom/nodes/DocumentFragment-getElementById.html | 62 ++ ...agment-querySelectorAll-after-modification.html | 24 + .../dom/nodes/DocumentType-literal-xhtml.xhtml | 23 + .../tests/dom/nodes/DocumentType-literal.html | 17 + .../tests/dom/nodes/DocumentType-remove.html | 16 + .../dom/nodes/Element-childElement-null-svg.svg | 20 + .../nodes/Element-childElement-null-xhtml.xhtml | 20 + .../tests/dom/nodes/Element-childElement-null.html | 15 + .../Element-childElementCount-dynamic-add-svg.svg | 22 + ...ement-childElementCount-dynamic-add-xhtml.xhtml | 22 + .../Element-childElementCount-dynamic-add.html | 17 + ...lement-childElementCount-dynamic-remove-svg.svg | 22 + ...nt-childElementCount-dynamic-remove-xhtml.xhtml | 22 + .../Element-childElementCount-dynamic-remove.html | 17 + .../Element-childElementCount-nochild-svg.svg | 19 + .../Element-childElementCount-nochild-xhtml.xhtml | 19 + .../nodes/Element-childElementCount-nochild.html | 14 + .../dom/nodes/Element-childElementCount-svg.svg | 25 + .../nodes/Element-childElementCount-xhtml.xhtml | 25 + .../tests/dom/nodes/Element-childElementCount.html | 20 + .../tests/dom/nodes/Element-children.html | 58 ++ .../tests/dom/nodes/Element-classlist.html | 478 +++++++++ .../tests/dom/nodes/Element-closest.html | 73 ++ .../Element-firstElementChild-entity-xhtml.xhtml | 27 + .../dom/nodes/Element-firstElementChild-entity.svg | 26 + .../Element-firstElementChild-namespace-svg.svg | 26 + ...Element-firstElementChild-namespace-xhtml.xhtml | 28 + .../nodes/Element-firstElementChild-namespace.html | 21 + .../dom/nodes/Element-firstElementChild-svg.svg | 23 + .../nodes/Element-firstElementChild-xhtml.xhtml | 23 + .../tests/dom/nodes/Element-firstElementChild.html | 18 + .../dom/nodes/Element-getElementsByClassName.html | 43 + ...tsByTagName-change-document-HTMLNess-iframe.xml | 1 + ...ElementsByTagName-change-document-HTMLNess.html | 51 + .../dom/nodes/Element-getElementsByTagName.html | 30 + .../dom/nodes/Element-getElementsByTagNameNS.html | 37 + .../tests/dom/nodes/Element-hasAttribute.html | 32 + .../tests/dom/nodes/Element-hasAttributes.html | 40 + .../dom/nodes/Element-insertAdjacentElement.html | 91 ++ .../dom/nodes/Element-insertAdjacentText.html | 76 ++ .../dom/nodes/Element-lastElementChild-svg.svg | 22 + .../dom/nodes/Element-lastElementChild-xhtml.xhtml | 22 + .../tests/dom/nodes/Element-lastElementChild.html | 17 + .../tests/dom/nodes/Element-matches-init.js | 65 ++ .../nodes/Element-matches-namespaced-elements.html | 24 + .../tests/dom/nodes/Element-matches.html | 22 + .../tests/dom/nodes/Element-matches.js | 135 +++ .../dom/nodes/Element-nextElementSibling-svg.svg | 23 + .../nodes/Element-nextElementSibling-xhtml.xhtml | 23 + .../dom/nodes/Element-nextElementSibling.html | 18 + .../nodes/Element-previousElementSibling-svg.svg | 28 + .../Element-previousElementSibling-xhtml.xhtml | 28 + .../dom/nodes/Element-previousElementSibling.html | 23 + .../tests/dom/nodes/Element-remove.html | 16 + .../tests/dom/nodes/Element-removeAttribute.html | 58 ++ .../tests/dom/nodes/Element-removeAttributeNS.html | 18 + .../nodes/Element-setAttribute-crbug-1138487.html | 22 + .../tests/dom/nodes/Element-setAttribute.html | 38 + .../dom/nodes/Element-siblingElement-null-svg.svg | 20 + .../nodes/Element-siblingElement-null-xhtml.xhtml | 20 + .../dom/nodes/Element-siblingElement-null.html | 16 + .../tests/dom/nodes/Element-tagName.html | 57 ++ .../dom/nodes/Element-webkitMatchesSelector.html | 22 + .../dom/nodes/MutationObserver-attributes.html | 406 ++++++++ .../nodes/MutationObserver-callback-arguments.html | 31 + .../dom/nodes/MutationObserver-characterData.html | 215 ++++ .../dom/nodes/MutationObserver-childList.html | 434 ++++++++ ...rver-cross-realm-callback-report-exception.html | 32 + .../dom/nodes/MutationObserver-disconnect.html | 48 + .../tests/dom/nodes/MutationObserver-document.html | 167 +++ .../dom/nodes/MutationObserver-inner-outer.html | 65 ++ .../tests/dom/nodes/MutationObserver-sanity.html | 95 ++ .../dom/nodes/MutationObserver-takeRecords.html | 53 + ...ode-appendChild-cereactions-vs-script.window.js | 27 + .../tests/dom/nodes/Node-appendChild.html | 59 ++ .../web-platform/tests/dom/nodes/Node-baseURI.html | 62 ++ .../tests/dom/nodes/Node-childNodes.html | 117 +++ .../dom/nodes/Node-cloneNode-XMLDocument.html | 28 + .../Node-cloneNode-document-with-doctype.html | 51 + ...de-cloneNode-external-stylesheet-no-bc.sub.html | 23 + .../Node-cloneNode-on-inactive-document-crash.html | 6 + .../tests/dom/nodes/Node-cloneNode-svg.html | 63 ++ .../tests/dom/nodes/Node-cloneNode.html | 346 +++++++ .../dom/nodes/Node-compareDocumentPosition.html | 87 ++ .../tests/dom/nodes/Node-constants.html | 39 + .../tests/dom/nodes/Node-contains-xml.xml | 83 ++ .../tests/dom/nodes/Node-contains.html | 36 + .../tests/dom/nodes/Node-insertBefore.html | 297 ++++++ .../dom/nodes/Node-isConnected-shadow-dom.html | 29 + .../tests/dom/nodes/Node-isConnected.html | 95 ++ .../tests/dom/nodes/Node-isEqualNode-iframe1.xml | 1 + .../tests/dom/nodes/Node-isEqualNode-iframe2.xml | 1 + .../tests/dom/nodes/Node-isEqualNode-xhtml.xhtml | 84 ++ .../tests/dom/nodes/Node-isEqualNode.html | 161 +++ .../tests/dom/nodes/Node-isSameNode.html | 111 ++ .../tests/dom/nodes/Node-lookupNamespaceURI.html | 124 +++ .../tests/dom/nodes/Node-lookupPrefix.xhtml | 31 + .../tests/dom/nodes/Node-mutation-adoptNode.html | 23 + .../tests/dom/nodes/Node-nodeName-xhtml.xhtml | 42 + .../tests/dom/nodes/Node-nodeName.html | 32 + .../tests/dom/nodes/Node-nodeValue.html | 71 ++ .../tests/dom/nodes/Node-normalize.html | 83 ++ .../tests/dom/nodes/Node-parentElement.html | 82 ++ .../tests/dom/nodes/Node-parentNode-iframe.html | 1 + .../tests/dom/nodes/Node-parentNode.html | 33 + .../tests/dom/nodes/Node-properties.html | 688 +++++++++++++ .../tests/dom/nodes/Node-removeChild.html | 58 ++ .../tests/dom/nodes/Node-replaceChild.html | 349 +++++++ .../tests/dom/nodes/Node-textContent.html | 265 +++++ .../tests/dom/nodes/NodeList-Iterable.html | 61 ++ .../dom/nodes/NodeList-live-mutations.window.js | 79 ++ .../NodeList-static-length-getter-tampered-1.html | 22 + .../NodeList-static-length-getter-tampered-2.html | 22 + .../NodeList-static-length-getter-tampered-3.html | 22 + ...st-static-length-getter-tampered-indexOf-1.html | 22 + ...st-static-length-getter-tampered-indexOf-2.html | 22 + ...st-static-length-getter-tampered-indexOf-3.html | 22 + .../tests/dom/nodes/ParentNode-append.html | 67 ++ .../tests/dom/nodes/ParentNode-children.html | 27 + .../tests/dom/nodes/ParentNode-prepend.html | 67 ++ .../ParentNode-querySelector-All-content.html | 377 +++++++ .../nodes/ParentNode-querySelector-All-content.xht | 372 +++++++ .../dom/nodes/ParentNode-querySelector-All-xht.xht | 124 +++ .../dom/nodes/ParentNode-querySelector-All.html | 120 +++ .../dom/nodes/ParentNode-querySelector-All.js | 261 +++++ .../ParentNode-querySelector-case-insensitive.html | 21 + .../nodes/ParentNode-querySelector-escapes.html | 123 +++ .../dom/nodes/ParentNode-querySelector-scope.html | 33 + ...rentNode-querySelectorAll-removed-elements.html | 30 + .../nodes/ParentNode-querySelectors-exclusive.html | 39 + .../ParentNode-querySelectors-namespaces.html | 21 + ...rySelectors-space-and-dash-attribute-value.html | 21 + .../dom/nodes/ParentNode-replaceChildren.html | 205 ++++ .../nodes/ProcessingInstruction-escapes-1.xhtml | 33 + .../nodes/ProcessingInstruction-literal-1.xhtml | 16 + .../nodes/ProcessingInstruction-literal-2.xhtml | 21 + .../tests/dom/nodes/Text-constructor.html | 11 + .../tests/dom/nodes/Text-splitText.html | 53 + .../tests/dom/nodes/Text-wholeText.html | 46 + .../tests/dom/nodes/adoption.window.js | 58 ++ .../tests/dom/nodes/append-on-Document.html | 53 + .../tests/dom/nodes/attributes-namednodemap.html | 120 +++ .../web-platform/tests/dom/nodes/attributes.html | 858 ++++++++++++++++ testing/web-platform/tests/dom/nodes/attributes.js | 18 + testing/web-platform/tests/dom/nodes/case.html | 18 + testing/web-platform/tests/dom/nodes/case.js | 186 ++++ .../tests/dom/nodes/characterset-helper.js | 62 ++ testing/web-platform/tests/dom/nodes/creators.js | 5 + testing/web-platform/tests/dom/nodes/encoding.py | 7 + .../tests/dom/nodes/getElementsByClassName-01.htm | 13 + .../tests/dom/nodes/getElementsByClassName-02.htm | 14 + .../tests/dom/nodes/getElementsByClassName-03.htm | 18 + .../tests/dom/nodes/getElementsByClassName-04.htm | 18 + .../tests/dom/nodes/getElementsByClassName-05.htm | 18 + .../tests/dom/nodes/getElementsByClassName-06.htm | 20 + .../tests/dom/nodes/getElementsByClassName-07.htm | 15 + .../tests/dom/nodes/getElementsByClassName-08.htm | 15 + .../tests/dom/nodes/getElementsByClassName-09.htm | 15 + .../tests/dom/nodes/getElementsByClassName-10.xml | 19 + .../tests/dom/nodes/getElementsByClassName-11.xml | 24 + .../tests/dom/nodes/getElementsByClassName-12.htm | 15 + .../tests/dom/nodes/getElementsByClassName-13.htm | 19 + .../tests/dom/nodes/getElementsByClassName-14.htm | 26 + .../tests/dom/nodes/getElementsByClassName-15.htm | 18 + .../tests/dom/nodes/getElementsByClassName-16.htm | 16 + .../tests/dom/nodes/getElementsByClassName-17.htm | 15 + .../tests/dom/nodes/getElementsByClassName-18.htm | 17 + .../tests/dom/nodes/getElementsByClassName-19.htm | 54 + .../tests/dom/nodes/getElementsByClassName-20.htm | 61 ++ .../tests/dom/nodes/getElementsByClassName-21.htm | 52 + .../tests/dom/nodes/getElementsByClassName-22.htm | 58 ++ .../tests/dom/nodes/getElementsByClassName-23.htm | 52 + .../tests/dom/nodes/getElementsByClassName-24.htm | 30 + .../tests/dom/nodes/getElementsByClassName-25.htm | 57 ++ .../tests/dom/nodes/getElementsByClassName-26.htm | 30 + .../tests/dom/nodes/getElementsByClassName-27.htm | 32 + .../tests/dom/nodes/getElementsByClassName-28.htm | 31 + .../tests/dom/nodes/getElementsByClassName-29.htm | 51 + .../tests/dom/nodes/getElementsByClassName-30.htm | 190 ++++ .../tests/dom/nodes/getElementsByClassName-31.htm | 22 + .../tests/dom/nodes/getElementsByClassName-32.html | 68 ++ .../nodes/getElementsByClassName-empty-set.html | 29 + ...ElementsByClassName-whitespace-class-names.html | 50 + .../dom/nodes/getElementsByClassNameFrame.htm | 6 + .../tests/dom/nodes/insert-adjacent.html | 79 ++ .../tests/dom/nodes/mutationobservers.js | 76 ++ .../tests/dom/nodes/node-appendchild-crash.html | 18 + .../nodes/pre-insertion-validation-hierarchy.js | 86 ++ .../dom/nodes/pre-insertion-validation-notfound.js | 108 ++ .../tests/dom/nodes/prepend-on-Document.html | 53 + .../web-platform/tests/dom/nodes/productions.js | 3 + .../dom/nodes/query-target-in-load-event.html | 13 + .../dom/nodes/query-target-in-load-event.part.html | 10 + .../tests/dom/nodes/remove-and-adopt-thcrash.html | 18 + ...from-shadow-host-and-adopt-into-iframe-ref.html | 4 + ...ove-from-shadow-host-and-adopt-into-iframe.html | 29 + .../tests/dom/nodes/remove-unscopable.html | 32 + testing/web-platform/tests/dom/nodes/rootNode.html | 96 ++ testing/web-platform/tests/dom/nodes/selectors.js | 755 ++++++++++++++ .../support/NodeList-static-length-tampered.js | 46 + .../dom/nodes/svg-template-querySelector.html | 29 + .../tests/dom/ranges/Range-adopt-test.html | 52 + .../tests/dom/ranges/Range-attributes.html | 23 + .../tests/dom/ranges/Range-cloneContents.html | 461 +++++++++ .../tests/dom/ranges/Range-cloneRange.html | 112 ++ .../tests/dom/ranges/Range-collapse.html | 67 ++ .../ranges/Range-commonAncestorContainer-2.html | 33 + .../dom/ranges/Range-commonAncestorContainer.html | 40 + .../dom/ranges/Range-compareBoundaryPoints.html | 182 ++++ .../tests/dom/ranges/Range-comparePoint-2.html | 23 + .../tests/dom/ranges/Range-comparePoint.html | 92 ++ .../tests/dom/ranges/Range-constructor.html | 20 + .../tests/dom/ranges/Range-deleteContents.html | 337 ++++++ .../tests/dom/ranges/Range-detach.html | 14 + .../tests/dom/ranges/Range-extractContents.html | 252 +++++ .../tests/dom/ranges/Range-insertNode.html | 286 ++++++ .../tests/dom/ranges/Range-intersectsNode-2.html | 36 + .../dom/ranges/Range-intersectsNode-binding.html | 25 + .../dom/ranges/Range-intersectsNode-shadow.html | 19 + .../tests/dom/ranges/Range-intersectsNode.html | 70 ++ .../tests/dom/ranges/Range-isPointInRange.html | 83 ++ .../dom/ranges/Range-mutations-appendChild.html | 14 + .../dom/ranges/Range-mutations-appendData.html | 14 + .../dom/ranges/Range-mutations-dataChange.html | 14 + .../dom/ranges/Range-mutations-deleteData.html | 14 + .../dom/ranges/Range-mutations-insertBefore.html | 14 + .../dom/ranges/Range-mutations-insertData.html | 14 + .../dom/ranges/Range-mutations-removeChild.html | 14 + .../dom/ranges/Range-mutations-replaceChild.html | 14 + .../dom/ranges/Range-mutations-replaceData.html | 14 + .../dom/ranges/Range-mutations-splitText.html | 14 + .../tests/dom/ranges/Range-mutations.js | 921 +++++++++++++++++ .../tests/dom/ranges/Range-selectNode.html | 99 ++ .../web-platform/tests/dom/ranges/Range-set.html | 221 ++++ .../tests/dom/ranges/Range-stringifier.html | 44 + .../tests/dom/ranges/Range-surroundContents.html | 324 ++++++ .../tests/dom/ranges/Range-test-iframe.html | 56 + .../tests/dom/ranges/StaticRange-constructor.html | 200 ++++ .../web-platform/tests/dom/slot-recalc-ref.html | 5 + testing/web-platform/tests/dom/slot-recalc.html | 23 + .../web-platform/tests/dom/svg-insert-crash.html | 18 + .../tests/dom/traversal/NodeFilter-constants.html | 34 + .../tests/dom/traversal/NodeIterator-removal.html | 100 ++ .../tests/dom/traversal/NodeIterator.html | 215 ++++ ...e-filter-cross-realm-null-browsing-context.html | 30 + .../TreeWalker-acceptNode-filter-cross-realm.html | 60 ++ .../traversal/TreeWalker-acceptNode-filter.html | 195 ++++ .../tests/dom/traversal/TreeWalker-basic.html | 154 +++ .../dom/traversal/TreeWalker-currentNode.html | 73 ++ .../TreeWalker-previousNodeLastChildReject.html | 87 ++ .../TreeWalker-previousSiblingLastChildSkip.html | 91 ++ .../dom/traversal/TreeWalker-traversal-reject.html | 109 ++ .../traversal/TreeWalker-traversal-skip-most.html | 66 ++ .../dom/traversal/TreeWalker-traversal-skip.html | 111 ++ .../TreeWalker-walking-outside-a-tree.html | 40 + .../tests/dom/traversal/TreeWalker.html | 324 ++++++ ...cross-realm-null-browsing-context-subframe.html | 13 + .../tests/dom/traversal/support/assert-node.js | 10 + .../dom/traversal/support/empty-document.html | 3 + .../tests/dom/traversal/unfinished/001.xml | 53 + .../tests/dom/traversal/unfinished/002.xml | 54 + .../tests/dom/traversal/unfinished/003.xml | 58 ++ .../tests/dom/traversal/unfinished/004.xml | 49 + .../tests/dom/traversal/unfinished/005.xml | 57 ++ .../tests/dom/traversal/unfinished/006.xml | 47 + .../tests/dom/traversal/unfinished/007.xml | 54 + .../tests/dom/traversal/unfinished/008.xml | 48 + .../tests/dom/traversal/unfinished/009.xml | 55 + .../tests/dom/traversal/unfinished/010.xml | 64 ++ .../tests/dom/traversal/unfinished/TODO | 1 + .../tests/dom/window-extends-event-target.html | 55 + testing/web-platform/tests/dom/xslt/README.md | 11 + .../web-platform/tests/dom/xslt/externalScript.js | 1 + .../dom/xslt/invalid-output-encoding-crash.html | 26 + testing/web-platform/tests/dom/xslt/sort-ref.html | 10 + testing/web-platform/tests/dom/xslt/sort.html | 48 + .../tests/dom/xslt/strip-space-crash.xml | 33 + ...gment-on-node-from-inactive-document-crash.html | 11 + .../xslt/transformToFragment.tentative.window.js | 39 + 588 files changed, 37302 insertions(+) create mode 100644 testing/web-platform/tests/dom/META.yml create mode 100644 testing/web-platform/tests/dom/abort/AbortSignal.any.js create mode 100644 testing/web-platform/tests/dom/abort/abort-signal-any.tentative.any.js create mode 100644 testing/web-platform/tests/dom/abort/abort-signal-timeout.html create mode 100644 testing/web-platform/tests/dom/abort/crashtests/timeout-close.html create mode 100644 testing/web-platform/tests/dom/abort/event.any.js create mode 100644 testing/web-platform/tests/dom/abort/reason-constructor.html create mode 100644 testing/web-platform/tests/dom/abort/resources/abort-signal-any-tests.js create mode 100644 testing/web-platform/tests/dom/attributes-are-nodes.html create mode 100644 testing/web-platform/tests/dom/collections/HTMLCollection-as-prototype.html create mode 100644 testing/web-platform/tests/dom/collections/HTMLCollection-delete.html create mode 100644 testing/web-platform/tests/dom/collections/HTMLCollection-empty-name.html create mode 100644 testing/web-platform/tests/dom/collections/HTMLCollection-iterator.html create mode 100644 testing/web-platform/tests/dom/collections/HTMLCollection-live-mutations.window.js create mode 100644 testing/web-platform/tests/dom/collections/HTMLCollection-own-props.html create mode 100644 testing/web-platform/tests/dom/collections/HTMLCollection-supported-property-indices.html create mode 100644 testing/web-platform/tests/dom/collections/HTMLCollection-supported-property-names.html create mode 100644 testing/web-platform/tests/dom/collections/domstringmap-supported-property-names.html create mode 100644 testing/web-platform/tests/dom/collections/namednodemap-supported-property-names.html create mode 100644 testing/web-platform/tests/dom/common.js create mode 100644 testing/web-platform/tests/dom/constants.js create mode 100644 testing/web-platform/tests/dom/eventPathRemoved.html create mode 100644 testing/web-platform/tests/dom/events/AddEventListenerOptions-once.any.js create mode 100644 testing/web-platform/tests/dom/events/AddEventListenerOptions-passive.any.js create mode 100644 testing/web-platform/tests/dom/events/AddEventListenerOptions-signal.any.js create mode 100644 testing/web-platform/tests/dom/events/Body-FrameSet-Event-Handlers.html create mode 100644 testing/web-platform/tests/dom/events/CustomEvent.html create mode 100644 testing/web-platform/tests/dom/events/Event-cancelBubble.html create mode 100644 testing/web-platform/tests/dom/events/Event-constants.html create mode 100644 testing/web-platform/tests/dom/events/Event-constructors.any.js create mode 100644 testing/web-platform/tests/dom/events/Event-defaultPrevented-after-dispatch.html create mode 100644 testing/web-platform/tests/dom/events/Event-defaultPrevented.html create mode 100644 testing/web-platform/tests/dom/events/Event-dispatch-bubble-canceled.html create mode 100644 testing/web-platform/tests/dom/events/Event-dispatch-bubbles-false.html create mode 100644 testing/web-platform/tests/dom/events/Event-dispatch-bubbles-true.html create mode 100644 testing/web-platform/tests/dom/events/Event-dispatch-click.html create mode 100644 testing/web-platform/tests/dom/events/Event-dispatch-click.tentative.html create mode 100644 testing/web-platform/tests/dom/events/Event-dispatch-detached-click.html create mode 100644 testing/web-platform/tests/dom/events/Event-dispatch-detached-input-and-change.html create mode 100644 testing/web-platform/tests/dom/events/Event-dispatch-handlers-changed.html create mode 100644 testing/web-platform/tests/dom/events/Event-dispatch-listener-order.window.js create mode 100644 testing/web-platform/tests/dom/events/Event-dispatch-multiple-cancelBubble.html create mode 100644 testing/web-platform/tests/dom/events/Event-dispatch-multiple-stopPropagation.html create mode 100644 testing/web-platform/tests/dom/events/Event-dispatch-omitted-capture.html create mode 100644 testing/web-platform/tests/dom/events/Event-dispatch-on-disabled-elements.html create mode 100644 testing/web-platform/tests/dom/events/Event-dispatch-order-at-target.html create mode 100644 testing/web-platform/tests/dom/events/Event-dispatch-order.html create mode 100644 testing/web-platform/tests/dom/events/Event-dispatch-other-document.html create mode 100644 testing/web-platform/tests/dom/events/Event-dispatch-propagation-stopped.html create mode 100644 testing/web-platform/tests/dom/events/Event-dispatch-redispatch.html create mode 100644 testing/web-platform/tests/dom/events/Event-dispatch-reenter.html create mode 100644 testing/web-platform/tests/dom/events/Event-dispatch-target-moved.html create mode 100644 testing/web-platform/tests/dom/events/Event-dispatch-target-removed.html create mode 100644 testing/web-platform/tests/dom/events/Event-dispatch-throwing.html create mode 100644 testing/web-platform/tests/dom/events/Event-init-while-dispatching.html create mode 100644 testing/web-platform/tests/dom/events/Event-initEvent.html create mode 100644 testing/web-platform/tests/dom/events/Event-isTrusted.any.js create mode 100644 testing/web-platform/tests/dom/events/Event-propagation.html create mode 100644 testing/web-platform/tests/dom/events/Event-returnValue.html create mode 100644 testing/web-platform/tests/dom/events/Event-stopImmediatePropagation.html create mode 100644 testing/web-platform/tests/dom/events/Event-stopPropagation-cancel-bubbling.html create mode 100644 testing/web-platform/tests/dom/events/Event-subclasses-constructors.html create mode 100644 testing/web-platform/tests/dom/events/Event-timestamp-cross-realm-getter.html create mode 100644 testing/web-platform/tests/dom/events/Event-timestamp-high-resolution.html create mode 100644 testing/web-platform/tests/dom/events/Event-timestamp-high-resolution.https.html create mode 100644 testing/web-platform/tests/dom/events/Event-timestamp-safe-resolution.html create mode 100644 testing/web-platform/tests/dom/events/Event-type-empty.html create mode 100644 testing/web-platform/tests/dom/events/Event-type.html create mode 100644 testing/web-platform/tests/dom/events/EventListener-addEventListener.sub.window.js create mode 100644 testing/web-platform/tests/dom/events/EventListener-handleEvent-cross-realm.html create mode 100644 testing/web-platform/tests/dom/events/EventListener-handleEvent.html create mode 100644 testing/web-platform/tests/dom/events/EventListener-incumbent-global-1.sub.html create mode 100644 testing/web-platform/tests/dom/events/EventListener-incumbent-global-2.sub.html create mode 100644 testing/web-platform/tests/dom/events/EventListener-incumbent-global-subframe-1.sub.html create mode 100644 testing/web-platform/tests/dom/events/EventListener-incumbent-global-subframe-2.sub.html create mode 100644 testing/web-platform/tests/dom/events/EventListener-incumbent-global-subsubframe.sub.html create mode 100644 testing/web-platform/tests/dom/events/EventListener-invoke-legacy.html create mode 100644 testing/web-platform/tests/dom/events/EventListenerOptions-capture.html create mode 100644 testing/web-platform/tests/dom/events/EventTarget-add-listener-platform-object.html create mode 100644 testing/web-platform/tests/dom/events/EventTarget-add-remove-listener.any.js create mode 100644 testing/web-platform/tests/dom/events/EventTarget-addEventListener.any.js create mode 100644 testing/web-platform/tests/dom/events/EventTarget-constructible.any.js create mode 100644 testing/web-platform/tests/dom/events/EventTarget-dispatchEvent-returnvalue.html create mode 100644 testing/web-platform/tests/dom/events/EventTarget-dispatchEvent.html create mode 100644 testing/web-platform/tests/dom/events/EventTarget-removeEventListener.any.js create mode 100644 testing/web-platform/tests/dom/events/EventTarget-this-of-listener.html create mode 100644 testing/web-platform/tests/dom/events/KeyEvent-initKeyEvent.html create mode 100644 testing/web-platform/tests/dom/events/event-disabled-dynamic.html create mode 100644 testing/web-platform/tests/dom/events/event-global-extra.window.js create mode 100644 testing/web-platform/tests/dom/events/event-global-is-still-set-when-coercing-beforeunload-result.html create mode 100644 testing/web-platform/tests/dom/events/event-global-is-still-set-when-reporting-exception-onerror.html create mode 100644 testing/web-platform/tests/dom/events/event-global-set-before-handleEvent-lookup.window.js create mode 100644 testing/web-platform/tests/dom/events/event-global.html create mode 100644 testing/web-platform/tests/dom/events/event-global.worker.js create mode 100644 testing/web-platform/tests/dom/events/focus-event-document-move.html create mode 100644 testing/web-platform/tests/dom/events/keypress-dispatch-crash.html create mode 100644 testing/web-platform/tests/dom/events/legacy-pre-activation-behavior.window.js create mode 100644 testing/web-platform/tests/dom/events/mouse-event-retarget.html create mode 100644 testing/web-platform/tests/dom/events/no-focus-events-at-clicking-editable-content-in-link.html create mode 100644 testing/web-platform/tests/dom/events/non-cancelable-when-passive/non-passive-mousewheel-event-listener-on-body.html create mode 100644 testing/web-platform/tests/dom/events/non-cancelable-when-passive/non-passive-mousewheel-event-listener-on-div.html create mode 100644 testing/web-platform/tests/dom/events/non-cancelable-when-passive/non-passive-mousewheel-event-listener-on-document.html create mode 100644 testing/web-platform/tests/dom/events/non-cancelable-when-passive/non-passive-mousewheel-event-listener-on-root.html create mode 100644 testing/web-platform/tests/dom/events/non-cancelable-when-passive/non-passive-mousewheel-event-listener-on-window.html create mode 100644 testing/web-platform/tests/dom/events/non-cancelable-when-passive/non-passive-touchmove-event-listener-on-body.html create mode 100644 testing/web-platform/tests/dom/events/non-cancelable-when-passive/non-passive-touchmove-event-listener-on-div.html create mode 100644 testing/web-platform/tests/dom/events/non-cancelable-when-passive/non-passive-touchmove-event-listener-on-document.html create mode 100644 testing/web-platform/tests/dom/events/non-cancelable-when-passive/non-passive-touchmove-event-listener-on-root.html create mode 100644 testing/web-platform/tests/dom/events/non-cancelable-when-passive/non-passive-touchmove-event-listener-on-window.html create mode 100644 testing/web-platform/tests/dom/events/non-cancelable-when-passive/non-passive-touchstart-event-listener-on-body.html create mode 100644 testing/web-platform/tests/dom/events/non-cancelable-when-passive/non-passive-touchstart-event-listener-on-div.html create mode 100644 testing/web-platform/tests/dom/events/non-cancelable-when-passive/non-passive-touchstart-event-listener-on-document.html create mode 100644 testing/web-platform/tests/dom/events/non-cancelable-when-passive/non-passive-touchstart-event-listener-on-root.html create mode 100644 testing/web-platform/tests/dom/events/non-cancelable-when-passive/non-passive-touchstart-event-listener-on-window.html create mode 100644 testing/web-platform/tests/dom/events/non-cancelable-when-passive/non-passive-wheel-event-listener-on-body.html create mode 100644 testing/web-platform/tests/dom/events/non-cancelable-when-passive/non-passive-wheel-event-listener-on-div.html create mode 100644 testing/web-platform/tests/dom/events/non-cancelable-when-passive/non-passive-wheel-event-listener-on-document.html create mode 100644 testing/web-platform/tests/dom/events/non-cancelable-when-passive/non-passive-wheel-event-listener-on-root.html create mode 100644 testing/web-platform/tests/dom/events/non-cancelable-when-passive/non-passive-wheel-event-listener-on-window.html create mode 100644 testing/web-platform/tests/dom/events/non-cancelable-when-passive/passive-mousewheel-event-listener-on-body.html create mode 100644 testing/web-platform/tests/dom/events/non-cancelable-when-passive/passive-mousewheel-event-listener-on-div.html create mode 100644 testing/web-platform/tests/dom/events/non-cancelable-when-passive/passive-mousewheel-event-listener-on-document.html create mode 100644 testing/web-platform/tests/dom/events/non-cancelable-when-passive/passive-mousewheel-event-listener-on-root.html create mode 100644 testing/web-platform/tests/dom/events/non-cancelable-when-passive/passive-mousewheel-event-listener-on-window.html create mode 100644 testing/web-platform/tests/dom/events/non-cancelable-when-passive/passive-touchmove-event-listener-on-body.html create mode 100644 testing/web-platform/tests/dom/events/non-cancelable-when-passive/passive-touchmove-event-listener-on-div.html create mode 100644 testing/web-platform/tests/dom/events/non-cancelable-when-passive/passive-touchmove-event-listener-on-document.html create mode 100644 testing/web-platform/tests/dom/events/non-cancelable-when-passive/passive-touchmove-event-listener-on-root.html create mode 100644 testing/web-platform/tests/dom/events/non-cancelable-when-passive/passive-touchmove-event-listener-on-window.html create mode 100644 testing/web-platform/tests/dom/events/non-cancelable-when-passive/passive-touchstart-event-listener-on-body.html create mode 100644 testing/web-platform/tests/dom/events/non-cancelable-when-passive/passive-touchstart-event-listener-on-div.html create mode 100644 testing/web-platform/tests/dom/events/non-cancelable-when-passive/passive-touchstart-event-listener-on-document.html create mode 100644 testing/web-platform/tests/dom/events/non-cancelable-when-passive/passive-touchstart-event-listener-on-root.html create mode 100644 testing/web-platform/tests/dom/events/non-cancelable-when-passive/passive-touchstart-event-listener-on-window.html create mode 100644 testing/web-platform/tests/dom/events/non-cancelable-when-passive/passive-wheel-event-listener-on-body.html create mode 100644 testing/web-platform/tests/dom/events/non-cancelable-when-passive/passive-wheel-event-listener-on-div.html create mode 100644 testing/web-platform/tests/dom/events/non-cancelable-when-passive/passive-wheel-event-listener-on-document.html create mode 100644 testing/web-platform/tests/dom/events/non-cancelable-when-passive/passive-wheel-event-listener-on-root.html create mode 100644 testing/web-platform/tests/dom/events/non-cancelable-when-passive/passive-wheel-event-listener-on-window.html create mode 100644 testing/web-platform/tests/dom/events/non-cancelable-when-passive/resources/scrolling.js create mode 100644 testing/web-platform/tests/dom/events/non-cancelable-when-passive/resources/touching.js create mode 100644 testing/web-platform/tests/dom/events/non-cancelable-when-passive/resources/wait-for.js create mode 100644 testing/web-platform/tests/dom/events/non-cancelable-when-passive/synthetic-events-cancelable.html create mode 100644 testing/web-platform/tests/dom/events/passive-by-default.html create mode 100644 testing/web-platform/tests/dom/events/relatedTarget.window.js create mode 100644 testing/web-platform/tests/dom/events/replace-event-listener-null-browsing-context-crash.html create mode 100644 testing/web-platform/tests/dom/events/resources/empty-document.html create mode 100644 testing/web-platform/tests/dom/events/resources/event-global-extra-frame.html create mode 100644 testing/web-platform/tests/dom/events/resources/event-global-is-still-set-when-coercing-beforeunload-result-frame.html create mode 100644 testing/web-platform/tests/dom/events/resources/prefixed-animation-event-tests.js create mode 100644 testing/web-platform/tests/dom/events/scrolling/iframe-chains.html create mode 100644 testing/web-platform/tests/dom/events/scrolling/input-text-scroll-event-when-using-arrow-keys.html create mode 100644 testing/web-platform/tests/dom/events/scrolling/overscroll-deltas.html create mode 100644 testing/web-platform/tests/dom/events/scrolling/overscroll-event-fired-to-document.html create mode 100644 testing/web-platform/tests/dom/events/scrolling/overscroll-event-fired-to-element-with-overscroll-behavior.html create mode 100644 testing/web-platform/tests/dom/events/scrolling/overscroll-event-fired-to-scrolled-element.html create mode 100644 testing/web-platform/tests/dom/events/scrolling/overscroll-event-fired-to-window.html create mode 100644 testing/web-platform/tests/dom/events/scrolling/scroll_support.js create mode 100644 testing/web-platform/tests/dom/events/scrolling/scrollend-event-fired-after-sequence-of-scrolls.tentative.html create mode 100644 testing/web-platform/tests/dom/events/scrolling/scrollend-event-fired-after-snap.html create mode 100644 testing/web-platform/tests/dom/events/scrolling/scrollend-event-fired-for-programmatic-scroll.html create mode 100644 testing/web-platform/tests/dom/events/scrolling/scrollend-event-fired-for-scrollIntoView.html create mode 100644 testing/web-platform/tests/dom/events/scrolling/scrollend-event-fired-to-document.html create mode 100644 testing/web-platform/tests/dom/events/scrolling/scrollend-event-fired-to-element-with-overscroll-behavior.html create mode 100644 testing/web-platform/tests/dom/events/scrolling/scrollend-event-fired-to-scrolled-element.html create mode 100644 testing/web-platform/tests/dom/events/scrolling/scrollend-event-fired-to-window.html create mode 100644 testing/web-platform/tests/dom/events/scrolling/scrollend-event-for-user-scroll.html create mode 100644 testing/web-platform/tests/dom/events/scrolling/scrollend-event-handler-content-attributes.html create mode 100644 testing/web-platform/tests/dom/events/scrolling/scrollend-event-not-fired-after-removing-scroller.tentative.html create mode 100644 testing/web-platform/tests/dom/events/shadow-relatedTarget.html create mode 100644 testing/web-platform/tests/dom/events/webkit-animation-end-event.html create mode 100644 testing/web-platform/tests/dom/events/webkit-animation-iteration-event.html create mode 100644 testing/web-platform/tests/dom/events/webkit-animation-start-event.html create mode 100644 testing/web-platform/tests/dom/events/webkit-transition-end-event.html create mode 100644 testing/web-platform/tests/dom/historical.html create mode 100644 testing/web-platform/tests/dom/idlharness-shadowrealm.window.js create mode 100644 testing/web-platform/tests/dom/idlharness.any.js create mode 100644 testing/web-platform/tests/dom/idlharness.window.js create mode 100644 testing/web-platform/tests/dom/interface-objects.html create mode 100644 testing/web-platform/tests/dom/lists/DOMTokenList-Iterable.html create mode 100644 testing/web-platform/tests/dom/lists/DOMTokenList-coverage-for-attributes.html create mode 100644 testing/web-platform/tests/dom/lists/DOMTokenList-iteration.html create mode 100644 testing/web-platform/tests/dom/lists/DOMTokenList-stringifier.html create mode 100644 testing/web-platform/tests/dom/lists/DOMTokenList-value.html create mode 100644 testing/web-platform/tests/dom/lists/README.md create mode 100644 testing/web-platform/tests/dom/nodes/CharacterData-appendChild.html create mode 100644 testing/web-platform/tests/dom/nodes/CharacterData-appendData.html create mode 100644 testing/web-platform/tests/dom/nodes/CharacterData-data.html create mode 100644 testing/web-platform/tests/dom/nodes/CharacterData-deleteData.html create mode 100644 testing/web-platform/tests/dom/nodes/CharacterData-insertData.html create mode 100644 testing/web-platform/tests/dom/nodes/CharacterData-remove.html create mode 100644 testing/web-platform/tests/dom/nodes/CharacterData-replaceData.html create mode 100644 testing/web-platform/tests/dom/nodes/CharacterData-substringData.html create mode 100644 testing/web-platform/tests/dom/nodes/CharacterData-surrogates.html create mode 100644 testing/web-platform/tests/dom/nodes/ChildNode-after.html create mode 100644 testing/web-platform/tests/dom/nodes/ChildNode-before.html create mode 100644 testing/web-platform/tests/dom/nodes/ChildNode-remove.js create mode 100644 testing/web-platform/tests/dom/nodes/ChildNode-replaceWith.html create mode 100644 testing/web-platform/tests/dom/nodes/Comment-Text-constructor.js create mode 100644 testing/web-platform/tests/dom/nodes/Comment-constructor.html create mode 100644 testing/web-platform/tests/dom/nodes/DOMImplementation-createDocument-with-null-browsing-context-crash.html create mode 100644 testing/web-platform/tests/dom/nodes/DOMImplementation-createDocument.html create mode 100644 testing/web-platform/tests/dom/nodes/DOMImplementation-createDocumentType.html create mode 100644 testing/web-platform/tests/dom/nodes/DOMImplementation-createHTMLDocument-with-null-browsing-context-crash.html create mode 100644 testing/web-platform/tests/dom/nodes/DOMImplementation-createHTMLDocument-with-saved-implementation.html create mode 100644 testing/web-platform/tests/dom/nodes/DOMImplementation-createHTMLDocument.html create mode 100644 testing/web-platform/tests/dom/nodes/DOMImplementation-createHTMLDocument.js create mode 100644 testing/web-platform/tests/dom/nodes/DOMImplementation-hasFeature.html create mode 100644 testing/web-platform/tests/dom/nodes/Document-Element-getElementsByTagName.js create mode 100644 testing/web-platform/tests/dom/nodes/Document-Element-getElementsByTagNameNS.js create mode 100644 testing/web-platform/tests/dom/nodes/Document-URL.html create mode 100644 testing/web-platform/tests/dom/nodes/Document-adoptNode.html create mode 100644 testing/web-platform/tests/dom/nodes/Document-characterSet-normalization-1.html create mode 100644 testing/web-platform/tests/dom/nodes/Document-characterSet-normalization-2.html create mode 100644 testing/web-platform/tests/dom/nodes/Document-constructor-svg.svg create mode 100644 testing/web-platform/tests/dom/nodes/Document-constructor-xml.xml create mode 100644 testing/web-platform/tests/dom/nodes/Document-constructor.html create mode 100644 testing/web-platform/tests/dom/nodes/Document-contentType/contentType/contenttype_bmp.html create mode 100644 testing/web-platform/tests/dom/nodes/Document-contentType/contentType/contenttype_css.html create mode 100644 testing/web-platform/tests/dom/nodes/Document-contentType/contentType/contenttype_datauri_02.html create mode 100644 testing/web-platform/tests/dom/nodes/Document-contentType/contentType/contenttype_gif.html create mode 100644 testing/web-platform/tests/dom/nodes/Document-contentType/contentType/contenttype_html.html create mode 100644 testing/web-platform/tests/dom/nodes/Document-contentType/contentType/contenttype_javascripturi.html create mode 100644 testing/web-platform/tests/dom/nodes/Document-contentType/contentType/contenttype_jpg.html create mode 100644 testing/web-platform/tests/dom/nodes/Document-contentType/contentType/contenttype_mimeheader_01.html create mode 100644 testing/web-platform/tests/dom/nodes/Document-contentType/contentType/contenttype_mimeheader_02.html create mode 100644 testing/web-platform/tests/dom/nodes/Document-contentType/contentType/contenttype_png.html create mode 100644 testing/web-platform/tests/dom/nodes/Document-contentType/contentType/contenttype_txt.html create mode 100644 testing/web-platform/tests/dom/nodes/Document-contentType/contentType/contenttype_xml.html create mode 100644 testing/web-platform/tests/dom/nodes/Document-contentType/contentType/createDocument.html create mode 100644 testing/web-platform/tests/dom/nodes/Document-contentType/contentType/createHTMLDocument.html create mode 100644 testing/web-platform/tests/dom/nodes/Document-contentType/contentType/xhr_responseType_document.html create mode 100644 testing/web-platform/tests/dom/nodes/Document-contentType/resources/blob.htm create mode 100644 testing/web-platform/tests/dom/nodes/Document-contentType/resources/blob.txt create mode 100644 testing/web-platform/tests/dom/nodes/Document-contentType/resources/blob.xml create mode 100644 testing/web-platform/tests/dom/nodes/Document-contentType/resources/lib.js create mode 100644 testing/web-platform/tests/dom/nodes/Document-contentType/resources/style.css create mode 100644 testing/web-platform/tests/dom/nodes/Document-contentType/resources/t.bmp create mode 100644 testing/web-platform/tests/dom/nodes/Document-contentType/resources/t.gif create mode 100644 testing/web-platform/tests/dom/nodes/Document-contentType/resources/t.jpg create mode 100644 testing/web-platform/tests/dom/nodes/Document-contentType/resources/t.png create mode 100644 testing/web-platform/tests/dom/nodes/Document-contentType/support/contenttype_setter.py create mode 100644 testing/web-platform/tests/dom/nodes/Document-createAttribute.html create mode 100644 testing/web-platform/tests/dom/nodes/Document-createCDATASection-xhtml.xhtml create mode 100644 testing/web-platform/tests/dom/nodes/Document-createCDATASection.html create mode 100644 testing/web-platform/tests/dom/nodes/Document-createComment-createTextNode.js create mode 100644 testing/web-platform/tests/dom/nodes/Document-createComment.html create mode 100644 testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/bare_mathml.html create mode 100644 testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/bare_mathml.svg create mode 100644 testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/bare_mathml.xhtml create mode 100644 testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/bare_mathml.xml create mode 100644 testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/bare_svg.html create mode 100644 testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/bare_svg.svg create mode 100644 testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/bare_svg.xhtml create mode 100644 testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/bare_svg.xml create mode 100644 testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/bare_xhtml.html create mode 100644 testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/bare_xhtml.svg create mode 100644 testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/bare_xhtml.xhtml create mode 100644 testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/bare_xhtml.xml create mode 100644 testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/empty.html create mode 100644 testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/empty.svg create mode 100644 testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/empty.xhtml create mode 100644 testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/empty.xml create mode 100755 testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/generate.py create mode 100644 testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/mathml.html create mode 100644 testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/mathml.svg create mode 100644 testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/mathml.xhtml create mode 100644 testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/mathml.xml create mode 100644 testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/minimal_html.html create mode 100644 testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/minimal_html.svg create mode 100644 testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/minimal_html.xhtml create mode 100644 testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/minimal_html.xml create mode 100644 testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/svg.html create mode 100644 testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/svg.svg create mode 100644 testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/svg.xhtml create mode 100644 testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/svg.xml create mode 100644 testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/xhtml.html create mode 100644 testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/xhtml.svg create mode 100644 testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/xhtml.xhtml create mode 100644 testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/xhtml.xml create mode 100644 testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/xhtml_ns_changed.html create mode 100644 testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/xhtml_ns_changed.svg create mode 100644 testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/xhtml_ns_changed.xhtml create mode 100644 testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/xhtml_ns_changed.xml create mode 100644 testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/xhtml_ns_removed.html create mode 100644 testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/xhtml_ns_removed.svg create mode 100644 testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/xhtml_ns_removed.xhtml create mode 100644 testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/xhtml_ns_removed.xml create mode 100644 testing/web-platform/tests/dom/nodes/Document-createElement-namespace.html create mode 100644 testing/web-platform/tests/dom/nodes/Document-createElement.html create mode 100644 testing/web-platform/tests/dom/nodes/Document-createElementNS.html create mode 100644 testing/web-platform/tests/dom/nodes/Document-createElementNS.js create mode 100644 testing/web-platform/tests/dom/nodes/Document-createEvent-touchevent.window.js create mode 100644 testing/web-platform/tests/dom/nodes/Document-createEvent.https.html create mode 100644 testing/web-platform/tests/dom/nodes/Document-createEvent.js create mode 100644 testing/web-platform/tests/dom/nodes/Document-createProcessingInstruction-xhtml.xhtml create mode 100644 testing/web-platform/tests/dom/nodes/Document-createProcessingInstruction.html create mode 100644 testing/web-platform/tests/dom/nodes/Document-createProcessingInstruction.js create mode 100644 testing/web-platform/tests/dom/nodes/Document-createTextNode.html create mode 100644 testing/web-platform/tests/dom/nodes/Document-createTreeWalker.html create mode 100644 testing/web-platform/tests/dom/nodes/Document-doctype.html create mode 100644 testing/web-platform/tests/dom/nodes/Document-getElementById.html create mode 100644 testing/web-platform/tests/dom/nodes/Document-getElementsByClassName.html create mode 100644 testing/web-platform/tests/dom/nodes/Document-getElementsByTagName-xhtml.xhtml create mode 100644 testing/web-platform/tests/dom/nodes/Document-getElementsByTagName.html create mode 100644 testing/web-platform/tests/dom/nodes/Document-getElementsByTagNameNS.html create mode 100644 testing/web-platform/tests/dom/nodes/Document-implementation.html create mode 100644 testing/web-platform/tests/dom/nodes/Document-importNode.html create mode 100644 testing/web-platform/tests/dom/nodes/DocumentFragment-constructor.html create mode 100644 testing/web-platform/tests/dom/nodes/DocumentFragment-getElementById.html create mode 100644 testing/web-platform/tests/dom/nodes/DocumentFragment-querySelectorAll-after-modification.html create mode 100644 testing/web-platform/tests/dom/nodes/DocumentType-literal-xhtml.xhtml create mode 100644 testing/web-platform/tests/dom/nodes/DocumentType-literal.html create mode 100644 testing/web-platform/tests/dom/nodes/DocumentType-remove.html create mode 100644 testing/web-platform/tests/dom/nodes/Element-childElement-null-svg.svg create mode 100644 testing/web-platform/tests/dom/nodes/Element-childElement-null-xhtml.xhtml create mode 100644 testing/web-platform/tests/dom/nodes/Element-childElement-null.html create mode 100644 testing/web-platform/tests/dom/nodes/Element-childElementCount-dynamic-add-svg.svg create mode 100644 testing/web-platform/tests/dom/nodes/Element-childElementCount-dynamic-add-xhtml.xhtml create mode 100644 testing/web-platform/tests/dom/nodes/Element-childElementCount-dynamic-add.html create mode 100644 testing/web-platform/tests/dom/nodes/Element-childElementCount-dynamic-remove-svg.svg create mode 100644 testing/web-platform/tests/dom/nodes/Element-childElementCount-dynamic-remove-xhtml.xhtml create mode 100644 testing/web-platform/tests/dom/nodes/Element-childElementCount-dynamic-remove.html create mode 100644 testing/web-platform/tests/dom/nodes/Element-childElementCount-nochild-svg.svg create mode 100644 testing/web-platform/tests/dom/nodes/Element-childElementCount-nochild-xhtml.xhtml create mode 100644 testing/web-platform/tests/dom/nodes/Element-childElementCount-nochild.html create mode 100644 testing/web-platform/tests/dom/nodes/Element-childElementCount-svg.svg create mode 100644 testing/web-platform/tests/dom/nodes/Element-childElementCount-xhtml.xhtml create mode 100644 testing/web-platform/tests/dom/nodes/Element-childElementCount.html create mode 100644 testing/web-platform/tests/dom/nodes/Element-children.html create mode 100644 testing/web-platform/tests/dom/nodes/Element-classlist.html create mode 100644 testing/web-platform/tests/dom/nodes/Element-closest.html create mode 100644 testing/web-platform/tests/dom/nodes/Element-firstElementChild-entity-xhtml.xhtml create mode 100644 testing/web-platform/tests/dom/nodes/Element-firstElementChild-entity.svg create mode 100644 testing/web-platform/tests/dom/nodes/Element-firstElementChild-namespace-svg.svg create mode 100644 testing/web-platform/tests/dom/nodes/Element-firstElementChild-namespace-xhtml.xhtml create mode 100644 testing/web-platform/tests/dom/nodes/Element-firstElementChild-namespace.html create mode 100644 testing/web-platform/tests/dom/nodes/Element-firstElementChild-svg.svg create mode 100644 testing/web-platform/tests/dom/nodes/Element-firstElementChild-xhtml.xhtml create mode 100644 testing/web-platform/tests/dom/nodes/Element-firstElementChild.html create mode 100644 testing/web-platform/tests/dom/nodes/Element-getElementsByClassName.html create mode 100644 testing/web-platform/tests/dom/nodes/Element-getElementsByTagName-change-document-HTMLNess-iframe.xml create mode 100644 testing/web-platform/tests/dom/nodes/Element-getElementsByTagName-change-document-HTMLNess.html create mode 100644 testing/web-platform/tests/dom/nodes/Element-getElementsByTagName.html create mode 100644 testing/web-platform/tests/dom/nodes/Element-getElementsByTagNameNS.html create mode 100644 testing/web-platform/tests/dom/nodes/Element-hasAttribute.html create mode 100644 testing/web-platform/tests/dom/nodes/Element-hasAttributes.html create mode 100644 testing/web-platform/tests/dom/nodes/Element-insertAdjacentElement.html create mode 100644 testing/web-platform/tests/dom/nodes/Element-insertAdjacentText.html create mode 100644 testing/web-platform/tests/dom/nodes/Element-lastElementChild-svg.svg create mode 100644 testing/web-platform/tests/dom/nodes/Element-lastElementChild-xhtml.xhtml create mode 100644 testing/web-platform/tests/dom/nodes/Element-lastElementChild.html create mode 100644 testing/web-platform/tests/dom/nodes/Element-matches-init.js create mode 100644 testing/web-platform/tests/dom/nodes/Element-matches-namespaced-elements.html create mode 100644 testing/web-platform/tests/dom/nodes/Element-matches.html create mode 100644 testing/web-platform/tests/dom/nodes/Element-matches.js create mode 100644 testing/web-platform/tests/dom/nodes/Element-nextElementSibling-svg.svg create mode 100644 testing/web-platform/tests/dom/nodes/Element-nextElementSibling-xhtml.xhtml create mode 100644 testing/web-platform/tests/dom/nodes/Element-nextElementSibling.html create mode 100644 testing/web-platform/tests/dom/nodes/Element-previousElementSibling-svg.svg create mode 100644 testing/web-platform/tests/dom/nodes/Element-previousElementSibling-xhtml.xhtml create mode 100644 testing/web-platform/tests/dom/nodes/Element-previousElementSibling.html create mode 100644 testing/web-platform/tests/dom/nodes/Element-remove.html create mode 100644 testing/web-platform/tests/dom/nodes/Element-removeAttribute.html create mode 100644 testing/web-platform/tests/dom/nodes/Element-removeAttributeNS.html create mode 100644 testing/web-platform/tests/dom/nodes/Element-setAttribute-crbug-1138487.html create mode 100644 testing/web-platform/tests/dom/nodes/Element-setAttribute.html create mode 100644 testing/web-platform/tests/dom/nodes/Element-siblingElement-null-svg.svg create mode 100644 testing/web-platform/tests/dom/nodes/Element-siblingElement-null-xhtml.xhtml create mode 100644 testing/web-platform/tests/dom/nodes/Element-siblingElement-null.html create mode 100644 testing/web-platform/tests/dom/nodes/Element-tagName.html create mode 100644 testing/web-platform/tests/dom/nodes/Element-webkitMatchesSelector.html create mode 100644 testing/web-platform/tests/dom/nodes/MutationObserver-attributes.html create mode 100644 testing/web-platform/tests/dom/nodes/MutationObserver-callback-arguments.html create mode 100644 testing/web-platform/tests/dom/nodes/MutationObserver-characterData.html create mode 100644 testing/web-platform/tests/dom/nodes/MutationObserver-childList.html create mode 100644 testing/web-platform/tests/dom/nodes/MutationObserver-cross-realm-callback-report-exception.html create mode 100644 testing/web-platform/tests/dom/nodes/MutationObserver-disconnect.html create mode 100644 testing/web-platform/tests/dom/nodes/MutationObserver-document.html create mode 100644 testing/web-platform/tests/dom/nodes/MutationObserver-inner-outer.html create mode 100644 testing/web-platform/tests/dom/nodes/MutationObserver-sanity.html create mode 100644 testing/web-platform/tests/dom/nodes/MutationObserver-takeRecords.html create mode 100644 testing/web-platform/tests/dom/nodes/Node-appendChild-cereactions-vs-script.window.js create mode 100644 testing/web-platform/tests/dom/nodes/Node-appendChild.html create mode 100644 testing/web-platform/tests/dom/nodes/Node-baseURI.html create mode 100644 testing/web-platform/tests/dom/nodes/Node-childNodes.html create mode 100644 testing/web-platform/tests/dom/nodes/Node-cloneNode-XMLDocument.html create mode 100644 testing/web-platform/tests/dom/nodes/Node-cloneNode-document-with-doctype.html create mode 100644 testing/web-platform/tests/dom/nodes/Node-cloneNode-external-stylesheet-no-bc.sub.html create mode 100644 testing/web-platform/tests/dom/nodes/Node-cloneNode-on-inactive-document-crash.html create mode 100644 testing/web-platform/tests/dom/nodes/Node-cloneNode-svg.html create mode 100644 testing/web-platform/tests/dom/nodes/Node-cloneNode.html create mode 100644 testing/web-platform/tests/dom/nodes/Node-compareDocumentPosition.html create mode 100644 testing/web-platform/tests/dom/nodes/Node-constants.html create mode 100644 testing/web-platform/tests/dom/nodes/Node-contains-xml.xml create mode 100644 testing/web-platform/tests/dom/nodes/Node-contains.html create mode 100644 testing/web-platform/tests/dom/nodes/Node-insertBefore.html create mode 100644 testing/web-platform/tests/dom/nodes/Node-isConnected-shadow-dom.html create mode 100644 testing/web-platform/tests/dom/nodes/Node-isConnected.html create mode 100644 testing/web-platform/tests/dom/nodes/Node-isEqualNode-iframe1.xml create mode 100644 testing/web-platform/tests/dom/nodes/Node-isEqualNode-iframe2.xml create mode 100644 testing/web-platform/tests/dom/nodes/Node-isEqualNode-xhtml.xhtml create mode 100644 testing/web-platform/tests/dom/nodes/Node-isEqualNode.html create mode 100644 testing/web-platform/tests/dom/nodes/Node-isSameNode.html create mode 100644 testing/web-platform/tests/dom/nodes/Node-lookupNamespaceURI.html create mode 100644 testing/web-platform/tests/dom/nodes/Node-lookupPrefix.xhtml create mode 100644 testing/web-platform/tests/dom/nodes/Node-mutation-adoptNode.html create mode 100644 testing/web-platform/tests/dom/nodes/Node-nodeName-xhtml.xhtml create mode 100644 testing/web-platform/tests/dom/nodes/Node-nodeName.html create mode 100644 testing/web-platform/tests/dom/nodes/Node-nodeValue.html create mode 100644 testing/web-platform/tests/dom/nodes/Node-normalize.html create mode 100644 testing/web-platform/tests/dom/nodes/Node-parentElement.html create mode 100644 testing/web-platform/tests/dom/nodes/Node-parentNode-iframe.html create mode 100644 testing/web-platform/tests/dom/nodes/Node-parentNode.html create mode 100644 testing/web-platform/tests/dom/nodes/Node-properties.html create mode 100644 testing/web-platform/tests/dom/nodes/Node-removeChild.html create mode 100644 testing/web-platform/tests/dom/nodes/Node-replaceChild.html create mode 100644 testing/web-platform/tests/dom/nodes/Node-textContent.html create mode 100644 testing/web-platform/tests/dom/nodes/NodeList-Iterable.html create mode 100644 testing/web-platform/tests/dom/nodes/NodeList-live-mutations.window.js create mode 100644 testing/web-platform/tests/dom/nodes/NodeList-static-length-getter-tampered-1.html create mode 100644 testing/web-platform/tests/dom/nodes/NodeList-static-length-getter-tampered-2.html create mode 100644 testing/web-platform/tests/dom/nodes/NodeList-static-length-getter-tampered-3.html create mode 100644 testing/web-platform/tests/dom/nodes/NodeList-static-length-getter-tampered-indexOf-1.html create mode 100644 testing/web-platform/tests/dom/nodes/NodeList-static-length-getter-tampered-indexOf-2.html create mode 100644 testing/web-platform/tests/dom/nodes/NodeList-static-length-getter-tampered-indexOf-3.html create mode 100644 testing/web-platform/tests/dom/nodes/ParentNode-append.html create mode 100644 testing/web-platform/tests/dom/nodes/ParentNode-children.html create mode 100644 testing/web-platform/tests/dom/nodes/ParentNode-prepend.html create mode 100644 testing/web-platform/tests/dom/nodes/ParentNode-querySelector-All-content.html create mode 100644 testing/web-platform/tests/dom/nodes/ParentNode-querySelector-All-content.xht create mode 100644 testing/web-platform/tests/dom/nodes/ParentNode-querySelector-All-xht.xht create mode 100644 testing/web-platform/tests/dom/nodes/ParentNode-querySelector-All.html create mode 100644 testing/web-platform/tests/dom/nodes/ParentNode-querySelector-All.js create mode 100644 testing/web-platform/tests/dom/nodes/ParentNode-querySelector-case-insensitive.html create mode 100644 testing/web-platform/tests/dom/nodes/ParentNode-querySelector-escapes.html create mode 100644 testing/web-platform/tests/dom/nodes/ParentNode-querySelector-scope.html create mode 100644 testing/web-platform/tests/dom/nodes/ParentNode-querySelectorAll-removed-elements.html create mode 100644 testing/web-platform/tests/dom/nodes/ParentNode-querySelectors-exclusive.html create mode 100644 testing/web-platform/tests/dom/nodes/ParentNode-querySelectors-namespaces.html create mode 100644 testing/web-platform/tests/dom/nodes/ParentNode-querySelectors-space-and-dash-attribute-value.html create mode 100644 testing/web-platform/tests/dom/nodes/ParentNode-replaceChildren.html create mode 100644 testing/web-platform/tests/dom/nodes/ProcessingInstruction-escapes-1.xhtml create mode 100644 testing/web-platform/tests/dom/nodes/ProcessingInstruction-literal-1.xhtml create mode 100644 testing/web-platform/tests/dom/nodes/ProcessingInstruction-literal-2.xhtml create mode 100644 testing/web-platform/tests/dom/nodes/Text-constructor.html create mode 100644 testing/web-platform/tests/dom/nodes/Text-splitText.html create mode 100644 testing/web-platform/tests/dom/nodes/Text-wholeText.html create mode 100644 testing/web-platform/tests/dom/nodes/adoption.window.js create mode 100644 testing/web-platform/tests/dom/nodes/append-on-Document.html create mode 100644 testing/web-platform/tests/dom/nodes/attributes-namednodemap.html create mode 100644 testing/web-platform/tests/dom/nodes/attributes.html create mode 100644 testing/web-platform/tests/dom/nodes/attributes.js create mode 100644 testing/web-platform/tests/dom/nodes/case.html create mode 100644 testing/web-platform/tests/dom/nodes/case.js create mode 100644 testing/web-platform/tests/dom/nodes/characterset-helper.js create mode 100644 testing/web-platform/tests/dom/nodes/creators.js create mode 100644 testing/web-platform/tests/dom/nodes/encoding.py create mode 100644 testing/web-platform/tests/dom/nodes/getElementsByClassName-01.htm create mode 100644 testing/web-platform/tests/dom/nodes/getElementsByClassName-02.htm create mode 100644 testing/web-platform/tests/dom/nodes/getElementsByClassName-03.htm create mode 100644 testing/web-platform/tests/dom/nodes/getElementsByClassName-04.htm create mode 100644 testing/web-platform/tests/dom/nodes/getElementsByClassName-05.htm create mode 100644 testing/web-platform/tests/dom/nodes/getElementsByClassName-06.htm create mode 100644 testing/web-platform/tests/dom/nodes/getElementsByClassName-07.htm create mode 100644 testing/web-platform/tests/dom/nodes/getElementsByClassName-08.htm create mode 100644 testing/web-platform/tests/dom/nodes/getElementsByClassName-09.htm create mode 100644 testing/web-platform/tests/dom/nodes/getElementsByClassName-10.xml create mode 100644 testing/web-platform/tests/dom/nodes/getElementsByClassName-11.xml create mode 100644 testing/web-platform/tests/dom/nodes/getElementsByClassName-12.htm create mode 100644 testing/web-platform/tests/dom/nodes/getElementsByClassName-13.htm create mode 100644 testing/web-platform/tests/dom/nodes/getElementsByClassName-14.htm create mode 100644 testing/web-platform/tests/dom/nodes/getElementsByClassName-15.htm create mode 100644 testing/web-platform/tests/dom/nodes/getElementsByClassName-16.htm create mode 100644 testing/web-platform/tests/dom/nodes/getElementsByClassName-17.htm create mode 100644 testing/web-platform/tests/dom/nodes/getElementsByClassName-18.htm create mode 100644 testing/web-platform/tests/dom/nodes/getElementsByClassName-19.htm create mode 100644 testing/web-platform/tests/dom/nodes/getElementsByClassName-20.htm create mode 100644 testing/web-platform/tests/dom/nodes/getElementsByClassName-21.htm create mode 100644 testing/web-platform/tests/dom/nodes/getElementsByClassName-22.htm create mode 100644 testing/web-platform/tests/dom/nodes/getElementsByClassName-23.htm create mode 100644 testing/web-platform/tests/dom/nodes/getElementsByClassName-24.htm create mode 100644 testing/web-platform/tests/dom/nodes/getElementsByClassName-25.htm create mode 100644 testing/web-platform/tests/dom/nodes/getElementsByClassName-26.htm create mode 100644 testing/web-platform/tests/dom/nodes/getElementsByClassName-27.htm create mode 100644 testing/web-platform/tests/dom/nodes/getElementsByClassName-28.htm create mode 100644 testing/web-platform/tests/dom/nodes/getElementsByClassName-29.htm create mode 100644 testing/web-platform/tests/dom/nodes/getElementsByClassName-30.htm create mode 100644 testing/web-platform/tests/dom/nodes/getElementsByClassName-31.htm create mode 100644 testing/web-platform/tests/dom/nodes/getElementsByClassName-32.html create mode 100644 testing/web-platform/tests/dom/nodes/getElementsByClassName-empty-set.html create mode 100644 testing/web-platform/tests/dom/nodes/getElementsByClassName-whitespace-class-names.html create mode 100644 testing/web-platform/tests/dom/nodes/getElementsByClassNameFrame.htm create mode 100644 testing/web-platform/tests/dom/nodes/insert-adjacent.html create mode 100644 testing/web-platform/tests/dom/nodes/mutationobservers.js create mode 100644 testing/web-platform/tests/dom/nodes/node-appendchild-crash.html create mode 100644 testing/web-platform/tests/dom/nodes/pre-insertion-validation-hierarchy.js create mode 100644 testing/web-platform/tests/dom/nodes/pre-insertion-validation-notfound.js create mode 100644 testing/web-platform/tests/dom/nodes/prepend-on-Document.html create mode 100644 testing/web-platform/tests/dom/nodes/productions.js create mode 100644 testing/web-platform/tests/dom/nodes/query-target-in-load-event.html create mode 100644 testing/web-platform/tests/dom/nodes/query-target-in-load-event.part.html create mode 100644 testing/web-platform/tests/dom/nodes/remove-and-adopt-thcrash.html create mode 100644 testing/web-platform/tests/dom/nodes/remove-from-shadow-host-and-adopt-into-iframe-ref.html create mode 100644 testing/web-platform/tests/dom/nodes/remove-from-shadow-host-and-adopt-into-iframe.html create mode 100644 testing/web-platform/tests/dom/nodes/remove-unscopable.html create mode 100644 testing/web-platform/tests/dom/nodes/rootNode.html create mode 100644 testing/web-platform/tests/dom/nodes/selectors.js create mode 100644 testing/web-platform/tests/dom/nodes/support/NodeList-static-length-tampered.js create mode 100644 testing/web-platform/tests/dom/nodes/svg-template-querySelector.html create mode 100644 testing/web-platform/tests/dom/ranges/Range-adopt-test.html create mode 100644 testing/web-platform/tests/dom/ranges/Range-attributes.html create mode 100644 testing/web-platform/tests/dom/ranges/Range-cloneContents.html create mode 100644 testing/web-platform/tests/dom/ranges/Range-cloneRange.html create mode 100644 testing/web-platform/tests/dom/ranges/Range-collapse.html create mode 100644 testing/web-platform/tests/dom/ranges/Range-commonAncestorContainer-2.html create mode 100644 testing/web-platform/tests/dom/ranges/Range-commonAncestorContainer.html create mode 100644 testing/web-platform/tests/dom/ranges/Range-compareBoundaryPoints.html create mode 100644 testing/web-platform/tests/dom/ranges/Range-comparePoint-2.html create mode 100644 testing/web-platform/tests/dom/ranges/Range-comparePoint.html create mode 100644 testing/web-platform/tests/dom/ranges/Range-constructor.html create mode 100644 testing/web-platform/tests/dom/ranges/Range-deleteContents.html create mode 100644 testing/web-platform/tests/dom/ranges/Range-detach.html create mode 100644 testing/web-platform/tests/dom/ranges/Range-extractContents.html create mode 100644 testing/web-platform/tests/dom/ranges/Range-insertNode.html create mode 100644 testing/web-platform/tests/dom/ranges/Range-intersectsNode-2.html create mode 100644 testing/web-platform/tests/dom/ranges/Range-intersectsNode-binding.html create mode 100644 testing/web-platform/tests/dom/ranges/Range-intersectsNode-shadow.html create mode 100644 testing/web-platform/tests/dom/ranges/Range-intersectsNode.html create mode 100644 testing/web-platform/tests/dom/ranges/Range-isPointInRange.html create mode 100644 testing/web-platform/tests/dom/ranges/Range-mutations-appendChild.html create mode 100644 testing/web-platform/tests/dom/ranges/Range-mutations-appendData.html create mode 100644 testing/web-platform/tests/dom/ranges/Range-mutations-dataChange.html create mode 100644 testing/web-platform/tests/dom/ranges/Range-mutations-deleteData.html create mode 100644 testing/web-platform/tests/dom/ranges/Range-mutations-insertBefore.html create mode 100644 testing/web-platform/tests/dom/ranges/Range-mutations-insertData.html create mode 100644 testing/web-platform/tests/dom/ranges/Range-mutations-removeChild.html create mode 100644 testing/web-platform/tests/dom/ranges/Range-mutations-replaceChild.html create mode 100644 testing/web-platform/tests/dom/ranges/Range-mutations-replaceData.html create mode 100644 testing/web-platform/tests/dom/ranges/Range-mutations-splitText.html create mode 100644 testing/web-platform/tests/dom/ranges/Range-mutations.js create mode 100644 testing/web-platform/tests/dom/ranges/Range-selectNode.html create mode 100644 testing/web-platform/tests/dom/ranges/Range-set.html create mode 100644 testing/web-platform/tests/dom/ranges/Range-stringifier.html create mode 100644 testing/web-platform/tests/dom/ranges/Range-surroundContents.html create mode 100644 testing/web-platform/tests/dom/ranges/Range-test-iframe.html create mode 100644 testing/web-platform/tests/dom/ranges/StaticRange-constructor.html create mode 100644 testing/web-platform/tests/dom/slot-recalc-ref.html create mode 100644 testing/web-platform/tests/dom/slot-recalc.html create mode 100644 testing/web-platform/tests/dom/svg-insert-crash.html create mode 100644 testing/web-platform/tests/dom/traversal/NodeFilter-constants.html create mode 100644 testing/web-platform/tests/dom/traversal/NodeIterator-removal.html create mode 100644 testing/web-platform/tests/dom/traversal/NodeIterator.html create mode 100644 testing/web-platform/tests/dom/traversal/TreeWalker-acceptNode-filter-cross-realm-null-browsing-context.html create mode 100644 testing/web-platform/tests/dom/traversal/TreeWalker-acceptNode-filter-cross-realm.html create mode 100644 testing/web-platform/tests/dom/traversal/TreeWalker-acceptNode-filter.html create mode 100644 testing/web-platform/tests/dom/traversal/TreeWalker-basic.html create mode 100644 testing/web-platform/tests/dom/traversal/TreeWalker-currentNode.html create mode 100644 testing/web-platform/tests/dom/traversal/TreeWalker-previousNodeLastChildReject.html create mode 100644 testing/web-platform/tests/dom/traversal/TreeWalker-previousSiblingLastChildSkip.html create mode 100644 testing/web-platform/tests/dom/traversal/TreeWalker-traversal-reject.html create mode 100644 testing/web-platform/tests/dom/traversal/TreeWalker-traversal-skip-most.html create mode 100644 testing/web-platform/tests/dom/traversal/TreeWalker-traversal-skip.html create mode 100644 testing/web-platform/tests/dom/traversal/TreeWalker-walking-outside-a-tree.html create mode 100644 testing/web-platform/tests/dom/traversal/TreeWalker.html create mode 100644 testing/web-platform/tests/dom/traversal/support/TreeWalker-acceptNode-filter-cross-realm-null-browsing-context-subframe.html create mode 100644 testing/web-platform/tests/dom/traversal/support/assert-node.js create mode 100644 testing/web-platform/tests/dom/traversal/support/empty-document.html create mode 100644 testing/web-platform/tests/dom/traversal/unfinished/001.xml create mode 100644 testing/web-platform/tests/dom/traversal/unfinished/002.xml create mode 100644 testing/web-platform/tests/dom/traversal/unfinished/003.xml create mode 100644 testing/web-platform/tests/dom/traversal/unfinished/004.xml create mode 100644 testing/web-platform/tests/dom/traversal/unfinished/005.xml create mode 100644 testing/web-platform/tests/dom/traversal/unfinished/006.xml create mode 100644 testing/web-platform/tests/dom/traversal/unfinished/007.xml create mode 100644 testing/web-platform/tests/dom/traversal/unfinished/008.xml create mode 100644 testing/web-platform/tests/dom/traversal/unfinished/009.xml create mode 100644 testing/web-platform/tests/dom/traversal/unfinished/010.xml create mode 100644 testing/web-platform/tests/dom/traversal/unfinished/TODO create mode 100644 testing/web-platform/tests/dom/window-extends-event-target.html create mode 100644 testing/web-platform/tests/dom/xslt/README.md create mode 100644 testing/web-platform/tests/dom/xslt/externalScript.js create mode 100644 testing/web-platform/tests/dom/xslt/invalid-output-encoding-crash.html create mode 100644 testing/web-platform/tests/dom/xslt/sort-ref.html create mode 100644 testing/web-platform/tests/dom/xslt/sort.html create mode 100644 testing/web-platform/tests/dom/xslt/strip-space-crash.xml create mode 100644 testing/web-platform/tests/dom/xslt/transformToFragment-on-node-from-inactive-document-crash.html create mode 100644 testing/web-platform/tests/dom/xslt/transformToFragment.tentative.window.js (limited to 'testing/web-platform/tests/dom') diff --git a/testing/web-platform/tests/dom/META.yml b/testing/web-platform/tests/dom/META.yml new file mode 100644 index 0000000000..6fd5b12664 --- /dev/null +++ b/testing/web-platform/tests/dom/META.yml @@ -0,0 +1,5 @@ +spec: https://dom.spec.whatwg.org/ +suggested_reviewers: + - jdm + - zqzhang + - annevk diff --git a/testing/web-platform/tests/dom/abort/AbortSignal.any.js b/testing/web-platform/tests/dom/abort/AbortSignal.any.js new file mode 100644 index 0000000000..3bbdc11a92 --- /dev/null +++ b/testing/web-platform/tests/dom/abort/AbortSignal.any.js @@ -0,0 +1,40 @@ +test(t => { + const signal = AbortSignal.abort(); + assert_true(signal instanceof AbortSignal, "returned object is an AbortSignal"); + assert_true(signal.aborted, "returned signal is already aborted"); +}, "the AbortSignal.abort() static returns an already aborted signal"); + +async_test(t => { + const s = AbortSignal.abort(); + s.addEventListener("abort", t.unreached_func("abort event listener called")); + s.onabort = t.unreached_func("abort event handler called"); + t.step_timeout(() => { t.done(); }, 2000); +}, "signal returned by AbortSignal.abort() should not fire abort event"); + +test(t => { + const signal = AbortSignal.timeout(0); + assert_true(signal instanceof AbortSignal, "returned object is an AbortSignal"); + assert_false(signal.aborted, "returned signal is not already aborted"); +}, "AbortSignal.timeout() returns a non-aborted signal"); + +async_test(t => { + const signal = AbortSignal.timeout(5); + signal.onabort = t.step_func_done(() => { + assert_true(signal.aborted, "signal is aborted"); + assert_true(signal.reason instanceof DOMException, "signal.reason is a DOMException"); + assert_equals(signal.reason.name, "TimeoutError", "signal.reason is a TimeoutError"); + }); +}, "Signal returned by AbortSignal.timeout() times out"); + +async_test(t => { + let result = ""; + for (const value of ["1", "2", "3"]) { + const signal = AbortSignal.timeout(5); + signal.onabort = t.step_func(() => { result += value; }); + } + + const signal = AbortSignal.timeout(5); + signal.onabort = t.step_func_done(() => { + assert_equals(result, "123", "Timeout order should be 123"); + }); +}, "AbortSignal timeouts fire in order"); diff --git a/testing/web-platform/tests/dom/abort/abort-signal-any.tentative.any.js b/testing/web-platform/tests/dom/abort/abort-signal-any.tentative.any.js new file mode 100644 index 0000000000..b4abb14c1a --- /dev/null +++ b/testing/web-platform/tests/dom/abort/abort-signal-any.tentative.any.js @@ -0,0 +1,4 @@ +// META: script=./resources/abort-signal-any-tests.js + +abortSignalAnySignalOnlyTests(AbortSignal); +abortSignalAnyTests(AbortSignal, AbortController); diff --git a/testing/web-platform/tests/dom/abort/abort-signal-timeout.html b/testing/web-platform/tests/dom/abort/abort-signal-timeout.html new file mode 100644 index 0000000000..2a9c13d614 --- /dev/null +++ b/testing/web-platform/tests/dom/abort/abort-signal-timeout.html @@ -0,0 +1,19 @@ + + +AbortSignal.timeout frame detach + + + + diff --git a/testing/web-platform/tests/dom/abort/crashtests/timeout-close.html b/testing/web-platform/tests/dom/abort/crashtests/timeout-close.html new file mode 100644 index 0000000000..ee8544a7f5 --- /dev/null +++ b/testing/web-platform/tests/dom/abort/crashtests/timeout-close.html @@ -0,0 +1,22 @@ + + + + + diff --git a/testing/web-platform/tests/dom/abort/event.any.js b/testing/web-platform/tests/dom/abort/event.any.js new file mode 100644 index 0000000000..bbbe28b233 --- /dev/null +++ b/testing/web-platform/tests/dom/abort/event.any.js @@ -0,0 +1,190 @@ +test(t => { + const c = new AbortController(), + s = c.signal; + let state = "begin"; + + assert_false(s.aborted); + assert_true("reason" in s, "signal has reason property"); + assert_equals(s.reason, undefined, "signal.reason is initially undefined"); + + s.addEventListener("abort", + t.step_func(e => { + assert_equals(state, "begin"); + state = "aborted"; + }) + ); + c.abort(); + + assert_equals(state, "aborted"); + assert_true(s.aborted); + assert_true(s.reason instanceof DOMException, "signal.reason is DOMException"); + assert_equals(s.reason.name, "AbortError", "signal.reason is AbortError"); + + c.abort(); +}, "AbortController abort() should fire event synchronously"); + +test(t => { + const controller = new AbortController(); + const signal = controller.signal; + assert_equals(controller.signal, signal, + "value of controller.signal should not have changed"); + controller.abort(); + assert_equals(controller.signal, signal, + "value of controller.signal should still not have changed"); +}, "controller.signal should always return the same object"); + +test(t => { + const controller = new AbortController(); + const signal = controller.signal; + let eventCount = 0; + signal.onabort = () => { + ++eventCount; + }; + controller.abort(); + assert_true(signal.aborted); + assert_equals(eventCount, 1, "event handler should have been called once"); + controller.abort(); + assert_true(signal.aborted); + assert_equals(eventCount, 1, + "event handler should not have been called again"); +}, "controller.abort() should do nothing the second time it is called"); + +test(t => { + const controller = new AbortController(); + controller.abort(); + controller.signal.onabort = + t.unreached_func("event handler should not be called"); +}, "event handler should not be called if added after controller.abort()"); + +test(t => { + const controller = new AbortController(); + const signal = controller.signal; + signal.onabort = t.step_func(e => { + assert_equals(e.type, "abort", "event type should be abort"); + assert_equals(e.target, signal, "event target should be signal"); + assert_false(e.bubbles, "event should not bubble"); + assert_true(e.isTrusted, "event should be trusted"); + }); + controller.abort(); +}, "the abort event should have the right properties"); + +test(t => { + const controller = new AbortController(); + const signal = controller.signal; + + assert_true("reason" in signal, "signal has reason property"); + assert_equals(signal.reason, undefined, "signal.reason is initially undefined"); + + const reason = Error("hello"); + controller.abort(reason); + + assert_true(signal.aborted, "signal.aborted"); + assert_equals(signal.reason, reason, "signal.reason"); +}, "AbortController abort(reason) should set signal.reason"); + +test(t => { + const controller = new AbortController(); + const signal = controller.signal; + + assert_true("reason" in signal, "signal has reason property"); + assert_equals(signal.reason, undefined, "signal.reason is initially undefined"); + + controller.abort(); + + assert_true(signal.aborted, "signal.aborted"); + assert_true(signal.reason instanceof DOMException, "signal.reason is DOMException"); + assert_equals(signal.reason.name, "AbortError", "signal.reason is AbortError"); +}, "aborting AbortController without reason creates an \"AbortError\" DOMException"); + +test(t => { + const controller = new AbortController(); + const signal = controller.signal; + + assert_true("reason" in signal, "signal has reason property"); + assert_equals(signal.reason, undefined, "signal.reason is initially undefined"); + + controller.abort(undefined); + + assert_true(signal.aborted, "signal.aborted"); + assert_true(signal.reason instanceof DOMException, "signal.reason is DOMException"); + assert_equals(signal.reason.name, "AbortError", "signal.reason is AbortError"); +}, "AbortController abort(undefined) creates an \"AbortError\" DOMException"); + +test(t => { + const controller = new AbortController(); + const signal = controller.signal; + + assert_true("reason" in signal, "signal has reason property"); + assert_equals(signal.reason, undefined, "signal.reason is initially undefined"); + + controller.abort(null); + + assert_true(signal.aborted, "signal.aborted"); + assert_equals(signal.reason, null, "signal.reason"); +}, "AbortController abort(null) should set signal.reason"); + +test(t => { + const signal = AbortSignal.abort(); + + assert_true(signal.aborted, "signal.aborted"); + assert_true(signal.reason instanceof DOMException, "signal.reason is DOMException"); + assert_equals(signal.reason.name, "AbortError", "signal.reason is AbortError"); +}, "static aborting signal should have right properties"); + +test(t => { + const reason = Error("hello"); + const signal = AbortSignal.abort(reason); + + assert_true(signal.aborted, "signal.aborted"); + assert_equals(signal.reason, reason, "signal.reason"); +}, "static aborting signal with reason should set signal.reason"); + +test(t => { + const signal = AbortSignal.abort(); + + assert_true( + signal.reason instanceof DOMException, + "signal.reason is a DOMException" + ); + assert_equals( + signal.reason, + signal.reason, + "signal.reason returns the same DOMException" + ); +}, "AbortSignal.reason returns the same DOMException"); + +test(t => { + const controller = new AbortController(); + controller.abort(); + + assert_true( + controller.signal.reason instanceof DOMException, + "signal.reason is a DOMException" + ); + assert_equals( + controller.signal.reason, + controller.signal.reason, + "signal.reason returns the same DOMException" + ); +}, "AbortController.signal.reason returns the same DOMException"); + +test(t => { + const reason = new Error('boom'); + const signal = AbortSignal.abort(reason); + assert_true(signal.aborted); + assert_throws_exactly(reason, () => signal.throwIfAborted()); +}, "throwIfAborted() should throw abort.reason if signal aborted"); + +test(t => { + const signal = AbortSignal.abort('hello'); + assert_true(signal.aborted); + assert_throws_exactly('hello', () => signal.throwIfAborted()); +}, "throwIfAborted() should throw primitive abort.reason if signal aborted"); + +test(t => { + const controller = new AbortController(); + assert_false(controller.signal.aborted); + controller.signal.throwIfAborted(); +}, "throwIfAborted() should not throw if signal not aborted"); + +done(); diff --git a/testing/web-platform/tests/dom/abort/reason-constructor.html b/testing/web-platform/tests/dom/abort/reason-constructor.html new file mode 100644 index 0000000000..0515165a0f --- /dev/null +++ b/testing/web-platform/tests/dom/abort/reason-constructor.html @@ -0,0 +1,12 @@ + + +AbortSignal.reason constructor + + + + diff --git a/testing/web-platform/tests/dom/abort/resources/abort-signal-any-tests.js b/testing/web-platform/tests/dom/abort/resources/abort-signal-any-tests.js new file mode 100644 index 0000000000..66e4141eac --- /dev/null +++ b/testing/web-platform/tests/dom/abort/resources/abort-signal-any-tests.js @@ -0,0 +1,185 @@ +// Tests for AbortSignal.any() and subclasses that don't use a controller. +function abortSignalAnySignalOnlyTests(signalInterface) { + const desc = `${signalInterface.name}.any()` + + test(t => { + const signal = signalInterface.any([]); + assert_false(signal.aborted); + }, `${desc} works with an empty array of signals`); +} + +// Tests for AbortSignal.any() and subclasses that use a controller. +function abortSignalAnyTests(signalInterface, controllerInterface) { + const suffix = `(using ${controllerInterface.name})`; + const desc = `${signalInterface.name}.any()`; + + test(t => { + const controller = new controllerInterface(); + const signal = controller.signal; + const cloneSignal = signalInterface.any([signal]); + assert_false(cloneSignal.aborted); + assert_true("reason" in cloneSignal, "cloneSignal has reason property"); + assert_equals(cloneSignal.reason, undefined, + "cloneSignal.reason is initially undefined"); + assert_not_equals(signal, cloneSignal, + `${desc} returns a new signal.`); + + let eventFired = false; + cloneSignal.onabort = t.step_func((e) => { + assert_equals(e.target, cloneSignal, + `The event target is the signal returned by ${desc}`); + eventFired = true; + }); + + controller.abort("reason string"); + assert_true(signal.aborted); + assert_true(cloneSignal.aborted); + assert_true(eventFired); + assert_equals(cloneSignal.reason, "reason string", + `${desc} propagates the abort reason`); + }, `${desc} follows a single signal ${suffix}`); + + test(t => { + for (let i = 0; i < 3; ++i) { + const controllers = []; + for (let j = 0; j < 3; ++j) { + controllers.push(new controllerInterface()); + } + const combinedSignal = signalInterface.any(controllers.map(c => c.signal)); + + let eventFired = false; + combinedSignal.onabort = t.step_func((e) => { + assert_equals(e.target, combinedSignal, + `The event target is the signal returned by ${desc}`); + eventFired = true; + }); + + controllers[i].abort(); + assert_true(eventFired); + assert_true(combinedSignal.aborted); + assert_true(combinedSignal.reason instanceof DOMException, + "signal.reason is a DOMException"); + assert_equals(combinedSignal.reason.name, "AbortError", + "signal.reason is a AbortError"); + } + }, `${desc} follows multiple signals ${suffix}`); + + test(t => { + const controllers = []; + for (let i = 0; i < 3; ++i) { + controllers.push(new controllerInterface()); + } + controllers[1].abort("reason 1"); + controllers[2].abort("reason 2"); + + const signal = signalInterface.any(controllers.map(c => c.signal)); + assert_true(signal.aborted); + assert_equals(signal.reason, "reason 1", + "The signal should be aborted with the first reason"); + }, `${desc} returns an aborted signal if passed an aborted signal ${suffix}`); + + test(t => { + const controller = new controllerInterface(); + const signal = signalInterface.any([controller.signal, controller.signal]); + assert_false(signal.aborted); + controller.abort("reason"); + assert_true(signal.aborted); + assert_equals(signal.reason, "reason"); + }, `${desc} can be passed the same signal more than once ${suffix}`); + + test(t => { + const controller1 = new controllerInterface(); + controller1.abort("reason 1"); + const controller2 = new controllerInterface(); + controller2.abort("reason 2"); + + const signal = signalInterface.any([controller1.signal, controller2.signal, controller1.signal]); + assert_true(signal.aborted); + assert_equals(signal.reason, "reason 1"); + }, `${desc} uses the first instance of a duplicate signal ${suffix}`); + + test(t => { + for (let i = 0; i < 3; ++i) { + const controllers = []; + for (let j = 0; j < 3; ++j) { + controllers.push(new controllerInterface()); + } + const combinedSignal1 = + signalInterface.any([controllers[0].signal, controllers[1].signal]); + const combinedSignal2 = + signalInterface.any([combinedSignal1, controllers[2].signal]); + + let eventFired = false; + combinedSignal2.onabort = t.step_func((e) => { + eventFired = true; + }); + + controllers[i].abort(); + assert_true(eventFired); + assert_true(combinedSignal2.aborted); + assert_true(combinedSignal2.reason instanceof DOMException, + "signal.reason is a DOMException"); + assert_equals(combinedSignal2.reason.name, "AbortError", + "signal.reason is a AbortError"); + } + }, `${desc} signals are composable ${suffix}`); + + async_test(t => { + const controller = new controllerInterface(); + const timeoutSignal = AbortSignal.timeout(5); + + const combinedSignal = signalInterface.any([controller.signal, timeoutSignal]); + + combinedSignal.onabort = t.step_func_done(() => { + assert_true(combinedSignal.aborted); + assert_true(combinedSignal.reason instanceof DOMException, + "combinedSignal.reason is a DOMException"); + assert_equals(combinedSignal.reason.name, "TimeoutError", + "combinedSignal.reason is a TimeoutError"); + }); + }, `${desc} works with signals returned by AbortSignal.timeout() ${suffix}`); + + test(t => { + const controller = new controllerInterface(); + let combined = signalInterface.any([controller.signal]); + combined = signalInterface.any([combined]); + combined = signalInterface.any([combined]); + combined = signalInterface.any([combined]); + + let eventFired = false; + combined.onabort = () => { + eventFired = true; + } + + assert_false(eventFired); + assert_false(combined.aborted); + + controller.abort("the reason"); + + assert_true(eventFired); + assert_true(combined.aborted); + assert_equals(combined.reason, "the reason"); + }, `${desc} works with intermediate signals ${suffix}`); + + test(t => { + const controller = new controllerInterface(); + const signals = []; + // The first event should be dispatched on the originating signal. + signals.push(controller.signal); + // All dependents are linked to `controller.signal` (never to another + // composite signal), so this is the order events should fire. + signals.push(signalInterface.any([controller.signal])); + signals.push(signalInterface.any([controller.signal])); + signals.push(signalInterface.any([signals[0]])); + signals.push(signalInterface.any([signals[1]])); + + let result = ""; + for (let i = 0; i < signals.length; i++) { + signals[i].addEventListener('abort', () => { + result += i; + }); + } + controller.abort(); + assert_equals(result, "01234"); + }, `Abort events for ${desc} signals fire in the right order ${suffix}`); +} diff --git a/testing/web-platform/tests/dom/attributes-are-nodes.html b/testing/web-platform/tests/dom/attributes-are-nodes.html new file mode 100644 index 0000000000..54ff4ccaec --- /dev/null +++ b/testing/web-platform/tests/dom/attributes-are-nodes.html @@ -0,0 +1,55 @@ + + +Attributes are Nodes but should not be accepted outside of the `attributes` NamedNodeMap + + + + + diff --git a/testing/web-platform/tests/dom/collections/HTMLCollection-as-prototype.html b/testing/web-platform/tests/dom/collections/HTMLCollection-as-prototype.html new file mode 100644 index 0000000000..d572d35c04 --- /dev/null +++ b/testing/web-platform/tests/dom/collections/HTMLCollection-as-prototype.html @@ -0,0 +1,29 @@ + + +Objects whose prototype is an HTMLCollection + + +
+ diff --git a/testing/web-platform/tests/dom/collections/HTMLCollection-delete.html b/testing/web-platform/tests/dom/collections/HTMLCollection-delete.html new file mode 100644 index 0000000000..99420d4319 --- /dev/null +++ b/testing/web-platform/tests/dom/collections/HTMLCollection-delete.html @@ -0,0 +1,45 @@ + + +Deleting properties from HTMLCollection + + +
+ + diff --git a/testing/web-platform/tests/dom/collections/HTMLCollection-empty-name.html b/testing/web-platform/tests/dom/collections/HTMLCollection-empty-name.html new file mode 100644 index 0000000000..4fc34db7f5 --- /dev/null +++ b/testing/web-platform/tests/dom/collections/HTMLCollection-empty-name.html @@ -0,0 +1,65 @@ + + +HTMLCollection and empty names + + +
+
+
+
+ +
+ diff --git a/testing/web-platform/tests/dom/collections/HTMLCollection-iterator.html b/testing/web-platform/tests/dom/collections/HTMLCollection-iterator.html new file mode 100644 index 0000000000..6296fd1b2d --- /dev/null +++ b/testing/web-platform/tests/dom/collections/HTMLCollection-iterator.html @@ -0,0 +1,45 @@ + + + + +HTMLCollection @@iterator Test + + +

+

+

+

+

+ diff --git a/testing/web-platform/tests/dom/collections/HTMLCollection-live-mutations.window.js b/testing/web-platform/tests/dom/collections/HTMLCollection-live-mutations.window.js new file mode 100644 index 0000000000..7dbfc6ccf6 --- /dev/null +++ b/testing/web-platform/tests/dom/collections/HTMLCollection-live-mutations.window.js @@ -0,0 +1,93 @@ +function testHTMLCollection(name, hooks) { + test(() => { + const nodes = { + root: document.createElement("div"), + div1: document.createElement("div"), + div2: document.createElement("div"), + p: document.createElement("p") + }; + + nodes.div1.id = "div1"; + nodes.div2.id = "div2"; + + const list = nodes.root.getElementsByTagName("div"); + + hooks.initial(list, nodes); + + nodes.root.appendChild(nodes.div1); + nodes.root.appendChild(nodes.p); + nodes.root.appendChild(nodes.div2); + + hooks.afterInsertion(list, nodes); + + nodes.root.removeChild(nodes.div1); + + hooks.afterRemoval(list, nodes); + }, `HTMLCollection live mutations: ${name}`); +} + +testHTMLCollection("HTMLCollection.length", { + initial(list) { + assert_equals(list.length, 0); + }, + afterInsertion(list) { + assert_equals(list.length, 2); + }, + afterRemoval(list) { + assert_equals(list.length, 1); + } +}); + +testHTMLCollection("HTMLCollection.item(index)", { + initial(list) { + assert_equals(list.item(0), null); + }, + afterInsertion(list, nodes) { + assert_equals(list.item(0), nodes.div1); + assert_equals(list.item(1), nodes.div2); + }, + afterRemoval(list, nodes) { + assert_equals(list.item(0), nodes.div2); + } +}); + +testHTMLCollection("HTMLCollection[index]", { + initial(list) { + assert_equals(list[0], undefined); + }, + afterInsertion(list, nodes) { + assert_equals(list[0], nodes.div1); + assert_equals(list[1], nodes.div2); + }, + afterRemoval(list, nodes) { + assert_equals(list[0], nodes.div2); + } +}); + +testHTMLCollection("HTMLCollection.namedItem(index)", { + initial(list) { + assert_equals(list.namedItem("div1"), null); + assert_equals(list.namedItem("div2"), null); + }, + afterInsertion(list, nodes) { + assert_equals(list.namedItem("div1"), nodes.div1); + assert_equals(list.namedItem("div2"), nodes.div2); + }, + afterRemoval(list, nodes) { + assert_equals(list.namedItem("div1"), null); + assert_equals(list.namedItem("div2"), nodes.div2); + } +}); + +testHTMLCollection("HTMLCollection ownPropertyNames", { + initial(list) { + assert_object_equals(Object.getOwnPropertyNames(list), []); + }, + afterInsertion(list) { + assert_object_equals(Object.getOwnPropertyNames(list), ["0", "1", "div1", "div2"]); + }, + afterRemoval(list) { + assert_object_equals(Object.getOwnPropertyNames(list), ["0", "div2"]); + } +}); + diff --git a/testing/web-platform/tests/dom/collections/HTMLCollection-own-props.html b/testing/web-platform/tests/dom/collections/HTMLCollection-own-props.html new file mode 100644 index 0000000000..99dc425dbe --- /dev/null +++ b/testing/web-platform/tests/dom/collections/HTMLCollection-own-props.html @@ -0,0 +1,109 @@ + + +HTMLCollection getters and own properties + + +
+ diff --git a/testing/web-platform/tests/dom/collections/HTMLCollection-supported-property-indices.html b/testing/web-platform/tests/dom/collections/HTMLCollection-supported-property-indices.html new file mode 100644 index 0000000000..5339ec31ea --- /dev/null +++ b/testing/web-platform/tests/dom/collections/HTMLCollection-supported-property-indices.html @@ -0,0 +1,179 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/testing/web-platform/tests/dom/collections/HTMLCollection-supported-property-names.html b/testing/web-platform/tests/dom/collections/HTMLCollection-supported-property-names.html new file mode 100644 index 0000000000..3d21e16692 --- /dev/null +++ b/testing/web-platform/tests/dom/collections/HTMLCollection-supported-property-names.html @@ -0,0 +1,135 @@ + + + + + + +
+ + + + + + + + + + + + + + + + + + diff --git a/testing/web-platform/tests/dom/collections/domstringmap-supported-property-names.html b/testing/web-platform/tests/dom/collections/domstringmap-supported-property-names.html new file mode 100644 index 0000000000..430aa44c3a --- /dev/null +++ b/testing/web-platform/tests/dom/collections/domstringmap-supported-property-names.html @@ -0,0 +1,54 @@ + + +DOMStringMap Test: Supported property names + + +
+ +
Simple
+ +
Simple
+ +
+ John Doe +
+ +
Jane Doe
+ +
Jim Doe
+ + diff --git a/testing/web-platform/tests/dom/collections/namednodemap-supported-property-names.html b/testing/web-platform/tests/dom/collections/namednodemap-supported-property-names.html new file mode 100644 index 0000000000..2c5dee4efd --- /dev/null +++ b/testing/web-platform/tests/dom/collections/namednodemap-supported-property-names.html @@ -0,0 +1,30 @@ + + +NamedNodeMap Test: Supported property names + + +
+
Simple
+ + \ No newline at end of file diff --git a/testing/web-platform/tests/dom/common.js b/testing/web-platform/tests/dom/common.js new file mode 100644 index 0000000000..70367b2eff --- /dev/null +++ b/testing/web-platform/tests/dom/common.js @@ -0,0 +1,1083 @@ +"use strict"; +// Written by Aryeh Gregor + +// 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 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() { + 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]", + "[processingInstruction, 0, processingInstruction, 4]", + ]; + + 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) { + // "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 is original end node, and they are a Text, + // ProcessingInstruction, or Comment node:" + if (range.startContainer == range.endContainer + && (range.startContainer.nodeType == Node.TEXT_NODE + || range.startContainer.nodeType == Node.PROCESSING_INSTRUCTION_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, ProcessingInstruction, or + // Comment node:" + if (firstPartiallyContainedChild + && (firstPartiallyContainedChild.nodeType == Node.TEXT_NODE + || firstPartiallyContainedChild.nodeType == Node.PROCESSING_INSTRUCTION_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, ProcessingInstruction, or + // Comment node:" + if (lastPartiallyContainedChild + && (lastPartiallyContainedChild.nodeType == Node.TEXT_NODE + || lastPartiallyContainedChild.nodeType == Node.PROCESSING_INSTRUCTION_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 a ProcessingInstruction or Comment node, or is + // a Text node whose parent is null, or is node, 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) + || range.startContainer == node) { + 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, + "First differing node: expected " + format_value(expected) + + ", got " + format_value(actual) + " [" + msg + "]"); + 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/testing/web-platform/tests/dom/constants.js b/testing/web-platform/tests/dom/constants.js new file mode 100644 index 0000000000..397df96fbc --- /dev/null +++ b/testing/web-platform/tests/dom/constants.js @@ -0,0 +1,11 @@ +function testConstants(objects, constants, msg) { + objects.forEach(function(arr) { + var o = arr[0], desc = arr[1]; + test(function() { + constants.forEach(function(d) { + assert_true(d[0] in o, "Object " + o + " doesn't have " + d[0]) + assert_equals(o[d[0]], d[1], "Object " + o + " value for " + d[0] + " is wrong") + }) + }, "Constants for " + msg + " on " + desc + ".") + }) +} diff --git a/testing/web-platform/tests/dom/eventPathRemoved.html b/testing/web-platform/tests/dom/eventPathRemoved.html new file mode 100644 index 0000000000..1ed9f88753 --- /dev/null +++ b/testing/web-platform/tests/dom/eventPathRemoved.html @@ -0,0 +1,16 @@ + +Event.path must be removed + + + +
+ diff --git a/testing/web-platform/tests/dom/events/AddEventListenerOptions-once.any.js b/testing/web-platform/tests/dom/events/AddEventListenerOptions-once.any.js new file mode 100644 index 0000000000..b4edd4345c --- /dev/null +++ b/testing/web-platform/tests/dom/events/AddEventListenerOptions-once.any.js @@ -0,0 +1,96 @@ +// META: title=AddEventListenerOptions.once + +"use strict"; + +test(function() { + var invoked_once = false; + var invoked_normal = false; + function handler_once() { + invoked_once = true; + } + function handler_normal() { + invoked_normal = true; + } + + const et = new EventTarget(); + et.addEventListener('test', handler_once, {once: true}); + et.addEventListener('test', handler_normal); + et.dispatchEvent(new Event('test')); + assert_equals(invoked_once, true, "Once handler should be invoked"); + assert_equals(invoked_normal, true, "Normal handler should be invoked"); + + invoked_once = false; + invoked_normal = false; + et.dispatchEvent(new Event('test')); + assert_equals(invoked_once, false, "Once handler shouldn't be invoked again"); + assert_equals(invoked_normal, true, "Normal handler should be invoked again"); + et.removeEventListener('test', handler_normal); +}, "Once listener should be invoked only once"); + +test(function() { + const et = new EventTarget(); + var invoked_count = 0; + function handler() { + invoked_count++; + if (invoked_count == 1) + et.dispatchEvent(new Event('test')); + } + et.addEventListener('test', handler, {once: true}); + et.dispatchEvent(new Event('test')); + assert_equals(invoked_count, 1, "Once handler should only be invoked once"); + + invoked_count = 0; + function handler2() { + invoked_count++; + if (invoked_count == 1) + et.addEventListener('test', handler2, {once: true}); + if (invoked_count <= 2) + et.dispatchEvent(new Event('test')); + } + et.addEventListener('test', handler2, {once: true}); + et.dispatchEvent(new Event('test')); + assert_equals(invoked_count, 2, "Once handler should only be invoked once after each adding"); +}, "Once listener should be invoked only once even if the event is nested"); + +test(function() { + var invoked_count = 0; + function handler() { + invoked_count++; + } + + const et = new EventTarget(); + + et.addEventListener('test', handler, {once: true}); + et.addEventListener('test', handler); + et.dispatchEvent(new Event('test')); + assert_equals(invoked_count, 1, "The handler should only be added once"); + + invoked_count = 0; + et.dispatchEvent(new Event('test')); + assert_equals(invoked_count, 0, "The handler was added as a once listener"); + + invoked_count = 0; + et.addEventListener('test', handler, {once: true}); + et.removeEventListener('test', handler); + et.dispatchEvent(new Event('test')); + assert_equals(invoked_count, 0, "The handler should have been removed"); +}, "Once listener should be added / removed like normal listeners"); + +test(function() { + const et = new EventTarget(); + + var invoked_count = 0; + + for (let n = 4; n > 0; n--) { + et.addEventListener('test', (e) => { + invoked_count++; + e.stopImmediatePropagation(); + }, {once: true}); + } + + for (let n = 4; n > 0; n--) { + et.dispatchEvent(new Event('test')); + } + + assert_equals(invoked_count, 4, "The listeners should be invoked"); +}, "Multiple once listeners should be invoked even if the stopImmediatePropagation is set"); diff --git a/testing/web-platform/tests/dom/events/AddEventListenerOptions-passive.any.js b/testing/web-platform/tests/dom/events/AddEventListenerOptions-passive.any.js new file mode 100644 index 0000000000..8e59cf5b37 --- /dev/null +++ b/testing/web-platform/tests/dom/events/AddEventListenerOptions-passive.any.js @@ -0,0 +1,134 @@ +// META: title=AddEventListenerOptions.passive + +test(function() { + var supportsPassive = false; + var query_options = { + get passive() { + supportsPassive = true; + return false; + }, + get dummy() { + assert_unreached("dummy value getter invoked"); + return false; + } + }; + + const et = new EventTarget(); + et.addEventListener('test_event', null, query_options); + assert_true(supportsPassive, "addEventListener doesn't support the passive option"); + + supportsPassive = false; + et.removeEventListener('test_event', null, query_options); + assert_false(supportsPassive, "removeEventListener supports the passive option when it should not"); +}, "Supports passive option on addEventListener only"); + +function testPassiveValue(optionsValue, expectedDefaultPrevented, existingEventTarget) { + var defaultPrevented = undefined; + var handler = function handler(e) { + assert_false(e.defaultPrevented, "Event prematurely marked defaultPrevented"); + e.preventDefault(); + defaultPrevented = e.defaultPrevented; + } + const et = existingEventTarget || new EventTarget(); + et.addEventListener('test', handler, optionsValue); + var uncanceled = et.dispatchEvent(new Event('test', {bubbles: true, cancelable: true})); + + assert_equals(defaultPrevented, expectedDefaultPrevented, "Incorrect defaultPrevented for options: " + JSON.stringify(optionsValue)); + assert_equals(uncanceled, !expectedDefaultPrevented, "Incorrect return value from dispatchEvent"); + + et.removeEventListener('test', handler, optionsValue); +} + +test(function() { + testPassiveValue(undefined, true); + testPassiveValue({}, true); + testPassiveValue({passive: false}, true); + testPassiveValue({passive: true}, false); + testPassiveValue({passive: 0}, true); + testPassiveValue({passive: 1}, false); +}, "preventDefault should be ignored if-and-only-if the passive option is true"); + +function testPassiveValueOnReturnValue(test, optionsValue, expectedDefaultPrevented) { + var defaultPrevented = undefined; + var handler = test.step_func(e => { + assert_false(e.defaultPrevented, "Event prematurely marked defaultPrevented"); + e.returnValue = false; + defaultPrevented = e.defaultPrevented; + }); + const et = new EventTarget(); + et.addEventListener('test', handler, optionsValue); + var uncanceled = et.dispatchEvent(new Event('test', {bubbles: true, cancelable: true})); + + assert_equals(defaultPrevented, expectedDefaultPrevented, "Incorrect defaultPrevented for options: " + JSON.stringify(optionsValue)); + assert_equals(uncanceled, !expectedDefaultPrevented, "Incorrect return value from dispatchEvent"); + + et.removeEventListener('test', handler, optionsValue); +} + +async_test(t => { + testPassiveValueOnReturnValue(t, undefined, true); + testPassiveValueOnReturnValue(t, {}, true); + testPassiveValueOnReturnValue(t, {passive: false}, true); + testPassiveValueOnReturnValue(t, {passive: true}, false); + testPassiveValueOnReturnValue(t, {passive: 0}, true); + testPassiveValueOnReturnValue(t, {passive: 1}, false); + t.done(); +}, "returnValue should be ignored if-and-only-if the passive option is true"); + +function testPassiveWithOtherHandlers(optionsValue, expectedDefaultPrevented) { + var handlerInvoked1 = false; + var dummyHandler1 = function() { + handlerInvoked1 = true; + }; + var handlerInvoked2 = false; + var dummyHandler2 = function() { + handlerInvoked2 = true; + }; + + const et = new EventTarget(); + et.addEventListener('test', dummyHandler1, {passive:true}); + et.addEventListener('test', dummyHandler2); + + testPassiveValue(optionsValue, expectedDefaultPrevented, et); + + assert_true(handlerInvoked1, "Extra passive handler not invoked"); + assert_true(handlerInvoked2, "Extra non-passive handler not invoked"); + + et.removeEventListener('test', dummyHandler1); + et.removeEventListener('test', dummyHandler2); +} + +test(function() { + testPassiveWithOtherHandlers({}, true); + testPassiveWithOtherHandlers({passive: false}, true); + testPassiveWithOtherHandlers({passive: true}, false); +}, "passive behavior of one listener should be unaffected by the presence of other listeners"); + +function testOptionEquivalence(optionValue1, optionValue2, expectedEquality) { + var invocationCount = 0; + var handler = function handler(e) { + invocationCount++; + } + const et = new EventTarget(); + et.addEventListener('test', handler, optionValue1); + et.addEventListener('test', handler, optionValue2); + et.dispatchEvent(new Event('test', {bubbles: true})); + assert_equals(invocationCount, expectedEquality ? 1 : 2, "equivalence of options " + + JSON.stringify(optionValue1) + " and " + JSON.stringify(optionValue2)); + et.removeEventListener('test', handler, optionValue1); + et.removeEventListener('test', handler, optionValue2); +} + +test(function() { + // Sanity check options that should be treated as distinct handlers + testOptionEquivalence({capture:true}, {capture:false, passive:false}, false); + testOptionEquivalence({capture:true}, {passive:true}, false); + + // Option values that should be treated as equivalent + testOptionEquivalence({}, {passive:false}, true); + testOptionEquivalence({passive:true}, {passive:false}, true); + testOptionEquivalence(undefined, {passive:true}, true); + testOptionEquivalence({capture: true, passive: false}, {capture: true, passive: true}, true); + +}, "Equivalence of option values"); + diff --git a/testing/web-platform/tests/dom/events/AddEventListenerOptions-signal.any.js b/testing/web-platform/tests/dom/events/AddEventListenerOptions-signal.any.js new file mode 100644 index 0000000000..e6a3426159 --- /dev/null +++ b/testing/web-platform/tests/dom/events/AddEventListenerOptions-signal.any.js @@ -0,0 +1,143 @@ +'use strict'; + +test(function() { + let count = 0; + function handler() { + count++; + } + const et = new EventTarget(); + const controller = new AbortController(); + et.addEventListener('test', handler, { signal: controller.signal }); + et.dispatchEvent(new Event('test')); + assert_equals(count, 1, "Adding a signal still adds a listener"); + et.dispatchEvent(new Event('test')); + assert_equals(count, 2, "The listener was not added with the once flag"); + controller.abort(); + et.dispatchEvent(new Event('test')); + assert_equals(count, 2, "Aborting on the controller removes the listener"); + et.addEventListener('test', handler, { signal: controller.signal }); + et.dispatchEvent(new Event('test')); + assert_equals(count, 2, "Passing an aborted signal never adds the handler"); +}, "Passing an AbortSignal to addEventListener options should allow removing a listener"); + +test(function() { + let count = 0; + function handler() { + count++; + } + const et = new EventTarget(); + const controller = new AbortController(); + et.addEventListener('test', handler, { signal: controller.signal }); + et.removeEventListener('test', handler); + et.dispatchEvent(new Event('test')); + assert_equals(count, 0, "The listener was still removed"); +}, "Passing an AbortSignal to addEventListener does not prevent removeEventListener"); + +test(function() { + let count = 0; + function handler() { + count++; + } + const et = new EventTarget(); + const controller = new AbortController(); + et.addEventListener('test', handler, { signal: controller.signal, once: true }); + controller.abort(); + et.dispatchEvent(new Event('test')); + assert_equals(count, 0, "The listener was still removed"); +}, "Passing an AbortSignal to addEventListener works with the once flag"); + +test(function() { + let count = 0; + function handler() { + count++; + } + const et = new EventTarget(); + const controller = new AbortController(); + et.addEventListener('test', handler, { signal: controller.signal, once: true }); + et.removeEventListener('test', handler); + et.dispatchEvent(new Event('test')); + assert_equals(count, 0, "The listener was still removed"); +}, "Removing a once listener works with a passed signal"); + +test(function() { + let count = 0; + function handler() { + count++; + } + const et = new EventTarget(); + const controller = new AbortController(); + et.addEventListener('first', handler, { signal: controller.signal, once: true }); + et.addEventListener('second', handler, { signal: controller.signal, once: true }); + controller.abort(); + et.dispatchEvent(new Event('first')); + et.dispatchEvent(new Event('second')); + assert_equals(count, 0, "The listener was still removed"); +}, "Passing an AbortSignal to multiple listeners"); + +test(function() { + let count = 0; + function handler() { + count++; + } + const et = new EventTarget(); + const controller = new AbortController(); + et.addEventListener('test', handler, { signal: controller.signal, capture: true }); + controller.abort(); + et.dispatchEvent(new Event('test')); + assert_equals(count, 0, "The listener was still removed"); +}, "Passing an AbortSignal to addEventListener works with the capture flag"); + +test(function() { + let count = 0; + function handler() { + count++; + } + const et = new EventTarget(); + const controller = new AbortController(); + et.addEventListener('test', () => { + controller.abort(); + }, { signal: controller.signal }); + et.addEventListener('test', handler, { signal: controller.signal }); + et.dispatchEvent(new Event('test')); + assert_equals(count, 0, "The listener was still removed"); +}, "Aborting from a listener does not call future listeners"); + +test(function() { + let count = 0; + function handler() { + count++; + } + const et = new EventTarget(); + const controller = new AbortController(); + et.addEventListener('test', () => { + et.addEventListener('test', handler, { signal: controller.signal }); + controller.abort(); + }, { signal: controller.signal }); + et.dispatchEvent(new Event('test')); + assert_equals(count, 0, "The listener was still removed"); +}, "Adding then aborting a listener in another listener does not call it"); + +test(function() { + const et = new EventTarget(); + const ac = new AbortController(); + let count = 0; + et.addEventListener('foo', () => { + et.addEventListener('foo', () => { + count++; + if (count > 5) ac.abort(); + et.dispatchEvent(new Event('foo')); + }, { signal: ac.signal }); + et.dispatchEvent(new Event('foo')); + }, { once: true }); + et.dispatchEvent(new Event('foo')); +}, "Aborting from a nested listener should remove it"); + +test(function() { + const et = new EventTarget(); + assert_throws_js(TypeError, () => { et.addEventListener("foo", () => {}, { signal: null }); }); +}, "Passing null as the signal should throw"); + +test(function() { + const et = new EventTarget(); + assert_throws_js(TypeError, () => { et.addEventListener("foo", null, { signal: null }); }); +}, "Passing null as the signal should throw (listener is also null)"); diff --git a/testing/web-platform/tests/dom/events/Body-FrameSet-Event-Handlers.html b/testing/web-platform/tests/dom/events/Body-FrameSet-Event-Handlers.html new file mode 100644 index 0000000000..3a891158d5 --- /dev/null +++ b/testing/web-platform/tests/dom/events/Body-FrameSet-Event-Handlers.html @@ -0,0 +1,123 @@ + + +HTMLBodyElement and HTMLFrameSetElement Event Handler Tests + + + + + diff --git a/testing/web-platform/tests/dom/events/CustomEvent.html b/testing/web-platform/tests/dom/events/CustomEvent.html new file mode 100644 index 0000000000..87050943f9 --- /dev/null +++ b/testing/web-platform/tests/dom/events/CustomEvent.html @@ -0,0 +1,35 @@ + +CustomEvent + + +
+ diff --git a/testing/web-platform/tests/dom/events/Event-cancelBubble.html b/testing/web-platform/tests/dom/events/Event-cancelBubble.html new file mode 100644 index 0000000000..d8d2d7239d --- /dev/null +++ b/testing/web-platform/tests/dom/events/Event-cancelBubble.html @@ -0,0 +1,132 @@ + + + + + Event.cancelBubble + + + + + + + +
+
+
+
+
+ + + diff --git a/testing/web-platform/tests/dom/events/Event-constants.html b/testing/web-platform/tests/dom/events/Event-constants.html new file mode 100644 index 0000000000..635e9894d9 --- /dev/null +++ b/testing/web-platform/tests/dom/events/Event-constants.html @@ -0,0 +1,23 @@ + +Event constants + + + +
+ diff --git a/testing/web-platform/tests/dom/events/Event-constructors.any.js b/testing/web-platform/tests/dom/events/Event-constructors.any.js new file mode 100644 index 0000000000..faa623ea92 --- /dev/null +++ b/testing/web-platform/tests/dom/events/Event-constructors.any.js @@ -0,0 +1,120 @@ +// META: title=Event constructors + +test(function() { + assert_throws_js( + TypeError, + () => Event(""), + "Calling Event constructor without 'new' must throw") +}) +test(function() { + assert_throws_js(TypeError, function() { + new Event() + }) +}) +test(function() { + var test_error = { name: "test" } + assert_throws_exactly(test_error, function() { + new Event({ toString: function() { throw test_error; } }) + }) +}) +test(function() { + var ev = new Event("") + assert_equals(ev.type, "") + assert_equals(ev.target, null) + assert_equals(ev.srcElement, null) + assert_equals(ev.currentTarget, null) + assert_equals(ev.eventPhase, Event.NONE) + assert_equals(ev.bubbles, false) + assert_equals(ev.cancelable, false) + assert_equals(ev.defaultPrevented, false) + assert_equals(ev.returnValue, true) + assert_equals(ev.isTrusted, false) + assert_true(ev.timeStamp > 0) + assert_true("initEvent" in ev) +}) +test(function() { + var ev = new Event("test") + assert_equals(ev.type, "test") + assert_equals(ev.target, null) + assert_equals(ev.srcElement, null) + assert_equals(ev.currentTarget, null) + assert_equals(ev.eventPhase, Event.NONE) + assert_equals(ev.bubbles, false) + assert_equals(ev.cancelable, false) + assert_equals(ev.defaultPrevented, false) + assert_equals(ev.returnValue, true) + assert_equals(ev.isTrusted, false) + assert_true(ev.timeStamp > 0) + assert_true("initEvent" in ev) +}) +test(function() { + assert_throws_js(TypeError, function() { Event("test") }, + 'Calling Event constructor without "new" must throw'); +}) +test(function() { + var ev = new Event("I am an event", { bubbles: true, cancelable: false}) + assert_equals(ev.type, "I am an event") + assert_equals(ev.bubbles, true) + assert_equals(ev.cancelable, false) +}) +test(function() { + var ev = new Event("@", { bubblesIGNORED: true, cancelable: true}) + assert_equals(ev.type, "@") + assert_equals(ev.bubbles, false) + assert_equals(ev.cancelable, true) +}) +test(function() { + var ev = new Event("@", { "bubbles\0IGNORED": true, cancelable: true}) + assert_equals(ev.type, "@") + assert_equals(ev.bubbles, false) + assert_equals(ev.cancelable, true) +}) +test(function() { + var ev = new Event("Xx", { cancelable: true}) + assert_equals(ev.type, "Xx") + assert_equals(ev.bubbles, false) + assert_equals(ev.cancelable, true) +}) +test(function() { + var ev = new Event("Xx", {}) + assert_equals(ev.type, "Xx") + assert_equals(ev.bubbles, false) + assert_equals(ev.cancelable, false) +}) +test(function() { + var ev = new Event("Xx", {bubbles: true, cancelable: false, sweet: "x"}) + assert_equals(ev.type, "Xx") + assert_equals(ev.bubbles, true) + assert_equals(ev.cancelable, false) + assert_equals(ev.sweet, undefined) +}) +test(function() { + var called = [] + var ev = new Event("Xx", { + get cancelable() { + called.push("cancelable") + return false + }, + get bubbles() { + called.push("bubbles") + return true; + }, + get sweet() { + called.push("sweet") + return "x" + } + }) + assert_array_equals(called, ["bubbles", "cancelable"]) + assert_equals(ev.type, "Xx") + assert_equals(ev.bubbles, true) + assert_equals(ev.cancelable, false) + assert_equals(ev.sweet, undefined) +}) +test(function() { + var ev = new CustomEvent("$", {detail: 54, sweet: "x", sweet2: "x", cancelable:true}) + assert_equals(ev.type, "$") + assert_equals(ev.bubbles, false) + assert_equals(ev.cancelable, true) + assert_equals(ev.sweet, undefined) + assert_equals(ev.detail, 54) +}) diff --git a/testing/web-platform/tests/dom/events/Event-defaultPrevented-after-dispatch.html b/testing/web-platform/tests/dom/events/Event-defaultPrevented-after-dispatch.html new file mode 100644 index 0000000000..8fef005eb5 --- /dev/null +++ b/testing/web-platform/tests/dom/events/Event-defaultPrevented-after-dispatch.html @@ -0,0 +1,44 @@ + + +Event.defaultPrevented is not reset after dispatchEvent() + + + + +
+ + diff --git a/testing/web-platform/tests/dom/events/Event-defaultPrevented.html b/testing/web-platform/tests/dom/events/Event-defaultPrevented.html new file mode 100644 index 0000000000..2548fa3e06 --- /dev/null +++ b/testing/web-platform/tests/dom/events/Event-defaultPrevented.html @@ -0,0 +1,55 @@ + +Event.defaultPrevented + + +
+ diff --git a/testing/web-platform/tests/dom/events/Event-dispatch-bubble-canceled.html b/testing/web-platform/tests/dom/events/Event-dispatch-bubble-canceled.html new file mode 100644 index 0000000000..20f398f66f --- /dev/null +++ b/testing/web-platform/tests/dom/events/Event-dispatch-bubble-canceled.html @@ -0,0 +1,59 @@ + + + +Setting cancelBubble=true prior to dispatchEvent() + + + + +
+ + + + + + + + + + + + + + + + + diff --git a/testing/web-platform/tests/dom/events/Event-dispatch-bubbles-false.html b/testing/web-platform/tests/dom/events/Event-dispatch-bubbles-false.html new file mode 100644 index 0000000000..0f43cb0275 --- /dev/null +++ b/testing/web-platform/tests/dom/events/Event-dispatch-bubbles-false.html @@ -0,0 +1,98 @@ + + + Event.bubbles attribute is set to false + + + + +
+ + + + + + + + + + + + + diff --git a/testing/web-platform/tests/dom/events/Event-dispatch-bubbles-true.html b/testing/web-platform/tests/dom/events/Event-dispatch-bubbles-true.html new file mode 100644 index 0000000000..b23605a1eb --- /dev/null +++ b/testing/web-platform/tests/dom/events/Event-dispatch-bubbles-true.html @@ -0,0 +1,108 @@ + + + Event.bubbles attribute is set to false + + + + +
+ + + + + + + + + + + + + diff --git a/testing/web-platform/tests/dom/events/Event-dispatch-click.html b/testing/web-platform/tests/dom/events/Event-dispatch-click.html new file mode 100644 index 0000000000..010305775d --- /dev/null +++ b/testing/web-platform/tests/dom/events/Event-dispatch-click.html @@ -0,0 +1,369 @@ + +Synthetic click event "magic" + + +
+ + diff --git a/testing/web-platform/tests/dom/events/Event-dispatch-click.tentative.html b/testing/web-platform/tests/dom/events/Event-dispatch-click.tentative.html new file mode 100644 index 0000000000..cfdae55ef2 --- /dev/null +++ b/testing/web-platform/tests/dom/events/Event-dispatch-click.tentative.html @@ -0,0 +1,78 @@ + +Clicks on input element + + + + diff --git a/testing/web-platform/tests/dom/events/Event-dispatch-detached-click.html b/testing/web-platform/tests/dom/events/Event-dispatch-detached-click.html new file mode 100644 index 0000000000..76ea3d78ba --- /dev/null +++ b/testing/web-platform/tests/dom/events/Event-dispatch-detached-click.html @@ -0,0 +1,20 @@ + +Click event on an element not in the document + + +
+ diff --git a/testing/web-platform/tests/dom/events/Event-dispatch-detached-input-and-change.html b/testing/web-platform/tests/dom/events/Event-dispatch-detached-input-and-change.html new file mode 100644 index 0000000000..a53ae71ac2 --- /dev/null +++ b/testing/web-platform/tests/dom/events/Event-dispatch-detached-input-and-change.html @@ -0,0 +1,190 @@ + + + +input and change events for detached checkbox and radio elements + + + + + + diff --git a/testing/web-platform/tests/dom/events/Event-dispatch-handlers-changed.html b/testing/web-platform/tests/dom/events/Event-dispatch-handlers-changed.html new file mode 100644 index 0000000000..24e6fd70cb --- /dev/null +++ b/testing/web-platform/tests/dom/events/Event-dispatch-handlers-changed.html @@ -0,0 +1,91 @@ + + + Dispatch additional events inside an event listener + + + +
+ + + + + + + + + + + + + + + diff --git a/testing/web-platform/tests/dom/events/Event-dispatch-listener-order.window.js b/testing/web-platform/tests/dom/events/Event-dispatch-listener-order.window.js new file mode 100644 index 0000000000..a01a472872 --- /dev/null +++ b/testing/web-platform/tests/dom/events/Event-dispatch-listener-order.window.js @@ -0,0 +1,20 @@ +test(t => { + const hostParent = document.createElement("section"), + host = hostParent.appendChild(document.createElement("div")), + shadowRoot = host.attachShadow({ mode: "closed" }), + targetParent = shadowRoot.appendChild(document.createElement("p")), + target = targetParent.appendChild(document.createElement("span")), + path = [hostParent, host, shadowRoot, targetParent, target], + expected = [], + result = []; + path.forEach((node, index) => { + expected.splice(index, 0, "capturing " + node.nodeName); + expected.splice(index + 1, 0, "bubbling " + node.nodeName); + }); + path.forEach(node => { + node.addEventListener("test", () => { result.push("bubbling " + node.nodeName) }); + node.addEventListener("test", () => { result.push("capturing " + node.nodeName) }, true); + }); + target.dispatchEvent(new CustomEvent('test', { detail: {}, bubbles: true, composed: true })); + assert_array_equals(result, expected); +}); diff --git a/testing/web-platform/tests/dom/events/Event-dispatch-multiple-cancelBubble.html b/testing/web-platform/tests/dom/events/Event-dispatch-multiple-cancelBubble.html new file mode 100644 index 0000000000..2873fd7794 --- /dev/null +++ b/testing/web-platform/tests/dom/events/Event-dispatch-multiple-cancelBubble.html @@ -0,0 +1,51 @@ + + + +Multiple dispatchEvent() and cancelBubble + + + + +
+ + + + + + diff --git a/testing/web-platform/tests/dom/events/Event-dispatch-multiple-stopPropagation.html b/testing/web-platform/tests/dom/events/Event-dispatch-multiple-stopPropagation.html new file mode 100644 index 0000000000..72644bd861 --- /dev/null +++ b/testing/web-platform/tests/dom/events/Event-dispatch-multiple-stopPropagation.html @@ -0,0 +1,51 @@ + + + + Multiple dispatchEvent() and stopPropagation() + + + + +
+ + + + + + diff --git a/testing/web-platform/tests/dom/events/Event-dispatch-omitted-capture.html b/testing/web-platform/tests/dom/events/Event-dispatch-omitted-capture.html new file mode 100644 index 0000000000..77074d9a3e --- /dev/null +++ b/testing/web-platform/tests/dom/events/Event-dispatch-omitted-capture.html @@ -0,0 +1,70 @@ + + +EventTarget.addEventListener: capture argument omitted + + + + +
+ + + + + + + + + + + + + diff --git a/testing/web-platform/tests/dom/events/Event-dispatch-on-disabled-elements.html b/testing/web-platform/tests/dom/events/Event-dispatch-on-disabled-elements.html new file mode 100644 index 0000000000..361006a724 --- /dev/null +++ b/testing/web-platform/tests/dom/events/Event-dispatch-on-disabled-elements.html @@ -0,0 +1,251 @@ + + + +Events must dispatch on disabled elements + + + + + + + diff --git a/testing/web-platform/tests/dom/events/Event-dispatch-order-at-target.html b/testing/web-platform/tests/dom/events/Event-dispatch-order-at-target.html new file mode 100644 index 0000000000..79673c3256 --- /dev/null +++ b/testing/web-platform/tests/dom/events/Event-dispatch-order-at-target.html @@ -0,0 +1,31 @@ + + +Listeners are invoked in correct order (AT_TARGET phase) + + +
+ diff --git a/testing/web-platform/tests/dom/events/Event-dispatch-order.html b/testing/web-platform/tests/dom/events/Event-dispatch-order.html new file mode 100644 index 0000000000..ca94434595 --- /dev/null +++ b/testing/web-platform/tests/dom/events/Event-dispatch-order.html @@ -0,0 +1,26 @@ + +Event phases order + + +
+ +
+
+
diff --git a/testing/web-platform/tests/dom/events/Event-dispatch-other-document.html b/testing/web-platform/tests/dom/events/Event-dispatch-other-document.html new file mode 100644 index 0000000000..689b48087a --- /dev/null +++ b/testing/web-platform/tests/dom/events/Event-dispatch-other-document.html @@ -0,0 +1,23 @@ + +Custom event on an element in another document + + +
+ diff --git a/testing/web-platform/tests/dom/events/Event-dispatch-propagation-stopped.html b/testing/web-platform/tests/dom/events/Event-dispatch-propagation-stopped.html new file mode 100644 index 0000000000..889f8cfe11 --- /dev/null +++ b/testing/web-platform/tests/dom/events/Event-dispatch-propagation-stopped.html @@ -0,0 +1,59 @@ + + + + Calling stopPropagation() prior to dispatchEvent() + + + + +
+ + + + + + + + + + + + + + + + + diff --git a/testing/web-platform/tests/dom/events/Event-dispatch-redispatch.html b/testing/web-platform/tests/dom/events/Event-dispatch-redispatch.html new file mode 100644 index 0000000000..cf861ca177 --- /dev/null +++ b/testing/web-platform/tests/dom/events/Event-dispatch-redispatch.html @@ -0,0 +1,124 @@ + + +EventTarget#dispatchEvent(): redispatching a native event + + + + + + +
+ diff --git a/testing/web-platform/tests/dom/events/Event-dispatch-reenter.html b/testing/web-platform/tests/dom/events/Event-dispatch-reenter.html new file mode 100644 index 0000000000..71f8517bdd --- /dev/null +++ b/testing/web-platform/tests/dom/events/Event-dispatch-reenter.html @@ -0,0 +1,66 @@ + + + Dispatch additional events inside an event listener + + +
+ + + + + + + + + + + + + diff --git a/testing/web-platform/tests/dom/events/Event-dispatch-target-moved.html b/testing/web-platform/tests/dom/events/Event-dispatch-target-moved.html new file mode 100644 index 0000000000..facb2c7b95 --- /dev/null +++ b/testing/web-platform/tests/dom/events/Event-dispatch-target-moved.html @@ -0,0 +1,73 @@ + + + Determined event propagation path - target moved + + + +
+ + + + + + + + + + + + + diff --git a/testing/web-platform/tests/dom/events/Event-dispatch-target-removed.html b/testing/web-platform/tests/dom/events/Event-dispatch-target-removed.html new file mode 100644 index 0000000000..531799c3ad --- /dev/null +++ b/testing/web-platform/tests/dom/events/Event-dispatch-target-removed.html @@ -0,0 +1,72 @@ + + +Determined event propagation path - target removed + + + +
+ + + + + + + + + + + + + diff --git a/testing/web-platform/tests/dom/events/Event-dispatch-throwing.html b/testing/web-platform/tests/dom/events/Event-dispatch-throwing.html new file mode 100644 index 0000000000..7d1c0d94a0 --- /dev/null +++ b/testing/web-platform/tests/dom/events/Event-dispatch-throwing.html @@ -0,0 +1,51 @@ + + +Throwing in event listeners + + +
+ diff --git a/testing/web-platform/tests/dom/events/Event-init-while-dispatching.html b/testing/web-platform/tests/dom/events/Event-init-while-dispatching.html new file mode 100644 index 0000000000..2aa1f6701c --- /dev/null +++ b/testing/web-platform/tests/dom/events/Event-init-while-dispatching.html @@ -0,0 +1,83 @@ + + +Re-initializing events while dispatching them + + + +
+ diff --git a/testing/web-platform/tests/dom/events/Event-initEvent.html b/testing/web-platform/tests/dom/events/Event-initEvent.html new file mode 100644 index 0000000000..ad1018d4da --- /dev/null +++ b/testing/web-platform/tests/dom/events/Event-initEvent.html @@ -0,0 +1,136 @@ + +Event.initEvent + + + +
+ diff --git a/testing/web-platform/tests/dom/events/Event-isTrusted.any.js b/testing/web-platform/tests/dom/events/Event-isTrusted.any.js new file mode 100644 index 0000000000..00bcecd0ed --- /dev/null +++ b/testing/web-platform/tests/dom/events/Event-isTrusted.any.js @@ -0,0 +1,11 @@ +test(function() { + var desc1 = Object.getOwnPropertyDescriptor(new Event("x"), "isTrusted"); + assert_not_equals(desc1, undefined); + assert_equals(typeof desc1.get, "function"); + + var desc2 = Object.getOwnPropertyDescriptor(new Event("x"), "isTrusted"); + assert_not_equals(desc2, undefined); + assert_equals(typeof desc2.get, "function"); + + assert_equals(desc1.get, desc2.get); +}); diff --git a/testing/web-platform/tests/dom/events/Event-propagation.html b/testing/web-platform/tests/dom/events/Event-propagation.html new file mode 100644 index 0000000000..33989eb4bf --- /dev/null +++ b/testing/web-platform/tests/dom/events/Event-propagation.html @@ -0,0 +1,48 @@ + +Event propagation tests + +
+ + + diff --git a/testing/web-platform/tests/dom/events/Event-returnValue.html b/testing/web-platform/tests/dom/events/Event-returnValue.html new file mode 100644 index 0000000000..08df2d4141 --- /dev/null +++ b/testing/web-platform/tests/dom/events/Event-returnValue.html @@ -0,0 +1,64 @@ + + + + + Event.returnValue + + + + + + + +
+ + + diff --git a/testing/web-platform/tests/dom/events/Event-stopImmediatePropagation.html b/testing/web-platform/tests/dom/events/Event-stopImmediatePropagation.html new file mode 100644 index 0000000000..b75732257a --- /dev/null +++ b/testing/web-platform/tests/dom/events/Event-stopImmediatePropagation.html @@ -0,0 +1,34 @@ + + +Event's stopImmediatePropagation + + + + + + +
+ + diff --git a/testing/web-platform/tests/dom/events/Event-stopPropagation-cancel-bubbling.html b/testing/web-platform/tests/dom/events/Event-stopPropagation-cancel-bubbling.html new file mode 100644 index 0000000000..5c2c49f338 --- /dev/null +++ b/testing/web-platform/tests/dom/events/Event-stopPropagation-cancel-bubbling.html @@ -0,0 +1,20 @@ + + + + + + + diff --git a/testing/web-platform/tests/dom/events/Event-subclasses-constructors.html b/testing/web-platform/tests/dom/events/Event-subclasses-constructors.html new file mode 100644 index 0000000000..08a5ded011 --- /dev/null +++ b/testing/web-platform/tests/dom/events/Event-subclasses-constructors.html @@ -0,0 +1,179 @@ + + +Event constructors + + +
+ diff --git a/testing/web-platform/tests/dom/events/Event-timestamp-cross-realm-getter.html b/testing/web-platform/tests/dom/events/Event-timestamp-cross-realm-getter.html new file mode 100644 index 0000000000..45823de26b --- /dev/null +++ b/testing/web-platform/tests/dom/events/Event-timestamp-cross-realm-getter.html @@ -0,0 +1,27 @@ + + +event.timeStamp is initialized using event's relevant global object + + + + + + diff --git a/testing/web-platform/tests/dom/events/Event-timestamp-high-resolution.html b/testing/web-platform/tests/dom/events/Event-timestamp-high-resolution.html new file mode 100644 index 0000000000..a049fef64b --- /dev/null +++ b/testing/web-platform/tests/dom/events/Event-timestamp-high-resolution.html @@ -0,0 +1,16 @@ + + + + + diff --git a/testing/web-platform/tests/dom/events/Event-timestamp-high-resolution.https.html b/testing/web-platform/tests/dom/events/Event-timestamp-high-resolution.https.html new file mode 100644 index 0000000000..70f9742947 --- /dev/null +++ b/testing/web-platform/tests/dom/events/Event-timestamp-high-resolution.https.html @@ -0,0 +1,16 @@ + + + + + diff --git a/testing/web-platform/tests/dom/events/Event-timestamp-safe-resolution.html b/testing/web-platform/tests/dom/events/Event-timestamp-safe-resolution.html new file mode 100644 index 0000000000..24f2dec93c --- /dev/null +++ b/testing/web-platform/tests/dom/events/Event-timestamp-safe-resolution.html @@ -0,0 +1,49 @@ + + + + \ No newline at end of file diff --git a/testing/web-platform/tests/dom/events/Event-type-empty.html b/testing/web-platform/tests/dom/events/Event-type-empty.html new file mode 100644 index 0000000000..225b85a613 --- /dev/null +++ b/testing/web-platform/tests/dom/events/Event-type-empty.html @@ -0,0 +1,35 @@ + +Event.type set to the empty string + + + + +
+ diff --git a/testing/web-platform/tests/dom/events/Event-type.html b/testing/web-platform/tests/dom/events/Event-type.html new file mode 100644 index 0000000000..22792f5c6c --- /dev/null +++ b/testing/web-platform/tests/dom/events/Event-type.html @@ -0,0 +1,22 @@ + +Event.type + + + + +
+ diff --git a/testing/web-platform/tests/dom/events/EventListener-addEventListener.sub.window.js b/testing/web-platform/tests/dom/events/EventListener-addEventListener.sub.window.js new file mode 100644 index 0000000000..b44bc33285 --- /dev/null +++ b/testing/web-platform/tests/dom/events/EventListener-addEventListener.sub.window.js @@ -0,0 +1,9 @@ +async_test(function(t) { + let crossOriginFrame = document.createElement('iframe'); + crossOriginFrame.src = 'https://{{hosts[alt][]}}:{{ports[https][0]}}/common/blank.html'; + document.body.appendChild(crossOriginFrame); + crossOriginFrame.addEventListener('load', t.step_func_done(function() { + let crossOriginWindow = crossOriginFrame.contentWindow; + window.addEventListener('click', crossOriginWindow); + })); +}, "EventListener.addEventListener doesn't throw when a cross origin object is passed in."); diff --git a/testing/web-platform/tests/dom/events/EventListener-handleEvent-cross-realm.html b/testing/web-platform/tests/dom/events/EventListener-handleEvent-cross-realm.html new file mode 100644 index 0000000000..663d04213f --- /dev/null +++ b/testing/web-platform/tests/dom/events/EventListener-handleEvent-cross-realm.html @@ -0,0 +1,75 @@ + + +Cross-realm EventListener throws TypeError of its associated Realm + + + + + + + diff --git a/testing/web-platform/tests/dom/events/EventListener-handleEvent.html b/testing/web-platform/tests/dom/events/EventListener-handleEvent.html new file mode 100644 index 0000000000..06bc1f6e2a --- /dev/null +++ b/testing/web-platform/tests/dom/events/EventListener-handleEvent.html @@ -0,0 +1,102 @@ + + +EventListener::handleEvent() + + + +
+ diff --git a/testing/web-platform/tests/dom/events/EventListener-incumbent-global-1.sub.html b/testing/web-platform/tests/dom/events/EventListener-incumbent-global-1.sub.html new file mode 100644 index 0000000000..9d941385cb --- /dev/null +++ b/testing/web-platform/tests/dom/events/EventListener-incumbent-global-1.sub.html @@ -0,0 +1,20 @@ + + + + + + + diff --git a/testing/web-platform/tests/dom/events/EventListener-incumbent-global-2.sub.html b/testing/web-platform/tests/dom/events/EventListener-incumbent-global-2.sub.html new file mode 100644 index 0000000000..4433c098d7 --- /dev/null +++ b/testing/web-platform/tests/dom/events/EventListener-incumbent-global-2.sub.html @@ -0,0 +1,20 @@ + + + + + + + diff --git a/testing/web-platform/tests/dom/events/EventListener-incumbent-global-subframe-1.sub.html b/testing/web-platform/tests/dom/events/EventListener-incumbent-global-subframe-1.sub.html new file mode 100644 index 0000000000..25487cc5e0 --- /dev/null +++ b/testing/web-platform/tests/dom/events/EventListener-incumbent-global-subframe-1.sub.html @@ -0,0 +1,13 @@ + + + diff --git a/testing/web-platform/tests/dom/events/EventListener-incumbent-global-subframe-2.sub.html b/testing/web-platform/tests/dom/events/EventListener-incumbent-global-subframe-2.sub.html new file mode 100644 index 0000000000..9c7235e2ad --- /dev/null +++ b/testing/web-platform/tests/dom/events/EventListener-incumbent-global-subframe-2.sub.html @@ -0,0 +1,13 @@ + + + diff --git a/testing/web-platform/tests/dom/events/EventListener-incumbent-global-subsubframe.sub.html b/testing/web-platform/tests/dom/events/EventListener-incumbent-global-subsubframe.sub.html new file mode 100644 index 0000000000..dd683f6f65 --- /dev/null +++ b/testing/web-platform/tests/dom/events/EventListener-incumbent-global-subsubframe.sub.html @@ -0,0 +1,20 @@ + + diff --git a/testing/web-platform/tests/dom/events/EventListener-invoke-legacy.html b/testing/web-platform/tests/dom/events/EventListener-invoke-legacy.html new file mode 100644 index 0000000000..a01afcd8d1 --- /dev/null +++ b/testing/web-platform/tests/dom/events/EventListener-invoke-legacy.html @@ -0,0 +1,66 @@ + + +Invoke legacy event listener + + + +
+ diff --git a/testing/web-platform/tests/dom/events/EventListenerOptions-capture.html b/testing/web-platform/tests/dom/events/EventListenerOptions-capture.html new file mode 100644 index 0000000000..f72cf3ca54 --- /dev/null +++ b/testing/web-platform/tests/dom/events/EventListenerOptions-capture.html @@ -0,0 +1,98 @@ + + +EventListenerOptions.capture + + + + +
+ + diff --git a/testing/web-platform/tests/dom/events/EventTarget-add-listener-platform-object.html b/testing/web-platform/tests/dom/events/EventTarget-add-listener-platform-object.html new file mode 100644 index 0000000000..d5565c22b3 --- /dev/null +++ b/testing/web-platform/tests/dom/events/EventTarget-add-listener-platform-object.html @@ -0,0 +1,32 @@ + + +addEventListener with a platform object + + + +Click me! + diff --git a/testing/web-platform/tests/dom/events/EventTarget-add-remove-listener.any.js b/testing/web-platform/tests/dom/events/EventTarget-add-remove-listener.any.js new file mode 100644 index 0000000000..b1d7ffb3e0 --- /dev/null +++ b/testing/web-platform/tests/dom/events/EventTarget-add-remove-listener.any.js @@ -0,0 +1,21 @@ +// META: title=EventTarget's addEventListener + removeEventListener + +"use strict"; + +function listener(evt) { + evt.preventDefault(); + return false; +} + +test(() => { + const et = new EventTarget(); + et.addEventListener("x", listener, false); + let event = new Event("x", { cancelable: true }); + let ret = et.dispatchEvent(event); + assert_false(ret); + + et.removeEventListener("x", listener); + event = new Event("x", { cancelable: true }); + ret = et.dispatchEvent(event); + assert_true(ret); +}, "Removing an event listener without explicit capture arg should succeed"); diff --git a/testing/web-platform/tests/dom/events/EventTarget-addEventListener.any.js b/testing/web-platform/tests/dom/events/EventTarget-addEventListener.any.js new file mode 100644 index 0000000000..e22da4aff8 --- /dev/null +++ b/testing/web-platform/tests/dom/events/EventTarget-addEventListener.any.js @@ -0,0 +1,9 @@ +// META: title=EventTarget.addEventListener + +// Step 1. +test(function() { + const et = new EventTarget(); + assert_equals(et.addEventListener("x", null, false), undefined); + assert_equals(et.addEventListener("x", null, true), undefined); + assert_equals(et.addEventListener("x", null), undefined); +}, "Adding a null event listener should succeed"); diff --git a/testing/web-platform/tests/dom/events/EventTarget-constructible.any.js b/testing/web-platform/tests/dom/events/EventTarget-constructible.any.js new file mode 100644 index 0000000000..b0e7614e62 --- /dev/null +++ b/testing/web-platform/tests/dom/events/EventTarget-constructible.any.js @@ -0,0 +1,62 @@ +"use strict"; + +test(() => { + const target = new EventTarget(); + const event = new Event("foo", { bubbles: true, cancelable: false }); + let callCount = 0; + + function listener(e) { + assert_equals(e, event); + ++callCount; + } + + target.addEventListener("foo", listener); + + target.dispatchEvent(event); + assert_equals(callCount, 1); + + target.dispatchEvent(event); + assert_equals(callCount, 2); + + target.removeEventListener("foo", listener); + target.dispatchEvent(event); + assert_equals(callCount, 2); +}, "A constructed EventTarget can be used as expected"); + +test(() => { + class NicerEventTarget extends EventTarget { + on(...args) { + this.addEventListener(...args); + } + + off(...args) { + this.removeEventListener(...args); + } + + dispatch(type, detail) { + this.dispatchEvent(new CustomEvent(type, { detail })); + } + } + + const target = new NicerEventTarget(); + const event = new Event("foo", { bubbles: true, cancelable: false }); + const detail = "some data"; + let callCount = 0; + + function listener(e) { + assert_equals(e.detail, detail); + ++callCount; + } + + target.on("foo", listener); + + target.dispatch("foo", detail); + assert_equals(callCount, 1); + + target.dispatch("foo", detail); + assert_equals(callCount, 2); + + target.off("foo", listener); + target.dispatch("foo", detail); + assert_equals(callCount, 2); +}, "EventTarget can be subclassed"); diff --git a/testing/web-platform/tests/dom/events/EventTarget-dispatchEvent-returnvalue.html b/testing/web-platform/tests/dom/events/EventTarget-dispatchEvent-returnvalue.html new file mode 100644 index 0000000000..c4466e0d6c --- /dev/null +++ b/testing/web-platform/tests/dom/events/EventTarget-dispatchEvent-returnvalue.html @@ -0,0 +1,71 @@ + + +EventTarget.dispatchEvent: return value + + + + + + +
+ + + + + + + + + + + + + diff --git a/testing/web-platform/tests/dom/events/EventTarget-dispatchEvent.html b/testing/web-platform/tests/dom/events/EventTarget-dispatchEvent.html new file mode 100644 index 0000000000..783561f5fb --- /dev/null +++ b/testing/web-platform/tests/dom/events/EventTarget-dispatchEvent.html @@ -0,0 +1,104 @@ + + +EventTarget.dispatchEvent + + + + + + +
+ diff --git a/testing/web-platform/tests/dom/events/EventTarget-removeEventListener.any.js b/testing/web-platform/tests/dom/events/EventTarget-removeEventListener.any.js new file mode 100644 index 0000000000..289dfcfbab --- /dev/null +++ b/testing/web-platform/tests/dom/events/EventTarget-removeEventListener.any.js @@ -0,0 +1,8 @@ +// META: title=EventTarget.removeEventListener + +// Step 1. +test(function() { + assert_equals(globalThis.removeEventListener("x", null, false), undefined); + assert_equals(globalThis.removeEventListener("x", null, true), undefined); + assert_equals(globalThis.removeEventListener("x", null), undefined); +}, "removing a null event listener should succeed"); diff --git a/testing/web-platform/tests/dom/events/EventTarget-this-of-listener.html b/testing/web-platform/tests/dom/events/EventTarget-this-of-listener.html new file mode 100644 index 0000000000..506564c413 --- /dev/null +++ b/testing/web-platform/tests/dom/events/EventTarget-this-of-listener.html @@ -0,0 +1,182 @@ + + +EventTarget listeners this value + + + + + + diff --git a/testing/web-platform/tests/dom/events/KeyEvent-initKeyEvent.html b/testing/web-platform/tests/dom/events/KeyEvent-initKeyEvent.html new file mode 100644 index 0000000000..3fffaba014 --- /dev/null +++ b/testing/web-platform/tests/dom/events/KeyEvent-initKeyEvent.html @@ -0,0 +1,23 @@ + + +KeyEvent.initKeyEvent + + +
+ diff --git a/testing/web-platform/tests/dom/events/event-disabled-dynamic.html b/testing/web-platform/tests/dom/events/event-disabled-dynamic.html new file mode 100644 index 0000000000..3f995b02f1 --- /dev/null +++ b/testing/web-platform/tests/dom/events/event-disabled-dynamic.html @@ -0,0 +1,21 @@ + + +Test that disabled is honored immediately in presence of dynamic changes + + + + + + + + diff --git a/testing/web-platform/tests/dom/events/event-global-extra.window.js b/testing/web-platform/tests/dom/events/event-global-extra.window.js new file mode 100644 index 0000000000..0f14961c40 --- /dev/null +++ b/testing/web-platform/tests/dom/events/event-global-extra.window.js @@ -0,0 +1,90 @@ +const otherWindow = document.body.appendChild(document.createElement("iframe")).contentWindow; + +["EventTarget", "XMLHttpRequest"].forEach(constructorName => { + async_test(t => { + const eventTarget = new otherWindow[constructorName](); + eventTarget.addEventListener("hi", t.step_func_done(e => { + assert_equals(otherWindow.event, undefined); + assert_equals(e, window.event); + })); + eventTarget.dispatchEvent(new Event("hi")); + }, "window.event for constructors from another global: " + constructorName); +}); + +// XXX: It would be good to test a subclass of EventTarget once we sort out +// https://github.com/heycam/webidl/issues/540 + +async_test(t => { + const element = document.body.appendChild(otherWindow.document.createElement("meh")); + element.addEventListener("yo", t.step_func_done(e => { + assert_equals(e, window.event); + })); + element.dispatchEvent(new Event("yo")); +}, "window.event and element from another document"); + +async_test(t => { + const doc = otherWindow.document, + element = doc.body.appendChild(doc.createElement("meh")), + child = element.appendChild(doc.createElement("bleh")); + element.addEventListener("yoyo", t.step_func(e => { + document.body.appendChild(element); + assert_equals(element.ownerDocument, document); + assert_equals(window.event, e); + assert_equals(otherWindow.event, undefined); + }), true); + element.addEventListener("yoyo", t.step_func(e => { + assert_equals(element.ownerDocument, document); + assert_equals(window.event, e); + assert_equals(otherWindow.event, undefined); + }), true); + child.addEventListener("yoyo", t.step_func_done(e => { + assert_equals(child.ownerDocument, document); + assert_equals(window.event, e); + assert_equals(otherWindow.event, undefined); + })); + child.dispatchEvent(new Event("yoyo")); +}, "window.event and moving an element post-dispatch"); + +test(t => { + const host = document.createElement("div"), + shadow = host.attachShadow({ mode: "open" }), + child = shadow.appendChild(document.createElement("trala")), + furtherChild = child.appendChild(document.createElement("waddup")); + let counter = 0; + host.addEventListener("hi", t.step_func(e => { + assert_equals(window.event, e); + assert_equals(counter++, 3); + })); + child.addEventListener("hi", t.step_func(e => { + assert_equals(window.event, undefined); + assert_equals(counter++, 2); + })); + furtherChild.addEventListener("hi", t.step_func(e => { + host.appendChild(child); + assert_equals(window.event, undefined); + assert_equals(counter++, 0); + })); + furtherChild.addEventListener("hi", t.step_func(e => { + assert_equals(window.event, undefined); + assert_equals(counter++, 1); + })); + furtherChild.dispatchEvent(new Event("hi", { composed: true, bubbles: true })); + assert_equals(counter, 4); +}, "window.event should not be affected by nodes moving post-dispatch"); + +async_test(t => { + const frame = document.body.appendChild(document.createElement("iframe")); + frame.src = "resources/event-global-extra-frame.html"; + frame.onload = t.step_func_done((load_event) => { + const event = new Event("hi"); + document.addEventListener("hi", frame.contentWindow.listener); // listener intentionally not wrapped in t.step_func + document.addEventListener("hi", t.step_func(e => { + assert_equals(event, e); + assert_equals(window.event, e); + })); + document.dispatchEvent(event); + assert_equals(frameState.event, event); + assert_equals(frameState.windowEvent, event); + assert_equals(frameState.parentEvent, load_event); + }); +}, "Listener from a different global"); diff --git a/testing/web-platform/tests/dom/events/event-global-is-still-set-when-coercing-beforeunload-result.html b/testing/web-platform/tests/dom/events/event-global-is-still-set-when-coercing-beforeunload-result.html new file mode 100644 index 0000000000..a64c8b6b8b --- /dev/null +++ b/testing/web-platform/tests/dom/events/event-global-is-still-set-when-coercing-beforeunload-result.html @@ -0,0 +1,23 @@ + + +window.event is still set when 'beforeunload' result is coerced to string + + + + + + + + + diff --git a/testing/web-platform/tests/dom/events/event-global-is-still-set-when-reporting-exception-onerror.html b/testing/web-platform/tests/dom/events/event-global-is-still-set-when-reporting-exception-onerror.html new file mode 100644 index 0000000000..ceaac4fe2b --- /dev/null +++ b/testing/web-platform/tests/dom/events/event-global-is-still-set-when-reporting-exception-onerror.html @@ -0,0 +1,43 @@ + + +window.onerror handler restores window.event after it reports an exception + + + + + + + + + diff --git a/testing/web-platform/tests/dom/events/event-global-set-before-handleEvent-lookup.window.js b/testing/web-platform/tests/dom/events/event-global-set-before-handleEvent-lookup.window.js new file mode 100644 index 0000000000..8f934bcea9 --- /dev/null +++ b/testing/web-platform/tests/dom/events/event-global-set-before-handleEvent-lookup.window.js @@ -0,0 +1,19 @@ +// https://dom.spec.whatwg.org/#concept-event-listener-inner-invoke (steps 8.2 - 12) +// https://webidl.spec.whatwg.org/#call-a-user-objects-operation (step 10.1) + +test(() => { + const eventTarget = new EventTarget; + + let currentEvent; + eventTarget.addEventListener("foo", { + get handleEvent() { + currentEvent = window.event; + return () => {}; + } + }); + + const event = new Event("foo"); + eventTarget.dispatchEvent(event); + + assert_equals(currentEvent, event); +}, "window.event is set before 'handleEvent' lookup"); diff --git a/testing/web-platform/tests/dom/events/event-global.html b/testing/web-platform/tests/dom/events/event-global.html new file mode 100644 index 0000000000..3e8d25ecb5 --- /dev/null +++ b/testing/web-platform/tests/dom/events/event-global.html @@ -0,0 +1,117 @@ + +window.event tests + + + +
+ diff --git a/testing/web-platform/tests/dom/events/event-global.worker.js b/testing/web-platform/tests/dom/events/event-global.worker.js new file mode 100644 index 0000000000..116cf32932 --- /dev/null +++ b/testing/web-platform/tests/dom/events/event-global.worker.js @@ -0,0 +1,14 @@ +importScripts("/resources/testharness.js"); +test(t => { + let seen = false; + const event = new Event("hi"); + assert_equals(self.event, undefined); + self.addEventListener("hi", t.step_func(e => { + seen = true; + assert_equals(self.event, undefined); + assert_equals(e, event); + })); + self.dispatchEvent(event); + assert_true(seen); +}, "There's no self.event (that's why we call it window.event) in workers"); +done(); diff --git a/testing/web-platform/tests/dom/events/focus-event-document-move.html b/testing/web-platform/tests/dom/events/focus-event-document-move.html new file mode 100644 index 0000000000..2943761ce1 --- /dev/null +++ b/testing/web-platform/tests/dom/events/focus-event-document-move.html @@ -0,0 +1,33 @@ + + + + + + + + + + + + +
Click me
+ + diff --git a/testing/web-platform/tests/dom/events/keypress-dispatch-crash.html b/testing/web-platform/tests/dom/events/keypress-dispatch-crash.html new file mode 100644 index 0000000000..3207adbd8c --- /dev/null +++ b/testing/web-platform/tests/dom/events/keypress-dispatch-crash.html @@ -0,0 +1,15 @@ + + + + + + + diff --git a/testing/web-platform/tests/dom/events/legacy-pre-activation-behavior.window.js b/testing/web-platform/tests/dom/events/legacy-pre-activation-behavior.window.js new file mode 100644 index 0000000000..e9e84bfad1 --- /dev/null +++ b/testing/web-platform/tests/dom/events/legacy-pre-activation-behavior.window.js @@ -0,0 +1,10 @@ +test(t => { + const input = document.body.appendChild(document.createElement('input')); + input.type = "radio"; + t.add_cleanup(() => input.remove()); + const clickEvent = new MouseEvent('click', { button: 0, which: 1 }); + input.addEventListener('change', t.step_func(() => { + assert_equals(clickEvent.eventPhase, Event.NONE); + })); + input.dispatchEvent(clickEvent); +}, "Use NONE phase during legacy-pre-activation behavior"); diff --git a/testing/web-platform/tests/dom/events/mouse-event-retarget.html b/testing/web-platform/tests/dom/events/mouse-event-retarget.html new file mode 100644 index 0000000000..c9ce6240d4 --- /dev/null +++ b/testing/web-platform/tests/dom/events/mouse-event-retarget.html @@ -0,0 +1,26 @@ + + +Script created MouseEvent properly retargets and adjusts offsetX + + + + + +
Hello
+ + diff --git a/testing/web-platform/tests/dom/events/no-focus-events-at-clicking-editable-content-in-link.html b/testing/web-platform/tests/dom/events/no-focus-events-at-clicking-editable-content-in-link.html new file mode 100644 index 0000000000..dc08636c46 --- /dev/null +++ b/testing/web-platform/tests/dom/events/no-focus-events-at-clicking-editable-content-in-link.html @@ -0,0 +1,80 @@ + + + + +Clicking editable content in link shouldn't cause redundant focus related events + + + + + + + +Hello +Hello + + + diff --git a/testing/web-platform/tests/dom/events/non-cancelable-when-passive/non-passive-mousewheel-event-listener-on-body.html b/testing/web-platform/tests/dom/events/non-cancelable-when-passive/non-passive-mousewheel-event-listener-on-body.html new file mode 100644 index 0000000000..5574fe0acb --- /dev/null +++ b/testing/web-platform/tests/dom/events/non-cancelable-when-passive/non-passive-mousewheel-event-listener-on-body.html @@ -0,0 +1,19 @@ + +non-passive mousewheel event listener on body + + + + + + + + +
+ diff --git a/testing/web-platform/tests/dom/events/non-cancelable-when-passive/non-passive-mousewheel-event-listener-on-div.html b/testing/web-platform/tests/dom/events/non-cancelable-when-passive/non-passive-mousewheel-event-listener-on-div.html new file mode 100644 index 0000000000..6fbf692cd7 --- /dev/null +++ b/testing/web-platform/tests/dom/events/non-cancelable-when-passive/non-passive-mousewheel-event-listener-on-div.html @@ -0,0 +1,35 @@ + +non-passive mousewheel event listener on div + + + + + + + + + +
+
+
+ diff --git a/testing/web-platform/tests/dom/events/non-cancelable-when-passive/non-passive-mousewheel-event-listener-on-document.html b/testing/web-platform/tests/dom/events/non-cancelable-when-passive/non-passive-mousewheel-event-listener-on-document.html new file mode 100644 index 0000000000..7d07393c69 --- /dev/null +++ b/testing/web-platform/tests/dom/events/non-cancelable-when-passive/non-passive-mousewheel-event-listener-on-document.html @@ -0,0 +1,19 @@ + +non-passive mousewheel event listener on document + + + + + + + + +
+ diff --git a/testing/web-platform/tests/dom/events/non-cancelable-when-passive/non-passive-mousewheel-event-listener-on-root.html b/testing/web-platform/tests/dom/events/non-cancelable-when-passive/non-passive-mousewheel-event-listener-on-root.html new file mode 100644 index 0000000000..e85fbacaba --- /dev/null +++ b/testing/web-platform/tests/dom/events/non-cancelable-when-passive/non-passive-mousewheel-event-listener-on-root.html @@ -0,0 +1,19 @@ + +non-passive mousewheel event listener on root + + + + + + + + +
+ diff --git a/testing/web-platform/tests/dom/events/non-cancelable-when-passive/non-passive-mousewheel-event-listener-on-window.html b/testing/web-platform/tests/dom/events/non-cancelable-when-passive/non-passive-mousewheel-event-listener-on-window.html new file mode 100644 index 0000000000..29b09f8561 --- /dev/null +++ b/testing/web-platform/tests/dom/events/non-cancelable-when-passive/non-passive-mousewheel-event-listener-on-window.html @@ -0,0 +1,19 @@ + +non-passive mousewheel event listener on window + + + + + + + + +
+ diff --git a/testing/web-platform/tests/dom/events/non-cancelable-when-passive/non-passive-touchmove-event-listener-on-body.html b/testing/web-platform/tests/dom/events/non-cancelable-when-passive/non-passive-touchmove-event-listener-on-body.html new file mode 100644 index 0000000000..f417bdd0a6 --- /dev/null +++ b/testing/web-platform/tests/dom/events/non-cancelable-when-passive/non-passive-touchmove-event-listener-on-body.html @@ -0,0 +1,25 @@ + +non-passive touchmove event listener on body + + + + + + + + + +
+ diff --git a/testing/web-platform/tests/dom/events/non-cancelable-when-passive/non-passive-touchmove-event-listener-on-div.html b/testing/web-platform/tests/dom/events/non-cancelable-when-passive/non-passive-touchmove-event-listener-on-div.html new file mode 100644 index 0000000000..11c9345407 --- /dev/null +++ b/testing/web-platform/tests/dom/events/non-cancelable-when-passive/non-passive-touchmove-event-listener-on-div.html @@ -0,0 +1,25 @@ + +non-passive touchmove event listener on div + + + + + + + + + +
+ diff --git a/testing/web-platform/tests/dom/events/non-cancelable-when-passive/non-passive-touchmove-event-listener-on-document.html b/testing/web-platform/tests/dom/events/non-cancelable-when-passive/non-passive-touchmove-event-listener-on-document.html new file mode 100644 index 0000000000..8b95a8d492 --- /dev/null +++ b/testing/web-platform/tests/dom/events/non-cancelable-when-passive/non-passive-touchmove-event-listener-on-document.html @@ -0,0 +1,25 @@ + +non-passive touchmove event listener on document + + + + + + + + + +
+ diff --git a/testing/web-platform/tests/dom/events/non-cancelable-when-passive/non-passive-touchmove-event-listener-on-root.html b/testing/web-platform/tests/dom/events/non-cancelable-when-passive/non-passive-touchmove-event-listener-on-root.html new file mode 100644 index 0000000000..c41ab72bd8 --- /dev/null +++ b/testing/web-platform/tests/dom/events/non-cancelable-when-passive/non-passive-touchmove-event-listener-on-root.html @@ -0,0 +1,25 @@ + +non-passive touchmove event listener on root + + + + + + + + + +
+ diff --git a/testing/web-platform/tests/dom/events/non-cancelable-when-passive/non-passive-touchmove-event-listener-on-window.html b/testing/web-platform/tests/dom/events/non-cancelable-when-passive/non-passive-touchmove-event-listener-on-window.html new file mode 100644 index 0000000000..3d6675c566 --- /dev/null +++ b/testing/web-platform/tests/dom/events/non-cancelable-when-passive/non-passive-touchmove-event-listener-on-window.html @@ -0,0 +1,25 @@ + + + + + + + + + + + +
+ diff --git a/testing/web-platform/tests/dom/events/non-cancelable-when-passive/non-passive-touchstart-event-listener-on-body.html b/testing/web-platform/tests/dom/events/non-cancelable-when-passive/non-passive-touchstart-event-listener-on-body.html new file mode 100644 index 0000000000..f6e6ecb06d --- /dev/null +++ b/testing/web-platform/tests/dom/events/non-cancelable-when-passive/non-passive-touchstart-event-listener-on-body.html @@ -0,0 +1,25 @@ + +non-passive touchstart event listener on body + + + + + + + + + +
+ diff --git a/testing/web-platform/tests/dom/events/non-cancelable-when-passive/non-passive-touchstart-event-listener-on-div.html b/testing/web-platform/tests/dom/events/non-cancelable-when-passive/non-passive-touchstart-event-listener-on-div.html new file mode 100644 index 0000000000..2e7c6e6b3b --- /dev/null +++ b/testing/web-platform/tests/dom/events/non-cancelable-when-passive/non-passive-touchstart-event-listener-on-div.html @@ -0,0 +1,25 @@ + +non-passive touchstart event listener on div + + + + + + + + + +
+ diff --git a/testing/web-platform/tests/dom/events/non-cancelable-when-passive/non-passive-touchstart-event-listener-on-document.html b/testing/web-platform/tests/dom/events/non-cancelable-when-passive/non-passive-touchstart-event-listener-on-document.html new file mode 100644 index 0000000000..22fcbdc322 --- /dev/null +++ b/testing/web-platform/tests/dom/events/non-cancelable-when-passive/non-passive-touchstart-event-listener-on-document.html @@ -0,0 +1,25 @@ + +non-passive touchstart event listener on document + + + + + + + + + +
+ diff --git a/testing/web-platform/tests/dom/events/non-cancelable-when-passive/non-passive-touchstart-event-listener-on-root.html b/testing/web-platform/tests/dom/events/non-cancelable-when-passive/non-passive-touchstart-event-listener-on-root.html new file mode 100644 index 0000000000..56c51349a0 --- /dev/null +++ b/testing/web-platform/tests/dom/events/non-cancelable-when-passive/non-passive-touchstart-event-listener-on-root.html @@ -0,0 +1,25 @@ + +non-passive touchstart event listener on root + + + + + + + + + +
+ diff --git a/testing/web-platform/tests/dom/events/non-cancelable-when-passive/non-passive-touchstart-event-listener-on-window.html b/testing/web-platform/tests/dom/events/non-cancelable-when-passive/non-passive-touchstart-event-listener-on-window.html new file mode 100644 index 0000000000..4e9d424a9d --- /dev/null +++ b/testing/web-platform/tests/dom/events/non-cancelable-when-passive/non-passive-touchstart-event-listener-on-window.html @@ -0,0 +1,25 @@ + +non-passive touchstart event listener on window + + + + + + + + + +
+ diff --git a/testing/web-platform/tests/dom/events/non-cancelable-when-passive/non-passive-wheel-event-listener-on-body.html b/testing/web-platform/tests/dom/events/non-cancelable-when-passive/non-passive-wheel-event-listener-on-body.html new file mode 100644 index 0000000000..070cadc291 --- /dev/null +++ b/testing/web-platform/tests/dom/events/non-cancelable-when-passive/non-passive-wheel-event-listener-on-body.html @@ -0,0 +1,18 @@ + +non-passive wheel event listener on body + + + + + + + +
+ diff --git a/testing/web-platform/tests/dom/events/non-cancelable-when-passive/non-passive-wheel-event-listener-on-div.html b/testing/web-platform/tests/dom/events/non-cancelable-when-passive/non-passive-wheel-event-listener-on-div.html new file mode 100644 index 0000000000..c49d18ac13 --- /dev/null +++ b/testing/web-platform/tests/dom/events/non-cancelable-when-passive/non-passive-wheel-event-listener-on-div.html @@ -0,0 +1,34 @@ + +non-passive wheel event listener on div + + + + + + + + +
+
+
+ diff --git a/testing/web-platform/tests/dom/events/non-cancelable-when-passive/non-passive-wheel-event-listener-on-document.html b/testing/web-platform/tests/dom/events/non-cancelable-when-passive/non-passive-wheel-event-listener-on-document.html new file mode 100644 index 0000000000..31a55cad43 --- /dev/null +++ b/testing/web-platform/tests/dom/events/non-cancelable-when-passive/non-passive-wheel-event-listener-on-document.html @@ -0,0 +1,18 @@ + +non-passive wheel event listener on document + + + + + + + +
+ diff --git a/testing/web-platform/tests/dom/events/non-cancelable-when-passive/non-passive-wheel-event-listener-on-root.html b/testing/web-platform/tests/dom/events/non-cancelable-when-passive/non-passive-wheel-event-listener-on-root.html new file mode 100644 index 0000000000..b7bacbfc7c --- /dev/null +++ b/testing/web-platform/tests/dom/events/non-cancelable-when-passive/non-passive-wheel-event-listener-on-root.html @@ -0,0 +1,18 @@ + +non-passive wheel event listener on root + + + + + + + +
+ diff --git a/testing/web-platform/tests/dom/events/non-cancelable-when-passive/non-passive-wheel-event-listener-on-window.html b/testing/web-platform/tests/dom/events/non-cancelable-when-passive/non-passive-wheel-event-listener-on-window.html new file mode 100644 index 0000000000..c236059df4 --- /dev/null +++ b/testing/web-platform/tests/dom/events/non-cancelable-when-passive/non-passive-wheel-event-listener-on-window.html @@ -0,0 +1,18 @@ + +non-passive wheel event listener on window + + + + + + + +
+ diff --git a/testing/web-platform/tests/dom/events/non-cancelable-when-passive/passive-mousewheel-event-listener-on-body.html b/testing/web-platform/tests/dom/events/non-cancelable-when-passive/passive-mousewheel-event-listener-on-body.html new file mode 100644 index 0000000000..9db12cfbdc --- /dev/null +++ b/testing/web-platform/tests/dom/events/non-cancelable-when-passive/passive-mousewheel-event-listener-on-body.html @@ -0,0 +1,19 @@ + +passive mousewheel event listener on body + + + + + + + + +
+ diff --git a/testing/web-platform/tests/dom/events/non-cancelable-when-passive/passive-mousewheel-event-listener-on-div.html b/testing/web-platform/tests/dom/events/non-cancelable-when-passive/passive-mousewheel-event-listener-on-div.html new file mode 100644 index 0000000000..373670856b --- /dev/null +++ b/testing/web-platform/tests/dom/events/non-cancelable-when-passive/passive-mousewheel-event-listener-on-div.html @@ -0,0 +1,35 @@ + +passive mousewheel event listener on div + + + + + + + + + +
+
+
+ diff --git a/testing/web-platform/tests/dom/events/non-cancelable-when-passive/passive-mousewheel-event-listener-on-document.html b/testing/web-platform/tests/dom/events/non-cancelable-when-passive/passive-mousewheel-event-listener-on-document.html new file mode 100644 index 0000000000..71262280b6 --- /dev/null +++ b/testing/web-platform/tests/dom/events/non-cancelable-when-passive/passive-mousewheel-event-listener-on-document.html @@ -0,0 +1,19 @@ + +passive mousewheel event listener on document + + + + + + + + +
+ diff --git a/testing/web-platform/tests/dom/events/non-cancelable-when-passive/passive-mousewheel-event-listener-on-root.html b/testing/web-platform/tests/dom/events/non-cancelable-when-passive/passive-mousewheel-event-listener-on-root.html new file mode 100644 index 0000000000..fc641d172e --- /dev/null +++ b/testing/web-platform/tests/dom/events/non-cancelable-when-passive/passive-mousewheel-event-listener-on-root.html @@ -0,0 +1,19 @@ + +passive mousewheel event listener on root + + + + + + + + +
+ diff --git a/testing/web-platform/tests/dom/events/non-cancelable-when-passive/passive-mousewheel-event-listener-on-window.html b/testing/web-platform/tests/dom/events/non-cancelable-when-passive/passive-mousewheel-event-listener-on-window.html new file mode 100644 index 0000000000..f60955c7c4 --- /dev/null +++ b/testing/web-platform/tests/dom/events/non-cancelable-when-passive/passive-mousewheel-event-listener-on-window.html @@ -0,0 +1,19 @@ + +passive mousewheel event listener on window + + + + + + + + +
+ diff --git a/testing/web-platform/tests/dom/events/non-cancelable-when-passive/passive-touchmove-event-listener-on-body.html b/testing/web-platform/tests/dom/events/non-cancelable-when-passive/passive-touchmove-event-listener-on-body.html new file mode 100644 index 0000000000..2349bad258 --- /dev/null +++ b/testing/web-platform/tests/dom/events/non-cancelable-when-passive/passive-touchmove-event-listener-on-body.html @@ -0,0 +1,25 @@ + +passive touchmove event listener on body + + + + + + + + + +
+ diff --git a/testing/web-platform/tests/dom/events/non-cancelable-when-passive/passive-touchmove-event-listener-on-div.html b/testing/web-platform/tests/dom/events/non-cancelable-when-passive/passive-touchmove-event-listener-on-div.html new file mode 100644 index 0000000000..a61b34851e --- /dev/null +++ b/testing/web-platform/tests/dom/events/non-cancelable-when-passive/passive-touchmove-event-listener-on-div.html @@ -0,0 +1,25 @@ + +passive touchmove event listener on div + + + + + + + + + +
+ diff --git a/testing/web-platform/tests/dom/events/non-cancelable-when-passive/passive-touchmove-event-listener-on-document.html b/testing/web-platform/tests/dom/events/non-cancelable-when-passive/passive-touchmove-event-listener-on-document.html new file mode 100644 index 0000000000..b49971b5b0 --- /dev/null +++ b/testing/web-platform/tests/dom/events/non-cancelable-when-passive/passive-touchmove-event-listener-on-document.html @@ -0,0 +1,25 @@ + +passive touchmove event listener on document + + + + + + + + + +
+ diff --git a/testing/web-platform/tests/dom/events/non-cancelable-when-passive/passive-touchmove-event-listener-on-root.html b/testing/web-platform/tests/dom/events/non-cancelable-when-passive/passive-touchmove-event-listener-on-root.html new file mode 100644 index 0000000000..b851704590 --- /dev/null +++ b/testing/web-platform/tests/dom/events/non-cancelable-when-passive/passive-touchmove-event-listener-on-root.html @@ -0,0 +1,25 @@ + +passive touchmove event listener on root + + + + + + + + + +
+ diff --git a/testing/web-platform/tests/dom/events/non-cancelable-when-passive/passive-touchmove-event-listener-on-window.html b/testing/web-platform/tests/dom/events/non-cancelable-when-passive/passive-touchmove-event-listener-on-window.html new file mode 100644 index 0000000000..351d6ace84 --- /dev/null +++ b/testing/web-platform/tests/dom/events/non-cancelable-when-passive/passive-touchmove-event-listener-on-window.html @@ -0,0 +1,25 @@ + +passive touchmove event listener on window + + + + + + + + + +
+ diff --git a/testing/web-platform/tests/dom/events/non-cancelable-when-passive/passive-touchstart-event-listener-on-body.html b/testing/web-platform/tests/dom/events/non-cancelable-when-passive/passive-touchstart-event-listener-on-body.html new file mode 100644 index 0000000000..c3d2b577fd --- /dev/null +++ b/testing/web-platform/tests/dom/events/non-cancelable-when-passive/passive-touchstart-event-listener-on-body.html @@ -0,0 +1,25 @@ + +passive touchstart event listener on body + + + + + + + + + +
+ diff --git a/testing/web-platform/tests/dom/events/non-cancelable-when-passive/passive-touchstart-event-listener-on-div.html b/testing/web-platform/tests/dom/events/non-cancelable-when-passive/passive-touchstart-event-listener-on-div.html new file mode 100644 index 0000000000..103e7f0d23 --- /dev/null +++ b/testing/web-platform/tests/dom/events/non-cancelable-when-passive/passive-touchstart-event-listener-on-div.html @@ -0,0 +1,25 @@ + +passive touchstart event listener on div + + + + + + + + + +
+ diff --git a/testing/web-platform/tests/dom/events/non-cancelable-when-passive/passive-touchstart-event-listener-on-document.html b/testing/web-platform/tests/dom/events/non-cancelable-when-passive/passive-touchstart-event-listener-on-document.html new file mode 100644 index 0000000000..2e4de2405f --- /dev/null +++ b/testing/web-platform/tests/dom/events/non-cancelable-when-passive/passive-touchstart-event-listener-on-document.html @@ -0,0 +1,25 @@ + +passive touchstart event listener on document + + + + + + + + + +
+ diff --git a/testing/web-platform/tests/dom/events/non-cancelable-when-passive/passive-touchstart-event-listener-on-root.html b/testing/web-platform/tests/dom/events/non-cancelable-when-passive/passive-touchstart-event-listener-on-root.html new file mode 100644 index 0000000000..0f52e9a16f --- /dev/null +++ b/testing/web-platform/tests/dom/events/non-cancelable-when-passive/passive-touchstart-event-listener-on-root.html @@ -0,0 +1,25 @@ + +passive touchstart event listener on root + + + + + + + + + +
+ diff --git a/testing/web-platform/tests/dom/events/non-cancelable-when-passive/passive-touchstart-event-listener-on-window.html b/testing/web-platform/tests/dom/events/non-cancelable-when-passive/passive-touchstart-event-listener-on-window.html new file mode 100644 index 0000000000..c47af8101f --- /dev/null +++ b/testing/web-platform/tests/dom/events/non-cancelable-when-passive/passive-touchstart-event-listener-on-window.html @@ -0,0 +1,25 @@ + +passive touchstart event listener on window + + + + + + + + + +
+ diff --git a/testing/web-platform/tests/dom/events/non-cancelable-when-passive/passive-wheel-event-listener-on-body.html b/testing/web-platform/tests/dom/events/non-cancelable-when-passive/passive-wheel-event-listener-on-body.html new file mode 100644 index 0000000000..fe0869b022 --- /dev/null +++ b/testing/web-platform/tests/dom/events/non-cancelable-when-passive/passive-wheel-event-listener-on-body.html @@ -0,0 +1,18 @@ + +passive wheel event listener on body + + + + + + + +
+ diff --git a/testing/web-platform/tests/dom/events/non-cancelable-when-passive/passive-wheel-event-listener-on-div.html b/testing/web-platform/tests/dom/events/non-cancelable-when-passive/passive-wheel-event-listener-on-div.html new file mode 100644 index 0000000000..e2ca6e795a --- /dev/null +++ b/testing/web-platform/tests/dom/events/non-cancelable-when-passive/passive-wheel-event-listener-on-div.html @@ -0,0 +1,34 @@ + +passive wheel event listener on div + + + + + + + + +
+
+
+ diff --git a/testing/web-platform/tests/dom/events/non-cancelable-when-passive/passive-wheel-event-listener-on-document.html b/testing/web-platform/tests/dom/events/non-cancelable-when-passive/passive-wheel-event-listener-on-document.html new file mode 100644 index 0000000000..61b716f7bb --- /dev/null +++ b/testing/web-platform/tests/dom/events/non-cancelable-when-passive/passive-wheel-event-listener-on-document.html @@ -0,0 +1,18 @@ + +passive wheel event listener on document + + + + + + + +
+ diff --git a/testing/web-platform/tests/dom/events/non-cancelable-when-passive/passive-wheel-event-listener-on-root.html b/testing/web-platform/tests/dom/events/non-cancelable-when-passive/passive-wheel-event-listener-on-root.html new file mode 100644 index 0000000000..6b383bc871 --- /dev/null +++ b/testing/web-platform/tests/dom/events/non-cancelable-when-passive/passive-wheel-event-listener-on-root.html @@ -0,0 +1,18 @@ + +passive wheel event listener on root + + + + + + + +
+ diff --git a/testing/web-platform/tests/dom/events/non-cancelable-when-passive/passive-wheel-event-listener-on-window.html b/testing/web-platform/tests/dom/events/non-cancelable-when-passive/passive-wheel-event-listener-on-window.html new file mode 100644 index 0000000000..a1e901f552 --- /dev/null +++ b/testing/web-platform/tests/dom/events/non-cancelable-when-passive/passive-wheel-event-listener-on-window.html @@ -0,0 +1,18 @@ + +passive wheel event listener on window + + + + + + + +
+ diff --git a/testing/web-platform/tests/dom/events/non-cancelable-when-passive/resources/scrolling.js b/testing/web-platform/tests/dom/events/non-cancelable-when-passive/resources/scrolling.js new file mode 100644 index 0000000000..88e10f5efd --- /dev/null +++ b/testing/web-platform/tests/dom/events/non-cancelable-when-passive/resources/scrolling.js @@ -0,0 +1,34 @@ +function raf() { + return new Promise((resolve) => { + // rAF twice. + window.requestAnimationFrame(() => { + window.requestAnimationFrame(resolve); + }); + }); +} + +async function runTest({target, eventName, passive, expectCancelable}) { + await raf(); + + let cancelable = null; + let arrived = false; + target.addEventListener(eventName, function (event) { + cancelable = event.cancelable; + arrived = true; + }, {passive:passive, once:true}); + + promise_test(async (t) => { + t.add_cleanup(() => { + document.querySelector('.remove-on-cleanup')?.remove(); + }); + const pos_x = Math.floor(window.innerWidth / 2); + const pos_y = Math.floor(window.innerHeight / 2); + const delta_x = 0; + const delta_y = 100; + + await new test_driver.Actions() + .scroll(pos_x, pos_y, delta_x, delta_y).send(); + await t.step_wait(() => arrived, `Didn't get event ${eventName} on ${target.localName}`); + assert_equals(cancelable, expectCancelable); + }); +} diff --git a/testing/web-platform/tests/dom/events/non-cancelable-when-passive/resources/touching.js b/testing/web-platform/tests/dom/events/non-cancelable-when-passive/resources/touching.js new file mode 100644 index 0000000000..620d26804b --- /dev/null +++ b/testing/web-platform/tests/dom/events/non-cancelable-when-passive/resources/touching.js @@ -0,0 +1,34 @@ +function waitForCompositorCommit() { + return new Promise((resolve) => { + // rAF twice. + window.requestAnimationFrame(() => { + window.requestAnimationFrame(resolve); + }); + }); +} + +function injectInput(touchDiv) { + return new test_driver.Actions() + .addPointer("touch_pointer", "touch") + .pointerMove(0, 0, {origin: touchDiv}) + .pointerDown() + .pointerMove(30, 30) + .pointerUp() + .send(); +} + +function runTest({target, eventName, passive, expectCancelable}) { + let touchDiv = document.getElementById("touchDiv"); + let cancelable = null; + let arrived = false; + target.addEventListener(eventName, function (event) { + cancelable = event.cancelable; + arrived = true; + }, {passive}); + promise_test(async () => { + await waitForCompositorCommit(); + await injectInput(touchDiv); + await waitFor(() => arrived); + assert_equals(cancelable, expectCancelable); + }); +} diff --git a/testing/web-platform/tests/dom/events/non-cancelable-when-passive/resources/wait-for.js b/testing/web-platform/tests/dom/events/non-cancelable-when-passive/resources/wait-for.js new file mode 100644 index 0000000000..0bf3e55834 --- /dev/null +++ b/testing/web-platform/tests/dom/events/non-cancelable-when-passive/resources/wait-for.js @@ -0,0 +1,15 @@ +function waitFor(condition, MAX_FRAME = 500) { + return new Promise((resolve, reject) => { + function tick(frames) { + // We requestAnimationFrame either for MAX_FRAME frames or until condition is + // met. + if (frames >= MAX_FRAME) + reject(new Error(`Condition did not become true after ${MAX_FRAME} frames`)); + else if (condition()) + resolve(); + else + requestAnimationFrame(() => tick(frames + 1)); + } + tick(0); + }); +} diff --git a/testing/web-platform/tests/dom/events/non-cancelable-when-passive/synthetic-events-cancelable.html b/testing/web-platform/tests/dom/events/non-cancelable-when-passive/synthetic-events-cancelable.html new file mode 100644 index 0000000000..4287770b8d --- /dev/null +++ b/testing/web-platform/tests/dom/events/non-cancelable-when-passive/synthetic-events-cancelable.html @@ -0,0 +1,34 @@ + +Synthetic events are always cancelable by default + + + + diff --git a/testing/web-platform/tests/dom/events/passive-by-default.html b/testing/web-platform/tests/dom/events/passive-by-default.html new file mode 100644 index 0000000000..02029f4dac --- /dev/null +++ b/testing/web-platform/tests/dom/events/passive-by-default.html @@ -0,0 +1,50 @@ + +Default passive event listeners on window, document, document element, body + + + + +
+ diff --git a/testing/web-platform/tests/dom/events/relatedTarget.window.js b/testing/web-platform/tests/dom/events/relatedTarget.window.js new file mode 100644 index 0000000000..ebc83ceb20 --- /dev/null +++ b/testing/web-platform/tests/dom/events/relatedTarget.window.js @@ -0,0 +1,81 @@ +// https://dom.spec.whatwg.org/#concept-event-dispatch + +const host = document.createElement("div"), + child = host.appendChild(document.createElement("p")), + shadow = host.attachShadow({ mode: "closed" }), + slot = shadow.appendChild(document.createElement("slot")); + +test(() => { + for (target of [shadow, slot]) { + for (relatedTarget of [new XMLHttpRequest(), self, host]) { + const event = new FocusEvent("demo", { relatedTarget: relatedTarget }); + target.dispatchEvent(event); + assert_equals(event.target, null); + assert_equals(event.relatedTarget, null); + } + } +}, "Reset if target pointed to a shadow tree"); + +test(() => { + for (relatedTarget of [shadow, slot]) { + for (target of [new XMLHttpRequest(), self, host]) { + const event = new FocusEvent("demo", { relatedTarget: relatedTarget }); + target.dispatchEvent(event); + assert_equals(event.target, target); + assert_equals(event.relatedTarget, host); + } + } +}, "Retarget a shadow-tree relatedTarget"); + +test(t => { + const shadowChild = shadow.appendChild(document.createElement("div")); + shadowChild.addEventListener("demo", t.step_func(() => document.body.appendChild(shadowChild))); + const event = new FocusEvent("demo", { relatedTarget: new XMLHttpRequest() }); + shadowChild.dispatchEvent(event); + assert_equals(shadowChild.parentNode, document.body); + assert_equals(event.target, null); + assert_equals(event.relatedTarget, null); + shadowChild.remove(); +}, "Reset if target pointed to a shadow tree pre-dispatch"); + +test(t => { + const shadowChild = shadow.appendChild(document.createElement("div")); + document.body.addEventListener("demo", t.step_func(() => document.body.appendChild(shadowChild))); + const event = new FocusEvent("demo", { relatedTarget: shadowChild }); + document.body.dispatchEvent(event); + assert_equals(shadowChild.parentNode, document.body); + assert_equals(event.target, document.body); + assert_equals(event.relatedTarget, host); + shadowChild.remove(); +}, "Retarget a shadow-tree relatedTarget, part 2"); + +test(t => { + const event = new FocusEvent("heya", { relatedTarget: shadow, cancelable: true }), + callback = t.unreached_func(); + host.addEventListener("heya", callback); + t.add_cleanup(() => host.removeEventListener("heya", callback)); + event.preventDefault(); + assert_true(event.defaultPrevented); + assert_false(host.dispatchEvent(event)); + assert_equals(event.target, null); + assert_equals(event.relatedTarget, null); + // Check that the dispatch flag is cleared + event.initEvent("x"); + assert_equals(event.type, "x"); +}, "Reset targets on early return"); + +test(t => { + const input = document.body.appendChild(document.createElement("input")), + event = new MouseEvent("click", { relatedTarget: shadow }); + let seen = false; + t.add_cleanup(() => input.remove()); + input.type = "checkbox"; + input.oninput = t.step_func(() => { + assert_equals(event.target, null); + assert_equals(event.relatedTarget, null); + assert_equals(event.composedPath().length, 0); + seen = true; + }); + assert_true(input.dispatchEvent(event)); + assert_true(seen); +}, "Reset targets before activation behavior"); diff --git a/testing/web-platform/tests/dom/events/replace-event-listener-null-browsing-context-crash.html b/testing/web-platform/tests/dom/events/replace-event-listener-null-browsing-context-crash.html new file mode 100644 index 0000000000..f41955eedd --- /dev/null +++ b/testing/web-platform/tests/dom/events/replace-event-listener-null-browsing-context-crash.html @@ -0,0 +1,16 @@ + +Event listeners: replace listener after moving between documents + + + + + + + + diff --git a/testing/web-platform/tests/dom/events/resources/empty-document.html b/testing/web-platform/tests/dom/events/resources/empty-document.html new file mode 100644 index 0000000000..b9cd130a07 --- /dev/null +++ b/testing/web-platform/tests/dom/events/resources/empty-document.html @@ -0,0 +1,3 @@ + + + diff --git a/testing/web-platform/tests/dom/events/resources/event-global-extra-frame.html b/testing/web-platform/tests/dom/events/resources/event-global-extra-frame.html new file mode 100644 index 0000000000..241dda8b66 --- /dev/null +++ b/testing/web-platform/tests/dom/events/resources/event-global-extra-frame.html @@ -0,0 +1,9 @@ + diff --git a/testing/web-platform/tests/dom/events/resources/event-global-is-still-set-when-coercing-beforeunload-result-frame.html b/testing/web-platform/tests/dom/events/resources/event-global-is-still-set-when-coercing-beforeunload-result-frame.html new file mode 100644 index 0000000000..5df4fa2793 --- /dev/null +++ b/testing/web-platform/tests/dom/events/resources/event-global-is-still-set-when-coercing-beforeunload-result-frame.html @@ -0,0 +1,6 @@ + + + + diff --git a/testing/web-platform/tests/dom/events/resources/prefixed-animation-event-tests.js b/testing/web-platform/tests/dom/events/resources/prefixed-animation-event-tests.js new file mode 100644 index 0000000000..021b6bb9df --- /dev/null +++ b/testing/web-platform/tests/dom/events/resources/prefixed-animation-event-tests.js @@ -0,0 +1,366 @@ +'use strict' + +// Runs a set of tests for a given prefixed/unprefixed animation event (e.g. +// animationstart/webkitAnimationStart). +// +// The eventDetails object must have the following form: +// { +// isTransition: false, <-- can be omitted, default false +// unprefixedType: 'animationstart', +// prefixedType: 'webkitAnimationStart', +// animationCssStyle: '1ms', <-- must NOT include animation name or +// transition property +// } +function runAnimationEventTests(eventDetails) { + const { + isTransition, + unprefixedType, + prefixedType, + animationCssStyle + } = eventDetails; + + // Derive the DOM event handler names, e.g. onanimationstart. + const unprefixedHandler = `on${unprefixedType}`; + const prefixedHandler = `on${prefixedType.toLowerCase()}`; + + const style = document.createElement('style'); + document.head.appendChild(style); + if (isTransition) { + style.sheet.insertRule( + `.baseStyle { width: 100px; transition: width ${animationCssStyle}; }`); + style.sheet.insertRule('.transition { width: 200px !important; }'); + } else { + style.sheet.insertRule('@keyframes anim {}'); + } + + function triggerAnimation(div) { + if (isTransition) { + div.classList.add('transition'); + } else { + div.style.animation = `anim ${animationCssStyle}`; + } + } + + test(t => { + const div = createDiv(t); + + assert_equals(div[unprefixedHandler], null, + `${unprefixedHandler} should initially be null`); + assert_equals(div[prefixedHandler], null, + `${prefixedHandler} should initially be null`); + + // Setting one should not affect the other. + div[unprefixedHandler] = () => { }; + + assert_not_equals(div[unprefixedHandler], null, + `setting ${unprefixedHandler} should make it non-null`); + assert_equals(div[prefixedHandler], null, + `setting ${unprefixedHandler} should not affect ${prefixedHandler}`); + + div[prefixedHandler] = () => { }; + + assert_not_equals(div[prefixedHandler], null, + `setting ${prefixedHandler} should make it non-null`); + assert_not_equals(div[unprefixedHandler], div[prefixedHandler], + 'the setters should be different'); + }, `${unprefixedHandler} and ${prefixedHandler} are not aliases`); + + // The below tests primarily test the interactions of prefixed animation + // events in the algorithm for invoking events: + // https://dom.spec.whatwg.org/#concept-event-listener-invoke + + promise_test(async t => { + const div = createDiv(t); + + let receivedEventCount = 0; + addTestScopedEventHandler(t, div, prefixedHandler, () => { + receivedEventCount++; + }); + addTestScopedEventListener(t, div, prefixedType, () => { + receivedEventCount++; + }); + + // The HTML spec[0] specifies that the prefixed event handlers have an + // 'Event handler event type' of the appropriate prefixed event type. E.g. + // onwebkitanimationend creates a listener for the event type + // 'webkitAnimationEnd'. + // + // [0]: https://html.spec.whatwg.org/multipage/webappapis.html#event-handlers-on-elements,-document-objects,-and-window-objects + div.dispatchEvent(new AnimationEvent(prefixedType)); + assert_equals(receivedEventCount, 2, + 'prefixed listener and handler received event'); + }, `dispatchEvent of a ${prefixedType} event does trigger a ` + + `prefixed event handler or listener`); + + promise_test(async t => { + const div = createDiv(t); + + let receivedEvent = false; + addTestScopedEventHandler(t, div, unprefixedHandler, () => { + receivedEvent = true; + }); + addTestScopedEventListener(t, div, unprefixedType, () => { + receivedEvent = true; + }); + + div.dispatchEvent(new AnimationEvent(prefixedType)); + assert_false(receivedEvent, + 'prefixed listener or handler received event'); + }, `dispatchEvent of a ${prefixedType} event does not trigger an ` + + `unprefixed event handler or listener`); + + + promise_test(async t => { + const div = createDiv(t); + + let receivedEvent = false; + addTestScopedEventHandler(t, div, prefixedHandler, () => { + receivedEvent = true; + }); + addTestScopedEventListener(t, div, prefixedType, () => { + receivedEvent = true; + }); + + // The rewrite rules from + // https://dom.spec.whatwg.org/#concept-event-listener-invoke step 8 do not + // apply because isTrusted will be false. + div.dispatchEvent(new AnimationEvent(unprefixedType)); + assert_false(receivedEvent, 'prefixed listener or handler received event'); + }, `dispatchEvent of an ${unprefixedType} event does not trigger a ` + + `prefixed event handler or listener`); + + promise_test(async t => { + const div = createDiv(t); + + let receivedEvent = false; + addTestScopedEventHandler(t, div, prefixedHandler, () => { + receivedEvent = true; + }); + + triggerAnimation(div); + await waitForEventThenAnimationFrame(t, unprefixedType); + assert_true(receivedEvent, `received ${prefixedHandler} event`); + }, `${prefixedHandler} event handler should trigger for an animation`); + + promise_test(async t => { + const div = createDiv(t); + + let receivedPrefixedEvent = false; + addTestScopedEventHandler(t, div, prefixedHandler, () => { + receivedPrefixedEvent = true; + }); + let receivedUnprefixedEvent = false; + addTestScopedEventHandler(t, div, unprefixedHandler, () => { + receivedUnprefixedEvent = true; + }); + + triggerAnimation(div); + await waitForEventThenAnimationFrame(t, unprefixedType); + assert_true(receivedUnprefixedEvent, `received ${unprefixedHandler} event`); + assert_false(receivedPrefixedEvent, `received ${prefixedHandler} event`); + }, `${prefixedHandler} event handler should not trigger if an unprefixed ` + + `event handler also exists`); + + promise_test(async t => { + const div = createDiv(t); + + let receivedPrefixedEvent = false; + addTestScopedEventHandler(t, div, prefixedHandler, () => { + receivedPrefixedEvent = true; + }); + let receivedUnprefixedEvent = false; + addTestScopedEventListener(t, div, unprefixedType, () => { + receivedUnprefixedEvent = true; + }); + + triggerAnimation(div); + await waitForEventThenAnimationFrame(t, unprefixedHandler); + assert_true(receivedUnprefixedEvent, `received ${unprefixedHandler} event`); + assert_false(receivedPrefixedEvent, `received ${prefixedHandler} event`); + }, `${prefixedHandler} event handler should not trigger if an unprefixed ` + + `listener also exists`); + + promise_test(async t => { + // We use a parent/child relationship to be able to register both prefixed + // and unprefixed event handlers without the deduplication logic kicking in. + const parent = createDiv(t); + const child = createDiv(t); + parent.appendChild(child); + // After moving the child, we have to clean style again. + getComputedStyle(child).transition; + getComputedStyle(child).width; + + let observedUnprefixedType; + addTestScopedEventHandler(t, parent, unprefixedHandler, e => { + observedUnprefixedType = e.type; + }); + let observedPrefixedType; + addTestScopedEventHandler(t, child, prefixedHandler, e => { + observedPrefixedType = e.type; + }); + + triggerAnimation(child); + await waitForEventThenAnimationFrame(t, unprefixedType); + + assert_equals(observedUnprefixedType, unprefixedType); + assert_equals(observedPrefixedType, prefixedType); + }, `event types for prefixed and unprefixed ${unprefixedType} event ` + + `handlers should be named appropriately`); + + promise_test(async t => { + const div = createDiv(t); + + let receivedEvent = false; + addTestScopedEventListener(t, div, prefixedType, () => { + receivedEvent = true; + }); + + triggerAnimation(div); + await waitForEventThenAnimationFrame(t, unprefixedHandler); + assert_true(receivedEvent, `received ${prefixedType} event`); + }, `${prefixedType} event listener should trigger for an animation`); + + promise_test(async t => { + const div = createDiv(t); + + let receivedPrefixedEvent = false; + addTestScopedEventListener(t, div, prefixedType, () => { + receivedPrefixedEvent = true; + }); + let receivedUnprefixedEvent = false; + addTestScopedEventListener(t, div, unprefixedType, () => { + receivedUnprefixedEvent = true; + }); + + triggerAnimation(div); + await waitForEventThenAnimationFrame(t, unprefixedHandler); + assert_true(receivedUnprefixedEvent, `received ${unprefixedType} event`); + assert_false(receivedPrefixedEvent, `received ${prefixedType} event`); + }, `${prefixedType} event listener should not trigger if an unprefixed ` + + `listener also exists`); + + promise_test(async t => { + const div = createDiv(t); + + let receivedPrefixedEvent = false; + addTestScopedEventListener(t, div, prefixedType, () => { + receivedPrefixedEvent = true; + }); + let receivedUnprefixedEvent = false; + addTestScopedEventHandler(t, div, unprefixedHandler, () => { + receivedUnprefixedEvent = true; + }); + + triggerAnimation(div); + await waitForEventThenAnimationFrame(t, unprefixedHandler); + assert_true(receivedUnprefixedEvent, `received ${unprefixedType} event`); + assert_false(receivedPrefixedEvent, `received ${prefixedType} event`); + }, `${prefixedType} event listener should not trigger if an unprefixed ` + + `event handler also exists`); + + promise_test(async t => { + // We use a parent/child relationship to be able to register both prefixed + // and unprefixed event listeners without the deduplication logic kicking in. + const parent = createDiv(t); + const child = createDiv(t); + parent.appendChild(child); + // After moving the child, we have to clean style again. + getComputedStyle(child).transition; + getComputedStyle(child).width; + + let observedUnprefixedType; + addTestScopedEventListener(t, parent, unprefixedType, e => { + observedUnprefixedType = e.type; + }); + let observedPrefixedType; + addTestScopedEventListener(t, child, prefixedType, e => { + observedPrefixedType = e.type; + }); + + triggerAnimation(child); + await waitForEventThenAnimationFrame(t, unprefixedHandler); + + assert_equals(observedUnprefixedType, unprefixedType); + assert_equals(observedPrefixedType, prefixedType); + }, `event types for prefixed and unprefixed ${unprefixedType} event ` + + `listeners should be named appropriately`); + + promise_test(async t => { + const div = createDiv(t); + + let receivedEvent = false; + addTestScopedEventListener(t, div, prefixedType.toLowerCase(), () => { + receivedEvent = true; + }); + addTestScopedEventListener(t, div, prefixedType.toUpperCase(), () => { + receivedEvent = true; + }); + + triggerAnimation(div); + await waitForEventThenAnimationFrame(t, unprefixedHandler); + assert_false(receivedEvent, `received ${prefixedType} event`); + }, `${prefixedType} event listener is case sensitive`); +} + +// Below are utility functions. + +// Creates a div element, appends it to the document body and removes the +// created element during test cleanup. +function createDiv(test) { + const element = document.createElement('div'); + element.classList.add('baseStyle'); + document.body.appendChild(element); + test.add_cleanup(() => { + element.remove(); + }); + + // Flush style before returning. Some browsers only do partial style re-calc, + // so ask for all important properties to make sure they are applied. + getComputedStyle(element).transition; + getComputedStyle(element).width; + + return element; +} + +// Adds an event handler for |handlerName| (calling |callback|) to the given +// |target|, that will automatically be cleaned up at the end of the test. +function addTestScopedEventHandler(test, target, handlerName, callback) { + assert_regexp_match( + handlerName, /^on/, 'Event handler names must start with "on"'); + assert_equals(target[handlerName], null, + `${handlerName} must be supported and not previously set`); + target[handlerName] = callback; + // We need this cleaned up even if the event handler doesn't run. + test.add_cleanup(() => { + if (target[handlerName]) + target[handlerName] = null; + }); +} + +// Adds an event listener for |type| (calling |callback|) to the given +// |target|, that will automatically be cleaned up at the end of the test. +function addTestScopedEventListener(test, target, type, callback) { + target.addEventListener(type, callback); + // We need this cleaned up even if the event handler doesn't run. + test.add_cleanup(() => { + target.removeEventListener(type, callback); + }); +} + +// Returns a promise that will resolve once the passed event (|eventName|) has +// triggered and one more animation frame has happened. Automatically chooses +// between an event handler or event listener based on whether |eventName| +// begins with 'on'. +// +// We always listen on window as we don't want to interfere with the test via +// triggering the prefixed event deduplication logic. +function waitForEventThenAnimationFrame(test, eventName) { + return new Promise((resolve, _) => { + const eventFunc = eventName.startsWith('on') + ? addTestScopedEventHandler : addTestScopedEventListener; + eventFunc(test, window, eventName, () => { + // rAF once to give the event under test time to come through. + requestAnimationFrame(resolve); + }); + }); +} diff --git a/testing/web-platform/tests/dom/events/scrolling/iframe-chains.html b/testing/web-platform/tests/dom/events/scrolling/iframe-chains.html new file mode 100644 index 0000000000..fb7d674aae --- /dev/null +++ b/testing/web-platform/tests/dom/events/scrolling/iframe-chains.html @@ -0,0 +1,48 @@ + + + + + + + + + + + +
+ +
+
+
+ + + diff --git a/testing/web-platform/tests/dom/events/scrolling/input-text-scroll-event-when-using-arrow-keys.html b/testing/web-platform/tests/dom/events/scrolling/input-text-scroll-event-when-using-arrow-keys.html new file mode 100644 index 0000000000..f84e446527 --- /dev/null +++ b/testing/web-platform/tests/dom/events/scrolling/input-text-scroll-event-when-using-arrow-keys.html @@ -0,0 +1,71 @@ + + + + + + + + + + + +

Moving the cursor using the arrow keys into an + input element fires scroll events when text has to scroll into view. + Uses arrow keys to move forward and backwards in the input + element.

+ + + + + + diff --git a/testing/web-platform/tests/dom/events/scrolling/overscroll-deltas.html b/testing/web-platform/tests/dom/events/scrolling/overscroll-deltas.html new file mode 100644 index 0000000000..6f0b77f22e --- /dev/null +++ b/testing/web-platform/tests/dom/events/scrolling/overscroll-deltas.html @@ -0,0 +1,85 @@ + + + + + + + + + + +
+
+ + + diff --git a/testing/web-platform/tests/dom/events/scrolling/overscroll-event-fired-to-document.html b/testing/web-platform/tests/dom/events/scrolling/overscroll-event-fired-to-document.html new file mode 100644 index 0000000000..c054ffca9c --- /dev/null +++ b/testing/web-platform/tests/dom/events/scrolling/overscroll-event-fired-to-document.html @@ -0,0 +1,62 @@ + + + + + + + + + + +
+
+
+
+ + + diff --git a/testing/web-platform/tests/dom/events/scrolling/overscroll-event-fired-to-element-with-overscroll-behavior.html b/testing/web-platform/tests/dom/events/scrolling/overscroll-event-fired-to-element-with-overscroll-behavior.html new file mode 100644 index 0000000000..750080e656 --- /dev/null +++ b/testing/web-platform/tests/dom/events/scrolling/overscroll-event-fired-to-element-with-overscroll-behavior.html @@ -0,0 +1,92 @@ + + + + + + + + + + +
+
+
+
+
+
+
+
+
+
+
+
+ + + diff --git a/testing/web-platform/tests/dom/events/scrolling/overscroll-event-fired-to-scrolled-element.html b/testing/web-platform/tests/dom/events/scrolling/overscroll-event-fired-to-scrolled-element.html new file mode 100644 index 0000000000..cfc782a809 --- /dev/null +++ b/testing/web-platform/tests/dom/events/scrolling/overscroll-event-fired-to-scrolled-element.html @@ -0,0 +1,65 @@ + + + + + + + + + + +
+
+
+
+ + + diff --git a/testing/web-platform/tests/dom/events/scrolling/overscroll-event-fired-to-window.html b/testing/web-platform/tests/dom/events/scrolling/overscroll-event-fired-to-window.html new file mode 100644 index 0000000000..ef5ae3daef --- /dev/null +++ b/testing/web-platform/tests/dom/events/scrolling/overscroll-event-fired-to-window.html @@ -0,0 +1,52 @@ + + + + + + + + + + +
+
+
+
+ + + diff --git a/testing/web-platform/tests/dom/events/scrolling/scroll_support.js b/testing/web-platform/tests/dom/events/scrolling/scroll_support.js new file mode 100644 index 0000000000..169393e4c3 --- /dev/null +++ b/testing/web-platform/tests/dom/events/scrolling/scroll_support.js @@ -0,0 +1,163 @@ +async function waitForScrollendEvent(test, target, timeoutMs = 500) { + return new Promise((resolve, reject) => { + const timeoutCallback = test.step_timeout(() => { + reject(`No Scrollend event received for target ${target}`); + }, timeoutMs); + target.addEventListener('scrollend', (evt) => { + clearTimeout(timeoutCallback); + resolve(evt); + }, { once: true }); + }); +} + +const MAX_FRAME = 700; +const MAX_UNCHANGED_FRAMES = 20; + +// Returns a promise that resolves when the given condition is met or rejects +// after MAX_FRAME animation frames. +// TODO(crbug.com/1400399): deprecate. We should not use frame based waits in +// WPT as frame rates may vary greatly in different testing environments. +function waitFor(condition, error_message = 'Reaches the maximum frames.') { + return new Promise((resolve, reject) => { + function tick(frames) { + // We requestAnimationFrame either for MAX_FRAM frames or until condition + // is met. + if (frames >= MAX_FRAME) + reject(error_message); + else if (condition()) + resolve(); + else + requestAnimationFrame(tick.bind(this, frames + 1)); + } + tick(0); + }); +} + +// TODO(crbug.com/1400446): Test driver should defer sending events until the +// browser is ready. Also the term compositor-commit is misleading as not all +// user-agents use a compositor process. +function waitForCompositorCommit() { + return new Promise((resolve) => { + // rAF twice. + window.requestAnimationFrame(() => { + window.requestAnimationFrame(resolve); + }); + }); +} + +// TODO(crbug.com/1400399): Deprecate as frame rates may vary greatly in +// different test environments. +function waitForAnimationEnd(getValue) { + var last_changed_frame = 0; + var last_position = getValue(); + return new Promise((resolve, reject) => { + function tick(frames) { + // We requestAnimationFrame either for MAX_FRAME or until + // MAX_UNCHANGED_FRAMES with no change have been observed. + if (frames >= MAX_FRAME || frames - last_changed_frame > MAX_UNCHANGED_FRAMES) { + resolve(); + } else { + current_value = getValue(); + if (last_position != current_value) { + last_changed_frame = frames; + last_position = current_value; + } + requestAnimationFrame(tick.bind(this, frames + 1)); + } + } + tick(0); + }) +} + +// Scrolls in target according to move_path with pauses in between +function touchScrollInTargetSequentiallyWithPause(target, move_path, pause_time_in_ms = 100) { + const test_driver_actions = new test_driver.Actions() + .addPointer("pointer1", "touch") + .pointerMove(0, 0, {origin: target}) + .pointerDown(); + + const substeps = 5; + let x = 0; + let y = 0; + // Do each move in 5 steps + for(let move of move_path) { + let step_x = (move.x - x) / substeps; + let step_y = (move.y - y) / substeps; + for(let step = 0; step < substeps; step++) { + x += step_x; + y += step_y; + test_driver_actions.pointerMove(x, y, {origin: target}); + } + test_driver_actions.pause(pause_time_in_ms); + } + + return test_driver_actions.pointerUp().send(); +} + +function touchScrollInTarget(pixels_to_scroll, target, direction, pause_time_in_ms = 100) { + var x_delta = 0; + var y_delta = 0; + const num_movs = 5; + if (direction == "down") { + y_delta = -1 * pixels_to_scroll / num_movs; + } else if (direction == "up") { + y_delta = pixels_to_scroll / num_movs; + } else if (direction == "right") { + x_delta = -1 * pixels_to_scroll / num_movs; + } else if (direction == "left") { + x_delta = pixels_to_scroll / num_movs; + } else { + throw("scroll direction '" + direction + "' is not expected, direction should be 'down', 'up', 'left' or 'right'"); + } + return new test_driver.Actions() + .addPointer("pointer1", "touch") + .pointerMove(0, 0, {origin: target}) + .pointerDown() + .pointerMove(x_delta, y_delta, {origin: target}) + .pointerMove(2 * x_delta, 2 * y_delta, {origin: target}) + .pointerMove(3 * x_delta, 3 * y_delta, {origin: target}) + .pointerMove(4 * x_delta, 4 * y_delta, {origin: target}) + .pointerMove(5 * x_delta, 5 * y_delta, {origin: target}) + .pause(pause_time_in_ms) + .pointerUp() + .send(); +} + +// Trigger fling by doing pointerUp right after pointerMoves. +function touchFlingInTarget(pixels_to_scroll, target, direction) { + touchScrollInTarget(pixels_to_scroll, target, direction, 0 /* pause_time */); +} + +function mouseActionsInTarget(target, origin, delta, pause_time_in_ms = 100) { + return new test_driver.Actions() + .addPointer("pointer1", "mouse") + .pointerMove(origin.x, origin.y, { origin: target }) + .pointerDown() + .pointerMove(origin.x + delta.x, origin.y + delta.y, { origin: target }) + .pointerMove(origin.x + delta.x * 2, origin.y + delta.y * 2, { origin: target }) + .pause(pause_time_in_ms) + .pointerUp() + .send(); +} + +// Returns a promise that resolves when the given condition holds for 10 +// animation frames or rejects if the condition changes to false within 10 +// animation frames. +// TODO(crbug.com/1400399): Deprecate as frame rates may very greatly in +// different test environments. +function conditionHolds(condition, error_message = 'Condition is not true anymore.') { + const MAX_FRAME = 10; + return new Promise((resolve, reject) => { + function tick(frames) { + // We requestAnimationFrame either for 10 frames or until condition is + // violated. + if (frames >= MAX_FRAME) + resolve(); + else if (!condition()) + reject(error_message); + else + requestAnimationFrame(tick.bind(this, frames + 1)); + } + tick(0); + }); +} diff --git a/testing/web-platform/tests/dom/events/scrolling/scrollend-event-fired-after-sequence-of-scrolls.tentative.html b/testing/web-platform/tests/dom/events/scrolling/scrollend-event-fired-after-sequence-of-scrolls.tentative.html new file mode 100644 index 0000000000..77bf029ced --- /dev/null +++ b/testing/web-platform/tests/dom/events/scrolling/scrollend-event-fired-after-sequence-of-scrolls.tentative.html @@ -0,0 +1,63 @@ + + + + + + + + + + + +
+
+
+
+ + + diff --git a/testing/web-platform/tests/dom/events/scrolling/scrollend-event-fired-after-snap.html b/testing/web-platform/tests/dom/events/scrolling/scrollend-event-fired-after-snap.html new file mode 100644 index 0000000000..03079ddc6c --- /dev/null +++ b/testing/web-platform/tests/dom/events/scrolling/scrollend-event-fired-after-snap.html @@ -0,0 +1,87 @@ + + + + + + + + + + + +
+
+
+
+
+
+ + + diff --git a/testing/web-platform/tests/dom/events/scrolling/scrollend-event-fired-for-programmatic-scroll.html b/testing/web-platform/tests/dom/events/scrolling/scrollend-event-fired-for-programmatic-scroll.html new file mode 100644 index 0000000000..c6569e0beb --- /dev/null +++ b/testing/web-platform/tests/dom/events/scrolling/scrollend-event-fired-for-programmatic-scroll.html @@ -0,0 +1,135 @@ + + + + + + + + + + + + +
+
+
+
+ + diff --git a/testing/web-platform/tests/dom/events/scrolling/scrollend-event-fired-for-scrollIntoView.html b/testing/web-platform/tests/dom/events/scrolling/scrollend-event-fired-for-scrollIntoView.html new file mode 100644 index 0000000000..8782b1dfee --- /dev/null +++ b/testing/web-platform/tests/dom/events/scrolling/scrollend-event-fired-for-scrollIntoView.html @@ -0,0 +1,124 @@ + + + + + + + + + + + + +
+
+
+
+ + diff --git a/testing/web-platform/tests/dom/events/scrolling/scrollend-event-fired-to-document.html b/testing/web-platform/tests/dom/events/scrolling/scrollend-event-fired-to-document.html new file mode 100644 index 0000000000..3090455388 --- /dev/null +++ b/testing/web-platform/tests/dom/events/scrolling/scrollend-event-fired-to-document.html @@ -0,0 +1,70 @@ + + + + + + + + + + + +
+
+
+
+ + + diff --git a/testing/web-platform/tests/dom/events/scrolling/scrollend-event-fired-to-element-with-overscroll-behavior.html b/testing/web-platform/tests/dom/events/scrolling/scrollend-event-fired-to-element-with-overscroll-behavior.html new file mode 100644 index 0000000000..acad168e56 --- /dev/null +++ b/testing/web-platform/tests/dom/events/scrolling/scrollend-event-fired-to-element-with-overscroll-behavior.html @@ -0,0 +1,102 @@ + + + + + + + + + + + +
+
+
+
+
+
+
+
+
+
+
+
+ + + diff --git a/testing/web-platform/tests/dom/events/scrolling/scrollend-event-fired-to-scrolled-element.html b/testing/web-platform/tests/dom/events/scrolling/scrollend-event-fired-to-scrolled-element.html new file mode 100644 index 0000000000..7343396942 --- /dev/null +++ b/testing/web-platform/tests/dom/events/scrolling/scrollend-event-fired-to-scrolled-element.html @@ -0,0 +1,68 @@ + + + + + + + + + + + +
+
+
+
+ + + diff --git a/testing/web-platform/tests/dom/events/scrolling/scrollend-event-fired-to-window.html b/testing/web-platform/tests/dom/events/scrolling/scrollend-event-fired-to-window.html new file mode 100644 index 0000000000..ef72f56d2b --- /dev/null +++ b/testing/web-platform/tests/dom/events/scrolling/scrollend-event-fired-to-window.html @@ -0,0 +1,55 @@ + + + + + + + + + + + +
+
+
+
+ + + diff --git a/testing/web-platform/tests/dom/events/scrolling/scrollend-event-for-user-scroll.html b/testing/web-platform/tests/dom/events/scrolling/scrollend-event-for-user-scroll.html new file mode 100644 index 0000000000..5146c5f719 --- /dev/null +++ b/testing/web-platform/tests/dom/events/scrolling/scrollend-event-for-user-scroll.html @@ -0,0 +1,199 @@ + + + + + + + + + + + + + +
+
+
+
+ + + + diff --git a/testing/web-platform/tests/dom/events/scrolling/scrollend-event-handler-content-attributes.html b/testing/web-platform/tests/dom/events/scrolling/scrollend-event-handler-content-attributes.html new file mode 100644 index 0000000000..47f563c39b --- /dev/null +++ b/testing/web-platform/tests/dom/events/scrolling/scrollend-event-handler-content-attributes.html @@ -0,0 +1,108 @@ + + + + + + + + + + + +
+
+
+
+ + diff --git a/testing/web-platform/tests/dom/events/scrolling/scrollend-event-not-fired-after-removing-scroller.tentative.html b/testing/web-platform/tests/dom/events/scrolling/scrollend-event-not-fired-after-removing-scroller.tentative.html new file mode 100644 index 0000000000..95447fbd12 --- /dev/null +++ b/testing/web-platform/tests/dom/events/scrolling/scrollend-event-not-fired-after-removing-scroller.tentative.html @@ -0,0 +1,84 @@ + + + + + + + + + + + + + + diff --git a/testing/web-platform/tests/dom/events/shadow-relatedTarget.html b/testing/web-platform/tests/dom/events/shadow-relatedTarget.html new file mode 100644 index 0000000000..713555b7d8 --- /dev/null +++ b/testing/web-platform/tests/dom/events/shadow-relatedTarget.html @@ -0,0 +1,30 @@ + + + + +
+ + diff --git a/testing/web-platform/tests/dom/events/webkit-animation-end-event.html b/testing/web-platform/tests/dom/events/webkit-animation-end-event.html new file mode 100644 index 0000000000..4186f6b7a9 --- /dev/null +++ b/testing/web-platform/tests/dom/events/webkit-animation-end-event.html @@ -0,0 +1,20 @@ + + +Prefixed CSS Animation end events + + + + + + + + + diff --git a/testing/web-platform/tests/dom/events/webkit-animation-iteration-event.html b/testing/web-platform/tests/dom/events/webkit-animation-iteration-event.html new file mode 100644 index 0000000000..fb251972a3 --- /dev/null +++ b/testing/web-platform/tests/dom/events/webkit-animation-iteration-event.html @@ -0,0 +1,23 @@ + + +Prefixed CSS Animation iteration events + + + + + + + + + diff --git a/testing/web-platform/tests/dom/events/webkit-animation-start-event.html b/testing/web-platform/tests/dom/events/webkit-animation-start-event.html new file mode 100644 index 0000000000..ad1036644a --- /dev/null +++ b/testing/web-platform/tests/dom/events/webkit-animation-start-event.html @@ -0,0 +1,20 @@ + + +Prefixed CSS Animation start events + + + + + + + + + diff --git a/testing/web-platform/tests/dom/events/webkit-transition-end-event.html b/testing/web-platform/tests/dom/events/webkit-transition-end-event.html new file mode 100644 index 0000000000..2741824e30 --- /dev/null +++ b/testing/web-platform/tests/dom/events/webkit-transition-end-event.html @@ -0,0 +1,21 @@ + + +Prefixed CSS Transition End event + + + + + + + + + diff --git a/testing/web-platform/tests/dom/historical.html b/testing/web-platform/tests/dom/historical.html new file mode 100644 index 0000000000..1bc209ec0e --- /dev/null +++ b/testing/web-platform/tests/dom/historical.html @@ -0,0 +1,222 @@ + +Historical DOM features must be removed + + +
+ diff --git a/testing/web-platform/tests/dom/idlharness-shadowrealm.window.js b/testing/web-platform/tests/dom/idlharness-shadowrealm.window.js new file mode 100644 index 0000000000..cb03c07c9b --- /dev/null +++ b/testing/web-platform/tests/dom/idlharness-shadowrealm.window.js @@ -0,0 +1,2 @@ +// META: script=/resources/idlharness-shadowrealm.js +idl_test_shadowrealm(["dom"], ["html"]); diff --git a/testing/web-platform/tests/dom/idlharness.any.js b/testing/web-platform/tests/dom/idlharness.any.js new file mode 100644 index 0000000000..26da3ab3bf --- /dev/null +++ b/testing/web-platform/tests/dom/idlharness.any.js @@ -0,0 +1,25 @@ +// META: global=worker +// META: script=/resources/WebIDLParser.js +// META: script=/resources/idlharness.js +// META: timeout=long + +// Note: This test doesn't cover the Window context, see idlharness.window.js +// for that coverage and why it can't be merged into this test. + +'use strict'; + +idl_test( + ['dom'], + ['html'], + idl_array => { + idl_array.add_objects({ + EventTarget: ['new EventTarget()'], + Event: ['new Event("foo")'], + CustomEvent: ['new CustomEvent("foo")'], + AbortController: ['new AbortController()'], + AbortSignal: ['new AbortController().signal'], + }); + } +); + +done(); diff --git a/testing/web-platform/tests/dom/idlharness.window.js b/testing/web-platform/tests/dom/idlharness.window.js new file mode 100644 index 0000000000..2c7bfd727e --- /dev/null +++ b/testing/web-platform/tests/dom/idlharness.window.js @@ -0,0 +1,52 @@ +// META: script=/resources/WebIDLParser.js +// META: script=/resources/idlharness.js +// META: script=/common/subset-tests-by-key.js +// META: variant=?include=Node +// META: variant=?exclude=Node +// META: timeout=long + +// Note: This isn't merged into idlharness.any.js because of the use of variants, +// i.e., include=Node wouldn't make sense for workers. + +'use strict'; + +idl_test( + ['dom', 'fullscreen'], + ['html'], + idl_array => { + self.xmlDoc = document.implementation.createDocument(null, '', null); + self.detachedRange = document.createRange(); + detachedRange.detach(); + self.element = xmlDoc.createElementNS(null, 'test'); + element.setAttribute('bar', 'baz'); + + idl_array.add_objects({ + EventTarget: ['new EventTarget()'], + Event: ['document.createEvent("Event")', 'new Event("foo")'], + CustomEvent: ['new CustomEvent("foo")'], + AbortController: ['new AbortController()'], + AbortSignal: ['new AbortController().signal'], + Document: ['new Document()'], + 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'], + XPathEvaluator: ['new XPathEvaluator()'], + XPathExpression: ['document.createExpression("//*")'], + XPathNSResolver: ['document.createNSResolver(document.body)'], + XPathResult: ['document.evaluate("//*", document.body)'], + XSLTProcessor: ['new XSLTProcessor()'], + }); + } +); diff --git a/testing/web-platform/tests/dom/interface-objects.html b/testing/web-platform/tests/dom/interface-objects.html new file mode 100644 index 0000000000..936d63517e --- /dev/null +++ b/testing/web-platform/tests/dom/interface-objects.html @@ -0,0 +1,46 @@ + +Interfaces + + +
+ diff --git a/testing/web-platform/tests/dom/lists/DOMTokenList-Iterable.html b/testing/web-platform/tests/dom/lists/DOMTokenList-Iterable.html new file mode 100644 index 0000000000..4cf84b12a2 --- /dev/null +++ b/testing/web-platform/tests/dom/lists/DOMTokenList-Iterable.html @@ -0,0 +1,34 @@ + + +DOMTokenList Iterable Test + + + + diff --git a/testing/web-platform/tests/dom/lists/DOMTokenList-coverage-for-attributes.html b/testing/web-platform/tests/dom/lists/DOMTokenList-coverage-for-attributes.html new file mode 100644 index 0000000000..e5f060b8ac --- /dev/null +++ b/testing/web-platform/tests/dom/lists/DOMTokenList-coverage-for-attributes.html @@ -0,0 +1,55 @@ + + +DOMTokenList coverage for attributes + + +
+ diff --git a/testing/web-platform/tests/dom/lists/DOMTokenList-iteration.html b/testing/web-platform/tests/dom/lists/DOMTokenList-iteration.html new file mode 100644 index 0000000000..f713ad4aa0 --- /dev/null +++ b/testing/web-platform/tests/dom/lists/DOMTokenList-iteration.html @@ -0,0 +1,71 @@ + + +DOMTokenList iteration: keys, values, etc. + + + + diff --git a/testing/web-platform/tests/dom/lists/DOMTokenList-stringifier.html b/testing/web-platform/tests/dom/lists/DOMTokenList-stringifier.html new file mode 100644 index 0000000000..b125388e02 --- /dev/null +++ b/testing/web-platform/tests/dom/lists/DOMTokenList-stringifier.html @@ -0,0 +1,25 @@ + + +DOMTokenList stringifier + + + + +
+ + diff --git a/testing/web-platform/tests/dom/lists/DOMTokenList-value.html b/testing/web-platform/tests/dom/lists/DOMTokenList-value.html new file mode 100644 index 0000000000..b0e39111d9 --- /dev/null +++ b/testing/web-platform/tests/dom/lists/DOMTokenList-value.html @@ -0,0 +1,24 @@ + + +DOMTokenList value + + + + + + diff --git a/testing/web-platform/tests/dom/lists/README.md b/testing/web-platform/tests/dom/lists/README.md new file mode 100644 index 0000000000..59c821a7da --- /dev/null +++ b/testing/web-platform/tests/dom/lists/README.md @@ -0,0 +1 @@ +See `../nodes/Element-classlist.html` for more DOMTokenList tests. diff --git a/testing/web-platform/tests/dom/nodes/CharacterData-appendChild.html b/testing/web-platform/tests/dom/nodes/CharacterData-appendChild.html new file mode 100644 index 0000000000..eb4f36c681 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/CharacterData-appendChild.html @@ -0,0 +1,34 @@ + + +Node.appendChild applied to CharacterData + + + + +
+ diff --git a/testing/web-platform/tests/dom/nodes/CharacterData-appendData.html b/testing/web-platform/tests/dom/nodes/CharacterData-appendData.html new file mode 100644 index 0000000000..a5d4072244 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/CharacterData-appendData.html @@ -0,0 +1,70 @@ + + +CharacterData.appendData + + + + +
+ diff --git a/testing/web-platform/tests/dom/nodes/CharacterData-data.html b/testing/web-platform/tests/dom/nodes/CharacterData-data.html new file mode 100644 index 0000000000..b3b29ea4d7 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/CharacterData-data.html @@ -0,0 +1,82 @@ + + +CharacterData.data + + + +
+ diff --git a/testing/web-platform/tests/dom/nodes/CharacterData-deleteData.html b/testing/web-platform/tests/dom/nodes/CharacterData-deleteData.html new file mode 100644 index 0000000000..84f4d5b415 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/CharacterData-deleteData.html @@ -0,0 +1,95 @@ + + +CharacterData.deleteData + + + + +
+ diff --git a/testing/web-platform/tests/dom/nodes/CharacterData-insertData.html b/testing/web-platform/tests/dom/nodes/CharacterData-insertData.html new file mode 100644 index 0000000000..62c0ca1018 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/CharacterData-insertData.html @@ -0,0 +1,90 @@ + + +CharacterData.insertData + + + + +
+ diff --git a/testing/web-platform/tests/dom/nodes/CharacterData-remove.html b/testing/web-platform/tests/dom/nodes/CharacterData-remove.html new file mode 100644 index 0000000000..aef9d56bfa --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/CharacterData-remove.html @@ -0,0 +1,24 @@ + + +CharacterData.remove + + + + +
+ diff --git a/testing/web-platform/tests/dom/nodes/CharacterData-replaceData.html b/testing/web-platform/tests/dom/nodes/CharacterData-replaceData.html new file mode 100644 index 0000000000..537751d832 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/CharacterData-replaceData.html @@ -0,0 +1,163 @@ + + +CharacterData.replaceData + + + + +
+ diff --git a/testing/web-platform/tests/dom/nodes/CharacterData-substringData.html b/testing/web-platform/tests/dom/nodes/CharacterData-substringData.html new file mode 100644 index 0000000000..b353526480 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/CharacterData-substringData.html @@ -0,0 +1,137 @@ + + +CharacterData.substringData + + + + +
+ diff --git a/testing/web-platform/tests/dom/nodes/CharacterData-surrogates.html b/testing/web-platform/tests/dom/nodes/CharacterData-surrogates.html new file mode 100644 index 0000000000..ff1014c5fd --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/CharacterData-surrogates.html @@ -0,0 +1,74 @@ + + +Splitting and joining surrogate pairs in CharacterData methods + + + + + + + +
+ diff --git a/testing/web-platform/tests/dom/nodes/ChildNode-after.html b/testing/web-platform/tests/dom/nodes/ChildNode-after.html new file mode 100644 index 0000000000..b5bf7ab5c2 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/ChildNode-after.html @@ -0,0 +1,166 @@ + + +ChildNode.after + + + + + diff --git a/testing/web-platform/tests/dom/nodes/ChildNode-before.html b/testing/web-platform/tests/dom/nodes/ChildNode-before.html new file mode 100644 index 0000000000..8659424465 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/ChildNode-before.html @@ -0,0 +1,166 @@ + + +ChildNode.before + + + + + diff --git a/testing/web-platform/tests/dom/nodes/ChildNode-remove.js b/testing/web-platform/tests/dom/nodes/ChildNode-remove.js new file mode 100644 index 0000000000..c36ba0d117 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/ChildNode-remove.js @@ -0,0 +1,30 @@ +function testRemove(node, parent, type) { + test(function() { + assert_true("remove" in node); + assert_equals(typeof node.remove, "function"); + assert_equals(node.remove.length, 0); + }, type + " should support remove()"); + test(function() { + assert_equals(node.parentNode, null, "Node should not have a parent"); + assert_equals(node.remove(), undefined); + assert_equals(node.parentNode, null, "Removed new node should not have a parent"); + }, "remove() should work if " + type + " doesn't have a parent"); + test(function() { + assert_equals(node.parentNode, null, "Node should not have a parent"); + parent.appendChild(node); + assert_equals(node.parentNode, parent, "Appended node should have a parent"); + assert_equals(node.remove(), undefined); + assert_equals(node.parentNode, null, "Removed node should not have a parent"); + assert_array_equals(parent.childNodes, [], "Parent should not have children"); + }, "remove() should work if " + type + " does have a parent"); + test(function() { + assert_equals(node.parentNode, null, "Node should not have a parent"); + var before = parent.appendChild(document.createComment("before")); + parent.appendChild(node); + var after = parent.appendChild(document.createComment("after")); + assert_equals(node.parentNode, parent, "Appended node should have a parent"); + assert_equals(node.remove(), undefined); + assert_equals(node.parentNode, null, "Removed node should not have a parent"); + assert_array_equals(parent.childNodes, [before, after], "Parent should have two children left"); + }, "remove() should work if " + type + " does have a parent and siblings"); +} diff --git a/testing/web-platform/tests/dom/nodes/ChildNode-replaceWith.html b/testing/web-platform/tests/dom/nodes/ChildNode-replaceWith.html new file mode 100644 index 0000000000..aab8b17f2a --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/ChildNode-replaceWith.html @@ -0,0 +1,110 @@ + + +ChildNode.replaceWith + + + + + diff --git a/testing/web-platform/tests/dom/nodes/Comment-Text-constructor.js b/testing/web-platform/tests/dom/nodes/Comment-Text-constructor.js new file mode 100644 index 0000000000..24b4425f4b --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Comment-Text-constructor.js @@ -0,0 +1,77 @@ +function test_constructor(ctor) { + test(function() { + var object = new window[ctor](); + assert_equals(Object.getPrototypeOf(object), + window[ctor].prototype, "Prototype chain: " + ctor); + assert_equals(Object.getPrototypeOf(Object.getPrototypeOf(object)), + CharacterData.prototype, "Prototype chain: CharacterData"); + assert_equals(Object.getPrototypeOf(Object.getPrototypeOf(Object.getPrototypeOf(object))), + Node.prototype, "Prototype chain: Node"); + }, "new " + ctor + "(): prototype chain"); + + test(function() { + var object = new window[ctor](); + assert_true(object instanceof Node, "Should be a Node"); + assert_true(object instanceof CharacterData, "Should be a CharacterData"); + assert_true(object instanceof window[ctor], "Should be a " + ctor); + }, "new " + ctor + "(): instanceof"); + + test(function() { + var object = new window[ctor](); + assert_equals(object.data, ""); + assert_equals(object.nodeValue, ""); + assert_equals(object.ownerDocument, document); + }, "new " + ctor + "(): no arguments"); + + var testArgs = [ + [undefined, ""], + [null, "null"], + [42, "42"], + ["", ""], + ["-", "-"], + ["--", "--"], + ["-->", "-->"], + [" +DOMImplementation.createHTMLDocument + + + + + + + + +
+ diff --git a/testing/web-platform/tests/dom/nodes/DOMImplementation-createHTMLDocument.js b/testing/web-platform/tests/dom/nodes/DOMImplementation-createHTMLDocument.js new file mode 100644 index 0000000000..3e7e9aa9b7 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/DOMImplementation-createHTMLDocument.js @@ -0,0 +1,25 @@ +function createHTMLDocuments(checkDoc) { + var tests = [ + ["", "", ""], + [null, "null", "null"], + [undefined, undefined, ""], + ["foo bar baz", "foo bar baz", "foo bar baz"], + ["foo\t\tbar baz", "foo\t\tbar baz", "foo bar baz"], + ["foo\n\nbar baz", "foo\n\nbar baz", "foo bar baz"], + ["foo\f\fbar baz", "foo\f\fbar baz", "foo bar baz"], + ["foo\r\rbar baz", "foo\r\rbar baz", "foo bar baz"], + ] + + tests.forEach(function(t, i) { + var title = t[0], expectedtitle = t[1], normalizedtitle = t[2] + test(function() { + var doc = document.implementation.createHTMLDocument(title); + checkDoc(doc, expectedtitle, normalizedtitle) + }, "createHTMLDocument test " + i + ": " + t.map(function(el) { return format_value(el) })) + }) + + test(function() { + var doc = document.implementation.createHTMLDocument(); + checkDoc(doc, undefined, "") + }, "Missing title argument"); +} diff --git a/testing/web-platform/tests/dom/nodes/DOMImplementation-hasFeature.html b/testing/web-platform/tests/dom/nodes/DOMImplementation-hasFeature.html new file mode 100644 index 0000000000..637565a60f --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/DOMImplementation-hasFeature.html @@ -0,0 +1,155 @@ + + +DOMImplementation.hasFeature(feature, version) + + + +
+ diff --git a/testing/web-platform/tests/dom/nodes/Document-Element-getElementsByTagName.js b/testing/web-platform/tests/dom/nodes/Document-Element-getElementsByTagName.js new file mode 100644 index 0000000000..dbbe667ff5 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Document-Element-getElementsByTagName.js @@ -0,0 +1,208 @@ +function test_getElementsByTagName(context, element) { + // TODO: getElementsByTagName("*") + test(function() { + assert_false(context.getElementsByTagName("html") instanceof NodeList, + "Should not return a NodeList") + assert_true(context.getElementsByTagName("html") instanceof HTMLCollection, + "Should return an HTMLCollection") + }, "Interfaces") + + test(function() { + var firstCollection = context.getElementsByTagName("html"), + secondCollection = context.getElementsByTagName("html") + assert_true(firstCollection !== secondCollection || + firstCollection === secondCollection) + }, "Caching is allowed") + + test(function() { + var l = context.getElementsByTagName("nosuchtag") + l[5] = "foopy" + assert_equals(l[5], undefined) + assert_equals(l.item(5), null) + }, "Shouldn't be able to set unsigned properties on a HTMLCollection (non-strict mode)") + + test(function() { + var l = context.getElementsByTagName("nosuchtag") + assert_throws_js(TypeError, function() { + "use strict"; + l[5] = "foopy" + }) + assert_equals(l[5], undefined) + assert_equals(l.item(5), null) + }, "Shouldn't be able to set unsigned properties on a HTMLCollection (strict mode)") + + test(function() { + var l = context.getElementsByTagName("nosuchtag") + var fn = l.item; + assert_equals(fn, HTMLCollection.prototype.item); + l.item = "pass" + assert_equals(l.item, "pass") + assert_equals(HTMLCollection.prototype.item, fn); + }, "Should be able to set expando shadowing a proto prop (item)") + + test(function() { + var l = context.getElementsByTagName("nosuchtag") + var fn = l.namedItem; + assert_equals(fn, HTMLCollection.prototype.namedItem); + l.namedItem = "pass" + assert_equals(l.namedItem, "pass") + assert_equals(HTMLCollection.prototype.namedItem, fn); + }, "Should be able to set expando shadowing a proto prop (namedItem)") + + test(function() { + var t1 = element.appendChild(document.createElement("pre")); + t1.id = "x"; + var t2 = element.appendChild(document.createElement("pre")); + t2.setAttribute("name", "y"); + var t3 = element.appendChild(document.createElementNS("", "pre")); + t3.setAttribute("id", "z"); + var t4 = element.appendChild(document.createElementNS("", "pre")); + t4.setAttribute("name", "w"); + this.add_cleanup(function() { + element.removeChild(t1) + element.removeChild(t2) + element.removeChild(t3) + element.removeChild(t4) + }); + + var list = context.getElementsByTagName('pre'); + var pre = list[0]; + assert_equals(pre.id, "x"); + + var exposedNames = { 'x': 0, 'y': 1, 'z': 2 }; + for (var exposedName in exposedNames) { + assert_equals(list[exposedName], list[exposedNames[exposedName]]); + assert_equals(list[exposedName], list.namedItem(exposedName)); + assert_true(exposedName in list, "'" + exposedName + "' in list"); + assert_true(list.hasOwnProperty(exposedName), + "list.hasOwnProperty('" + exposedName + "')"); + } + + var unexposedNames = ["w"]; + for (var unexposedName of unexposedNames) { + assert_false(unexposedName in list); + assert_false(list.hasOwnProperty(unexposedName)); + assert_equals(list[unexposedName], undefined); + assert_equals(list.namedItem(unexposedName), null); + } + + assert_array_equals(Object.getOwnPropertyNames(list).sort(), + ["0", "1", "2", "3", "x", "y", "z"]); + + var desc = Object.getOwnPropertyDescriptor(list, '0'); + assert_equals(typeof desc, "object", "descriptor should be an object"); + assert_true(desc.enumerable, "desc.enumerable"); + assert_true(desc.configurable, "desc.configurable"); + + desc = Object.getOwnPropertyDescriptor(list, 'x'); + assert_equals(typeof desc, "object", "descriptor should be an object"); + assert_false(desc.enumerable, "desc.enumerable"); + assert_true(desc.configurable, "desc.configurable"); + }, "hasOwnProperty, getOwnPropertyDescriptor, getOwnPropertyNames") + + test(function() { + assert_equals(document.createElementNS("http://www.w3.org/1999/xhtml", "i").localName, "i") // Sanity + var t = element.appendChild(document.createElementNS("http://www.w3.org/1999/xhtml", "I")) + this.add_cleanup(function() {element.removeChild(t)}) + assert_equals(t.localName, "I") + assert_equals(t.tagName, "I") + assert_equals(context.getElementsByTagName("I").length, 0) + assert_equals(context.getElementsByTagName("i").length, 0) + }, "HTML element with uppercase tagName never matches in HTML Documents") + + test(function() { + var t = element.appendChild(document.createElementNS("test", "st")) + this.add_cleanup(function() {element.removeChild(t)}) + assert_array_equals(context.getElementsByTagName("st"), [t]) + assert_array_equals(context.getElementsByTagName("ST"), []) + }, "Element in non-HTML namespace, no prefix, lowercase name") + + test(function() { + var t = element.appendChild(document.createElementNS("test", "ST")) + this.add_cleanup(function() {element.removeChild(t)}) + assert_array_equals(context.getElementsByTagName("ST"), [t]) + assert_array_equals(context.getElementsByTagName("st"), []) + }, "Element in non-HTML namespace, no prefix, uppercase name") + + test(function() { + var t = element.appendChild(document.createElementNS("test", "te:st")) + this.add_cleanup(function() {element.removeChild(t)}) + assert_array_equals(context.getElementsByTagName("st"), []) + assert_array_equals(context.getElementsByTagName("ST"), []) + assert_array_equals(context.getElementsByTagName("te:st"), [t]) + assert_array_equals(context.getElementsByTagName("te:ST"), []) + }, "Element in non-HTML namespace, prefix, lowercase name") + + test(function() { + var t = element.appendChild(document.createElementNS("test", "te:ST")) + this.add_cleanup(function() {element.removeChild(t)}) + assert_array_equals(context.getElementsByTagName("st"), []) + assert_array_equals(context.getElementsByTagName("ST"), []) + assert_array_equals(context.getElementsByTagName("te:st"), []) + assert_array_equals(context.getElementsByTagName("te:ST"), [t]) + }, "Element in non-HTML namespace, prefix, uppercase name") + + test(function() { + var t = element.appendChild(document.createElement("aÇ")) + this.add_cleanup(function() {element.removeChild(t)}) + assert_equals(t.localName, "aÇ") + assert_array_equals(context.getElementsByTagName("AÇ"), [t], "All uppercase input") + assert_array_equals(context.getElementsByTagName("aÇ"), [t], "Ascii lowercase input") + assert_array_equals(context.getElementsByTagName("aç"), [], "All lowercase input") + }, "Element in HTML namespace, no prefix, non-ascii characters in name") + + test(function() { + var t = element.appendChild(document.createElementNS("test", "AÇ")) + this.add_cleanup(function() {element.removeChild(t)}) + assert_array_equals(context.getElementsByTagName("AÇ"), [t]) + assert_array_equals(context.getElementsByTagName("aÇ"), []) + assert_array_equals(context.getElementsByTagName("aç"), []) + }, "Element in non-HTML namespace, non-ascii characters in name") + + test(function() { + var t = element.appendChild(document.createElementNS("http://www.w3.org/1999/xhtml", "test:aÇ")) + this.add_cleanup(function() {element.removeChild(t)}) + assert_array_equals(context.getElementsByTagName("TEST:AÇ"), [t], "All uppercase input") + assert_array_equals(context.getElementsByTagName("test:aÇ"), [t], "Ascii lowercase input") + assert_array_equals(context.getElementsByTagName("test:aç"), [], "All lowercase input") + }, "Element in HTML namespace, prefix, non-ascii characters in name") + + test(function() { + var t = element.appendChild(document.createElementNS("test", "TEST:AÇ")) + this.add_cleanup(function() {element.removeChild(t)}) + assert_array_equals(context.getElementsByTagName("TEST:AÇ"), [t], "All uppercase input") + assert_array_equals(context.getElementsByTagName("test:aÇ"), [], "Ascii lowercase input") + assert_array_equals(context.getElementsByTagName("test:aç"), [], "All lowercase input") + }, "Element in non-HTML namespace, prefix, non-ascii characters in name") + + test(function() { + var actual = context.getElementsByTagName("*"); + var expected = []; + var get_elements = function(node) { + for (var i = 0; i < node.childNodes.length; i++) { + var child = node.childNodes[i]; + if (child.nodeType === child.ELEMENT_NODE) { + expected.push(child); + get_elements(child); + } + } + } + get_elements(context); + assert_array_equals(actual, expected); + }, "getElementsByTagName('*')") + + test(function() { + var t1 = element.appendChild(document.createElement("abc")); + this.add_cleanup(function() {element.removeChild(t1)}); + + var l = context.getElementsByTagName("abc"); + assert_true(l instanceof HTMLCollection); + assert_equals(l.length, 1); + + var t2 = element.appendChild(document.createElement("abc")); + assert_equals(l.length, 2); + + element.removeChild(t2); + assert_equals(l.length, 1); + }, "getElementsByTagName() should be a live collection"); +} diff --git a/testing/web-platform/tests/dom/nodes/Document-Element-getElementsByTagNameNS.js b/testing/web-platform/tests/dom/nodes/Document-Element-getElementsByTagNameNS.js new file mode 100644 index 0000000000..b610c49d86 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Document-Element-getElementsByTagNameNS.js @@ -0,0 +1,143 @@ +function test_getElementsByTagNameNS(context, element) { + test(function() { + assert_false(context.getElementsByTagNameNS("http://www.w3.org/1999/xhtml", "html") instanceof NodeList, "NodeList") + assert_true(context.getElementsByTagNameNS("http://www.w3.org/1999/xhtml", "html") instanceof HTMLCollection, "HTMLCollection") + var firstCollection = context.getElementsByTagNameNS("http://www.w3.org/1999/xhtml", "html"), + secondCollection = context.getElementsByTagNameNS("http://www.w3.org/1999/xhtml", "html") + assert_true(firstCollection !== secondCollection || firstCollection === secondCollection, + "Caching is allowed.") + }) + + test(function() { + var t = element.appendChild(document.createElementNS("test", "body")) + this.add_cleanup(function() {element.removeChild(t)}) + var actual = context.getElementsByTagNameNS("*", "body"); + var expected = []; + var get_elements = function(node) { + for (var i = 0; i < node.childNodes.length; i++) { + var child = node.childNodes[i]; + if (child.nodeType === child.ELEMENT_NODE) { + if (child.localName == "body") { + expected.push(child); + } + get_elements(child); + } + } + } + get_elements(context); + assert_array_equals(actual, expected); + }, "getElementsByTagNameNS('*', 'body')") + + test(function() { + assert_array_equals(context.getElementsByTagNameNS("", "*"), []); + var t = element.appendChild(document.createElementNS("", "body")) + this.add_cleanup(function() {element.removeChild(t)}) + assert_array_equals(context.getElementsByTagNameNS("", "*"), [t]); + }, "Empty string namespace") + + test(function() { + var t = element.appendChild(document.createElementNS("test", "body")) + this.add_cleanup(function() {element.removeChild(t)}) + assert_array_equals(context.getElementsByTagNameNS("test", "body"), [t]); + }, "body element in test namespace, no prefix") + + test(function() { + var t = element.appendChild(document.createElementNS("test", "test:body")) + this.add_cleanup(function() {element.removeChild(t)}) + assert_array_equals(context.getElementsByTagNameNS("test", "body"), [t]); + }, "body element in test namespace, prefix") + + test(function() { + var t = element.appendChild(document.createElementNS("test", "BODY")) + this.add_cleanup(function() {element.removeChild(t)}) + assert_array_equals(context.getElementsByTagNameNS("test", "BODY"), [t]); + assert_array_equals(context.getElementsByTagNameNS("test", "body"), []); + }, "BODY element in test namespace, no prefix") + + test(function() { + var t = element.appendChild(document.createElementNS("http://www.w3.org/1999/xhtml", "abc")) + this.add_cleanup(function() {element.removeChild(t)}) + assert_array_equals(context.getElementsByTagNameNS("http://www.w3.org/1999/xhtml", "abc"), [t]); + assert_array_equals(context.getElementsByTagNameNS("http://www.w3.org/1999/xhtml", "ABC"), []); + assert_array_equals(context.getElementsByTagNameNS("test", "ABC"), []); + }, "abc element in html namespace") + + test(function() { + var t = element.appendChild(document.createElementNS("http://www.w3.org/1999/xhtml", "ABC")) + this.add_cleanup(function() {element.removeChild(t)}) + assert_array_equals(context.getElementsByTagNameNS("http://www.w3.org/1999/xhtml", "abc"), []); + assert_array_equals(context.getElementsByTagNameNS("http://www.w3.org/1999/xhtml", "ABC"), [t]); + }, "ABC element in html namespace") + + test(function() { + var t = element.appendChild(document.createElementNS("http://www.w3.org/1999/xhtml", "AÇ")) + this.add_cleanup(function() {element.removeChild(t)}) + assert_array_equals(context.getElementsByTagNameNS("http://www.w3.org/1999/xhtml", "AÇ"), [t]); + assert_array_equals(context.getElementsByTagNameNS("test", "aÇ"), []); + assert_array_equals(context.getElementsByTagNameNS("test", "aç"), []); + }, "AÇ, case sensitivity") + + test(function() { + var t = element.appendChild(document.createElementNS("test", "test:BODY")) + this.add_cleanup(function() {element.removeChild(t)}) + assert_array_equals(context.getElementsByTagNameNS("test", "BODY"), [t]); + assert_array_equals(context.getElementsByTagNameNS("test", "body"), []); + }, "BODY element in test namespace, prefix") + + test(function() { + var t = element.appendChild(document.createElementNS("test", "test:test")) + this.add_cleanup(function() {element.removeChild(t)}) + var actual = context.getElementsByTagNameNS("http://www.w3.org/1999/xhtml", "*"); + var expected = []; + var get_elements = function(node) { + for (var i = 0; i < node.childNodes.length; i++) { + var child = node.childNodes[i]; + if (child.nodeType === child.ELEMENT_NODE) { + if (child !== t) { + expected.push(child); + } + get_elements(child); + } + } + } + get_elements(context); + assert_array_equals(actual, expected); + }, "getElementsByTagNameNS('http://www.w3.org/1999/xhtml', '*')") + + test(function() { + var actual = context.getElementsByTagNameNS("*", "*"); + var expected = []; + var get_elements = function(node) { + for (var i = 0; i < node.childNodes.length; i++) { + var child = node.childNodes[i]; + if (child.nodeType === child.ELEMENT_NODE) { + expected.push(child); + get_elements(child); + } + } + } + get_elements(context); + assert_array_equals(actual, expected); + }, "getElementsByTagNameNS('*', '*')") + + test(function() { + assert_array_equals(context.getElementsByTagNameNS("**", "*"), []); + assert_array_equals(context.getElementsByTagNameNS(null, "0"), []); + assert_array_equals(context.getElementsByTagNameNS(null, "div"), []); + }, "Empty lists") + + test(function() { + var t1 = element.appendChild(document.createElementNS("test", "abc")); + this.add_cleanup(function() {element.removeChild(t1)}); + + var l = context.getElementsByTagNameNS("test", "abc"); + assert_true(l instanceof HTMLCollection); + assert_equals(l.length, 1); + + var t2 = element.appendChild(document.createElementNS("test", "abc")); + assert_equals(l.length, 2); + + element.removeChild(t2); + assert_equals(l.length, 1); + }, "getElementsByTagNameNS() should be a live collection"); +} diff --git a/testing/web-platform/tests/dom/nodes/Document-URL.html b/testing/web-platform/tests/dom/nodes/Document-URL.html new file mode 100644 index 0000000000..242def1fb3 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Document-URL.html @@ -0,0 +1,18 @@ + + +Document.URL with redirect + + +
+ diff --git a/testing/web-platform/tests/dom/nodes/Document-adoptNode.html b/testing/web-platform/tests/dom/nodes/Document-adoptNode.html new file mode 100644 index 0000000000..60a4e6772a --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Document-adoptNode.html @@ -0,0 +1,50 @@ + + +Document.adoptNode + + + +
+x + diff --git a/testing/web-platform/tests/dom/nodes/Document-characterSet-normalization-1.html b/testing/web-platform/tests/dom/nodes/Document-characterSet-normalization-1.html new file mode 100644 index 0000000000..0facd50e49 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Document-characterSet-normalization-1.html @@ -0,0 +1,157 @@ + +document.characterSet (inputEncoding and charset as aliases) normalization tests + + +
+ + + + + + diff --git a/testing/web-platform/tests/dom/nodes/Document-characterSet-normalization-2.html b/testing/web-platform/tests/dom/nodes/Document-characterSet-normalization-2.html new file mode 100644 index 0000000000..7c7691bdc1 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Document-characterSet-normalization-2.html @@ -0,0 +1,179 @@ + +document.characterSet (inputEncoding and charset as aliases) normalization tests + + +
+ + + + + + diff --git a/testing/web-platform/tests/dom/nodes/Document-constructor-svg.svg b/testing/web-platform/tests/dom/nodes/Document-constructor-svg.svg new file mode 100644 index 0000000000..77e3d8996e --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Document-constructor-svg.svg @@ -0,0 +1,46 @@ + + + +Document constructor + + + +test(function() { + var doc = new Document(); + assert_true(doc instanceof Node, "Should be a Node"); + assert_true(doc instanceof Document, "Should be a Document"); + assert_false(doc instanceof XMLDocument, "Should not be an XMLDocument"); + assert_equals(Object.getPrototypeOf(doc), Document.prototype, + "Document should be the primary interface"); +}, "new Document(): interfaces") + +test(function() { + var doc = new Document(); + assert_equals(doc.firstChild, null, "firstChild"); + assert_equals(doc.lastChild, null, "lastChild"); + assert_equals(doc.doctype, null, "doctype"); + assert_equals(doc.documentElement, null, "documentElement"); + assert_array_equals(doc.childNodes, [], "childNodes"); +}, "new Document(): children") + +test(function() { + var doc = new Document(); + assert_equals(doc.URL, "about:blank"); + assert_equals(doc.documentURI, "about:blank"); + assert_equals(doc.compatMode, "CSS1Compat"); + assert_equals(doc.characterSet, "UTF-8"); + assert_equals(doc.contentType, "application/xml"); + assert_equals(doc.createElement("DIV").localName, "DIV"); +}, "new Document(): metadata") + +test(function() { + var doc = new Document(); + assert_equals(doc.characterSet, "UTF-8", "characterSet"); + assert_equals(doc.charset, "UTF-8", "charset"); + assert_equals(doc.inputEncoding, "UTF-8", "inputEncoding"); +}, "new Document(): characterSet aliases") + + + diff --git a/testing/web-platform/tests/dom/nodes/Document-constructor-xml.xml b/testing/web-platform/tests/dom/nodes/Document-constructor-xml.xml new file mode 100644 index 0000000000..c9fc775806 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Document-constructor-xml.xml @@ -0,0 +1,49 @@ + + + + +Document constructor + + + + + + + + diff --git a/testing/web-platform/tests/dom/nodes/Document-constructor.html b/testing/web-platform/tests/dom/nodes/Document-constructor.html new file mode 100644 index 0000000000..e17de28471 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Document-constructor.html @@ -0,0 +1,56 @@ + + + +Document constructor + + + +
+ diff --git a/testing/web-platform/tests/dom/nodes/Document-contentType/contentType/contenttype_bmp.html b/testing/web-platform/tests/dom/nodes/Document-contentType/contentType/contenttype_bmp.html new file mode 100644 index 0000000000..8286437416 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Document-contentType/contentType/contenttype_bmp.html @@ -0,0 +1,15 @@ + +BMP document.contentType === 'image/bmp' + + +
+ diff --git a/testing/web-platform/tests/dom/nodes/Document-contentType/contentType/contenttype_css.html b/testing/web-platform/tests/dom/nodes/Document-contentType/contentType/contenttype_css.html new file mode 100644 index 0000000000..0eb35edd5e --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Document-contentType/contentType/contenttype_css.html @@ -0,0 +1,15 @@ + +CSS document.contentType === 'text/css' + + +
+ \ No newline at end of file diff --git a/testing/web-platform/tests/dom/nodes/Document-contentType/contentType/contenttype_datauri_02.html b/testing/web-platform/tests/dom/nodes/Document-contentType/contentType/contenttype_datauri_02.html new file mode 100644 index 0000000000..c124cb3979 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Document-contentType/contentType/contenttype_datauri_02.html @@ -0,0 +1,15 @@ + +Data URI document.contentType === 'text/html' when data URI MIME type is set + + +
+ diff --git a/testing/web-platform/tests/dom/nodes/Document-contentType/contentType/contenttype_gif.html b/testing/web-platform/tests/dom/nodes/Document-contentType/contentType/contenttype_gif.html new file mode 100644 index 0000000000..8dd66dae59 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Document-contentType/contentType/contenttype_gif.html @@ -0,0 +1,15 @@ + +GIF document.contentType === 'image/gif' + + +
+ \ No newline at end of file diff --git a/testing/web-platform/tests/dom/nodes/Document-contentType/contentType/contenttype_html.html b/testing/web-platform/tests/dom/nodes/Document-contentType/contentType/contenttype_html.html new file mode 100644 index 0000000000..2b2d7263eb --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Document-contentType/contentType/contenttype_html.html @@ -0,0 +1,15 @@ + +HTM document.contentType === 'text/html' + + +
+ \ No newline at end of file diff --git a/testing/web-platform/tests/dom/nodes/Document-contentType/contentType/contenttype_javascripturi.html b/testing/web-platform/tests/dom/nodes/Document-contentType/contentType/contenttype_javascripturi.html new file mode 100644 index 0000000000..956589615a --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Document-contentType/contentType/contenttype_javascripturi.html @@ -0,0 +1,16 @@ + +Javascript URI document.contentType === 'text/html' + + +
+ diff --git a/testing/web-platform/tests/dom/nodes/Document-contentType/contentType/contenttype_jpg.html b/testing/web-platform/tests/dom/nodes/Document-contentType/contentType/contenttype_jpg.html new file mode 100644 index 0000000000..13f57ec8b9 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Document-contentType/contentType/contenttype_jpg.html @@ -0,0 +1,15 @@ + +JPG document.contentType === 'image/jpeg' + + +
+ \ No newline at end of file diff --git a/testing/web-platform/tests/dom/nodes/Document-contentType/contentType/contenttype_mimeheader_01.html b/testing/web-platform/tests/dom/nodes/Document-contentType/contentType/contenttype_mimeheader_01.html new file mode 100644 index 0000000000..87885efba6 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Document-contentType/contentType/contenttype_mimeheader_01.html @@ -0,0 +1,15 @@ + +Custom document.contentType === 'text/xml' when explicitly set to this value + + +
+ \ No newline at end of file diff --git a/testing/web-platform/tests/dom/nodes/Document-contentType/contentType/contenttype_mimeheader_02.html b/testing/web-platform/tests/dom/nodes/Document-contentType/contentType/contenttype_mimeheader_02.html new file mode 100644 index 0000000000..33870147fc --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Document-contentType/contentType/contenttype_mimeheader_02.html @@ -0,0 +1,15 @@ + +Custom document.contentType === 'text/html' when explicitly set to this value and an attempt is made to override this value in an HTML meta header + + +
+ \ No newline at end of file diff --git a/testing/web-platform/tests/dom/nodes/Document-contentType/contentType/contenttype_png.html b/testing/web-platform/tests/dom/nodes/Document-contentType/contentType/contenttype_png.html new file mode 100644 index 0000000000..a214ad3e98 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Document-contentType/contentType/contenttype_png.html @@ -0,0 +1,15 @@ + +PNG document.contentType === 'image/png' + + +
+ \ No newline at end of file diff --git a/testing/web-platform/tests/dom/nodes/Document-contentType/contentType/contenttype_txt.html b/testing/web-platform/tests/dom/nodes/Document-contentType/contentType/contenttype_txt.html new file mode 100644 index 0000000000..f40f641fb0 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Document-contentType/contentType/contenttype_txt.html @@ -0,0 +1,15 @@ + +TXT document.contentType === 'text/plain' + + +
+ diff --git a/testing/web-platform/tests/dom/nodes/Document-contentType/contentType/contenttype_xml.html b/testing/web-platform/tests/dom/nodes/Document-contentType/contentType/contenttype_xml.html new file mode 100644 index 0000000000..c382de8490 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Document-contentType/contentType/contenttype_xml.html @@ -0,0 +1,15 @@ + +XML document.contentType === 'application/xml' + + +
+ diff --git a/testing/web-platform/tests/dom/nodes/Document-contentType/contentType/createDocument.html b/testing/web-platform/tests/dom/nodes/Document-contentType/contentType/createDocument.html new file mode 100644 index 0000000000..78a952de4a --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Document-contentType/contentType/createDocument.html @@ -0,0 +1,11 @@ + +document.implementation.createDocument: document.contentType === 'application/xhtml+xml' + + +
+ diff --git a/testing/web-platform/tests/dom/nodes/Document-contentType/contentType/createHTMLDocument.html b/testing/web-platform/tests/dom/nodes/Document-contentType/contentType/createHTMLDocument.html new file mode 100644 index 0000000000..185e3c8c92 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Document-contentType/contentType/createHTMLDocument.html @@ -0,0 +1,11 @@ + +document.implementation.createHTMLDocument: document.contentType === 'text/html' + + +
+ diff --git a/testing/web-platform/tests/dom/nodes/Document-contentType/contentType/xhr_responseType_document.html b/testing/web-platform/tests/dom/nodes/Document-contentType/contentType/xhr_responseType_document.html new file mode 100644 index 0000000000..c2fb6c19fd --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Document-contentType/contentType/xhr_responseType_document.html @@ -0,0 +1,18 @@ + +XHR - retrieve HTML document: document.contentType === 'application/xml' + + +
+ diff --git a/testing/web-platform/tests/dom/nodes/Document-contentType/resources/blob.htm b/testing/web-platform/tests/dom/nodes/Document-contentType/resources/blob.htm new file mode 100644 index 0000000000..9d235ed07c --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Document-contentType/resources/blob.htm @@ -0,0 +1 @@ +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa \ No newline at end of file diff --git a/testing/web-platform/tests/dom/nodes/Document-contentType/resources/blob.txt b/testing/web-platform/tests/dom/nodes/Document-contentType/resources/blob.txt new file mode 100644 index 0000000000..9d235ed07c --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Document-contentType/resources/blob.txt @@ -0,0 +1 @@ +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa \ No newline at end of file diff --git a/testing/web-platform/tests/dom/nodes/Document-contentType/resources/blob.xml b/testing/web-platform/tests/dom/nodes/Document-contentType/resources/blob.xml new file mode 100644 index 0000000000..0922ed14b8 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Document-contentType/resources/blob.xml @@ -0,0 +1,2 @@ + +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa \ No newline at end of file diff --git a/testing/web-platform/tests/dom/nodes/Document-contentType/resources/lib.js b/testing/web-platform/tests/dom/nodes/Document-contentType/resources/lib.js new file mode 100644 index 0000000000..c41d336c08 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Document-contentType/resources/lib.js @@ -0,0 +1 @@ +var t; \ No newline at end of file diff --git a/testing/web-platform/tests/dom/nodes/Document-contentType/resources/style.css b/testing/web-platform/tests/dom/nodes/Document-contentType/resources/style.css new file mode 100644 index 0000000000..bb4ff575b7 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Document-contentType/resources/style.css @@ -0,0 +1,12 @@ +.unknown +{ + background-color:lightblue; +} +.pass +{ + background-color:lime; +} +.fail +{ + background-color:red; +} diff --git a/testing/web-platform/tests/dom/nodes/Document-contentType/resources/t.bmp b/testing/web-platform/tests/dom/nodes/Document-contentType/resources/t.bmp new file mode 100644 index 0000000000..5697c0aef4 Binary files /dev/null and b/testing/web-platform/tests/dom/nodes/Document-contentType/resources/t.bmp differ diff --git a/testing/web-platform/tests/dom/nodes/Document-contentType/resources/t.gif b/testing/web-platform/tests/dom/nodes/Document-contentType/resources/t.gif new file mode 100644 index 0000000000..91f269207a Binary files /dev/null and b/testing/web-platform/tests/dom/nodes/Document-contentType/resources/t.gif differ diff --git a/testing/web-platform/tests/dom/nodes/Document-contentType/resources/t.jpg b/testing/web-platform/tests/dom/nodes/Document-contentType/resources/t.jpg new file mode 100644 index 0000000000..72b51899e4 Binary files /dev/null and b/testing/web-platform/tests/dom/nodes/Document-contentType/resources/t.jpg differ diff --git a/testing/web-platform/tests/dom/nodes/Document-contentType/resources/t.png b/testing/web-platform/tests/dom/nodes/Document-contentType/resources/t.png new file mode 100644 index 0000000000..447d9e3012 Binary files /dev/null and b/testing/web-platform/tests/dom/nodes/Document-contentType/resources/t.png differ diff --git a/testing/web-platform/tests/dom/nodes/Document-contentType/support/contenttype_setter.py b/testing/web-platform/tests/dom/nodes/Document-contentType/support/contenttype_setter.py new file mode 100644 index 0000000000..c4b1f8df27 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Document-contentType/support/contenttype_setter.py @@ -0,0 +1,20 @@ +def main(request, response): + type = request.GET.first(b"type", None) + subtype = request.GET.first(b"subtype", None) + if type and subtype: + response.headers[b"Content-Type"] = type + b"/" + subtype + + removeContentType = request.GET.first(b"removeContentType", None) + if removeContentType: + try: + del response.headers[b"Content-Type"] + except KeyError: + pass + + content = b'' + mimeHead = request.GET.first(b"mime", None); + if mimeHead: + content += b'' % mimeHead + content += b"" + + return content diff --git a/testing/web-platform/tests/dom/nodes/Document-createAttribute.html b/testing/web-platform/tests/dom/nodes/Document-createAttribute.html new file mode 100644 index 0000000000..b3dc8b60b9 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Document-createAttribute.html @@ -0,0 +1,55 @@ + + +Document.createAttribute + + + + +
+ diff --git a/testing/web-platform/tests/dom/nodes/Document-createCDATASection-xhtml.xhtml b/testing/web-platform/tests/dom/nodes/Document-createCDATASection-xhtml.xhtml new file mode 100644 index 0000000000..b0a5a7f284 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Document-createCDATASection-xhtml.xhtml @@ -0,0 +1,22 @@ + + + + + document.createCDATASection + + + + + + + + + + diff --git a/testing/web-platform/tests/dom/nodes/Document-createCDATASection.html b/testing/web-platform/tests/dom/nodes/Document-createCDATASection.html new file mode 100644 index 0000000000..72b3684c75 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Document-createCDATASection.html @@ -0,0 +1,16 @@ + + +document.createCDATASection must throw in HTML documents + + + + + diff --git a/testing/web-platform/tests/dom/nodes/Document-createComment-createTextNode.js b/testing/web-platform/tests/dom/nodes/Document-createComment-createTextNode.js new file mode 100644 index 0000000000..62a38d380d --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Document-createComment-createTextNode.js @@ -0,0 +1,22 @@ +function test_create(method, iface, nodeType, nodeName) { + ["\u000b", "a -- b", "a-", "-b", null, undefined].forEach(function(value) { + test(function() { + var c = document[method](value); + var expected = String(value); + assert_true(c instanceof iface); + assert_true(c instanceof CharacterData); + assert_true(c instanceof Node); + assert_equals(c.ownerDocument, document); + assert_equals(c.data, expected, "data"); + assert_equals(c.nodeValue, expected, "nodeValue"); + assert_equals(c.textContent, expected, "textContent"); + assert_equals(c.length, expected.length); + assert_equals(c.nodeType, nodeType); + assert_equals(c.nodeName, nodeName); + assert_equals(c.hasChildNodes(), false); + assert_equals(c.childNodes.length, 0); + assert_equals(c.firstChild, null); + assert_equals(c.lastChild, null); + }, method + "(" + format_value(value) + ")"); + }); +} diff --git a/testing/web-platform/tests/dom/nodes/Document-createComment.html b/testing/web-platform/tests/dom/nodes/Document-createComment.html new file mode 100644 index 0000000000..a175c3a2f8 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Document-createComment.html @@ -0,0 +1,21 @@ + + +Document.createComment + + + + + + + + + + + + + + +
+ diff --git a/testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/bare_mathml.html b/testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/bare_mathml.html new file mode 100644 index 0000000000..b80a99a784 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/bare_mathml.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/bare_mathml.svg b/testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/bare_mathml.svg new file mode 100644 index 0000000000..b80a99a784 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/bare_mathml.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/bare_mathml.xhtml b/testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/bare_mathml.xhtml new file mode 100644 index 0000000000..b80a99a784 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/bare_mathml.xhtml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/bare_mathml.xml b/testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/bare_mathml.xml new file mode 100644 index 0000000000..b80a99a784 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/bare_mathml.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/bare_svg.html b/testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/bare_svg.html new file mode 100644 index 0000000000..dc1ced5b6b --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/bare_svg.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/bare_svg.svg b/testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/bare_svg.svg new file mode 100644 index 0000000000..dc1ced5b6b --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/bare_svg.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/bare_svg.xhtml b/testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/bare_svg.xhtml new file mode 100644 index 0000000000..dc1ced5b6b --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/bare_svg.xhtml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/bare_svg.xml b/testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/bare_svg.xml new file mode 100644 index 0000000000..dc1ced5b6b --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/bare_svg.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/bare_xhtml.html b/testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/bare_xhtml.html new file mode 100644 index 0000000000..6c70bcfe4d --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/bare_xhtml.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/bare_xhtml.svg b/testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/bare_xhtml.svg new file mode 100644 index 0000000000..6c70bcfe4d --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/bare_xhtml.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/bare_xhtml.xhtml b/testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/bare_xhtml.xhtml new file mode 100644 index 0000000000..6c70bcfe4d --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/bare_xhtml.xhtml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/bare_xhtml.xml b/testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/bare_xhtml.xml new file mode 100644 index 0000000000..6c70bcfe4d --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/bare_xhtml.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/empty.html b/testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/empty.html new file mode 100644 index 0000000000..e69de29bb2 diff --git a/testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/empty.svg b/testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/empty.svg new file mode 100644 index 0000000000..e69de29bb2 diff --git a/testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/empty.xhtml b/testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/empty.xhtml new file mode 100644 index 0000000000..e69de29bb2 diff --git a/testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/empty.xml b/testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/empty.xml new file mode 100644 index 0000000000..e69de29bb2 diff --git a/testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/generate.py b/testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/generate.py new file mode 100755 index 0000000000..a0bca546c7 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/generate.py @@ -0,0 +1,80 @@ +#!/usr/bin/python + +from __future__ import print_function + +import os +import sys + +THIS_NAME = u"generate.py" + +# Note: these lists must be kept in sync with the lists in +# Document-createElement-namespace.html, and this script must be run whenever +# the lists are updated. (We could keep the lists in a shared JSON file, but +# seems like too much effort.) +FILES = ( + (u"empty", u""), + (u"minimal_html", u""), + + (u"xhtml", u''), + (u"svg", u''), + (u"mathml", u''), + + (u"bare_xhtml", u""), + (u"bare_svg", u""), + (u"bare_mathml", u""), + + (u"xhtml_ns_removed", u"""\ + + + +"""), + (u"xhtml_ns_changed", u"""\ + + + +"""), +) + +EXTENSIONS = ( + u"html", + u"xhtml", + u"xml", + u"svg", + # Was not able to get server MIME type working properly :( + #"mml", +) + +def __main__(): + if len(sys.argv) > 1: + print(u"No arguments expected, aborting") + return + + if not os.access(THIS_NAME, os.F_OK): + print(u"Must be run from the directory of " + THIS_NAME + u", aborting") + return + + for name in os.listdir(u"."): + if name == THIS_NAME: + continue + os.remove(name) + + manifest = open(u"MANIFEST", u"w") + + for name, contents in FILES: + for extension in EXTENSIONS: + f = open(name + u"." + extension, u"w") + f.write(contents) + f.close() + manifest.write(u"support " + name + u"." + extension + u"\n") + + manifest.close() + +__main__() diff --git a/testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/mathml.html b/testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/mathml.html new file mode 100644 index 0000000000..0bec8e99e4 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/mathml.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/mathml.svg b/testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/mathml.svg new file mode 100644 index 0000000000..0bec8e99e4 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/mathml.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/mathml.xhtml b/testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/mathml.xhtml new file mode 100644 index 0000000000..0bec8e99e4 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/mathml.xhtml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/mathml.xml b/testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/mathml.xml new file mode 100644 index 0000000000..0bec8e99e4 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/mathml.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/minimal_html.html b/testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/minimal_html.html new file mode 100644 index 0000000000..a33d9859af --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/minimal_html.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/minimal_html.svg b/testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/minimal_html.svg new file mode 100644 index 0000000000..a33d9859af --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/minimal_html.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/minimal_html.xhtml b/testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/minimal_html.xhtml new file mode 100644 index 0000000000..a33d9859af --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/minimal_html.xhtml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/minimal_html.xml b/testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/minimal_html.xml new file mode 100644 index 0000000000..a33d9859af --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/minimal_html.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/svg.html b/testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/svg.html new file mode 100644 index 0000000000..64def4af7f --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/svg.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/svg.svg b/testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/svg.svg new file mode 100644 index 0000000000..64def4af7f --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/svg.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/svg.xhtml b/testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/svg.xhtml new file mode 100644 index 0000000000..64def4af7f --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/svg.xhtml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/svg.xml b/testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/svg.xml new file mode 100644 index 0000000000..64def4af7f --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/svg.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/xhtml.html b/testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/xhtml.html new file mode 100644 index 0000000000..1cba998241 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/xhtml.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/xhtml.svg b/testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/xhtml.svg new file mode 100644 index 0000000000..1cba998241 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/xhtml.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/xhtml.xhtml b/testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/xhtml.xhtml new file mode 100644 index 0000000000..1cba998241 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/xhtml.xhtml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/xhtml.xml b/testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/xhtml.xml new file mode 100644 index 0000000000..1cba998241 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/xhtml.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/xhtml_ns_changed.html b/testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/xhtml_ns_changed.html new file mode 100644 index 0000000000..b228c7f740 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/xhtml_ns_changed.html @@ -0,0 +1,7 @@ + + + diff --git a/testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/xhtml_ns_changed.svg b/testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/xhtml_ns_changed.svg new file mode 100644 index 0000000000..b228c7f740 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/xhtml_ns_changed.svg @@ -0,0 +1,7 @@ + + + diff --git a/testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/xhtml_ns_changed.xhtml b/testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/xhtml_ns_changed.xhtml new file mode 100644 index 0000000000..b228c7f740 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/xhtml_ns_changed.xhtml @@ -0,0 +1,7 @@ + + + diff --git a/testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/xhtml_ns_changed.xml b/testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/xhtml_ns_changed.xml new file mode 100644 index 0000000000..b228c7f740 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/xhtml_ns_changed.xml @@ -0,0 +1,7 @@ + + + diff --git a/testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/xhtml_ns_removed.html b/testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/xhtml_ns_removed.html new file mode 100644 index 0000000000..dba395fed0 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/xhtml_ns_removed.html @@ -0,0 +1,7 @@ + + + diff --git a/testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/xhtml_ns_removed.svg b/testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/xhtml_ns_removed.svg new file mode 100644 index 0000000000..dba395fed0 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/xhtml_ns_removed.svg @@ -0,0 +1,7 @@ + + + diff --git a/testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/xhtml_ns_removed.xhtml b/testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/xhtml_ns_removed.xhtml new file mode 100644 index 0000000000..dba395fed0 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/xhtml_ns_removed.xhtml @@ -0,0 +1,7 @@ + + + diff --git a/testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/xhtml_ns_removed.xml b/testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/xhtml_ns_removed.xml new file mode 100644 index 0000000000..dba395fed0 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Document-createElement-namespace-tests/xhtml_ns_removed.xml @@ -0,0 +1,7 @@ + + + diff --git a/testing/web-platform/tests/dom/nodes/Document-createElement-namespace.html b/testing/web-platform/tests/dom/nodes/Document-createElement-namespace.html new file mode 100644 index 0000000000..cea61f1aec --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Document-createElement-namespace.html @@ -0,0 +1,117 @@ + +document.createElement() namespace tests + +
+ + + diff --git a/testing/web-platform/tests/dom/nodes/Document-createElement.html b/testing/web-platform/tests/dom/nodes/Document-createElement.html new file mode 100644 index 0000000000..93435ac82d --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Document-createElement.html @@ -0,0 +1,158 @@ + + +Document.createElement + + + + + + + +
+ + + diff --git a/testing/web-platform/tests/dom/nodes/Document-createElementNS.html b/testing/web-platform/tests/dom/nodes/Document-createElementNS.html new file mode 100644 index 0000000000..5ad81043de --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Document-createElementNS.html @@ -0,0 +1,224 @@ + + +Document.createElementNS + + + + +
+ + + diff --git a/testing/web-platform/tests/dom/nodes/Document-createElementNS.js b/testing/web-platform/tests/dom/nodes/Document-createElementNS.js new file mode 100644 index 0000000000..2cf2948563 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Document-createElementNS.js @@ -0,0 +1,189 @@ +var createElementNS_tests = [ + /* Arrays with three elements: + * the namespace argument + * the qualifiedName argument + * the expected exception, or null if none + */ + [null, null, null], + [null, undefined, null], + [null, "foo", null], + [null, "1foo", "INVALID_CHARACTER_ERR"], + [null, "f1oo", null], + [null, "foo1", null], + [null, "\u0BC6foo", null], + [null, "\u037Efoo", "INVALID_CHARACTER_ERR"], + [null, "}foo", "INVALID_CHARACTER_ERR"], + [null, "f}oo", "INVALID_CHARACTER_ERR"], + [null, "foo}", "INVALID_CHARACTER_ERR"], + [null, "\uFFFFfoo", "INVALID_CHARACTER_ERR"], + [null, "f\uFFFFoo", "INVALID_CHARACTER_ERR"], + [null, "foo\uFFFF", "INVALID_CHARACTER_ERR"], + [null, "", "INVALID_CHARACTER_ERR"], + [null, "", "INVALID_CHARACTER_ERR"], + [null, "f", "INVALID_CHARACTER_ERR"], + ["http://example.com/", "fo", "INVALID_CHARACTER_ERR"], + ["http://example.com/", "namespaceURI:,", "INVALID_CHARACTER_ERR"], + ["http://example.com/", "namespaceURI:a ", "INVALID_CHARACTER_ERR"], + ["http://example.com/", "namespaceURI:\"", "INVALID_CHARACTER_ERR"], + ["/", "foo", null], + ["/", "1foo", "INVALID_CHARACTER_ERR"], + ["/", "f1oo", null], + ["/", "foo1", null], + ["/", ":foo", "INVALID_CHARACTER_ERR"], + ["/", "f:oo", null], + ["/", "foo:", "INVALID_CHARACTER_ERR"], + ["/", "xml", null], + ["/", "xmlns", "NAMESPACE_ERR"], + ["/", "xmlfoo", null], + ["/", "xml:foo", "NAMESPACE_ERR"], + ["/", "xmlns:foo", "NAMESPACE_ERR"], + ["/", "xmlfoo:bar", null], + ["http://www.w3.org/XML/1998/namespace", "foo", null], + ["http://www.w3.org/XML/1998/namespace", "1foo", "INVALID_CHARACTER_ERR"], + ["http://www.w3.org/XML/1998/namespace", "f1oo", null], + ["http://www.w3.org/XML/1998/namespace", "foo1", null], + ["http://www.w3.org/XML/1998/namespace", ":foo", "INVALID_CHARACTER_ERR"], + ["http://www.w3.org/XML/1998/namespace", "f:oo", null], + ["http://www.w3.org/XML/1998/namespace", "foo:", "INVALID_CHARACTER_ERR"], + ["http://www.w3.org/XML/1998/namespace", "xml", null], + ["http://www.w3.org/XML/1998/namespace", "xmlns", "NAMESPACE_ERR"], + ["http://www.w3.org/XML/1998/namespace", "xmlfoo", null], + ["http://www.w3.org/XML/1998/namespace", "xml:foo", null], + ["http://www.w3.org/XML/1998/namespace", "xmlns:foo", "NAMESPACE_ERR"], + ["http://www.w3.org/XML/1998/namespace", "xmlfoo:bar", null], + ["http://www.w3.org/XML/1998/namespaces", "xml:foo", "NAMESPACE_ERR"], + ["http://www.w3.org/xml/1998/namespace", "xml:foo", "NAMESPACE_ERR"], + ["http://www.w3.org/2000/xmlns/", "foo", "NAMESPACE_ERR"], + ["http://www.w3.org/2000/xmlns/", "1foo", "INVALID_CHARACTER_ERR"], + ["http://www.w3.org/2000/xmlns/", "f1oo", "NAMESPACE_ERR"], + ["http://www.w3.org/2000/xmlns/", "foo1", "NAMESPACE_ERR"], + ["http://www.w3.org/2000/xmlns/", ":foo", "INVALID_CHARACTER_ERR"], + ["http://www.w3.org/2000/xmlns/", "f:oo", "NAMESPACE_ERR"], + ["http://www.w3.org/2000/xmlns/", "foo:", "INVALID_CHARACTER_ERR"], + ["http://www.w3.org/2000/xmlns/", "xml", "NAMESPACE_ERR"], + ["http://www.w3.org/2000/xmlns/", "xmlns", null], + ["http://www.w3.org/2000/xmlns/", "xmlfoo", "NAMESPACE_ERR"], + ["http://www.w3.org/2000/xmlns/", "xml:foo", "NAMESPACE_ERR"], + ["http://www.w3.org/2000/xmlns/", "xmlns:foo", null], + ["http://www.w3.org/2000/xmlns/", "xmlfoo:bar", "NAMESPACE_ERR"], + ["http://www.w3.org/2000/xmlns/", "foo:xmlns", "NAMESPACE_ERR"], + ["foo:", "foo", null], + ["foo:", "1foo", "INVALID_CHARACTER_ERR"], + ["foo:", "f1oo", null], + ["foo:", "foo1", null], + ["foo:", ":foo", "INVALID_CHARACTER_ERR"], + ["foo:", "f:oo", null], + ["foo:", "foo:", "INVALID_CHARACTER_ERR"], + ["foo:", "xml", null], + ["foo:", "xmlns", "NAMESPACE_ERR"], + ["foo:", "xmlfoo", null], + ["foo:", "xml:foo", "NAMESPACE_ERR"], + ["foo:", "xmlns:foo", "NAMESPACE_ERR"], + ["foo:", "xmlfoo:bar", null], +] diff --git a/testing/web-platform/tests/dom/nodes/Document-createEvent-touchevent.window.js b/testing/web-platform/tests/dom/nodes/Document-createEvent-touchevent.window.js new file mode 100644 index 0000000000..6523ac5a02 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Document-createEvent-touchevent.window.js @@ -0,0 +1,12 @@ +for (const variant of ['TouchEvent', 'touchevent', 'TOUCHEVENT']) { + test(() => { + if (!('ontouchstart' in document)) { + assert_throws_dom("NOT_SUPPORTED_ERR", () => { + document.createEvent(variant); + }); + } else { + document.createEvent(variant); + // The interface and other details of the event is tested in Document-createEvent.https.html + } + }, `document.createEvent('${variant}') should throw if 'expose legacy touch event APIs' is false`); +} diff --git a/testing/web-platform/tests/dom/nodes/Document-createEvent.https.html b/testing/web-platform/tests/dom/nodes/Document-createEvent.https.html new file mode 100644 index 0000000000..4781d54e8e --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Document-createEvent.https.html @@ -0,0 +1,170 @@ + + +Document.createEvent + + + + +
+ diff --git a/testing/web-platform/tests/dom/nodes/Document-createEvent.js b/testing/web-platform/tests/dom/nodes/Document-createEvent.js new file mode 100644 index 0000000000..57e8e966f8 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Document-createEvent.js @@ -0,0 +1,22 @@ +var aliases = { + "BeforeUnloadEvent": "BeforeUnloadEvent", + "CompositionEvent": "CompositionEvent", + "CustomEvent": "CustomEvent", + "DeviceMotionEvent": "DeviceMotionEvent", + "DeviceOrientationEvent": "DeviceOrientationEvent", + "DragEvent": "DragEvent", + "Event": "Event", + "Events": "Event", + "FocusEvent": "FocusEvent", + "HashChangeEvent": "HashChangeEvent", + "HTMLEvents": "Event", + "KeyboardEvent": "KeyboardEvent", + "MessageEvent": "MessageEvent", + "MouseEvent": "MouseEvent", + "MouseEvents": "MouseEvent", + "StorageEvent": "StorageEvent", + "SVGEvents": "Event", + "TextEvent": "CompositionEvent", + "UIEvent": "UIEvent", + "UIEvents": "UIEvent", +}; diff --git a/testing/web-platform/tests/dom/nodes/Document-createProcessingInstruction-xhtml.xhtml b/testing/web-platform/tests/dom/nodes/Document-createProcessingInstruction-xhtml.xhtml new file mode 100644 index 0000000000..d06f70fdcb --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Document-createProcessingInstruction-xhtml.xhtml @@ -0,0 +1,15 @@ + + +Document.createProcessingInstruction in XML documents + + + + + + + + +
+ + +
+ diff --git a/testing/web-platform/tests/dom/nodes/Document-createProcessingInstruction.js b/testing/web-platform/tests/dom/nodes/Document-createProcessingInstruction.js new file mode 100644 index 0000000000..d6cc3725f0 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Document-createProcessingInstruction.js @@ -0,0 +1,39 @@ +test(function() { + var invalid = [ + ["A", "?>"], + ["\u00B7A", "x"], + ["\u00D7A", "x"], + ["A\u00D7", "x"], + ["\\A", "x"], + ["\f", "x"], + [0, "x"], + ["0", "x"] + ], + valid = [ + ["xml:fail", "x"], + ["A\u00B7A", "x"], + ["a0", "x"] + ] + + for (var i = 0, il = invalid.length; i < il; i++) { + test(function() { + assert_throws_dom("INVALID_CHARACTER_ERR", function() { + document.createProcessingInstruction(invalid[i][0], invalid[i][1]) + }) + }, "Should throw an INVALID_CHARACTER_ERR for target " + + format_value(invalid[i][0]) + " and data " + + format_value(invalid[i][1]) + ".") + } + for (var i = 0, il = valid.length; i < il; ++i) { + test(function() { + var pi = document.createProcessingInstruction(valid[i][0], valid[i][1]); + assert_equals(pi.target, valid[i][0]); + assert_equals(pi.data, valid[i][1]); + assert_equals(pi.ownerDocument, document); + assert_true(pi instanceof ProcessingInstruction); + assert_true(pi instanceof Node); + }, "Should get a ProcessingInstruction for target " + + format_value(valid[i][0]) + " and data " + + format_value(valid[i][1]) + ".") + } +}) diff --git a/testing/web-platform/tests/dom/nodes/Document-createTextNode.html b/testing/web-platform/tests/dom/nodes/Document-createTextNode.html new file mode 100644 index 0000000000..ccc1b1b77f --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Document-createTextNode.html @@ -0,0 +1,21 @@ + + +Document.createTextNode + + + + + + + + + + + + + + +
+ diff --git a/testing/web-platform/tests/dom/nodes/Document-createTreeWalker.html b/testing/web-platform/tests/dom/nodes/Document-createTreeWalker.html new file mode 100644 index 0000000000..1e8420d841 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Document-createTreeWalker.html @@ -0,0 +1,42 @@ + + +Document.createTreeWalker + + +
+ diff --git a/testing/web-platform/tests/dom/nodes/Document-doctype.html b/testing/web-platform/tests/dom/nodes/Document-doctype.html new file mode 100644 index 0000000000..75bfd8506d --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Document-doctype.html @@ -0,0 +1,21 @@ + + + +Document.doctype + + + +
+ diff --git a/testing/web-platform/tests/dom/nodes/Document-getElementById.html b/testing/web-platform/tests/dom/nodes/Document-getElementById.html new file mode 100644 index 0000000000..1dec4c085b --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Document-getElementById.html @@ -0,0 +1,350 @@ + + +Document.getElementById + + + + + +
+ + +
+ + +
+ + +
+

P

+ +
+ + +
+
+
+
+
+ + + + diff --git a/testing/web-platform/tests/dom/nodes/Document-getElementsByClassName.html b/testing/web-platform/tests/dom/nodes/Document-getElementsByClassName.html new file mode 100644 index 0000000000..db8fac212d --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Document-getElementsByClassName.html @@ -0,0 +1,26 @@ + +Document.getElementsByClassName + + + +
+ diff --git a/testing/web-platform/tests/dom/nodes/Document-getElementsByTagName-xhtml.xhtml b/testing/web-platform/tests/dom/nodes/Document-getElementsByTagName-xhtml.xhtml new file mode 100644 index 0000000000..309a29ae77 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Document-getElementsByTagName-xhtml.xhtml @@ -0,0 +1,104 @@ + + + +Document.getElementsByTagName + + + + +
+

+
+
+
diff --git a/testing/web-platform/tests/dom/nodes/Document-getElementsByTagName.html b/testing/web-platform/tests/dom/nodes/Document-getElementsByTagName.html
new file mode 100644
index 0000000000..00e3435c4c
--- /dev/null
+++ b/testing/web-platform/tests/dom/nodes/Document-getElementsByTagName.html
@@ -0,0 +1,11 @@
+
+
+Document.getElementsByTagName
+
+
+
+
+
+ diff --git a/testing/web-platform/tests/dom/nodes/Document-getElementsByTagNameNS.html b/testing/web-platform/tests/dom/nodes/Document-getElementsByTagNameNS.html new file mode 100644 index 0000000000..063dc98215 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Document-getElementsByTagNameNS.html @@ -0,0 +1,11 @@ + + +Document.getElementsByTagNameNS + + + + +
+ diff --git a/testing/web-platform/tests/dom/nodes/Document-implementation.html b/testing/web-platform/tests/dom/nodes/Document-implementation.html new file mode 100644 index 0000000000..aed5259659 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Document-implementation.html @@ -0,0 +1,20 @@ + + +Document.implementation + + + +
+ diff --git a/testing/web-platform/tests/dom/nodes/Document-importNode.html b/testing/web-platform/tests/dom/nodes/Document-importNode.html new file mode 100644 index 0000000000..d27cce6c56 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Document-importNode.html @@ -0,0 +1,67 @@ + + +Document.importNode + + + +
+ diff --git a/testing/web-platform/tests/dom/nodes/DocumentFragment-constructor.html b/testing/web-platform/tests/dom/nodes/DocumentFragment-constructor.html new file mode 100644 index 0000000000..e97a7c4836 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/DocumentFragment-constructor.html @@ -0,0 +1,22 @@ + + +DocumentFragment constructor + + + + + diff --git a/testing/web-platform/tests/dom/nodes/DocumentFragment-getElementById.html b/testing/web-platform/tests/dom/nodes/DocumentFragment-getElementById.html new file mode 100644 index 0000000000..ce0d302c12 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/DocumentFragment-getElementById.html @@ -0,0 +1,62 @@ + + +DocumentFragment.prototype.getElementById + + + + + + + + + diff --git a/testing/web-platform/tests/dom/nodes/DocumentFragment-querySelectorAll-after-modification.html b/testing/web-platform/tests/dom/nodes/DocumentFragment-querySelectorAll-after-modification.html new file mode 100644 index 0000000000..8049363885 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/DocumentFragment-querySelectorAll-after-modification.html @@ -0,0 +1,24 @@ + + +querySelectorAll should still work on DocumentFragments after they are modified + + + + + diff --git a/testing/web-platform/tests/dom/nodes/DocumentType-literal-xhtml.xhtml b/testing/web-platform/tests/dom/nodes/DocumentType-literal-xhtml.xhtml new file mode 100644 index 0000000000..2b6965c14b --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/DocumentType-literal-xhtml.xhtml @@ -0,0 +1,23 @@ + + + +DocumentType literals + + + + + + + +
+ + + diff --git a/testing/web-platform/tests/dom/nodes/DocumentType-literal.html b/testing/web-platform/tests/dom/nodes/DocumentType-literal.html new file mode 100644 index 0000000000..a755c397b0 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/DocumentType-literal.html @@ -0,0 +1,17 @@ + +DocumentType literals + + + + + +
+ diff --git a/testing/web-platform/tests/dom/nodes/DocumentType-remove.html b/testing/web-platform/tests/dom/nodes/DocumentType-remove.html new file mode 100644 index 0000000000..9e18d3511a --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/DocumentType-remove.html @@ -0,0 +1,16 @@ + + +DocumentType.remove + + + + +
+ diff --git a/testing/web-platform/tests/dom/nodes/Element-childElement-null-svg.svg b/testing/web-platform/tests/dom/nodes/Element-childElement-null-svg.svg new file mode 100644 index 0000000000..388482874b --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Element-childElement-null-svg.svg @@ -0,0 +1,20 @@ + + +Null test + + + +Test of firstElementChild and lastChildElement returning null +Test + + +test(function() { + var parentEl = document.getElementById("parentEl") + assert_equals(parentEl.firstElementChild, null) + assert_equals(parentEl.lastElementChild, null) +}) + + diff --git a/testing/web-platform/tests/dom/nodes/Element-childElement-null-xhtml.xhtml b/testing/web-platform/tests/dom/nodes/Element-childElement-null-xhtml.xhtml new file mode 100644 index 0000000000..daedab6d97 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Element-childElement-null-xhtml.xhtml @@ -0,0 +1,20 @@ + + + +Null Test + + + + +

Test of firstElementChild and lastChildElement returning null

+
+

Test.

+ + + diff --git a/testing/web-platform/tests/dom/nodes/Element-childElement-null.html b/testing/web-platform/tests/dom/nodes/Element-childElement-null.html new file mode 100644 index 0000000000..1863a41da5 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Element-childElement-null.html @@ -0,0 +1,15 @@ + + +Null test + + +

Test of firstElementChild and lastChildElement returning null

+
+

Test.

+ diff --git a/testing/web-platform/tests/dom/nodes/Element-childElementCount-dynamic-add-svg.svg b/testing/web-platform/tests/dom/nodes/Element-childElementCount-dynamic-add-svg.svg new file mode 100644 index 0000000000..d149f1ea3f --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Element-childElementCount-dynamic-add-svg.svg @@ -0,0 +1,22 @@ + + +Dynamic Adding of Elements + + + +Test of Dynamic Adding of Elements +The result of this test is +unknown. + + +test(function() { + var parentEl = document.getElementById("parentEl"); + var newChild = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); + parentEl.appendChild(newChild); + assert_equals(parentEl.childElementCount, 2) +}) + + diff --git a/testing/web-platform/tests/dom/nodes/Element-childElementCount-dynamic-add-xhtml.xhtml b/testing/web-platform/tests/dom/nodes/Element-childElementCount-dynamic-add-xhtml.xhtml new file mode 100644 index 0000000000..c97ed1965b --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Element-childElementCount-dynamic-add-xhtml.xhtml @@ -0,0 +1,22 @@ + + + +Dynamic Adding of Elements + + + + +

Test of Dynamic Adding of Elements

+
+

The result of this test is +logged above.

+ + + diff --git a/testing/web-platform/tests/dom/nodes/Element-childElementCount-dynamic-add.html b/testing/web-platform/tests/dom/nodes/Element-childElementCount-dynamic-add.html new file mode 100644 index 0000000000..3e7490b21d --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Element-childElementCount-dynamic-add.html @@ -0,0 +1,17 @@ + + +Dynamic Adding of Elements + + +

Test of Dynamic Adding of Elements

+
+

The result of this test is +logged above.

+ diff --git a/testing/web-platform/tests/dom/nodes/Element-childElementCount-dynamic-remove-svg.svg b/testing/web-platform/tests/dom/nodes/Element-childElementCount-dynamic-remove-svg.svg new file mode 100644 index 0000000000..bf99de65aa --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Element-childElementCount-dynamic-remove-svg.svg @@ -0,0 +1,22 @@ + + +Dynamic Removal of Elements + + + +Test of Dynamic Removal of Elements +The result of this test is +unknown. + + +test(function() { + var parentEl = document.getElementById("parentEl"); + var lec = parentEl.lastElementChild; + parentEl.removeChild(lec); + assert_equals(parentEl.childElementCount, 1) +}) + + diff --git a/testing/web-platform/tests/dom/nodes/Element-childElementCount-dynamic-remove-xhtml.xhtml b/testing/web-platform/tests/dom/nodes/Element-childElementCount-dynamic-remove-xhtml.xhtml new file mode 100644 index 0000000000..f0009b0a77 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Element-childElementCount-dynamic-remove-xhtml.xhtml @@ -0,0 +1,22 @@ + + + +Dynamic Removal of Elements + + + + +

Test of Removal Adding of Elements

+
+

The result of this test is +logged above.

+ + + diff --git a/testing/web-platform/tests/dom/nodes/Element-childElementCount-dynamic-remove.html b/testing/web-platform/tests/dom/nodes/Element-childElementCount-dynamic-remove.html new file mode 100644 index 0000000000..3f7e7c7ead --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Element-childElementCount-dynamic-remove.html @@ -0,0 +1,17 @@ + + +Dynamic Removal of Elements + + +

Test of Dynamic Removal of Elements

+
+

The result of this test is +unknown.

+ diff --git a/testing/web-platform/tests/dom/nodes/Element-childElementCount-nochild-svg.svg b/testing/web-platform/tests/dom/nodes/Element-childElementCount-nochild-svg.svg new file mode 100644 index 0000000000..8ba5743607 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Element-childElementCount-nochild-svg.svg @@ -0,0 +1,19 @@ + + +childElementCount + + + +Test of childElementCount with No Child Element Nodes +Test + + +test(function() { + var parentEl = document.getElementById("parentEl") + assert_equals(parentEl.childElementCount, 0) +}) + + diff --git a/testing/web-platform/tests/dom/nodes/Element-childElementCount-nochild-xhtml.xhtml b/testing/web-platform/tests/dom/nodes/Element-childElementCount-nochild-xhtml.xhtml new file mode 100644 index 0000000000..f567a20c23 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Element-childElementCount-nochild-xhtml.xhtml @@ -0,0 +1,19 @@ + + + +childElementCount without Child Element Nodes + + + + +

Test of childElementCount with No Child Element Nodes

+
+

Test.

+ + + diff --git a/testing/web-platform/tests/dom/nodes/Element-childElementCount-nochild.html b/testing/web-platform/tests/dom/nodes/Element-childElementCount-nochild.html new file mode 100644 index 0000000000..fb52fb205c --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Element-childElementCount-nochild.html @@ -0,0 +1,14 @@ + + +childElementCount without Child Element Nodes + + +

Test of childElementCount with No Child Element Nodes

+
+

Test.

+ diff --git a/testing/web-platform/tests/dom/nodes/Element-childElementCount-svg.svg b/testing/web-platform/tests/dom/nodes/Element-childElementCount-svg.svg new file mode 100644 index 0000000000..ff93eff625 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Element-childElementCount-svg.svg @@ -0,0 +1,25 @@ + + +childElementCount + + + +Test of childElementCount +The result of this test is +unknown. + + + + + + +test(function() { + var parentEl = document.getElementById("parentEl") + assert_true("childElementCount" in parentEl) + assert_equals(parentEl.childElementCount, 3) +}) + + diff --git a/testing/web-platform/tests/dom/nodes/Element-childElementCount-xhtml.xhtml b/testing/web-platform/tests/dom/nodes/Element-childElementCount-xhtml.xhtml new file mode 100644 index 0000000000..6b719ff7a8 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Element-childElementCount-xhtml.xhtml @@ -0,0 +1,25 @@ + + + +childElementCount + + + + +

Test of childElementCount

+
+

The result of this test is +unknown. + + + +

+ + + diff --git a/testing/web-platform/tests/dom/nodes/Element-childElementCount.html b/testing/web-platform/tests/dom/nodes/Element-childElementCount.html new file mode 100644 index 0000000000..8cfe567f91 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Element-childElementCount.html @@ -0,0 +1,20 @@ + + +childElementCount + + +

Test of childElementCount

+
+

The result of this test is +given above. + + + +

+ diff --git a/testing/web-platform/tests/dom/nodes/Element-children.html b/testing/web-platform/tests/dom/nodes/Element-children.html new file mode 100644 index 0000000000..c0210f9667 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Element-children.html @@ -0,0 +1,58 @@ + +HTMLCollection edge cases + + +
+
+ diff --git a/testing/web-platform/tests/dom/nodes/Element-classlist.html b/testing/web-platform/tests/dom/nodes/Element-classlist.html new file mode 100644 index 0000000000..2b5a271ba4 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Element-classlist.html @@ -0,0 +1,478 @@ + + +Test for the classList element attribute + + +
+ diff --git a/testing/web-platform/tests/dom/nodes/Element-closest.html b/testing/web-platform/tests/dom/nodes/Element-closest.html new file mode 100644 index 0000000000..386e3bd251 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Element-closest.html @@ -0,0 +1,73 @@ + + +Test for Element.closest + + + + +
+ diff --git a/testing/web-platform/tests/dom/nodes/Element-firstElementChild-entity-xhtml.xhtml b/testing/web-platform/tests/dom/nodes/Element-firstElementChild-entity-xhtml.xhtml new file mode 100644 index 0000000000..f28005e9c8 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Element-firstElementChild-entity-xhtml.xhtml @@ -0,0 +1,27 @@ + +unknown."> +]> + + +Entity References + + + + +

Test of Entity References

+
+

The result of this test is &tree;

+ + + diff --git a/testing/web-platform/tests/dom/nodes/Element-firstElementChild-entity.svg b/testing/web-platform/tests/dom/nodes/Element-firstElementChild-entity.svg new file mode 100644 index 0000000000..3a20ea79ab --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Element-firstElementChild-entity.svg @@ -0,0 +1,26 @@ + +unknown."> +]> + +Entity References + + + +Test of Entity References +The result of this test is &tree; + + +test(function() { + var parentEl = document.getElementById("parentEl") + var fec = parentEl.firstElementChild; + assert_true(!!fec) + assert_equals(fec.nodeType, 1) + assert_equals(fec.getAttribute("id"), "first_element_child") +}) + + diff --git a/testing/web-platform/tests/dom/nodes/Element-firstElementChild-namespace-svg.svg b/testing/web-platform/tests/dom/nodes/Element-firstElementChild-namespace-svg.svg new file mode 100644 index 0000000000..d42c08777c --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Element-firstElementChild-namespace-svg.svg @@ -0,0 +1,26 @@ + + +firstElementChild with namespaces + + + +Test of firstElementChild with namespaces + + + + + +test(function() { + var parentEl = document.getElementById("parentEl"); + var fec = parentEl.firstElementChild; + assert_true(!!fec) + assert_equals(fec.nodeType, 1) + assert_equals(fec.getAttribute("id"), "first_element_child") + assert_equals(fec.localName, "dill") +}) + + diff --git a/testing/web-platform/tests/dom/nodes/Element-firstElementChild-namespace-xhtml.xhtml b/testing/web-platform/tests/dom/nodes/Element-firstElementChild-namespace-xhtml.xhtml new file mode 100644 index 0000000000..29441d2786 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Element-firstElementChild-namespace-xhtml.xhtml @@ -0,0 +1,28 @@ + + + +firstElementChild with namespaces + + + + +

Test of firstElementChild with namespaces

+
+ +
+
+

The result of this test is +logged above.

+ + + diff --git a/testing/web-platform/tests/dom/nodes/Element-firstElementChild-namespace.html b/testing/web-platform/tests/dom/nodes/Element-firstElementChild-namespace.html new file mode 100644 index 0000000000..629deab3ae --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Element-firstElementChild-namespace.html @@ -0,0 +1,21 @@ + + +firstElementChild with namespaces + + +

Test of firstElementChild with namespaces

+
+

The result of this test is a unknown.

+ diff --git a/testing/web-platform/tests/dom/nodes/Element-firstElementChild-svg.svg b/testing/web-platform/tests/dom/nodes/Element-firstElementChild-svg.svg new file mode 100644 index 0000000000..359c5b82ca --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Element-firstElementChild-svg.svg @@ -0,0 +1,23 @@ + + +firstElementChild + + + +Test of firstElementChild +The result of this test is +unknown. + + +test(function() { + var parentEl = document.getElementById("parentEl"); + var fec = parentEl.firstElementChild; + assert_true(!!fec) + assert_equals(fec.nodeType, 1) + assert_equals(fec.getAttribute("id"), "first_element_child") +}) + + diff --git a/testing/web-platform/tests/dom/nodes/Element-firstElementChild-xhtml.xhtml b/testing/web-platform/tests/dom/nodes/Element-firstElementChild-xhtml.xhtml new file mode 100644 index 0000000000..302052b0fc --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Element-firstElementChild-xhtml.xhtml @@ -0,0 +1,23 @@ + + + +firstElementChild + + + + +

Test of firstElementChild

+
+

The result of this test is +logged above.

+ + + diff --git a/testing/web-platform/tests/dom/nodes/Element-firstElementChild.html b/testing/web-platform/tests/dom/nodes/Element-firstElementChild.html new file mode 100644 index 0000000000..12a0c5946e --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Element-firstElementChild.html @@ -0,0 +1,18 @@ + + +firstElementChild + + +

Test of firstElementChild

+
+

The result of this test is +logged above.

+ diff --git a/testing/web-platform/tests/dom/nodes/Element-getElementsByClassName.html b/testing/web-platform/tests/dom/nodes/Element-getElementsByClassName.html new file mode 100644 index 0000000000..bc87b05d25 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Element-getElementsByClassName.html @@ -0,0 +1,43 @@ + +Element.getElementsByClassName + + +
+ diff --git a/testing/web-platform/tests/dom/nodes/Element-getElementsByTagName-change-document-HTMLNess-iframe.xml b/testing/web-platform/tests/dom/nodes/Element-getElementsByTagName-change-document-HTMLNess-iframe.xml new file mode 100644 index 0000000000..f3f286eafc --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Element-getElementsByTagName-change-document-HTMLNess-iframe.xml @@ -0,0 +1 @@ + diff --git a/testing/web-platform/tests/dom/nodes/Element-getElementsByTagName-change-document-HTMLNess.html b/testing/web-platform/tests/dom/nodes/Element-getElementsByTagName-change-document-HTMLNess.html new file mode 100644 index 0000000000..c41ee2e877 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Element-getElementsByTagName-change-document-HTMLNess.html @@ -0,0 +1,51 @@ + + + + + + + diff --git a/testing/web-platform/tests/dom/nodes/Element-getElementsByTagName.html b/testing/web-platform/tests/dom/nodes/Element-getElementsByTagName.html new file mode 100644 index 0000000000..87c4fe934a --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Element-getElementsByTagName.html @@ -0,0 +1,30 @@ + + +Element.getElementsByTagName + + + + +
+ diff --git a/testing/web-platform/tests/dom/nodes/Element-getElementsByTagNameNS.html b/testing/web-platform/tests/dom/nodes/Element-getElementsByTagNameNS.html new file mode 100644 index 0000000000..f826afc391 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Element-getElementsByTagNameNS.html @@ -0,0 +1,37 @@ + + +Element.getElementsByTagNameNS + + + + +
+ diff --git a/testing/web-platform/tests/dom/nodes/Element-hasAttribute.html b/testing/web-platform/tests/dom/nodes/Element-hasAttribute.html new file mode 100644 index 0000000000..26528d7569 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Element-hasAttribute.html @@ -0,0 +1,32 @@ + + +Element.prototype.hasAttribute + + + + + + + diff --git a/testing/web-platform/tests/dom/nodes/Element-hasAttributes.html b/testing/web-platform/tests/dom/nodes/Element-hasAttributes.html new file mode 100644 index 0000000000..fbb9c233b7 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Element-hasAttributes.html @@ -0,0 +1,40 @@ + + + + + + + + +
+

+ + + diff --git a/testing/web-platform/tests/dom/nodes/Element-insertAdjacentElement.html b/testing/web-platform/tests/dom/nodes/Element-insertAdjacentElement.html new file mode 100644 index 0000000000..9eafee6a76 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Element-insertAdjacentElement.html @@ -0,0 +1,91 @@ + + + + + + +
+
+
+ + + + + diff --git a/testing/web-platform/tests/dom/nodes/Element-insertAdjacentText.html b/testing/web-platform/tests/dom/nodes/Element-insertAdjacentText.html new file mode 100644 index 0000000000..be744fd49e --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Element-insertAdjacentText.html @@ -0,0 +1,76 @@ + + + + + + +
+
+
+ + diff --git a/testing/web-platform/tests/dom/nodes/Element-lastElementChild-svg.svg b/testing/web-platform/tests/dom/nodes/Element-lastElementChild-svg.svg new file mode 100644 index 0000000000..1cec4a1308 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Element-lastElementChild-svg.svg @@ -0,0 +1,22 @@ + + +lastElementChild + + + +Test of lastElementChild +The result of this test is not known. + + +test(function() { + var parentEl = document.getElementById("parentEl"); + var lec = parentEl.lastElementChild; + assert_true(!!lec) + assert_equals(lec.nodeType, 1) + assert_equals(lec.getAttribute("id"), "last_element_child") +}) + + diff --git a/testing/web-platform/tests/dom/nodes/Element-lastElementChild-xhtml.xhtml b/testing/web-platform/tests/dom/nodes/Element-lastElementChild-xhtml.xhtml new file mode 100644 index 0000000000..3150b92a42 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Element-lastElementChild-xhtml.xhtml @@ -0,0 +1,22 @@ + + + +firstElementChild + + + + +

Test of firstElementChild

+
+

The result of this test is logged above.

+ + + diff --git a/testing/web-platform/tests/dom/nodes/Element-lastElementChild.html b/testing/web-platform/tests/dom/nodes/Element-lastElementChild.html new file mode 100644 index 0000000000..de7aebdf24 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Element-lastElementChild.html @@ -0,0 +1,17 @@ + + +lastElementChild + + +

Test of lastElementChild

+
+

The result of this test is logged above.

+ diff --git a/testing/web-platform/tests/dom/nodes/Element-matches-init.js b/testing/web-platform/tests/dom/nodes/Element-matches-init.js new file mode 100644 index 0000000000..254af61565 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Element-matches-init.js @@ -0,0 +1,65 @@ +function init(e, method) { + /* + * This test suite tests Selectors API methods in 4 different contexts: + * 1. Document node + * 2. In-document Element node + * 3. Detached Element node (an element with no parent, not in the document) + * 4. Document Fragment node + * + * For each context, the following tests are run: + * + * The interface check tests ensure that each type of node exposes the Selectors API methods. + * + * The matches() tests are run + * All the selectors tested for both the valid and invalid selector tests are found in selectors.js. + * See comments in that file for documentation of the format used. + * + * The level2-lib.js file contains all the common test functions for running each of the aforementioned tests + */ + + var docType = "html"; // Only run tests suitable for HTML + + // Prepare the nodes for testing + var doc = e.target.contentDocument; // Document Node tests + + var element = doc.getElementById("root"); // In-document Element Node tests + + //Setup the namespace tests + setupSpecialElements(doc, element); + + var outOfScope = element.cloneNode(true); // Append this to the body before running the in-document + // Element tests, but after running the Document tests. This + // tests that no elements that are not descendants of element + // are selected. + + traverse(outOfScope, function(elem) { // Annotate each element as being a clone; used for verifying + elem.setAttribute("data-clone", ""); // that none of these elements ever match. + }); + + + var detached = element.cloneNode(true); // Detached Element Node tests + + var fragment = doc.createDocumentFragment(); // Fragment Node tests + fragment.appendChild(element.cloneNode(true)); + + // Setup Tests + interfaceCheckMatches(method, "Document", doc); + interfaceCheckMatches(method, "Detached Element", detached); + interfaceCheckMatches(method, "Fragment", fragment); + interfaceCheckMatches(method, "In-document Element", element); + + runSpecialMatchesTests(method, "DIV Element", element); + runSpecialMatchesTests(method, "NULL Element", document.createElement("null")); + runSpecialMatchesTests(method, "UNDEFINED Element", document.createElement("undefined")); + + runInvalidSelectorTestMatches(method, "Document", doc, invalidSelectors); + runInvalidSelectorTestMatches(method, "Detached Element", detached, invalidSelectors); + runInvalidSelectorTestMatches(method, "Fragment", fragment, invalidSelectors); + runInvalidSelectorTestMatches(method, "In-document Element", element, invalidSelectors); + + runMatchesTest(method, "In-document", doc, validSelectors, "html"); + runMatchesTest(method, "Detached", detached, validSelectors, "html"); + runMatchesTest(method, "Fragment", fragment, validSelectors, "html"); + + runMatchesTest(method, "In-document", doc, scopedSelectors, "html"); +} diff --git a/testing/web-platform/tests/dom/nodes/Element-matches-namespaced-elements.html b/testing/web-platform/tests/dom/nodes/Element-matches-namespaced-elements.html new file mode 100644 index 0000000000..e61b11ca61 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Element-matches-namespaced-elements.html @@ -0,0 +1,24 @@ + + +matches/webkitMatchesSelector must work when an element has a namespace + + + + + diff --git a/testing/web-platform/tests/dom/nodes/Element-matches.html b/testing/web-platform/tests/dom/nodes/Element-matches.html new file mode 100644 index 0000000000..de234b6639 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Element-matches.html @@ -0,0 +1,22 @@ + + +Selectors-API Level 2 Test Suite: HTML with Selectors Level 3 + + + + + + + + + +
This test requires JavaScript.
+ + diff --git a/testing/web-platform/tests/dom/nodes/Element-matches.js b/testing/web-platform/tests/dom/nodes/Element-matches.js new file mode 100644 index 0000000000..a1455c671f --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Element-matches.js @@ -0,0 +1,135 @@ +/* + * Check that the matches() method exists on the given Node + */ +function interfaceCheckMatches(method, type, obj) { + if (obj.nodeType === obj.ELEMENT_NODE) { + test(function() { + assert_idl_attribute(obj, method, type + " supports " + method); + }, type + " supports " + method) + } else { + test(function() { + assert_false(method in obj, type + " supports " + method); + }, type + " should not support " + method) + } +} + +function runSpecialMatchesTests(method, type, element) { + test(function() { // 1 + if (element.tagName.toLowerCase() === "null") { + assert_true(element[method](null), "An element with the tag name '" + element.tagName.toLowerCase() + "' should match."); + } else { + assert_false(element[method](null), "An element with the tag name '" + element.tagName.toLowerCase() + "' should not match."); + } + }, type + "." + method + "(null)") + + test(function() { // 2 + if (element.tagName.toLowerCase() === "undefined") { + assert_true(element[method](undefined), "An element with the tag name '" + element.tagName.toLowerCase() + "' should match."); + } else { + assert_false(element[method](undefined), "An element with the tag name '" + element.tagName.toLowerCase() + "' should not match."); + } + }, type + "." + method + "(undefined)") + + test(function() { // 3 + assert_throws_js(element.ownerDocument.defaultView.TypeError, function() { + element[method](); + }, "This should throw a TypeError.") + }, type + "." + method + " no parameter") +} + +/* + * Execute queries with the specified invalid selectors for matches() + * Only run these tests when errors are expected. Don't run for valid selector tests. + */ +function runInvalidSelectorTestMatches(method, type, root, selectors) { + if (root.nodeType === root.ELEMENT_NODE) { + for (var i = 0; i < selectors.length; i++) { + var s = selectors[i]; + var n = s["name"]; + var q = s["selector"]; + + test(function() { + assert_throws_dom( + "SyntaxError", + root.ownerDocument.defaultView.DOMException, + function() { + root[method](q) + } + ); + }, type + "." + method + ": " + n + ": " + q); + } + } +} + +function runMatchesTest(method, type, root, selectors, docType) { + var nodeType = getNodeType(root); + + for (var i = 0; i < selectors.length; i++) { + var s = selectors[i]; + var n = s["name"]; + var q = s["selector"]; + var e = s["expect"]; + var u = s["unexpected"]; + + var ctx = s["ctx"]; + var ref = s["ref"]; + + if ((!s["exclude"] || (s["exclude"].indexOf(nodeType) === -1 && s["exclude"].indexOf(docType) === -1)) + && (s["testType"] & TEST_MATCH) ) { + + if (ctx && !ref) { + test(function() { + var j, element, refNode; + for (j = 0; j < e.length; j++) { + element = root.querySelector("#" + e[j]); + refNode = root.querySelector(ctx); + assert_true(element[method](q, refNode), "The element #" + e[j] + " should match the selector.") + } + + if (u) { + for (j = 0; j < u.length; j++) { + element = root.querySelector("#" + u[j]); + refNode = root.querySelector(ctx); + assert_false(element[method](q, refNode), "The element #" + u[j] + " should not match the selector.") + } + } + }, type + " Element." + method + ": " + n + " (with refNode Element): " + q); + } + + if (ref) { + test(function() { + var j, element, refNodes; + for (j = 0; j < e.length; j++) { + element = root.querySelector("#" + e[j]); + refNodes = root.querySelectorAll(ref); + assert_true(element[method](q, refNodes), "The element #" + e[j] + " should match the selector.") + } + + if (u) { + for (j = 0; j < u.length; j++) { + element = root.querySelector("#" + u[j]); + refNodes = root.querySelectorAll(ref); + assert_false(element[method](q, refNodes), "The element #" + u[j] + " should not match the selector.") + } + } + }, type + " Element." + method + ": " + n + " (with refNodes NodeList): " + q); + } + + if (!ctx && !ref) { + test(function() { + for (var j = 0; j < e.length; j++) { + var element = root.querySelector("#" + e[j]); + assert_true(element[method](q), "The element #" + e[j] + " should match the selector.") + } + + if (u) { + for (j = 0; j < u.length; j++) { + element = root.querySelector("#" + u[j]); + assert_false(element[method](q), "The element #" + u[j] + " should not match the selector.") + } + } + }, type + " Element." + method + ": " + n + " (with no refNodes): " + q); + } + } + } +} diff --git a/testing/web-platform/tests/dom/nodes/Element-nextElementSibling-svg.svg b/testing/web-platform/tests/dom/nodes/Element-nextElementSibling-svg.svg new file mode 100644 index 0000000000..3e17cad20c --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Element-nextElementSibling-svg.svg @@ -0,0 +1,23 @@ + + +nextElementSibling + + + +Test of nextElementSibling +The result of this test is unknown. + + +test(function() { + var parentEl = document.getElementById("parentEl"); + var fec = document.getElementById("first_element_child"); + var nes = fec.nextElementSibling; + assert_true(!!nes) + assert_equals(nes.nodeType, 1) + assert_equals(nes.getAttribute("id"), "last_element_child") +}) + + diff --git a/testing/web-platform/tests/dom/nodes/Element-nextElementSibling-xhtml.xhtml b/testing/web-platform/tests/dom/nodes/Element-nextElementSibling-xhtml.xhtml new file mode 100644 index 0000000000..915209bda2 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Element-nextElementSibling-xhtml.xhtml @@ -0,0 +1,23 @@ + + + +nextElementSibling + + + + +

Test of nextElementSibling

+
+

The result of this test is unknown.

+ + + diff --git a/testing/web-platform/tests/dom/nodes/Element-nextElementSibling.html b/testing/web-platform/tests/dom/nodes/Element-nextElementSibling.html new file mode 100644 index 0000000000..985c602f41 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Element-nextElementSibling.html @@ -0,0 +1,18 @@ + + +nextElementSibling + + +

Test of nextElementSibling

+
+

The result of this test is unknown.

+ diff --git a/testing/web-platform/tests/dom/nodes/Element-previousElementSibling-svg.svg b/testing/web-platform/tests/dom/nodes/Element-previousElementSibling-svg.svg new file mode 100644 index 0000000000..671d2c87f2 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Element-previousElementSibling-svg.svg @@ -0,0 +1,28 @@ + + +previousElementSibling + + + +Test of previousElementSibling +The result of this test is +unknown. + + + +fnord + + +test(function() { + var parentEl = document.getElementById("parentEl"); + var lec = document.getElementById("last_element_child"); + var pes = lec.previousElementSibling; + assert_true(!!pes) + assert_equals(pes.nodeType, 1) + assert_equals(pes.getAttribute("id"), "middle_element_child") +}) + + diff --git a/testing/web-platform/tests/dom/nodes/Element-previousElementSibling-xhtml.xhtml b/testing/web-platform/tests/dom/nodes/Element-previousElementSibling-xhtml.xhtml new file mode 100644 index 0000000000..7fbbc6d384 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Element-previousElementSibling-xhtml.xhtml @@ -0,0 +1,28 @@ + + + +previousElementSibling + + + + +

Test of previousElementSibling

+
+

The result of this test is +unknown. + + + +

+ + + diff --git a/testing/web-platform/tests/dom/nodes/Element-previousElementSibling.html b/testing/web-platform/tests/dom/nodes/Element-previousElementSibling.html new file mode 100644 index 0000000000..02c7b16df5 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Element-previousElementSibling.html @@ -0,0 +1,23 @@ + + +previousElementSibling + + +

Test of previousElementSibling

+
+

The result of this test is +unknown. + + + +

+ diff --git a/testing/web-platform/tests/dom/nodes/Element-remove.html b/testing/web-platform/tests/dom/nodes/Element-remove.html new file mode 100644 index 0000000000..ab642d660b --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Element-remove.html @@ -0,0 +1,16 @@ + + +Element.remove + + + + +
+ diff --git a/testing/web-platform/tests/dom/nodes/Element-removeAttribute.html b/testing/web-platform/tests/dom/nodes/Element-removeAttribute.html new file mode 100644 index 0000000000..df79e62cf4 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Element-removeAttribute.html @@ -0,0 +1,58 @@ + + +Element.prototype.removeAttribute + + + + + diff --git a/testing/web-platform/tests/dom/nodes/Element-removeAttributeNS.html b/testing/web-platform/tests/dom/nodes/Element-removeAttributeNS.html new file mode 100644 index 0000000000..a2773e6f1e --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Element-removeAttributeNS.html @@ -0,0 +1,18 @@ + +Element.removeAttributeNS + + + +
+ diff --git a/testing/web-platform/tests/dom/nodes/Element-setAttribute-crbug-1138487.html b/testing/web-platform/tests/dom/nodes/Element-setAttribute-crbug-1138487.html new file mode 100644 index 0000000000..9aa9ed8139 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Element-setAttribute-crbug-1138487.html @@ -0,0 +1,22 @@ + + + + diff --git a/testing/web-platform/tests/dom/nodes/Element-setAttribute.html b/testing/web-platform/tests/dom/nodes/Element-setAttribute.html new file mode 100644 index 0000000000..7609406815 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Element-setAttribute.html @@ -0,0 +1,38 @@ + + +Element.prototype.setAttribute + + + + + diff --git a/testing/web-platform/tests/dom/nodes/Element-siblingElement-null-svg.svg b/testing/web-platform/tests/dom/nodes/Element-siblingElement-null-svg.svg new file mode 100644 index 0000000000..48c981b8c8 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Element-siblingElement-null-svg.svg @@ -0,0 +1,20 @@ + + +Null test + + + +Test of previousElementSibling and nextElementSibling returning null +The result of this test is unknown. + + +test(function() { + var fec = document.getElementById("first_element_child"); + assert_equals(fec.previousElementSibling, null) + assert_equals(fec.nextElementSibling, null) +}) + + diff --git a/testing/web-platform/tests/dom/nodes/Element-siblingElement-null-xhtml.xhtml b/testing/web-platform/tests/dom/nodes/Element-siblingElement-null-xhtml.xhtml new file mode 100644 index 0000000000..fcf4d54ff9 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Element-siblingElement-null-xhtml.xhtml @@ -0,0 +1,20 @@ + + + +Null Test + + + + +

Test of previousElementSibling and nextElementSibling returning null

+
+

The result of this test is unknown.

+ + + diff --git a/testing/web-platform/tests/dom/nodes/Element-siblingElement-null.html b/testing/web-platform/tests/dom/nodes/Element-siblingElement-null.html new file mode 100644 index 0000000000..a7920b4fb8 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Element-siblingElement-null.html @@ -0,0 +1,16 @@ + + +Null test + + +

Test of previousElementSibling and nextElementSibling returning null

+
+

The result of this test is unknown.

+ + diff --git a/testing/web-platform/tests/dom/nodes/Element-tagName.html b/testing/web-platform/tests/dom/nodes/Element-tagName.html new file mode 100644 index 0000000000..43e7a2d2bf --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Element-tagName.html @@ -0,0 +1,57 @@ + +Element.tagName + + +
+ diff --git a/testing/web-platform/tests/dom/nodes/Element-webkitMatchesSelector.html b/testing/web-platform/tests/dom/nodes/Element-webkitMatchesSelector.html new file mode 100644 index 0000000000..107f810203 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Element-webkitMatchesSelector.html @@ -0,0 +1,22 @@ + + +Selectors-API Level 2 Test Suite: HTML with Selectors Level 3 + + + + + + + + + +
This test requires JavaScript.
+ + diff --git a/testing/web-platform/tests/dom/nodes/MutationObserver-attributes.html b/testing/web-platform/tests/dom/nodes/MutationObserver-attributes.html new file mode 100644 index 0000000000..6721b7eecd --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/MutationObserver-attributes.html @@ -0,0 +1,406 @@ + + +MutationObservers: attributes mutations + + + +

MutationObservers: attributes mutations

+
+ +
+

+ +

+

+

+

+ + +

+

+

+

+ +

+

+

+

+

+ +

+

+

+ +

+

+

+

+

+

+ +

+

+ +

+

+

+ +

+

+ + +

+

+ +

+

+

+ +

+

+ +

+

+ +

+ +
+ + diff --git a/testing/web-platform/tests/dom/nodes/MutationObserver-callback-arguments.html b/testing/web-platform/tests/dom/nodes/MutationObserver-callback-arguments.html new file mode 100644 index 0000000000..d64758cb4f --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/MutationObserver-callback-arguments.html @@ -0,0 +1,31 @@ + + +MutationObserver: callback arguments + + + +
+
+ diff --git a/testing/web-platform/tests/dom/nodes/MutationObserver-characterData.html b/testing/web-platform/tests/dom/nodes/MutationObserver-characterData.html new file mode 100644 index 0000000000..addaef03da --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/MutationObserver-characterData.html @@ -0,0 +1,215 @@ + + +MutationObservers: characterData mutations + + + +

MutationObservers: characterData mutations

+
+ +
+ +

text content

+ +

text content

+ +

CHAN

+

CHANGED

+

CHANGED

+ +

CHGED

+

CHANGED

+

CHANGED

+ +

CCCHANGED

+

CHANGED

+ +

CCCHANGED

+

CHANGED

+ +

+ +

+ +

CHANN

+

CHANN

+ +

CHANN

+

CHANN

+ +

CHANN

+ +
+ + diff --git a/testing/web-platform/tests/dom/nodes/MutationObserver-childList.html b/testing/web-platform/tests/dom/nodes/MutationObserver-childList.html new file mode 100644 index 0000000000..e4c674e027 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/MutationObserver-childList.html @@ -0,0 +1,434 @@ + + +MutationObservers: childList mutations + + + +

MutationObservers: childList mutations

+
+ +
+

+text content +text content +text content +text content +text content +text content +

+ +
+
+

text content

+ +

text content

+

+

+

text content

+ +

PAS

+

CH

+ +

text content

+

text content

+

ANCHGED

+

text content

+

text content

+

text content

+ +

text content

+

text content

+

CHGEDAN

+

text content

+

text content

+

text content

+ + +

text content

+

text content

+

NO CHANGED

+

text content

+ +

text content

+ +

NO CHANGED

+

CHANN

+ +

NO CHANGED

+

CHANN

+ +

CHAED

+

CHAE

+ +

CHANGED

+ +
+ + + + diff --git a/testing/web-platform/tests/dom/nodes/MutationObserver-cross-realm-callback-report-exception.html b/testing/web-platform/tests/dom/nodes/MutationObserver-cross-realm-callback-report-exception.html new file mode 100644 index 0000000000..7d05c045b3 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/MutationObserver-cross-realm-callback-report-exception.html @@ -0,0 +1,32 @@ + + +MutationObserver reports the exception from its callback in the callback's global object + + + + + + diff --git a/testing/web-platform/tests/dom/nodes/MutationObserver-disconnect.html b/testing/web-platform/tests/dom/nodes/MutationObserver-disconnect.html new file mode 100644 index 0000000000..883edecf74 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/MutationObserver-disconnect.html @@ -0,0 +1,48 @@ + + +MutationObservers: disconnect + + +

MutationObservers: disconnect

+
+
+

+
+ diff --git a/testing/web-platform/tests/dom/nodes/MutationObserver-document.html b/testing/web-platform/tests/dom/nodes/MutationObserver-document.html new file mode 100644 index 0000000000..4662b23459 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/MutationObserver-document.html @@ -0,0 +1,167 @@ + + +MutationObservers: takeRecords + + + +

MutationObservers: document mutations

+
+ +

+ +

+

diff --git a/testing/web-platform/tests/dom/nodes/MutationObserver-inner-outer.html b/testing/web-platform/tests/dom/nodes/MutationObserver-inner-outer.html new file mode 100644 index 0000000000..9f6d871417 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/MutationObserver-inner-outer.html @@ -0,0 +1,65 @@ + + +MutationObservers: innerHTML, outerHTML mutations + + + +

MutationObservers: innerHTML, outerHTML mutations

+
+ +
+ +

old text

+ +

old text

+ +

old text

+
+ + diff --git a/testing/web-platform/tests/dom/nodes/MutationObserver-sanity.html b/testing/web-platform/tests/dom/nodes/MutationObserver-sanity.html new file mode 100644 index 0000000000..a4f6382b94 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/MutationObserver-sanity.html @@ -0,0 +1,95 @@ + + + + + + diff --git a/testing/web-platform/tests/dom/nodes/MutationObserver-takeRecords.html b/testing/web-platform/tests/dom/nodes/MutationObserver-takeRecords.html new file mode 100644 index 0000000000..6a27ef77ec --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/MutationObserver-takeRecords.html @@ -0,0 +1,53 @@ + + +MutationObservers: takeRecords + + + +

MutationObservers: takeRecords

+
+ +
+ +

+ +
+ + + diff --git a/testing/web-platform/tests/dom/nodes/Node-appendChild-cereactions-vs-script.window.js b/testing/web-platform/tests/dom/nodes/Node-appendChild-cereactions-vs-script.window.js new file mode 100644 index 0000000000..bc0b8ad6dc --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Node-appendChild-cereactions-vs-script.window.js @@ -0,0 +1,27 @@ +const results = []; +test(() => { + class Script1 extends HTMLScriptElement { + constructor() { + super(); + } + connectedCallback() { + results.push("ce connected s1"); + } + } + class Script2 extends HTMLScriptElement { + constructor() { + super(); + } + connectedCallback() { + results.push("ce connected s2"); + } + } + customElements.define("script-1", Script1, { extends: "script" }); + customElements.define("script-2", Script2, { extends: "script" }); + const s1 = new Script1(); + s1.textContent = "results.push('s1')"; + const s2 = new Script2(); + s2.textContent = "results.push('s2')"; + document.body.append(s1, s2); + assert_array_equals(results, ["s1", "s2", "ce connected s1", "ce connected s2"]); +}, "Custom element reactions follow script execution"); diff --git a/testing/web-platform/tests/dom/nodes/Node-appendChild.html b/testing/web-platform/tests/dom/nodes/Node-appendChild.html new file mode 100644 index 0000000000..8264cb11a5 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Node-appendChild.html @@ -0,0 +1,59 @@ + + +Node.appendChild + + + +
+ + diff --git a/testing/web-platform/tests/dom/nodes/Node-baseURI.html b/testing/web-platform/tests/dom/nodes/Node-baseURI.html new file mode 100644 index 0000000000..e9e9d76a10 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Node-baseURI.html @@ -0,0 +1,62 @@ + +Node.baseURI + + +
+ diff --git a/testing/web-platform/tests/dom/nodes/Node-childNodes.html b/testing/web-platform/tests/dom/nodes/Node-childNodes.html new file mode 100644 index 0000000000..0d38df37b2 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Node-childNodes.html @@ -0,0 +1,117 @@ + + +Node.childNodes + + + + + +
+
+
  • 1
  • 2
  • 3
  • 4
+
+ diff --git a/testing/web-platform/tests/dom/nodes/Node-cloneNode-XMLDocument.html b/testing/web-platform/tests/dom/nodes/Node-cloneNode-XMLDocument.html new file mode 100644 index 0000000000..2c63c77530 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Node-cloneNode-XMLDocument.html @@ -0,0 +1,28 @@ + + +Cloning of an XMLDocument + + + + + + + + + diff --git a/testing/web-platform/tests/dom/nodes/Node-cloneNode-document-with-doctype.html b/testing/web-platform/tests/dom/nodes/Node-cloneNode-document-with-doctype.html new file mode 100644 index 0000000000..21963084d2 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Node-cloneNode-document-with-doctype.html @@ -0,0 +1,51 @@ + + +Cloning of a document with a doctype + + + + + + + diff --git a/testing/web-platform/tests/dom/nodes/Node-cloneNode-external-stylesheet-no-bc.sub.html b/testing/web-platform/tests/dom/nodes/Node-cloneNode-external-stylesheet-no-bc.sub.html new file mode 100644 index 0000000000..bce6074aad --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Node-cloneNode-external-stylesheet-no-bc.sub.html @@ -0,0 +1,23 @@ + + +cloneNode on a stylesheet link in a browsing-context-less document + + + + + diff --git a/testing/web-platform/tests/dom/nodes/Node-cloneNode-on-inactive-document-crash.html b/testing/web-platform/tests/dom/nodes/Node-cloneNode-on-inactive-document-crash.html new file mode 100644 index 0000000000..cbd7a1e6a5 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Node-cloneNode-on-inactive-document-crash.html @@ -0,0 +1,6 @@ + + diff --git a/testing/web-platform/tests/dom/nodes/Node-cloneNode-svg.html b/testing/web-platform/tests/dom/nodes/Node-cloneNode-svg.html new file mode 100644 index 0000000000..9d4704b074 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Node-cloneNode-svg.html @@ -0,0 +1,63 @@ + + +Cloning of SVG elements and attributes + + + + + + + + + + diff --git a/testing/web-platform/tests/dom/nodes/Node-cloneNode.html b/testing/web-platform/tests/dom/nodes/Node-cloneNode.html new file mode 100644 index 0000000000..e97259dace --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Node-cloneNode.html @@ -0,0 +1,346 @@ + + +Node.cloneNode + + + +
+ diff --git a/testing/web-platform/tests/dom/nodes/Node-compareDocumentPosition.html b/testing/web-platform/tests/dom/nodes/Node-compareDocumentPosition.html new file mode 100644 index 0000000000..afae60aad1 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Node-compareDocumentPosition.html @@ -0,0 +1,87 @@ + +Node.compareDocumentPosition() tests + +
+ + + + + diff --git a/testing/web-platform/tests/dom/nodes/Node-constants.html b/testing/web-platform/tests/dom/nodes/Node-constants.html new file mode 100644 index 0000000000..33e7c10e73 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Node-constants.html @@ -0,0 +1,39 @@ + +Node constants + + + +
+ diff --git a/testing/web-platform/tests/dom/nodes/Node-contains-xml.xml b/testing/web-platform/tests/dom/nodes/Node-contains-xml.xml new file mode 100644 index 0000000000..f9b20d68d6 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Node-contains-xml.xml @@ -0,0 +1,83 @@ + + + +Node.nodeName + + + + + + +
+
+ + Link text +
+ + + diff --git a/testing/web-platform/tests/dom/nodes/Node-contains.html b/testing/web-platform/tests/dom/nodes/Node-contains.html new file mode 100644 index 0000000000..c44f072b11 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Node-contains.html @@ -0,0 +1,36 @@ + +Node.contains() tests + +
+ + + + + diff --git a/testing/web-platform/tests/dom/nodes/Node-insertBefore.html b/testing/web-platform/tests/dom/nodes/Node-insertBefore.html new file mode 100644 index 0000000000..ecb4d18314 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Node-insertBefore.html @@ -0,0 +1,297 @@ + +Node.insertBefore + + +
+ + + + + diff --git a/testing/web-platform/tests/dom/nodes/Node-isConnected-shadow-dom.html b/testing/web-platform/tests/dom/nodes/Node-isConnected-shadow-dom.html new file mode 100644 index 0000000000..7d04dc32f2 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Node-isConnected-shadow-dom.html @@ -0,0 +1,29 @@ + + +Test of Node.isConnected in a shadow tree + + + + + + diff --git a/testing/web-platform/tests/dom/nodes/Node-isConnected.html b/testing/web-platform/tests/dom/nodes/Node-isConnected.html new file mode 100644 index 0000000000..da0b460de4 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Node-isConnected.html @@ -0,0 +1,95 @@ + + + +Node.prototype.isConnected + + + + + + + diff --git a/testing/web-platform/tests/dom/nodes/Node-isEqualNode-iframe1.xml b/testing/web-platform/tests/dom/nodes/Node-isEqualNode-iframe1.xml new file mode 100644 index 0000000000..8077e73c27 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Node-isEqualNode-iframe1.xml @@ -0,0 +1 @@ + ]> diff --git a/testing/web-platform/tests/dom/nodes/Node-isEqualNode-iframe2.xml b/testing/web-platform/tests/dom/nodes/Node-isEqualNode-iframe2.xml new file mode 100644 index 0000000000..eacc9d17af --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Node-isEqualNode-iframe2.xml @@ -0,0 +1 @@ + ]> diff --git a/testing/web-platform/tests/dom/nodes/Node-isEqualNode-xhtml.xhtml b/testing/web-platform/tests/dom/nodes/Node-isEqualNode-xhtml.xhtml new file mode 100644 index 0000000000..3170643d2f --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Node-isEqualNode-xhtml.xhtml @@ -0,0 +1,84 @@ + + +Node.isEqualNode + + + + +
+ + diff --git a/testing/web-platform/tests/dom/nodes/Node-properties.html b/testing/web-platform/tests/dom/nodes/Node-properties.html new file mode 100644 index 0000000000..10f92e7d7e --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Node-properties.html @@ -0,0 +1,688 @@ + +Node assorted property tests + + +
+ + + + diff --git a/testing/web-platform/tests/dom/nodes/Node-removeChild.html b/testing/web-platform/tests/dom/nodes/Node-removeChild.html new file mode 100644 index 0000000000..6158423359 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Node-removeChild.html @@ -0,0 +1,58 @@ + +Node.removeChild + + + +
+ + diff --git a/testing/web-platform/tests/dom/nodes/Node-replaceChild.html b/testing/web-platform/tests/dom/nodes/Node-replaceChild.html new file mode 100644 index 0000000000..74aac67d43 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Node-replaceChild.html @@ -0,0 +1,349 @@ + + +Node.replaceChild + + + +
+ + + + diff --git a/testing/web-platform/tests/dom/nodes/Node-textContent.html b/testing/web-platform/tests/dom/nodes/Node-textContent.html new file mode 100644 index 0000000000..cf2e072087 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Node-textContent.html @@ -0,0 +1,265 @@ + + +Node.textContent + + +
+ diff --git a/testing/web-platform/tests/dom/nodes/NodeList-Iterable.html b/testing/web-platform/tests/dom/nodes/NodeList-Iterable.html new file mode 100644 index 0000000000..fcbee175cb --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/NodeList-Iterable.html @@ -0,0 +1,61 @@ + + +NodeList Iterable Test + + +

+

+

+

+

+ +
123
+ diff --git a/testing/web-platform/tests/dom/nodes/NodeList-live-mutations.window.js b/testing/web-platform/tests/dom/nodes/NodeList-live-mutations.window.js new file mode 100644 index 0000000000..a11fed1e38 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/NodeList-live-mutations.window.js @@ -0,0 +1,79 @@ +function testNodeList(name, hooks) { + test(() => { + const nodes = { + root: document.createElement("div"), + div1: document.createElement("div"), + div2: document.createElement("div"), + p: document.createElement("p") + }; + + const list = nodes.root.childNodes; + + hooks.initial(list, nodes); + + nodes.root.appendChild(nodes.div1); + nodes.root.appendChild(nodes.p); + nodes.root.appendChild(nodes.div2); + + hooks.afterInsertion(list, nodes); + + nodes.root.removeChild(nodes.div1); + + hooks.afterRemoval(list, nodes); + }, `NodeList live mutations: ${name}`); +} + +testNodeList("NodeList.length", { + initial(list) { + assert_equals(list.length, 0); + }, + afterInsertion(list) { + assert_equals(list.length, 3); + }, + afterRemoval(list) { + assert_equals(list.length, 2); + } +}); + +testNodeList("NodeList.item(index)", { + initial(list) { + assert_equals(list.item(0), null); + }, + afterInsertion(list, nodes) { + assert_equals(list.item(0), nodes.div1); + assert_equals(list.item(1), nodes.p); + assert_equals(list.item(2), nodes.div2); + }, + afterRemoval(list, nodes) { + assert_equals(list.item(0), nodes.p); + assert_equals(list.item(1), nodes.div2); + } +}); + +testNodeList("NodeList[index]", { + initial(list) { + assert_equals(list[0], undefined); + }, + afterInsertion(list, nodes) { + assert_equals(list[0], nodes.div1); + assert_equals(list[1], nodes.p); + assert_equals(list[2], nodes.div2); + }, + afterRemoval(list, nodes) { + assert_equals(list[0], nodes.p); + assert_equals(list[1], nodes.div2); + } +}); + +testNodeList("NodeList ownPropertyNames", { + initial(list) { + assert_object_equals(Object.getOwnPropertyNames(list), []); + }, + afterInsertion(list) { + assert_object_equals(Object.getOwnPropertyNames(list), ["0", "1", "2"]); + }, + afterRemoval(list) { + assert_object_equals(Object.getOwnPropertyNames(list), ["0", "1"]); + } +}); + diff --git a/testing/web-platform/tests/dom/nodes/NodeList-static-length-getter-tampered-1.html b/testing/web-platform/tests/dom/nodes/NodeList-static-length-getter-tampered-1.html new file mode 100644 index 0000000000..c5c58f9d12 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/NodeList-static-length-getter-tampered-1.html @@ -0,0 +1,22 @@ + + + +NodeList (static collection) "length" getter tampered + + + + + + + diff --git a/testing/web-platform/tests/dom/nodes/NodeList-static-length-getter-tampered-2.html b/testing/web-platform/tests/dom/nodes/NodeList-static-length-getter-tampered-2.html new file mode 100644 index 0000000000..bac0511202 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/NodeList-static-length-getter-tampered-2.html @@ -0,0 +1,22 @@ + + + +NodeList (static collection) "length" getter tampered + + + + + + + diff --git a/testing/web-platform/tests/dom/nodes/NodeList-static-length-getter-tampered-3.html b/testing/web-platform/tests/dom/nodes/NodeList-static-length-getter-tampered-3.html new file mode 100644 index 0000000000..9690aab3c1 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/NodeList-static-length-getter-tampered-3.html @@ -0,0 +1,22 @@ + + + +NodeList (static collection) "length" getter tampered + + + + + + + diff --git a/testing/web-platform/tests/dom/nodes/NodeList-static-length-getter-tampered-indexOf-1.html b/testing/web-platform/tests/dom/nodes/NodeList-static-length-getter-tampered-indexOf-1.html new file mode 100644 index 0000000000..5ce4146757 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/NodeList-static-length-getter-tampered-indexOf-1.html @@ -0,0 +1,22 @@ + + + +NodeList (static collection) "length" getter tampered (Array.prototype.indexOf) + + + + + + + diff --git a/testing/web-platform/tests/dom/nodes/NodeList-static-length-getter-tampered-indexOf-2.html b/testing/web-platform/tests/dom/nodes/NodeList-static-length-getter-tampered-indexOf-2.html new file mode 100644 index 0000000000..57814ed5ac --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/NodeList-static-length-getter-tampered-indexOf-2.html @@ -0,0 +1,22 @@ + + + +NodeList (static collection) "length" getter tampered (Array.prototype.indexOf) + + + + + + + diff --git a/testing/web-platform/tests/dom/nodes/NodeList-static-length-getter-tampered-indexOf-3.html b/testing/web-platform/tests/dom/nodes/NodeList-static-length-getter-tampered-indexOf-3.html new file mode 100644 index 0000000000..838f376dd2 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/NodeList-static-length-getter-tampered-indexOf-3.html @@ -0,0 +1,22 @@ + + + +NodeList (static collection) "length" getter tampered (Array.prototype.indexOf) + + + + + + + diff --git a/testing/web-platform/tests/dom/nodes/ParentNode-append.html b/testing/web-platform/tests/dom/nodes/ParentNode-append.html new file mode 100644 index 0000000000..4e101f73a2 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/ParentNode-append.html @@ -0,0 +1,67 @@ + + +ParentNode.append + + + + + + diff --git a/testing/web-platform/tests/dom/nodes/ParentNode-children.html b/testing/web-platform/tests/dom/nodes/ParentNode-children.html new file mode 100644 index 0000000000..6621e7d9de --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/ParentNode-children.html @@ -0,0 +1,27 @@ + + +ParentNode.children + + + +
+
+
  • 1
  • 2
  • 3
  • 4
+
+ + diff --git a/testing/web-platform/tests/dom/nodes/ParentNode-prepend.html b/testing/web-platform/tests/dom/nodes/ParentNode-prepend.html new file mode 100644 index 0000000000..f6aa38a2dd --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/ParentNode-prepend.html @@ -0,0 +1,67 @@ + + +ParentNode.prepend + + + + + + diff --git a/testing/web-platform/tests/dom/nodes/ParentNode-querySelector-All-content.html b/testing/web-platform/tests/dom/nodes/ParentNode-querySelector-All-content.html new file mode 100644 index 0000000000..8dc1354551 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/ParentNode-querySelector-All-content.html @@ -0,0 +1,377 @@ + + + + + Selectors-API Test Suite: HTML with Selectors Level 2 using TestHarness: Test Document + + + + + + + + +
+
+ +
+

Universal selector tests inside element with id="universal".

+
+
Some preformatted text with some embedded code
+

This is a normal link: W3C

+
Some more nested elements code hyperlink
+
+ +
+
+
+
+
+

+

+    
+
    + + + + +
    + +
    +
    +
    +
    +
    + +
    + + + + + + + + + +
    + +
    +
    + +
    +
    +
    +
    + +
    +
    + + + + + + + + + +

    +
    + +
    +
    +
    +
    +
    +
    + +
    + + + + +
    +
    +
    +
    +
    + +

    +
    + +
    + + + + +
    +
    +
    +
    + +

    +
    + +
    + + + + +
    +
    +
    +
    +
    +
    + +

    +
    + +
    + + + + +
    + +
      +
    1. +
    2. +
    3. +
    4. +
    5. +
    6. +
    7. +
    8. +
    9. +
    10. +
    11. +
    12. +
    + +

    + span1 + em1 + + em2 + span2 + strong1 + em3 + span3 + span4 + strong2 + em4 +

    +
    + +
    +
    +
    +
    + +

    +

    +

    +
    + +
    +

    +

    +

    + +
    +
    +
    +
    + +
    +

    + +

    +

    + + +

    +

    + + + +

    +
    > + +
    +

    +

    +

    +

    Text node

    +

    +
    + + + +
    +
    +
    +
    +
    +
    + +
    + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    +
    +
    +
    + +

    +

    +

    +
    + +
    All pseudo-element tests
    + +
    +

    +

    +

    + + +
    +
    +

    +
    +

    +
    +
    +
    +
    + + + + + + +
    + +
    +
    +
    + +
      +
    • +
    • +
    • +
    • +
    + + + + + + +
    + +
    +
    +
    +
    +
    +
    +
    +
    +
    + +
    +
    +
    +
    +
    +
    +
    +
    +
    + +
    +
    +
    +
    +
    +
    +

    +
    +
    +
    +

    +

    +
    + +
    +
    +
    +
    +
    +
    +

    +
    +
    +
    +

    +

    +
    + +
    + + +
    +
    + + diff --git a/testing/web-platform/tests/dom/nodes/ParentNode-querySelector-All-content.xht b/testing/web-platform/tests/dom/nodes/ParentNode-querySelector-All-content.xht new file mode 100644 index 0000000000..0e9b925f58 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/ParentNode-querySelector-All-content.xht @@ -0,0 +1,372 @@ + + + + Selectors-API Test Suite: HTML with Selectors Level 2 using TestHarness: Test Document + + + + + + + +
    +
    + +
    +

    Universal selector tests inside element with id="universal".

    +
    +
    Some preformatted text with some embedded code
    +

    This is a normal link: W3C

    +
    Some more nested elements code hyperlink
    +
    + +
    +
    +
    +
    +
    +

    +
    
    +    
    +
      + + + + +
      + +
      +
      +
      +
      +
      + +
      + + + + + + + + + +
      + +
      +
      + +
      +
      +
      +
      + +
      +
      + + + + + + + + + +

      +
      + +
      +
      +
      +
      +
      +
      + +
      + + + + +
      +
      +
      +
      +
      + +

      +
      + +
      + + + + +
      +
      +
      +
      + +

      +
      + +
      + + + + +
      +
      +
      +
      +
      +
      + +

      +
      + +
      + + + + +
      + +
        +
      1. +
      2. +
      3. +
      4. +
      5. +
      6. +
      7. +
      8. +
      9. +
      10. +
      11. +
      12. +
      + +

      + span1 + em1 + + em2 + span2 + strong1 + em3 + span3 + span4 + strong2 + em4 +

      +
      + +
      +
      +
      +
      + +

      +

      +

      +
      + +
      +

      +

      +

      + +
      +
      +
      +
      + +
      +

      + +

      +

      + + +

      +

      + + + +

      +
      > + +
      +

      +

      +

      +

      Text node

      +

      +
      + + + +
      +
      +
      +
      +
      +
      + +
      + + + + + + + + + + + + + + + + + + + + + + + +
      + +
      +
      +
      +
      + +

      +

      +

      +
      + +
      All pseudo-element tests
      + +
      +

      +

      +

      + + +
      +
      +

      +
      +

      +
      +
      +
      +
      + + + + + + +
      + +
      +
      +
      + +
        +
      • +
      • +
      • +
      • +
      + + + + + + +
      + +
      +
      +
      +
      +
      +
      +
      +
      +
      + +
      +
      +
      +
      +
      +
      +
      +
      +
      + +
      +
      +
      +
      +
      +
      +

      +
      +
      +
      +

      +

      +
      + +
      +
      +
      +
      +
      +
      +

      +
      +
      +
      +

      +

      +
      + +
      + + +
      +
      + + diff --git a/testing/web-platform/tests/dom/nodes/ParentNode-querySelector-All-xht.xht b/testing/web-platform/tests/dom/nodes/ParentNode-querySelector-All-xht.xht new file mode 100644 index 0000000000..f2d94da1da --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/ParentNode-querySelector-All-xht.xht @@ -0,0 +1,124 @@ + + + + +Selectors-API Test Suite: XHTML + + + + + + + +
      This test requires JavaScript.
      + + + + diff --git a/testing/web-platform/tests/dom/nodes/ParentNode-querySelector-All.html b/testing/web-platform/tests/dom/nodes/ParentNode-querySelector-All.html new file mode 100644 index 0000000000..7d68e7f297 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/ParentNode-querySelector-All.html @@ -0,0 +1,120 @@ + + + +Selectors-API Test Suite: HTML + + + + + + +
      This test requires JavaScript.
      + + diff --git a/testing/web-platform/tests/dom/nodes/ParentNode-querySelector-All.js b/testing/web-platform/tests/dom/nodes/ParentNode-querySelector-All.js new file mode 100644 index 0000000000..3c6c503179 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/ParentNode-querySelector-All.js @@ -0,0 +1,261 @@ +// Require selectors.js to be included before this. + +/* + * Create and append special elements that cannot be created correctly with HTML markup alone. + */ +function setupSpecialElements(doc, parent) { + // Setup null and undefined tests + parent.appendChild(doc.createElement("null")); + parent.appendChild(doc.createElement("undefined")); + + // Setup namespace tests + var anyNS = doc.createElement("div"); + var noNS = doc.createElement("div"); + anyNS.id = "any-namespace"; + noNS.id = "no-namespace"; + + var divs; + div = [doc.createElement("div"), + doc.createElementNS("http://www.w3.org/1999/xhtml", "div"), + doc.createElementNS("", "div"), + doc.createElementNS("http://www.example.org/ns", "div")]; + + div[0].id = "any-namespace-div1"; + div[1].id = "any-namespace-div2"; + div[2].setAttribute("id", "any-namespace-div3"); // Non-HTML elements can't use .id property + div[3].setAttribute("id", "any-namespace-div4"); + + for (var i = 0; i < div.length; i++) { + anyNS.appendChild(div[i]) + } + + div = [doc.createElement("div"), + doc.createElementNS("http://www.w3.org/1999/xhtml", "div"), + doc.createElementNS("", "div"), + doc.createElementNS("http://www.example.org/ns", "div")]; + + div[0].id = "no-namespace-div1"; + div[1].id = "no-namespace-div2"; + div[2].setAttribute("id", "no-namespace-div3"); // Non-HTML elements can't use .id property + div[3].setAttribute("id", "no-namespace-div4"); + + for (i = 0; i < div.length; i++) { + noNS.appendChild(div[i]) + } + + parent.appendChild(anyNS); + parent.appendChild(noNS); + + var span = doc.getElementById("attr-presence-i1"); + span.setAttributeNS("http://www.example.org/ns", "title", ""); +} + +/* + * Check that the querySelector and querySelectorAll methods exist on the given Node + */ +function interfaceCheck(type, obj) { + test(function() { + var q = typeof obj.querySelector === "function"; + assert_true(q, type + " supports querySelector."); + }, type + " supports querySelector") + + test(function() { + var qa = typeof obj.querySelectorAll === "function"; + assert_true( qa, type + " supports querySelectorAll."); + }, type + " supports querySelectorAll") + + test(function() { + var list = obj.querySelectorAll("div"); + if (obj.ownerDocument) { // The object is not a Document + assert_true(list instanceof obj.ownerDocument.defaultView.NodeList, "The result should be an instance of a NodeList") + } else { // The object is a Document + assert_true(list instanceof obj.defaultView.NodeList, "The result should be an instance of a NodeList") + } + }, type + ".querySelectorAll returns NodeList instance") +} + +/* + * Verify that the NodeList returned by querySelectorAll is static and and that a new list is created after + * each call. A static list should not be affected by subsequent changes to the DOM. + */ +function verifyStaticList(type, doc, root) { + var pre, post, preLength; + + test(function() { + pre = root.querySelectorAll("div"); + preLength = pre.length; + + var div = doc.createElement("div"); + (root.body || root).appendChild(div); + + assert_equals(pre.length, preLength, "The length of the NodeList should not change.") + }, type + ": static NodeList") + + test(function() { + post = root.querySelectorAll("div"), + assert_equals(post.length, preLength + 1, "The length of the new NodeList should be 1 more than the previous list.") + }, type + ": new NodeList") +} + +/* + * Verify handling of special values for the selector parameter, including stringification of + * null and undefined, and the handling of the empty string. + */ +function runSpecialSelectorTests(type, root) { + let global = (root.ownerDocument || root).defaultView; + + test(function() { // 1 + assert_equals(root.querySelectorAll(null).length, 1, "This should find one element with the tag name 'NULL'."); + }, type + ".querySelectorAll null") + + test(function() { // 2 + assert_equals(root.querySelectorAll(undefined).length, 1, "This should find one element with the tag name 'UNDEFINED'."); + }, type + ".querySelectorAll undefined") + + test(function() { // 3 + assert_throws_js(global.TypeError, function() { + root.querySelectorAll(); + }, "This should throw a TypeError.") + }, type + ".querySelectorAll no parameter") + + test(function() { // 4 + var elm = root.querySelector(null) + assert_not_equals(elm, null, "This should find an element."); + assert_equals(elm.tagName.toUpperCase(), "NULL", "The tag name should be 'NULL'.") + }, type + ".querySelector null") + + test(function() { // 5 + var elm = root.querySelector(undefined) + assert_not_equals(elm, undefined, "This should find an element."); + assert_equals(elm.tagName.toUpperCase(), "UNDEFINED", "The tag name should be 'UNDEFINED'.") + }, type + ".querySelector undefined") + + test(function() { // 6 + assert_throws_js(global.TypeError, function() { + root.querySelector(); + }, "This should throw a TypeError.") + }, type + ".querySelector no parameter") + + test(function() { // 7 + result = root.querySelectorAll("*"); + var i = 0; + traverse(root, function(elem) { + if (elem !== root) { + assert_equals(elem, result[i], "The result in index " + i + " should be in tree order."); + i++; + } + }) + }, type + ".querySelectorAll tree order"); +} + +/* + * Execute queries with the specified valid selectors for both querySelector() and querySelectorAll() + * Only run these tests when results are expected. Don't run for syntax error tests. + */ +function runValidSelectorTest(type, root, selectors, testType, docType) { + var nodeType = ""; + switch (root.nodeType) { + case Node.DOCUMENT_NODE: + nodeType = "document"; + break; + case Node.ELEMENT_NODE: + nodeType = root.parentNode ? "element" : "detached"; + break; + case Node.DOCUMENT_FRAGMENT_NODE: + nodeType = "fragment"; + break; + default: + assert_unreached(); + nodeType = "unknown"; // This should never happen. + } + + for (var i = 0; i < selectors.length; i++) { + var s = selectors[i]; + var n = s["name"]; + var q = s["selector"]; + var e = s["expect"]; + + if ((!s["exclude"] || (s["exclude"].indexOf(nodeType) === -1 && s["exclude"].indexOf(docType) === -1)) + && (s["testType"] & testType) ) { + var foundall, found; + + test(function() { + foundall = root.querySelectorAll(q); + assert_not_equals(foundall, null, "The method should not return null.") + assert_equals(foundall.length, e.length, "The method should return the expected number of matches.") + + for (var i = 0; i < e.length; i++) { + assert_not_equals(foundall[i], null, "The item in index " + i + " should not be null.") + assert_equals(foundall[i].getAttribute("id"), e[i], "The item in index " + i + " should have the expected ID."); + assert_false(foundall[i].hasAttribute("data-clone"), "This should not be a cloned element."); + } + }, type + ".querySelectorAll: " + n + ": " + q); + + test(function() { + found = root.querySelector(q); + + if (e.length > 0) { + assert_not_equals(found, null, "The method should return a match.") + assert_equals(found.getAttribute("id"), e[0], "The method should return the first match."); + assert_equals(found, foundall[0], "The result should match the first item from querySelectorAll."); + assert_false(found.hasAttribute("data-clone"), "This should not be annotated as a cloned element."); + } else { + assert_equals(found, null, "The method should not match anything."); + } + }, type + ".querySelector: " + n + ": " + q); + } + } +} + +function windowFor(root) { + return root.defaultView || root.ownerDocument.defaultView; +} + +/* + * Execute queries with the specified invalid selectors for both querySelector() and querySelectorAll() + * Only run these tests when errors are expected. Don't run for valid selector tests. + */ +function runInvalidSelectorTest(type, root, selectors) { + for (var i = 0; i < selectors.length; i++) { + var s = selectors[i]; + var n = s["name"]; + var q = s["selector"]; + + test(function() { + assert_throws_dom("SyntaxError", windowFor(root).DOMException, function() { + root.querySelector(q) + }); + }, type + ".querySelector: " + n + ": " + q); + + test(function() { + assert_throws_dom("SyntaxError", windowFor(root).DOMException, function() { + root.querySelectorAll(q) + }); + }, type + ".querySelectorAll: " + n + ": " + q); + } +} + +function traverse(elem, fn) { + if (elem.nodeType === elem.ELEMENT_NODE) { + fn(elem); + } + elem = elem.firstChild; + while (elem) { + traverse(elem, fn); + elem = elem.nextSibling; + } +} + +function getNodeType(node) { + switch (node.nodeType) { + case Node.DOCUMENT_NODE: + return "document"; + case Node.ELEMENT_NODE: + return node.parentNode ? "element" : "detached"; + case Node.DOCUMENT_FRAGMENT_NODE: + return "fragment"; + default: + assert_unreached(); + return "unknown"; // This should never happen. + } +} diff --git a/testing/web-platform/tests/dom/nodes/ParentNode-querySelector-case-insensitive.html b/testing/web-platform/tests/dom/nodes/ParentNode-querySelector-case-insensitive.html new file mode 100644 index 0000000000..e461ee5016 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/ParentNode-querySelector-case-insensitive.html @@ -0,0 +1,21 @@ + + +querySelector(All) must work with the i and *= selectors + + + + + + + diff --git a/testing/web-platform/tests/dom/nodes/ParentNode-querySelector-escapes.html b/testing/web-platform/tests/dom/nodes/ParentNode-querySelector-escapes.html new file mode 100644 index 0000000000..65a75e5c03 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/ParentNode-querySelector-escapes.html @@ -0,0 +1,123 @@ + + +querySelector() with CSS escapes + + + + + + + + diff --git a/testing/web-platform/tests/dom/nodes/ParentNode-querySelector-scope.html b/testing/web-platform/tests/dom/nodes/ParentNode-querySelector-scope.html new file mode 100644 index 0000000000..d984956d6c --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/ParentNode-querySelector-scope.html @@ -0,0 +1,33 @@ + + +querySelector(All) scoped to a root element + + + +

      hello

      + + diff --git a/testing/web-platform/tests/dom/nodes/ParentNode-querySelectorAll-removed-elements.html b/testing/web-platform/tests/dom/nodes/ParentNode-querySelectorAll-removed-elements.html new file mode 100644 index 0000000000..3cefc80906 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/ParentNode-querySelectorAll-removed-elements.html @@ -0,0 +1,30 @@ + + +querySelectorAll must not return removed elements + + + + +
      + + diff --git a/testing/web-platform/tests/dom/nodes/ParentNode-querySelectors-exclusive.html b/testing/web-platform/tests/dom/nodes/ParentNode-querySelectors-exclusive.html new file mode 100644 index 0000000000..5cff9367cf --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/ParentNode-querySelectors-exclusive.html @@ -0,0 +1,39 @@ + + +querySelector/querySelectorAll should not include their thisArg + + + + + diff --git a/testing/web-platform/tests/dom/nodes/ParentNode-querySelectors-namespaces.html b/testing/web-platform/tests/dom/nodes/ParentNode-querySelectors-namespaces.html new file mode 100644 index 0000000000..714999b3f0 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/ParentNode-querySelectors-namespaces.html @@ -0,0 +1,21 @@ + + +querySelectorAll must work with namespace attribute selectors on SVG + + + + + + + diff --git a/testing/web-platform/tests/dom/nodes/ParentNode-querySelectors-space-and-dash-attribute-value.html b/testing/web-platform/tests/dom/nodes/ParentNode-querySelectors-space-and-dash-attribute-value.html new file mode 100644 index 0000000000..e08c6e6db1 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/ParentNode-querySelectors-space-and-dash-attribute-value.html @@ -0,0 +1,21 @@ + + +querySelector(All) must work for attribute values that contain spaces and dashes + + + + +Test One + + diff --git a/testing/web-platform/tests/dom/nodes/ParentNode-replaceChildren.html b/testing/web-platform/tests/dom/nodes/ParentNode-replaceChildren.html new file mode 100644 index 0000000000..ee22009fcb --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/ParentNode-replaceChildren.html @@ -0,0 +1,205 @@ + + +ParentNode.replaceChildren + + + + + + + diff --git a/testing/web-platform/tests/dom/nodes/ProcessingInstruction-escapes-1.xhtml b/testing/web-platform/tests/dom/nodes/ProcessingInstruction-escapes-1.xhtml new file mode 100644 index 0000000000..d629a8464b --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/ProcessingInstruction-escapes-1.xhtml @@ -0,0 +1,33 @@ + + + + + + +ProcessingInstruction numeric escapes + + + + + + +
      + + + diff --git a/testing/web-platform/tests/dom/nodes/ProcessingInstruction-literal-1.xhtml b/testing/web-platform/tests/dom/nodes/ProcessingInstruction-literal-1.xhtml new file mode 100644 index 0000000000..4eaf86cbdc --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/ProcessingInstruction-literal-1.xhtml @@ -0,0 +1,16 @@ + + + +<?xml?> is not a ProcessingInstruction + + + + +
      + + + diff --git a/testing/web-platform/tests/dom/nodes/ProcessingInstruction-literal-2.xhtml b/testing/web-platform/tests/dom/nodes/ProcessingInstruction-literal-2.xhtml new file mode 100644 index 0000000000..d878c697c0 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/ProcessingInstruction-literal-2.xhtml @@ -0,0 +1,21 @@ + + + +ProcessingInstruction literals + + + + + + +
      + + + diff --git a/testing/web-platform/tests/dom/nodes/Text-constructor.html b/testing/web-platform/tests/dom/nodes/Text-constructor.html new file mode 100644 index 0000000000..dbd9a0be01 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Text-constructor.html @@ -0,0 +1,11 @@ + + +Text constructor + + + + +
      + diff --git a/testing/web-platform/tests/dom/nodes/Text-splitText.html b/testing/web-platform/tests/dom/nodes/Text-splitText.html new file mode 100644 index 0000000000..2dd23018cb --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Text-splitText.html @@ -0,0 +1,53 @@ + + +Text.splitText() + + + +
      + diff --git a/testing/web-platform/tests/dom/nodes/Text-wholeText.html b/testing/web-platform/tests/dom/nodes/Text-wholeText.html new file mode 100644 index 0000000000..2467930da8 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/Text-wholeText.html @@ -0,0 +1,46 @@ + + +Text - wholeText + + + + diff --git a/testing/web-platform/tests/dom/nodes/adoption.window.js b/testing/web-platform/tests/dom/nodes/adoption.window.js new file mode 100644 index 0000000000..ad90aaf375 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/adoption.window.js @@ -0,0 +1,58 @@ +// Testing DocumentFragment with host separately as it has a different node document by design +test(() => { + const df = document.createElement("template").content; + const child = df.appendChild(new Text('hi')); + assert_not_equals(df.ownerDocument, document); + const nodeDocument = df.ownerDocument; + document.body.appendChild(df); + assert_equals(df.childNodes.length, 0); + assert_equals(child.ownerDocument, document); + assert_equals(df.ownerDocument, nodeDocument); +}, `appendChild() and DocumentFragment with host`); + +test(() => { + const df = document.createElement("template").content; + const child = df.appendChild(new Text('hi')); + const nodeDocument = df.ownerDocument; + document.adoptNode(df); + assert_equals(df.childNodes.length, 1); + assert_equals(child.ownerDocument, nodeDocument); + assert_equals(df.ownerDocument, nodeDocument); +}, `adoptNode() and DocumentFragment with host`); + +[ + { + "name": "DocumentFragment", + "creator": doc => doc.createDocumentFragment() + }, + { + "name": "ShadowRoot", + "creator": doc => doc.createElementNS("http://www.w3.org/1999/xhtml", "div").attachShadow({mode: "closed"}) + } +].forEach(dfTest => { + test(() => { + const doc = new Document(); + const df = dfTest.creator(doc); + const child = df.appendChild(new Text('hi')); + assert_equals(df.ownerDocument, doc); + + document.body.appendChild(df); + assert_equals(df.childNodes.length, 0); + assert_equals(child.ownerDocument, document); + assert_equals(df.ownerDocument, doc); + }, `appendChild() and ${dfTest.name}`); + + test(() => { + const doc = new Document(); + const df = dfTest.creator(doc); + const child = df.appendChild(new Text('hi')); + if (dfTest.name === "ShadowRoot") { + assert_throws_dom("HierarchyRequestError", () => document.adoptNode(df)); + } else { + document.adoptNode(df); + assert_equals(df.childNodes.length, 1); + assert_equals(child.ownerDocument, document); + assert_equals(df.ownerDocument, document); + } + }, `adoptNode() and ${dfTest.name}`); +}); diff --git a/testing/web-platform/tests/dom/nodes/append-on-Document.html b/testing/web-platform/tests/dom/nodes/append-on-Document.html new file mode 100644 index 0000000000..78f278b381 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/append-on-Document.html @@ -0,0 +1,53 @@ + + +DocumentType.append + + + + + diff --git a/testing/web-platform/tests/dom/nodes/attributes-namednodemap.html b/testing/web-platform/tests/dom/nodes/attributes-namednodemap.html new file mode 100644 index 0000000000..96f9d30703 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/attributes-namednodemap.html @@ -0,0 +1,120 @@ + +Tests of some tricky semantics around NamedNodeMap and the element.attributes collection + + + + + + + + diff --git a/testing/web-platform/tests/dom/nodes/attributes.html b/testing/web-platform/tests/dom/nodes/attributes.html new file mode 100644 index 0000000000..c6db7eb8aa --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/attributes.html @@ -0,0 +1,858 @@ + + +Attributes tests + + + + + + + +
      + + + + + + + + diff --git a/testing/web-platform/tests/dom/nodes/attributes.js b/testing/web-platform/tests/dom/nodes/attributes.js new file mode 100644 index 0000000000..ef32bf6a67 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/attributes.js @@ -0,0 +1,18 @@ +function attr_is(attr, v, ln, ns, p, n) { + assert_equals(attr.value, v) + assert_equals(attr.nodeValue, v) + assert_equals(attr.textContent, v) + assert_equals(attr.localName, ln) + assert_equals(attr.namespaceURI, ns) + assert_equals(attr.prefix, p) + assert_equals(attr.name, n) + assert_equals(attr.nodeName, n); + assert_equals(attr.specified, true) +} + +function attributes_are(el, l) { + for (var i = 0, il = l.length; i < il; i++) { + attr_is(el.attributes[i], l[i][1], l[i][0], (l[i].length < 3) ? null : l[i][2], null, l[i][0]) + assert_equals(el.attributes[i].ownerElement, el) + } +} diff --git a/testing/web-platform/tests/dom/nodes/case.html b/testing/web-platform/tests/dom/nodes/case.html new file mode 100644 index 0000000000..c3c195141c --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/case.html @@ -0,0 +1,18 @@ + + +Tests for case-sensitivity in APIs + + + + + + + + + + + + + + +
      diff --git a/testing/web-platform/tests/dom/nodes/case.js b/testing/web-platform/tests/dom/nodes/case.js new file mode 100644 index 0000000000..8c2da4a44a --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/case.js @@ -0,0 +1,186 @@ +/* + * document.createElement(NS) + * + * document.getElementsByTagName(NS) + * + * Element.setAttribute(NS) + * + * Element.getAttribute(NS) + * Element.hasAttribute(NS) + * Element.getElementsByTagName(NS) + */ + +var tests = []; +setup(function() { + var name_inputs = ["abc", "Abc", "ABC", "ä", "Ä"]; + var namespaces = ["http://www.w3.org/1999/xhtml", "http://www.w3.org/2000/svg", "http://FOO"]; + name_inputs.forEach(function(x) { + tests.push(["createElement " + x, test_create_element, [x]]); + tests.push(["setAttribute " +x, test_set_attribute, [x]]); + tests.push(["getAttribute " +x, test_get_attribute, [x]]); + tests.push(["getElementsByTagName a:" +x, test_get_elements_tag_name, + [outer_product(namespaces, ["a"], name_inputs), + x]]); + tests.push(["getElementsByTagName " +x, test_get_elements_tag_name, + [outer_product(namespaces, [null], name_inputs), + x]]); + }); + outer_product(namespaces, name_inputs, name_inputs).forEach(function(x) { + tests.push(["createElementNS " + x, test_create_element_ns, x]); + tests.push(["setAttributeNS " + x, test_set_attribute_ns, x]); + tests.push(["getAttributeNS " + x, test_get_attribute_ns, x]); + }); + outer_product([null].concat(namespaces), name_inputs).forEach(function(x) { + tests.push(["getElementsByTagNameNS " + x, test_get_elements_tag_name_ns, + outer_product(namespaces, name_inputs), x]); + }); + name_inputs.forEach(function(x) { + tests.push(["createElementNS " + x, test_create_element_ns, [null, null, x]]); + tests.push(["setAttributeNS " + x, test_set_attribute_ns, [null, null, x]]); + tests.push(["getAttributeNS " + x, test_get_attribute_ns, [null, null, x]]); + }); + + }); +function outer_product() { + var rv = []; + function compute_outer_product() { + var args = Array.prototype.slice.call(arguments); + var index = args[0]; + if (index < args.length) { + args[index].forEach(function(x) { + compute_outer_product.apply(this, [index+1].concat(args.slice(1, index), x, args.slice(index+1))); + }); + } else { + rv.push(args.slice(1)); + } + } + compute_outer_product.apply(this, [1].concat(Array.prototype.slice.call(arguments))); + return rv; +} + +function expected_case(input) { + //is_html gets set by a global on the page loading the tests + if (is_html) { + return ascii_lowercase(input); + } else { + return input; + } +} + +function ascii_lowercase(input) { + return input.replace(/[A-Z]/g, function(x) { + return x.toLowerCase(); + }); +} + +function get_qualified_name(el) { + if (el.prefix) { + return el.prefix + ":" + el.localName; + } + return el.localName; +} + +function test_create_element(name) { + var node = document.createElement(name); + assert_equals(node.localName, expected_case(name)); +} + +function test_create_element_ns(namespace, prefix, local_name) { + var qualified_name = prefix ? prefix + ":" + local_name : local_name; + var node = document.createElementNS(namespace, qualified_name); + assert_equals(node.prefix, prefix, "prefix"); + assert_equals(node.localName, local_name, "localName"); +} + +function test_set_attribute(name) { + var node = document.createElement("div"); + node.setAttribute(name, "test"); + assert_equals(node.attributes[0].localName, expected_case(name)); +} + +function test_set_attribute_ns(namespace, prefix, local_name) { + var qualified_name = prefix ? prefix + ":" + local_name : local_name; + var node = document.createElement("div"); + node.setAttributeNS(namespace, qualified_name, "test"); + var attr = node.attributes[0]; + assert_equals(attr.prefix, prefix, "prefix"); + assert_equals(attr.localName, local_name, "localName"); +} + +function test_get_attribute(name) { + var node = document.createElement("div"); + node.setAttribute(name, "test"); + var expected_name = expected_case(name); + assert_equals(node.getAttribute(expected_name), "test"); + if (expected_name != name) { + assert_equals(node.getAttribute(expected_name), "test"); + } else if (name !== ascii_lowercase(name)) { + assert_equals(node.getAttribute(ascii_lowercase(name)), null); + } +} + +function test_get_attribute_ns(namespace, prefix, local_name) { + var qualified_name = prefix ? prefix + ":" + local_name : local_name; + var node = document.createElement("div"); + node.setAttributeNS(namespace, qualified_name, "test"); + var expected_name = local_name; + assert_equals(node.getAttributeNS(namespace, expected_name), "test"); + if (local_name !== ascii_lowercase(local_name)) { + assert_equals(node.getAttributeNS(namespace, ascii_lowercase(local_name)), null); + } +} + +function test_get_elements_tag_name(elements_to_create, search_string) { + var container = document.createElement("div"); + elements_to_create.forEach(function(x) { + var qualified_name = x[1] ? x[1] + ":" + x[2] : x[2]; + var element = document.createElementNS(x[0], qualified_name); + container.appendChild(element); + }); + var expected = Array.prototype.filter.call(container.childNodes, + function(node) { + if (is_html && node.namespaceURI === "http://www.w3.org/1999/xhtml") { + return get_qualified_name(node) === expected_case(search_string); + } else { + return get_qualified_name(node) === search_string; + } + }); + document.documentElement.appendChild(container); + try { + assert_array_equals(document.getElementsByTagName(search_string), expected); + } finally { + document.documentElement.removeChild(container); + } +} + +function test_get_elements_tag_name_ns(elements_to_create, search_input) { + var search_uri = search_input[0]; + var search_name = search_input[1]; + var container = document.createElement("div"); + elements_to_create.forEach(function(x) { + var qualified_name = x[1] ? x[1] + ":" + x[2] : x[2]; + var element = document.createElementNS(x[0], qualified_name); + container.appendChild(element); + }); + var expected = Array.prototype.filter.call(container.childNodes, + function(node) { + return node.namespaceURI === search_uri; + return node.localName === search_name; + }); + document.documentElement.appendChild(container); + try { + assert_array_equals(document.getElementsByTagNameNS(search_uri, search_name), expected); + } catch(e) { + throw e; + } finally { + document.documentElement.removeChild(container); + } +} + +function test_func() { + var func = arguments[0]; + var rest = arguments[1]; + func.apply(this, rest); +} + +generate_tests(test_func, tests); diff --git a/testing/web-platform/tests/dom/nodes/characterset-helper.js b/testing/web-platform/tests/dom/nodes/characterset-helper.js new file mode 100644 index 0000000000..ecbe556ae2 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/characterset-helper.js @@ -0,0 +1,62 @@ +function runCharacterSetTests(encodingMap) { + // Add spaces and mix up case + Object.keys(encodingMap).forEach(function(name) { + var lower = encodingMap[name]; + var upper = encodingMap[name].map(function(s) { return s.toUpperCase() }); + var mixed = encodingMap[name].map(function(s) { + var ret = ""; + for (var i = 0; i < s.length; i += 2) { + ret += s[i].toUpperCase(); + if (i + 1 < s.length) { + ret += s[i + 1]; + } + } + return ret; + }); + var spacey = encodingMap[name].map(function(s) { + return " \t\n\f\r" + s + " \t\n\f\r"; + }); + encodingMap[name] = []; + for (var i = 0; i < lower.length; i++) { + encodingMap[name].push(lower[i]); + /* + if (lower[i] != upper[i]) { + encodingMap[name].push(upper[i]); + } + if (lower[i] != mixed[i] && upper[i] != mixed[i]) { + encodingMap[name].push(mixed[i]); + } + encodingMap[name].push(spacey[i]); + */ + } + }); + + Object.keys(encodingMap).forEach(function(name) { + encodingMap[name].forEach(function(label) { + var iframe = document.createElement("iframe"); + var t = async_test("Name " + format_value(name) + + " has label " + format_value(label) + " (characterSet)"); + var t2 = async_test("Name " + format_value(name) + + " has label " + format_value(label) + " (inputEncoding)"); + var t3 = async_test("Name " + format_value(name) + + " has label " + format_value(label) + " (charset)"); + iframe.src = "encoding.py?label=" + label; + iframe.onload = function() { + t.step(function() { + assert_equals(iframe.contentDocument.characterSet, name); + }); + t2.step(function() { + assert_equals(iframe.contentDocument.inputEncoding, name); + }); + t3.step(function() { + assert_equals(iframe.contentDocument.charset, name); + }); + document.body.removeChild(iframe); + t.done(); + t2.done(); + t3.done(); + }; + document.body.appendChild(iframe); + }); + }); +} \ No newline at end of file diff --git a/testing/web-platform/tests/dom/nodes/creators.js b/testing/web-platform/tests/dom/nodes/creators.js new file mode 100644 index 0000000000..8b7415d13f --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/creators.js @@ -0,0 +1,5 @@ +var creators = { + "element": "createElement", + "text": "createTextNode", + "comment": "createComment" +}; diff --git a/testing/web-platform/tests/dom/nodes/encoding.py b/testing/web-platform/tests/dom/nodes/encoding.py new file mode 100644 index 0000000000..15edff7061 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/encoding.py @@ -0,0 +1,7 @@ +from html import escape + +from wptserve.utils import isomorphic_decode + +def main(request, response): + label = request.GET.first(b'label') + return u"""""" % escape(isomorphic_decode(label)) diff --git a/testing/web-platform/tests/dom/nodes/getElementsByClassName-01.htm b/testing/web-platform/tests/dom/nodes/getElementsByClassName-01.htm new file mode 100644 index 0000000000..457d6c400f --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/getElementsByClassName-01.htm @@ -0,0 +1,13 @@ + + + + document.getElementsByClassName(): simple + + + + +
      + + + diff --git a/testing/web-platform/tests/dom/nodes/getElementsByClassName-02.htm b/testing/web-platform/tests/dom/nodes/getElementsByClassName-02.htm new file mode 100644 index 0000000000..d5e513fa88 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/getElementsByClassName-02.htm @@ -0,0 +1,14 @@ + + + + document.getElementsByClassName(): also simple + + + + +
      + + + diff --git a/testing/web-platform/tests/dom/nodes/getElementsByClassName-03.htm b/testing/web-platform/tests/dom/nodes/getElementsByClassName-03.htm new file mode 100644 index 0000000000..a9e2d3af1a --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/getElementsByClassName-03.htm @@ -0,0 +1,18 @@ + + + + document.getElementsByClassName(): changing classes + + + + +
      + + + diff --git a/testing/web-platform/tests/dom/nodes/getElementsByClassName-04.htm b/testing/web-platform/tests/dom/nodes/getElementsByClassName-04.htm new file mode 100644 index 0000000000..0c62fed2c5 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/getElementsByClassName-04.htm @@ -0,0 +1,18 @@ + + + + document.getElementsByClassName(): changing classes + + + + +
      + + + diff --git a/testing/web-platform/tests/dom/nodes/getElementsByClassName-05.htm b/testing/web-platform/tests/dom/nodes/getElementsByClassName-05.htm new file mode 100644 index 0000000000..98245f6427 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/getElementsByClassName-05.htm @@ -0,0 +1,18 @@ + + + + document.getElementsByClassName(): changing classes + + + + +
      + + + diff --git a/testing/web-platform/tests/dom/nodes/getElementsByClassName-06.htm b/testing/web-platform/tests/dom/nodes/getElementsByClassName-06.htm new file mode 100644 index 0000000000..4975a89e09 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/getElementsByClassName-06.htm @@ -0,0 +1,20 @@ + + + + document.getElementsByClassName(): adding element with class + + + + +
      + + + diff --git a/testing/web-platform/tests/dom/nodes/getElementsByClassName-07.htm b/testing/web-platform/tests/dom/nodes/getElementsByClassName-07.htm new file mode 100644 index 0000000000..b0102fb2e6 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/getElementsByClassName-07.htm @@ -0,0 +1,15 @@ + + + + document.getElementsByClassName(): multiple classes + + + + +
      + + + diff --git a/testing/web-platform/tests/dom/nodes/getElementsByClassName-08.htm b/testing/web-platform/tests/dom/nodes/getElementsByClassName-08.htm new file mode 100644 index 0000000000..a248af4929 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/getElementsByClassName-08.htm @@ -0,0 +1,15 @@ + + + + document.getElementsByClassName(): multiple classes + + + + +
      + + + diff --git a/testing/web-platform/tests/dom/nodes/getElementsByClassName-09.htm b/testing/web-platform/tests/dom/nodes/getElementsByClassName-09.htm new file mode 100644 index 0000000000..9011f3068c --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/getElementsByClassName-09.htm @@ -0,0 +1,15 @@ + + + + document.getElementsByClassName(): case sensitive + + + + +
      + + + diff --git a/testing/web-platform/tests/dom/nodes/getElementsByClassName-10.xml b/testing/web-platform/tests/dom/nodes/getElementsByClassName-10.xml new file mode 100644 index 0000000000..b3e3122cb0 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/getElementsByClassName-10.xml @@ -0,0 +1,19 @@ + + + document.getElementsByClassName(): compound + + + + +
      +
      + + +
      + + + diff --git a/testing/web-platform/tests/dom/nodes/getElementsByClassName-11.xml b/testing/web-platform/tests/dom/nodes/getElementsByClassName-11.xml new file mode 100644 index 0000000000..8593fa7a0e --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/getElementsByClassName-11.xml @@ -0,0 +1,24 @@ + + + document.getElementsByClassName(): "tricky" compound + + + + +
      +
      + + + + + +
      + + + diff --git a/testing/web-platform/tests/dom/nodes/getElementsByClassName-12.htm b/testing/web-platform/tests/dom/nodes/getElementsByClassName-12.htm new file mode 100644 index 0000000000..3b7f328b47 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/getElementsByClassName-12.htm @@ -0,0 +1,15 @@ + + + + element.getElementsByClassName(): simple + + + + +
      + + + diff --git a/testing/web-platform/tests/dom/nodes/getElementsByClassName-13.htm b/testing/web-platform/tests/dom/nodes/getElementsByClassName-13.htm new file mode 100644 index 0000000000..f3af106aed --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/getElementsByClassName-13.htm @@ -0,0 +1,19 @@ + + + + element.getElementsByClassName(): adding an element + + + + +
      + + + diff --git a/testing/web-platform/tests/dom/nodes/getElementsByClassName-14.htm b/testing/web-platform/tests/dom/nodes/getElementsByClassName-14.htm new file mode 100644 index 0000000000..83addb7ba5 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/getElementsByClassName-14.htm @@ -0,0 +1,26 @@ + + + + document.getElementsByClassName(): case-insensitive (quirks mode) + + + + + +
      +
      +
      +
      + + + diff --git a/testing/web-platform/tests/dom/nodes/getElementsByClassName-15.htm b/testing/web-platform/tests/dom/nodes/getElementsByClassName-15.htm new file mode 100644 index 0000000000..89614de30d --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/getElementsByClassName-15.htm @@ -0,0 +1,18 @@ + + + + document.getElementsByClassName(array): "a\n" + + + + +
      + + + diff --git a/testing/web-platform/tests/dom/nodes/getElementsByClassName-16.htm b/testing/web-platform/tests/dom/nodes/getElementsByClassName-16.htm new file mode 100644 index 0000000000..3f987a7ae0 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/getElementsByClassName-16.htm @@ -0,0 +1,16 @@ + + + + document.getElementsByClassName(array): "b","a" + + + + +
      + + + diff --git a/testing/web-platform/tests/dom/nodes/getElementsByClassName-17.htm b/testing/web-platform/tests/dom/nodes/getElementsByClassName-17.htm new file mode 100644 index 0000000000..ae5ebda6e2 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/getElementsByClassName-17.htm @@ -0,0 +1,15 @@ + + + + document.getElementsByClassName(array): "b a" + + + + +
      + + + diff --git a/testing/web-platform/tests/dom/nodes/getElementsByClassName-18.htm b/testing/web-platform/tests/dom/nodes/getElementsByClassName-18.htm new file mode 100644 index 0000000000..9f6cf75a50 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/getElementsByClassName-18.htm @@ -0,0 +1,17 @@ + + + + element.getElementsByClassName(array): "a", "b" + + + + +
      +

      + + + diff --git a/testing/web-platform/tests/dom/nodes/getElementsByClassName-19.htm b/testing/web-platform/tests/dom/nodes/getElementsByClassName-19.htm new file mode 100644 index 0000000000..da233c743a --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/getElementsByClassName-19.htm @@ -0,0 +1,54 @@ + + + getElementsByClassName + + + + + + +
      +
      + + text +
      + + + + + + + + + + + + + + + + + + + + + + + +
      text caption
      TEXT head
      td text1
      td text
      td te xt
      TEXT foot
      +
      xt te
      + + + diff --git a/testing/web-platform/tests/dom/nodes/getElementsByClassName-20.htm b/testing/web-platform/tests/dom/nodes/getElementsByClassName-20.htm new file mode 100644 index 0000000000..6429e37bb5 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/getElementsByClassName-20.htm @@ -0,0 +1,61 @@ + + + getElementsByClassName + + + + + + +
      +
      + + text +
      + + + + + + + + + + + + + + + + + + + + + + + +
      text caption
      TEXT head
      td text1
      td text
      td te xt
      TEXT foot
      +
      xt te
      + + + diff --git a/testing/web-platform/tests/dom/nodes/getElementsByClassName-21.htm b/testing/web-platform/tests/dom/nodes/getElementsByClassName-21.htm new file mode 100644 index 0000000000..339ff2d3e1 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/getElementsByClassName-21.htm @@ -0,0 +1,52 @@ + + + getElementsByClassName + + + + + + +
      +
      + + text +
      + + + + + + + + + + + + + + + + + + + + + + + +
      text caption
      TEXT head
      td text1
      td text
      td te xt
      TEXT foot
      +
      xt te
      + + + diff --git a/testing/web-platform/tests/dom/nodes/getElementsByClassName-22.htm b/testing/web-platform/tests/dom/nodes/getElementsByClassName-22.htm new file mode 100644 index 0000000000..c203967007 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/getElementsByClassName-22.htm @@ -0,0 +1,58 @@ + + + getElementsByClassName + + + + + + +
      +
      + + text +
      + + + + + + + + + + + + + + + + + + + + + + + +
      text caption
      TEXT head
      td text1
      td text
      td te xt
      TEXT foot
      +
      xt te
      + + + diff --git a/testing/web-platform/tests/dom/nodes/getElementsByClassName-23.htm b/testing/web-platform/tests/dom/nodes/getElementsByClassName-23.htm new file mode 100644 index 0000000000..0af8a09952 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/getElementsByClassName-23.htm @@ -0,0 +1,52 @@ + + + getElementsByClassName + + + + + + +
      +
      + + text +
      + + + + + + + + + + + + + + + + + + + + + + + +
      text caption
      TEXT head
      td text1
      td text
      td te xt
      TEXT foot
      +
      xt te
      + + + diff --git a/testing/web-platform/tests/dom/nodes/getElementsByClassName-24.htm b/testing/web-platform/tests/dom/nodes/getElementsByClassName-24.htm new file mode 100644 index 0000000000..838987ad0c --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/getElementsByClassName-24.htm @@ -0,0 +1,30 @@ + + + + getElementsByClassName + + + + + + +
      +
      + + text +
      +
      ΔЙあ叶葉 קم
      + + + + diff --git a/testing/web-platform/tests/dom/nodes/getElementsByClassName-25.htm b/testing/web-platform/tests/dom/nodes/getElementsByClassName-25.htm new file mode 100644 index 0000000000..21f2a9ff7a --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/getElementsByClassName-25.htm @@ -0,0 +1,57 @@ + + + getElementsByClassName + + + + + + +
      +
      + + text +
      + + + + + + + + + + + + + + + + + + + + + + + +
      text caption
      TEXT head
      td text1
      td text
      td te xt
      TEXT foot
      +
      xt te
      + + + diff --git a/testing/web-platform/tests/dom/nodes/getElementsByClassName-26.htm b/testing/web-platform/tests/dom/nodes/getElementsByClassName-26.htm new file mode 100644 index 0000000000..0d7ff1ba1f --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/getElementsByClassName-26.htm @@ -0,0 +1,30 @@ + + + getElementsByClassName + + + + + + +
      +
      + te xt +
      + te; xt + test link #foo +
      + text +
      +
      xt te
      + + diff --git a/testing/web-platform/tests/dom/nodes/getElementsByClassName-27.htm b/testing/web-platform/tests/dom/nodes/getElementsByClassName-27.htm new file mode 100644 index 0000000000..95fc674428 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/getElementsByClassName-27.htm @@ -0,0 +1,32 @@ + + + getElementsByClassName + + + + + + +
      +
      + te xt +
      + te; xt + test link #foo + dummy tag +
      + text +
      +
      xt te
      + + diff --git a/testing/web-platform/tests/dom/nodes/getElementsByClassName-28.htm b/testing/web-platform/tests/dom/nodes/getElementsByClassName-28.htm new file mode 100644 index 0000000000..1fc94d807c --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/getElementsByClassName-28.htm @@ -0,0 +1,31 @@ + + + getElementsByClassName + + + + + + +
      +
      + te xt +
      + te; xt + test link #foo + te xt namespace +
      + text +
      +
      xt te
      + + diff --git a/testing/web-platform/tests/dom/nodes/getElementsByClassName-29.htm b/testing/web-platform/tests/dom/nodes/getElementsByClassName-29.htm new file mode 100644 index 0000000000..ad489752cc --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/getElementsByClassName-29.htm @@ -0,0 +1,51 @@ + + + getElementsByClassName + + + + + + +
      +
      + + text +
      + + + + + + + + + + + + + + + + + + + + + + + +
      text caption
      TEXT head
      td text1
      td text
      td te xt
      TEXT foot
      +
      xt te
      + + + diff --git a/testing/web-platform/tests/dom/nodes/getElementsByClassName-30.htm b/testing/web-platform/tests/dom/nodes/getElementsByClassName-30.htm new file mode 100644 index 0000000000..c0b4faf2d4 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/getElementsByClassName-30.htm @@ -0,0 +1,190 @@ + + + getElementsByClassName + + + + + + + + + + +
      + a + abbr + acronym +
      address
      + applet + b + bdo + big +
      blockquote
      +
      + +
      center
      + cite + code + del + dfn + dir +
    • li
    • +
      +
      div
      +
      +
      +
      dd
      +
      + em + font +
      + +
      + legend +
      +
      +

      h1

      +
      + i + + + + ins + kbd + + + + menu + + + + +
        ol
      +

      p

      +
      pre
      + q + s + samp + + small + span + strike + strong + sub + sup + colgroup + + + + + + + + + + + + +
      caption
      th
      td
      + + tt + u +
        ul
      + var + + diff --git a/testing/web-platform/tests/dom/nodes/getElementsByClassName-31.htm b/testing/web-platform/tests/dom/nodes/getElementsByClassName-31.htm new file mode 100644 index 0000000000..0e1ac014ae --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/getElementsByClassName-31.htm @@ -0,0 +1,22 @@ + + + +getElementsByClassName across documents + + + +
      + diff --git a/testing/web-platform/tests/dom/nodes/getElementsByClassName-32.html b/testing/web-platform/tests/dom/nodes/getElementsByClassName-32.html new file mode 100644 index 0000000000..29eb41353c --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/getElementsByClassName-32.html @@ -0,0 +1,68 @@ + + + +Node.prototype.getElementsByClassName tests imported from jsdom + + + + +
      +
      +
      +
      +
      +
      + + diff --git a/testing/web-platform/tests/dom/nodes/getElementsByClassName-empty-set.html b/testing/web-platform/tests/dom/nodes/getElementsByClassName-empty-set.html new file mode 100644 index 0000000000..75b8d5a9f8 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/getElementsByClassName-empty-set.html @@ -0,0 +1,29 @@ + + + +Node.prototype.getElementsByClassName with no real class names + + + + +test + + diff --git a/testing/web-platform/tests/dom/nodes/getElementsByClassName-whitespace-class-names.html b/testing/web-platform/tests/dom/nodes/getElementsByClassName-whitespace-class-names.html new file mode 100644 index 0000000000..59bfd2e6b1 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/getElementsByClassName-whitespace-class-names.html @@ -0,0 +1,50 @@ + + + +Node.prototype.getElementsByClassName with no real class names + + + + +LINE TABULATION +NEXT LINE +NO-BREAK SPACE +OGHAM SPACE MARK +EN QUAD +EM QUAD +EN SPACE +EM SPACE +THREE-PER-EM SPACE +FOUR-PER-EM SPACE +SIX-PER-EM SPACE +FIGURE SPACE +PUNCTUATION SPACE +THIN SPACE +HAIR SPACE +LINE SEPARATOR +PARAGRAPH SEPARATOR +NARROW NO-BREAK SPACE +MEDIUM MATHEMATICAL SPACE +IDEOGRAPHIC SPACE + +MONGOLIAN VOWEL SEPARATOR +ZERO WIDTH SPACE +ZERO WIDTH NON-JOINER +ZERO WIDTH JOINER +WORD JOINER +ZERO WIDTH NON-BREAKING SPACE + + diff --git a/testing/web-platform/tests/dom/nodes/getElementsByClassNameFrame.htm b/testing/web-platform/tests/dom/nodes/getElementsByClassNameFrame.htm new file mode 100644 index 0000000000..544df60a99 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/getElementsByClassNameFrame.htm @@ -0,0 +1,6 @@ + + + + +getElementsByClassName + diff --git a/testing/web-platform/tests/dom/nodes/insert-adjacent.html b/testing/web-platform/tests/dom/nodes/insert-adjacent.html new file mode 100644 index 0000000000..68b6f4ee66 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/insert-adjacent.html @@ -0,0 +1,79 @@ + + + + + + + +
      +
      + + diff --git a/testing/web-platform/tests/dom/nodes/mutationobservers.js b/testing/web-platform/tests/dom/nodes/mutationobservers.js new file mode 100644 index 0000000000..a95529ab39 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/mutationobservers.js @@ -0,0 +1,76 @@ +// Compares a mutation record to a predefined one +// mutationToCheck is a mutation record from the user agent +// expectedRecord is a mutation record minted by the test +// for expectedRecord, if properties are omitted, they get default ones +function checkRecords(target, mutationToCheck, expectedRecord) { + var mr1; + var mr2; + + + function checkField(property, isArray) { + var field = mr2[property]; + if (isArray === undefined) { + isArray = false; + } + if (field instanceof Function) { + field = field(); + } else if (field === undefined) { + if (isArray) { + field = new Array(); + } else { + field = null; + } + } + if (isArray) { + assert_array_equals(mr1[property], field, property + " didn't match"); + } else { + assert_equals(mr1[property], field, property + " didn't match"); + } + } + + assert_equals(mutationToCheck.length, expectedRecord.length, "mutation records must match"); + for (var item = 0; item < mutationToCheck.length; item++) { + mr1 = mutationToCheck[item]; + mr2 = expectedRecord[item]; + + if (mr2.target instanceof Function) { + assert_equals(mr1.target, mr2.target(), "target node must match"); + } else if (mr2.target !== undefined) { + assert_equals(mr1.target, mr2.target, "target node must match"); + } else { + assert_equals(mr1.target, target, "target node must match"); + } + + checkField("type"); + checkField("addedNodes", true); + checkField("removedNodes", true); + checkField("previousSibling"); + checkField("nextSibling"); + checkField("attributeName"); + checkField("attributeNamespace"); + checkField("oldValue"); + }; +} + +function runMutationTest(node, mutationObserverOptions, mutationRecordSequence, mutationFunction, description, target) { + var test = async_test(description); + + + function moc(mrl, obs) { + test.step( + function () { + if (target === undefined) target = node; + checkRecords(target, mrl, mutationRecordSequence); + test.done(); + } + ); + } + + test.step( + function () { + (new MutationObserver(moc)).observe(node, mutationObserverOptions); + mutationFunction(); + } + ); + return mutationRecordSequence.length +} diff --git a/testing/web-platform/tests/dom/nodes/node-appendchild-crash.html b/testing/web-platform/tests/dom/nodes/node-appendchild-crash.html new file mode 100644 index 0000000000..245de87f2d --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/node-appendchild-crash.html @@ -0,0 +1,18 @@ + + + + + + + + + + diff --git a/testing/web-platform/tests/dom/nodes/pre-insertion-validation-hierarchy.js b/testing/web-platform/tests/dom/nodes/pre-insertion-validation-hierarchy.js new file mode 100644 index 0000000000..6ef2576df2 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/pre-insertion-validation-hierarchy.js @@ -0,0 +1,86 @@ +/** + * Validations where `child` argument is irrelevant. + * @param {Function} methodName + */ +function preInsertionValidateHierarchy(methodName) { + function insert(parent, node) { + if (parent[methodName].length > 1) { + // This is for insertBefore(). We can't blindly pass `null` for all methods + // as doing so will move nodes before validation. + parent[methodName](node, null); + } else { + parent[methodName](node); + } + } + + // Step 2 + test(() => { + const doc = document.implementation.createHTMLDocument("title"); + assert_throws_dom("HierarchyRequestError", () => insert(doc.body, doc.body)); + assert_throws_dom("HierarchyRequestError", () => insert(doc.body, doc.documentElement)); + }, "If node is a host-including inclusive ancestor of parent, then throw a HierarchyRequestError DOMException."); + + // Step 4 + test(() => { + const doc = document.implementation.createHTMLDocument("title"); + const doc2 = document.implementation.createHTMLDocument("title2"); + assert_throws_dom("HierarchyRequestError", () => insert(doc, doc2)); + }, "If node is not a DocumentFragment, DocumentType, Element, Text, ProcessingInstruction, or Comment node, then throw a HierarchyRequestError DOMException."); + + // Step 5, in case of inserting a text node into a document + test(() => { + const doc = document.implementation.createHTMLDocument("title"); + assert_throws_dom("HierarchyRequestError", () => insert(doc, doc.createTextNode("text"))); + }, "If node is a Text node and parent is a document, then throw a HierarchyRequestError DOMException."); + + // Step 5, in case of inserting a doctype into a non-document + test(() => { + const doc = document.implementation.createHTMLDocument("title"); + const doctype = doc.childNodes[0]; + assert_throws_dom("HierarchyRequestError", () => insert(doc.createElement("a"), doctype)); + }, "If node is a doctype and parent is not a document, then throw a HierarchyRequestError DOMException.") + + // Step 6, in case of DocumentFragment including multiple elements + test(() => { + const doc = document.implementation.createHTMLDocument("title"); + doc.documentElement.remove(); + const df = doc.createDocumentFragment(); + df.appendChild(doc.createElement("a")); + df.appendChild(doc.createElement("b")); + assert_throws_dom("HierarchyRequestError", () => insert(doc, df)); + }, "If node is a DocumentFragment with multiple elements and parent is a document, then throw a HierarchyRequestError DOMException."); + + // Step 6, in case of DocumentFragment has multiple elements when document already has an element + test(() => { + const doc = document.implementation.createHTMLDocument("title"); + const df = doc.createDocumentFragment(); + df.appendChild(doc.createElement("a")); + assert_throws_dom("HierarchyRequestError", () => insert(doc, df)); + }, "If node is a DocumentFragment with an element and parent is a document with another element, then throw a HierarchyRequestError DOMException."); + + // Step 6, in case of an element + test(() => { + const doc = document.implementation.createHTMLDocument("title"); + const el = doc.createElement("a"); + assert_throws_dom("HierarchyRequestError", () => insert(doc, el)); + }, "If node is an Element and parent is a document with another element, then throw a HierarchyRequestError DOMException."); + + // Step 6, in case of a doctype when document already has another doctype + test(() => { + const doc = document.implementation.createHTMLDocument("title"); + const doctype = doc.childNodes[0].cloneNode(); + doc.documentElement.remove(); + assert_throws_dom("HierarchyRequestError", () => insert(doc, doctype)); + }, "If node is a doctype and parent is a document with another doctype, then throw a HierarchyRequestError DOMException."); + + // Step 6, in case of a doctype when document has an element + if (methodName !== "prepend") { + // Skip `.prepend` as this doesn't throw if `child` is an element + test(() => { + const doc = document.implementation.createHTMLDocument("title"); + const doctype = doc.childNodes[0].cloneNode(); + doc.childNodes[0].remove(); + assert_throws_dom("HierarchyRequestError", () => insert(doc, doctype)); + }, "If node is a doctype and parent is a document with an element, then throw a HierarchyRequestError DOMException."); + } +} diff --git a/testing/web-platform/tests/dom/nodes/pre-insertion-validation-notfound.js b/testing/web-platform/tests/dom/nodes/pre-insertion-validation-notfound.js new file mode 100644 index 0000000000..705283fa23 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/pre-insertion-validation-notfound.js @@ -0,0 +1,108 @@ +function getNonParentNodes() { + return [ + document.implementation.createDocumentType("html", "", ""), + document.createTextNode("text"), + document.implementation.createDocument(null, "foo", null).createProcessingInstruction("foo", "bar"), + document.createComment("comment"), + document.implementation.createDocument(null, "foo", null).createCDATASection("data"), + ]; +} + +function getNonInsertableNodes() { + return [ + document.implementation.createHTMLDocument("title") + ]; +} + +function getNonDocumentParentNodes() { + return [ + document.createElement("div"), + document.createDocumentFragment(), + ]; +} + +// Test that the steps happen in the right order, to the extent that it's +// observable. The variable names "parent", "child", and "node" match the +// corresponding variables in the replaceChild algorithm in these tests. + +// Step 1 happens before step 3. +test(function() { + var illegalParents = getNonParentNodes(); + var child = document.createElement("div"); + var node = document.createElement("div"); + illegalParents.forEach(function (parent) { + assert_throws_dom("HierarchyRequestError", function() { + insertFunc.call(parent, node, child); + }); + }); +}, "Should check the 'parent' type before checking whether 'child' is a child of 'parent'"); + +// Step 2 happens before step 3. +test(function() { + var parent = document.createElement("div"); + var child = document.createElement("div"); + var node = document.createElement("div"); + + node.appendChild(parent); + assert_throws_dom("HierarchyRequestError", function() { + insertFunc.call(parent, node, child); + }); +}, "Should check that 'node' is not an ancestor of 'parent' before checking whether 'child' is a child of 'parent'"); + +// Step 3 happens before step 4. +test(function() { + var parent = document.createElement("div"); + var child = document.createElement("div"); + + var illegalChildren = getNonInsertableNodes(); + illegalChildren.forEach(function (node) { + assert_throws_dom("NotFoundError", function() { + insertFunc.call(parent, node, child); + }); + }); +}, "Should check whether 'child' is a child of 'parent' before checking whether 'node' is of a type that can have a parent."); + + +// Step 3 happens before step 5. +test(function() { + var child = document.createElement("div"); + + var node = document.createTextNode(""); + var parent = document.implementation.createDocument(null, "foo", null); + assert_throws_dom("NotFoundError", function() { + insertFunc.call(parent, node, child); + }); + + node = document.implementation.createDocumentType("html", "", ""); + getNonDocumentParentNodes().forEach(function (parent) { + assert_throws_dom("NotFoundError", function() { + insertFunc.call(parent, node, child); + }); + }); +}, "Should check whether 'child' is a child of 'parent' before checking whether 'node' is of a type that can have a parent of the type that 'parent' is."); + +// Step 3 happens before step 6. +test(function() { + var child = document.createElement("div"); + var parent = document.implementation.createDocument(null, null, null); + + var node = document.createDocumentFragment(); + node.appendChild(document.createElement("div")); + node.appendChild(document.createElement("div")); + assert_throws_dom("NotFoundError", function() { + insertFunc.call(parent, node, child); + }); + + node = document.createElement("div"); + parent.appendChild(document.createElement("div")); + assert_throws_dom("NotFoundError", function() { + insertFunc.call(parent, node, child); + }); + + parent.firstChild.remove(); + parent.appendChild(document.implementation.createDocumentType("html", "", "")); + node = document.implementation.createDocumentType("html", "", "") + assert_throws_dom("NotFoundError", function() { + insertFunc.call(parent, node, child); + }); +}, "Should check whether 'child' is a child of 'parent' before checking whether 'node' can be inserted into the document given the kids the document has right now."); diff --git a/testing/web-platform/tests/dom/nodes/prepend-on-Document.html b/testing/web-platform/tests/dom/nodes/prepend-on-Document.html new file mode 100644 index 0000000000..1d6d43a463 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/prepend-on-Document.html @@ -0,0 +1,53 @@ + + +DocumentType.prepend + + + + + diff --git a/testing/web-platform/tests/dom/nodes/productions.js b/testing/web-platform/tests/dom/nodes/productions.js new file mode 100644 index 0000000000..218797fc45 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/productions.js @@ -0,0 +1,3 @@ +var invalid_names = ["", "invalid^Name", "\\", "'", '"', "0", "0:a"] // XXX +var valid_names = ["x", "X", ":", "a:0"] +var invalid_qnames = [":a", "b:", "x:y:z"] // XXX diff --git a/testing/web-platform/tests/dom/nodes/query-target-in-load-event.html b/testing/web-platform/tests/dom/nodes/query-target-in-load-event.html new file mode 100644 index 0000000000..2835286f96 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/query-target-in-load-event.html @@ -0,0 +1,13 @@ + + + + + + diff --git a/testing/web-platform/tests/dom/nodes/query-target-in-load-event.part.html b/testing/web-platform/tests/dom/nodes/query-target-in-load-event.part.html new file mode 100644 index 0000000000..7eb1baf15f --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/query-target-in-load-event.part.html @@ -0,0 +1,10 @@ + + + +
      diff --git a/testing/web-platform/tests/dom/nodes/remove-and-adopt-thcrash.html b/testing/web-platform/tests/dom/nodes/remove-and-adopt-thcrash.html new file mode 100644 index 0000000000..d37015ec9f --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/remove-and-adopt-thcrash.html @@ -0,0 +1,18 @@ + +Test for a Chrome crash when adopting a node into another document + + + +
      +
      + diff --git a/testing/web-platform/tests/dom/nodes/remove-from-shadow-host-and-adopt-into-iframe-ref.html b/testing/web-platform/tests/dom/nodes/remove-from-shadow-host-and-adopt-into-iframe-ref.html new file mode 100644 index 0000000000..98de2b6883 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/remove-from-shadow-host-and-adopt-into-iframe-ref.html @@ -0,0 +1,4 @@ + +DOM Test Reference +

      You should see the word PASS below.

      +
      PASS
      diff --git a/testing/web-platform/tests/dom/nodes/remove-from-shadow-host-and-adopt-into-iframe.html b/testing/web-platform/tests/dom/nodes/remove-from-shadow-host-and-adopt-into-iframe.html new file mode 100644 index 0000000000..612aed637d --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/remove-from-shadow-host-and-adopt-into-iframe.html @@ -0,0 +1,29 @@ + + + + Adopting a shadow host child into an iframe + + + + + + + +

      You should see the word PASS below.

      + +
      PASS
      + + diff --git a/testing/web-platform/tests/dom/nodes/remove-unscopable.html b/testing/web-platform/tests/dom/nodes/remove-unscopable.html new file mode 100644 index 0000000000..0238b0fa97 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/remove-unscopable.html @@ -0,0 +1,32 @@ + + + + + +
      + diff --git a/testing/web-platform/tests/dom/nodes/rootNode.html b/testing/web-platform/tests/dom/nodes/rootNode.html new file mode 100644 index 0000000000..784831da0e --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/rootNode.html @@ -0,0 +1,96 @@ + + + + +Node.prototype.getRootNode() + + + + + + + + diff --git a/testing/web-platform/tests/dom/nodes/selectors.js b/testing/web-platform/tests/dom/nodes/selectors.js new file mode 100644 index 0000000000..5e05547c9a --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/selectors.js @@ -0,0 +1,755 @@ +// Bit-mapped flags to indicate which tests the selector is suitable for +var TEST_QSA = 0x01; // querySelector() and querySelectorAll() tests +var TEST_FIND = 0x04; // find() and findAll() tests, may be unsuitable for querySelector[All] +var TEST_MATCH = 0x10; // matches() tests + +/* + * All of these invalid selectors should result in a SyntaxError being thrown by the APIs. + * + * name: A descriptive name of the selector being tested + * selector: The selector to test + */ +var invalidSelectors = [ + {name: "Empty String", selector: ""}, + {name: "Invalid character", selector: "["}, + {name: "Invalid character", selector: "]"}, + {name: "Invalid character", selector: "("}, + {name: "Invalid character", selector: ")"}, + {name: "Invalid character", selector: "{"}, + {name: "Invalid character", selector: "}"}, + {name: "Invalid character", selector: "<"}, + {name: "Invalid character", selector: ">"}, + {name: "Invalid ID", selector: "#"}, + {name: "Invalid group of selectors", selector: "div,"}, + {name: "Invalid class", selector: "."}, + {name: "Invalid class", selector: ".5cm"}, + {name: "Invalid class", selector: "..test"}, + {name: "Invalid class", selector: ".foo..quux"}, + {name: "Invalid class", selector: ".bar."}, + {name: "Invalid combinator", selector: "div % address, p"}, + {name: "Invalid combinator", selector: "div ++ address, p"}, + {name: "Invalid combinator", selector: "div ~~ address, p"}, + {name: "Invalid [att=value] selector", selector: "[*=test]"}, + {name: "Invalid [att=value] selector", selector: "[*|*=test]"}, + {name: "Invalid [att=value] selector", selector: "[class= space unquoted ]"}, + {name: "Unknown pseudo-class", selector: "div:example"}, + {name: "Unknown pseudo-class", selector: ":example"}, + {name: "Unknown pseudo-class", selector: "div:linkexample"}, + {name: "Unknown pseudo-element", selector: "div::example"}, + {name: "Unknown pseudo-element", selector: "::example"}, + {name: "Invalid pseudo-element", selector: ":::before"}, + {name: "Invalid pseudo-element", selector: ":: before"}, + {name: "Undeclared namespace", selector: "ns|div"}, + {name: "Undeclared namespace", selector: ":not(ns|div)"}, + {name: "Invalid namespace", selector: "^|div"}, + {name: "Invalid namespace", selector: "$|div"}, + {name: "Relative selector", selector: ">*"}, +]; + +/* + * All of these should be valid selectors, expected to match zero or more elements in the document. + * None should throw any errors. + * + * name: A descriptive name of the selector being tested + * selector: The selector to test + * expect: A list of IDs of the elements expected to be matched. List must be given in tree order. + * exclude: An array of contexts to exclude from testing. The valid values are: + * ["document", "element", "fragment", "detached", "html", "xhtml"] + * The "html" and "xhtml" values represent the type of document being queried. These are useful + * for tests that are affected by differences between HTML and XML, such as case sensitivity. + * level: An integer indicating the CSS or Selectors level in which the selector being tested was introduced. + * testType: A bit-mapped flag indicating the type of test. + * + * Note: Interactive pseudo-classes (:active :hover and :focus) have not been tested in this test suite. + */ +var validSelectors = [ + // Type Selector + {name: "Type selector, matching html element", selector: "html", expect: ["html"], exclude: ["element", "fragment", "detached"], level: 1, testType: TEST_QSA | TEST_MATCH}, + {name: "Type selector, matching html element", selector: "html", expect: [] /*no matches*/, exclude: ["document"], level: 1, testType: TEST_QSA}, + {name: "Type selector, matching body element", selector: "body", expect: ["body"], exclude: ["element", "fragment", "detached"], level: 1, testType: TEST_QSA | TEST_MATCH}, + {name: "Type selector, matching body element", selector: "body", expect: [] /*no matches*/, exclude: ["document"], level: 1, testType: TEST_QSA}, + + // Universal Selector + {name: "Universal selector, matching all elements", selector: "*", expect: ["universal", "universal-p1", "universal-code1", "universal-hr1", "universal-pre1", "universal-span1", "universal-p2", "universal-a1", "universal-address1", "universal-code2", "universal-a2"], level: 2, testType: TEST_MATCH}, + {name: "Universal selector, matching all children of element with specified ID", selector: "#universal>*", expect: ["universal-p1", "universal-hr1", "universal-pre1", "universal-p2", "universal-address1"], level: 2, testType: TEST_QSA | TEST_MATCH}, + {name: "Universal selector, matching all grandchildren of element with specified ID", selector: "#universal>*>*", expect: ["universal-code1", "universal-span1", "universal-a1", "universal-code2"], level: 2, testType: TEST_QSA | TEST_MATCH}, + {name: "Universal selector, matching all children of empty element with specified ID", selector: "#empty>*", expect: [] /*no matches*/, level: 2, testType: TEST_QSA}, + {name: "Universal selector, matching all descendants of element with specified ID", selector: "#universal *", expect: ["universal-p1", "universal-code1", "universal-hr1", "universal-pre1", "universal-span1", "universal-p2", "universal-a1", "universal-address1", "universal-code2", "universal-a2"], level: 2, testType: TEST_QSA | TEST_MATCH}, + + // Attribute Selectors + // - presence [att] + {name: "Attribute presence selector, matching align attribute with value", selector: ".attr-presence-div1[align]", expect: ["attr-presence-div1"], level: 2, testType: TEST_QSA | TEST_MATCH}, + {name: "Attribute presence selector, matching align attribute with empty value", selector: ".attr-presence-div2[align]", expect: ["attr-presence-div2"], level: 2, testType: TEST_QSA | TEST_MATCH}, + {name: "Attribute presence selector, matching title attribute, case insensitivity", selector: "#attr-presence [*|TiTlE]", expect: ["attr-presence-a1", "attr-presence-span1", "attr-presence-i1"], exclude: ["xhtml"], level: 2, testType: TEST_QSA | TEST_MATCH}, + {name: "Attribute presence selector, not matching title attribute, case sensitivity", selector: "#attr-presence [*|TiTlE]", expect: [], exclude: ["html"], level: 2, testType: TEST_QSA | TEST_MATCH}, + {name: "Attribute presence selector, matching custom data-* attribute", selector: "[data-attr-presence]", expect: ["attr-presence-pre1", "attr-presence-blockquote1"], level: 2, testType: TEST_QSA | TEST_MATCH}, + {name: "Attribute presence selector, not matching attribute with similar name", selector: ".attr-presence-div3[align], .attr-presence-div4[align]", expect: [] /*no matches*/, level: 2, testType: TEST_QSA}, + {name: "Attribute presence selector, matching attribute with non-ASCII characters", selector: "ul[data-中文]", expect: ["attr-presence-ul1"], level: 2, testType: TEST_QSA | TEST_MATCH}, + {name: "Attribute presence selector, not matching default option without selected attribute", selector: "#attr-presence-select1 option[selected]", expect: [] /* no matches */, level: 2, testType: TEST_QSA}, + {name: "Attribute presence selector, matching option with selected attribute", selector: "#attr-presence-select2 option[selected]", expect: ["attr-presence-select2-option4"], level: 2, testType: TEST_QSA | TEST_MATCH}, + {name: "Attribute presence selector, matching multiple options with selected attributes", selector: "#attr-presence-select3 option[selected]", expect: ["attr-presence-select3-option2", "attr-presence-select3-option3"], level: 2, testType: TEST_QSA | TEST_MATCH}, + + // - value [att=val] + {name: "Attribute value selector, matching align attribute with value", selector: "#attr-value [align=\"center\"]", expect: ["attr-value-div1"], level: 2, testType: TEST_QSA | TEST_MATCH}, + {name: "Attribute value selector, matching align attribute with value, unclosed bracket", selector: "#attr-value [align=\"center\"", expect: ["attr-value-div1"], level: 2, testType: TEST_QSA | TEST_MATCH}, + {name: "Attribute value selector, matching align attribute with empty value", selector: "#attr-value [align=\"\"]", expect: ["attr-value-div2"], level: 2, testType: TEST_QSA | TEST_MATCH}, + {name: "Attribute value selector, not matching align attribute with partial value", selector: "#attr-value [align=\"c\"]", expect: [] /*no matches*/, level: 2, testType: TEST_QSA}, + {name: "Attribute value selector, not matching align attribute with incorrect value", selector: "#attr-value [align=\"centera\"]", expect: [] /*no matches*/, level: 2, testType: TEST_QSA}, + {name: "Attribute value selector, matching custom data-* attribute with unicode escaped value", selector: "[data-attr-value=\"\\e9\"]", expect: ["attr-value-div3"], level: 2, testType: TEST_QSA | TEST_MATCH}, + {name: "Attribute value selector, matching custom data-* attribute with escaped character", selector: "[data-attr-value\_foo=\"\\e9\"]", expect: ["attr-value-div4"], level: 2, testType: TEST_QSA | TEST_MATCH}, + {name: "Attribute value selector with single-quoted value, matching multiple inputs with type attributes", selector: "#attr-value input[type='hidden'],#attr-value input[type='radio']", expect: ["attr-value-input3", "attr-value-input4", "attr-value-input6", "attr-value-input8", "attr-value-input9"], level: 2, testType: TEST_QSA | TEST_MATCH}, + {name: "Attribute value selector with double-quoted value, matching multiple inputs with type attributes", selector: "#attr-value input[type=\"hidden\"],#attr-value input[type='radio']", expect: ["attr-value-input3", "attr-value-input4", "attr-value-input6", "attr-value-input8", "attr-value-input9"], level: 2, testType: TEST_QSA | TEST_MATCH}, + {name: "Attribute value selector with unquoted value, matching multiple inputs with type attributes", selector: "#attr-value input[type=hidden],#attr-value input[type=radio]", expect: ["attr-value-input3", "attr-value-input4", "attr-value-input6", "attr-value-input8", "attr-value-input9"], level: 2, testType: TEST_QSA | TEST_MATCH}, + {name: "Attribute value selector, matching attribute with value using non-ASCII characters", selector: "[data-attr-value=中文]", expect: ["attr-value-div5"], level: 2, testType: TEST_QSA | TEST_MATCH}, + + // - whitespace-separated list [att~=val] + {name: "Attribute whitespace-separated list selector, matching class attribute with value", selector: "#attr-whitespace [class~=\"div1\"]", expect: ["attr-whitespace-div1"], level: 2, testType: TEST_QSA | TEST_MATCH}, + {name: "Attribute whitespace-separated list selector, not matching class attribute with empty value", selector: "#attr-whitespace [class~=\"\"]", expect: [] /*no matches*/ , level: 2, testType: TEST_QSA}, + {name: "Attribute whitespace-separated list selector, not matching class attribute with partial value", selector: "[data-attr-whitespace~=\"div\"]", expect: [] /*no matches*/ , level: 2, testType: TEST_QSA}, + {name: "Attribute whitespace-separated list selector, matching custom data-* attribute with unicode escaped value", selector: "[data-attr-whitespace~=\"\\0000e9\"]", expect: ["attr-whitespace-div4"], level: 2, testType: TEST_QSA | TEST_MATCH}, + {name: "Attribute whitespace-separated list selector, matching custom data-* attribute with escaped character", selector: "[data-attr-whitespace\_foo~=\"\\e9\"]", expect: ["attr-whitespace-div5"], level: 2, testType: TEST_QSA | TEST_MATCH}, + {name: "Attribute whitespace-separated list selector with single-quoted value, matching multiple links with rel attributes", selector: "#attr-whitespace a[rel~='bookmark'], #attr-whitespace a[rel~='nofollow']", expect: ["attr-whitespace-a1", "attr-whitespace-a2", "attr-whitespace-a3", "attr-whitespace-a5", "attr-whitespace-a7"], level: 2, testType: TEST_QSA | TEST_MATCH}, + {name: "Attribute whitespace-separated list selector with double-quoted value, matching multiple links with rel attributes", selector: "#attr-whitespace a[rel~=\"bookmark\"],#attr-whitespace a[rel~='nofollow']", expect: ["attr-whitespace-a1", "attr-whitespace-a2", "attr-whitespace-a3", "attr-whitespace-a5", "attr-whitespace-a7"], level: 2, testType: TEST_QSA | TEST_MATCH}, + {name: "Attribute whitespace-separated list selector with unquoted value, matching multiple links with rel attributes", selector: "#attr-whitespace a[rel~=bookmark], #attr-whitespace a[rel~=nofollow]", expect: ["attr-whitespace-a1", "attr-whitespace-a2", "attr-whitespace-a3", "attr-whitespace-a5", "attr-whitespace-a7"], level: 2, testType: TEST_QSA | TEST_MATCH}, + {name: "Attribute whitespace-separated list selector with double-quoted value, not matching value with space", selector: "#attr-whitespace a[rel~=\"book mark\"]", expect: [] /* no matches */, level: 2, testType: TEST_QSA}, + {name: "Attribute whitespace-separated list selector, matching title attribute with value using non-ASCII characters", selector: "#attr-whitespace [title~=中文]", expect: ["attr-whitespace-p1"], level: 2, testType: TEST_QSA | TEST_MATCH}, + + // - hyphen-separated list [att|=val] + {name: "Attribute hyphen-separated list selector, not matching unspecified lang attribute", selector: "#attr-hyphen-div1[lang|=\"en\"]", expect: [] /*no matches*/, level: 2, testType: TEST_QSA}, + {name: "Attribute hyphen-separated list selector, matching lang attribute with exact value", selector: "#attr-hyphen-div2[lang|=\"fr\"]", expect: ["attr-hyphen-div2"], level: 2, testType: TEST_QSA | TEST_MATCH}, + {name: "Attribute hyphen-separated list selector, matching lang attribute with partial value", selector: "#attr-hyphen-div3[lang|=\"en\"]", expect: ["attr-hyphen-div3"], level: 2, testType: TEST_QSA | TEST_MATCH}, + {name: "Attribute hyphen-separated list selector, not matching incorrect value", selector: "#attr-hyphen-div4[lang|=\"es-AR\"]", expect: [] /*no matches*/, level: 2, testType: TEST_QSA}, + + // - substring begins-with [att^=val] (Level 3) + {name: "Attribute begins with selector, matching href attributes beginning with specified substring", selector: "#attr-begins a[href^=\"http://www\"]", expect: ["attr-begins-a1", "attr-begins-a3"], level: 3, testType: TEST_QSA | TEST_MATCH}, + {name: "Attribute begins with selector, matching lang attributes beginning with specified substring, ", selector: "#attr-begins [lang^=\"en-\"]", expect: ["attr-begins-div2", "attr-begins-div4"], level: 3, testType: TEST_QSA | TEST_MATCH}, + {name: "Attribute begins with selector, not matching class attribute with empty value", selector: "#attr-begins [class^=\"\"]", expect: [] /*no matches*/, level: 3, testType: TEST_QSA}, + {name: "Attribute begins with selector, not matching class attribute not beginning with specified substring", selector: "#attr-begins [class^=apple]", expect: [] /*no matches*/, level: 3, testType: TEST_QSA}, + {name: "Attribute begins with selector with single-quoted value, matching class attribute beginning with specified substring", selector: "#attr-begins [class^=' apple']", expect: ["attr-begins-p1"], level: 3, testType: TEST_QSA | TEST_MATCH}, + {name: "Attribute begins with selector with double-quoted value, matching class attribute beginning with specified substring", selector: "#attr-begins [class^=\" apple\"]", expect: ["attr-begins-p1"], level: 3, testType: TEST_QSA | TEST_MATCH}, + {name: "Attribute begins with selector with unquoted value, not matching class attribute not beginning with specified substring", selector: "#attr-begins [class^= apple]", expect: [] /*no matches*/, level: 3, testType: TEST_QSA}, + + // - substring ends-with [att$=val] (Level 3) + {name: "Attribute ends with selector, matching href attributes ending with specified substring", selector: "#attr-ends a[href$=\".org\"]", expect: ["attr-ends-a1", "attr-ends-a3"], level: 3, testType: TEST_QSA | TEST_MATCH}, + {name: "Attribute ends with selector, matching lang attributes ending with specified substring, ", selector: "#attr-ends [lang$=\"-CH\"]", expect: ["attr-ends-div2", "attr-ends-div4"], level: 3, testType: TEST_QSA | TEST_MATCH}, + {name: "Attribute ends with selector, not matching class attribute with empty value", selector: "#attr-ends [class$=\"\"]", expect: [] /*no matches*/, level: 3, testType: TEST_QSA}, + {name: "Attribute ends with selector, not matching class attribute not ending with specified substring", selector: "#attr-ends [class$=apple]", expect: [] /*no matches*/, level: 3, testType: TEST_QSA}, + {name: "Attribute ends with selector with single-quoted value, matching class attribute ending with specified substring", selector: "#attr-ends [class$='apple ']", expect: ["attr-ends-p1"], level: 3, testType: TEST_QSA | TEST_MATCH}, + {name: "Attribute ends with selector with double-quoted value, matching class attribute ending with specified substring", selector: "#attr-ends [class$=\"apple \"]", expect: ["attr-ends-p1"], level: 3, testType: TEST_QSA | TEST_MATCH}, + {name: "Attribute ends with selector with unquoted value, not matching class attribute not ending with specified substring", selector: "#attr-ends [class$=apple ]", expect: [] /*no matches*/, level: 3, testType: TEST_QSA}, + + // - substring contains [att*=val] (Level 3) + {name: "Attribute contains selector, matching href attributes beginning with specified substring", selector: "#attr-contains a[href*=\"http://www\"]", expect: ["attr-contains-a1", "attr-contains-a3"], level: 3, testType: TEST_QSA | TEST_MATCH}, + {name: "Attribute contains selector, matching href attributes ending with specified substring", selector: "#attr-contains a[href*=\".org\"]", expect: ["attr-contains-a1", "attr-contains-a2"], level: 3, testType: TEST_QSA | TEST_MATCH}, + {name: "Attribute contains selector, matching href attributes containing specified substring", selector: "#attr-contains a[href*=\".example.\"]", expect: ["attr-contains-a1", "attr-contains-a3"], level: 3, testType: TEST_QSA | TEST_MATCH}, + {name: "Attribute contains selector, matching lang attributes beginning with specified substring, ", selector: "#attr-contains [lang*=\"en-\"]", expect: ["attr-contains-div2", "attr-contains-div6"], level: 3, testType: TEST_QSA | TEST_MATCH}, + {name: "Attribute contains selector, matching lang attributes ending with specified substring, ", selector: "#attr-contains [lang*=\"-CH\"]", expect: ["attr-contains-div3", "attr-contains-div5"], level: 3, testType: TEST_QSA | TEST_MATCH}, + {name: "Attribute contains selector, not matching class attribute with empty value", selector: "#attr-contains [class*=\"\"]", expect: [] /*no matches*/, level: 3, testType: TEST_QSA}, + {name: "Attribute contains selector with single-quoted value, matching class attribute beginning with specified substring", selector: "#attr-contains [class*=' apple']", expect: ["attr-contains-p1"], level: 3, testType: TEST_QSA | TEST_MATCH}, + {name: "Attribute contains selector with single-quoted value, matching class attribute ending with specified substring", selector: "#attr-contains [class*='orange ']", expect: ["attr-contains-p1"], level: 3, testType: TEST_QSA | TEST_MATCH}, + {name: "Attribute contains selector with single-quoted value, matching class attribute containing specified substring", selector: "#attr-contains [class*='ple banana ora']", expect: ["attr-contains-p1"], level: 3, testType: TEST_QSA | TEST_MATCH}, + {name: "Attribute contains selector with double-quoted value, matching class attribute beginning with specified substring", selector: "#attr-contains [class*=\" apple\"]", expect: ["attr-contains-p1"], level: 3, testType: TEST_QSA | TEST_MATCH}, + {name: "Attribute contains selector with double-quoted value, matching class attribute ending with specified substring", selector: "#attr-contains [class*=\"orange \"]", expect: ["attr-contains-p1"], level: 3, testType: TEST_QSA | TEST_MATCH}, + {name: "Attribute contains selector with double-quoted value, matching class attribute containing specified substring", selector: "#attr-contains [class*=\"ple banana ora\"]", expect: ["attr-contains-p1"], level: 3, testType: TEST_QSA | TEST_MATCH}, + {name: "Attribute contains selector with unquoted value, matching class attribute beginning with specified substring", selector: "#attr-contains [class*= apple]", expect: ["attr-contains-p1"], level: 3, testType: TEST_QSA | TEST_MATCH}, + {name: "Attribute contains selector with unquoted value, matching class attribute ending with specified substring", selector: "#attr-contains [class*=orange ]", expect: ["attr-contains-p1"], level: 3, testType: TEST_QSA | TEST_MATCH}, + {name: "Attribute contains selector with unquoted value, matching class attribute containing specified substring", selector: "#attr-contains [class*= banana ]", expect: ["attr-contains-p1"], level: 3, testType: TEST_QSA | TEST_MATCH}, + + // Pseudo-classes + // - :root (Level 3) + {name: ":root pseudo-class selector, matching document root element", selector: ":root", expect: ["html"], exclude: ["element", "fragment", "detached"], level: 3, testType: TEST_QSA | TEST_MATCH}, + {name: ":root pseudo-class selector, not matching document root element", selector: ":root", expect: [] /*no matches*/, exclude: ["document"], level: 3, testType: TEST_QSA}, + + // - :nth-child(n) (Level 3) + // XXX write descriptions + {name: ":nth-child selector, matching the third child element", selector: "#pseudo-nth-table1 :nth-child(3)", expect: ["pseudo-nth-td3", "pseudo-nth-td9", "pseudo-nth-tr3", "pseudo-nth-td15"], level: 3, testType: TEST_QSA | TEST_MATCH}, + {name: ":nth-child selector, matching every third child element", selector: "#pseudo-nth li:nth-child(3n)", expect: ["pseudo-nth-li3", "pseudo-nth-li6", "pseudo-nth-li9", "pseudo-nth-li12"], level: 3, testType: TEST_QSA | TEST_MATCH}, + {name: ":nth-child selector, matching every second child element, starting from the fourth", selector: "#pseudo-nth li:nth-child(2n+4)", expect: ["pseudo-nth-li4", "pseudo-nth-li6", "pseudo-nth-li8", "pseudo-nth-li10", "pseudo-nth-li12"], level: 3, testType: TEST_QSA | TEST_MATCH}, + {name: ":nth-child selector, matching every fourth child element, starting from the third", selector: "#pseudo-nth-p1 :nth-child(4n-1)", expect: ["pseudo-nth-em2", "pseudo-nth-span3"], level: 3, testType: TEST_QSA | TEST_MATCH}, + + // - :nth-last-child (Level 3) + {name: ":nth-last-child selector, matching the third last child element", selector: "#pseudo-nth-table1 :nth-last-child(3)", expect: ["pseudo-nth-tr1", "pseudo-nth-td4", "pseudo-nth-td10", "pseudo-nth-td16"], level: 3, testType: TEST_QSA | TEST_MATCH}, + {name: ":nth-last-child selector, matching every third child element from the end", selector: "#pseudo-nth li:nth-last-child(3n)", expect: ["pseudo-nth-li1", "pseudo-nth-li4", "pseudo-nth-li7", "pseudo-nth-li10"], level: 3, testType: TEST_QSA | TEST_MATCH}, + {name: ":nth-last-child selector, matching every second child element from the end, starting from the fourth last", selector: "#pseudo-nth li:nth-last-child(2n+4)", expect: ["pseudo-nth-li1", "pseudo-nth-li3", "pseudo-nth-li5", "pseudo-nth-li7", "pseudo-nth-li9"], level: 3, testType: TEST_QSA | TEST_MATCH}, + {name: ":nth-last-child selector, matching every fourth element from the end, starting from the third last", selector: "#pseudo-nth-p1 :nth-last-child(4n-1)", expect: ["pseudo-nth-span2", "pseudo-nth-span4"], level: 3, testType: TEST_QSA | TEST_MATCH}, + + // - :nth-of-type(n) (Level 3) + {name: ":nth-of-type selector, matching the third em element", selector: "#pseudo-nth-p1 em:nth-of-type(3)", expect: ["pseudo-nth-em3"], level: 3, testType: TEST_QSA | TEST_MATCH}, + {name: ":nth-of-type selector, matching every second element of their type", selector: "#pseudo-nth-p1 :nth-of-type(2n)", expect: ["pseudo-nth-em2", "pseudo-nth-span2", "pseudo-nth-span4", "pseudo-nth-strong2", "pseudo-nth-em4"], level: 3, testType: TEST_QSA | TEST_MATCH}, + {name: ":nth-of-type selector, matching every second elemetn of their type, starting from the first", selector: "#pseudo-nth-p1 span:nth-of-type(2n-1)", expect: ["pseudo-nth-span1", "pseudo-nth-span3"], level: 3, testType: TEST_QSA | TEST_MATCH}, + + // - :nth-last-of-type(n) (Level 3) + {name: ":nth-last-of-type selector, matching the third last em element", selector: "#pseudo-nth-p1 em:nth-last-of-type(3)", expect: ["pseudo-nth-em2"], level: 3, testType: TEST_QSA | TEST_MATCH}, + {name: ":nth-last-of-type selector, matching every second last element of their type", selector: "#pseudo-nth-p1 :nth-last-of-type(2n)", expect: ["pseudo-nth-span1", "pseudo-nth-em1", "pseudo-nth-strong1", "pseudo-nth-em3", "pseudo-nth-span3"], level: 3, testType: TEST_QSA | TEST_MATCH}, + {name: ":nth-last-of-type selector, matching every second last element of their type, starting from the last", selector: "#pseudo-nth-p1 span:nth-last-of-type(2n-1)", expect: ["pseudo-nth-span2", "pseudo-nth-span4"], level: 3, testType: TEST_QSA | TEST_MATCH}, + + // - :first-of-type (Level 3) + {name: ":first-of-type selector, matching the first em element", selector: "#pseudo-nth-p1 em:first-of-type", expect: ["pseudo-nth-em1"], level: 3, testType: TEST_QSA | TEST_MATCH}, + {name: ":first-of-type selector, matching the first of every type of element", selector: "#pseudo-nth-p1 :first-of-type", expect: ["pseudo-nth-span1", "pseudo-nth-em1", "pseudo-nth-strong1"], level: 3, testType: TEST_QSA | TEST_MATCH}, + {name: ":first-of-type selector, matching the first td element in each table row", selector: "#pseudo-nth-table1 tr :first-of-type", expect: ["pseudo-nth-td1", "pseudo-nth-td7", "pseudo-nth-td13"], level: 3, testType: TEST_QSA | TEST_MATCH}, + + // - :last-of-type (Level 3) + {name: ":last-of-type selector, matching the last em elemnet", selector: "#pseudo-nth-p1 em:last-of-type", expect: ["pseudo-nth-em4"], level: 3, testType: TEST_QSA | TEST_MATCH}, + {name: ":last-of-type selector, matching the last of every type of element", selector: "#pseudo-nth-p1 :last-of-type", expect: ["pseudo-nth-span4", "pseudo-nth-strong2", "pseudo-nth-em4"], level: 3, testType: TEST_QSA | TEST_MATCH}, + {name: ":last-of-type selector, matching the last td element in each table row", selector: "#pseudo-nth-table1 tr :last-of-type", expect: ["pseudo-nth-td6", "pseudo-nth-td12", "pseudo-nth-td18"], level: 3, testType: TEST_QSA | TEST_MATCH}, + + // - :first-child + {name: ":first-child pseudo-class selector, matching first child div element", selector: "#pseudo-first-child div:first-child", expect: ["pseudo-first-child-div1"], level: 2, testType: TEST_QSA | TEST_MATCH}, + {name: ":first-child pseudo-class selector, doesn't match non-first-child elements", selector: ".pseudo-first-child-div2:first-child, .pseudo-first-child-div3:first-child", expect: [] /*no matches*/, level: 2, testType: TEST_QSA}, + {name: ":first-child pseudo-class selector, matching first-child of multiple elements", selector: "#pseudo-first-child span:first-child", expect: ["pseudo-first-child-span1", "pseudo-first-child-span3", "pseudo-first-child-span5"], level: 2, testType: TEST_QSA | TEST_MATCH}, + + // - :last-child (Level 3) + {name: ":last-child pseudo-class selector, matching last child div element", selector: "#pseudo-last-child div:last-child", expect: ["pseudo-last-child-div3"], level: 3, testType: TEST_QSA | TEST_MATCH}, + {name: ":last-child pseudo-class selector, doesn't match non-last-child elements", selector: ".pseudo-last-child-div1:last-child, .pseudo-last-child-div2:first-child", expect: [] /*no matches*/, level: 3, testType: TEST_QSA}, + {name: ":last-child pseudo-class selector, matching first-child of multiple elements", selector: "#pseudo-last-child span:last-child", expect: ["pseudo-last-child-span2", "pseudo-last-child-span4", "pseudo-last-child-span6"], level: 3, testType: TEST_QSA | TEST_MATCH}, + + // - :only-child (Level 3) + {name: ":pseudo-only-child pseudo-class selector, matching all only-child elements", selector: "#pseudo-only :only-child", expect: ["pseudo-only-span1"], level: 3, testType: TEST_QSA | TEST_MATCH}, + {name: ":pseudo-only-child pseudo-class selector, matching only-child em elements", selector: "#pseudo-only em:only-child", expect: [] /*no matches*/, level: 3, testType: TEST_QSA}, + + // - :only-of-type (Level 3) + {name: ":pseudo-only-of-type pseudo-class selector, matching all elements with no siblings of the same type", selector: "#pseudo-only :only-of-type", expect: ["pseudo-only-span1", "pseudo-only-em1"], level: 3, testType: TEST_QSA | TEST_MATCH}, + {name: ":pseudo-only-of-type pseudo-class selector, matching em elements with no siblings of the same type", selector: "#pseudo-only em:only-of-type", expect: ["pseudo-only-em1"], level: 3, testType: TEST_QSA | TEST_MATCH}, + + // - :empty (Level 3) + {name: ":empty pseudo-class selector, matching empty p elements", selector: "#pseudo-empty p:empty", expect: ["pseudo-empty-p1", "pseudo-empty-p2"], level: 3, testType: TEST_QSA | TEST_MATCH}, + {name: ":empty pseudo-class selector, matching all empty elements", selector: "#pseudo-empty :empty", expect: ["pseudo-empty-p1", "pseudo-empty-p2", "pseudo-empty-span1"], level: 3, testType: TEST_QSA | TEST_MATCH}, + + // - :link and :visited + // Implementations may treat all visited links as unvisited, so these cannot be tested separately. + // The only guarantee is that ":link,:visited" matches the set of all visited and unvisited links and that they are individually mutually exclusive sets. + {name: ":link and :visited pseudo-class selectors, matching a and area elements with href attributes", selector: "#pseudo-link :link, #pseudo-link :visited", expect: ["pseudo-link-a1", "pseudo-link-a2", "pseudo-link-area1"], level: 1, testType: TEST_QSA | TEST_MATCH}, + {name: ":link and :visited pseudo-class selectors, matching no elements", selector: "#head :link, #head :visited", expect: [] /*no matches*/, exclude: ["element", "fragment", "detached"], level: 1, testType: TEST_QSA | TEST_MATCH}, + {name: ":link and :visited pseudo-class selectors, not matching link elements with href attributes", selector: "#head :link, #head :visited", expect: [] /*no matches*/, exclude: ["document"], level: 1, testType: TEST_QSA}, + {name: ":link and :visited pseudo-class selectors, chained, mutually exclusive pseudo-classes match nothing", selector: ":link:visited", expect: [] /*no matches*/, exclude: ["document"], level: 1, testType: TEST_QSA}, + + // - :target (Level 3) + {name: ":target pseudo-class selector, matching the element referenced by the URL fragment identifier", selector: ":target", expect: [] /*no matches*/, exclude: ["document", "element"], level: 3, testType: TEST_QSA}, + {name: ":target pseudo-class selector, matching the element referenced by the URL fragment identifier", selector: ":target", expect: ["target"], exclude: ["fragment", "detached"], level: 3, testType: TEST_QSA | TEST_MATCH}, + + // - :lang() + {name: ":lang pseudo-class selector, matching inherited language", selector: "#pseudo-lang-div1:lang(en)", expect: ["pseudo-lang-div1"], exclude: ["detached", "fragment"], level: 2, testType: TEST_QSA | TEST_MATCH}, + {name: ":lang pseudo-class selector, not matching element with no inherited language", selector: "#pseudo-lang-div1:lang(en)", expect: [] /*no matches*/, exclude: ["document", "element"], level: 2, testType: TEST_QSA}, + {name: ":lang pseudo-class selector, matching specified language with exact value", selector: "#pseudo-lang-div2:lang(fr)", expect: ["pseudo-lang-div2"], level: 2, testType: TEST_QSA | TEST_MATCH}, + {name: ":lang pseudo-class selector, matching specified language with partial value", selector: "#pseudo-lang-div3:lang(en)", expect: ["pseudo-lang-div3"], level: 2, testType: TEST_QSA | TEST_MATCH}, + {name: ":lang pseudo-class selector, not matching incorrect language", selector: "#pseudo-lang-div4:lang(es-AR)", expect: [] /*no matches*/, level: 2, testType: TEST_QSA}, + + // - :enabled (Level 3) + {name: ":enabled pseudo-class selector, matching all enabled form controls", selector: "#pseudo-ui :enabled", expect: ["pseudo-ui-input1", "pseudo-ui-input2", "pseudo-ui-input3", "pseudo-ui-input4", "pseudo-ui-input5", "pseudo-ui-input6", + "pseudo-ui-input7", "pseudo-ui-input8", "pseudo-ui-input9", "pseudo-ui-textarea1", "pseudo-ui-button1"], level: 3, testType: TEST_QSA | TEST_MATCH}, + {name: ":enabled pseudo-class selector, not matching link elements", selector: "#pseudo-link :enabled", expect: [] /*no matches*/, unexpected: ["pseudo-link-a1","pseudo-link-a2","pseudo-link-a3","pseudo-link-map1","pseudo-link-area1","pseudo-link-area2"], level: 3, testType: TEST_QSA | TEST_MATCH}, + + // - :disabled (Level 3) + {name: ":disabled pseudo-class selector, matching all disabled form controls", selector: "#pseudo-ui :disabled", expect: ["pseudo-ui-input10", "pseudo-ui-input11", "pseudo-ui-input12", "pseudo-ui-input13", "pseudo-ui-input14", "pseudo-ui-input15", + "pseudo-ui-input16", "pseudo-ui-input17", "pseudo-ui-input18", "pseudo-ui-textarea2", "pseudo-ui-button2"], level: 3, testType: TEST_QSA | TEST_MATCH}, + {name: ":disabled pseudo-class selector, not matching link elements", selector: "#pseudo-link :disabled", expect: [] /*no matches*/, unexpected: ["pseudo-link-a1","pseudo-link-a2","pseudo-link-a3","pseudo-link-map1","pseudo-link-area1","pseudo-link-area2"], level: 3, testType: TEST_QSA | TEST_MATCH}, + + // - :checked (Level 3) + {name: ":checked pseudo-class selector, matching checked radio buttons and checkboxes", selector: "#pseudo-ui :checked", expect: ["pseudo-ui-input4", "pseudo-ui-input6", "pseudo-ui-input13", "pseudo-ui-input15"], level: 3, testType: TEST_QSA | TEST_MATCH}, + + // - :not(s) (Level 3) + {name: ":not pseudo-class selector, matching ", selector: "#not>:not(div)", expect: ["not-p1", "not-p2", "not-p3"], level: 3, testType: TEST_QSA | TEST_MATCH}, + {name: ":not pseudo-class selector, matching ", selector: "#not * :not(:first-child)", expect: ["not-em1", "not-em2", "not-em3"], level: 3, testType: TEST_QSA | TEST_MATCH}, + {name: ":not pseudo-class selector, matching nothing", selector: ":not(*)", expect: [] /* no matches */, level: 3, testType: TEST_QSA}, + {name: ":not pseudo-class selector, matching nothing", selector: ":not(*|*)", expect: [] /* no matches */, level: 3, testType: TEST_QSA}, + {name: ":not pseudo-class selector argument surrounded by spaces, matching ", selector: "#not>:not( div )", expect: ["not-p1", "not-p2", "not-p3"], level: 3, testType: TEST_QSA | TEST_MATCH}, + + // Pseudo-elements + // - ::first-line + {name: ":first-line pseudo-element (one-colon syntax) selector, not matching any elements", selector: "#pseudo-element:first-line", expect: [] /*no matches*/, level: 2, testType: TEST_QSA}, + {name: "::first-line pseudo-element (two-colon syntax) selector, not matching any elements", selector: "#pseudo-element::first-line", expect: [] /*no matches*/, level: 3, testType: TEST_QSA}, + + // - ::first-letter + {name: ":first-letter pseudo-element (one-colon syntax) selector, not matching any elements", selector: "#pseudo-element:first-letter", expect: [] /*no matches*/, level: 2, testType: TEST_QSA}, + {name: "::first-letter pseudo-element (two-colon syntax) selector, not matching any elements", selector: "#pseudo-element::first-letter", expect: [] /*no matches*/, level: 3, testType: TEST_QSA}, + + // - ::before + {name: ":before pseudo-element (one-colon syntax) selector, not matching any elements", selector: "#pseudo-element:before", expect: [] /*no matches*/, level: 2, testType: TEST_QSA}, + {name: "::before pseudo-element (two-colon syntax) selector, not matching any elements", selector: "#pseudo-element::before", expect: [] /*no matches*/, level: 3, testType: TEST_QSA}, + + // - ::after + {name: ":after pseudo-element (one-colon syntax) selector, not matching any elements", selector: "#pseudo-element:after", expect: [] /*no matches*/, level: 2, testType: TEST_QSA}, + {name: "::after pseudo-element (two-colon syntax) selector, not matching any elements", selector: "#pseudo-element::after", expect: [] /*no matches*/, level: 3, testType: TEST_QSA}, + + // Class Selectors + {name: "Class selector, matching element with specified class", selector: ".class-p", expect: ["class-p1","class-p2", "class-p3"], level: 1, testType: TEST_QSA | TEST_MATCH}, + {name: "Class selector, chained, matching only elements with all specified classes", selector: "#class .apple.orange.banana", expect: ["class-div1", "class-div2", "class-p4", "class-div3", "class-p6", "class-div4"], level: 1, testType: TEST_QSA | TEST_MATCH}, + {name: "Class Selector, chained, with type selector", selector: "div.apple.banana.orange", expect: ["class-div1", "class-div2", "class-div3", "class-div4"], level: 1, testType: TEST_QSA | TEST_MATCH}, + {name: "Class selector, matching element with class value using non-ASCII characters (1)", selector: ".\u53F0\u5317Ta\u0301ibe\u030Ci", expect: ["class-span1"], level: 1, testType: TEST_QSA | TEST_MATCH}, + {name: "Class selector, matching multiple elements with class value using non-ASCII characters", selector: ".\u53F0\u5317", expect: ["class-span1","class-span2"], level: 1, testType: TEST_QSA | TEST_MATCH}, + {name: "Class selector, chained, matching element with multiple class values using non-ASCII characters (1)", selector: ".\u53F0\u5317Ta\u0301ibe\u030Ci.\u53F0\u5317", expect: ["class-span1"], level: 1, testType: TEST_QSA | TEST_MATCH}, + {name: "Class selector, matching element with class with escaped character", selector: ".foo\\:bar", expect: ["class-span3"], level: 1, testType: TEST_QSA | TEST_MATCH}, + {name: "Class selector, matching element with class with escaped character", selector: ".test\\.foo\\[5\\]bar", expect: ["class-span4"], level: 1, testType: TEST_QSA | TEST_MATCH}, + + // ID Selectors + {name: "ID selector, matching element with specified id", selector: "#id #id-div1", expect: ["id-div1"], level: 1, testType: TEST_QSA | TEST_MATCH}, + {name: "ID selector, chained, matching element with specified id", selector: "#id-div1, #id-div1", expect: ["id-div1"], level: 1, testType: TEST_QSA | TEST_MATCH}, + {name: "ID selector, chained, matching element with specified id", selector: "#id-div1, #id-div2", expect: ["id-div1", "id-div2"], level: 1, testType: TEST_QSA | TEST_MATCH}, + {name: "ID Selector, chained, with type selector", selector: "div#id-div1, div#id-div2", expect: ["id-div1", "id-div2"], level: 1, testType: TEST_QSA | TEST_MATCH}, + {name: "ID selector, not matching non-existent descendant", selector: "#id #none", expect: [] /*no matches*/, level: 1, testType: TEST_QSA}, + {name: "ID selector, not matching non-existent ancestor", selector: "#none #id-div1", expect: [] /*no matches*/, level: 1, testType: TEST_QSA}, + {name: "ID selector, matching multiple elements with duplicate id", selector: "#id-li-duplicate", expect: ["id-li-duplicate", "id-li-duplicate", "id-li-duplicate", "id-li-duplicate"], level: 1, testType: TEST_QSA | TEST_MATCH}, + + {name: "ID selector, matching id value using non-ASCII characters (1)", selector: "#\u53F0\u5317Ta\u0301ibe\u030Ci", expect: ["\u53F0\u5317Ta\u0301ibe\u030Ci"], level: 1, testType: TEST_QSA | TEST_MATCH}, + {name: "ID selector, matching id value using non-ASCII characters (2)", selector: "#\u53F0\u5317", expect: ["\u53F0\u5317"], level: 1, testType: TEST_QSA | TEST_MATCH}, + {name: "ID selector, matching id values using non-ASCII characters (1)", selector: "#\u53F0\u5317Ta\u0301ibe\u030Ci, #\u53F0\u5317", expect: ["\u53F0\u5317Ta\u0301ibe\u030Ci", "\u53F0\u5317"], level: 1, testType: TEST_QSA | TEST_MATCH}, + + // XXX runMatchesTest() in level2-lib.js can't handle this because obtaining the expected nodes requires escaping characters when generating the selector from 'expect' values + {name: "ID selector, matching element with id with escaped character", selector: "#\\#foo\\:bar", expect: ["#foo:bar"], level: 1, testType: TEST_QSA}, + {name: "ID selector, matching element with id with escaped character", selector: "#test\\.foo\\[5\\]bar", expect: ["test.foo[5]bar"], level: 1, testType: TEST_QSA}, + + // Namespaces + // XXX runMatchesTest() in level2-lib.js can't handle these because non-HTML elements don't have a recognised id + {name: "Namespace selector, matching element with any namespace", selector: "#any-namespace *|div", expect: ["any-namespace-div1", "any-namespace-div2", "any-namespace-div3", "any-namespace-div4"], level: 3, testType: TEST_QSA}, + {name: "Namespace selector, matching div elements in no namespace only", selector: "#no-namespace |div", expect: ["no-namespace-div3"], level: 3, testType: TEST_QSA}, + {name: "Namespace selector, matching any elements in no namespace only", selector: "#no-namespace |*", expect: ["no-namespace-div3"], level: 3, testType: TEST_QSA}, + + // Combinators + // - Descendant combinator ' ' + {name: "Descendant combinator, matching element that is a descendant of an element with id", selector: "#descendant div", expect: ["descendant-div1", "descendant-div2", "descendant-div3", "descendant-div4"], level: 1, testType: TEST_QSA | TEST_MATCH}, + {name: "Descendant combinator, matching element with id that is a descendant of an element", selector: "body #descendant-div1", expect: ["descendant-div1"], exclude: ["detached", "fragment"], level: 1, testType: TEST_QSA | TEST_MATCH}, + {name: "Descendant combinator, matching element with id that is a descendant of an element", selector: "div #descendant-div1", expect: ["descendant-div1"], level: 1, testType: TEST_QSA | TEST_MATCH}, + {name: "Descendant combinator, matching element with id that is a descendant of an element with id", selector: "#descendant #descendant-div2", expect: ["descendant-div2"], level: 1, testType: TEST_QSA | TEST_MATCH}, + {name: "Descendant combinator, matching element with class that is a descendant of an element with id", selector: "#descendant .descendant-div2", expect: ["descendant-div2"], level: 1, testType: TEST_QSA | TEST_MATCH}, + {name: "Descendant combinator, matching element with class that is a descendant of an element with class", selector: ".descendant-div1 .descendant-div3", expect: ["descendant-div3"], level: 1, testType: TEST_QSA | TEST_MATCH}, + {name: "Descendant combinator, not matching element with id that is not a descendant of an element with id", selector: "#descendant-div1 #descendant-div4", expect: [] /*no matches*/, level: 1, testType: TEST_QSA}, + {name: "Descendant combinator, whitespace characters", selector: "#descendant\t\r\n#descendant-div2", expect: ["descendant-div2"], level: 1, testType: TEST_QSA | TEST_MATCH}, + + /* The future of this combinator is uncertain, see + * https://github.com/w3c/csswg-drafts/issues/641 + * These tests are commented out until a final decision is made on whether to + * keep the feature in the spec. + */ + + // // - Descendant combinator '>>' + // {name: "Descendant combinator '>>', matching element that is a descendant of an element with id", selector: "#descendant>>div", expect: ["descendant-div1", "descendant-div2", "descendant-div3", "descendant-div4"], level: 1, testType: TEST_QSA | TEST_MATCH}, + // {name: "Descendant combinator '>>', matching element with id that is a descendant of an element", selector: "body>>#descendant-div1", expect: ["descendant-div1"], exclude: ["detached", "fragment"], level: 1, testType: TEST_QSA | TEST_MATCH}, + // {name: "Descendant combinator '>>', matching element with id that is a descendant of an element", selector: "div>>#descendant-div1", expect: ["descendant-div1"], level: 1, testType: TEST_QSA | TEST_MATCH}, + // {name: "Descendant combinator '>>', matching element with id that is a descendant of an element with id", selector: "#descendant>>#descendant-div2", expect: ["descendant-div2"], level: 1, testType: TEST_QSA | TEST_MATCH}, + // {name: "Descendant combinator '>>', matching element with class that is a descendant of an element with id", selector: "#descendant>>.descendant-div2", expect: ["descendant-div2"], level: 1, testType: TEST_QSA | TEST_MATCH}, + // {name: "Descendant combinator '>>', matching element with class that is a descendant of an element with class", selector: ".descendant-div1>>.descendant-div3", expect: ["descendant-div3"], level: 1, testType: TEST_QSA | TEST_MATCH}, + // {name: "Descendant combinator '>>', not matching element with id that is not a descendant of an element with id", selector: "#descendant-div1>>#descendant-div4", expect: [] /*no matches*/, level: 1, testType: TEST_QSA}, + + // - Child combinator '>' + {name: "Child combinator, matching element that is a child of an element with id", selector: "#child>div", expect: ["child-div1", "child-div4"], level: 2, testType: TEST_QSA | TEST_MATCH}, + {name: "Child combinator, matching element with id that is a child of an element", selector: "div>#child-div1", expect: ["child-div1"], level: 2, testType: TEST_QSA | TEST_MATCH}, + {name: "Child combinator, matching element with id that is a child of an element with id", selector: "#child>#child-div1", expect: ["child-div1"], level: 2, testType: TEST_QSA | TEST_MATCH}, + {name: "Child combinator, matching element with id that is a child of an element with class", selector: "#child-div1>.child-div2", expect: ["child-div2"], level: 2, testType: TEST_QSA | TEST_MATCH}, + {name: "Child combinator, matching element with class that is a child of an element with class", selector: ".child-div1>.child-div2", expect: ["child-div2"], level: 2, testType: TEST_QSA | TEST_MATCH}, + {name: "Child combinator, not matching element with id that is not a child of an element with id", selector: "#child>#child-div3", expect: [] /*no matches*/, level: 2, testType: TEST_QSA}, + {name: "Child combinator, not matching element with id that is not a child of an element with class", selector: "#child-div1>.child-div3", expect: [] /*no matches*/, level: 2, testType: TEST_QSA}, + {name: "Child combinator, not matching element with class that is not a child of an element with class", selector: ".child-div1>.child-div3", expect: [] /*no matches*/, level: 2, testType: TEST_QSA}, + {name: "Child combinator, surrounded by whitespace", selector: "#child-div1\t\r\n>\t\r\n#child-div2", expect: ["child-div2"], level: 2, testType: TEST_QSA | TEST_MATCH}, + {name: "Child combinator, whitespace after", selector: "#child-div1>\t\r\n#child-div2", expect: ["child-div2"], level: 2, testType: TEST_QSA | TEST_MATCH}, + {name: "Child combinator, whitespace before", selector: "#child-div1\t\r\n>#child-div2", expect: ["child-div2"], level: 2, testType: TEST_QSA | TEST_MATCH}, + {name: "Child combinator, no whitespace", selector: "#child-div1>#child-div2", expect: ["child-div2"], level: 2, testType: TEST_QSA | TEST_MATCH}, + + // - Adjacent sibling combinator '+' + {name: "Adjacent sibling combinator, matching element that is an adjacent sibling of an element with id", selector: "#adjacent-div2+div", expect: ["adjacent-div4"], level: 2, testType: TEST_QSA | TEST_MATCH}, + {name: "Adjacent sibling combinator, matching element with id that is an adjacent sibling of an element", selector: "div+#adjacent-div4", expect: ["adjacent-div4"], level: 2, testType: TEST_QSA | TEST_MATCH}, + {name: "Adjacent sibling combinator, matching element with id that is an adjacent sibling of an element with id", selector: "#adjacent-div2+#adjacent-div4", expect: ["adjacent-div4"], level: 2, testType: TEST_QSA | TEST_MATCH}, + {name: "Adjacent sibling combinator, matching element with class that is an adjacent sibling of an element with id", selector: "#adjacent-div2+.adjacent-div4", expect: ["adjacent-div4"], level: 2, testType: TEST_QSA | TEST_MATCH}, + {name: "Adjacent sibling combinator, matching element with class that is an adjacent sibling of an element with class", selector: ".adjacent-div2+.adjacent-div4", expect: ["adjacent-div4"], level: 2, testType: TEST_QSA | TEST_MATCH}, + {name: "Adjacent sibling combinator, matching p element that is an adjacent sibling of a div element", selector: "#adjacent div+p", expect: ["adjacent-p2"], level: 2, testType: TEST_QSA | TEST_MATCH}, + {name: "Adjacent sibling combinator, not matching element with id that is not an adjacent sibling of an element with id", selector: "#adjacent-div2+#adjacent-p2, #adjacent-div2+#adjacent-div1", expect: [] /*no matches*/, level: 2, testType: TEST_QSA}, + {name: "Adjacent sibling combinator, surrounded by whitespace", selector: "#adjacent-p2\t\r\n+\t\r\n#adjacent-p3", expect: ["adjacent-p3"], level: 2, testType: TEST_QSA | TEST_MATCH}, + {name: "Adjacent sibling combinator, whitespace after", selector: "#adjacent-p2+\t\r\n#adjacent-p3", expect: ["adjacent-p3"], level: 2, testType: TEST_QSA | TEST_MATCH}, + {name: "Adjacent sibling combinator, whitespace before", selector: "#adjacent-p2\t\r\n+#adjacent-p3", expect: ["adjacent-p3"], level: 2, testType: TEST_QSA | TEST_MATCH}, + {name: "Adjacent sibling combinator, no whitespace", selector: "#adjacent-p2+#adjacent-p3", expect: ["adjacent-p3"], level: 2, testType: TEST_QSA | TEST_MATCH}, + + // - General sibling combinator ~ (Level 3) + {name: "General sibling combinator, matching element that is a sibling of an element with id", selector: "#sibling-div2~div", expect: ["sibling-div4", "sibling-div6"], level: 3, testType: TEST_QSA | TEST_MATCH}, + {name: "General sibling combinator, matching element with id that is a sibling of an element", selector: "div~#sibling-div4", expect: ["sibling-div4"], level: 3, testType: TEST_QSA | TEST_MATCH}, + {name: "General sibling combinator, matching element with id that is a sibling of an element with id", selector: "#sibling-div2~#sibling-div4", expect: ["sibling-div4"], level: 3, testType: TEST_QSA | TEST_MATCH}, + {name: "General sibling combinator, matching element with class that is a sibling of an element with id", selector: "#sibling-div2~.sibling-div", expect: ["sibling-div4", "sibling-div6"], level: 3, testType: TEST_QSA | TEST_MATCH}, + {name: "General sibling combinator, matching p element that is a sibling of a div element", selector: "#sibling div~p", expect: ["sibling-p2", "sibling-p3"], level: 3, testType: TEST_QSA | TEST_MATCH}, + {name: "General sibling combinator, not matching element with id that is not a sibling after a p element", selector: "#sibling>p~div", expect: [] /*no matches*/, level: 3, testType: TEST_QSA}, + {name: "General sibling combinator, not matching element with id that is not a sibling after an element with id", selector: "#sibling-div2~#sibling-div3, #sibling-div2~#sibling-div1", expect: [] /*no matches*/, level: 3, testType: TEST_QSA}, + {name: "General sibling combinator, surrounded by whitespace", selector: "#sibling-p2\t\r\n~\t\r\n#sibling-p3", expect: ["sibling-p3"], level: 3, testType: TEST_QSA | TEST_MATCH}, + {name: "General sibling combinator, whitespace after", selector: "#sibling-p2~\t\r\n#sibling-p3", expect: ["sibling-p3"], level: 3, testType: TEST_QSA | TEST_MATCH}, + {name: "General sibling combinator, whitespace before", selector: "#sibling-p2\t\r\n~#sibling-p3", expect: ["sibling-p3"], level: 3, testType: TEST_QSA | TEST_MATCH}, + {name: "General sibling combinator, no whitespace", selector: "#sibling-p2~#sibling-p3", expect: ["sibling-p3"], level: 3, testType: TEST_QSA | TEST_MATCH}, + + // Group of selectors (comma) + {name: "Syntax, group of selectors separator, surrounded by whitespace", selector: "#group em\t\r \n,\t\r \n#group strong", expect: ["group-em1", "group-strong1"], level: 1, testType: TEST_QSA | TEST_MATCH}, + {name: "Syntax, group of selectors separator, whitespace after", selector: "#group em,\t\r\n#group strong", expect: ["group-em1", "group-strong1"], level: 1, testType: TEST_QSA | TEST_MATCH}, + {name: "Syntax, group of selectors separator, whitespace before", selector: "#group em\t\r\n,#group strong", expect: ["group-em1", "group-strong1"], level: 1, testType: TEST_QSA | TEST_MATCH}, + {name: "Syntax, group of selectors separator, no whitespace", selector: "#group em,#group strong", expect: ["group-em1", "group-strong1"], level: 1, testType: TEST_QSA | TEST_MATCH}, + + // ::slotted (shouldn't match anything, but is a valid selector) + {name: "Slotted selector", selector: "::slotted(foo)", expect: [], level: 3, testType: TEST_QSA}, + {name: "Slotted selector (no matching closing paren)", selector: "::slotted(foo", expect: [], level: 3, testType: TEST_QSA}, +]; + + +/* + * These selectors are intended to be used with the find(), findAll() and matches() methods. Expected results + * should be determined under the assumption that :scope will be prepended to the selector where appropriate, + * in accordance with the specification. + * + * All of these should be valid relative selectors, expected to match zero or more elements in the document. + * None should throw any errors. + * + * name: A descriptive name of the selector being tested + * + * selector: The selector to test + * + * ctx: A selector to obtain the context object to use for tests invoking context.find(), + * and to use as a single reference node for tests invoking document.find(). + * Note: context = root.querySelector(ctx); + * + * ref: A selector to obtain the reference nodes to be used for the selector. + * Note: If root is the document or an in-document element: + * refNodes = document.querySelectorAll(ref); + * Otherwise, if root is a fragment or detached element: + * refNodes = root.querySelectorAll(ref); + * + * expect: A list of IDs of the elements expected to be matched. List must be given in tree order. + * + * unexpected: A list of IDs of some elements that are not expected to match the given selector. + * This is used to verify that unexpected.matches(selector, refNode) does not match. + * + * exclude: An array of contexts to exclude from testing. The valid values are: + * ["document", "element", "fragment", "detached", "html", "xhtml"] + * The "html" and "xhtml" values represent the type of document being queried. These are useful + * for tests that are affected by differences between HTML and XML, such as case sensitivity. + * + * level: An integer indicating the CSS or Selectors level in which the selector being tested was introduced. + * + * testType: A bit-mapped flag indicating the type of test. + * + * The test function for these tests accepts a specified root node, on which the methods will be invoked during the tests. + * + * Based on whether either 'context' or 'refNodes', or both, are specified the tests will execute the following methods: + * + * Where testType is TEST_FIND: + * + * context.findAll(selector, refNodes) + * context.findAll(selector) // Only if refNodes is not specified + * root.findAll(selector, context) // Only if refNodes is not specified + * root.findAll(selector, refNodes) // Only if context is not specified + * root.findAll(selector) // Only if neither context nor refNodes is specified + * + * Where testType is TEST_QSA + * + * context.querySelectorAll(selector) + * root.querySelectorAll(selector) // Only if neither context nor refNodes is specified + * + * Equivalent tests will be run for .find() as well. + * Note: Do not specify a testType of TEST_QSA where either implied :scope or explicit refNodes + * are required. + * + * Where testType is TEST_MATCH: + * For each expected result given, within the specified root: + * + * expect.matches(selector, context) // Only where refNodes is not specified + * expect.matches(selector, refNodes) + * expect.matches(selector) // Only if neither context nor refNodes is specified + * + * The tests involving refNodes for both find(), findAll() and matches() will each be run by passing the + * collection as a NodeList, an Array and, if there is only a single element, an Element node. + * + * Note: Interactive pseudo-classes (:active :hover and :focus) have not been tested in this test suite. + */ + +var scopedSelectors = [ + //{name: "", selector: "", ctx: "", ref: "", expect: [], level: 1, testType: TEST_FIND | TEST_MATCH}, + + // Attribute Selectors + // - presence [att] + {name: "Attribute presence selector, matching align attribute with value", selector: ".attr-presence-div1[align]", ctx: "#attr-presence", expect: ["attr-presence-div1"], level: 2, testType: TEST_FIND | TEST_MATCH}, + {name: "Attribute presence selector, matching align attribute with empty value", selector: ".attr-presence-div2[align]", ctx: "#attr-presence", expect: ["attr-presence-div2"], level: 2, testType: TEST_FIND | TEST_MATCH}, + {name: "Attribute presence selector, matching title attribute, case insensitivity", selector: "[TiTlE]", ctx: "#attr-presence", expect: ["attr-presence-a1", "attr-presence-span1"], exclude: ["xhtml"], level: 2, testType: TEST_FIND | TEST_MATCH}, + {name: "Attribute presence selector, not matching title attribute, case sensitivity", selector: "[TiTlE]", ctx: "#attr-presence", expect: [], exclude: ["html"], level: 2, testType: TEST_FIND | TEST_MATCH}, + {name: "Attribute presence selector, matching custom data-* attribute", selector: "[data-attr-presence]", ctx: "#attr-presence", expect: ["attr-presence-pre1", "attr-presence-blockquote1"], level: 2, testType: TEST_FIND | TEST_MATCH}, + {name: "Attribute presence selector, not matching attribute with similar name", selector: ".attr-presence-div3[align], .attr-presence-div4[align]", ctx: "#attr-presence", expect: [] /*no matches*/, level: 2, testType: TEST_FIND}, + {name: "Attribute presence selector, matching attribute with non-ASCII characters", selector: "ul[data-中文]", ctx: "#attr-presence", expect: ["attr-presence-ul1"], level: 2, testType: TEST_FIND | TEST_MATCH}, + {name: "Attribute presence selector, not matching default option without selected attribute", selector: "#attr-presence-select1 option[selected]", ctx: "#attr-presence", expect: [] /* no matches */, level: 2, testType: TEST_FIND}, + {name: "Attribute presence selector, matching option with selected attribute", selector: "#attr-presence-select2 option[selected]", ctx: "#attr-presence", expect: ["attr-presence-select2-option4"], level: 2, testType: TEST_FIND | TEST_MATCH}, + {name: "Attribute presence selector, matching multiple options with selected attributes", selector: "#attr-presence-select3 option[selected]", ctx: "#attr-presence", expect: ["attr-presence-select3-option2", "attr-presence-select3-option3"], level: 2, testType: TEST_FIND | TEST_MATCH}, + + // - value [att=val] + {name: "Attribute value selector, matching align attribute with value", selector: "[align=\"center\"]", ctx: "#attr-value", expect: ["attr-value-div1"], level: 2, testType: TEST_FIND | TEST_MATCH}, + {name: "Attribute value selector, matching align attribute with empty value", selector: "[align=\"\"]", ctx: "#attr-value", expect: ["attr-value-div2"], level: 2, testType: TEST_FIND | TEST_MATCH}, + {name: "Attribute value selector, not matching align attribute with partial value", selector: "[align=\"c\"]", ctx: "#attr-value", expect: [] /*no matches*/, level: 2, testType: TEST_FIND}, + {name: "Attribute value selector, not matching align attribute with incorrect value", selector: "[align=\"centera\"]", ctx: "#attr-value", expect: [] /*no matches*/, level: 2, testType: TEST_FIND}, + {name: "Attribute value selector, matching custom data-* attribute with unicode escaped value", selector: "[data-attr-value=\"\\e9\"]", ctx: "#attr-value", expect: ["attr-value-div3"], level: 2, testType: TEST_FIND | TEST_MATCH}, + {name: "Attribute value selector, matching custom data-* attribute with escaped character", selector: "[data-attr-value\_foo=\"\\e9\"]", ctx: "#attr-value", expect: ["attr-value-div4"], level: 2, testType: TEST_FIND | TEST_MATCH}, + {name: "Attribute value selector with single-quoted value, matching multiple inputs with type attributes", selector: "input[type='hidden'],#attr-value input[type='radio']", ctx: "#attr-value", expect: ["attr-value-input3", "attr-value-input4", "attr-value-input6", "attr-value-input8", "attr-value-input9"], level: 2, testType: TEST_FIND | TEST_MATCH}, + {name: "Attribute value selector with double-quoted value, matching multiple inputs with type attributes", selector: "input[type=\"hidden\"],#attr-value input[type='radio']", ctx: "#attr-value", expect: ["attr-value-input3", "attr-value-input4", "attr-value-input6", "attr-value-input8", "attr-value-input9"], level: 2, testType: TEST_FIND | TEST_MATCH}, + {name: "Attribute value selector with unquoted value, matching multiple inputs with type attributes", selector: "input[type=hidden],#attr-value input[type=radio]", ctx: "#attr-value", expect: ["attr-value-input3", "attr-value-input4", "attr-value-input6", "attr-value-input8", "attr-value-input9"], level: 2, testType: TEST_FIND | TEST_MATCH}, + {name: "Attribute value selector, matching attribute with value using non-ASCII characters", selector: "[data-attr-value=中文]", ctx: "#attr-value", expect: ["attr-value-div5"], level: 2, testType: TEST_FIND | TEST_MATCH}, + + // - whitespace-separated list [att~=val] + {name: "Attribute whitespace-separated list selector, matching class attribute with value", selector: "[class~=\"div1\"]", ctx: "#attr-whitespace", expect: ["attr-whitespace-div1"], level: 2, testType: TEST_FIND | TEST_MATCH}, + {name: "Attribute whitespace-separated list selector, not matching class attribute with empty value", selector: "[class~=\"\"]", ctx: "#attr-whitespace", expect: [] /*no matches*/ , level: 2, testType: TEST_FIND}, + {name: "Attribute whitespace-separated list selector, not matching class attribute with partial value", selector: "[data-attr-whitespace~=\"div\"]", ctx: "#attr-whitespace", expect: [] /*no matches*/ , level: 2, testType: TEST_FIND}, + {name: "Attribute whitespace-separated list selector, matching custom data-* attribute with unicode escaped value", selector: "[data-attr-whitespace~=\"\\0000e9\"]", ctx: "#attr-whitespace", expect: ["attr-whitespace-div4"], level: 2, testType: TEST_FIND | TEST_MATCH}, + {name: "Attribute whitespace-separated list selector, matching custom data-* attribute with escaped character", selector: "[data-attr-whitespace\_foo~=\"\\e9\"]", ctx: "#attr-whitespace", expect: ["attr-whitespace-div5"], level: 2, testType: TEST_FIND | TEST_MATCH}, + {name: "Attribute whitespace-separated list selector with single-quoted value, matching multiple links with rel attributes", selector: "a[rel~='bookmark'], #attr-whitespace a[rel~='nofollow']", ctx: "#attr-whitespace", expect: ["attr-whitespace-a1", "attr-whitespace-a2", "attr-whitespace-a3", "attr-whitespace-a5", "attr-whitespace-a7"], level: 2, testType: TEST_FIND | TEST_MATCH}, + {name: "Attribute whitespace-separated list selector with double-quoted value, matching multiple links with rel attributes", selector: "a[rel~=\"bookmark\"],#attr-whitespace a[rel~='nofollow']", ctx: "#attr-whitespace", expect: ["attr-whitespace-a1", "attr-whitespace-a2", "attr-whitespace-a3", "attr-whitespace-a5", "attr-whitespace-a7"], level: 2, testType: TEST_FIND | TEST_MATCH}, + {name: "Attribute whitespace-separated list selector with unquoted value, matching multiple links with rel attributes", selector: "a[rel~=bookmark], #attr-whitespace a[rel~=nofollow]", ctx: "#attr-whitespace", expect: ["attr-whitespace-a1", "attr-whitespace-a2", "attr-whitespace-a3", "attr-whitespace-a5", "attr-whitespace-a7"], level: 2, testType: TEST_FIND | TEST_MATCH}, + {name: "Attribute whitespace-separated list selector with double-quoted value, not matching value with space", selector: "a[rel~=\"book mark\"]", ctx: "#attr-whitespace", expect: [] /* no matches */, level: 2, testType: TEST_FIND}, + {name: "Attribute whitespace-separated list selector, matching title attribute with value using non-ASCII characters", selector: "[title~=中文]", ctx: "#attr-whitespace", expect: ["attr-whitespace-p1"], level: 2, testType: TEST_FIND | TEST_MATCH}, + + // - hyphen-separated list [att|=val] + {name: "Attribute hyphen-separated list selector, not matching unspecified lang attribute", selector: "#attr-hyphen-div1[lang|=\"en\"]", ctx: "#attr-hyphen", expect: [] /*no matches*/, level: 2, testType: TEST_FIND}, + {name: "Attribute hyphen-separated list selector, matching lang attribute with exact value", selector: "#attr-hyphen-div2[lang|=\"fr\"]", ctx: "#attr-hyphen", expect: ["attr-hyphen-div2"], level: 2, testType: TEST_FIND | TEST_MATCH}, + {name: "Attribute hyphen-separated list selector, matching lang attribute with partial value", selector: "#attr-hyphen-div3[lang|=\"en\"]", ctx: "#attr-hyphen", expect: ["attr-hyphen-div3"], level: 2, testType: TEST_FIND | TEST_MATCH}, + {name: "Attribute hyphen-separated list selector, not matching incorrect value", selector: "#attr-hyphen-div4[lang|=\"es-AR\"]", ctx: "#attr-hyphen", expect: [] /*no matches*/, level: 2, testType: TEST_FIND}, + + // - substring begins-with [att^=val] (Level 3) + {name: "Attribute begins with selector, matching href attributes beginning with specified substring", selector: "a[href^=\"http://www\"]", ctx: "#attr-begins", expect: ["attr-begins-a1", "attr-begins-a3"], level: 3, testType: TEST_FIND | TEST_MATCH}, + {name: "Attribute begins with selector, matching lang attributes beginning with specified substring, ", selector: "[lang^=\"en-\"]", ctx: "#attr-begins", expect: ["attr-begins-div2", "attr-begins-div4"], level: 3, testType: TEST_FIND | TEST_MATCH}, + {name: "Attribute begins with selector, not matching class attribute with empty value", selector: "[class^=\"\"]", ctx: "#attr-begins", expect: [] /*no matches*/, level: 3, testType: TEST_FIND}, + {name: "Attribute begins with selector, not matching class attribute not beginning with specified substring", selector: "[class^=apple]", ctx: "#attr-begins", expect: [] /*no matches*/, level: 3, testType: TEST_FIND}, + {name: "Attribute begins with selector with single-quoted value, matching class attribute beginning with specified substring", selector: "[class^=' apple']", ctx: "#attr-begins", expect: ["attr-begins-p1"], level: 3, testType: TEST_FIND | TEST_MATCH}, + {name: "Attribute begins with selector with double-quoted value, matching class attribute beginning with specified substring", selector: "[class^=\" apple\"]", ctx: "#attr-begins", expect: ["attr-begins-p1"], level: 3, testType: TEST_FIND | TEST_MATCH}, + {name: "Attribute begins with selector with unquoted value, not matching class attribute not beginning with specified substring", selector: "[class^= apple]", ctx: "#attr-begins", expect: [] /*no matches*/, level: 3, testType: TEST_FIND}, + + // - substring ends-with [att$=val] (Level 3) + {name: "Attribute ends with selector, matching href attributes ending with specified substring", selector: "a[href$=\".org\"]", ctx: "#attr-ends", expect: ["attr-ends-a1", "attr-ends-a3"], level: 3, testType: TEST_FIND | TEST_MATCH}, + {name: "Attribute ends with selector, matching lang attributes ending with specified substring, ", selector: "[lang$=\"-CH\"]", ctx: "#attr-ends", expect: ["attr-ends-div2", "attr-ends-div4"], level: 3, testType: TEST_FIND | TEST_MATCH}, + {name: "Attribute ends with selector, not matching class attribute with empty value", selector: "[class$=\"\"]", ctx: "#attr-ends", expect: [] /*no matches*/, level: 3, testType: TEST_FIND}, + {name: "Attribute ends with selector, not matching class attribute not ending with specified substring", selector: "[class$=apple]", ctx: "#attr-ends", expect: [] /*no matches*/, level: 3, testType: TEST_FIND}, + {name: "Attribute ends with selector with single-quoted value, matching class attribute ending with specified substring", selector: "[class$='apple ']", ctx: "#attr-ends", expect: ["attr-ends-p1"], level: 3, testType: TEST_FIND | TEST_MATCH}, + {name: "Attribute ends with selector with double-quoted value, matching class attribute ending with specified substring", selector: "[class$=\"apple \"]", ctx: "#attr-ends", expect: ["attr-ends-p1"], level: 3, testType: TEST_FIND | TEST_MATCH}, + {name: "Attribute ends with selector with unquoted value, not matching class attribute not ending with specified substring", selector: "[class$=apple ]", ctx: "#attr-ends", expect: [] /*no matches*/, level: 3, testType: TEST_FIND}, + + // - substring contains [att*=val] (Level 3) + {name: "Attribute contains selector, matching href attributes beginning with specified substring", selector: "a[href*=\"http://www\"]", ctx: "#attr-contains", expect: ["attr-contains-a1", "attr-contains-a3"], level: 3, testType: TEST_FIND | TEST_MATCH}, + {name: "Attribute contains selector, matching href attributes ending with specified substring", selector: "a[href*=\".org\"]", ctx: "#attr-contains", expect: ["attr-contains-a1", "attr-contains-a2"], level: 3, testType: TEST_FIND | TEST_MATCH}, + {name: "Attribute contains selector, matching href attributes containing specified substring", selector: "a[href*=\".example.\"]", ctx: "#attr-contains", expect: ["attr-contains-a1", "attr-contains-a3"], level: 3, testType: TEST_FIND | TEST_MATCH}, + {name: "Attribute contains selector, matching lang attributes beginning with specified substring, ", selector: "[lang*=\"en-\"]", ctx: "#attr-contains", expect: ["attr-contains-div2", "attr-contains-div6"], level: 3, testType: TEST_FIND | TEST_MATCH}, + {name: "Attribute contains selector, matching lang attributes ending with specified substring, ", selector: "[lang*=\"-CH\"]", ctx: "#attr-contains", expect: ["attr-contains-div3", "attr-contains-div5"], level: 3, testType: TEST_FIND | TEST_MATCH}, + {name: "Attribute contains selector, not matching class attribute with empty value", selector: "[class*=\"\"]", ctx: "#attr-contains", expect: [] /*no matches*/, level: 3, testType: TEST_FIND}, + {name: "Attribute contains selector with single-quoted value, matching class attribute beginning with specified substring", selector: "[class*=' apple']", ctx: "#attr-contains", expect: ["attr-contains-p1"], level: 3, testType: TEST_FIND | TEST_MATCH}, + {name: "Attribute contains selector with single-quoted value, matching class attribute ending with specified substring", selector: "[class*='orange ']", ctx: "#attr-contains", expect: ["attr-contains-p1"], level: 3, testType: TEST_FIND | TEST_MATCH}, + {name: "Attribute contains selector with single-quoted value, matching class attribute containing specified substring", selector: "[class*='ple banana ora']", ctx: "#attr-contains", expect: ["attr-contains-p1"], level: 3, testType: TEST_FIND | TEST_MATCH}, + {name: "Attribute contains selector with double-quoted value, matching class attribute beginning with specified substring", selector: "[class*=\" apple\"]", ctx: "#attr-contains", expect: ["attr-contains-p1"], level: 3, testType: TEST_FIND | TEST_MATCH}, + {name: "Attribute contains selector with double-quoted value, matching class attribute ending with specified substring", selector: "[class*=\"orange \"]", ctx: "#attr-contains", expect: ["attr-contains-p1"], level: 3, testType: TEST_FIND | TEST_MATCH}, + {name: "Attribute contains selector with double-quoted value, matching class attribute containing specified substring", selector: "[class*=\"ple banana ora\"]", ctx: "#attr-contains", expect: ["attr-contains-p1"], level: 3, testType: TEST_FIND | TEST_MATCH}, + {name: "Attribute contains selector with unquoted value, matching class attribute beginning with specified substring", selector: "[class*= apple]", ctx: "#attr-contains", expect: ["attr-contains-p1"], level: 3, testType: TEST_FIND | TEST_MATCH}, + {name: "Attribute contains selector with unquoted value, matching class attribute ending with specified substring", selector: "[class*=orange ]", ctx: "#attr-contains", expect: ["attr-contains-p1"], level: 3, testType: TEST_FIND | TEST_MATCH}, + {name: "Attribute contains selector with unquoted value, matching class attribute containing specified substring", selector: "[class*= banana ]", ctx: "#attr-contains", expect: ["attr-contains-p1"], level: 3, testType: TEST_FIND | TEST_MATCH}, + + // Pseudo-classes + // - :root (Level 3) + {name: ":root pseudo-class selector, matching document root element", selector: ":root", expect: ["html"], exclude: ["element", "fragment", "detached"], level: 3, testType: TEST_FIND}, + {name: ":root pseudo-class selector, not matching document root element", selector: ":root", expect: [] /*no matches*/, exclude: ["document"], level: 3, testType: TEST_FIND}, + {name: ":root pseudo-class selector, not matching document root element", selector: ":root", ctx: "#html", expect: [] /*no matches*/, exclude: ["fragment", "detached"], level: 3, testType: TEST_FIND}, + + // - :nth-child(n) (Level 3) + {name: ":nth-child selector, matching the third child element", selector: ":nth-child(3)", ctx: "#pseudo-nth-table1", expect: ["pseudo-nth-td3", "pseudo-nth-td9", "pseudo-nth-tr3", "pseudo-nth-td15"], level: 3, testType: TEST_FIND | TEST_MATCH}, + {name: ":nth-child selector, matching every third child element", selector: "li:nth-child(3n)", ctx: "#pseudo-nth", expect: ["pseudo-nth-li3", "pseudo-nth-li6", "pseudo-nth-li9", "pseudo-nth-li12"], level: 3, testType: TEST_FIND | TEST_MATCH}, + {name: ":nth-child selector, matching every second child element, starting from the fourth", selector: "li:nth-child(2n+4)", ctx: "#pseudo-nth", expect: ["pseudo-nth-li4", "pseudo-nth-li6", "pseudo-nth-li8", "pseudo-nth-li10", "pseudo-nth-li12"], level: 3, testType: TEST_FIND | TEST_MATCH}, + {name: ":nth-child selector, matching every second child element, starting from the fourth, with whitespace", selector: "li:nth-child(2n \t\r\n+ \t\r\n4)", ctx: "#pseudo-nth", expect: ["pseudo-nth-li4", "pseudo-nth-li6", "pseudo-nth-li8", "pseudo-nth-li10", "pseudo-nth-li12"], level: 3, testType: TEST_FIND | TEST_MATCH}, + {name: ":nth-child selector, matching every fourth child element, starting from the third", selector: ":nth-child(4n-1)", ctx: "#pseudo-nth-p1", expect: ["pseudo-nth-em2", "pseudo-nth-span3"], level: 3, testType: TEST_FIND | TEST_MATCH}, + {name: ":nth-child selector, matching every fourth child element, starting from the third, with whitespace", selector: ":nth-child(4n \t\r\n- \t\r\n1)", ctx: "#pseudo-nth-p1", expect: ["pseudo-nth-em2", "pseudo-nth-span3"], level: 3, testType: TEST_FIND | TEST_MATCH}, + {name: ":nth-child selector used twice, matching ", selector: ":nth-child(1) :nth-child(1)", ctx: "#pseudo-nth", expect: ["pseudo-nth-table1", "pseudo-nth-tr1"], level: 3, testType: TEST_FIND | TEST_MATCH}, + + // - :nth-last-child (Level 3) + {name: ":nth-last-child selector, matching the third last child element", selector: ":nth-last-child(3)", ctx: "#pseudo-nth-table1", expect: ["pseudo-nth-tr1", "pseudo-nth-td4", "pseudo-nth-td10", "pseudo-nth-td16"], level: 3, testType: TEST_FIND | TEST_MATCH}, + {name: ":nth-last-child selector, matching every third child element from the end", selector: "li:nth-last-child(3n)", ctx: "pseudo-nth", expect: ["pseudo-nth-li1", "pseudo-nth-li4", "pseudo-nth-li7", "pseudo-nth-li10"], level: 3, testType: TEST_FIND | TEST_MATCH}, + {name: ":nth-last-child selector, matching every second child element from the end, starting from the fourth last", selector: "li:nth-last-child(2n+4)", ctx: "pseudo-nth", expect: ["pseudo-nth-li1", "pseudo-nth-li3", "pseudo-nth-li5", "pseudo-nth-li7", "pseudo-nth-li9"], level: 3, testType: TEST_FIND | TEST_MATCH}, + {name: ":nth-last-child selector, matching every fourth element from the end, starting from the third last", selector: ":nth-last-child(4n-1)", ctx: "#pseudo-nth-p1", expect: ["pseudo-nth-span2", "pseudo-nth-span4"], level: 3, testType: TEST_FIND | TEST_MATCH}, + + // - :nth-of-type(n) (Level 3) + {name: ":nth-of-type selector, matching the third em element", selector: "em:nth-of-type(3)", ctx: "#pseudo-nth-p1", expect: ["pseudo-nth-em3"], level: 3, testType: TEST_FIND | TEST_MATCH}, + {name: ":nth-of-type selector, matching every second element of their type", selector: ":nth-of-type(2n)", ctx: "#pseudo-nth-p1", expect: ["pseudo-nth-em2", "pseudo-nth-span2", "pseudo-nth-span4", "pseudo-nth-strong2", "pseudo-nth-em4"], level: 3, testType: TEST_FIND | TEST_MATCH}, + {name: ":nth-of-type selector, matching every second elemetn of their type, starting from the first", selector: "span:nth-of-type(2n-1)", ctx: "#pseudo-nth-p1", expect: ["pseudo-nth-span1", "pseudo-nth-span3"], level: 3, testType: TEST_FIND | TEST_MATCH}, + + // - :nth-last-of-type(n) (Level 3) + {name: ":nth-last-of-type selector, matching the third last em element", selector: "em:nth-last-of-type(3)", ctx: "#pseudo-nth-p1", expect: ["pseudo-nth-em2"], level: 3, testType: TEST_FIND | TEST_MATCH}, + {name: ":nth-last-of-type selector, matching every second last element of their type", selector: ":nth-last-of-type(2n)", ctx: "#pseudo-nth-p1", expect: ["pseudo-nth-span1", "pseudo-nth-em1", "pseudo-nth-strong1", "pseudo-nth-em3", "pseudo-nth-span3"], level: 3, testType: TEST_FIND | TEST_MATCH}, + {name: ":nth-last-of-type selector, matching every second last element of their type, starting from the last", selector: "span:nth-last-of-type(2n-1)", ctx: "#pseudo-nth-p1", expect: ["pseudo-nth-span2", "pseudo-nth-span4"], level: 3, testType: TEST_FIND | TEST_MATCH}, + + // - :first-of-type (Level 3) + {name: ":first-of-type selector, matching the first em element", selector: "em:first-of-type", ctx: "#pseudo-nth-p1", expect: ["pseudo-nth-em1"], level: 3, testType: TEST_FIND | TEST_MATCH}, + {name: ":first-of-type selector, matching the first of every type of element", selector: ":first-of-type", ctx: "#pseudo-nth-p1", expect: ["pseudo-nth-span1", "pseudo-nth-em1", "pseudo-nth-strong1"], level: 3, testType: TEST_FIND | TEST_MATCH}, + {name: ":first-of-type selector, matching the first td element in each table row", selector: "tr :first-of-type", ctx: "#pseudo-nth-table1", expect: ["pseudo-nth-td1", "pseudo-nth-td7", "pseudo-nth-td13"], level: 3, testType: TEST_FIND | TEST_MATCH}, + + // - :last-of-type (Level 3) + {name: ":last-of-type selector, matching the last em elemnet", selector: "em:last-of-type", ctx: "#pseudo-nth-p1", expect: ["pseudo-nth-em4"], level: 3, testType: TEST_FIND | TEST_MATCH}, + {name: ":last-of-type selector, matching the last of every type of element", selector: ":last-of-type", ctx: "#pseudo-nth-p1", expect: ["pseudo-nth-span4", "pseudo-nth-strong2", "pseudo-nth-em4"], level: 3, testType: TEST_FIND | TEST_MATCH}, + {name: ":last-of-type selector, matching the last td element in each table row", selector: "tr :last-of-type", ctx: "#pseudo-nth-table1", expect: ["pseudo-nth-td6", "pseudo-nth-td12", "pseudo-nth-td18"], level: 3, testType: TEST_FIND | TEST_MATCH}, + + // - :first-child + {name: ":first-child pseudo-class selector, matching first child div element", selector: "div:first-child", ctx: "#pseudo-first-child", expect: ["pseudo-first-child-div1"], level: 2, testType: TEST_FIND | TEST_MATCH}, + {name: ":first-child pseudo-class selector, doesn't match non-first-child elements", selector: ".pseudo-first-child-div2:first-child, .pseudo-first-child-div3:first-child", ctx: "#pseudo-first-child", expect: [] /*no matches*/, level: 2, testType: TEST_FIND}, + {name: ":first-child pseudo-class selector, matching first-child of multiple elements", selector: "span:first-child", ctx: "#pseudo-first-child", expect: ["pseudo-first-child-span1", "pseudo-first-child-span3", "pseudo-first-child-span5"], level: 2, testType: TEST_FIND | TEST_MATCH}, + + // - :last-child (Level 3) + {name: ":last-child pseudo-class selector, matching last child div element", selector: "div:last-child", ctx: "#pseudo-last-child", expect: ["pseudo-last-child-div3"], level: 3, testType: TEST_FIND | TEST_MATCH}, + {name: ":last-child pseudo-class selector, doesn't match non-last-child elements", selector: ".pseudo-last-child-div1:last-child, .pseudo-last-child-div2:first-child", ctx: "#pseudo-last-child", expect: [] /*no matches*/, level: 3, testType: TEST_FIND}, + {name: ":last-child pseudo-class selector, matching first-child of multiple elements", selector: "span:last-child", ctx: "#pseudo-last-child", expect: ["pseudo-last-child-span2", "pseudo-last-child-span4", "pseudo-last-child-span6"], level: 3, testType: TEST_FIND | TEST_MATCH}, + + // - :only-child (Level 3) + {name: ":pseudo-only-child pseudo-class selector, matching all only-child elements", selector: ":only-child", ctx: "#pseudo-only", expect: ["pseudo-only-span1"], level: 3, testType: TEST_FIND | TEST_MATCH}, + {name: ":pseudo-only-child pseudo-class selector, matching only-child em elements", selector: "em:only-child", ctx: "#pseudo-only", expect: [] /*no matches*/, level: 3, testType: TEST_FIND}, + + // - :only-of-type (Level 3) + {name: ":pseudo-only-of-type pseudo-class selector, matching all elements with no siblings of the same type", selector: " :only-of-type", ctx: "#pseudo-only", expect: ["pseudo-only-span1", "pseudo-only-em1"], level: 3, testType: TEST_FIND | TEST_MATCH}, + {name: ":pseudo-only-of-type pseudo-class selector, matching em elements with no siblings of the same type", selector: " em:only-of-type", ctx: "#pseudo-only", expect: ["pseudo-only-em1"], level: 3, testType: TEST_FIND | TEST_MATCH}, + + // - :empty (Level 3) + {name: ":empty pseudo-class selector, matching empty p elements", selector: "p:empty", ctx: "#pseudo-empty", expect: ["pseudo-empty-p1", "pseudo-empty-p2"], level: 3, testType: TEST_FIND | TEST_MATCH}, + {name: ":empty pseudo-class selector, matching all empty elements", selector: ":empty", ctx: "#pseudo-empty", expect: ["pseudo-empty-p1", "pseudo-empty-p2", "pseudo-empty-span1"], level: 3, testType: TEST_FIND | TEST_MATCH}, + + // - :link and :visited + // Implementations may treat all visited links as unvisited, so these cannot be tested separately. + // The only guarantee is that ":link,:visited" matches the set of all visited and unvisited links and that they are individually mutually exclusive sets. + {name: ":link and :visited pseudo-class selectors, matching a and area elements with href attributes", selector: " :link, #pseudo-link :visited", ctx: "#pseudo-link", expect: ["pseudo-link-a1", "pseudo-link-a2", "pseudo-link-area1"], level: 1, testType: TEST_FIND | TEST_MATCH}, + {name: ":link and :visited pseudo-class selectors, matching no elements", selector: " :link, #head :visited", ctx: "#head", expect: [] /*no matches*/, exclude: ["element", "fragment", "detached"], level: 1, testType: TEST_FIND | TEST_MATCH}, + {name: ":link and :visited pseudo-class selectors, not matching link elements with href attributes", selector: " :link, #head :visited", ctx: "#head", expect: [] /*no matches*/, exclude: ["document"], level: 1, testType: TEST_FIND}, + {name: ":link and :visited pseudo-class selectors, chained, mutually exclusive pseudo-classes match nothing", selector: ":link:visited", ctx: "#html", expect: [] /*no matches*/, exclude: ["document"], level: 1, testType: TEST_FIND}, + +// XXX Figure out context or refNodes for this + // - :target (Level 3) + {name: ":target pseudo-class selector, matching the element referenced by the URL fragment identifier", selector: ":target", ctx: "", expect: [] /*no matches*/, exclude: ["document", "element"], level: 3, testType: TEST_FIND}, + {name: ":target pseudo-class selector, matching the element referenced by the URL fragment identifier", selector: ":target", ctx: "", expect: ["target"], exclude: ["fragment", "detached"], level: 3, testType: TEST_FIND}, + +// XXX Fix ctx in tests below + + // - :lang() + {name: ":lang pseudo-class selector, matching inherited language (1)", selector: "#pseudo-lang-div1:lang(en)", ctx: "", expect: ["pseudo-lang-div1"], exclude: ["detached", "fragment"], level: 2, testType: TEST_FIND | TEST_MATCH}, + {name: ":lang pseudo-class selector, not matching element with no inherited language", selector: "#pseudo-lang-div1:lang(en)", ctx: "", expect: [] /*no matches*/, exclude: ["document", "element"], level: 2, testType: TEST_FIND}, + {name: ":lang pseudo-class selector, matching specified language with exact value (1)", selector: "#pseudo-lang-div2:lang(fr)", ctx: "", expect: ["pseudo-lang-div2"], level: 2, testType: TEST_FIND | TEST_MATCH}, + {name: ":lang pseudo-class selector, matching specified language with partial value (1)", selector: "#pseudo-lang-div3:lang(en)", ctx: "", expect: ["pseudo-lang-div3"], level: 2, testType: TEST_FIND | TEST_MATCH}, + {name: ":lang pseudo-class selector, not matching incorrect language", selector: "#pseudo-lang-div4:lang(es-AR)", ctx: "", expect: [] /*no matches*/, level: 2, testType: TEST_FIND}, + + // - :enabled (Level 3) + {name: ":enabled pseudo-class selector, matching all enabled form controls (1)", selector: "#pseudo-ui :enabled", ctx: "", expect: ["pseudo-ui-input1", "pseudo-ui-input2", "pseudo-ui-input3", "pseudo-ui-input4", "pseudo-ui-input5", "pseudo-ui-input6", + "pseudo-ui-input7", "pseudo-ui-input8", "pseudo-ui-input9", "pseudo-ui-textarea1", "pseudo-ui-button1"], level: 3, testType: TEST_FIND | TEST_MATCH}, + {name: ":enabled pseudo-class selector, not matching link elements (1)", selector: "#pseudo-link :enabled", ctx: "", expect: [] /*no matches*/, unexpected: ["pseudo-link-a1","pseudo-link-a2","pseudo-link-a3","pseudo-link-map1","pseudo-link-area1","pseudo-link-area2"], level: 3, testType: TEST_QSA | TEST_MATCH}, + + // - :disabled (Level 3) + {name: ":disabled pseudo-class selector, matching all disabled form controls (1)", selector: "#pseudo-ui :disabled", ctx: "", expect: ["pseudo-ui-input10", "pseudo-ui-input11", "pseudo-ui-input12", "pseudo-ui-input13", "pseudo-ui-input14", "pseudo-ui-input15", + "pseudo-ui-input16", "pseudo-ui-input17", "pseudo-ui-input18", "pseudo-ui-textarea2", "pseudo-ui-button2"], level: 3, testType: TEST_FIND | TEST_MATCH}, + {name: ":disabled pseudo-class selector, not matching link elements (1)", selector: "#pseudo-link :disabled", ctx: "", expect: [] /*no matches*/, unexpected: ["pseudo-link-a1","pseudo-link-a2","pseudo-link-a3","pseudo-link-map1","pseudo-link-area1","pseudo-link-area2"], level: 3, testType: TEST_QSA | TEST_MATCH}, + + // - :checked (Level 3) + {name: ":checked pseudo-class selector, matching checked radio buttons and checkboxes (1)", selector: "#pseudo-ui :checked", ctx: "", expect: ["pseudo-ui-input4", "pseudo-ui-input6", "pseudo-ui-input13", "pseudo-ui-input15"], level: 3, testType: TEST_FIND | TEST_MATCH}, + + // - :not(s) (Level 3) + {name: ":not pseudo-class selector, matching (1)", selector: "#not>:not(div)", ctx: "", expect: ["not-p1", "not-p2", "not-p3"], level: 3, testType: TEST_FIND | TEST_MATCH}, + {name: ":not pseudo-class selector, matching (1)", selector: "#not * :not(:first-child)", ctx: "", expect: ["not-em1", "not-em2", "not-em3"], level: 3, testType: TEST_FIND | TEST_MATCH}, + {name: ":not pseudo-class selector, matching nothing", selector: ":not(*)", ctx: "", expect: [] /* no matches */, level: 3, testType: TEST_FIND}, + {name: ":not pseudo-class selector, matching nothing", selector: ":not(*|*)", ctx: "", expect: [] /* no matches */, level: 3, testType: TEST_FIND}, + + // Pseudo-elements + // - ::first-line + {name: ":first-line pseudo-element (one-colon syntax) selector, not matching any elements", selector: "#pseudo-element:first-line", ctx: "", expect: [] /*no matches*/, level: 2, testType: TEST_FIND}, + {name: "::first-line pseudo-element (two-colon syntax) selector, not matching any elements", selector: "#pseudo-element::first-line", ctx: "", expect: [] /*no matches*/, level: 3, testType: TEST_FIND}, + + // - ::first-letter + {name: ":first-letter pseudo-element (one-colon syntax) selector, not matching any elements", selector: "#pseudo-element:first-letter", ctx: "", expect: [] /*no matches*/, level: 2, testType: TEST_FIND}, + {name: "::first-letter pseudo-element (two-colon syntax) selector, not matching any elements", selector: "#pseudo-element::first-letter", ctx: "", expect: [] /*no matches*/, level: 3, testType: TEST_FIND}, + + // - ::before + {name: ":before pseudo-element (one-colon syntax) selector, not matching any elements", selector: "#pseudo-element:before", ctx: "", expect: [] /*no matches*/, level: 2, testType: TEST_FIND}, + {name: "::before pseudo-element (two-colon syntax) selector, not matching any elements", selector: "#pseudo-element::before", ctx: "", expect: [] /*no matches*/, level: 3, testType: TEST_FIND}, + + // - ::after + {name: ":after pseudo-element (one-colon syntax) selector, not matching any elements", selector: "#pseudo-element:after", ctx: "", expect: [] /*no matches*/, level: 2, testType: TEST_FIND}, + {name: "::after pseudo-element (two-colon syntax) selector, not matching any elements", selector: "#pseudo-element::after", ctx: "", expect: [] /*no matches*/, level: 3, testType: TEST_FIND}, + + // Class Selectors + {name: "Class selector, matching element with specified class (1)", selector: ".class-p", ctx: "", expect: ["class-p1","class-p2", "class-p3"], level: 1, testType: TEST_FIND | TEST_MATCH}, + {name: "Class selector, chained, matching only elements with all specified classes (1)", selector: "#class .apple.orange.banana", ctx: "", expect: ["class-div1", "class-div2", "class-p4", "class-div3", "class-p6", "class-div4"], level: 1, testType: TEST_FIND | TEST_MATCH}, + {name: "Class Selector, chained, with type selector (1)", selector: "div.apple.banana.orange", ctx: "", expect: ["class-div1", "class-div2", "class-div3", "class-div4"], level: 1, testType: TEST_FIND | TEST_MATCH}, + {name: "Class selector, matching element with class value using non-ASCII characters (2)", selector: ".\u53F0\u5317Ta\u0301ibe\u030Ci", ctx: "", expect: ["class-span1"], level: 1, testType: TEST_FIND | TEST_MATCH}, + {name: "Class selector, matching multiple elements with class value using non-ASCII characters (1)", selector: ".\u53F0\u5317", ctx: "", expect: ["class-span1","class-span2"], level: 1, testType: TEST_FIND | TEST_MATCH}, + {name: "Class selector, chained, matching element with multiple class values using non-ASCII characters (2)", selector: ".\u53F0\u5317Ta\u0301ibe\u030Ci.\u53F0\u5317", ctx: "", expect: ["class-span1"], level: 1, testType: TEST_FIND | TEST_MATCH}, + {name: "Class selector, matching element with class with escaped character (1)", selector: ".foo\\:bar", ctx: "", expect: ["class-span3"], level: 1, testType: TEST_FIND | TEST_MATCH}, + {name: "Class selector, matching element with class with escaped character (1)", selector: ".test\\.foo\\[5\\]bar", ctx: "", expect: ["class-span4"], level: 1, testType: TEST_FIND | TEST_MATCH}, + + // ID Selectors + {name: "ID selector, matching element with specified id (1)", selector: "#id #id-div1", ctx: "", expect: ["id-div1"], level: 1, testType: TEST_FIND | TEST_MATCH}, + {name: "ID selector, chained, matching element with specified id (1)", selector: "#id-div1, #id-div1", ctx: "", expect: ["id-div1"], level: 1, testType: TEST_FIND | TEST_MATCH}, + {name: "ID selector, chained, matching element with specified id (1)", selector: "#id-div1, #id-div2", ctx: "", expect: ["id-div1", "id-div2"], level: 1, testType: TEST_FIND | TEST_MATCH}, + {name: "ID Selector, chained, with type selector (1)", selector: "div#id-div1, div#id-div2", ctx: "", expect: ["id-div1", "id-div2"], level: 1, testType: TEST_FIND | TEST_MATCH}, + {name: "ID selector, not matching non-existent descendant", selector: "#id #none", ctx: "", expect: [] /*no matches*/, level: 1, testType: TEST_FIND}, + {name: "ID selector, not matching non-existent ancestor", selector: "#none #id-div1", ctx: "", expect: [] /*no matches*/, level: 1, testType: TEST_FIND}, + {name: "ID selector, matching multiple elements with duplicate id (1)", selector: "#id-li-duplicate", ctx: "", expect: ["id-li-duplicate", "id-li-duplicate", "id-li-duplicate", "id-li-duplicate"], level: 1, testType: TEST_FIND | TEST_MATCH}, + + {name: "ID selector, matching id value using non-ASCII characters (3)", selector: "#\u53F0\u5317Ta\u0301ibe\u030Ci", ctx: "", expect: ["\u53F0\u5317Ta\u0301ibe\u030Ci"], level: 1, testType: TEST_FIND | TEST_MATCH}, + {name: "ID selector, matching id value using non-ASCII characters (4)", selector: "#\u53F0\u5317", ctx: "", expect: ["\u53F0\u5317"], level: 1, testType: TEST_FIND | TEST_MATCH}, + {name: "ID selector, matching id values using non-ASCII characters (2)", selector: "#\u53F0\u5317Ta\u0301ibe\u030Ci, #\u53F0\u5317", ctx: "", expect: ["\u53F0\u5317Ta\u0301ibe\u030Ci", "\u53F0\u5317"], level: 1, testType: TEST_FIND | TEST_MATCH}, + + // XXX runMatchesTest() in level2-lib.js can't handle this because obtaining the expected nodes requires escaping characters when generating the selector from 'expect' values + {name: "ID selector, matching element with id with escaped character", selector: "#\\#foo\\:bar", ctx: "", expect: ["#foo:bar"], level: 1, testType: TEST_FIND}, + {name: "ID selector, matching element with id with escaped character", selector: "#test\\.foo\\[5\\]bar", ctx: "", expect: ["test.foo[5]bar"], level: 1, testType: TEST_FIND}, + + // Namespaces + // XXX runMatchesTest() in level2-lib.js can't handle these because non-HTML elements don't have a recognised id + {name: "Namespace selector, matching element with any namespace", selector: "#any-namespace *|div", ctx: "", expect: ["any-namespace-div1", "any-namespace-div2", "any-namespace-div3", "any-namespace-div4"], level: 3, testType: TEST_FIND}, + {name: "Namespace selector, matching div elements in no namespace only", selector: "#no-namespace |div", ctx: "", expect: ["no-namespace-div3"], level: 3, testType: TEST_FIND}, + {name: "Namespace selector, matching any elements in no namespace only", selector: "#no-namespace |*", ctx: "", expect: ["no-namespace-div3"], level: 3, testType: TEST_FIND}, + + // Combinators + // - Descendant combinator ' ' + {name: "Descendant combinator, matching element that is a descendant of an element with id (1)", selector: "#descendant div", ctx: "", expect: ["descendant-div1", "descendant-div2", "descendant-div3", "descendant-div4"], level: 1, testType: TEST_FIND | TEST_MATCH}, + {name: "Descendant combinator, matching element with id that is a descendant of an element (1)", selector: "body #descendant-div1", ctx: "", expect: ["descendant-div1"], exclude: ["detached", "fragment"], level: 1, testType: TEST_FIND | TEST_MATCH}, + {name: "Descendant combinator, matching element with id that is a descendant of an element (1)", selector: "div #descendant-div1", ctx: "", expect: ["descendant-div1"], level: 1, testType: TEST_FIND | TEST_MATCH}, + {name: "Descendant combinator, matching element with id that is a descendant of an element with id (1)", selector: "#descendant #descendant-div2", ctx: "", expect: ["descendant-div2"], level: 1, testType: TEST_FIND | TEST_MATCH}, + {name: "Descendant combinator, matching element with class that is a descendant of an element with id (1)", selector: "#descendant .descendant-div2", ctx: "", expect: ["descendant-div2"], level: 1, testType: TEST_FIND | TEST_MATCH}, + {name: "Descendant combinator, matching element with class that is a descendant of an element with class (1)", selector: ".descendant-div1 .descendant-div3", ctx: "", expect: ["descendant-div3"], level: 1, testType: TEST_FIND | TEST_MATCH}, + {name: "Descendant combinator, not matching element with id that is not a descendant of an element with id", selector: "#descendant-div1 #descendant-div4", ctx: "", expect: [] /*no matches*/, level: 1, testType: TEST_FIND}, + {name: "Descendant combinator, whitespace characters (1)", selector: "#descendant\t\r\n#descendant-div2", ctx: "", expect: ["descendant-div2"], level: 1, testType: TEST_FIND | TEST_MATCH}, + + // // - Descendant combinator '>>' + // {name: "Descendant combinator '>>', matching element that is a descendant of an element with id (1)", selector: "#descendant>>div", ctx: "", expect: ["descendant-div1", "descendant-div2", "descendant-div3", "descendant-div4"], level: 1, testType: TEST_FIND | TEST_MATCH}, + // {name: "Descendant combinator '>>', matching element with id that is a descendant of an element (1)", selector: "body>>#descendant-div1", ctx: "", expect: ["descendant-div1"], exclude: ["detached", "fragment"], level: 1, testType: TEST_FIND | TEST_MATCH}, + // {name: "Descendant combinator '>>', matching element with id that is a descendant of an element (1)", selector: "div>>#descendant-div1", ctx: "", expect: ["descendant-div1"], level: 1, testType: TEST_FIND | TEST_MATCH}, + // {name: "Descendant combinator '>>', matching element with id that is a descendant of an element with id (1)", selector: "#descendant>>#descendant-div2", ctx: "", expect: ["descendant-div2"], level: 1, testType: TEST_FIND | TEST_MATCH}, + // {name: "Descendant combinator '>>', matching element with class that is a descendant of an element with id (1)", selector: "#descendant>>.descendant-div2", ctx: "", expect: ["descendant-div2"], level: 1, testType: TEST_FIND | TEST_MATCH}, + // {name: "Descendant combinator, '>>', matching element with class that is a descendant of an element with class (1)", selector: ".descendant-div1>>.descendant-div3", ctx: "", expect: ["descendant-div3"], level: 1, testType: TEST_FIND | TEST_MATCH}, + // {name: "Descendant combinator '>>', not matching element with id that is not a descendant of an element with id", selector: "#descendant-div1>>#descendant-div4", ctx: "", expect: [] /*no matches*/, level: 1, testType: TEST_FIND}, + + // - Child combinator '>' + {name: "Child combinator, matching element that is a child of an element with id (1)", selector: "#child>div", ctx: "", expect: ["child-div1", "child-div4"], level: 2, testType: TEST_FIND | TEST_MATCH}, + {name: "Child combinator, matching element with id that is a child of an element (1)", selector: "div>#child-div1", ctx: "", expect: ["child-div1"], level: 2, testType: TEST_FIND | TEST_MATCH}, + {name: "Child combinator, matching element with id that is a child of an element with id (1)", selector: "#child>#child-div1", ctx: "", expect: ["child-div1"], level: 2, testType: TEST_FIND | TEST_MATCH}, + {name: "Child combinator, matching element with id that is a child of an element with class (1)", selector: "#child-div1>.child-div2", ctx: "", expect: ["child-div2"], level: 2, testType: TEST_FIND | TEST_MATCH}, + {name: "Child combinator, matching element with class that is a child of an element with class (1)", selector: ".child-div1>.child-div2", ctx: "", expect: ["child-div2"], level: 2, testType: TEST_FIND | TEST_MATCH}, + {name: "Child combinator, not matching element with id that is not a child of an element with id", selector: "#child>#child-div3", ctx: "", expect: [] /*no matches*/, level: 2, testType: TEST_FIND}, + {name: "Child combinator, not matching element with id that is not a child of an element with class", selector: "#child-div1>.child-div3", ctx: "", expect: [] /*no matches*/, level: 2, testType: TEST_FIND}, + {name: "Child combinator, not matching element with class that is not a child of an element with class", selector: ".child-div1>.child-div3", ctx: "", expect: [] /*no matches*/, level: 2, testType: TEST_FIND}, + {name: "Child combinator, surrounded by whitespace (1)", selector: "#child-div1\t\r\n>\t\r\n#child-div2", ctx: "", expect: ["child-div2"], level: 2, testType: TEST_FIND | TEST_MATCH}, + {name: "Child combinator, whitespace after (1)", selector: "#child-div1>\t\r\n#child-div2", ctx: "", expect: ["child-div2"], level: 2, testType: TEST_FIND | TEST_MATCH}, + {name: "Child combinator, whitespace before (1)", selector: "#child-div1\t\r\n>#child-div2", ctx: "", expect: ["child-div2"], level: 2, testType: TEST_FIND | TEST_MATCH}, + {name: "Child combinator, no whitespace (1)", selector: "#child-div1>#child-div2", ctx: "", expect: ["child-div2"], level: 2, testType: TEST_FIND | TEST_MATCH}, + + // - Adjacent sibling combinator '+' + {name: "Adjacent sibling combinator, matching element that is an adjacent sibling of an element with id (1)", selector: "#adjacent-div2+div", ctx: "", expect: ["adjacent-div4"], level: 2, testType: TEST_FIND | TEST_MATCH}, + {name: "Adjacent sibling combinator, matching element with id that is an adjacent sibling of an element (1)", selector: "div+#adjacent-div4", ctx: "", expect: ["adjacent-div4"], level: 2, testType: TEST_FIND | TEST_MATCH}, + {name: "Adjacent sibling combinator, matching element with id that is an adjacent sibling of an element with id (1)", selector: "#adjacent-div2+#adjacent-div4", ctx: "", expect: ["adjacent-div4"], level: 2, testType: TEST_FIND | TEST_MATCH}, + {name: "Adjacent sibling combinator, matching element with class that is an adjacent sibling of an element with id (1)", selector: "#adjacent-div2+.adjacent-div4", ctx: "", expect: ["adjacent-div4"], level: 2, testType: TEST_FIND | TEST_MATCH}, + {name: "Adjacent sibling combinator, matching element with class that is an adjacent sibling of an element with class (1)", selector: ".adjacent-div2+.adjacent-div4", ctx: "", expect: ["adjacent-div4"], level: 2, testType: TEST_FIND | TEST_MATCH}, + {name: "Adjacent sibling combinator, matching p element that is an adjacent sibling of a div element (1)", selector: "#adjacent div+p", ctx: "", expect: ["adjacent-p2"], level: 2, testType: TEST_FIND | TEST_MATCH}, + {name: "Adjacent sibling combinator, not matching element with id that is not an adjacent sibling of an element with id", selector: "#adjacent-div2+#adjacent-p2, #adjacent-div2+#adjacent-div1", ctx: "", expect: [] /*no matches*/, level: 2, testType: TEST_FIND}, + {name: "Adjacent sibling combinator, surrounded by whitespace (1)", selector: "#adjacent-p2\t\r\n+\t\r\n#adjacent-p3", ctx: "", expect: ["adjacent-p3"], level: 2, testType: TEST_FIND | TEST_MATCH}, + {name: "Adjacent sibling combinator, whitespace after (1)", selector: "#adjacent-p2+\t\r\n#adjacent-p3", ctx: "", expect: ["adjacent-p3"], level: 2, testType: TEST_FIND | TEST_MATCH}, + {name: "Adjacent sibling combinator, whitespace before (1)", selector: "#adjacent-p2\t\r\n+#adjacent-p3", ctx: "", expect: ["adjacent-p3"], level: 2, testType: TEST_FIND | TEST_MATCH}, + {name: "Adjacent sibling combinator, no whitespace (1)", selector: "#adjacent-p2+#adjacent-p3", ctx: "", expect: ["adjacent-p3"], level: 2, testType: TEST_FIND | TEST_MATCH}, + + // - General sibling combinator ~ (Level 3) + {name: "General sibling combinator, matching element that is a sibling of an element with id (1)", selector: "#sibling-div2~div", ctx: "", expect: ["sibling-div4", "sibling-div6"], level: 3, testType: TEST_FIND | TEST_MATCH}, + {name: "General sibling combinator, matching element with id that is a sibling of an element (1)", selector: "div~#sibling-div4", ctx: "", expect: ["sibling-div4"], level: 3, testType: TEST_FIND | TEST_MATCH}, + {name: "General sibling combinator, matching element with id that is a sibling of an element with id (1)", selector: "#sibling-div2~#sibling-div4", ctx: "", expect: ["sibling-div4"], level: 3, testType: TEST_FIND | TEST_MATCH}, + {name: "General sibling combinator, matching element with class that is a sibling of an element with id (1)", selector: "#sibling-div2~.sibling-div", ctx: "", expect: ["sibling-div4", "sibling-div6"], level: 3, testType: TEST_FIND | TEST_MATCH}, + {name: "General sibling combinator, matching p element that is a sibling of a div element (1)", selector: "#sibling div~p", ctx: "", expect: ["sibling-p2", "sibling-p3"], level: 3, testType: TEST_FIND | TEST_MATCH}, + {name: "General sibling combinator, not matching element with id that is not a sibling after a p element (1)", selector: "#sibling>p~div", ctx: "", expect: [] /*no matches*/, level: 3, testType: TEST_FIND}, + {name: "General sibling combinator, not matching element with id that is not a sibling after an element with id", selector: "#sibling-div2~#sibling-div3, #sibling-div2~#sibling-div1", ctx: "", expect: [] /*no matches*/, level: 3, testType: TEST_FIND}, + {name: "General sibling combinator, surrounded by whitespace (1)", selector: "#sibling-p2\t\r\n~\t\r\n#sibling-p3", ctx: "", expect: ["sibling-p3"], level: 3, testType: TEST_FIND | TEST_MATCH}, + {name: "General sibling combinator, whitespace after (1)", selector: "#sibling-p2~\t\r\n#sibling-p3", ctx: "", expect: ["sibling-p3"], level: 3, testType: TEST_FIND | TEST_MATCH}, + {name: "General sibling combinator, whitespace before (1)", selector: "#sibling-p2\t\r\n~#sibling-p3", ctx: "", expect: ["sibling-p3"], level: 3, testType: TEST_FIND | TEST_MATCH}, + {name: "General sibling combinator, no whitespace (1)", selector: "#sibling-p2~#sibling-p3", ctx: "", expect: ["sibling-p3"], level: 3, testType: TEST_FIND | TEST_MATCH}, + + // Group of selectors (comma) + {name: "Syntax, group of selectors separator, surrounded by whitespace (1)", selector: "#group em\t\r \n,\t\r \n#group strong", ctx: "", expect: ["group-em1", "group-strong1"], level: 1, testType: TEST_FIND | TEST_MATCH}, + {name: "Syntax, group of selectors separator, whitespace after (1)", selector: "#group em,\t\r\n#group strong", ctx: "", expect: ["group-em1", "group-strong1"], level: 1, testType: TEST_FIND | TEST_MATCH}, + {name: "Syntax, group of selectors separator, whitespace before (1)", selector: "#group em\t\r\n,#group strong", ctx: "", expect: ["group-em1", "group-strong1"], level: 1, testType: TEST_FIND | TEST_MATCH}, + {name: "Syntax, group of selectors separator, no whitespace (1)", selector: "#group em,#group strong", ctx: "", expect: ["group-em1", "group-strong1"], level: 1, testType: TEST_FIND | TEST_MATCH}, +]; diff --git a/testing/web-platform/tests/dom/nodes/support/NodeList-static-length-tampered.js b/testing/web-platform/tests/dom/nodes/support/NodeList-static-length-tampered.js new file mode 100644 index 0000000000..51167e2ddc --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/support/NodeList-static-length-tampered.js @@ -0,0 +1,46 @@ +"use strict"; + +function makeStaticNodeList(length) { + const fooRoot = document.createElement("div"); + + for (var i = 0; i < length; i++) { + const el = document.createElement("span"); + el.className = "foo"; + fooRoot.append(el); + } + + document.body.append(fooRoot); + return fooRoot.querySelectorAll(".foo"); +} + +const indexOfNodeList = new Function("nodeList", ` + const __cacheBust = ${Math.random()}; + + const el = nodeList[50]; + + let index = -1; + + for (var i = 0; i < 1e5 / 2; i++) { + for (var j = 0; j < nodeList.length; j++) { + if (nodeList[j] === el) { + index = j; + break; + } + } + } + + return index; +`); + +const arrayIndexOfNodeList = new Function("nodeList", ` + const __cacheBust = ${Math.random()}; + + const el = nodeList[50]; + const {indexOf} = Array.prototype; + + for (var i = 0; i < 1e5; i++) { + var index = indexOf.call(nodeList, el); + } + + return index; +`); diff --git a/testing/web-platform/tests/dom/nodes/svg-template-querySelector.html b/testing/web-platform/tests/dom/nodes/svg-template-querySelector.html new file mode 100644 index 0000000000..5d2f634143 --- /dev/null +++ b/testing/web-platform/tests/dom/nodes/svg-template-querySelector.html @@ -0,0 +1,29 @@ + + +querySelector on template fragments with SVG elements + + + + + + + + + diff --git a/testing/web-platform/tests/dom/ranges/Range-adopt-test.html b/testing/web-platform/tests/dom/ranges/Range-adopt-test.html new file mode 100644 index 0000000000..3735fc38fd --- /dev/null +++ b/testing/web-platform/tests/dom/ranges/Range-adopt-test.html @@ -0,0 +1,52 @@ + + + + diff --git a/testing/web-platform/tests/dom/ranges/Range-attributes.html b/testing/web-platform/tests/dom/ranges/Range-attributes.html new file mode 100644 index 0000000000..ced47edc50 --- /dev/null +++ b/testing/web-platform/tests/dom/ranges/Range-attributes.html @@ -0,0 +1,23 @@ + +Range attributes + + + + +
      + diff --git a/testing/web-platform/tests/dom/ranges/Range-cloneContents.html b/testing/web-platform/tests/dom/ranges/Range-cloneContents.html new file mode 100644 index 0000000000..6064151f62 --- /dev/null +++ b/testing/web-platform/tests/dom/ranges/Range-cloneContents.html @@ -0,0 +1,461 @@ + +Range.cloneContents() tests + + +

      To debug test failures, add a query parameter "subtest" with the test id (like +"?subtest=5"). Only that test will be run. Then you can look at the resulting +iframe in the DOM. +

      + + + + diff --git a/testing/web-platform/tests/dom/ranges/Range-cloneRange.html b/testing/web-platform/tests/dom/ranges/Range-cloneRange.html new file mode 100644 index 0000000000..6c736df29f --- /dev/null +++ b/testing/web-platform/tests/dom/ranges/Range-cloneRange.html @@ -0,0 +1,112 @@ + +Range.cloneRange() and document.createRange() tests + + +
      + + + + diff --git a/testing/web-platform/tests/dom/ranges/Range-collapse.html b/testing/web-platform/tests/dom/ranges/Range-collapse.html new file mode 100644 index 0000000000..141dbdf610 --- /dev/null +++ b/testing/web-platform/tests/dom/ranges/Range-collapse.html @@ -0,0 +1,67 @@ + +Range.collapse() and .collapsed tests + + +
      + + + + diff --git a/testing/web-platform/tests/dom/ranges/Range-commonAncestorContainer-2.html b/testing/web-platform/tests/dom/ranges/Range-commonAncestorContainer-2.html new file mode 100644 index 0000000000..f0a3e451cd --- /dev/null +++ b/testing/web-platform/tests/dom/ranges/Range-commonAncestorContainer-2.html @@ -0,0 +1,33 @@ + +Range.commonAncestorContainer + + +
      + diff --git a/testing/web-platform/tests/dom/ranges/Range-commonAncestorContainer.html b/testing/web-platform/tests/dom/ranges/Range-commonAncestorContainer.html new file mode 100644 index 0000000000..7882ccc31f --- /dev/null +++ b/testing/web-platform/tests/dom/ranges/Range-commonAncestorContainer.html @@ -0,0 +1,40 @@ + +Range.commonAncestorContainer tests + + +
      + + + + diff --git a/testing/web-platform/tests/dom/ranges/Range-compareBoundaryPoints.html b/testing/web-platform/tests/dom/ranges/Range-compareBoundaryPoints.html new file mode 100644 index 0000000000..9d150ae0ab --- /dev/null +++ b/testing/web-platform/tests/dom/ranges/Range-compareBoundaryPoints.html @@ -0,0 +1,182 @@ + +Range.compareBoundaryPoints() tests + + + +
      + + + + diff --git a/testing/web-platform/tests/dom/ranges/Range-comparePoint-2.html b/testing/web-platform/tests/dom/ranges/Range-comparePoint-2.html new file mode 100644 index 0000000000..30a6c57ad9 --- /dev/null +++ b/testing/web-platform/tests/dom/ranges/Range-comparePoint-2.html @@ -0,0 +1,23 @@ + +Range.comparePoint + + + + +
      + diff --git a/testing/web-platform/tests/dom/ranges/Range-comparePoint.html b/testing/web-platform/tests/dom/ranges/Range-comparePoint.html new file mode 100644 index 0000000000..e18ac95c4c --- /dev/null +++ b/testing/web-platform/tests/dom/ranges/Range-comparePoint.html @@ -0,0 +1,92 @@ + +Range.comparePoint() tests + + +
      + + + + diff --git a/testing/web-platform/tests/dom/ranges/Range-constructor.html b/testing/web-platform/tests/dom/ranges/Range-constructor.html new file mode 100644 index 0000000000..e8cfbef753 --- /dev/null +++ b/testing/web-platform/tests/dom/ranges/Range-constructor.html @@ -0,0 +1,20 @@ + +Range constructor test + +
      + + + diff --git a/testing/web-platform/tests/dom/ranges/Range-deleteContents.html b/testing/web-platform/tests/dom/ranges/Range-deleteContents.html new file mode 100644 index 0000000000..40dc400125 --- /dev/null +++ b/testing/web-platform/tests/dom/ranges/Range-deleteContents.html @@ -0,0 +1,337 @@ + +Range.deleteContents() tests + + +

      To debug test failures, add a query parameter "subtest" with the test id (like +"?subtest=5"). Only that test will be run. Then you can look at the resulting +iframe in the DOM. +

      + + + + diff --git a/testing/web-platform/tests/dom/ranges/Range-detach.html b/testing/web-platform/tests/dom/ranges/Range-detach.html new file mode 100644 index 0000000000..ac35d71369 --- /dev/null +++ b/testing/web-platform/tests/dom/ranges/Range-detach.html @@ -0,0 +1,14 @@ + +Range.detach + + + + +
      + diff --git a/testing/web-platform/tests/dom/ranges/Range-extractContents.html b/testing/web-platform/tests/dom/ranges/Range-extractContents.html new file mode 100644 index 0000000000..88f8fa55f8 --- /dev/null +++ b/testing/web-platform/tests/dom/ranges/Range-extractContents.html @@ -0,0 +1,252 @@ + +Range.extractContents() tests + + +

      To debug test failures, add a query parameter "subtest" with the test id (like +"?subtest=5"). Only that test will be run. Then you can look at the resulting +iframe in the DOM. +

      + + + + diff --git a/testing/web-platform/tests/dom/ranges/Range-insertNode.html b/testing/web-platform/tests/dom/ranges/Range-insertNode.html new file mode 100644 index 0000000000..b0a9d43f98 --- /dev/null +++ b/testing/web-platform/tests/dom/ranges/Range-insertNode.html @@ -0,0 +1,286 @@ + +Range.insertNode() tests + + +

      To debug test failures, add a query parameter "subtest" with the test id (like +"?subtest=5,16"). Only that test will be run. Then you can look at the resulting +iframes in the DOM. +

      + + + + diff --git a/testing/web-platform/tests/dom/ranges/Range-intersectsNode-2.html b/testing/web-platform/tests/dom/ranges/Range-intersectsNode-2.html new file mode 100644 index 0000000000..48072d98af --- /dev/null +++ b/testing/web-platform/tests/dom/ranges/Range-intersectsNode-2.html @@ -0,0 +1,36 @@ + +Range.intersectsNode + + +
      s0s1s2
      + diff --git a/testing/web-platform/tests/dom/ranges/Range-intersectsNode-binding.html b/testing/web-platform/tests/dom/ranges/Range-intersectsNode-binding.html new file mode 100644 index 0000000000..57d159b030 --- /dev/null +++ b/testing/web-platform/tests/dom/ranges/Range-intersectsNode-binding.html @@ -0,0 +1,25 @@ + +Range.intersectsNode + + + + +
      + diff --git a/testing/web-platform/tests/dom/ranges/Range-intersectsNode-shadow.html b/testing/web-platform/tests/dom/ranges/Range-intersectsNode-shadow.html new file mode 100644 index 0000000000..8219ba8285 --- /dev/null +++ b/testing/web-platform/tests/dom/ranges/Range-intersectsNode-shadow.html @@ -0,0 +1,19 @@ + +Range.intersectsNode with Shadow DOM + + +
      + + diff --git a/testing/web-platform/tests/dom/ranges/Range-intersectsNode.html b/testing/web-platform/tests/dom/ranges/Range-intersectsNode.html new file mode 100644 index 0000000000..97e10f6f0d --- /dev/null +++ b/testing/web-platform/tests/dom/ranges/Range-intersectsNode.html @@ -0,0 +1,70 @@ + +Range.intersectsNode() tests + + +
      + + + + diff --git a/testing/web-platform/tests/dom/ranges/Range-isPointInRange.html b/testing/web-platform/tests/dom/ranges/Range-isPointInRange.html new file mode 100644 index 0000000000..80db97e844 --- /dev/null +++ b/testing/web-platform/tests/dom/ranges/Range-isPointInRange.html @@ -0,0 +1,83 @@ + +Range.isPointInRange() tests + + +
      + + + + diff --git a/testing/web-platform/tests/dom/ranges/Range-mutations-appendChild.html b/testing/web-platform/tests/dom/ranges/Range-mutations-appendChild.html new file mode 100644 index 0000000000..5b5b5a55df --- /dev/null +++ b/testing/web-platform/tests/dom/ranges/Range-mutations-appendChild.html @@ -0,0 +1,14 @@ + +Range mutation tests - appendChild + + + +
      + + + + + diff --git a/testing/web-platform/tests/dom/ranges/Range-mutations-appendData.html b/testing/web-platform/tests/dom/ranges/Range-mutations-appendData.html new file mode 100644 index 0000000000..1d4879d57c --- /dev/null +++ b/testing/web-platform/tests/dom/ranges/Range-mutations-appendData.html @@ -0,0 +1,14 @@ + +Range mutation tests - appendData + + + +
      + + + + + diff --git a/testing/web-platform/tests/dom/ranges/Range-mutations-dataChange.html b/testing/web-platform/tests/dom/ranges/Range-mutations-dataChange.html new file mode 100644 index 0000000000..3683e8bb9b --- /dev/null +++ b/testing/web-platform/tests/dom/ranges/Range-mutations-dataChange.html @@ -0,0 +1,14 @@ + +Range mutation tests - update data by IDL attributes + + + +
      + + + + + diff --git a/testing/web-platform/tests/dom/ranges/Range-mutations-deleteData.html b/testing/web-platform/tests/dom/ranges/Range-mutations-deleteData.html new file mode 100644 index 0000000000..5f2b852f5b --- /dev/null +++ b/testing/web-platform/tests/dom/ranges/Range-mutations-deleteData.html @@ -0,0 +1,14 @@ + +Range mutation tests - deleteData + + + +
      + + + + + diff --git a/testing/web-platform/tests/dom/ranges/Range-mutations-insertBefore.html b/testing/web-platform/tests/dom/ranges/Range-mutations-insertBefore.html new file mode 100644 index 0000000000..c71b239547 --- /dev/null +++ b/testing/web-platform/tests/dom/ranges/Range-mutations-insertBefore.html @@ -0,0 +1,14 @@ + +Range mutation tests - insertBefore + + + +
      + + + + + diff --git a/testing/web-platform/tests/dom/ranges/Range-mutations-insertData.html b/testing/web-platform/tests/dom/ranges/Range-mutations-insertData.html new file mode 100644 index 0000000000..fca533d503 --- /dev/null +++ b/testing/web-platform/tests/dom/ranges/Range-mutations-insertData.html @@ -0,0 +1,14 @@ + +Range mutation tests - insertData + + + +
      + + + + + diff --git a/testing/web-platform/tests/dom/ranges/Range-mutations-removeChild.html b/testing/web-platform/tests/dom/ranges/Range-mutations-removeChild.html new file mode 100644 index 0000000000..a8d2381253 --- /dev/null +++ b/testing/web-platform/tests/dom/ranges/Range-mutations-removeChild.html @@ -0,0 +1,14 @@ + +Range mutation tests - removeChild + + + +
      + + + + + diff --git a/testing/web-platform/tests/dom/ranges/Range-mutations-replaceChild.html b/testing/web-platform/tests/dom/ranges/Range-mutations-replaceChild.html new file mode 100644 index 0000000000..a4ef0c365e --- /dev/null +++ b/testing/web-platform/tests/dom/ranges/Range-mutations-replaceChild.html @@ -0,0 +1,14 @@ + +Range mutation tests - replaceChild + + + +
      + + + + + diff --git a/testing/web-platform/tests/dom/ranges/Range-mutations-replaceData.html b/testing/web-platform/tests/dom/ranges/Range-mutations-replaceData.html new file mode 100644 index 0000000000..55ddb146ea --- /dev/null +++ b/testing/web-platform/tests/dom/ranges/Range-mutations-replaceData.html @@ -0,0 +1,14 @@ + +Range mutation tests - replaceData + + + +
      + + + + + diff --git a/testing/web-platform/tests/dom/ranges/Range-mutations-splitText.html b/testing/web-platform/tests/dom/ranges/Range-mutations-splitText.html new file mode 100644 index 0000000000..fbb4c8d9b6 --- /dev/null +++ b/testing/web-platform/tests/dom/ranges/Range-mutations-splitText.html @@ -0,0 +1,14 @@ + +Range mutation tests - splitText + + + +
      + + + + + diff --git a/testing/web-platform/tests/dom/ranges/Range-mutations.js b/testing/web-platform/tests/dom/ranges/Range-mutations.js new file mode 100644 index 0000000000..23c013ac6a --- /dev/null +++ b/testing/web-platform/tests/dom/ranges/Range-mutations.js @@ -0,0 +1,921 @@ +"use strict"; + +// These tests probably use too much abstraction and too little copy-paste. +// Reader beware. +// +// TODO: +// +// * Lots and lots and lots more different types of ranges +// * insertBefore() with DocumentFragments +// * Fill out other insert/remove tests +// * normalize() (https://www.w3.org/Bugs/Public/show_bug.cgi?id=13843) + +// Give a textual description of the range we're testing, for the test names. +function describeRange(startContainer, startOffset, endContainer, endOffset) { + if (startContainer == endContainer && startOffset == endOffset) { + return "range collapsed at (" + startContainer + ", " + startOffset + ")"; + } else if (startContainer == endContainer) { + return "range on " + startContainer + " from " + startOffset + " to " + endOffset; + } else { + return "range from (" + startContainer + ", " + startOffset + ") to (" + endContainer + ", " + endOffset + ")"; + } +} + +// Lists of the various types of nodes we'll want to use. We use strings that +// we can later eval(), so that we can produce legible test names. +var textNodes = [ + "paras[0].firstChild", + "paras[1].firstChild", + "foreignTextNode", + "xmlTextNode", + "detachedTextNode", + "detachedForeignTextNode", + "detachedXmlTextNode", +]; +var commentNodes = [ + "comment", + "foreignComment", + "xmlComment", + "detachedComment", + "detachedForeignComment", + "detachedXmlComment", +]; +var characterDataNodes = textNodes.concat(commentNodes); + +// This function is slightly scary, but it works well enough, so . . . +// sourceTests is an array of test data that will be altered in mysterious ways +// before being passed off to doTest, descFn is something that takes an element +// of sourceTests and produces the first part of a human-readable description +// of the test, testFn is the function that doTest will call to do the actual +// work and tell it what results to expect. +function doTests(sourceTests, descFn, testFn) { + var tests = []; + for (var i = 0; i < sourceTests.length; i++) { + var params = sourceTests[i]; + var len = params.length; + tests.push([ + descFn(params) + ", with unselected " + describeRange(params[len - 4], params[len - 3], params[len - 2], params[len - 1]), + // The closure here ensures that the params that testFn get are the + // current version of params, not the version from the last + // iteration of this loop. We test that none of the parameters + // evaluate to undefined to catch bugs in our eval'ing, like + // mistyping a property name. + function(params) { return function() { + var evaledParams = params.map(eval); + for (var i = 0; i < evaledParams.length; i++) { + assert_not_equals(typeof evaledParams[i], "undefined", + "Test bug: " + params[i] + " is undefined"); + } + return testFn.apply(null, evaledParams); + } }(params), + false, + params[len - 4], + params[len - 3], + params[len - 2], + params[len - 1] + ]); + tests.push([ + descFn(params) + ", with selected " + describeRange(params[len - 4], params[len - 3], params[len - 2], params[len - 1]), + function(params) { return function(selectedRange) { + var evaledParams = params.slice(0, len - 4).map(eval); + for (var i = 0; i < evaledParams.length; i++) { + assert_not_equals(typeof evaledParams[i], "undefined", + "Test bug: " + params[i] + " is undefined"); + } + // Override input range with the one that was actually selected when computing the expected result. + evaledParams = evaledParams.concat([selectedRange.startContainer, selectedRange.startOffset, selectedRange.endContainer, selectedRange.endOffset]); + return testFn.apply(null, evaledParams); + } }(params), + true, + params[len - 4], + params[len - 3], + params[len - 2], + params[len - 1] + ]); + } + generate_tests(doTest, tests); +} + +// Set up the range, call the callback function to do the DOM modification and +// tell us what to expect. The callback function needs to return a +// four-element array with the expected start/end containers/offsets, and +// receives no arguments. useSelection tells us whether the Range should be +// added to a Selection and the Selection tested to ensure that the mutation +// affects user selections as well as other ranges; every test is run with this +// both false and true, because when it's set to true WebKit and Opera fail all +// tests' sanity checks, which is unhelpful. The last four parameters just +// tell us what range to build. +function doTest(callback, useSelection, startContainer, startOffset, endContainer, endOffset) { + // Recreate all the test nodes in case they were altered by the last test + // run. + setupRangeTests(); + startContainer = eval(startContainer); + startOffset = eval(startOffset); + endContainer = eval(endContainer); + endOffset = eval(endOffset); + + var ownerDoc = startContainer.nodeType == Node.DOCUMENT_NODE + ? startContainer + : startContainer.ownerDocument; + var range = ownerDoc.createRange(); + range.setStart(startContainer, startOffset); + range.setEnd(endContainer, endOffset); + + if (useSelection) { + getSelection().removeAllRanges(); + getSelection().addRange(range); + + // Some browsers refuse to add a range unless it results in an actual visible selection. + if (!getSelection().rangeCount) + return; + + // Override range with the one that was actually selected as it differs in some browsers. + range = getSelection().getRangeAt(0); + } + + var expected = callback(range); + + assert_equals(range.startContainer, expected[0], + "Wrong start container"); + assert_equals(range.startOffset, expected[1], + "Wrong start offset"); + assert_equals(range.endContainer, expected[2], + "Wrong end container"); + assert_equals(range.endOffset, expected[3], + "Wrong end offset"); +} + + +// Now we get to the specific tests. + +function testSplitText(oldNode, offset, startContainer, startOffset, endContainer, endOffset) { + // Save these for later + var originalStartOffset = startOffset; + var originalEndOffset = endOffset; + var originalLength = oldNode.length; + + var newNode; + try { + newNode = oldNode.splitText(offset); + } catch (e) { + // Should only happen if offset is negative + return [startContainer, startOffset, endContainer, endOffset]; + } + + // First we adjust for replacing data: + // + // "Replace data with offset offset, count count, and data the empty + // string." + // + // That translates to offset = offset, count = originalLength - offset, + // data = "". node is oldNode. + // + // "For every boundary point whose node is node, and whose offset is + // greater than offset but less than or equal to offset plus count, set its + // offset to offset." + if (startContainer == oldNode + && startOffset > offset + && startOffset <= originalLength) { + startOffset = offset; + } + + if (endContainer == oldNode + && endOffset > offset + && endOffset <= originalLength) { + endOffset = offset; + } + + // "For every boundary point whose node is node, and whose offset is + // greater than offset plus count, add the length of data to its offset, + // then subtract count from it." + // + // Can't happen: offset plus count is originalLength. + + // Now we insert a node, if oldNode's parent isn't null: "For each boundary + // point whose node is the new parent of the affected node and whose offset + // is greater than the new index of the affected node, add one to the + // boundary point's offset." + if (startContainer == oldNode.parentNode + && startOffset > 1 + indexOf(oldNode)) { + startOffset++; + } + + if (endContainer == oldNode.parentNode + && endOffset > 1 + indexOf(oldNode)) { + endOffset++; + } + + // Finally, the splitText stuff itself: + // + // "If parent is not null, run these substeps: + // + // * "For each range whose start node is node and start offset is greater + // than offset, set its start node to new node and decrease its start + // offset by offset. + // + // * "For each range whose end node is node and end offset is greater + // than offset, set its end node to new node and decrease its end offset + // by offset. + // + // * "For each range whose start node is parent and start offset is equal + // to the index of node + 1, increase its start offset by one. + // + // * "For each range whose end node is parent and end offset is equal to + // the index of node + 1, increase its end offset by one." + if (oldNode.parentNode) { + if (startContainer == oldNode && originalStartOffset > offset) { + startContainer = newNode; + startOffset = originalStartOffset - offset; + } + + if (endContainer == oldNode && originalEndOffset > offset) { + endContainer = newNode; + endOffset = originalEndOffset - offset; + } + + if (startContainer == oldNode.parentNode + && startOffset == 1 + indexOf(oldNode)) { + startOffset++; + } + + if (endContainer == oldNode.parentNode + && endOffset == 1 + indexOf(oldNode)) { + endOffset++; + } + } + + return [startContainer, startOffset, endContainer, endOffset]; +} + +// The offset argument is unsigned, so per WebIDL -1 should wrap to 4294967295, +// which is probably longer than the length, so it should throw an exception. +// This is no different from the other cases where the offset is longer than +// the length, and the wrapping complicates my testing slightly, so I won't +// bother testing negative values here or in other cases. +var splitTextTests = []; +for (var i = 0; i < textNodes.length; i++) { + var node = textNodes[i]; + splitTextTests.push([node, 376, node, 0, node, 1]); + splitTextTests.push([node, 0, node, 0, node, 0]); + splitTextTests.push([node, 1, node, 1, node, 1]); + splitTextTests.push([node, node + ".length", node, node + ".length", node, node + ".length"]); + splitTextTests.push([node, 1, node, 1, node, 3]); + splitTextTests.push([node, 2, node, 1, node, 3]); + splitTextTests.push([node, 3, node, 1, node, 3]); +} + +splitTextTests.push( + ["paras[0].firstChild", 1, "paras[0]", 0, "paras[0]", 0], + ["paras[0].firstChild", 1, "paras[0]", 0, "paras[0]", 1], + ["paras[0].firstChild", 1, "paras[0]", 1, "paras[0]", 1], + ["paras[0].firstChild", 1, "paras[0].firstChild", 1, "paras[0]", 1], + ["paras[0].firstChild", 2, "paras[0].firstChild", 1, "paras[0]", 1], + ["paras[0].firstChild", 3, "paras[0].firstChild", 1, "paras[0]", 1], + ["paras[0].firstChild", 1, "paras[0]", 0, "paras[0].firstChild", 3], + ["paras[0].firstChild", 2, "paras[0]", 0, "paras[0].firstChild", 3], + ["paras[0].firstChild", 3, "paras[0]", 0, "paras[0].firstChild", 3] +); + + +function testReplaceDataAlgorithm(node, offset, count, data, callback, startContainer, startOffset, endContainer, endOffset) { + // Mutation works the same any time DOM Core's "replace data" algorithm is + // invoked. node, offset, count, data are as in that algorithm. The + // callback is what does the actual setting. Not to be confused with + // testReplaceData, which tests the replaceData() method. + + // Barring any provision to the contrary, the containers and offsets must + // not change. + var expectedStartContainer = startContainer; + var expectedStartOffset = startOffset; + var expectedEndContainer = endContainer; + var expectedEndOffset = endOffset; + + var originalParent = node.parentNode; + var originalData = node.data; + + var exceptionThrown = false; + try { + callback(); + } catch (e) { + // Should only happen if offset is greater than length + exceptionThrown = true; + } + + assert_equals(node.parentNode, originalParent, + "Sanity check failed: changing data changed the parent"); + + // "User agents must run the following steps whenever they replace data of + // a CharacterData node, as though they were written in the specification + // for that algorithm after all other steps. In particular, the steps must + // not be executed if the algorithm threw an exception." + if (exceptionThrown) { + assert_equals(node.data, originalData, + "Sanity check failed: exception thrown but data changed"); + } else { + assert_equals(node.data, + originalData.substr(0, offset) + data + originalData.substr(offset + count), + "Sanity check failed: data not changed as expected"); + } + + // "For every boundary point whose node is node, and whose offset is + // greater than offset but less than or equal to offset plus count, set + // its offset to offset." + if (!exceptionThrown + && startContainer == node + && startOffset > offset + && startOffset <= offset + count) { + expectedStartOffset = offset; + } + + if (!exceptionThrown + && endContainer == node + && endOffset > offset + && endOffset <= offset + count) { + expectedEndOffset = offset; + } + + // "For every boundary point whose node is node, and whose offset is + // greater than offset plus count, add the length of data to its offset, + // then subtract count from it." + if (!exceptionThrown + && startContainer == node + && startOffset > offset + count) { + expectedStartOffset += data.length - count; + } + + if (!exceptionThrown + && endContainer == node + && endOffset > offset + count) { + expectedEndOffset += data.length - count; + } + + return [expectedStartContainer, expectedStartOffset, expectedEndContainer, expectedEndOffset]; +} + +function testInsertData(node, offset, data, startContainer, startOffset, endContainer, endOffset) { + return testReplaceDataAlgorithm(node, offset, 0, data, + function() { node.insertData(offset, data) }, + startContainer, startOffset, endContainer, endOffset); +} + +var insertDataTests = []; +for (var i = 0; i < characterDataNodes.length; i++) { + var node = characterDataNodes[i]; + insertDataTests.push([node, 376, '"foo"', node, 0, node, 1]); + insertDataTests.push([node, 0, '"foo"', node, 0, node, 0]); + insertDataTests.push([node, 1, '"foo"', node, 1, node, 1]); + insertDataTests.push([node, node + ".length", '"foo"', node, node + ".length", node, node + ".length"]); + insertDataTests.push([node, 1, '"foo"', node, 1, node, 3]); + insertDataTests.push([node, 2, '"foo"', node, 1, node, 3]); + insertDataTests.push([node, 3, '"foo"', node, 1, node, 3]); + + insertDataTests.push([node, 376, '""', node, 0, node, 1]); + insertDataTests.push([node, 0, '""', node, 0, node, 0]); + insertDataTests.push([node, 1, '""', node, 1, node, 1]); + insertDataTests.push([node, node + ".length", '""', node, node + ".length", node, node + ".length"]); + insertDataTests.push([node, 1, '""', node, 1, node, 3]); + insertDataTests.push([node, 2, '""', node, 1, node, 3]); + insertDataTests.push([node, 3, '""', node, 1, node, 3]); +} + +insertDataTests.push( + ["paras[0].firstChild", 1, '"foo"', "paras[0]", 0, "paras[0]", 0], + ["paras[0].firstChild", 1, '"foo"', "paras[0]", 0, "paras[0]", 1], + ["paras[0].firstChild", 1, '"foo"', "paras[0]", 1, "paras[0]", 1], + ["paras[0].firstChild", 1, '"foo"', "paras[0].firstChild", 1, "paras[0]", 1], + ["paras[0].firstChild", 2, '"foo"', "paras[0].firstChild", 1, "paras[0]", 1], + ["paras[0].firstChild", 3, '"foo"', "paras[0].firstChild", 1, "paras[0]", 1], + ["paras[0].firstChild", 1, '"foo"', "paras[0]", 0, "paras[0].firstChild", 3], + ["paras[0].firstChild", 2, '"foo"', "paras[0]", 0, "paras[0].firstChild", 3], + ["paras[0].firstChild", 3, '"foo"', "paras[0]", 0, "paras[0].firstChild", 3] +); + + +function testAppendData(node, data, startContainer, startOffset, endContainer, endOffset) { + return testReplaceDataAlgorithm(node, node.length, 0, data, + function() { node.appendData(data) }, + startContainer, startOffset, endContainer, endOffset); +} + +var appendDataTests = []; +for (var i = 0; i < characterDataNodes.length; i++) { + var node = characterDataNodes[i]; + appendDataTests.push([node, '"foo"', node, 0, node, 1]); + appendDataTests.push([node, '"foo"', node, 0, node, 0]); + appendDataTests.push([node, '"foo"', node, 1, node, 1]); + appendDataTests.push([node, '"foo"', node, 0, node, node + ".length"]); + appendDataTests.push([node, '"foo"', node, 1, node, node + ".length"]); + appendDataTests.push([node, '"foo"', node, node + ".length", node, node + ".length"]); + appendDataTests.push([node, '"foo"', node, 1, node, 3]); + + appendDataTests.push([node, '""', node, 0, node, 1]); + appendDataTests.push([node, '""', node, 0, node, 0]); + appendDataTests.push([node, '""', node, 1, node, 1]); + appendDataTests.push([node, '""', node, 0, node, node + ".length"]); + appendDataTests.push([node, '""', node, 1, node, node + ".length"]); + appendDataTests.push([node, '""', node, node + ".length", node, node + ".length"]); + appendDataTests.push([node, '""', node, 1, node, 3]); +} + +appendDataTests.push( + ["paras[0].firstChild", '""', "paras[0]", 0, "paras[0]", 0], + ["paras[0].firstChild", '""', "paras[0]", 0, "paras[0]", 1], + ["paras[0].firstChild", '""', "paras[0]", 1, "paras[0]", 1], + ["paras[0].firstChild", '""', "paras[0].firstChild", 1, "paras[0]", 1], + ["paras[0].firstChild", '""', "paras[0]", 0, "paras[0].firstChild", 3], + + ["paras[0].firstChild", '"foo"', "paras[0]", 0, "paras[0]", 0], + ["paras[0].firstChild", '"foo"', "paras[0]", 0, "paras[0]", 1], + ["paras[0].firstChild", '"foo"', "paras[0]", 1, "paras[0]", 1], + ["paras[0].firstChild", '"foo"', "paras[0].firstChild", 1, "paras[0]", 1], + ["paras[0].firstChild", '"foo"', "paras[0]", 0, "paras[0].firstChild", 3] +); + + +function testDeleteData(node, offset, count, startContainer, startOffset, endContainer, endOffset) { + return testReplaceDataAlgorithm(node, offset, count, "", + function() { node.deleteData(offset, count) }, + startContainer, startOffset, endContainer, endOffset); +} + +var deleteDataTests = []; +for (var i = 0; i < characterDataNodes.length; i++) { + var node = characterDataNodes[i]; + deleteDataTests.push([node, 376, 2, node, 0, node, 1]); + deleteDataTests.push([node, 0, 2, node, 0, node, 0]); + deleteDataTests.push([node, 1, 2, node, 1, node, 1]); + deleteDataTests.push([node, node + ".length", 2, node, node + ".length", node, node + ".length"]); + deleteDataTests.push([node, 1, 2, node, 1, node, 3]); + deleteDataTests.push([node, 2, 2, node, 1, node, 3]); + deleteDataTests.push([node, 3, 2, node, 1, node, 3]); + + deleteDataTests.push([node, 376, 0, node, 0, node, 1]); + deleteDataTests.push([node, 0, 0, node, 0, node, 0]); + deleteDataTests.push([node, 1, 0, node, 1, node, 1]); + deleteDataTests.push([node, node + ".length", 0, node, node + ".length", node, node + ".length"]); + deleteDataTests.push([node, 1, 0, node, 1, node, 3]); + deleteDataTests.push([node, 2, 0, node, 1, node, 3]); + deleteDataTests.push([node, 3, 0, node, 1, node, 3]); + + deleteDataTests.push([node, 376, 631, node, 0, node, 1]); + deleteDataTests.push([node, 0, 631, node, 0, node, 0]); + deleteDataTests.push([node, 1, 631, node, 1, node, 1]); + deleteDataTests.push([node, node + ".length", 631, node, node + ".length", node, node + ".length"]); + deleteDataTests.push([node, 1, 631, node, 1, node, 3]); + deleteDataTests.push([node, 2, 631, node, 1, node, 3]); + deleteDataTests.push([node, 3, 631, node, 1, node, 3]); +} + +deleteDataTests.push( + ["paras[0].firstChild", 1, 2, "paras[0]", 0, "paras[0]", 0], + ["paras[0].firstChild", 1, 2, "paras[0]", 0, "paras[0]", 1], + ["paras[0].firstChild", 1, 2, "paras[0]", 1, "paras[0]", 1], + ["paras[0].firstChild", 1, 2, "paras[0].firstChild", 1, "paras[0]", 1], + ["paras[0].firstChild", 2, 2, "paras[0].firstChild", 1, "paras[0]", 1], + ["paras[0].firstChild", 3, 2, "paras[0].firstChild", 1, "paras[0]", 1], + ["paras[0].firstChild", 1, 2, "paras[0]", 0, "paras[0].firstChild", 3], + ["paras[0].firstChild", 2, 2, "paras[0]", 0, "paras[0].firstChild", 3], + ["paras[0].firstChild", 3, 2, "paras[0]", 0, "paras[0].firstChild", 3] +); + + +function testReplaceData(node, offset, count, data, startContainer, startOffset, endContainer, endOffset) { + return testReplaceDataAlgorithm(node, offset, count, data, + function() { node.replaceData(offset, count, data) }, + startContainer, startOffset, endContainer, endOffset); +} + +var replaceDataTests = []; +for (var i = 0; i < characterDataNodes.length; i++) { + var node = characterDataNodes[i]; + replaceDataTests.push([node, 376, 0, '"foo"', node, 0, node, 1]); + replaceDataTests.push([node, 0, 0, '"foo"', node, 0, node, 0]); + replaceDataTests.push([node, 1, 0, '"foo"', node, 1, node, 1]); + replaceDataTests.push([node, node + ".length", 0, '"foo"', node, node + ".length", node, node + ".length"]); + replaceDataTests.push([node, 1, 0, '"foo"', node, 1, node, 3]); + replaceDataTests.push([node, 2, 0, '"foo"', node, 1, node, 3]); + replaceDataTests.push([node, 3, 0, '"foo"', node, 1, node, 3]); + + replaceDataTests.push([node, 376, 0, '""', node, 0, node, 1]); + replaceDataTests.push([node, 0, 0, '""', node, 0, node, 0]); + replaceDataTests.push([node, 1, 0, '""', node, 1, node, 1]); + replaceDataTests.push([node, node + ".length", 0, '""', node, node + ".length", node, node + ".length"]); + replaceDataTests.push([node, 1, 0, '""', node, 1, node, 3]); + replaceDataTests.push([node, 2, 0, '""', node, 1, node, 3]); + replaceDataTests.push([node, 3, 0, '""', node, 1, node, 3]); + + replaceDataTests.push([node, 376, 1, '"foo"', node, 0, node, 1]); + replaceDataTests.push([node, 0, 1, '"foo"', node, 0, node, 0]); + replaceDataTests.push([node, 1, 1, '"foo"', node, 1, node, 1]); + replaceDataTests.push([node, node + ".length", 1, '"foo"', node, node + ".length", node, node + ".length"]); + replaceDataTests.push([node, 1, 1, '"foo"', node, 1, node, 3]); + replaceDataTests.push([node, 2, 1, '"foo"', node, 1, node, 3]); + replaceDataTests.push([node, 3, 1, '"foo"', node, 1, node, 3]); + + replaceDataTests.push([node, 376, 1, '""', node, 0, node, 1]); + replaceDataTests.push([node, 0, 1, '""', node, 0, node, 0]); + replaceDataTests.push([node, 1, 1, '""', node, 1, node, 1]); + replaceDataTests.push([node, node + ".length", 1, '""', node, node + ".length", node, node + ".length"]); + replaceDataTests.push([node, 1, 1, '""', node, 1, node, 3]); + replaceDataTests.push([node, 2, 1, '""', node, 1, node, 3]); + replaceDataTests.push([node, 3, 1, '""', node, 1, node, 3]); + + replaceDataTests.push([node, 376, 47, '"foo"', node, 0, node, 1]); + replaceDataTests.push([node, 0, 47, '"foo"', node, 0, node, 0]); + replaceDataTests.push([node, 1, 47, '"foo"', node, 1, node, 1]); + replaceDataTests.push([node, node + ".length", 47, '"foo"', node, node + ".length", node, node + ".length"]); + replaceDataTests.push([node, 1, 47, '"foo"', node, 1, node, 3]); + replaceDataTests.push([node, 2, 47, '"foo"', node, 1, node, 3]); + replaceDataTests.push([node, 3, 47, '"foo"', node, 1, node, 3]); + + replaceDataTests.push([node, 376, 47, '""', node, 0, node, 1]); + replaceDataTests.push([node, 0, 47, '""', node, 0, node, 0]); + replaceDataTests.push([node, 1, 47, '""', node, 1, node, 1]); + replaceDataTests.push([node, node + ".length", 47, '""', node, node + ".length", node, node + ".length"]); + replaceDataTests.push([node, 1, 47, '""', node, 1, node, 3]); + replaceDataTests.push([node, 2, 47, '""', node, 1, node, 3]); + replaceDataTests.push([node, 3, 47, '""', node, 1, node, 3]); +} + +replaceDataTests.push( + ["paras[0].firstChild", 1, 0, '"foo"', "paras[0]", 0, "paras[0]", 0], + ["paras[0].firstChild", 1, 0, '"foo"', "paras[0]", 0, "paras[0]", 1], + ["paras[0].firstChild", 1, 0, '"foo"', "paras[0]", 1, "paras[0]", 1], + ["paras[0].firstChild", 1, 0, '"foo"', "paras[0].firstChild", 1, "paras[0]", 1], + ["paras[0].firstChild", 2, 0, '"foo"', "paras[0].firstChild", 1, "paras[0]", 1], + ["paras[0].firstChild", 3, 0, '"foo"', "paras[0].firstChild", 1, "paras[0]", 1], + ["paras[0].firstChild", 1, 0, '"foo"', "paras[0]", 0, "paras[0].firstChild", 3], + ["paras[0].firstChild", 2, 0, '"foo"', "paras[0]", 0, "paras[0].firstChild", 3], + ["paras[0].firstChild", 3, 0, '"foo"', "paras[0]", 0, "paras[0].firstChild", 3], + + ["paras[0].firstChild", 1, 1, '"foo"', "paras[0]", 0, "paras[0]", 0], + ["paras[0].firstChild", 1, 1, '"foo"', "paras[0]", 0, "paras[0]", 1], + ["paras[0].firstChild", 1, 1, '"foo"', "paras[0]", 1, "paras[0]", 1], + ["paras[0].firstChild", 1, 1, '"foo"', "paras[0].firstChild", 1, "paras[0]", 1], + ["paras[0].firstChild", 2, 1, '"foo"', "paras[0].firstChild", 1, "paras[0]", 1], + ["paras[0].firstChild", 3, 1, '"foo"', "paras[0].firstChild", 1, "paras[0]", 1], + ["paras[0].firstChild", 1, 1, '"foo"', "paras[0]", 0, "paras[0].firstChild", 3], + ["paras[0].firstChild", 2, 1, '"foo"', "paras[0]", 0, "paras[0].firstChild", 3], + ["paras[0].firstChild", 3, 1, '"foo"', "paras[0]", 0, "paras[0].firstChild", 3], + + ["paras[0].firstChild", 1, 47, '"foo"', "paras[0]", 0, "paras[0]", 0], + ["paras[0].firstChild", 1, 47, '"foo"', "paras[0]", 0, "paras[0]", 1], + ["paras[0].firstChild", 1, 47, '"foo"', "paras[0]", 1, "paras[0]", 1], + ["paras[0].firstChild", 1, 47, '"foo"', "paras[0].firstChild", 1, "paras[0]", 1], + ["paras[0].firstChild", 2, 47, '"foo"', "paras[0].firstChild", 1, "paras[0]", 1], + ["paras[0].firstChild", 3, 47, '"foo"', "paras[0].firstChild", 1, "paras[0]", 1], + ["paras[0].firstChild", 1, 47, '"foo"', "paras[0]", 0, "paras[0].firstChild", 3], + ["paras[0].firstChild", 2, 47, '"foo"', "paras[0]", 0, "paras[0].firstChild", 3], + ["paras[0].firstChild", 3, 47, '"foo"', "paras[0]", 0, "paras[0].firstChild", 3] +); + + +// There are lots of ways to set data, so we pass a callback that does the +// actual setting. +function testDataChange(node, attr, op, rval, startContainer, startOffset, endContainer, endOffset) { + return testReplaceDataAlgorithm(node, 0, node.length, op == "=" ? rval : node[attr] + rval, + function() { + if (op == "=") { + node[attr] = rval; + } else if (op == "+=") { + node[attr] += rval; + } else { + throw "Unknown op " + op; + } + }, + startContainer, startOffset, endContainer, endOffset); +} + +var dataChangeTests = []; +var dataChangeTestAttrs = ["data", "textContent", "nodeValue"]; +for (var i = 0; i < characterDataNodes.length; i++) { + var node = characterDataNodes[i]; + var dataChangeTestRanges = [ + [node, 0, node, 0], + [node, 0, node, 1], + [node, 1, node, 1], + [node, 0, node, node + ".length"], + [node, 1, node, node + ".length"], + [node, node + ".length", node, node + ".length"], + ]; + + for (var j = 0; j < dataChangeTestRanges.length; j++) { + for (var k = 0; k < dataChangeTestAttrs.length; k++) { + dataChangeTests.push([ + node, + '"' + dataChangeTestAttrs[k] + '"', + '"="', + '""', + ].concat(dataChangeTestRanges[j])); + + dataChangeTests.push([ + node, + '"' + dataChangeTestAttrs[k] + '"', + '"="', + '"foo"', + ].concat(dataChangeTestRanges[j])); + + dataChangeTests.push([ + node, + '"' + dataChangeTestAttrs[k] + '"', + '"="', + node + "." + dataChangeTestAttrs[k], + ].concat(dataChangeTestRanges[j])); + + dataChangeTests.push([ + node, + '"' + dataChangeTestAttrs[k] + '"', + '"+="', + '""', + ].concat(dataChangeTestRanges[j])); + + dataChangeTests.push([ + node, + '"' + dataChangeTestAttrs[k] + '"', + '"+="', + '"foo"', + ].concat(dataChangeTestRanges[j])); + + dataChangeTests.push([ + node, + '"' + dataChangeTestAttrs[k] + '"', + '"+="', + node + "." + dataChangeTestAttrs[k] + ].concat(dataChangeTestRanges[j])); + } + } +} + + +// Now we test node insertions and deletions, as opposed to just data changes. +// To avoid loads of repetition, we define modifyForRemove() and +// modifyForInsert(). + +// If we were to remove removedNode from its parent, what would the boundary +// point [node, offset] become? Returns [new node, new offset]. Must be +// called BEFORE the node is actually removed, so its parent is not null. (If +// the parent is null, it will do nothing.) +function modifyForRemove(removedNode, point) { + var oldParent = removedNode.parentNode; + var oldIndex = indexOf(removedNode); + if (!oldParent) { + return point; + } + + // "For each boundary point whose node is removed node or a descendant of + // it, set the boundary point to (old parent, old index)." + if (point[0] == removedNode || isDescendant(point[0], removedNode)) { + return [oldParent, oldIndex]; + } + + // "For each boundary point whose node is old parent and whose offset is + // greater than old index, subtract one from its offset." + if (point[0] == oldParent && point[1] > oldIndex) { + return [point[0], point[1] - 1]; + } + + return point; +} + +// Update the given boundary point [node, offset] to account for the fact that +// insertedNode was just inserted into its current position. This must be +// called AFTER insertedNode was already inserted. +function modifyForInsert(insertedNode, point) { + // "For each boundary point whose node is the new parent of the affected + // node and whose offset is greater than the new index of the affected + // node, add one to the boundary point's offset." + if (point[0] == insertedNode.parentNode && point[1] > indexOf(insertedNode)) { + return [point[0], point[1] + 1]; + } + + return point; +} + + +function testInsertBefore(newParent, affectedNode, refNode, startContainer, startOffset, endContainer, endOffset) { + var expectedStart = [startContainer, startOffset]; + var expectedEnd = [endContainer, endOffset]; + + expectedStart = modifyForRemove(affectedNode, expectedStart); + expectedEnd = modifyForRemove(affectedNode, expectedEnd); + + try { + newParent.insertBefore(affectedNode, refNode); + } catch (e) { + // For our purposes, assume that DOM Core is true -- i.e., ignore + // mutation events and similar. + return [startContainer, startOffset, endContainer, endOffset]; + } + + expectedStart = modifyForInsert(affectedNode, expectedStart); + expectedEnd = modifyForInsert(affectedNode, expectedEnd); + + return expectedStart.concat(expectedEnd); +} + +var insertBeforeTests = [ + // Moving a node to its current position + ["testDiv", "paras[0]", "paras[1]", "paras[0]", 0, "paras[0]", 0], + ["testDiv", "paras[0]", "paras[1]", "paras[0]", 0, "paras[0]", 1], + ["testDiv", "paras[0]", "paras[1]", "paras[0]", 1, "paras[0]", 1], + ["testDiv", "paras[0]", "paras[1]", "testDiv", 0, "testDiv", 2], + ["testDiv", "paras[0]", "paras[1]", "testDiv", 1, "testDiv", 1], + ["testDiv", "paras[0]", "paras[1]", "testDiv", 1, "testDiv", 2], + ["testDiv", "paras[0]", "paras[1]", "testDiv", 2, "testDiv", 2], + + // Stuff that actually moves something. Note that paras[0] and paras[1] + // are both children of testDiv. + ["paras[0]", "paras[1]", "paras[0].firstChild", "paras[0]", 0, "paras[0]", 0], + ["paras[0]", "paras[1]", "paras[0].firstChild", "paras[0]", 0, "paras[0]", 1], + ["paras[0]", "paras[1]", "paras[0].firstChild", "paras[0]", 1, "paras[0]", 1], + ["paras[0]", "paras[1]", "paras[0].firstChild", "testDiv", 0, "testDiv", 1], + ["paras[0]", "paras[1]", "paras[0].firstChild", "testDiv", 0, "testDiv", 2], + ["paras[0]", "paras[1]", "paras[0].firstChild", "testDiv", 1, "testDiv", 1], + ["paras[0]", "paras[1]", "paras[0].firstChild", "testDiv", 1, "testDiv", 2], + ["paras[0]", "paras[1]", "null", "paras[0]", 0, "paras[0]", 0], + ["paras[0]", "paras[1]", "null", "paras[0]", 0, "paras[0]", 1], + ["paras[0]", "paras[1]", "null", "paras[0]", 1, "paras[0]", 1], + ["paras[0]", "paras[1]", "null", "testDiv", 0, "testDiv", 1], + ["paras[0]", "paras[1]", "null", "testDiv", 0, "testDiv", 2], + ["paras[0]", "paras[1]", "null", "testDiv", 1, "testDiv", 1], + ["paras[0]", "paras[1]", "null", "testDiv", 1, "testDiv", 2], + ["foreignDoc", "detachedComment", "foreignDoc.documentElement", "foreignDoc", 0, "foreignDoc", 0], + ["foreignDoc", "detachedComment", "foreignDoc.documentElement", "foreignDoc", 0, "foreignDoc", 1], + ["foreignDoc", "detachedComment", "foreignDoc.documentElement", "foreignDoc", 0, "foreignDoc", 2], + ["foreignDoc", "detachedComment", "foreignDoc.documentElement", "foreignDoc", 1, "foreignDoc", 1], + ["foreignDoc", "detachedComment", "foreignDoc.doctype", "foreignDoc", 0, "foreignDoc", 0], + ["foreignDoc", "detachedComment", "foreignDoc.doctype", "foreignDoc", 0, "foreignDoc", 1], + ["foreignDoc", "detachedComment", "foreignDoc.doctype", "foreignDoc", 0, "foreignDoc", 2], + ["foreignDoc", "detachedComment", "foreignDoc.doctype", "foreignDoc", 1, "foreignDoc", 1], + ["foreignDoc", "detachedComment", "null", "foreignDoc", 0, "foreignDoc", 1], + ["paras[0]", "xmlTextNode", "paras[0].firstChild", "paras[0]", 0, "paras[0]", 0], + ["paras[0]", "xmlTextNode", "paras[0].firstChild", "paras[0]", 0, "paras[0]", 1], + ["paras[0]", "xmlTextNode", "paras[0].firstChild", "paras[0]", 1, "paras[0]", 1], + + // Stuff that throws exceptions + ["paras[0]", "paras[0]", "paras[0].firstChild", "paras[0]", 0, "paras[0]", 1], + ["paras[0]", "testDiv", "paras[0].firstChild", "paras[0]", 0, "paras[0]", 1], + ["paras[0]", "document", "paras[0].firstChild", "paras[0]", 0, "paras[0]", 1], + ["paras[0]", "foreignDoc", "paras[0].firstChild", "paras[0]", 0, "paras[0]", 1], + ["paras[0]", "document.doctype", "paras[0].firstChild", "paras[0]", 0, "paras[0]", 1], +]; + + +function testReplaceChild(newParent, newChild, oldChild, startContainer, startOffset, endContainer, endOffset) { + var expectedStart = [startContainer, startOffset]; + var expectedEnd = [endContainer, endOffset]; + + expectedStart = modifyForRemove(oldChild, expectedStart); + expectedEnd = modifyForRemove(oldChild, expectedEnd); + + if (newChild != oldChild) { + // Don't do this twice, if they're the same! + expectedStart = modifyForRemove(newChild, expectedStart); + expectedEnd = modifyForRemove(newChild, expectedEnd); + } + + try { + newParent.replaceChild(newChild, oldChild); + } catch (e) { + return [startContainer, startOffset, endContainer, endOffset]; + } + + expectedStart = modifyForInsert(newChild, expectedStart); + expectedEnd = modifyForInsert(newChild, expectedEnd); + + return expectedStart.concat(expectedEnd); +} + +var replaceChildTests = [ + // Moving a node to its current position. Doesn't match most browsers' + // behavior, but we probably want to keep the spec the same anyway: + // https://bugzilla.mozilla.org/show_bug.cgi?id=647603 + ["testDiv", "paras[0]", "paras[0]", "paras[0]", 0, "paras[0]", 0], + ["testDiv", "paras[0]", "paras[0]", "paras[0]", 0, "paras[0]", 1], + ["testDiv", "paras[0]", "paras[0]", "paras[0]", 1, "paras[0]", 1], + ["testDiv", "paras[0]", "paras[0]", "testDiv", 0, "testDiv", 2], + ["testDiv", "paras[0]", "paras[0]", "testDiv", 1, "testDiv", 1], + ["testDiv", "paras[0]", "paras[0]", "testDiv", 1, "testDiv", 2], + ["testDiv", "paras[0]", "paras[0]", "testDiv", 2, "testDiv", 2], + + // Stuff that actually moves something. + ["paras[0]", "paras[1]", "paras[0].firstChild", "paras[0]", 0, "paras[0]", 0], + ["paras[0]", "paras[1]", "paras[0].firstChild", "paras[0]", 0, "paras[0]", 1], + ["paras[0]", "paras[1]", "paras[0].firstChild", "paras[0]", 1, "paras[0]", 1], + ["paras[0]", "paras[1]", "paras[0].firstChild", "testDiv", 0, "testDiv", 1], + ["paras[0]", "paras[1]", "paras[0].firstChild", "testDiv", 0, "testDiv", 2], + ["paras[0]", "paras[1]", "paras[0].firstChild", "testDiv", 1, "testDiv", 1], + ["paras[0]", "paras[1]", "paras[0].firstChild", "testDiv", 1, "testDiv", 2], + ["foreignDoc", "detachedComment", "foreignDoc.documentElement", "foreignDoc", 0, "foreignDoc", 0], + ["foreignDoc", "detachedComment", "foreignDoc.documentElement", "foreignDoc", 0, "foreignDoc", 1], + ["foreignDoc", "detachedComment", "foreignDoc.documentElement", "foreignDoc", 0, "foreignDoc", 2], + ["foreignDoc", "detachedComment", "foreignDoc.documentElement", "foreignDoc", 1, "foreignDoc", 1], + ["foreignDoc", "detachedComment", "foreignDoc.doctype", "foreignDoc", 0, "foreignDoc", 0], + ["foreignDoc", "detachedComment", "foreignDoc.doctype", "foreignDoc", 0, "foreignDoc", 1], + ["foreignDoc", "detachedComment", "foreignDoc.doctype", "foreignDoc", 0, "foreignDoc", 2], + ["foreignDoc", "detachedComment", "foreignDoc.doctype", "foreignDoc", 1, "foreignDoc", 1], + ["paras[0]", "xmlTextNode", "paras[0].firstChild", "paras[0]", 0, "paras[0]", 0], + ["paras[0]", "xmlTextNode", "paras[0].firstChild", "paras[0]", 0, "paras[0]", 1], + ["paras[0]", "xmlTextNode", "paras[0].firstChild", "paras[0]", 1, "paras[0]", 1], + + // Stuff that throws exceptions + ["paras[0]", "paras[0]", "paras[0].firstChild", "paras[0]", 0, "paras[0]", 1], + ["paras[0]", "testDiv", "paras[0].firstChild", "paras[0]", 0, "paras[0]", 1], + ["paras[0]", "document", "paras[0].firstChild", "paras[0]", 0, "paras[0]", 1], + ["paras[0]", "foreignDoc", "paras[0].firstChild", "paras[0]", 0, "paras[0]", 1], + ["paras[0]", "document.doctype", "paras[0].firstChild", "paras[0]", 0, "paras[0]", 1], +]; + + +function testAppendChild(newParent, affectedNode, startContainer, startOffset, endContainer, endOffset) { + var expectedStart = [startContainer, startOffset]; + var expectedEnd = [endContainer, endOffset]; + + expectedStart = modifyForRemove(affectedNode, expectedStart); + expectedEnd = modifyForRemove(affectedNode, expectedEnd); + + try { + newParent.appendChild(affectedNode); + } catch (e) { + return [startContainer, startOffset, endContainer, endOffset]; + } + + // These two lines will actually never do anything, if you think about it, + // but let's leave them in so correctness is more obvious. + expectedStart = modifyForInsert(affectedNode, expectedStart); + expectedEnd = modifyForInsert(affectedNode, expectedEnd); + + return expectedStart.concat(expectedEnd); +} + +var appendChildTests = [ + // Moving a node to its current position + ["testDiv", "testDiv.lastChild", "testDiv.lastChild", 0, "testDiv.lastChild", 0], + ["testDiv", "testDiv.lastChild", "testDiv.lastChild", 0, "testDiv.lastChild", 1], + ["testDiv", "testDiv.lastChild", "testDiv.lastChild", 1, "testDiv.lastChild", 1], + ["testDiv", "testDiv.lastChild", "testDiv", "testDiv.childNodes.length - 2", "testDiv", "testDiv.childNodes.length"], + ["testDiv", "testDiv.lastChild", "testDiv", "testDiv.childNodes.length - 2", "testDiv", "testDiv.childNodes.length - 1"], + ["testDiv", "testDiv.lastChild", "testDiv", "testDiv.childNodes.length - 1", "testDiv", "testDiv.childNodes.length"], + ["testDiv", "testDiv.lastChild", "testDiv", "testDiv.childNodes.length - 1", "testDiv", "testDiv.childNodes.length - 1"], + ["testDiv", "testDiv.lastChild", "testDiv", "testDiv.childNodes.length", "testDiv", "testDiv.childNodes.length"], + ["detachedDiv", "detachedDiv.lastChild", "detachedDiv.lastChild", 0, "detachedDiv.lastChild", 0], + ["detachedDiv", "detachedDiv.lastChild", "detachedDiv.lastChild", 0, "detachedDiv.lastChild", 1], + ["detachedDiv", "detachedDiv.lastChild", "detachedDiv.lastChild", 1, "detachedDiv.lastChild", 1], + ["detachedDiv", "detachedDiv.lastChild", "detachedDiv", "detachedDiv.childNodes.length - 2", "detachedDiv", "detachedDiv.childNodes.length"], + ["detachedDiv", "detachedDiv.lastChild", "detachedDiv", "detachedDiv.childNodes.length - 2", "detachedDiv", "detachedDiv.childNodes.length - 1"], + ["detachedDiv", "detachedDiv.lastChild", "detachedDiv", "detachedDiv.childNodes.length - 1", "detachedDiv", "detachedDiv.childNodes.length"], + ["detachedDiv", "detachedDiv.lastChild", "detachedDiv", "detachedDiv.childNodes.length - 1", "detachedDiv", "detachedDiv.childNodes.length - 1"], + ["detachedDiv", "detachedDiv.lastChild", "detachedDiv", "detachedDiv.childNodes.length", "detachedDiv", "detachedDiv.childNodes.length"], + + // Stuff that actually moves something + ["paras[0]", "paras[1]", "paras[0]", 0, "paras[0]", 0], + ["paras[0]", "paras[1]", "paras[0]", 0, "paras[0]", 1], + ["paras[0]", "paras[1]", "paras[0]", 1, "paras[0]", 1], + ["paras[0]", "paras[1]", "testDiv", 0, "testDiv", 1], + ["paras[0]", "paras[1]", "testDiv", 0, "testDiv", 2], + ["paras[0]", "paras[1]", "testDiv", 1, "testDiv", 1], + ["paras[0]", "paras[1]", "testDiv", 1, "testDiv", 2], + ["foreignDoc", "detachedComment", "foreignDoc", "foreignDoc.childNodes.length - 1", "foreignDoc", "foreignDoc.childNodes.length"], + ["foreignDoc", "detachedComment", "foreignDoc", "foreignDoc.childNodes.length - 1", "foreignDoc", "foreignDoc.childNodes.length - 1"], + ["foreignDoc", "detachedComment", "foreignDoc", "foreignDoc.childNodes.length", "foreignDoc", "foreignDoc.childNodes.length"], + ["foreignDoc", "detachedComment", "detachedComment", 0, "detachedComment", 5], + ["paras[0]", "xmlTextNode", "paras[0]", 0, "paras[0]", 0], + ["paras[0]", "xmlTextNode", "paras[0]", 0, "paras[0]", 1], + ["paras[0]", "xmlTextNode", "paras[0]", 1, "paras[0]", 1], + + // Stuff that throws exceptions + ["paras[0]", "paras[0]", "paras[0]", 0, "paras[0]", 1], + ["paras[0]", "testDiv", "paras[0]", 0, "paras[0]", 1], + ["paras[0]", "document", "paras[0]", 0, "paras[0]", 1], + ["paras[0]", "foreignDoc", "paras[0]", 0, "paras[0]", 1], + ["paras[0]", "document.doctype", "paras[0]", 0, "paras[0]", 1], +]; + + +function testRemoveChild(affectedNode, startContainer, startOffset, endContainer, endOffset) { + var expectedStart = [startContainer, startOffset]; + var expectedEnd = [endContainer, endOffset]; + + expectedStart = modifyForRemove(affectedNode, expectedStart); + expectedEnd = modifyForRemove(affectedNode, expectedEnd); + + // We don't test cases where the parent is wrong, so this should never + // throw an exception. + affectedNode.parentNode.removeChild(affectedNode); + + return expectedStart.concat(expectedEnd); +} + +var removeChildTests = [ + ["paras[0]", "paras[0]", 0, "paras[0]", 0], + ["paras[0]", "paras[0]", 0, "paras[0]", 1], + ["paras[0]", "paras[0]", 1, "paras[0]", 1], + ["paras[0]", "testDiv", 0, "testDiv", 0], + ["paras[0]", "testDiv", 0, "testDiv", 1], + ["paras[0]", "testDiv", 1, "testDiv", 1], + ["paras[0]", "testDiv", 0, "testDiv", 2], + ["paras[0]", "testDiv", 1, "testDiv", 2], + ["paras[0]", "testDiv", 2, "testDiv", 2], + + ["foreignDoc.documentElement", "foreignDoc", 0, "foreignDoc", "foreignDoc.childNodes.length"], +]; diff --git a/testing/web-platform/tests/dom/ranges/Range-selectNode.html b/testing/web-platform/tests/dom/ranges/Range-selectNode.html new file mode 100644 index 0000000000..fe9b1f7860 --- /dev/null +++ b/testing/web-platform/tests/dom/ranges/Range-selectNode.html @@ -0,0 +1,99 @@ + +Range.selectNode() and .selectNodeContents() tests + + +
      + + + + diff --git a/testing/web-platform/tests/dom/ranges/Range-set.html b/testing/web-platform/tests/dom/ranges/Range-set.html new file mode 100644 index 0000000000..694fc60749 --- /dev/null +++ b/testing/web-platform/tests/dom/ranges/Range-set.html @@ -0,0 +1,221 @@ + +Range setting tests + + + +
      + + + + diff --git a/testing/web-platform/tests/dom/ranges/Range-stringifier.html b/testing/web-platform/tests/dom/ranges/Range-stringifier.html new file mode 100644 index 0000000000..330c7421ea --- /dev/null +++ b/testing/web-platform/tests/dom/ranges/Range-stringifier.html @@ -0,0 +1,44 @@ + + +Range stringifier + + + +
      Test div
      +
      Another div
      +
      Last div
      +
      + diff --git a/testing/web-platform/tests/dom/ranges/Range-surroundContents.html b/testing/web-platform/tests/dom/ranges/Range-surroundContents.html new file mode 100644 index 0000000000..c9d47fcbad --- /dev/null +++ b/testing/web-platform/tests/dom/ranges/Range-surroundContents.html @@ -0,0 +1,324 @@ + + +Range.surroundContents() tests + + +

      To debug test failures, add a query parameter "subtest" with the test id (like +"?subtest=5,16"). Only that test will be run. Then you can look at the resulting +iframes in the DOM. +

      + + + + diff --git a/testing/web-platform/tests/dom/ranges/Range-test-iframe.html b/testing/web-platform/tests/dom/ranges/Range-test-iframe.html new file mode 100644 index 0000000000..f354ff758f --- /dev/null +++ b/testing/web-platform/tests/dom/ranges/Range-test-iframe.html @@ -0,0 +1,56 @@ + +Range test iframe + + + + + diff --git a/testing/web-platform/tests/dom/ranges/StaticRange-constructor.html b/testing/web-platform/tests/dom/ranges/StaticRange-constructor.html new file mode 100644 index 0000000000..6aae93f49b --- /dev/null +++ b/testing/web-platform/tests/dom/ranges/StaticRange-constructor.html @@ -0,0 +1,200 @@ + +StaticRange constructor test + +
      + + +
      abcdefghi
      + diff --git a/testing/web-platform/tests/dom/slot-recalc-ref.html b/testing/web-platform/tests/dom/slot-recalc-ref.html new file mode 100644 index 0000000000..521eedb42a --- /dev/null +++ b/testing/web-platform/tests/dom/slot-recalc-ref.html @@ -0,0 +1,5 @@ + +
      +

      there should be more text below this

      +

      PASS if this text is visible

      +
      diff --git a/testing/web-platform/tests/dom/slot-recalc.html b/testing/web-platform/tests/dom/slot-recalc.html new file mode 100644 index 0000000000..5124336ad2 --- /dev/null +++ b/testing/web-platform/tests/dom/slot-recalc.html @@ -0,0 +1,23 @@ + + + + + + + + + diff --git a/testing/web-platform/tests/dom/svg-insert-crash.html b/testing/web-platform/tests/dom/svg-insert-crash.html new file mode 100644 index 0000000000..80eec1fba7 --- /dev/null +++ b/testing/web-platform/tests/dom/svg-insert-crash.html @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + diff --git a/testing/web-platform/tests/dom/traversal/NodeFilter-constants.html b/testing/web-platform/tests/dom/traversal/NodeFilter-constants.html new file mode 100644 index 0000000000..1ce4736cc6 --- /dev/null +++ b/testing/web-platform/tests/dom/traversal/NodeFilter-constants.html @@ -0,0 +1,34 @@ + +NodeFilter constants + + + +
      + diff --git a/testing/web-platform/tests/dom/traversal/NodeIterator-removal.html b/testing/web-platform/tests/dom/traversal/NodeIterator-removal.html new file mode 100644 index 0000000000..b5fc69541a --- /dev/null +++ b/testing/web-platform/tests/dom/traversal/NodeIterator-removal.html @@ -0,0 +1,100 @@ + +NodeIterator removal tests + + +
      + + + + diff --git a/testing/web-platform/tests/dom/traversal/NodeIterator.html b/testing/web-platform/tests/dom/traversal/NodeIterator.html new file mode 100644 index 0000000000..fb81676cc5 --- /dev/null +++ b/testing/web-platform/tests/dom/traversal/NodeIterator.html @@ -0,0 +1,215 @@ + +NodeIterator tests + + +
      + + + + diff --git a/testing/web-platform/tests/dom/traversal/TreeWalker-acceptNode-filter-cross-realm-null-browsing-context.html b/testing/web-platform/tests/dom/traversal/TreeWalker-acceptNode-filter-cross-realm-null-browsing-context.html new file mode 100644 index 0000000000..f8e71bcdf5 --- /dev/null +++ b/testing/web-platform/tests/dom/traversal/TreeWalker-acceptNode-filter-cross-realm-null-browsing-context.html @@ -0,0 +1,30 @@ + + +TreeWalker: NodeFilter from detached iframe doesn't get called + + + + +
      + + diff --git a/testing/web-platform/tests/dom/traversal/TreeWalker-acceptNode-filter-cross-realm.html b/testing/web-platform/tests/dom/traversal/TreeWalker-acceptNode-filter-cross-realm.html new file mode 100644 index 0000000000..da91cf6cb2 --- /dev/null +++ b/testing/web-platform/tests/dom/traversal/TreeWalker-acceptNode-filter-cross-realm.html @@ -0,0 +1,60 @@ + + +TreeWalker: cross-realm NodeFilter throws TypeError of its associated Realm + + + + + + +
      +
      +
      + + diff --git a/testing/web-platform/tests/dom/traversal/TreeWalker-acceptNode-filter.html b/testing/web-platform/tests/dom/traversal/TreeWalker-acceptNode-filter.html new file mode 100644 index 0000000000..282dc9d142 --- /dev/null +++ b/testing/web-platform/tests/dom/traversal/TreeWalker-acceptNode-filter.html @@ -0,0 +1,195 @@ + + + + +TreeWalker: acceptNode-filter + + + + +
      + + +

      Test JS objects as NodeFilters

      + + + diff --git a/testing/web-platform/tests/dom/traversal/TreeWalker-basic.html b/testing/web-platform/tests/dom/traversal/TreeWalker-basic.html new file mode 100644 index 0000000000..bd8b112840 --- /dev/null +++ b/testing/web-platform/tests/dom/traversal/TreeWalker-basic.html @@ -0,0 +1,154 @@ + + + + +TreeWalker: Basic test + + + +
      + + +

      This test checks the basic functionality of TreeWalker.

      + + + diff --git a/testing/web-platform/tests/dom/traversal/TreeWalker-currentNode.html b/testing/web-platform/tests/dom/traversal/TreeWalker-currentNode.html new file mode 100644 index 0000000000..f795abe0d2 --- /dev/null +++ b/testing/web-platform/tests/dom/traversal/TreeWalker-currentNode.html @@ -0,0 +1,73 @@ + + + + +TreeWalker: currentNode + + + +
      + + +
      +

      Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.

      +
      +

      Test TreeWalker currentNode functionality

      + + + diff --git a/testing/web-platform/tests/dom/traversal/TreeWalker-previousNodeLastChildReject.html b/testing/web-platform/tests/dom/traversal/TreeWalker-previousNodeLastChildReject.html new file mode 100644 index 0000000000..e24ca06e20 --- /dev/null +++ b/testing/web-platform/tests/dom/traversal/TreeWalker-previousNodeLastChildReject.html @@ -0,0 +1,87 @@ + + + + +TreeWalker: previousNodeLastChildReject + + + +
      + + +

      Test that previousNode properly respects the filter.

      + + + diff --git a/testing/web-platform/tests/dom/traversal/TreeWalker-previousSiblingLastChildSkip.html b/testing/web-platform/tests/dom/traversal/TreeWalker-previousSiblingLastChildSkip.html new file mode 100644 index 0000000000..5e28aa5142 --- /dev/null +++ b/testing/web-platform/tests/dom/traversal/TreeWalker-previousSiblingLastChildSkip.html @@ -0,0 +1,91 @@ + + + + +TreeWalker: previousSiblingLastChildSkip + + + +
      + + +

      Test that previousSibling properly respects the filter.

      + + + diff --git a/testing/web-platform/tests/dom/traversal/TreeWalker-traversal-reject.html b/testing/web-platform/tests/dom/traversal/TreeWalker-traversal-reject.html new file mode 100644 index 0000000000..d6c96adc11 --- /dev/null +++ b/testing/web-platform/tests/dom/traversal/TreeWalker-traversal-reject.html @@ -0,0 +1,109 @@ + + + + +TreeWalker: traversal-reject + + + +
      + + +

      Test TreeWalker with rejection

      + + + diff --git a/testing/web-platform/tests/dom/traversal/TreeWalker-traversal-skip-most.html b/testing/web-platform/tests/dom/traversal/TreeWalker-traversal-skip-most.html new file mode 100644 index 0000000000..b6eafd4596 --- /dev/null +++ b/testing/web-platform/tests/dom/traversal/TreeWalker-traversal-skip-most.html @@ -0,0 +1,66 @@ + + + + +TreeWalker: traversal-skip-most + + + +
      + + +

      Test TreeWalker with skipping

      + + + diff --git a/testing/web-platform/tests/dom/traversal/TreeWalker-traversal-skip.html b/testing/web-platform/tests/dom/traversal/TreeWalker-traversal-skip.html new file mode 100644 index 0000000000..6bbebe667e --- /dev/null +++ b/testing/web-platform/tests/dom/traversal/TreeWalker-traversal-skip.html @@ -0,0 +1,111 @@ + + + + +TreeWalker: traversal-skip + + + +
      + + +

      Test TreeWalker with skipping

      + + + diff --git a/testing/web-platform/tests/dom/traversal/TreeWalker-walking-outside-a-tree.html b/testing/web-platform/tests/dom/traversal/TreeWalker-walking-outside-a-tree.html new file mode 100644 index 0000000000..b99e33e01f --- /dev/null +++ b/testing/web-platform/tests/dom/traversal/TreeWalker-walking-outside-a-tree.html @@ -0,0 +1,40 @@ + + + + +TreeWalker: walking-outside-a-tree + + + +
      + + +

      [Acid3 - Test 006a] walking outside a tree

      + + + diff --git a/testing/web-platform/tests/dom/traversal/TreeWalker.html b/testing/web-platform/tests/dom/traversal/TreeWalker.html new file mode 100644 index 0000000000..093c781447 --- /dev/null +++ b/testing/web-platform/tests/dom/traversal/TreeWalker.html @@ -0,0 +1,324 @@ + +TreeWalker tests + + +
      + + + + diff --git a/testing/web-platform/tests/dom/traversal/support/TreeWalker-acceptNode-filter-cross-realm-null-browsing-context-subframe.html b/testing/web-platform/tests/dom/traversal/support/TreeWalker-acceptNode-filter-cross-realm-null-browsing-context-subframe.html new file mode 100644 index 0000000000..f5e393d0f0 --- /dev/null +++ b/testing/web-platform/tests/dom/traversal/support/TreeWalker-acceptNode-filter-cross-realm-null-browsing-context-subframe.html @@ -0,0 +1,13 @@ + + + diff --git a/testing/web-platform/tests/dom/traversal/support/assert-node.js b/testing/web-platform/tests/dom/traversal/support/assert-node.js new file mode 100644 index 0000000000..0d5d8ad74f --- /dev/null +++ b/testing/web-platform/tests/dom/traversal/support/assert-node.js @@ -0,0 +1,10 @@ +// |expected| should be an object indicating the expected type of node. +function assert_node(actual, expected) +{ + assert_true(actual instanceof expected.type, + 'Node type mismatch: actual = ' + actual.nodeType + ', expected = ' + expected.nodeType); + if (typeof(expected.id) !== 'undefined') + assert_equals(actual.id, expected.id); + if (typeof(expected.nodeValue) !== 'undefined') + assert_equals(actual.nodeValue, expected.nodeValue); +} diff --git a/testing/web-platform/tests/dom/traversal/support/empty-document.html b/testing/web-platform/tests/dom/traversal/support/empty-document.html new file mode 100644 index 0000000000..b9cd130a07 --- /dev/null +++ b/testing/web-platform/tests/dom/traversal/support/empty-document.html @@ -0,0 +1,3 @@ + + + diff --git a/testing/web-platform/tests/dom/traversal/unfinished/001.xml b/testing/web-platform/tests/dom/traversal/unfinished/001.xml new file mode 100644 index 0000000000..08bce72fcf --- /dev/null +++ b/testing/web-platform/tests/dom/traversal/unfinished/001.xml @@ -0,0 +1,53 @@ + + + DOM Traversal: NodeIterator: Basics + + + +
      FAIL: Script failed to run.
      + + + + + \ No newline at end of file diff --git a/testing/web-platform/tests/dom/traversal/unfinished/002.xml b/testing/web-platform/tests/dom/traversal/unfinished/002.xml new file mode 100644 index 0000000000..bf3489688c --- /dev/null +++ b/testing/web-platform/tests/dom/traversal/unfinished/002.xml @@ -0,0 +1,54 @@ + + + DOM Traversal: NodeIterator: Basics Backwards + + + +
      FAIL: Script failed to run.
      + + + + + \ No newline at end of file diff --git a/testing/web-platform/tests/dom/traversal/unfinished/003.xml b/testing/web-platform/tests/dom/traversal/unfinished/003.xml new file mode 100644 index 0000000000..268e6bb4d7 --- /dev/null +++ b/testing/web-platform/tests/dom/traversal/unfinished/003.xml @@ -0,0 +1,58 @@ + + + DOM Traversal: NodeIterator: Removal of nodes that should have no effect + + + + +
      FAIL: Script did not complete.
      +

      + + \ No newline at end of file diff --git a/testing/web-platform/tests/dom/traversal/unfinished/004.xml b/testing/web-platform/tests/dom/traversal/unfinished/004.xml new file mode 100644 index 0000000000..618978f021 --- /dev/null +++ b/testing/web-platform/tests/dom/traversal/unfinished/004.xml @@ -0,0 +1,49 @@ + + + DOM Traversal: NodeIterator: Removal of the Reference Node + + + +
      FAIL: Script did not complete.
      +

      + + \ No newline at end of file diff --git a/testing/web-platform/tests/dom/traversal/unfinished/005.xml b/testing/web-platform/tests/dom/traversal/unfinished/005.xml new file mode 100644 index 0000000000..643e2f1cd4 --- /dev/null +++ b/testing/web-platform/tests/dom/traversal/unfinished/005.xml @@ -0,0 +1,57 @@ + + + DOM Traversal: NodeIterator: Removal of the Reference Node (deep check) + + + +
      FAIL: Script did not complete.
      +

      + + \ No newline at end of file diff --git a/testing/web-platform/tests/dom/traversal/unfinished/006.xml b/testing/web-platform/tests/dom/traversal/unfinished/006.xml new file mode 100644 index 0000000000..c2302af836 --- /dev/null +++ b/testing/web-platform/tests/dom/traversal/unfinished/006.xml @@ -0,0 +1,47 @@ + + + DOM Traversal: NodeIterator: Removal of an ancestor of the Reference Node (forwards) + + + +
      FAIL: Script did not complete.
      +

      + + diff --git a/testing/web-platform/tests/dom/traversal/unfinished/007.xml b/testing/web-platform/tests/dom/traversal/unfinished/007.xml new file mode 100644 index 0000000000..98b212e4e5 --- /dev/null +++ b/testing/web-platform/tests/dom/traversal/unfinished/007.xml @@ -0,0 +1,54 @@ + + + DOM Traversal: NodeIterator: Removal of an ancestor of the Reference Node (forwards) (deep check) + + + +
      FAIL: Script did not complete.
      +

      + + diff --git a/testing/web-platform/tests/dom/traversal/unfinished/008.xml b/testing/web-platform/tests/dom/traversal/unfinished/008.xml new file mode 100644 index 0000000000..41d7008ae4 --- /dev/null +++ b/testing/web-platform/tests/dom/traversal/unfinished/008.xml @@ -0,0 +1,48 @@ + + + DOM Traversal: NodeIterator: Removal of an ancestor of the Reference Node (backwards) + + + +
      FAIL: Script did not complete.
      +

      + + diff --git a/testing/web-platform/tests/dom/traversal/unfinished/009.xml b/testing/web-platform/tests/dom/traversal/unfinished/009.xml new file mode 100644 index 0000000000..c3006ecbd6 --- /dev/null +++ b/testing/web-platform/tests/dom/traversal/unfinished/009.xml @@ -0,0 +1,55 @@ + + + DOM Traversal: NodeIterator: Removal of an ancestor of the Reference Node (backwards) (deep check) + + + +
      FAIL: Script did not complete.
      +

      + + diff --git a/testing/web-platform/tests/dom/traversal/unfinished/010.xml b/testing/web-platform/tests/dom/traversal/unfinished/010.xml new file mode 100644 index 0000000000..63263a5fd7 --- /dev/null +++ b/testing/web-platform/tests/dom/traversal/unfinished/010.xml @@ -0,0 +1,64 @@ + + + DOM Traversal: NodeIterator: Filters + + + +
      FAIL: Script failed to run.
      + + + + + \ No newline at end of file diff --git a/testing/web-platform/tests/dom/traversal/unfinished/TODO b/testing/web-platform/tests/dom/traversal/unfinished/TODO new file mode 100644 index 0000000000..cecdf98b08 --- /dev/null +++ b/testing/web-platform/tests/dom/traversal/unfinished/TODO @@ -0,0 +1 @@ +Check what happens when a NodeFilter turns a number not in the range 1..3 \ No newline at end of file diff --git a/testing/web-platform/tests/dom/window-extends-event-target.html b/testing/web-platform/tests/dom/window-extends-event-target.html new file mode 100644 index 0000000000..3b690324e5 --- /dev/null +++ b/testing/web-platform/tests/dom/window-extends-event-target.html @@ -0,0 +1,55 @@ + + +Window extends EventTarget + + + + + + diff --git a/testing/web-platform/tests/dom/xslt/README.md b/testing/web-platform/tests/dom/xslt/README.md new file mode 100644 index 0000000000..ac713ce179 --- /dev/null +++ b/testing/web-platform/tests/dom/xslt/README.md @@ -0,0 +1,11 @@ +# XSLT + +This directory contains tentative tests for [XSLT](https://dom.spec.whatwg.org/#xslt). + +See [whatwg/dom#181](https://github.com/whatwg/dom/issues/181) for getting XSLT +better specified. + +There are additional details on XSLT in HTML: +- [Interactions with XPath and XSLT](https://html.spec.whatwg.org/multipage/infrastructure.html#interactions-with-xpath-and-xslt) +- [Interaction of `script` elements and XSLT](https://html.spec.whatwg.org/multipage/scripting.html#scriptTagXSLT) (non-normative) +- [Interaction of `template` elements with XSLT and XPath](https://html.spec.whatwg.org/multipage/scripting.html#template-XSLT-XPath) (non-normative) diff --git a/testing/web-platform/tests/dom/xslt/externalScript.js b/testing/web-platform/tests/dom/xslt/externalScript.js new file mode 100644 index 0000000000..7a2bf36225 --- /dev/null +++ b/testing/web-platform/tests/dom/xslt/externalScript.js @@ -0,0 +1 @@ +window.externalScript = true; diff --git a/testing/web-platform/tests/dom/xslt/invalid-output-encoding-crash.html b/testing/web-platform/tests/dom/xslt/invalid-output-encoding-crash.html new file mode 100644 index 0000000000..d84bb5b3c3 --- /dev/null +++ b/testing/web-platform/tests/dom/xslt/invalid-output-encoding-crash.html @@ -0,0 +1,26 @@ + + + + + + + + + diff --git a/testing/web-platform/tests/dom/xslt/sort-ref.html b/testing/web-platform/tests/dom/xslt/sort-ref.html new file mode 100644 index 0000000000..163002d0d0 --- /dev/null +++ b/testing/web-platform/tests/dom/xslt/sort-ref.html @@ -0,0 +1,10 @@ + + + + +
      +
      1
      +
      2
      +
      3
      +
      7
      +
      diff --git a/testing/web-platform/tests/dom/xslt/sort.html b/testing/web-platform/tests/dom/xslt/sort.html new file mode 100644 index 0000000000..631c3edd6a --- /dev/null +++ b/testing/web-platform/tests/dom/xslt/sort.html @@ -0,0 +1,48 @@ + + + + +
      + + + + + + + diff --git a/testing/web-platform/tests/dom/xslt/strip-space-crash.xml b/testing/web-platform/tests/dom/xslt/strip-space-crash.xml new file mode 100644 index 0000000000..61a906a5e7 --- /dev/null +++ b/testing/web-platform/tests/dom/xslt/strip-space-crash.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/testing/web-platform/tests/dom/xslt/transformToFragment-on-node-from-inactive-document-crash.html b/testing/web-platform/tests/dom/xslt/transformToFragment-on-node-from-inactive-document-crash.html new file mode 100644 index 0000000000..38a62a0a9d --- /dev/null +++ b/testing/web-platform/tests/dom/xslt/transformToFragment-on-node-from-inactive-document-crash.html @@ -0,0 +1,11 @@ + + + + diff --git a/testing/web-platform/tests/dom/xslt/transformToFragment.tentative.window.js b/testing/web-platform/tests/dom/xslt/transformToFragment.tentative.window.js new file mode 100644 index 0000000000..7bb6a56855 --- /dev/null +++ b/testing/web-platform/tests/dom/xslt/transformToFragment.tentative.window.js @@ -0,0 +1,39 @@ +const cases = { + internal: '', + external: '', +}; + +const loaded = new Promise(resolve => { + window.addEventListener('load', resolve); +}); + +Object.entries(cases).forEach(([k, v]) => { + const xsltSrc = ` + + +
      + ${v} +
      +
      +
      `; + + const processor = new XSLTProcessor(); + const parser = new DOMParser(); + processor.importStylesheet( + parser.parseFromString(xsltSrc, 'application/xml') + ); + document.body.appendChild( + processor.transformToFragment( + parser.parseFromString('', 'application/xml'), + document + ) + ); + + promise_test(async () => { + await loaded; + assert_true( + window[`${k}Script`], + 'script element from XSLTProcessor.transformToFragment() is evaluated' + ); + }, `${k} script`); +}) -- cgit v1.2.3