summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/html/dom
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
commit26a029d407be480d791972afb5975cf62c9360a6 (patch)
treef435a8308119effd964b339f76abb83a57c29483 /testing/web-platform/tests/html/dom
parentInitial commit. (diff)
downloadfirefox-26a029d407be480d791972afb5975cf62c9360a6.tar.xz
firefox-26a029d407be480d791972afb5975cf62c9360a6.zip
Adding upstream version 124.0.1.upstream/124.0.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'testing/web-platform/tests/html/dom')
-rw-r--r--testing/web-platform/tests/html/dom/aria-attribute-reflection.html487
-rw-r--r--testing/web-platform/tests/html/dom/aria-element-reflection-disconnected.html82
-rw-r--r--testing/web-platform/tests/html/dom/aria-element-reflection.html846
-rw-r--r--testing/web-platform/tests/html/dom/directionality/bdi-element-invalid-dir-ref.html13
-rw-r--r--testing/web-platform/tests/html/dom/directionality/bdi-element-invalid-dir.html17
-rw-r--r--testing/web-platform/tests/html/dom/documents/dom-tree-accessors/Document.body.html227
-rw-r--r--testing/web-platform/tests/html/dom/documents/dom-tree-accessors/Document.currentScript.html219
-rw-r--r--testing/web-platform/tests/html/dom/documents/dom-tree-accessors/Document.getElementsByClassName-null-undef.html30
-rw-r--r--testing/web-platform/tests/html/dom/documents/dom-tree-accessors/Element.getElementsByClassName-null-undef.html30
-rw-r--r--testing/web-platform/tests/html/dom/documents/dom-tree-accessors/cross-domain.js1
-rw-r--r--testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.embeds-document.plugins-01.html87
-rw-r--r--testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.forms.html83
-rw-r--r--testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.getElementsByClassName-same.html17
-rw-r--r--testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.getElementsByName/document.getElementsByName-case-xhtml.xhtml21
-rw-r--r--testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.getElementsByName/document.getElementsByName-case.html16
-rw-r--r--testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.getElementsByName/document.getElementsByName-id-xhtml.xhtml20
-rw-r--r--testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.getElementsByName/document.getElementsByName-id.html15
-rw-r--r--testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.getElementsByName/document.getElementsByName-interface.html16
-rw-r--r--testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.getElementsByName/document.getElementsByName-liveness.html26
-rw-r--r--testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.getElementsByName/document.getElementsByName-namespace-xhtml.xhtml32
-rw-r--r--testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.getElementsByName/document.getElementsByName-namespace.html27
-rw-r--r--testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.getElementsByName/document.getElementsByName-newelements-xhtml.xhtml126
-rw-r--r--testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.getElementsByName/document.getElementsByName-newelements.html47
-rw-r--r--testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.getElementsByName/document.getElementsByName-null-undef-xhtml.xhtml35
-rw-r--r--testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.getElementsByName/document.getElementsByName-null-undef.html30
-rw-r--r--testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.getElementsByName/document.getElementsByName-param-xhtml.xhtml28
-rw-r--r--testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.getElementsByName/document.getElementsByName-param.html23
-rw-r--r--testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.getElementsByName/document.getElementsByName-same.html17
-rw-r--r--testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.head-01.html22
-rw-r--r--testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.head-02.html20
-rw-r--r--testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.images.html119
-rw-r--r--testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.links.html27
-rw-r--r--testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.scripts.html21
-rw-r--r--testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.title-01.html32
-rw-r--r--testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.title-02.xhtml37
-rw-r--r--testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.title-03.html31
-rw-r--r--testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.title-04.xhtml48
-rw-r--r--testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.title-05.html42
-rw-r--r--testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.title-06.html19
-rw-r--r--testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.title-07.html11
-rw-r--r--testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.title-08.html22
-rw-r--r--testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.title-09.html97
-rw-r--r--testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.title-not-in-html-svg.html27
-rw-r--r--testing/web-platform/tests/html/dom/documents/dom-tree-accessors/nameditem-01.html19
-rw-r--r--testing/web-platform/tests/html/dom/documents/dom-tree-accessors/nameditem-02.html99
-rw-r--r--testing/web-platform/tests/html/dom/documents/dom-tree-accessors/nameditem-03.html18
-rw-r--r--testing/web-platform/tests/html/dom/documents/dom-tree-accessors/nameditem-04.html104
-rw-r--r--testing/web-platform/tests/html/dom/documents/dom-tree-accessors/nameditem-05.html104
-rw-r--r--testing/web-platform/tests/html/dom/documents/dom-tree-accessors/nameditem-06.html104
-rw-r--r--testing/web-platform/tests/html/dom/documents/dom-tree-accessors/nameditem-07.html109
-rw-r--r--testing/web-platform/tests/html/dom/documents/dom-tree-accessors/nameditem-08.html31
-rw-r--r--testing/web-platform/tests/html/dom/documents/dom-tree-accessors/nameditem-names.html101
-rw-r--r--testing/web-platform/tests/html/dom/documents/resource-metadata-management/document-compatmode-01.html13
-rw-r--r--testing/web-platform/tests/html/dom/documents/resource-metadata-management/document-compatmode-02.html14
-rw-r--r--testing/web-platform/tests/html/dom/documents/resource-metadata-management/document-compatmode-03.html12
-rw-r--r--testing/web-platform/tests/html/dom/documents/resource-metadata-management/document-compatmode-04.xhtml18
-rw-r--r--testing/web-platform/tests/html/dom/documents/resource-metadata-management/document-compatmode-05.xhtml19
-rw-r--r--testing/web-platform/tests/html/dom/documents/resource-metadata-management/document-compatmode-06.xhtml17
-rw-r--r--testing/web-platform/tests/html/dom/documents/resource-metadata-management/document-cookie.html41
-rw-r--r--testing/web-platform/tests/html/dom/documents/resource-metadata-management/document-lastModified-01.html25
-rw-r--r--testing/web-platform/tests/html/dom/documents/resource-metadata-management/document-lastModified.html15
-rw-r--r--testing/web-platform/tests/html/dom/documents/resource-metadata-management/document-lastModified.html.headers1
-rw-r--r--testing/web-platform/tests/html/dom/documents/resource-metadata-management/document-readyState.html33
-rw-r--r--testing/web-platform/tests/html/dom/documents/resource-metadata-management/support/document-lastModified-utils.js78
-rw-r--r--testing/web-platform/tests/html/dom/elements-embedded.js156
-rw-r--r--testing/web-platform/tests/html/dom/elements-forms-weekmonth.js42
-rw-r--r--testing/web-platform/tests/html/dom/elements-forms.js128
-rw-r--r--testing/web-platform/tests/html/dom/elements-grouping.js57
-rw-r--r--testing/web-platform/tests/html/dom/elements-metadata.js50
-rw-r--r--testing/web-platform/tests/html/dom/elements-misc.js60
-rw-r--r--testing/web-platform/tests/html/dom/elements-obsolete.js50
-rw-r--r--testing/web-platform/tests/html/dom/elements-sections.js64
-rw-r--r--testing/web-platform/tests/html/dom/elements-tabular.js109
-rw-r--r--testing/web-platform/tests/html/dom/elements-text.js63
-rw-r--r--testing/web-platform/tests/html/dom/elements/elements-in-the-dom/historical.html24
-rw-r--r--testing/web-platform/tests/html/dom/elements/elements-in-the-dom/unknown-element.html22
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/.htaccess16
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/classlist-nonstring.html44
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/custom-attrs.html29
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/data_unicode_attr.html22
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dataset-binding.window.js45
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dataset-delete.html54
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dataset-enumeration.html31
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dataset-get.html57
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dataset-prototype.html26
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dataset-set.html44
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dataset.html38
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir-assorted.window.js115
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir-auto-div-append-child.html18
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir-auto-dynamic-changes.window.js276
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir-auto-form-associated.window.js71
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir-bdi-script.html24
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-01-ref.html23
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-01.html33
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-02-ref.html23
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-02.html33
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-03-ref.html23
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-03.html33
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-04-ref.html23
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-04.html33
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-05-ref.html23
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-05.html33
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-06-ref.html23
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-06.html33
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-07-ref.html23
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-07.html33
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-08-ref.html23
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-08.html33
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-09-ref.html23
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-09.html33
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-10-ref.html23
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-10.html33
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-11-ref.html23
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-11.html33
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-12-ref.html23
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-12.html31
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-13-ref.html23
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-13.html30
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-14-ref.html23
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-14.html30
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-15-ref.html24
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-15.html30
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-16-ref.html23
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-16.html30
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-17-ref.html23
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-17.html30
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-18-ref.html23
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-18.html30
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-19-ref.html23
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-19.html30
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-20-ref.html22
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-20.html30
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-21-ref.html22
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-21.html30
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-22-ref.html23
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-22.html30
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-23-ref.html22
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-23.html30
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-24-ref.html22
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-24.html30
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-25-ref.html25
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-25.html32
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-26-ref.html25
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-26.html32
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-27-ref.html25
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-27.html32
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-28-ref.html25
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-28.html32
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-29-ref.html25
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-29.html32
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-30-ref.html25
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-30.html32
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-31-ref.html23
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-31.html32
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-32-ref.html23
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-32.html30
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-33-ref.html23
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-33.html32
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-34-ref.html23
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-34.html32
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-35-ref.html23
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-35.html32
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-36-ref.html23
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-36.html32
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-37-ref.html23
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-37.html32
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-38-ref.html23
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-38.html32
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-39-ref.html24
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-39.html32
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-40-ref.html23
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-40.html32
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-41-ref.html24
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-41.html32
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-utils.js8
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir-slots-directionality.html97
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-EN-L-ref.html57
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-EN-L.html58
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-EN-R-ref.html57
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-EN-R.html58
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-L-ref.html57
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-L.html58
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-N-EN-L-ref.html57
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-N-EN-L.html58
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-N-EN-R-ref.html57
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-N-EN-R.html58
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-N-EN-ref.html50
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-N-EN.html51
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-N-L-ref.html57
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-N-L.html58
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-N-R-ref.html57
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-N-R.html58
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-R-ref.html58
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-R.html58
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-contained-L-ref.html61
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-contained-L.html62
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-contained-R-ref.html57
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-contained-R.html58
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-contained-bdi-L-ref.html60
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-contained-bdi-L.html61
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-contained-bdi-R-ref.html57
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-contained-bdi-R.html58
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-contained-dir-L-ref.html60
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-contained-dir-L.html61
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-contained-dir-R-ref.html57
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-contained-dir-R.html58
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-contained-dir_auto-L-ref.html60
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-contained-dir_auto-L.html61
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-contained-dir_auto-R-ref.html57
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-contained-dir_auto-R.html58
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-contained-script-L-ref.html57
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-contained-script-L.html58
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-contained-script-R-ref.html58
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-contained-script-R.html59
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-contained-style-L-ref.html57
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-contained-style-L.html58
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-contained-style-R-ref.html57
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-contained-style-R.html58
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-contained-textarea-L-ref.html60
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-contained-textarea-L.html61
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-contained-textarea-R-ref.html57
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-contained-textarea-R.html58
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-EN-L-ref.html58
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-EN-L.html59
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-EN-R-ref.html58
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-EN-R.html59
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-L-ref.html58
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-L.html59
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-N-EN-L-ref.html58
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-N-EN-L.html59
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-N-EN-R-ref.html58
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-N-EN-R.html59
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-N-EN-ref.html53
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-N-EN.html54
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-N-L-ref.html58
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-N-L.html59
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-N-R-ref.html58
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-N-R.html59
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-R-ref.html58
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-R.html59
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-script-EN-L-ref.html58
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-script-EN-L.html70
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-script-EN-R-ref.html58
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-script-EN-R.html70
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-script-L-ref.html58
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-script-L.html70
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-script-N-EN-L-ref.html58
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-script-N-EN-L.html70
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-script-N-EN-R-ref.html58
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-script-N-EN-R.html70
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-script-N-EN-ref.html53
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-script-N-EN.html69
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-script-N-L-ref.html58
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-script-N-L.html70
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-script-N-R-ref.html58
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-script-N-R.html70
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-script-R-ref.html58
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-script-R.html70
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-isolate-ref.html57
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-isolate.html58
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-pre-N-EN-ref.html49
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-pre-N-EN.html66
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-pre-N-between-Rs-ref.html61
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-pre-N-between-Rs.html76
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-pre-mixed-ref.html61
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-pre-mixed.html77
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-textarea-N-EN-ref.html49
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-textarea-N-EN.html66
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-textarea-N-between-Rs-ref.html64
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-textarea-N-between-Rs.html79
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-textarea-mixed-ref.html64
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-textarea-mixed.html80
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-textarea-script-N-EN-ref.html49
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-textarea-script-N-EN.html77
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-textarea-script-N-between-Rs-ref.html60
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-textarea-script-N-between-Rs.html84
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-textarea-script-mixed-ref.html64
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-textarea-script-mixed.html100
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/document-dir.html26
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/id-attribute.html130
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/id-name-specialcase.html30
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/id-name.html17
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/lang-attribute-shadow.window.js81
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/lang-attribute.window.js16
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/lang-xmllang-01-ref.html20
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/lang-xmllang-01.html58
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/lang-xyzzy-ref.html9
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/lang-xyzzy.html12
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/mapped-attribute-adopt-001.html23
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/style-01-ref.html24
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/style-01.html26
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/the-anchor-attribute-001.tentative.html39
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/the-anchor-attribute-002.tentative.html50
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/the-anchor-attribute-003-crash.tentative.html27
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/the-anchor-attribute-003.tentative.html71
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/the-lang-attribute-001.html41
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/the-lang-attribute-002.html41
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/the-lang-attribute-003.html41
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/the-lang-attribute-003.html.headers1
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/the-lang-attribute-004.html42
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/the-lang-attribute-005.html41
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/the-lang-attribute-005.html.headers1
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/the-lang-attribute-006.html42
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/the-lang-attribute-006.html.headers1
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/the-lang-attribute-007.html42
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/the-lang-attribute-008.html41
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/the-lang-attribute-009.html41
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/the-lang-attribute-009.html.headers1
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/the-lang-attribute-010.html42
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/the-lang-attribute-011.html.headers1
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/the-translate-attribute-007.html29
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/the-translate-attribute-008.html29
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/the-translate-attribute-009.html29
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/the-translate-attribute-010.html29
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/the-translate-attribute-011.html29
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/the-translate-attribute-012.html29
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/title-manual.html8
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/translate-enumerated-ascii-case-insensitive.html26
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/translate-inherit-no-parent-element.html33
-rw-r--r--testing/web-platform/tests/html/dom/elements/global-attributes/translate-non-html-translation-mode.html46
-rw-r--r--testing/web-platform/tests/html/dom/elements/images/bypass-cache-revalidation.html37
-rw-r--r--testing/web-platform/tests/html/dom/elements/images/image.py28
-rw-r--r--testing/web-platform/tests/html/dom/elements/name-content-attribute-and-property.html57
-rw-r--r--testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-001a.html36
-rw-r--r--testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-001b.html36
-rw-r--r--testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-001c.html36
-rw-r--r--testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-002a.html36
-rw-r--r--testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-002b.html36
-rw-r--r--testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-002c.html36
-rw-r--r--testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-003a.html36
-rw-r--r--testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-003b.html36
-rw-r--r--testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-003c.html36
-rw-r--r--testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-004a.html36
-rw-r--r--testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-004b.html36
-rw-r--r--testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-004c.html36
-rw-r--r--testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-005a.html36
-rw-r--r--testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-005b.html36
-rw-r--r--testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-005c.html36
-rw-r--r--testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-006a.html32
-rw-r--r--testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-006b.html32
-rw-r--r--testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-006c.html32
-rw-r--r--testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-007a.html36
-rw-r--r--testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-007b.html36
-rw-r--r--testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-007c.html36
-rw-r--r--testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-008a.html36
-rw-r--r--testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-008b.html36
-rw-r--r--testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-008c.html36
-rw-r--r--testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-009a.html33
-rw-r--r--testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-009b.html33
-rw-r--r--testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-009c.html33
-rw-r--r--testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/reference/dir-isolation-001-ref.html16
-rw-r--r--testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/reference/dir-isolation-002a-ref.html16
-rw-r--r--testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/reference/dir-isolation-002b-ref.html16
-rw-r--r--testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/reference/dir-isolation-002c-ref.html16
-rw-r--r--testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/reference/dir-isolation-003-ref.html16
-rw-r--r--testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/reference/dir-isolation-004-ref.html16
-rw-r--r--testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/reference/dir-isolation-005-ref.html16
-rw-r--r--testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/reference/dir-isolation-006-ref.html16
-rw-r--r--testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/reference/dir-isolation-006c-ref.html16
-rw-r--r--testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/reference/dir-isolation-007-ref.html16
-rw-r--r--testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/reference/dir-isolation-008-ref.html16
-rw-r--r--testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/reference/dir-isolation-009-ref.html16
-rw-r--r--testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/reference/dir-isolation-009b-ref.html16
-rw-r--r--testing/web-platform/tests/html/dom/elements/the-innertext-and-outertext-properties/dynamic-getter.html88
-rw-r--r--testing/web-platform/tests/html/dom/elements/the-innertext-and-outertext-properties/getter-first-letter-marker-multicol.html18
-rw-r--r--testing/web-platform/tests/html/dom/elements/the-innertext-and-outertext-properties/getter-tests.js401
-rw-r--r--testing/web-platform/tests/html/dom/elements/the-innertext-and-outertext-properties/getter.html64
-rw-r--r--testing/web-platform/tests/html/dom/elements/the-innertext-and-outertext-properties/innertext-domnoderemoved-crash.html16
-rw-r--r--testing/web-platform/tests/html/dom/elements/the-innertext-and-outertext-properties/innertext-setter-tests.js42
-rw-r--r--testing/web-platform/tests/html/dom/elements/the-innertext-and-outertext-properties/innertext-setter.html88
-rw-r--r--testing/web-platform/tests/html/dom/elements/the-innertext-and-outertext-properties/multiple-text-nodes.window.js16
-rw-r--r--testing/web-platform/tests/html/dom/elements/the-innertext-and-outertext-properties/outertext-setter.html180
-rw-r--r--testing/web-platform/tests/html/dom/elements/wai-aria/README.md1
-rw-r--r--testing/web-platform/tests/html/dom/historical.html55
-rw-r--r--testing/web-platform/tests/html/dom/idlharness-shadowrealm.window.js2
-rw-r--r--testing/web-platform/tests/html/dom/idlharness.https.html241
-rw-r--r--testing/web-platform/tests/html/dom/idlharness.worker.js22
-rw-r--r--testing/web-platform/tests/html/dom/new-harness.js11
-rw-r--r--testing/web-platform/tests/html/dom/original-harness.js339
-rw-r--r--testing/web-platform/tests/html/dom/reflection-embedded.html17
-rw-r--r--testing/web-platform/tests/html/dom/reflection-forms-weekmonth.html17
-rw-r--r--testing/web-platform/tests/html/dom/reflection-forms.html17
-rw-r--r--testing/web-platform/tests/html/dom/reflection-grouping.html17
-rw-r--r--testing/web-platform/tests/html/dom/reflection-metadata.html17
-rw-r--r--testing/web-platform/tests/html/dom/reflection-misc.html17
-rw-r--r--testing/web-platform/tests/html/dom/reflection-obsolete.html17
-rw-r--r--testing/web-platform/tests/html/dom/reflection-original.html40
-rw-r--r--testing/web-platform/tests/html/dom/reflection-sections.html17
-rw-r--r--testing/web-platform/tests/html/dom/reflection-tabular.html17
-rw-r--r--testing/web-platform/tests/html/dom/reflection-text.html17
-rw-r--r--testing/web-platform/tests/html/dom/reflection.js1065
-rw-r--r--testing/web-platform/tests/html/dom/render-blocking/blocking-idl-attr.html44
-rw-r--r--testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-001.tentative.html28
-rw-r--r--testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-002.tentative.html37
-rw-r--r--testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-003.tentative.html33
-rw-r--r--testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-004.tentative.html30
-rw-r--r--testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-005.tentative.html30
-rw-r--r--testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-006.tentative.html30
-rw-r--r--testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-007.tentative.html28
-rw-r--r--testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-008.tentative.html30
-rw-r--r--testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-009.tentative.html30
-rw-r--r--testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-010.tentative.html30
-rw-r--r--testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-011.tentative.html30
-rw-r--r--testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-012.tentative.html30
-rw-r--r--testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-013.tentative.html30
-rw-r--r--testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-014.tentative.html36
-rw-r--r--testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-015.tentative.html32
-rw-r--r--testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-016.tentative.html32
-rw-r--r--testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-017.tentative.html31
-rw-r--r--testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-018.tentative.html32
-rw-r--r--testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-019.tentative.html32
-rw-r--r--testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-020.tentative.html31
-rw-r--r--testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-021.tentative.html35
-rw-r--r--testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-022.tentative.html32
-rw-r--r--testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-023.tentative.html31
-rw-r--r--testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-024.tentative.html36
-rw-r--r--testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-025.tentative.html38
-rw-r--r--testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-026.tentative.html38
-rw-r--r--testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-027.tentative.html38
-rw-r--r--testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-028.tentative.html48
-rw-r--r--testing/web-platform/tests/html/dom/render-blocking/non-render-blocking-scripts.optional.html61
-rw-r--r--testing/web-platform/tests/html/dom/render-blocking/parser-blocking-script.html19
-rw-r--r--testing/web-platform/tests/html/dom/render-blocking/parser-inserted-async-inline-module-with-import.html21
-rw-r--r--testing/web-platform/tests/html/dom/render-blocking/parser-inserted-async-script.html19
-rw-r--r--testing/web-platform/tests/html/dom/render-blocking/parser-inserted-defer-script.html19
-rw-r--r--testing/web-platform/tests/html/dom/render-blocking/parser-inserted-inline-module-with-import.html21
-rw-r--r--testing/web-platform/tests/html/dom/render-blocking/parser-inserted-module-script.html19
-rw-r--r--testing/web-platform/tests/html/dom/render-blocking/parser-inserted-style-element.html20
-rw-r--r--testing/web-platform/tests/html/dom/render-blocking/parser-inserted-stylesheet-link.html18
-rw-r--r--testing/web-platform/tests/html/dom/render-blocking/remove-attr-script-keeps-blocking.html25
-rw-r--r--testing/web-platform/tests/html/dom/render-blocking/remove-attr-style-keeps-blocking.html28
-rw-r--r--testing/web-platform/tests/html/dom/render-blocking/remove-attr-stylesheet-link-keeps-blocking.html27
-rw-r--r--testing/web-platform/tests/html/dom/render-blocking/remove-attr-unblocks-rendering.optional.html86
-rw-r--r--testing/web-platform/tests/html/dom/render-blocking/remove-element-unblocks-rendering.optional.html83
-rw-r--r--testing/web-platform/tests/html/dom/render-blocking/remove-pending-async-render-blocking-script.html19
-rw-r--r--testing/web-platform/tests/html/dom/render-blocking/script-inserted-inline-module-with-import.html25
-rw-r--r--testing/web-platform/tests/html/dom/render-blocking/script-inserted-module-script.html22
-rw-r--r--testing/web-platform/tests/html/dom/render-blocking/script-inserted-script.html21
-rw-r--r--testing/web-platform/tests/html/dom/render-blocking/script-inserted-style-element.html26
-rw-r--r--testing/web-platform/tests/html/dom/render-blocking/script-inserted-stylesheet-link.html27
-rw-r--r--testing/web-platform/tests/html/dom/render-blocking/support/dummy-1.js1
-rw-r--r--testing/web-platform/tests/html/dom/render-blocking/support/dummy-1.mjs1
-rw-r--r--testing/web-platform/tests/html/dom/render-blocking/support/target-red.css3
-rw-r--r--testing/web-platform/tests/html/dom/render-blocking/support/test-render-blocking.js118
-rw-r--r--testing/web-platform/tests/html/dom/render-blocking/support/utils.js5
-rw-r--r--testing/web-platform/tests/html/dom/resources/self-origin-subframe.html22
-rw-r--r--testing/web-platform/tests/html/dom/self-origin.any.js5
-rw-r--r--testing/web-platform/tests/html/dom/self-origin.sub.html93
-rw-r--r--testing/web-platform/tests/html/dom/usvstring-reflection.https.html139
449 files changed, 21914 insertions, 0 deletions
diff --git a/testing/web-platform/tests/html/dom/aria-attribute-reflection.html b/testing/web-platform/tests/html/dom/aria-attribute-reflection.html
new file mode 100644
index 0000000000..fa5e9ad5c7
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/aria-attribute-reflection.html
@@ -0,0 +1,487 @@
+<!DOCTYPE HTML>
+<meta charset="utf-8" />
+<title>Element Reflection for ARIA properties</title>
+<link rel=help href="https://wicg.github.io/aom/spec/aria-reflection.html">
+<link rel="author" title="Meredith Lane" href="meredithl@chromium.org">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<script>
+function testNullable(element, jsAttr, contentAttr) {
+ var originalValue = element[jsAttr];
+ assert_false(originalValue === null);
+ element[jsAttr] = null;
+ assert_equals(element[jsAttr], null);
+ assert_false(element.hasAttribute(contentAttr));
+ // Setting to undefined results in same state as setting to null.
+ element[jsAttr] = originalValue;
+ element[jsAttr] = undefined;
+ assert_equals(element[jsAttr], null);
+ assert_false(element.hasAttribute(contentAttr));
+}
+</script>
+
+<div id="role" role="button"></div>
+<script>
+test(function(t) {
+ var element = document.getElementById("role");
+ assert_equals(element.role, "button");
+ element.role = "checkbox";
+ assert_equals(element.getAttribute("role"), "checkbox");
+ testNullable(element, "role", "role");
+}, "role attribute reflects.");
+</script>
+
+<div id="atomic" aria-atomic="true"></div>
+<script>
+test(function(t) {
+ var element = document.getElementById("atomic");
+ assert_equals(element.ariaAtomic, "true");
+ element.ariaAtomic = "false";
+ assert_equals(element.getAttribute("aria-atomic"), "false");
+ testNullable(element, "ariaAtomic", "aria-atomic");
+}, "aria-atomic attribute reflects.");
+</script>
+
+<div id="autocomplete" aria-autocomplete="list"></div>
+<script>
+test(function(t) {
+ var element = document.getElementById("autocomplete");
+ assert_equals(element.ariaAutoComplete, "list");
+ element.ariaAutoComplete = "inline";
+ assert_equals(element.getAttribute("aria-autocomplete"), "inline");
+ testNullable(element, "ariaAutoComplete", "aria-autocomplete");
+}, "aria-autocomplete attribute reflects.");
+</script>
+
+<div id="busy" aria-busy="true"></div>
+<script>
+test(function(t) {
+ var element = document.getElementById("busy");
+ assert_equals(element.ariaBusy, "true");
+ element.ariaBusy = "false";
+ assert_equals(element.getAttribute("aria-busy"), "false");
+ testNullable(element, "ariaBusy", "aria-busy");
+}, "aria-busy attribute reflects.");
+</script>
+
+<div id="checked" aria-checked="mixed"></div>
+<script>
+test(function(t) {
+ var element = document.getElementById("checked");
+ assert_equals(element.ariaChecked, "mixed");
+ element.ariaChecked = "true";
+ assert_equals(element.getAttribute("aria-checked"), "true");
+ testNullable(element, "ariaChecked", "aria-checked");
+}, "aria-checked attribute reflects.");
+</script>
+
+<div id="colcount" aria-colcount="5"></div>
+<script>
+test(function(t) {
+ var element = document.getElementById("colcount");
+ assert_equals(element.ariaColCount, "5");
+ element.ariaColCount = "6";
+ assert_equals(element.getAttribute("aria-colcount"), "6");
+ testNullable(element, "ariaColCount", "aria-colcount");
+}, "aria-colcount attribute reflects.");
+</script>
+
+<div id="colindex" aria-colindex="1"></div>
+<script>
+test(function(t) {
+ var element = document.getElementById("colindex");
+ assert_equals(element.ariaColIndex, "1");
+ element.ariaColIndex = "2";
+ assert_equals(element.getAttribute("aria-colindex"), "2");
+ testNullable(element, "ariaColIndex", "aria-colindex");
+}, "aria-colindex attribute reflects.");
+</script>
+
+<div id="colspan" aria-colspan="2"></div>
+<script>
+test(function(t) {
+ var element = document.getElementById("colspan");
+ assert_equals(element.ariaColSpan, "2");
+ element.ariaColSpan = "3";
+ assert_equals(element.getAttribute("aria-colspan"), "3");
+ testNullable(element, "ariaColSpan", "aria-colspan");
+}, "aria-colspan attribute reflects.");
+</script>
+
+<div id="current" aria-current="page"></div>
+<script>
+test(function(t) {
+ var element = document.getElementById("current");
+ assert_equals(element.ariaCurrent, "page");
+ element.ariaCurrent = "step";
+ assert_equals(element.getAttribute("aria-current"), "step");
+ testNullable(element, "ariaCurrent", "aria-current");
+}, "aria-current attribute reflects.");
+</script>
+
+<div id="disabled" aria-disabled="true"></div>
+
+<div id="description" aria-description="cold as ice"></div>
+<script>
+test(function(t) {
+ var element = document.getElementById("description");
+ assert_equals(element.ariaDescription, "cold as ice");
+ element.ariaDescription = "hot as fire";
+ assert_equals(element.getAttribute("aria-description"), "hot as fire");
+ testNullable(element, "ariaDescription", "aria-description");
+}, "aria-description attribute reflects.");
+</script>
+
+<script>
+test(function(t) {
+ var element = document.getElementById("disabled");
+ assert_equals(element.ariaDisabled, "true");
+ element.ariaDisabled = "false";
+ assert_equals(element.getAttribute("aria-disabled"), "false");
+ testNullable(element, "ariaDisabled", "aria-disabled");
+}, "aria-disabled attribute reflects.");
+</script>
+
+<div id="expanded" aria-expanded="true"></div>
+<script>
+test(function(t) {
+ var element = document.getElementById("expanded");
+ assert_equals(element.ariaExpanded, "true");
+ element.ariaExpanded = "false";
+ assert_equals(element.getAttribute("aria-expanded"), "false");
+ testNullable(element, "ariaExpanded", "aria-expanded");
+}, "aria-expanded attribute reflects.");
+</script>
+
+<div id="haspopup" aria-haspopup="menu"></div>
+<script>
+test(function(t) {
+ var element = document.getElementById("haspopup");
+ assert_equals(element.ariaHasPopup, "menu");
+ element.ariaHasPopup = "listbox";
+ assert_equals(element.getAttribute("aria-haspopup"), "listbox");
+ testNullable(element, "ariaHasPopup", "aria-haspopup");
+}, "aria-haspopup attribute reflects.");
+</script>
+
+<div id="hidden" aria-hidden="true" tabindex="-1"></div>
+<script>
+test(function(t) {
+ var element = document.getElementById("hidden");
+ assert_equals(element.ariaHidden, "true");
+ element.ariaHidden = "false";
+ assert_equals(element.getAttribute("aria-hidden"), "false");
+ testNullable(element, "ariaHidden", "aria-hidden");
+}, "aria-hidden attribute reflects.");
+</script>
+
+<div id="invalid" aria-invalid="true"></div>
+<script>
+test(function(t) {
+ var element = document.getElementById("invalid");
+ assert_equals(element.ariaInvalid, "true");
+ element.ariaInvalid = "grammar";
+ assert_equals(element.getAttribute("aria-invalid"), "grammar");
+ testNullable(element, "ariaInvalid", "aria-invalid");
+}, "aria-invalid attribute reflects.");
+</script>
+
+<div id="keyshortcuts" aria-keyshortcuts="x"></div>
+<script>
+test(function(t) {
+ var element = document.getElementById("keyshortcuts");
+ assert_equals(element.ariaKeyShortcuts, "x");
+ element.ariaKeyShortcuts = "y";
+ assert_equals(element.getAttribute("aria-keyshortcuts"), "y");
+ testNullable(element, "ariaKeyShortcuts", "aria-keyshortcuts");
+}, "aria-keyshortcuts attribute reflects.");
+</script>
+
+<div id="label" aria-label="x"></div>
+<script>
+test(function(t) {
+ var element = document.getElementById("label");
+ assert_equals(element.ariaLabel, "x");
+ element.ariaLabel = "y";
+ assert_equals(element.getAttribute("aria-label"), "y");
+ testNullable(element, "ariaLabel", "aria-label");
+}, "aria-label attribute reflects.");
+</script>
+
+<div id="level" aria-level="1"></div>
+<script>
+test(function(t) {
+ var element = document.getElementById("level");
+ assert_equals(element.ariaLevel, "1");
+ element.ariaLevel = "2";
+ assert_equals(element.getAttribute("aria-level"), "2");
+ testNullable(element, "ariaLevel", "aria-level");
+}, "aria-level attribute reflects.");
+</script>
+
+<div id="live" aria-live="polite"></div>
+<script>
+test(function(t) {
+ var element = document.getElementById("live");
+ assert_equals(element.ariaLive, "polite");
+ element.ariaLive = "assertive";
+ assert_equals(element.getAttribute("aria-live"), "assertive");
+ testNullable(element, "ariaLive", "aria-live");
+}, "aria-live attribute reflects.");
+</script>
+
+<div id="modal" aria-modal="true"></div>
+<script>
+test(function(t) {
+ var element = document.getElementById("modal");
+ assert_equals(element.ariaModal, "true");
+ element.ariaModal = "false";
+ assert_equals(element.getAttribute("aria-modal"), "false");
+ testNullable(element, "ariaModal", "aria-modal");
+}, "aria-modal attribute reflects.");
+</script>
+
+<div id="multiline" aria-multiline="true"></div>
+<script>
+test(function(t) {
+ var element = document.getElementById("multiline");
+ assert_equals(element.ariaMultiLine, "true");
+ element.ariaMultiLine = "false";
+ assert_equals(element.getAttribute("aria-multiline"), "false");
+ testNullable(element, "ariaMultiLine", "aria-multiline");
+}, "aria-multiline attribute reflects.");
+</script>
+
+<div id="multiselectable" aria-multiselectable="true"></div>
+<script>
+test(function(t) {
+ var element = document.getElementById("multiselectable");
+ assert_equals(element.ariaMultiSelectable, "true");
+ element.ariaMultiSelectable = "false";
+ assert_equals(element.getAttribute("aria-multiselectable"), "false");
+ testNullable(element, "ariaMultiSelectable", "aria-multiselectable");
+}, "aria-multiselectable attribute reflects.");
+</script>
+
+<div id="orientation" aria-orientation="vertical"></div>
+<script>
+test(function(t) {
+ var element = document.getElementById("orientation");
+ assert_equals(element.ariaOrientation, "vertical");
+ element.ariaOrientation = "horizontal";
+ assert_equals(element.getAttribute("aria-orientation"), "horizontal");
+ testNullable(element, "ariaOrientation", "aria-orientation");
+}, "aria-orientation attribute reflects.");
+</script>
+
+<div id="placeholder" aria-placeholder="x"></div>
+<script>
+test(function(t) {
+ var element = document.getElementById("placeholder");
+ assert_equals(element.ariaPlaceholder, "x");
+ element.ariaPlaceholder = "y";
+ assert_equals(element.getAttribute("aria-placeholder"), "y");
+ testNullable(element, "ariaPlaceholder", "aria-placeholder");
+}, "aria-placeholder attribute reflects.");
+</script>
+
+<div id="posinset" aria-posinset="10"></div>
+<script>
+test(function(t) {
+ var element = document.getElementById("posinset");
+ assert_equals(element.ariaPosInSet, "10");
+ element.ariaPosInSet = "11";
+ assert_equals(element.getAttribute("aria-posinset"), "11");
+ testNullable(element, "ariaPosInSet", "aria-posinset");
+}, "aria-posinset attribute reflects.");
+</script>
+
+<button id="pressed" aria-pressed="true"></button>
+
+<script>
+test(function(t) {
+ var element = document.getElementById("pressed");
+ assert_equals(element.ariaPressed, "true");
+ element.ariaPressed = "false";
+ assert_equals(element.getAttribute("aria-pressed"), "false");
+ testNullable(element, "ariaPressed", "aria-pressed");
+}, "aria-pressed attribute reflects.");
+</script>
+
+<div id="readonly" aria-readonly="true"></div>
+<script>
+test(function(t) {
+ var element = document.getElementById("readonly");
+ assert_equals(element.ariaReadOnly, "true");
+ element.ariaReadOnly = "false";
+ assert_equals(element.getAttribute("aria-readonly"), "false");
+ testNullable(element, "ariaReadOnly", "aria-readonly");
+}, "aria-readonly attribute reflects.");
+</script>
+
+<div id="relevant" aria-relevant="text"></div>
+<script>
+test(function(t) {
+ var element = document.getElementById("relevant");
+ assert_equals(element.ariaRelevant, "text");
+ element.ariaRelevant = "removals";
+ assert_equals(element.getAttribute("aria-relevant"), "removals");
+ testNullable(element, "ariaRelevant", "aria-relevant");
+}, "aria-relevant attribute reflects.");
+</script>
+
+<div id="required" aria-required="true"></div>
+<script>
+test(function(t) {
+ var element = document.getElementById("required");
+ assert_equals(element.ariaRequired, "true");
+ element.ariaRequired = "false";
+ assert_equals(element.getAttribute("aria-required"), "false");
+ testNullable(element, "ariaRequired", "aria-required");
+}, "aria-required attribute reflects.");
+</script>
+
+<div id="roledescription" aria-roledescription="x"></div>
+<script>
+test(function(t) {
+ var element = document.getElementById("roledescription");
+ assert_equals(element.ariaRoleDescription, "x");
+ element.ariaRoleDescription = "y";
+ assert_equals(element.getAttribute("aria-roledescription"), "y");
+ testNullable(element, "ariaRoleDescription", "aria-roledescription");
+}, "aria-roledescription attribute reflects.");
+</script>
+
+<div id="rowcount" aria-rowcount="10"></div>
+<script>
+test(function(t) {
+ var element = document.getElementById("rowcount");
+ assert_equals(element.ariaRowCount, "10");
+ element.ariaRowCount = "11";
+ assert_equals(element.getAttribute("aria-rowcount"), "11");
+ testNullable(element, "ariaRowCount", "aria-rowcount");
+}, "aria-rowcount attribute reflects.");
+</script>
+
+<div id="rowindex" aria-rowindex="1"></div>
+<script>
+test(function(t) {
+ var element = document.getElementById("rowindex");
+ assert_equals(element.ariaRowIndex, "1");
+ element.ariaRowIndex = "2";
+ assert_equals(element.getAttribute("aria-rowindex"), "2");
+ testNullable(element, "ariaRowIndex", "aria-rowindex");
+}, "aria-rowindex attribute reflects.");
+</script>
+
+<div id="rowspan" aria-rowspan="2"></div>
+<script>
+test(function(t) {
+ var element = document.getElementById("rowspan");
+ assert_equals(element.ariaRowSpan, "2");
+ element.ariaRowSpan = "3";
+ assert_equals(element.getAttribute("aria-rowspan"), "3");
+ testNullable(element, "ariaRowSpan", "aria-rowspan");
+}, "aria-rowspan attribute reflects.");
+</script>
+
+<div id="selected" aria-selected="true"></div>
+<script>
+test(function(t) {
+ var element = document.getElementById("selected");
+ assert_equals(element.ariaSelected, "true");
+ element.ariaSelected = "false";
+ assert_equals(element.getAttribute("aria-selected"), "false");
+ testNullable(element, "ariaSelected", "aria-selected");
+}, "aria-selected attribute reflects.");
+</script>
+
+<div id="setsize" aria-setsize="10"></div>
+<script>
+test(function(t) {
+ var element = document.getElementById("setsize");
+ assert_equals(element.ariaSetSize, "10");
+ element.ariaSetSize = "11";
+ assert_equals(element.getAttribute("aria-setsize"), "11");
+ testNullable(element, "ariaSetSize", "aria-setsize");
+}, "aria-setsize attribute reflects.");
+</script>
+
+<div id="sort" aria-sort="descending"></div>
+<script>
+test(function(t) {
+ var element = document.getElementById("sort");
+ assert_equals(element.ariaSort, "descending");
+ element.ariaSort = "ascending";
+ assert_equals(element.getAttribute("aria-sort"), "ascending");
+ testNullable(element, "ariaSort", "aria-sort");
+}, "aria-sort attribute reflects.");
+</script>
+
+<div id="valuemax" aria-valuemax="99"></div>
+<script>
+test(function(t) {
+ var element = document.getElementById("valuemax");
+ assert_equals(element.ariaValueMax, "99");
+ element.ariaValueMax = "100";
+ assert_equals(element.getAttribute("aria-valuemax"), "100");
+ testNullable(element, "ariaValueMax", "aria-valuemax");
+}, "aria-valuemax attribute reflects.");
+</script>
+
+<div id="valuemin" aria-valuemin="3"></div>
+<script>
+test(function(t) {
+ var element = document.getElementById("valuemin");
+ assert_equals(element.ariaValueMin, "3");
+ element.ariaValueMin = "2";
+ assert_equals(element.getAttribute("aria-valuemin"), "2");
+ testNullable(element, "ariaValueMin", "aria-valuemin");
+}, "aria-valuemin attribute reflects.");
+</script>
+
+<div id="valuenow" aria-valuenow="50"></div>
+<script>
+test(function(t) {
+ var element = document.getElementById("valuenow");
+ assert_equals(element.ariaValueNow, "50");
+ element.ariaValueNow = "51";
+ assert_equals(element.getAttribute("aria-valuenow"), "51");
+ testNullable(element, "ariaValueNow", "aria-valuenow");
+}, "aria-valuenow attribute reflects.");
+</script>
+
+<div id="valuetext" aria-valuetext="50%"></div>
+<script>
+test(function(t) {
+ var element = document.getElementById("valuetext");
+ assert_equals(element.ariaValueText, "50%");
+ element.ariaValueText = "51%";
+ assert_equals(element.getAttribute("aria-valuetext"), "51%");
+ testNullable(element, "ariaValueText", "aria-valuetext");
+}, "aria-valuetext attribute reflects.");
+</script>
+
+<div id="braillelabel" aria-braillelabel="x"></div>
+<script>
+test(function(t) {
+ var element = document.getElementById("braillelabel");
+ assert_equals(element.ariaBrailleLabel, "x");
+ element.ariaBrailleLabel = "y";
+ assert_equals(element.getAttribute("aria-braillelabel"), "y");
+ testNullable(element, "ariaBrailleLabel", "aria-braillelabel");
+}, "aria-braillelabel attribute reflects.");
+</script>
+
+<div id="brailleroledescription" aria-brailleroledescription="x"></div>
+<script>
+test(function(t) {
+ var element = document.getElementById("brailleroledescription");
+ assert_equals(element.ariaBrailleRoleDescription, "x");
+ element.ariaBrailleRoleDescription = "y";
+ assert_equals(element.getAttribute("aria-brailleroledescription"), "y");
+ testNullable(element, "ariaBrailleRoleDescription", "aria-brailleroledescription");
+}, "aria-brailleroledescription attribute reflects.");
+</script>
+</html>
diff --git a/testing/web-platform/tests/html/dom/aria-element-reflection-disconnected.html b/testing/web-platform/tests/html/dom/aria-element-reflection-disconnected.html
new file mode 100644
index 0000000000..d3acc35e9f
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/aria-element-reflection-disconnected.html
@@ -0,0 +1,82 @@
+<!DOCTYPE HTML>
+<meta charset="utf-8" />
+<link rel=help href="https://html.spec.whatwg.org/#attr-associated-element">
+<link rel="author" href="masonf@chromium.org">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<div id=single_element>
+ <input aria-activedescendant=foo>
+ <p id=foo></p>
+</div>
+
+<div id=array>
+ <input aria-describedby="foo1 foo2">
+ <div id=targets>
+ <p id=foo1></p>
+ <p id=foo2></p>
+ </div>
+</div>
+
+<script>
+ function isIterable(obj) {
+ if (obj === null)
+ return false;
+ return typeof obj[Symbol.iterator] === 'function';
+ }
+ function toSet(elementOrList) {
+ if (!isIterable(elementOrList)) {
+ return new Set([elementOrList]);
+ }
+ return new Set(elementOrList);
+ }
+ function assert_equal_elements(arr1, arr2, msg) {
+ msg = msg || "Arrays not equal";
+ arr1 = toSet(arr1);
+ arr2 = toSet(arr2);
+ assert_true(arr1.size === arr2.size &&
+ [...arr1].every((x) => arr2.has(x)), msg);
+ }
+ function single_test(container, targets, contentAttr, idlAttr, isSingleTarget) {
+ // Start with idref-based reference:
+ const el = container.querySelector('input');
+ assert_true(el.getAttribute(contentAttr) != null && el.getAttribute(contentAttr) != '','Should start with idref attribute');
+ assert_equal_elements(el[idlAttr],targets);
+ container.remove();
+ assert_equal_elements(el[idlAttr],targets,'idrefs should continue to work when target is disconnected');
+ document.body.appendChild(container);
+ assert_equal_elements(el[idlAttr],targets,'functional when reconnected');
+
+ // Now set up an attr-associated element:
+ el[idlAttr] = isSingleTarget ? targets[0] : targets;
+ assert_equal_elements(el[idlAttr],targets);
+ assert_equals(el.getAttribute(contentAttr),'','Content attribute is present but empty');
+ container.remove();
+ assert_equal_elements(el[idlAttr],targets,'attr-associated element still functional');
+ assert_equals(el.getAttribute(contentAttr),'','Attribute still blank');
+ document.body.appendChild(container);
+ assert_equal_elements(el[idlAttr],targets,'still functional when reconnected');
+
+ // Sanity check:
+ el.removeAttribute(contentAttr);
+ assert_equal_elements(el[idlAttr],null);
+ assert_equals(el.getAttribute(contentAttr),null);
+ container.remove();
+ assert_equal_elements(el[idlAttr],null);
+ assert_equals(el.getAttribute(contentAttr),null);
+ document.body.appendChild(container);
+ }
+
+ test(() => {
+ const container = document.getElementById('single_element');
+ const targets = [container.querySelector('#foo')];
+ single_test(container, targets, 'aria-activedescendant', 'ariaActiveDescendantElement', true);
+ },'Element references should stay valid when content is disconnected (single element)');
+
+ test(() => {
+ const container = document.getElementById('array');
+ const targets = Array.from(container.querySelector('#targets').children);
+ single_test(container, targets, 'aria-describedby', 'ariaDescribedByElements', false);
+ },'Element references should stay valid when content is disconnected (element array)');
+</script>
+
diff --git a/testing/web-platform/tests/html/dom/aria-element-reflection.html b/testing/web-platform/tests/html/dom/aria-element-reflection.html
new file mode 100644
index 0000000000..bdf2450708
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/aria-element-reflection.html
@@ -0,0 +1,846 @@
+<!DOCTYPE HTML>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>Element Reflection for aria-activedescendant and aria-errormessage</title>
+ <link rel=help href="https://whatpr.org/html/3917/common-dom-interfaces.html#reflecting-content-attributes-in-idl-attributes:element">
+ <link rel="author" title="Meredith Lane" href="meredithl@chromium.org">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+
+ <div id="activedescendant" aria-activedescendant="x"></div>
+
+ <div id="parentListbox" role="listbox" aria-activedescendant="i1">
+ <div role="option" id="i1">Item 1</div>
+ <div role="option" id="i2">Item 2</div>
+ </div>
+
+ <script>
+ test(function(t) {
+ assert_equals(activedescendant.ariaActiveDescendantElement, null,
+ "invalid ID for relationship returns null");
+
+ // Element reference should be set if the content attribute was included.
+ assert_equals(parentListbox.getAttribute("aria-activedescendant"), "i1", "check content attribute after parsing.");
+ assert_equals(parentListbox.ariaActiveDescendantElement, i1, "check idl attribute after parsing.");
+ assert_equals(parentListbox.ariaActiveDescendantElement, parentListbox.ariaActiveDescendantElement, "check idl attribute caching after parsing.");
+
+ // If we set the content attribute, the element reference should reflect this.
+ parentListbox.setAttribute("aria-activedescendant", "i2");
+ assert_equals(parentListbox.ariaActiveDescendantElement, i2, "setting the content attribute updates the element reference.");
+ assert_equals(parentListbox.ariaActiveDescendantElement, parentListbox.ariaActiveDescendantElement, "check idl attribute caching after update.");
+
+ // Setting the element reference should set the empty string in the content attribute.
+ parentListbox.ariaActiveDescendantElement = i1;
+ assert_equals(parentListbox.ariaActiveDescendantElement, i1, "getter should return the right element reference.");
+ assert_equals(parentListbox.getAttribute("aria-activedescendant"), "", "content attribute should be empty.");
+
+ // Both content and IDL attribute should be nullable.
+ parentListbox.ariaActiveDescendantElement = null;
+ assert_equals(parentListbox.ariaActiveDescendantElement, null);
+ assert_false(parentListbox.hasAttribute("aria-activedescendant"));
+ assert_equals(parentListbox.getAttribute("aria-activedescendant"), null, "nullifying the idl attribute removes the content attribute.");
+
+ // Setting content attribute to non-existent or non compatible element should nullify the IDL attribute.
+ // Reset the element to an existant one.
+ parentListbox.setAttribute("aria-activedescendant", "i1");
+ assert_equals(parentListbox.ariaActiveDescendantElement, i1, "reset attribute.");
+
+ parentListbox.setAttribute("aria-activedescendant", "non-existent-element");
+ assert_equals(parentListbox.getAttribute("aria-activedescendant"), "non-existent-element");
+ assert_equals(parentListbox.ariaActiveDescendantElement, null,"non-DOM content attribute should null the element reference");
+ }, "aria-activedescendant element reflection");
+ </script>
+
+ <div id="parentListbox2" role="listbox" aria-activedescendant="option1">
+ <div role="option" id="option1">Item 1</div>
+ <div role="option" id="option2">Item 2</div>
+ </div>
+
+ <script>
+ test(function(t) {
+ const option1 = document.getElementById("option1");
+ const option2 = document.getElementById("option2");
+ assert_equals(parentListbox2.ariaActiveDescendantElement, option1);
+ option1.removeAttribute("id");
+ option2.setAttribute("id", "option1");
+ const option2Duplicate = document.getElementById("option1");
+ assert_equals(option2, option2Duplicate);
+
+ assert_equals(parentListbox2.ariaActiveDescendantElement, option2);
+ }, "If the content attribute is set directly, the IDL attribute getter always returns the first element whose ID matches the content attribute.");
+ </script>
+
+ <div id="blankIdParent" role="listbox">
+ <div role="option" id="multiple-id"></div>
+ <div role="option" id="multiple-id"></div>
+ </div>
+
+ <script>
+ test(function(t) {
+ // Get second child of parent. This violates the setting of a reflected element
+ // as it will not be the first child of the parent with that ID, which should
+ // result in an empty string for the content attribute.
+ blankIdParent.ariaActiveDescendantElement = blankIdParent.children[1];
+ assert_true(blankIdParent.hasAttribute("aria-activedescendant"));
+ assert_equals(blankIdParent.getAttribute("aria-activedescendant"), "");
+ assert_equals(blankIdParent.ariaActiveDescendantElement, blankIdParent.children[1]);
+ }, "Setting the IDL attribute to an element which is not the first element in DOM order with its ID causes the content attribute to be an empty string");
+ </script>
+
+ <div id="outerContainer">
+ <p id="lightParagraph">Hello world!</p>
+ <span id="shadowHost">
+ </span>
+ </div>
+
+ <script>
+ test(function(t) {
+ const shadow = shadowHost.attachShadow({mode: "open"});
+ const link = document.createElement("a");
+ shadow.appendChild(link);
+
+ assert_equals(lightParagraph.ariaActiveDescendantElement, null);
+
+ // The given element crosses a shadow dom boundary, so it cannot be
+ // set as an element reference.
+ lightParagraph.ariaActiveDescendantElement = link;
+ assert_equals(lightParagraph.ariaActiveDescendantElement, null);
+
+ // The given element crosses a shadow dom boundary (upwards), so
+ // can be used as an element reference, but the content attribute
+ // should reflect the empty string.
+ link.ariaActiveDescendantElement = lightParagraph;
+ assert_equals(link.ariaActiveDescendantElement, lightParagraph);
+ assert_equals(link.getAttribute("aria-activedescendant"), "");
+ }, "Setting an element reference that crosses into a shadow tree is disallowed, but setting one that is in a shadow inclusive ancestor is allowed.");
+ </script>
+
+ <input id="startTime" ></input>
+ <span id="errorMessage">Invalid Time</span>
+
+ <script>
+ test(function(t) {
+ startTime.ariaErrorMessageElements = [errorMessage];
+ assert_equals(startTime.getAttribute("aria-errormessage"), "");
+ assert_array_equals(startTime.ariaErrorMessageElements, [errorMessage]);
+
+ startTime.ariaErrorMessageElements = [];
+ assert_array_equals(startTime.ariaErrorMessageElements, []);
+ assert_equals(startTime.getAttribute("aria-errormessage"), "");
+
+ startTime.setAttribute("aria-errormessage", "errorMessage");
+ assert_array_equals(startTime.ariaErrorMessageElements, [errorMessage]);
+
+ }, "aria-errormessage");
+
+ test(function (t) {
+ assert_false('ariaErrorMessageElement' in startTime);
+ }, 'ariaErrorMessageElement is not defined')
+
+ </script>
+
+ <label>
+ Password:
+ <input id="passwordField" type="password" aria-details="pw">
+ </label>
+
+ <ul>
+ <li id="listItem1">First description.</li>
+ <li id="listItem2">Second description.</li>
+ </ul>
+
+ <script>
+
+ test(function(t) {
+ assert_array_equals(passwordField.ariaDetailsElements, []);
+ passwordField.ariaDetailsElements = [ listItem1 ];
+ assert_equals(passwordField.getAttribute("aria-details"), "");
+ assert_array_equals(passwordField.ariaDetailsElements, [ listItem1 ]);
+
+ passwordField.ariaDetailsElements = [ listItem2 ];
+ assert_equals(passwordField.getAttribute("aria-details"), "");
+ assert_array_equals(passwordField.ariaDetailsElements, [ listItem2 ]);
+ }, "aria-details");
+ </script>
+
+ <div id="deletionParent" role="listbox" aria-activedescendant="contentAttrElement">
+ <div role="option" id="contentAttrElement">Item 1</div>
+ <div role="option" id="idlAttrElement">Item 2</div>
+ </div>
+
+ <script>
+
+ test(function(t) {
+ const contentAttrElement = document.getElementById("contentAttrElement");
+ const idlAttrElement = document.getElementById("idlAttrElement");
+
+ assert_equals(deletionParent.getAttribute("aria-activedescendant"), "contentAttrElement");
+ assert_equals(deletionParent.ariaActiveDescendantElement, contentAttrElement);
+
+ // Deleting an element set via the content attribute.
+ deletionParent.removeChild(contentAttrElement);
+ assert_equals(deletionParent.getAttribute("aria-activedescendant"), "contentAttrElement");
+
+ // As it was not explitly set, the attr-associated-element is computed from the content attribute,
+ // and since descendant1 has been removed from the DOM, it is not valid.
+ assert_equals(deletionParent.ariaActiveDescendantElement, null);
+
+ // Deleting an element set via the IDL attribute.
+ deletionParent.ariaActiveDescendantElement = idlAttrElement;
+ assert_equals(deletionParent.getAttribute("aria-activedescendant"), "");
+
+ deletionParent.removeChild(idlAttrElement);
+ assert_equals(deletionParent.ariaActiveDescendantElement, null);
+
+ // The content attribute is still empty.
+ assert_equals(deletionParent.getAttribute("aria-activedescendant"), "");
+ }, "Deleting a reflected element should return null for the IDL attribute and the content attribute will be empty.");
+ </script>
+
+ <div id="parentNode" role="listbox" aria-activedescendant="changingIdElement">
+ <div role="option" id="changingIdElement">Item 1</div>
+ <div role="option" id="persistantIDElement">Item 2</div>
+ </div>
+
+ <script>
+ test(function(t) {
+ const changingIdElement = document.getElementById("changingIdElement");
+ assert_equals(parentNode.ariaActiveDescendantElement, changingIdElement);
+
+ // Modify the id attribute.
+ changingIdElement.setAttribute("id", "new-id");
+
+ // The content attribute still reflects the old id, and we expect the
+ // Element reference to be null as there is no DOM node with id "original"
+ assert_equals(parentNode.getAttribute("aria-activedescendant"), "changingIdElement");
+ assert_equals(parentNode.ariaActiveDescendantElement, null, "Element set via content attribute with a changed id will return null on getting");
+
+ parentNode.ariaActiveDescendantElement = changingIdElement;
+ assert_equals(parentNode.getAttribute("aria-activedescendant"), "");
+ assert_equals(parentNode.ariaActiveDescendantElement, changingIdElement);
+
+ // The explicitly set element takes precendance over the content attribute.
+ // This means that we still return the same element reference, but the
+ // content attribute is empty.
+ changingIdElement.setAttribute("id", "newer-id");
+ assert_equals(parentNode.ariaActiveDescendantElement, changingIdElement, "explicitly set element is still present even after the id has been changed");
+ assert_equals(parentNode.getAttribute("aria-activedescendant"), "", "content attribute is empty.");
+ }, "Changing the ID of an element doesn't lose the reference.");
+ </script>
+
+ <!-- TODO(chrishall): change naming scheme to inner/outer -->
+ <div id="lightParent" role="listbox">
+ <div id="lightElement" role="option">Hello world!</div>
+ </div>
+ <div id="shadowHostElement"></div>
+
+ <script>
+ test(function(t) {
+ const lightElement = document.getElementById("lightElement");
+ const shadowRoot = shadowHostElement.attachShadow({mode: "open"});
+
+ assert_equals(lightParent.ariaActiveDescendantElement, null, 'null before');
+ assert_equals(lightParent.getAttribute('aria-activedescendant'), null, 'null before');
+
+ lightParent.ariaActiveDescendantElement = lightElement;
+ assert_equals(lightParent.ariaActiveDescendantElement, lightElement);
+ assert_equals(lightParent.getAttribute('aria-activedescendant'), "");
+
+ // Move the referenced element into shadow DOM.
+ // This will cause the computed attr-associated element to be null as the
+ // referenced element will no longer be in a valid scope.
+ // The underlying reference is kept intact, so if the referenced element is
+ // later restored to a valid scope the computed attr-associated element will
+ // then reflect
+ shadowRoot.appendChild(lightElement);
+ assert_equals(lightParent.ariaActiveDescendantElement, null, "computed attr-assoc element should be null as referenced element is in an invalid scope");
+ assert_equals(lightParent.getAttribute("aria-activedescendant"), "");
+
+ // Move the referenced element back into light DOM.
+ // Since the underlying reference was kept intact, after moving the
+ // referenced element back to a valid scope should be reflected in the
+ // computed attr-associated element.
+ lightParent.appendChild(lightElement);
+ assert_equals(lightParent.ariaActiveDescendantElement, lightElement, "computed attr-assoc element should be restored as referenced element is back in a valid scope");
+ assert_equals(lightParent.getAttribute("aria-activedescendant"), "");
+ }, "Reparenting an element into a descendant shadow scope hides the element reference.");
+ </script>
+
+ <div id='fruitbowl' role='listbox'>
+ <div id='apple' role='option'>I am an apple</div>
+ <div id='pear' role='option'>I am a pear</div>
+ <div id='banana' role='option'>I am a banana</div>
+ </div>
+ <div id='shadowFridge'></div>
+
+ <script>
+ test(function(t) {
+ const shadowRoot = shadowFridge.attachShadow({mode: "open"});
+ const banana = document.getElementById("banana");
+
+ fruitbowl.ariaActiveDescendantElement = apple;
+ assert_equals(fruitbowl.ariaActiveDescendantElement, apple);
+ assert_equals(fruitbowl.getAttribute("aria-activedescendant"), "");
+
+ // Move the referenced element into shadow DOM.
+ shadowRoot.appendChild(apple);
+ assert_equals(fruitbowl.ariaActiveDescendantElement, null, "computed attr-assoc element should be null as referenced element is in an invalid scope");
+ // The content attribute is still empty.
+ assert_equals(fruitbowl.getAttribute("aria-activedescendant"), "");
+
+ // let us rename our banana to an apple
+ banana.setAttribute("id", "apple");
+ const lyingBanana = document.getElementById("apple");
+ assert_equals(lyingBanana, banana);
+
+ // our ariaActiveDescendantElement thankfully isn't tricked.
+ // this is thanks to the underlying reference being kept intact, it is
+ // checked and found to be in an invalid scope.
+ assert_equals(fruitbowl.ariaActiveDescendantElement, null);
+ // our content attribute is empty.
+ assert_equals(fruitbowl.getAttribute("aria-activedescendant"), "");
+
+ // when we remove our IDL attribute, the content attribute is also thankfully cleared.
+ fruitbowl.ariaActiveDescendantElement = null;
+ assert_equals(fruitbowl.ariaActiveDescendantElement, null);
+ assert_equals(fruitbowl.getAttribute("aria-activedescendant"), null);
+ }, "Reparenting referenced element cannot cause retargeting of reference.");
+ </script>
+
+ <div id='toaster' role='listbox'></div>
+ <div id='shadowPantry'></div>
+
+ <script>
+ test(function(t) {
+ const shadowRoot = shadowPantry.attachShadow({mode: "open"});
+
+ // Our toast starts in the shadowPantry.
+ const toast = document.createElement("div");
+ toast.setAttribute("id", "toast");
+ shadowRoot.appendChild(toast);
+
+ // Prepare my toast for toasting
+ toaster.ariaActiveDescendantElement = toast;
+ assert_equals(toaster.ariaActiveDescendantElement, null);
+ assert_equals(toaster.getAttribute("aria-activedescendant"), "");
+
+ // Time to make some toast
+ toaster.appendChild(toast);
+ assert_equals(toaster.ariaActiveDescendantElement, toast);
+ // Current spec behaviour:
+ assert_equals(toaster.getAttribute("aria-activedescendant"), "");
+ }, "Element reference set in invalid scope remains intact throughout move to valid scope.");
+ </script>
+
+ <div id="billingElementContainer">
+ <div id="billingElement">Billing</div>
+ </div>
+ <div>
+ <div id="nameElement">Name</div>
+ <input type="text" id="input1" aria-labelledby="billingElement nameElement"/>
+ </div>
+ <div>
+ <div id="addressElement">Address</div>
+ <input type="text" id="input2"/>
+ </div>
+
+ <script>
+ test(function(t) {
+ const billingElement = document.getElementById("billingElement")
+ assert_array_equals(input1.ariaLabelledByElements, [billingElement, nameElement], "parsed content attribute sets element references.");
+ assert_equals(input1.ariaLabelledByElements, input1.ariaLabelledByElements, "check idl attribute caching after parsing");
+ assert_equals(input2.ariaLabelledByElements, null, "Testing missing content attribute after parsing.");
+
+ input2.ariaLabelledByElements = [billingElement, addressElement];
+ assert_array_equals(input2.ariaLabelledByElements, [billingElement, addressElement], "Testing IDL setter/getter.");
+ assert_equals(input1.ariaLabelledByElements, input1.ariaLabelledByElements, "check idl attribute caching after update");
+ assert_equals(input2.getAttribute("aria-labelledby"), "");
+
+ // Remove the billingElement from the DOM.
+ // As it was explicitly set the underlying association will remain intact,
+ // but it will be hidden until the element is moved back into a valid scope.
+ billingElement.remove();
+ assert_array_equals(input2.ariaLabelledByElements, [addressElement], "Computed ariaLabelledByElements shouldn't include billing when out of scope.");
+
+ // Insert the billingElement back into the DOM and check that it is visible
+ // again, as the underlying association should have been kept intact.
+ billingElementContainer.appendChild(billingElement);
+ assert_array_equals(input2.ariaLabelledByElements, [billingElement, addressElement], "Billing element back in scope.");
+
+ input2.ariaLabelledByElements = [];
+ assert_array_equals(input2.ariaLabelledByElements, [], "Testing IDL setter/getter for empty array.");
+ assert_equals(input2.getAttribute("aria-labelledby"), "");
+
+ input1.removeAttribute("aria-labelledby");
+ assert_equals(input1.ariaLabelledByElements, null);
+
+ input1.setAttribute("aria-labelledby", "nameElement addressElement");
+ assert_array_equals(input1.ariaLabelledByElements, [nameElement, addressElement],
+ "computed value after setting attribute directly");
+
+ input1.ariaLabelledByElements = null;
+ assert_false(input1.hasAttribute("aria-labelledby", "Nullifying the IDL attribute should remove the content attribute."));
+ }, "aria-labelledby.");
+ </script>
+
+ <ul role="tablist">
+ <li role="presentation"><a id="link1" role="tab" aria-controls="panel1">Tab 1</a></li>
+ <li role="presentation"><a id="link2" role="tab">Tab 2</a></li>
+ </ul>
+
+ <div role="tabpanel" id="panel1"></div>
+ <div role="tabpanel" id="panel2"></div>
+
+ <script>
+ test(function(t) {
+ assert_array_equals(link1.ariaControlsElements, [panel1]);
+ assert_equals(link2.ariaControlsElements, null);
+
+ link2.setAttribute("aria-controls", "panel1 panel2");
+ assert_array_equals(link2.ariaControlsElements, [panel1, panel2]);
+
+ link1.ariaControlsElements = [];
+ assert_equals(link1.getAttribute("aria-controls"), "");
+
+ link2.ariaControlsElements = [panel1, panel2];
+ assert_equals(link2.getAttribute("aria-controls"), "");
+ assert_array_equals(link2.ariaControlsElements, [panel1, panel2]);
+
+ link2.removeAttribute("aria-controls");
+ assert_equals(link2.ariaControlsElements, null);
+
+ link2.ariaControlsElements = [panel1, panel2];
+ assert_equals(link2.getAttribute("aria-controls"), "");
+ assert_array_equals(link2.ariaControlsElements, [panel1, panel2]);
+
+ link2.ariaControlsElements = null;
+ assert_false(link2.hasAttribute("aria-controls", "Nullifying the IDL attribute should remove the content attribute."));
+ }, "aria-controls.");
+ </script>
+
+ <a id="describedLink" aria-describedby="description1 description2">Fruit</a>
+ <div id="description1">Delicious</div>
+ <div id="description2">Nutritious</div>
+
+ <script>
+ test(function(t) {
+ assert_array_equals(describedLink.ariaDescribedByElements, [description1, description2]);
+
+ describedLink.ariaDescribedByElements = [description1, description2];
+ assert_equals(describedLink.getAttribute("aria-describedby"), "");
+ assert_array_equals(describedLink.ariaDescribedByElements, [description1, description2]);
+
+ describedLink.ariaDescribedByElements = [];
+ assert_equals(describedLink.getAttribute("aria-describedby"), "");
+
+ describedLink.setAttribute("aria-describedby", "description1");
+ assert_array_equals(describedLink.ariaDescribedByElements, [description1]);
+
+ describedLink.removeAttribute("aria-describedby");
+ assert_equals(describedLink.ariaDescribedByElements, null);
+
+ describedLink.ariaDescribedByElements = [description1, description2];
+ assert_equals(describedLink.getAttribute("aria-describedby"), "");
+ assert_array_equals(describedLink.ariaDescribedByElements, [description1, description2]);
+
+ describedLink.ariaDescribedByElements = null;
+ assert_false(describedLink.hasAttribute("aria-describedby", "Nullifying the IDL attribute should remove the content attribute."));
+ }, "aria-describedby.");
+ </script>
+
+ <h2 id="titleHeading" aria-flowto="article1 article2">Title</h2>
+ <div>Next</div>
+ <article id="article2">Content2</article>
+ <article id="article1">Content1</article>
+
+ <script>
+ test(function(t) {
+ const article1 = document.getElementById("article1");
+ const article2 = document.getElementById("article2");
+
+ assert_array_equals(titleHeading.ariaFlowToElements, [article1, article2]);
+
+ titleHeading.ariaFlowToElements = [article1, article2];
+ assert_equals(titleHeading.getAttribute("aria-flowto"), "");
+ assert_array_equals(titleHeading.ariaFlowToElements, [article1, article2]);
+
+ titleHeading.ariaFlowToElements = [];
+ assert_equals(titleHeading.getAttribute("aria-flowto"), "");
+
+ titleHeading.setAttribute("aria-flowto", "article1");
+ assert_array_equals(titleHeading.ariaFlowToElements, [article1]);
+
+ titleHeading.removeAttribute("aria-flowto");
+ assert_equals(titleHeading.ariaFlowToElements, null);
+
+ titleHeading.ariaFlowToElements = [article1, article2];
+ assert_equals(titleHeading.getAttribute("aria-flowto"), "");
+ assert_array_equals(titleHeading.ariaFlowToElements, [article1, article2]);
+
+ titleHeading.ariaFlowToElements = null;
+ assert_false(titleHeading.hasAttribute("aria-flowto", "Nullifying the IDL attribute should remove the content attribute."));
+ }, "aria-flowto.");
+ </script>
+
+ <ul>
+ <li id="listItemOwner" aria-owns="child1 child2">Parent</li>
+ </ul>
+ <ul>
+ <li id="child1">Child 1</li>
+ <li id="child2">Child 2</li>
+ </ul>
+ <script>
+ test(function(t) {
+ assert_array_equals(listItemOwner.ariaOwnsElements, [child1, child2]);
+
+ listItemOwner.removeAttribute("aria-owns");
+ assert_equals(listItemOwner.ariaOwnsElements, null);
+
+ listItemOwner.ariaOwnsElements = [child1, child2];
+ assert_equals(listItemOwner.getAttribute("aria-owns"), "");
+ assert_array_equals(listItemOwner.ariaOwnsElements, [child1, child2]);
+
+ listItemOwner.ariaOwnsElements = [];
+ assert_equals(listItemOwner.getAttribute("aria-owns"), "");
+
+ listItemOwner.setAttribute("aria-owns", "child1");
+ assert_array_equals(listItemOwner.ariaOwnsElements, [child1]);
+
+ listItemOwner.ariaOwnsElements = [child1, child2];
+ assert_equals(listItemOwner.getAttribute("aria-owns"), "");
+ assert_array_equals(listItemOwner.ariaOwnsElements, [child1, child2]);
+
+ listItemOwner.ariaOwnsElements = null;
+ assert_false(listItemOwner.hasAttribute("aria-owns", "Nullifying the IDL attribute should remove the content attribute."));
+ }, "aria-owns.");
+ </script>
+
+ <div id="lightDomContainer">
+ <h2 id="lightDomHeading" aria-flowto="shadowChild1 shadowChild2">Light DOM Heading</h2>
+ <div id="host"></div>
+ <p id="lightDomText1">Light DOM text</p>
+ <p id="lightDomText2">Light DOM text</p>
+ </div>
+
+ <script>
+ test(function(t) {
+ const shadowRoot = host.attachShadow({mode: "open"});
+ const shadowChild1 = document.createElement("article");
+ shadowChild1.setAttribute("id", "shadowChild1");
+ shadowRoot.appendChild(shadowChild1);
+ const shadowChild2 = document.createElement("article");
+ shadowChild2.setAttribute("id", "shadowChild1");
+ shadowRoot.appendChild(shadowChild2);
+
+ // The elements in the content attribute are in a "darker" tree - they
+ // enter a shadow encapsulation boundary, so not be associated any more.
+ assert_array_equals(lightDomHeading.ariaFlowToElements, []);
+
+ // These elements are in a shadow including ancestor, i.e "lighter" tree.
+ // Valid for the IDL attribute, but content attribute should be null.
+ shadowChild1.ariaFlowToElements = [lightDomText1, lightDomText2];
+ assert_equals(shadowChild1.getAttribute("aria-flowto"), "", "empty content attribute for elements that cross shadow boundaries.");
+
+ // These IDs belong to a different scope, so the attr-associated-element
+ // cannot be computed.
+ shadowChild2.setAttribute("aria-flowto", "lightDomText1 lightDomText2");
+ assert_array_equals(shadowChild2.ariaFlowToElements, []);
+
+ // Elements that cross into shadow DOM are dropped, only reflect the valid
+ // elements in IDL and in the content attribute.
+ lightDomHeading.ariaFlowToElements = [shadowChild1, shadowChild2, lightDomText1, lightDomText2];
+ assert_array_equals(lightDomHeading.ariaFlowToElements, [lightDomText1, lightDomText2], "IDL should only include valid elements");
+ assert_equals(lightDomHeading.getAttribute("aria-flowto"), "", "empty content attribute if any given elements cross shadow boundaries");
+
+ // Using a mixture of elements in the same scope and in a shadow including
+ // ancestor should set the IDL attribute, but should reflect the empty
+ // string in the content attribute.
+ shadowChild1.removeAttribute("aria-flowto");
+ shadowChild1.ariaFlowToElements = [shadowChild1, lightDomText1];
+ assert_equals(shadowChild1.getAttribute("aria-flowto"), "", "Setting IDL elements with a mix of scopes should reflect an empty string in the content attribute")
+
+ }, "shadow DOM behaviour for FrozenArray element reflection.");
+ </script>
+
+ <div id="describedButtonContainer">
+ <div id="buttonDescription1">Delicious</div>
+ <div id="buttonDescription2">Nutritious</div>
+ <div id="outerShadowHost"></div>
+ </div>
+
+ <script>
+ test(function(t) {
+ const description1 = document.getElementById("buttonDescription1");
+ const description2 = document.getElementById("buttonDescription2");
+ const outerShadowRoot = outerShadowHost.attachShadow({mode: "open"});
+ const innerShadowHost = document.createElement("div");
+ outerShadowRoot.appendChild(innerShadowHost);
+ const innerShadowRoot = innerShadowHost.attachShadow({mode: "open"});
+
+ // Create an element, add some attr associated light DOM elements and append it to the outer shadow root.
+ const describedElement = document.createElement("button");
+ describedButtonContainer.appendChild(describedElement);
+ describedElement.ariaDescribedByElements = [description1, description2];
+
+ // All elements were in the same scope, so elements are gettable and the content attribute is empty.
+ assert_array_equals(describedElement.ariaDescribedByElements, [description1, description2], "same scope reference");
+ assert_equals(describedElement.getAttribute("aria-describedby"), "");
+
+ outerShadowRoot.appendChild(describedElement);
+
+ // Explicitly set attr-associated-elements should still be gettable because we are referencing elements in a lighter scope.
+ // The content attr is empty.
+ assert_array_equals(describedElement.ariaDescribedByElements, [description1, description2], "lighter scope reference");
+ assert_equals(describedElement.getAttribute("aria-describedby"), "");
+
+ // Move the explicitly set elements into a deeper shadow DOM to test the relationship should not be gettable.
+ innerShadowRoot.appendChild(description1);
+ innerShadowRoot.appendChild(description2);
+
+ // Explicitly set elements are no longer retrievable, because they are no longer in a valid scope.
+ assert_array_equals(describedElement.ariaDescribedByElements, [], "invalid scope reference");
+ assert_equals(describedElement.getAttribute("aria-describedby"), "");
+
+ // Move into the same shadow scope as the explicitly set elements to test that the elements are gettable.
+ innerShadowRoot.appendChild(describedElement);
+ assert_array_equals(describedElement.ariaDescribedByElements, [description1, description2], "restored valid scope reference");
+ assert_equals(describedElement.getAttribute("aria-describedby"), "");
+ }, "Moving explicitly set elements across shadow DOM boundaries.");
+ </script>
+
+ <div id="sameScopeContainer">
+ <div id="labeledby" aria-labeledby="headingLabel1 headingLabel2">Misspelling</div>
+ <div id="headingLabel1">Wonderful</div>
+ <div id="headingLabel2">Fantastic</div>
+
+ <div id="headingShadowHost"></div>
+ </div>
+
+ <script>
+ test(function(t) {
+ const shadowRoot = headingShadowHost.attachShadow({mode: "open"});
+ const headingElement = document.createElement("h1");
+ const headingLabel1 = document.getElementById("headingLabel1")
+ const headingLabel2 = document.getElementById("headingLabel2")
+ shadowRoot.appendChild(headingElement);
+
+ assert_array_equals(labeledby.ariaLabelledByElements, [headingLabel1, headingLabel2], "aria-labeled by is supported by IDL getter.");
+
+ // Explicitly set elements are in a lighter shadow DOM, so that's ok.
+ headingElement.ariaLabelledByElements = [headingLabel1, headingLabel2];
+ assert_array_equals(headingElement.ariaLabelledByElements, [headingLabel1, headingLabel2], "Lighter elements are gettable when explicitly set.");
+ assert_equals(headingElement.getAttribute("aria-labelledby"), "");
+
+ // Move into Light DOM, explicitly set elements should still be gettable.
+ // Note that the content attribute is still empty.
+ sameScopeContainer.appendChild(headingElement);
+ assert_array_equals(headingElement.ariaLabelledByElements, [headingLabel1, headingLabel2], "Elements are all in same scope, so gettable.");
+ assert_equals(headingElement.getAttribute("aria-labelledby"), "", "Content attribute is empty.");
+
+ // Reset the association, the content attribute is sitll empty.
+ headingElement.ariaLabelledByElements = [headingLabel1, headingLabel2];
+ assert_equals(headingElement.getAttribute("aria-labelledby"), "");
+
+ // Remove the referring element from the DOM, elements are no longer longer exposed,
+ // underlying internal reference is still kept intact.
+ headingElement.remove();
+ assert_array_equals(headingElement.ariaLabelledByElements, [], "Element is no longer in the document, so references should no longer be exposed.");
+ assert_equals(headingElement.getAttribute("aria-labelledby"), "");
+
+ // Insert it back in.
+ sameScopeContainer.appendChild(headingElement);
+ assert_array_equals(headingElement.ariaLabelledByElements, [headingLabel1, headingLabel2], "Element is restored to valid scope, so should be gettable.");
+ assert_equals(headingElement.getAttribute("aria-labelledby"), "");
+
+ // Remove everything from the DOM, nothing is exposed again.
+ headingLabel1.remove();
+ headingLabel2.remove();
+ assert_array_equals(headingElement.ariaLabelledByElements, []);
+ assert_equals(headingElement.getAttribute("aria-labelledby"), "");
+ assert_equals(document.getElementById("headingLabel1"), null);
+ assert_equals(document.getElementById("headingLabel2"), null);
+
+ // Reset the association.
+ headingElement.ariaLabelledByElements = [headingLabel1, headingLabel2];
+ assert_array_equals(headingElement.ariaLabelledByElements, []);
+ assert_equals(headingElement.getAttribute("aria-labelledby"), "");
+ }, "Moving explicitly set elements around within the same scope, and removing from the DOM.");
+ </script>
+
+ <input id="input">
+ <optgroup>
+ <option id="first">First option</option>
+ <option id="second">Second option</option>
+ </optgroup>
+
+ <script>
+ test(function(t) {
+ input.ariaActiveDescendantElement = first;
+ first.parentElement.appendChild(first);
+
+ assert_equals(input.ariaActiveDescendantElement, first);
+ }, "Reparenting.");
+ </script>
+
+ <div id='fromDiv'></div>
+
+ <script>
+ test(function(t) {
+ const toSpan = document.createElement('span');
+ toSpan.setAttribute("id", "toSpan");
+ fromDiv.ariaActiveDescendantElement = toSpan;
+
+ assert_equals(fromDiv.ariaActiveDescendantElement, null, "Referenced element not inserted into document, so is in an invalid scope.");
+ assert_equals(fromDiv.getAttribute("aria-activedescendant"), "", "Invalid scope, so content attribute not set.");
+
+ fromDiv.appendChild(toSpan);
+ assert_equals(fromDiv.ariaActiveDescendantElement, toSpan, "Referenced element now inserted into the document.");
+ assert_equals(fromDiv.getAttribute("aria-activedescendant"), "", "Content attribute remains empty, as it is only updated at set time.");
+
+ }, "Attaching element reference before it's inserted into the DOM.");
+ </script>
+
+ <div id='originalDocumentDiv'></div>
+
+ <script>
+ test(function(t) {
+ const newDoc = document.implementation.createHTMLDocument('new document');
+ const newDocSpan = newDoc.createElement('span');
+ newDoc.body.appendChild(newDocSpan);
+
+ // Create a reference across documents.
+ originalDocumentDiv.ariaActiveDescendantElement = newDocSpan;
+
+ assert_equals(originalDocumentDiv.ariaActiveDescendantElement, null, "Cross-document is an invalid scope, so reference will not be visible.");
+ assert_equals(fromDiv.getAttribute("aria-activedescendant"), "", "Invalid scope when set, so content attribute not set.");
+
+ // "Move" span to first document.
+ originalDocumentDiv.appendChild(newDocSpan);
+
+ // Implementation defined: moving object into same document from other document may cause reference to become visible.
+ assert_equals(originalDocumentDiv.ariaActiveDescendantElement, newDocSpan, "Implementation defined: moving object back *may* make reference visible.");
+ assert_equals(fromDiv.getAttribute("aria-activedescendant"), "", "Invalid scope when set, so content attribute not set.");
+ }, "Cross-document references and moves.");
+ </script>
+
+
+ <script>
+ test(function(t) {
+ const otherDoc = document.implementation.createHTMLDocument('otherDoc');
+ const otherDocDiv = otherDoc.createElement('div');
+ const otherDocSpan = otherDoc.createElement('span');
+ otherDocDiv.appendChild(otherDocSpan);
+ otherDoc.body.appendChild(otherDocDiv);
+
+ otherDocDiv.ariaActiveDescendantElement = otherDocSpan;
+ assert_equals(otherDocDiv.ariaActiveDescendantElement, otherDocSpan, "Setting reference on a different document.");
+
+ // Adopt element from other oducment.
+ document.body.appendChild(document.adoptNode(otherDocDiv));
+ assert_equals(otherDocDiv.ariaActiveDescendantElement, otherDocSpan, "Reference should be kept on the new document too.");
+ }, "Adopting element keeps references.");
+ </script>
+
+ <div id="cachingInvariantMain"></div>
+ <div id="cachingInvariantElement1"></div>
+ <div id="cachingInvariantElement2"></div>
+ <div id="cachingInvariantElement3"></div>
+ <div id="cachingInvariantElement4"></div>
+ <div id="cachingInvariantElement5"></div>
+
+ <script>
+ test(function(t) {
+ cachingInvariantMain.ariaControlsElements = [cachingInvariantElement1, cachingInvariantElement2];
+ cachingInvariantMain.ariaDescribedByElements = [cachingInvariantElement3, cachingInvariantElement4];
+ cachingInvariantMain.ariaDetailsElements = [cachingInvariantElement5];
+ cachingInvariantMain.ariaFlowToElements = [cachingInvariantElement1, cachingInvariantElement3];
+ cachingInvariantMain.ariaLabelledByElements = [cachingInvariantElement2, cachingInvariantElement4];
+ cachingInvariantMain.ariaOwnsElements = [cachingInvariantElement1, cachingInvariantElement2, cachingInvariantElement3];
+
+ let ariaControlsElementsArray = cachingInvariantMain.ariaControlsElements;
+ let ariaDescribedByElementsArray = cachingInvariantMain.ariaDescribedByElements;
+ let ariaDetailsElementsArray = cachingInvariantMain.ariaDetailsElements;
+ let ariaFlowToElementsArray = cachingInvariantMain.ariaFlowToElements;
+ let ariaLabelledByElementsArray = cachingInvariantMain.ariaLabelledByElements;
+ let ariaOwnsElementsArray = cachingInvariantMain.ariaOwnsElements;
+
+ assert_equals(ariaControlsElementsArray, cachingInvariantMain.ariaControlsElements, "Caching invariant for ariaControlsElements");
+ assert_equals(ariaDescribedByElementsArray, cachingInvariantMain.ariaDescribedByElements, "Caching invariant for ariaDescribedByElements");
+ assert_equals(ariaDetailsElementsArray, cachingInvariantMain.ariaDetailsElements, "Caching invariant for ariaDetailsElements");
+ assert_equals(ariaFlowToElementsArray, cachingInvariantMain.ariaFlowToElements, "Caching invariant for ariaFlowToElements");
+ assert_equals(ariaLabelledByElementsArray, cachingInvariantMain.ariaLabelledByElements, "Caching invariant for ariaLabelledByElements");
+ assert_equals(ariaOwnsElementsArray, cachingInvariantMain.ariaOwnsElements, "Caching invariant for ariaOwnsElements");
+
+ // Ensure that stale values don't continue to be cached
+ cachingInvariantMain.ariaControlsElements = [cachingInvariantElement4, cachingInvariantElement5];
+ cachingInvariantMain.ariaDescribedByElements = [cachingInvariantElement1, cachingInvariantElement2];
+ cachingInvariantMain.ariaDetailsElements = [cachingInvariantElement3];
+ cachingInvariantMain.ariaFlowToElements = [cachingInvariantElement4, cachingInvariantElement5];
+ cachingInvariantMain.ariaLabelledByElements = [cachingInvariantElement1, cachingInvariantElement2];
+ cachingInvariantMain.ariaOwnsElements = [cachingInvariantElement3, cachingInvariantElement4, cachingInvariantElement1];
+
+ ariaControlsElementsArray = cachingInvariantMain.ariaControlsElements;
+ ariaDescribedByElementsArray = cachingInvariantMain.ariaDescribedByElements;
+ ariaDetailsElementsArray = cachingInvariantMain.ariaDetailsElements;
+ ariaFlowToElementsArray = cachingInvariantMain.ariaFlowToElements;
+ ariaLabelledByElementsArray = cachingInvariantMain.ariaLabelledByElements;
+ ariaOwnsElementsArray = cachingInvariantMain.ariaOwnsElements;
+
+ assert_equals(ariaControlsElementsArray, cachingInvariantMain.ariaControlsElements, "Caching invariant for ariaControlsElements");
+ assert_equals(ariaDescribedByElementsArray, cachingInvariantMain.ariaDescribedByElements, "Caching invariant for ariaDescribedByElements");
+ assert_equals(ariaDetailsElementsArray, cachingInvariantMain.ariaDetailsElements, "Caching invariant for ariaDetailsElements");
+ assert_equals(ariaFlowToElementsArray, cachingInvariantMain.ariaFlowToElements, "Caching invariant for ariaFlowToElements");
+ assert_equals(ariaLabelledByElementsArray, cachingInvariantMain.ariaLabelledByElements, "Caching invariant for ariaLabelledByElements");
+ assert_equals(ariaOwnsElementsArray, cachingInvariantMain.ariaOwnsElements, "Caching invariant for ariaOwnsElements");
+
+ }, "Caching invariant different attributes.");
+ </script>
+
+ <div id="cachingInvariantMain1"></div>
+ <div id="cachingInvariantMain2"></div>
+
+ <script>
+ test(function(t) {
+ cachingInvariantMain1.ariaDescribedByElements = [cachingInvariantElement1, cachingInvariantElement2];
+ cachingInvariantMain2.ariaDescribedByElements = [cachingInvariantElement3, cachingInvariantElement4];
+
+ let ariaDescribedByElementsArray1 = cachingInvariantMain1.ariaDescribedByElements;
+ let ariaDescribedByElementsArray2 = cachingInvariantMain2.ariaDescribedByElements;
+
+ assert_equals(ariaDescribedByElementsArray1, cachingInvariantMain1.ariaDescribedByElements, "Caching invariant for ariaDescribedByElements in one elemnt");
+ assert_equals(ariaDescribedByElementsArray2, cachingInvariantMain2.ariaDescribedByElements, "Caching invariant for ariaDescribedByElements in onother elemnt");
+ }, "Caching invariant different elements.");
+ </script>
+
+ <div id="badInputValues"></div>
+ <div id="badInputValues2"></div>
+
+ <script>
+ test(function(t) {
+ assert_throws_js(TypeError, () => { badInputValues.ariaActiveDescendantElement = "a string"; });
+ assert_throws_js(TypeError, () => { badInputValues.ariaActiveDescendantElement = 1; });
+ assert_throws_js(TypeError, () => { badInputValues.ariaActiveDescendantElement = [ badInputValues2 ]; });
+
+ assert_throws_js(TypeError, () => { badInputValues.ariaControlsElements = "a string" });
+ assert_throws_js(TypeError, () => { badInputValues.ariaControlsElements = 1 });
+ assert_throws_js(TypeError, () => { badInputValues.ariaControlsElements = [1, 2, 3] });
+ assert_throws_js(TypeError, () => { badInputValues.ariaControlsElements = badInputValues2 });
+ }, "Passing values of the wrong type should throw a TypeError");
+ </script>
+
+ <!-- TODO(chrishall): add additional GC test covering:
+ if an element is in an invalid scope but attached to the document, it's
+ not GC'd;
+ -->
+
+ <!-- TODO(chrishall): add additional GC test covering:
+ if an element is not attached to the document, but is in a tree fragment
+ which is not GC'd because there is a script reference to another element
+ in the tree fragment, and the relationship is valid because it is between
+ two elements in that tree fragment, the relationship is exposed *and* the
+ element is not GC'd
+ -->
+
+</html>
diff --git a/testing/web-platform/tests/html/dom/directionality/bdi-element-invalid-dir-ref.html b/testing/web-platform/tests/html/dom/directionality/bdi-element-invalid-dir-ref.html
new file mode 100644
index 0000000000..88ccd4b9b5
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/directionality/bdi-element-invalid-dir-ref.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta name="author" title="Ryosuke Niwa" href="mailto:rniwa@webkit.org">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/dom.html#the-directionality">
+<style>
+div { width: 100px; height: 100px; background: green; }
+</style>
+</head>
+<body>
+<div></div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/directionality/bdi-element-invalid-dir.html b/testing/web-platform/tests/html/dom/directionality/bdi-element-invalid-dir.html
new file mode 100644
index 0000000000..629cee8738
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/directionality/bdi-element-invalid-dir.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta name="author" title="Ryosuke Niwa" href="mailto:rniwa@webkit.org">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/dom.html#the-directionality">
+<link rel="match" href="bdi-element-invalid-dir-ref.html">
+<style>
+div { position: relative; width: 100px; height: 100px; background: red; }
+bdi { width: 100px; height: 100px; display: block; }
+span { display: inline-block; width: 50px; height: 100px; background: green; color: green; }
+#left { background: green; position: absolute; left: 0px; top: 0px; }
+</style>
+</head>
+<body>
+<div><bdi dir="foo"><span id="left"></span><span>&#x05EA;</span></bdi></div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/Document.body.html b/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/Document.body.html
new file mode 100644
index 0000000000..77de1d93b5
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/Document.body.html
@@ -0,0 +1,227 @@
+<!DOCTYPE html>
+<title>Document.body</title>
+<link rel="author" title="Ms2ger" href="mailto:ms2ger@gmail.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-document-body">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<script>
+function createDocument() {
+ var doc = document.implementation.createHTMLDocument("");
+ doc.removeChild(doc.documentElement);
+ return doc;
+}
+test(function() {
+ var doc = createDocument();
+ assert_equals(doc.body, null);
+}, "Childless document");
+test(function() {
+ var doc = createDocument();
+ doc.appendChild(doc.createElement("html"));
+ assert_equals(doc.body, null);
+}, "Childless html element");
+test(function() {
+ var doc = createDocument();
+ var html = doc.appendChild(doc.createElement("html"));
+ var b =
+ html.appendChild(doc.createElement("body"));
+ html.appendChild(doc.createElement("frameset"));
+ assert_equals(doc.body, b);
+}, "Body followed by frameset inside the html element");
+test(function() {
+ var doc = createDocument();
+ var html = doc.appendChild(doc.createElement("html"));
+ var f =
+ html.appendChild(doc.createElement("frameset"));
+ html.appendChild(doc.createElement("body"));
+ assert_equals(doc.body, f);
+}, "Frameset followed by body inside the html element");
+test(function() {
+ var doc = createDocument();
+ var html =
+ doc.appendChild(doc.createElementNS("http://example.org/test", "html"));
+ html.appendChild(doc.createElement("body"));
+ html.appendChild(doc.createElement("frameset"));
+ assert_equals(doc.body, null);
+}, "Body followed by frameset inside a non-HTML html element");
+test(function() {
+ var doc = createDocument();
+ var html =
+ doc.appendChild(doc.createElementNS("http://example.org/test", "html"));
+ html.appendChild(doc.createElement("frameset"));
+ html.appendChild(doc.createElement("body"));
+ assert_equals(doc.body, null);
+}, "Frameset followed by body inside a non-HTML html element");
+test(function() {
+ var doc = createDocument();
+ var html = doc.appendChild(doc.createElement("html"));
+ html.appendChild(
+ doc.createElementNS("http://example.org/test", "body"));
+ var b = html.appendChild(doc.createElement("body"));
+ assert_equals(doc.body, b);
+}, "Non-HTML body followed by body inside the html element");
+test(function() {
+ var doc = createDocument();
+ var html = doc.appendChild(doc.createElement("html"));
+ html.appendChild(
+ doc.createElementNS("http://example.org/test", "frameset"));
+ var b = html.appendChild(doc.createElement("body"));
+ assert_equals(doc.body, b);
+}, "Non-HTML frameset followed by body inside the html element");
+test(function() {
+ var doc = createDocument();
+ var html = doc.appendChild(doc.createElement("html"));
+ var x = html.appendChild(doc.createElement("x"));
+ x.appendChild(doc.createElement("body"));
+ var body = html.appendChild(doc.createElement("body"));
+ assert_equals(doc.body, body);
+}, "Body inside an x element followed by a body");
+test(function() {
+ var doc = createDocument();
+ var html = doc.appendChild(doc.createElement("html"));
+ var x = html.appendChild(doc.createElement("x"));
+ x.appendChild(doc.createElement("frameset"));
+ var frameset = html.appendChild(doc.createElement("frameset"));
+ assert_equals(doc.body, frameset);
+}, "Frameset inside an x element followed by a frameset");
+
+// Root node is not a html element.
+test(function() {
+ var doc = createDocument();
+ doc.appendChild(doc.createElement("body"));
+ assert_equals(doc.body, null);
+}, "Body as the root node");
+test(function() {
+ var doc = createDocument();
+ doc.appendChild(doc.createElement("frameset"));
+ assert_equals(doc.body, null);
+}, "Frameset as the root node");
+test(function() {
+ var doc = createDocument();
+ var body = doc.appendChild(doc.createElement("body"));
+ body.appendChild(doc.createElement("frameset"));
+ assert_equals(doc.body, null);
+}, "Body as the root node with a frameset child");
+test(function() {
+ var doc = createDocument();
+ var frameset = doc.appendChild(doc.createElement("frameset"));
+ frameset.appendChild(doc.createElement("body"));
+ assert_equals(doc.body, null);
+}, "Frameset as the root node with a body child");
+test(function() {
+ var doc = createDocument();
+ doc.appendChild(doc.createElementNS("http://example.org/test", "body"));
+ assert_equals(doc.body, null);
+}, "Non-HTML body as the root node");
+test(function() {
+ var doc = createDocument();
+ doc.appendChild(doc.createElementNS("http://example.org/test", "frameset"));
+ assert_equals(doc.body, null);
+}, "Non-HTML frameset as the root node");
+
+test(function() {
+ assert_not_equals(document.body, null);
+ assert_true(document.body instanceof HTMLBodyElement, "should be HTMLBodyElement");
+ assert_equals(document.body.tagName, "BODY");
+}, "existing document's body");
+
+
+var originalBody = document.body;
+test(function() {
+ assert_throws_js(TypeError, function() {
+ document.body = "text"
+ })
+ assert_equals(document.body, originalBody);
+}, "Setting document.body to a string.")
+test(function() {
+ assert_throws_dom("HierarchyRequestError", function() {
+ document.body = document.createElement("div")
+ })
+ assert_equals(document.body, originalBody);
+}, "Setting document.body to a div element.")
+test(function() {
+ var doc = createDocument();
+ assert_throws_dom("HierarchyRequestError", function() {
+ doc.body = doc.createElement("body")
+ })
+ assert_equals(doc.body, null);
+}, "Setting document.body when there's no root element.")
+test(function() {
+ var doc = document.implementation.createHTMLDocument();
+
+ var new_body = doc.createElement("body");
+ assert_true(new_body instanceof HTMLBodyElement, "should be HTMLBodyElement");
+ assert_equals(new_body.tagName, "BODY");
+
+ doc.body = new_body;
+ assert_equals(doc.body, new_body);
+}, "Setting document.body to a new body element.");
+test(function() {
+ var doc = document.implementation.createHTMLDocument();
+
+ var new_frameset = doc.createElement("frameset");
+ assert_true(new_frameset instanceof HTMLFrameSetElement, "should be HTMLFrameSetElement");
+ assert_equals(new_frameset.tagName, "FRAMESET");
+
+ doc.body = new_frameset;
+ assert_equals(doc.body, new_frameset, "test6-3, append frameset to a new document");
+}, "Setting document.body to a new frameset element.");
+
+test(function() {
+ var doc = createDocument();
+ var html = doc.appendChild(doc.createElement("html"));
+ var f =
+ html.appendChild(doc.createElement("frameset"));
+ assert_equals(doc.body, f);
+
+ var b = doc.createElement("body");
+ doc.body = b;
+
+ assert_equals(f.parentNode, null,
+ "Frameset should have been removed from the tree");
+ assert_equals(doc.body, b, "Body should be the new doc.body");
+}, "Setting document.body to a body will replace an existing frameset if there is one.");
+
+test(function() {
+ var doc = createDocument();
+ var html = doc.appendChild(doc.createElement("html"));
+ var b =
+ html.appendChild(doc.createElement("body"));
+ assert_equals(doc.body, b);
+
+ var f = doc.createElement("frameset");
+ doc.body = f;
+
+ assert_equals(b.parentNode, null,
+ "Body should have been removed from the tree");
+ assert_equals(doc.body, f, "Frameset should be the new doc.body");
+}, "Setting document.body to a frameset will replace an existing body if there is one.");
+
+test(function() {
+ var doc = createDocument();
+ var html = doc.appendChild(doc.createElement("html"));
+ var b =
+ html.appendChild(doc.createElement("body"));
+ var f1 = html.appendChild(doc.createElement("frameset"));
+ assert_equals(doc.body, b);
+
+ var f2 = doc.createElement("frameset");
+ doc.body = f2;
+
+ assert_equals(b.parentNode, null,
+ "Body should have been removed from the tree");
+ assert_equals(f1.parentNode, html,
+ "Frameset following body should still be in the tree.");
+ assert_equals(doc.body, f2, "New frameset should be the new doc.body");
+ assert_equals(f2.nextSibling, f1, "New frameset should have replaced the body");
+}, "Setting document.body to a frameset will replace the first existing body/frameset.");
+
+test(function() {
+ var doc = createDocument();
+ doc.appendChild(doc.createElement("test"));
+ var new_body = doc.createElement("body");
+ doc.body = new_body;
+ assert_equals(doc.documentElement.firstChild, new_body, "new_body should be inserted");
+ assert_equals(doc.body, null, "Getter should return null when the root is not html");
+}, "Setting document.body to a new body element when the root element is a test element.");
+</script>
diff --git a/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/Document.currentScript.html b/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/Document.currentScript.html
new file mode 100644
index 0000000000..245bae98ee
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/Document.currentScript.html
@@ -0,0 +1,219 @@
+<!DOCTYPE HTML>
+<meta charset=utf-8>
+<title>Document.currentScript</title>
+<link rel=help href="https://html.spec.whatwg.org/multipage/#dom-document-currentscript">
+<link rel=help href="https://html.spec.whatwg.org/multipage/#execute-the-script-block">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/get-host-info.sub.js"></script>
+<div id="log"></div>
+<script>
+var data = {
+ "parse-inline" : [],
+ "parse-ext" : [],
+ "dom-inline" : [],
+ "dom-ext" : [],
+ "nested" : ["nested-outer","nested-inner","nested-outer"],
+ "script-load-error" : [null],
+ "script-window-error" : ["script-error-compile","script-error-runtime"],
+ "timeout" : [null],
+ "eval" : [],
+ "xhr-test" : [],
+ "script-svg" : [],
+ "script-async" : [],
+ "script-defer" : [],
+ "script-async-false" : [],
+ "iframe-src" : [],
+ "cross-origin" : [null],
+ "document-write" : [],
+ "microtask": [],
+};
+
+var expected = {};
+var actual = {};
+
+Object.keys(data).forEach(function(id) {
+ var test_expected = data[id];
+ if(test_expected.length == 0) {
+ test_expected = [id];
+ }
+ expected[id] = test_expected;
+ actual[id] = [];
+});
+
+var tests = {};
+setup({allow_uncaught_exception : true});
+
+Object.keys(expected).forEach(function(id) {
+ var testmsg = "Script " + id;
+ tests[id] = async_test(testmsg);
+});
+
+function verify(id) {
+ tests[id].step(function() {
+ actual[id].push(document.currentScript);
+ })
+}
+
+function finish(id) {
+ tests[id].step(function() {
+ assert_array_equals(actual[id],expected[id].map(function(id) {
+ return document.getElementById(id);
+ }));
+ this.done();
+ })
+}
+
+</script>
+
+<!-- Test parser inserted scripts -->
+<script id="parse-inline">
+verify('parse-inline');
+finish('parse-inline')
+</script>
+<script id="parse-ext" src="data:text/plain,verify('parse-ext')"></script>
+<script>finish('parse-ext');</script>
+
+<!-- Test DOM inserted scripts -->
+<script>
+var s = document.createElement("script");
+s.textContent = "verify('dom-inline');";
+s.id = "dom-inline";
+document.body.appendChild(s);
+finish('dom-inline');
+
+s = document.createElement("script");
+s.src = "data:text/plain,verify('dom-ext');";
+s.id = "dom-ext";
+s.onload = function() {
+ finish('dom-ext');
+}
+document.body.appendChild(s);
+</script>
+
+<!-- Test Nested scripts -->
+<script id="nested-outer">
+ verify("nested");
+ var s = document.createElement("script");
+ s.textContent = "verify('nested')";
+ s.id = "nested-inner";
+ document.body.appendChild(s);
+ verify("nested");
+ finish('nested');
+</script>
+
+<!-- Test script load error event listener -->
+<script>
+function testLoadFail() {
+ verify('script-load-error');
+ finish('script-load-error');
+}
+</script>
+
+<script src="http://some.nonexistant.test/fail" id="script-load-error" onerror="testLoadFail()">
+</script>
+
+<!-- Test for runtime and compile time errors -->
+<script>
+ window.onerror = function() {
+ verify('script-window-error');
+ }
+
+ var s = document.createElement("script");
+ s.id = "script-error-compile";
+ s.textContent = "{";
+ document.body.appendChild(s);
+
+ window.onerror = function() {
+ verify('script-window-error');
+ }
+
+ s = document.createElement("script");
+ s.id = "script-error-runtime";
+ s.textContent = "undefinedfn();";
+ document.body.appendChild(s);
+
+ finish('script-window-error');
+</script>
+
+<!-- Verify in setTimeout -->
+<script>
+ setTimeout(function() {
+ verify('timeout');
+ finish('timeout');
+ },0);
+</script>
+
+<!-- Verify in eval -->
+<script id="eval">
+ eval('verify("eval")');
+ finish("eval");
+</script>
+
+<!-- Verify in synchronous xhr -->
+<script id="xhr-test">
+ var request = new XMLHttpRequest();
+ request.open('GET','/',false);
+ request.send(null);
+
+ if(request.status === 200) {
+ verify('xhr-test');
+ finish('xhr-test');
+ }
+</script>
+
+<!-- Testing script within svg -->
+<svg>
+ <script id="script-svg">
+ verify('script-svg');
+ finish('script-svg');
+ </script>
+</svg>
+
+<!-- Test script async and defer -->
+<script id='script-async' async src='data:text/plain,verify("script-async"),finish("script-async")'></script>
+
+<script id='script-defer' defer src='data:text/plain,verify("script-defer"),finish("script-defer")'></script>
+
+<!-- Test async = false dynamic script loading -->
+<script>
+ var s = document.createElement("script");
+ s.id = "script-async-false";
+ s.src = "data:text/plain,verify('script-async-false');"
+ s.onload = function() {
+ finish('script-async-false');
+ }
+ s.async = false;
+ document.body.appendChild(s);
+</script>
+
+<!-- Verify in iframe javascript uri scheme -->
+<iframe src="javascript:parent.verify('iframe-src'),parent.finish('iframe-src')"
+ style="visibility:hidden;display:none">
+</iframe>
+
+<!-- Testing cross origin script -->
+<script>
+var s = document.createElement("script");
+s.id = "cross-origin";
+s.src = get_host_info(). HTTP_REMOTE_ORIGIN + "/html/dom/documents/dom-tree-accessors/cross-domain.js"
+s.onload = function() {
+ verify('cross-origin')
+ finish('cross-origin');
+}
+document.body.appendChild(s);
+
+</script>
+
+<!-- Testing document.write -->
+<script>
+document.write('<script id="document-write">verify("document-write"); finish("document-write");</' + 'script>');
+</script>
+
+<!-- Testing microtask -->
+<script id="microtask">
+ Promise.resolve().then(() => {
+ verify("microtask");
+ finish("microtask");
+ });
+</script>
diff --git a/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/Document.getElementsByClassName-null-undef.html b/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/Document.getElementsByClassName-null-undef.html
new file mode 100644
index 0000000000..dc132e5ec7
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/Document.getElementsByClassName-null-undef.html
@@ -0,0 +1,30 @@
+<!doctype html>
+<title>getElementsByClassName and null/undefined</title>
+<link rel="author" title="Ms2ger" href="mailto:ms2ger@gmail.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-getelementsbyclassname">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<div id="test">
+<p id="p1"></p>
+<p class="undefined" id="p2"></p>
+<p class="null" id="p3"></p>
+<p class="undefined null" id="p4"></p>
+</div>
+<script>
+test(function() {
+ var wrapper = document.getElementById("test");
+ assert_equals(document.getElementsByClassName(undefined).length, 2);
+ assert_equals(document.getElementsByClassName(undefined)[0],
+ document.getElementById("p2"));
+ assert_equals(document.getElementsByClassName(undefined)[1],
+ document.getElementById("p4"));
+/*
+ assert_equals(document.getElementsByClassName(null).length, 2);
+ assert_equals(document.getElementsByClassName(null)[0],
+ document.getElementById("p3"));
+ assert_equals(document.getElementsByClassName(null)[1],
+ document.getElementById("p4"));
+*/
+});
+</script>
diff --git a/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/Element.getElementsByClassName-null-undef.html b/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/Element.getElementsByClassName-null-undef.html
new file mode 100644
index 0000000000..b4d9241647
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/Element.getElementsByClassName-null-undef.html
@@ -0,0 +1,30 @@
+<!doctype html>
+<title>getElementsByClassName and null/undefined</title>
+<link rel="author" title="Ms2ger" href="mailto:ms2ger@gmail.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-getelementsbyclassname">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<div id="test">
+<p id="p1"></p>
+<p class="undefined" id="p2"></p>
+<p class="null" id="p3"></p>
+<p class="undefined null" id="p4"></p>
+</div>
+<script>
+test(function() {
+ var wrapper = document.getElementById("test");
+ assert_equals(wrapper.getElementsByClassName(undefined).length, 2);
+ assert_equals(wrapper.getElementsByClassName(undefined)[0],
+ document.getElementById("p2"));
+ assert_equals(wrapper.getElementsByClassName(undefined)[1],
+ document.getElementById("p4"));
+/*
+ assert_equals(wrapper.getElementsByClassName(null).length, 2);
+ assert_equals(wrapper.getElementsByClassName(null)[0],
+ document.getElementById("p3"));
+ assert_equals(wrapper.getElementsByClassName(null)[1],
+ document.getElementById("p4"));
+*/
+});
+</script>
diff --git a/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/cross-domain.js b/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/cross-domain.js
new file mode 100644
index 0000000000..32effe3c45
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/cross-domain.js
@@ -0,0 +1 @@
+//test script to check cross-domain script execution as in Document.currentScript.sub.html \ No newline at end of file
diff --git a/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.embeds-document.plugins-01.html b/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.embeds-document.plugins-01.html
new file mode 100644
index 0000000000..e710798915
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.embeds-document.plugins-01.html
@@ -0,0 +1,87 @@
+<!DOCTYPE html>
+<title>document.embeds and document.plugins</title>
+<link rel="author" title="Ms2ger" href="mailto:ms2ger@gmail.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-document-embeds">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-document-plugins">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<script>
+test(function() {
+ assert_equals(document.embeds, document.embeds,
+ "embeds should be constant");
+ assert_equals(document.plugins, document.plugins,
+ "plugins should be constant");
+ assert_equals(document.embeds, document.plugins,
+ "embeds should be the same as plugins");
+ assert_equals(document.embeds.length, 0);
+ assert_equals(document.plugins.length, 0);
+}, "No plugins");
+
+test(function() {
+ var embed = document.body.appendChild(document.createElement("embed"));
+ this.add_cleanup(function() { document.body.removeChild(embed) });
+
+ assert_array_equals(document.embeds, [embed]);
+ assert_array_equals(document.plugins, [embed]);
+
+ assert_equals(document.embeds, document.embeds,
+ "embeds should be constant");
+ assert_equals(document.plugins, document.plugins,
+ "plugins should be constant");
+ assert_equals(document.embeds, document.plugins,
+ "embeds should be the same as plugins");
+}, "One plugin");
+
+test(function() {
+ var embed1 = document.createElement("embed"),
+ embed2 = document.createElement("embed");
+
+ document.body.appendChild(embed2);
+ this.add_cleanup(function() { document.body.removeChild(embed2) });
+ document.body.insertBefore(embed1, embed2);
+ this.add_cleanup(function() { document.body.removeChild(embed1) });
+
+ assert_array_equals(document.embeds, [embed1, embed2]);
+ assert_array_equals(document.plugins, [embed1, embed2]);
+
+ assert_equals(document.embeds, document.embeds,
+ "embeds should be constant");
+ assert_equals(document.plugins, document.plugins,
+ "plugins should be constant");
+ assert_equals(document.embeds, document.plugins,
+ "embeds should be the same as plugins");
+}, "Two plugins");
+
+test(function() {
+ var embed1 = document.createElement("embed"),
+ embed2 = document.createElement("embed");
+ document.body.appendChild(embed1);
+ this.add_cleanup(function() { document.body.removeChild(embed1) });
+ var embeds = document.embeds;
+ assert_true(embeds instanceof HTMLCollection);
+ assert_equals(embeds.length, 1);
+
+ document.body.appendChild(embed2);
+ assert_equals(embeds.length, 2);
+
+ document.body.removeChild(embed2);
+ assert_equals(embeds.length, 1);
+}, "Document.embeds should be a live collection");
+
+test(function() {
+ var embed1 = document.createElement("embed"),
+ embed2 = document.createElement("embed");
+ document.body.appendChild(embed1);
+ this.add_cleanup(function() { document.body.removeChild(embed1) });
+ var pls = document.plugins;
+ assert_true(pls instanceof HTMLCollection);
+ assert_equals(pls.length, 1);
+
+ document.body.appendChild(embed2);
+ assert_equals(pls.length, 2);
+
+ document.body.removeChild(embed2);
+ assert_equals(pls.length, 1);
+}, "Document.plugins should be a live collection");
+</script>
diff --git a/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.forms.html b/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.forms.html
new file mode 100644
index 0000000000..f354c57477
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.forms.html
@@ -0,0 +1,83 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Document.forms</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<form id="form1">
+<input type="button" name="thebutton" value="alpha">
+<input type=radio name=r1 value=a>
+<input type=radio name=r1 value=b>
+<input type=radio name=r1 value=c>
+<input type=radio name=r1 value=d>
+<input type=radio name=r1 value=e>
+</form>
+
+<form id="form2">
+<input type="button" name="thebutton" value="alpha">
+<input type=radio name=r1 value="a">
+<input type=radio name=r1 value="b">
+<input type=radio name=r1 value="c">
+<input type=radio name=r1 value="d">
+<input type=radio name=r1 value="e">
+</form>
+
+<form id=""></form>
+<script>
+test(function() {
+ assert_equals(document.forms.length, 3);
+ assert_equals(document.forms[0].id, "form1");
+ assert_equals(document.forms[1].id, "form2");
+ assert_equals(document.forms.form1.id, "form1");
+ assert_equals(document.forms.form2.id, "form2");
+ assert_equals(document.forms.item(0).id, "form1");
+ assert_equals(document.forms.item(1).id, "form2");
+ assert_equals(document.forms.namedItem("form1").id, "form1");
+ assert_equals(document.forms.namedItem("form2").id, "form2");
+}, "document.forms")
+
+test(function() {
+ // The `item` method takes one *numeric* argument. Passing a string to `item`
+ // results in that string getting converted to 0
+ assert_equals(document.forms.item("form1").id, "form1");
+ assert_equals(document.forms.item("form2").id, "form1");
+}, "document.forms.item with string arg")
+
+test(function() {
+ assert_equals(document.forms[""], undefined);
+ assert_equals(document.forms.namedItem(""), null);
+}, "document.forms with empty string")
+
+test(function() {
+ var result = [];
+ for (var p in document.forms) {
+ result.push(p);
+ }
+ // https://webidl.spec.whatwg.org/#property-enumeration
+ // If the object supports indexed properties, then the object’s supported
+ // property indices are enumerated first, in numerical order.
+ assert_array_equals(result.splice(0, 3), ["0", "1", "2"]);
+ // [...]
+ // Finally, any enumerable own properties or properties from the object’s
+ // prototype chain are then enumerated, in no defined order.
+ assert_array_equals(result.sort(), ["item", "namedItem", "length"].sort())
+}, "document.forms iteration")
+
+test(function() {
+ var result = Object.getOwnPropertyNames(document.forms);
+ assert_array_equals(result, ["0", "1", "2", "form1", "form2"])
+}, "document.forms getOwnPropertyNames")
+
+test(function() {
+ var forms = document.forms;
+ assert_true(forms instanceof HTMLCollection);
+ assert_equals(forms.length, 3);
+
+ var form = document.createElement("form");
+ document.body.appendChild(form);
+ assert_equals(forms.length, 4);
+
+ document.body.removeChild(form);
+ assert_equals(forms.length, 3);
+}, "Document.forms should be a live collection");
+</script>
diff --git a/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.getElementsByClassName-same.html b/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.getElementsByClassName-same.html
new file mode 100644
index 0000000000..a91c838d8a
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.getElementsByClassName-same.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<title>Calling getElementsByClassName with the same argument</title>
+<link rel="author" title="Ms2ger" href="mailto:ms2ger@gmail.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-getelementsbyclassname">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<div id="test">
+<div class="abcd"></div>
+</div>
+<script>
+test(function() {
+ var list1 = document.getElementsByClassName("abcd");
+ var list2 = document.getElementsByClassName("abcd");
+ assert_true(list1 === list2 || list1 !== list2);
+}, "The user agent may return the same object as the object returned by the earlier call.");
+</script>
diff --git a/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.getElementsByName/document.getElementsByName-case-xhtml.xhtml b/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.getElementsByName/document.getElementsByName-case-xhtml.xhtml
new file mode 100644
index 0000000000..f15edb6f1d
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.getElementsByName/document.getElementsByName-case-xhtml.xhtml
@@ -0,0 +1,21 @@
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title>getElementsByName and case</title>
+<link rel="author" title="Ms2ger" href="mailto:ms2ger@gmail.com"/>
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-document-getelementsbyname"/>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+</head>
+<body>
+<div id="log"></div>
+<div id="test">
+<div name="abcd"></div>
+</div>
+<script>
+test(function() {
+ assert_equals(document.getElementsByName("ABCD").length, 0);
+ assert_equals(document.getElementsByName("abcd").length, 1);
+});
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.getElementsByName/document.getElementsByName-case.html b/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.getElementsByName/document.getElementsByName-case.html
new file mode 100644
index 0000000000..9a82e6805c
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.getElementsByName/document.getElementsByName-case.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<title>getElementsByName and case</title>
+<link rel="author" title="Ms2ger" href="mailto:ms2ger@gmail.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-document-getelementsbyname">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<div id="test">
+<div name="abcd"></div>
+</div>
+<script>
+test(function() {
+ assert_equals(document.getElementsByName("ABCD").length, 0);
+ assert_equals(document.getElementsByName("abcd").length, 1);
+});
+</script>
diff --git a/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.getElementsByName/document.getElementsByName-id-xhtml.xhtml b/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.getElementsByName/document.getElementsByName-id-xhtml.xhtml
new file mode 100644
index 0000000000..51b9e22f84
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.getElementsByName/document.getElementsByName-id-xhtml.xhtml
@@ -0,0 +1,20 @@
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title>getElementsByName and ids</title>
+<link rel="author" title="Ms2ger" href="mailto:ms2ger@gmail.com"/>
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-document-getelementsbyname"/>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+</head>
+<body>
+<div id="log"></div>
+<div id="test">
+<div id="abcd"></div>
+</div>
+<script>
+test(function() {
+ assert_equals(document.getElementsByName("abcd").length, 0);
+});
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.getElementsByName/document.getElementsByName-id.html b/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.getElementsByName/document.getElementsByName-id.html
new file mode 100644
index 0000000000..099215d3a7
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.getElementsByName/document.getElementsByName-id.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<title>getElementsByName and ids</title>
+<link rel="author" title="Ms2ger" href="mailto:ms2ger@gmail.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-document-getelementsbyname">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<div id="test">
+<div id="abcd"></div>
+</div>
+<script>
+test(function() {
+ assert_equals(document.getElementsByName("abcd").length, 0);
+});
+</script>
diff --git a/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.getElementsByName/document.getElementsByName-interface.html b/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.getElementsByName/document.getElementsByName-interface.html
new file mode 100644
index 0000000000..97646e39cf
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.getElementsByName/document.getElementsByName-interface.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<title>Document.getElementsByName: interfaces</title>
+<link rel="author" title="Ms2ger" href="mailto:Ms2ger@gmail.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-document-getelementsbyname">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<script>
+test(function() {
+ var collection = document.getElementsByName("name");
+ assert_class_string(collection, "NodeList");
+ assert_true(collection instanceof NodeList, "Should be a NodeList");
+ assert_false(collection instanceof HTMLCollection,
+ "Should not be a HTMLCollection");
+});
+</script>
diff --git a/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.getElementsByName/document.getElementsByName-liveness.html b/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.getElementsByName/document.getElementsByName-liveness.html
new file mode 100644
index 0000000000..74aad6954f
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.getElementsByName/document.getElementsByName-liveness.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<title>Document.getElementsByName: liveness</title>
+<link rel="author" title="Intel" href="http://www.intel.com">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<script>
+test(function() {
+ var input = document.createElement("input"),
+ embed = document.createElement("embed");
+ input.setAttribute("name", "test");
+ input.setAttribute("type", "text");
+ embed.setAttribute("name", "test");
+ document.body.appendChild(input);
+ this.add_cleanup(function() { document.body.removeChild(input) });
+ var e = document.getElementsByName("test");
+ assert_true(e instanceof NodeList);
+ assert_equals(e.length, 1);
+
+ document.body.appendChild(embed);
+ assert_equals(e.length, 2);
+
+ document.body.removeChild(embed);
+ assert_equals(e.length, 1);
+}, "Document.getElementsByName() should be a live collection");
+</script>
diff --git a/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.getElementsByName/document.getElementsByName-namespace-xhtml.xhtml b/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.getElementsByName/document.getElementsByName-namespace-xhtml.xhtml
new file mode 100644
index 0000000000..e09ece7b1f
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.getElementsByName/document.getElementsByName-namespace-xhtml.xhtml
@@ -0,0 +1,32 @@
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title>getElementsByName and foreign namespaces</title>
+<link rel="author" title="Ms2ger" href="mailto:ms2ger@gmail.com"/>
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-document-getelementsbyname"/>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+</head>
+<body>
+<div id="log"></div>
+<div id="test">
+<p name="math"><math name="math" xmlns="http://www.w3.org/1998/Math/MathML">
+<mi>a</mi>
+<mo>+</mo>
+<mi>b</mi>
+</math></p>
+<p name="svg"><svg width="300" height="100" name="svg" xmlns="http://www.w3.org/2000/svg">
+<rect width="300" height="100" fill="rgb(0,0,255)"/>
+</svg></p>
+</div>
+<script>
+test(function() {
+ var ps = document.getElementById("test")
+ .getElementsByTagName("p");
+ assert_equals(document.getElementsByName("math").length, 1);
+ assert_equals(document.getElementsByName("math")[0], ps[0]);
+ assert_equals(document.getElementsByName("svg").length, 1);
+ assert_equals(document.getElementsByName("svg")[0], ps[1]);
+});
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.getElementsByName/document.getElementsByName-namespace.html b/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.getElementsByName/document.getElementsByName-namespace.html
new file mode 100644
index 0000000000..63b6260424
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.getElementsByName/document.getElementsByName-namespace.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<title>getElementsByName and foreign namespaces</title>
+<link rel="author" title="Ms2ger" href="mailto:ms2ger@gmail.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-document-getelementsbyname">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<div id="test">
+<p name="math"><math name="math">
+<mi>a</mi>
+<mo>+</mo>
+<mi>b</mi>
+</math>
+<p name="svg"><svg width="300" height="100" name="svg">
+<rect width="300" height="100" fill="rgb(0,0,255)"/>
+</svg>
+</div>
+<script>
+test(function() {
+ var ps = document.getElementById("test")
+ .getElementsByTagName("p");
+ assert_equals(document.getElementsByName("math").length, 1);
+ assert_equals(document.getElementsByName("math")[0], ps[0]);
+ assert_equals(document.getElementsByName("svg").length, 1);
+ assert_equals(document.getElementsByName("svg")[0], ps[1]);
+});
+</script>
diff --git a/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.getElementsByName/document.getElementsByName-newelements-xhtml.xhtml b/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.getElementsByName/document.getElementsByName-newelements-xhtml.xhtml
new file mode 100644
index 0000000000..c2dc99a55d
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.getElementsByName/document.getElementsByName-newelements-xhtml.xhtml
@@ -0,0 +1,126 @@
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title>getElementsByName and newly introduced HTML elements</title>
+<link rel="author" title="Ms2ger" href="mailto:ms2ger@gmail.com"/>
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-document-getelementsbyname"/>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+</head>
+<body>
+<div id="log"></div>
+<div id="test">
+<section name="section"></section>
+<article name="article"></article>
+<aside name="aside"></aside>
+<hgroup name="hgroup"></hgroup>
+<header name="header"></header>
+<footer name="footer"></footer>
+<nav name="nav"></nav>
+<dialog name="dialog"></dialog>
+<figure name="figure"></figure>
+<audio name="audio"></audio>
+<video name="video"></video>
+<embed name="embed"></embed>
+<mark name="mark"></mark>
+<meter name="meter"></meter>
+<progress name="progress"></progress>
+<time name="time"></time>
+<canvas name="canvas"></canvas>
+<command name="command"></command>
+<menu name="menu"></menu>
+<details name="details"></details>
+<datalist name="datalist"></datalist>
+<keygen name="keygen"></keygen>
+<output name="output"></output>
+<ruby name="ruby"></ruby>
+<rt name="rt"></rt>
+<rp name="rp"></rp>
+<source name="source"/>
+</div>
+<script>
+test(function() {
+ assert_equals(document.getElementsByName("section").length, 1);
+ assert_equals(document.getElementsByName("section")[0],
+ document.getElementsByTagName("section")[0]);
+ assert_equals(document.getElementsByName("article").length, 1);
+ assert_equals(document.getElementsByName("article")[0],
+ document.getElementsByTagName("article")[0]);
+ assert_equals(document.getElementsByName("aside").length, 1);
+ assert_equals(document.getElementsByName("aside")[0],
+ document.getElementsByTagName("aside")[0]);
+ assert_equals(document.getElementsByName("hgroup").length, 1);
+ assert_equals(document.getElementsByName("hgroup")[0],
+ document.getElementsByTagName("hgroup")[0]);
+ assert_equals(document.getElementsByName("header").length, 1);
+ assert_equals(document.getElementsByName("header")[0],
+ document.getElementsByTagName("header")[0]);
+ assert_equals(document.getElementsByName("footer").length, 1);
+ assert_equals(document.getElementsByName("footer")[0],
+ document.getElementsByTagName("footer")[0]);
+ assert_equals(document.getElementsByName("nav").length, 1);
+ assert_equals(document.getElementsByName("nav")[0],
+ document.getElementsByTagName("nav")[0]);
+ assert_equals(document.getElementsByName("dialog").length, 1);
+ assert_equals(document.getElementsByName("dialog")[0],
+ document.getElementsByTagName("dialog")[0]);
+ assert_equals(document.getElementsByName("figure").length, 1);
+ assert_equals(document.getElementsByName("figure")[0],
+ document.getElementsByTagName("figure")[0]);
+ assert_equals(document.getElementsByName("audio").length, 1);
+ assert_equals(document.getElementsByName("audio")[0],
+ document.getElementsByTagName("audio")[0]);
+ assert_equals(document.getElementsByName("video").length, 1);
+ assert_equals(document.getElementsByName("video")[0],
+ document.getElementsByTagName("video")[0]);
+ assert_equals(document.getElementsByName("embed").length, 1);
+ assert_equals(document.getElementsByName("embed")[0],
+ document.getElementsByTagName("embed")[0]);
+ assert_equals(document.getElementsByName("mark").length, 1);
+ assert_equals(document.getElementsByName("mark")[0],
+ document.getElementsByTagName("mark")[0]);
+ assert_equals(document.getElementsByName("meter").length, 1);
+ assert_equals(document.getElementsByName("meter")[0],
+ document.getElementsByTagName("meter")[0]);
+ assert_equals(document.getElementsByName("progress").length, 1);
+ assert_equals(document.getElementsByName("progress")[0],
+ document.getElementsByTagName("progress")[0]);
+ assert_equals(document.getElementsByName("time").length, 1);
+ assert_equals(document.getElementsByName("time")[0],
+ document.getElementsByTagName("time")[0]);
+ assert_equals(document.getElementsByName("canvas").length, 1);
+ assert_equals(document.getElementsByName("canvas")[0],
+ document.getElementsByTagName("canvas")[0]);
+ assert_equals(document.getElementsByName("command").length, 1);
+ assert_equals(document.getElementsByName("command")[0],
+ document.getElementsByTagName("command")[0]);
+ assert_equals(document.getElementsByName("menu").length, 1);
+ assert_equals(document.getElementsByName("menu")[0],
+ document.getElementsByTagName("menu")[0]);
+ assert_equals(document.getElementsByName("details").length, 1);
+ assert_equals(document.getElementsByName("details")[0],
+ document.getElementsByTagName("details")[0]);
+ assert_equals(document.getElementsByName("datalist").length, 1);
+ assert_equals(document.getElementsByName("datalist")[0],
+ document.getElementsByTagName("datalist")[0]);
+ assert_equals(document.getElementsByName("keygen").length, 1);
+ assert_equals(document.getElementsByName("keygen")[0],
+ document.getElementsByTagName("keygen")[0]);
+ assert_equals(document.getElementsByName("output").length, 1);
+ assert_equals(document.getElementsByName("output")[0],
+ document.getElementsByTagName("output")[0]);
+ assert_equals(document.getElementsByName("ruby").length, 1);
+ assert_equals(document.getElementsByName("ruby")[0],
+ document.getElementsByTagName("ruby")[0]);
+ assert_equals(document.getElementsByName("rt").length, 1);
+ assert_equals(document.getElementsByName("rt")[0],
+ document.getElementsByTagName("rt")[0]);
+ assert_equals(document.getElementsByName("rp").length, 1);
+ assert_equals(document.getElementsByName("rp")[0],
+ document.getElementsByTagName("rp")[0]);
+ assert_equals(document.getElementsByName("source").length, 1);
+ assert_equals(document.getElementsByName("source")[0],
+ document.getElementsByTagName("source")[0]);
+});
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.getElementsByName/document.getElementsByName-newelements.html b/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.getElementsByName/document.getElementsByName-newelements.html
new file mode 100644
index 0000000000..2ab42b9733
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.getElementsByName/document.getElementsByName-newelements.html
@@ -0,0 +1,47 @@
+<!DOCTYPE html>
+<title>getElementsByName and newly introduced HTML elements</title>
+<link rel="author" title="Ms2ger" href="mailto:ms2ger@gmail.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-document-getelementsbyname">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<div id="test">
+<section name="section"></section>
+<article name="article"></article>
+<aside name="aside"></aside>
+<hgroup name="hgroup"></hgroup>
+<header name="header"></header>
+<footer name="footer"></footer>
+<nav name="nav"></nav>
+<dialog name="dialog"></dialog>
+<figure name="figure"></figure>
+<audio name="audio"></audio>
+<video name="video"></video>
+<embed name="embed"></embed>
+<mark name="mark"></mark>
+<meter name="meter"></meter>
+<progress name="progress"></progress>
+<time name="time"></time>
+<canvas name="canvas"></canvas>
+<command name="command"></command>
+<menu name="menu"></menu>
+<details name="details"></details>
+<datalist name="datalist"></datalist>
+<keygen name="keygen"></keygen>
+<output name="output"></output>
+<ruby name="ruby"></ruby>
+<rt name="rt"></rt>
+<rp name="rp"></rp>
+<source name="source">
+</div>
+<script>
+var testDiv = document.getElementById("test");
+for (var i = 0; i < testDiv.children.length; i++) {
+ var name = testDiv.children[i].getAttribute("name");
+ test(function() {
+ assert_equals(document.getElementsByName(name).length, 1);
+ assert_equals(document.getElementsByName(name)[0],
+ document.getElementsByTagName(name)[0]);
+ }, 'getElementsByName("' + name + '")');
+}
+</script>
diff --git a/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.getElementsByName/document.getElementsByName-null-undef-xhtml.xhtml b/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.getElementsByName/document.getElementsByName-null-undef-xhtml.xhtml
new file mode 100644
index 0000000000..06d182860b
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.getElementsByName/document.getElementsByName-null-undef-xhtml.xhtml
@@ -0,0 +1,35 @@
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title>Calling getElementsByName with null and undefined</title>
+<link rel="author" title="Ms2ger" href="mailto:ms2ger@gmail.com"/>
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-document-getelementsbyname"/>
+<link rel="help" href="https://webidl.spec.whatwg.org/#es-DOMString"/>
+<link rel="help" href="http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-262.pdf#page=57"/>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+</head>
+<body>
+<div id="log"></div>
+<script>
+test(function() {
+ var n = document.createElement("div");
+ n.setAttribute("name", "null");
+
+ document.body.appendChild(n);
+ this.add_cleanup(function() { document.body.removeChild(n) });
+
+ assert_equals(document.getElementsByName(null)[0], n);
+}, "getElementsByName(null)");
+
+test(function() {
+ var u = document.createElement("div");
+ u.setAttribute("name", "undefined");
+
+ document.body.appendChild(u);
+ this.add_cleanup(function() { document.body.removeChild(u) });
+
+ assert_equals(document.getElementsByName(undefined)[0], u);
+}, "getElementsByName(undefined)");
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.getElementsByName/document.getElementsByName-null-undef.html b/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.getElementsByName/document.getElementsByName-null-undef.html
new file mode 100644
index 0000000000..f1dfbf9e39
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.getElementsByName/document.getElementsByName-null-undef.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<title>Calling getElementsByName with null and undefined</title>
+<link rel="author" title="Ms2ger" href="mailto:ms2ger@gmail.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-document-getelementsbyname">
+<link rel="help" href="https://webidl.spec.whatwg.org/#es-DOMString">
+<link rel="help" href="http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-262.pdf#page=57">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<script>
+test(function() {
+ var n = document.createElement("div");
+ n.setAttribute("name", "null");
+
+ document.body.appendChild(n);
+ this.add_cleanup(function() { document.body.removeChild(n) });
+
+ assert_equals(document.getElementsByName(null)[0], n);
+}, "getElementsByName(null)");
+
+test(function() {
+ var u = document.createElement("div");
+ u.setAttribute("name", "undefined");
+
+ document.body.appendChild(u);
+ this.add_cleanup(function() { document.body.removeChild(u) });
+
+ assert_equals(document.getElementsByName(undefined)[0], u);
+}, "getElementsByName(undefined)");
+</script>
diff --git a/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.getElementsByName/document.getElementsByName-param-xhtml.xhtml b/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.getElementsByName/document.getElementsByName-param-xhtml.xhtml
new file mode 100644
index 0000000000..e57e9d5c0d
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.getElementsByName/document.getElementsByName-param-xhtml.xhtml
@@ -0,0 +1,28 @@
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title>getElementsByName and the param element</title>
+<link rel="author" title="Ms2ger" href="mailto:ms2ger@gmail.com"/>
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-document-getelementsbyname"/>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+</head>
+<body>
+<div id="log"></div>
+<div id="test">
+<param name="test1"/>
+<object>
+<param name="test2"/>
+</object>
+</div>
+<script>
+test(function() {
+ assert_equals(document.getElementsByName("test1").length, 1);
+ assert_equals(document.getElementsByName("test1")[0],
+ document.getElementsByTagName("param")[0]);
+ assert_equals(document.getElementsByName("test2").length, 1);
+ assert_equals(document.getElementsByName("test2")[0],
+ document.getElementsByTagName("param")[1]);
+});
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.getElementsByName/document.getElementsByName-param.html b/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.getElementsByName/document.getElementsByName-param.html
new file mode 100644
index 0000000000..aa1bb01bfa
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.getElementsByName/document.getElementsByName-param.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<title>getElementsByName and the param element</title>
+<link rel="author" title="Ms2ger" href="mailto:ms2ger@gmail.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-document-getelementsbyname">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<div id="test">
+<param name="test1">
+<object>
+<param name="test2">
+</object>
+</div>
+<script>
+test(function() {
+ assert_equals(document.getElementsByName("test1").length, 1);
+ assert_equals(document.getElementsByName("test1")[0],
+ document.getElementsByTagName("param")[0]);
+ assert_equals(document.getElementsByName("test2").length, 1);
+ assert_equals(document.getElementsByName("test2")[0],
+ document.getElementsByTagName("param")[1]);
+});
+</script>
diff --git a/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.getElementsByName/document.getElementsByName-same.html b/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.getElementsByName/document.getElementsByName-same.html
new file mode 100644
index 0000000000..f122857a2b
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.getElementsByName/document.getElementsByName-same.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<title>Calling getElementsByName with the same argument</title>
+<link rel="author" title="Ms2ger" href="mailto:ms2ger@gmail.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-document-getelementsbyname">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<div id="test">
+<div name="abcd"></div>
+</div>
+<script>
+test(function() {
+ var list1 = document.getElementsByName("abcd");
+ var list2 = document.getElementsByName("abcd");
+ assert_true(list1 === list2 || list1 !== list2);
+}, "The user agent may return the same object as the object returned by the earlier call.");
+</script>
diff --git a/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.head-01.html b/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.head-01.html
new file mode 100644
index 0000000000..f919d79a32
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.head-01.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<title>document.head</title>
+<link rel="author" title="Ms2ger" href="mailto:ms2ger@gmail.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-document-head">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<script>
+test(function() {
+ var head = document.getElementsByTagName("head")[0];
+ assert_equals(document.head, head);
+ document.head = "";
+ assert_equals(document.head, head);
+ document.head = document.createElement("head");
+ assert_equals(document.head, head);
+ document.documentElement.appendChild(document.createElement("head"));
+ assert_equals(document.head, head);
+ var head2 = document.createElement("head");
+ document.documentElement.insertBefore(head2, head);
+ assert_equals(document.head, head2);
+});
+</script>
diff --git a/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.head-02.html b/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.head-02.html
new file mode 100644
index 0000000000..d0189574e2
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.head-02.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<title>document.head</title>
+<link rel="author" title="Ms2ger" href="mailto:ms2ger@gmail.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-document-head">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<script>
+var HTML = "http://www.w3.org/1999/xhtml";
+test(function() {
+ var head = document.getElementsByTagName("head")[0];
+ assert_equals(document.head, head);
+ var head2 = document.createElementNS(HTML, "blah:head");
+ document.documentElement.insertBefore(head2, head);
+ assert_equals(document.head, head2);
+ var head3 = document.createElementNS("http://www.example.org/", "blah:head");
+ document.documentElement.insertBefore(head3, head2);
+ assert_equals(document.head, head2);
+});
+</script>
diff --git a/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.images.html b/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.images.html
new file mode 100644
index 0000000000..10ebe5ee8a
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.images.html
@@ -0,0 +1,119 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Document.images</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<div id=log></div>
+<div id=test>
+<img>
+<img id=x><img name=y><img id=z1 name=z2>
+<img id=a><img id=a>
+<img name=b><img name=b>
+<img id=><img name=>
+<input type=image name=input>
+</div>
+<script>
+function assert_all(aAssertFunc, aCollection) {
+ for (var i = 0; i < aCollection.length; ++i) {
+ aAssertFunc(aCollection[i]);
+ }
+}
+
+var XHTML = "http://www.w3.org/1999/xhtml";
+var div, images, c;
+
+setup(function() {
+ div = document.getElementById("test");
+ var foreign =
+ div.appendChild(document.createElementNS("http://example.org", "img"));
+ foreign.setAttribute("id", "f");
+
+ images = [].slice.call(div.getElementsByTagNameNS(XHTML, "img"));
+
+ c = document.images;
+});
+
+test(function() {
+ assert_equals(c.length, 10);
+ assert_array_equals(c, images);
+
+ assert_all(function (aElement) {
+ assert_equals(aElement.namespaceURI, XHTML);
+ }, c);
+}, "document.images should contain all HTML img elements");
+
+test(function() {
+ assert_equals(c.x, images[1]);
+ assert_equals(c.namedItem("x"), images[1]);
+ assert_true("x" in c, '"x" in c');
+}, "img with id");
+
+test(function() {
+ assert_equals(c.y, images[2]);
+ assert_equals(c.namedItem("y"), images[2]);
+ assert_true("y" in c, '"y" in c');
+}, "img with name");
+
+test(function() {
+ assert_equals(c.z1, images[3]);
+ assert_equals(c.namedItem("z1"), images[3]);
+ assert_true("z1" in c, '"z1" in c');
+ assert_equals(c.z2, images[3]);
+ assert_equals(c.namedItem("z2"), images[3]);
+ assert_true("z2" in c, '"z2" in c');
+}, "img with id and name");
+
+test(function() {
+ assert_equals(c.a, images[4]);
+ assert_equals(c.namedItem("a"), images[4]);
+ assert_true("a" in c, '"a" in c');
+}, "Two img elements with the same id");
+
+test(function() {
+ assert_equals(c.b, images[6]);
+ assert_equals(c.namedItem("b"), images[6]);
+ assert_true("b" in c, '"b" in c');
+}, "Two img elements with the same name");
+
+test(function() {
+ assert_equals(c.c, undefined);
+ assert_equals(c.namedItem("c"), null);
+ assert_false("c" in c, '"c" in c');
+}, "Unknown name should not be in the collection");
+
+test(function() {
+ assert_equals(c.f, undefined);
+ assert_equals(c.namedItem("f"), null);
+ assert_false("f" in c, '"f" in c');
+}, "Foreign element should not be in the collection");
+
+test(function() {
+ assert_equals(c.input, undefined);
+ assert_equals(c.namedItem("input"), null);
+ assert_false("input" in c, '"input" in c');
+ var input = div.getElementsByTagName("input")[0];
+ assert_all(function (aElement) {
+ assert_not_equals(aElement.namespaceURI, input);
+ }, c);
+}, "Input elements should not be in the collection");
+
+test(function() {
+ assert_equals(c[""], undefined);
+ assert_equals(c.namedItem(""), null);
+ assert_false("" in c, '"" in c');
+}, "The empty string should not be in the collections");
+
+test(function() {
+ var div = document.getElementById("test");
+ var imgs = document.images;
+ assert_true(imgs instanceof HTMLCollection);
+ assert_equals(imgs.length, 10);
+
+ var img = document.createElement("img");
+ div.appendChild(img);
+ assert_equals(imgs.length, 11);
+
+ div.removeChild(img);
+ assert_equals(imgs.length, 10);
+}, "Document.images should be a live collection");
+</script>
diff --git a/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.links.html b/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.links.html
new file mode 100644
index 0000000000..69c7d8c52c
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.links.html
@@ -0,0 +1,27 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Document.links</title>
+<link rel="author" title="Intel" href="http://www.intel.com">
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<div id=log></div>
+<div id=test>
+<a href=""></a>
+<a href=""></a>
+</div>
+<script>
+test(function() {
+ var div = document.getElementById("test");
+ var links = document.links;
+ assert_true(links instanceof HTMLCollection);
+ assert_equals(links.length, 2);
+
+ var a = document.createElement("a");
+ a.setAttribute("href", "");
+ div.appendChild(a);
+ assert_equals(links.length, 3);
+
+ div.removeChild(a);
+ assert_equals(links.length, 2);
+}, "Document.links should be a live collection");
+</script>
diff --git a/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.scripts.html b/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.scripts.html
new file mode 100644
index 0000000000..82d3db14b2
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.scripts.html
@@ -0,0 +1,21 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Document.scripts</title>
+<link rel="author" title="Intel" href="http://www.intel.com">
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<div id=log></div>
+<script>
+test(function() {
+ var scripts = document.scripts;
+ assert_true(scripts instanceof HTMLCollection);
+ assert_equals(scripts.length, 3);
+
+ var script = document.createElement("script");
+ document.body.appendChild(script);
+ assert_equals(scripts.length, 4);
+
+ document.body.removeChild(script);
+ assert_equals(scripts.length, 3);
+}, "Document.scripts should be a live collection");
+</script>
diff --git a/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.title-01.html b/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.title-01.html
new file mode 100644
index 0000000000..05ddab9ca4
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.title-01.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<title>document.title with head blown away</title>
+<link rel="author" title="Ms2ger" href="mailto:ms2ger@gmail.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#document.title">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<script>
+test(function() {
+ assert_equals(document.title, "document.title with head blown away");
+})
+test(function() {
+ var head = document.getElementsByTagName("head")[0];
+ assert_true(!!head, "Head gone?!")
+ head.parentNode.removeChild(head);
+ assert_false(!!document.getElementsByTagName("head")[0], "Head still there?!")
+ document.title = "FAIL";
+ assert_equals(document.title, "");
+})
+test(function() {
+ var title2 = document.createElement("title");
+ title2.appendChild(document.createTextNode("PASS"));
+ document.body.appendChild(title2);
+ assert_equals(document.title, "PASS");
+})
+test(function() {
+ var title3 = document.createElement("title");
+ title3.appendChild(document.createTextNode("PASS2"));
+ document.documentElement.insertBefore(title3, document.body);
+ assert_equals(document.title, "PASS2");
+})
+</script>
diff --git a/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.title-02.xhtml b/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.title-02.xhtml
new file mode 100644
index 0000000000..917b8787df
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.title-02.xhtml
@@ -0,0 +1,37 @@
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title>document.title with head blown away</title>
+<link rel="author" title="Ms2ger" href="mailto:ms2ger@gmail.com"/>
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#document.title"/>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+</head>
+<body>
+<div id="log"></div>
+<script>
+test(function() {
+ assert_equals(document.title, "document.title with head blown away");
+})
+test(function() {
+ var head = document.getElementsByTagName("head")[0];
+ assert_true(!!head, "Head gone?!")
+ head.parentNode.removeChild(head);
+ assert_false(!!document.getElementsByTagName("head")[0], "Head still there?!")
+ document.title = "FAIL";
+ assert_equals(document.title, "");
+})
+test(function() {
+ var title2 = document.createElement("title");
+ title2.appendChild(document.createTextNode("PASS"));
+ document.body.appendChild(title2);
+ assert_equals(document.title, "PASS");
+})
+test(function() {
+ var title3 = document.createElement("title");
+ title3.appendChild(document.createTextNode("PASS2"));
+ document.documentElement.insertBefore(title3, document.body);
+ assert_equals(document.title, "PASS2");
+})
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.title-03.html b/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.title-03.html
new file mode 100644
index 0000000000..952c29db5f
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.title-03.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<title> document.title and space normalization </title>
+<link rel="author" title="Ms2ger" href="mailto:ms2ger@gmail.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#document.title">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<script>
+function test_title(set, expected) {
+ test(function() {
+ document.title = set;
+ assert_equals(document.title, expected);
+ }, "document.title after setting to " + format_value(set));
+}
+
+test(function() {
+ // Single space characters must be normalized. (WHATWG r4353)
+ assert_equals(document.title, "document.title and space normalization");
+}, "document.title initial value");
+
+test_title("one space", "one space");
+test_title("two spaces", "two spaces");
+test_title("one\ttab", "one tab");
+test_title("two\t\ttabs", "two tabs");
+test_title("one\nnewline", "one newline");
+test_title("two\n\nnewlines", "two newlines");
+test_title("one\fform feed", "one form feed");
+test_title("two\f\fform feeds", "two form feeds");
+test_title("one\rcarriage return", "one carriage return");
+test_title("two\r\rcarriage returns", "two carriage returns");
+</script>
diff --git a/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.title-04.xhtml b/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.title-04.xhtml
new file mode 100644
index 0000000000..fbe891650a
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.title-04.xhtml
@@ -0,0 +1,48 @@
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title> document.title and space normalization </title>
+<link rel="author" title="Ms2ger" href="mailto:ms2ger@gmail.com"/>
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#document.title"/>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+</head>
+<body>
+<div id="log"></div>
+<script>
+test(function() {
+ // Single space characters must be normalized. (WHATWG r4353)
+ assert_equals(document.title, "document.title and space normalization");
+
+ document.title = "one space";
+ assert_equals(document.title, "one space");
+
+ document.title = "two spaces";
+ assert_equals(document.title, "two spaces");
+
+ document.title = "one\ttab";
+ assert_equals(document.title, "one tab");
+
+ document.title = "two\t\ttabs";
+ assert_equals(document.title, "two tabs");
+
+ document.title = "one\nnewline";
+ assert_equals(document.title, "one newline");
+
+ document.title = "two\n\nnewlines";
+ assert_equals(document.title, "two newlines");
+
+ document.title = "one\fform feed";
+ assert_equals(document.title, "one form feed");
+
+ document.title = "two\f\fform feeds";
+ assert_equals(document.title, "two form feeds");
+
+ document.title = "one\rcarriage return";
+ assert_equals(document.title, "one carriage return");
+
+ document.title = "two\r\rcarriage returns";
+ assert_equals(document.title, "two carriage returns");
+});
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.title-05.html b/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.title-05.html
new file mode 100644
index 0000000000..df6ffc30f8
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.title-05.html
@@ -0,0 +1,42 @@
+<!doctype html>
+<title>document.title and White_Space characters</title>
+<link rel="author" title="Ms2ger" href="mailto:ms2ger@gmail.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#document.title">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<script>
+var White_Space = [
+ "\u000B",
+ "\u0085",
+ "\u00A0",
+ "\u1680",
+ "\u180E",
+ "\u2000",
+ "\u2001",
+ "\u2002",
+ "\u2003",
+ "\u2004",
+ "\u2005",
+ "\u2006",
+ "\u2007",
+ "\u2008",
+ "\u2009",
+ "\u200A",
+ "\u2028",
+ "\u2029",
+ "\u202F",
+ "\u205F",
+ "\u3000"
+];
+
+White_Space.forEach(function(character, i) {
+ test(function() {
+ var s = character + "a" + character + character + "b" + character + "c" +
+ String(i) + character;
+ document.title = s;
+ assert_equals(document.title, s);
+ }, "Removing whitespace in document.title: U+" +
+ character.charCodeAt(0).toString(16));
+});
+</script>
diff --git a/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.title-06.html b/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.title-06.html
new file mode 100644
index 0000000000..a80723f238
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.title-06.html
@@ -0,0 +1,19 @@
+<!doctype html>
+<title>document.title and the empty string</title>
+<link rel="author" title="Ms2ger" href="mailto:ms2ger@gmail.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#document.title">
+<meta name="assert" content="On setting document.title to the empty string, no text node must be created.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<script>
+test(function() {
+ var head = document.documentElement.firstChild;
+ head.removeChild(head.firstChild);
+ assert_equals(document.title, "");
+ document.title = "";
+ assert_equals(document.title, "");
+ assert_true(head.lastChild instanceof HTMLTitleElement, "Need a title element.");
+ assert_equals(head.lastChild.firstChild, null);
+});
+</script>
diff --git a/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.title-07.html b/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.title-07.html
new file mode 100644
index 0000000000..9723d3f811
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.title-07.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<title>Document.title and DOMImplementation.createHTMLDocument</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/dom/nodes/DOMImplementation-createHTMLDocument.js"></script>
+<div id="log"></div>
+<script>
+createHTMLDocuments(function(doc, expectedtitle, normalizedtitle) {
+ assert_equals(doc.title, normalizedtitle)
+})
+</script>
diff --git a/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.title-08.html b/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.title-08.html
new file mode 100644
index 0000000000..a643b75f4e
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.title-08.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<link rel="author" title="Denis Ah-Kang" href="mailto:denis@w3.org">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#document.title">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<script>
+test(function() {
+ assert_equals(document.title, "");
+}, "No title element");
+
+test(function() {
+ var title = document.createElement("title");
+ title.appendChild(document.createTextNode("PASS"));
+ document.head.appendChild(title);
+ assert_equals(document.title, "PASS");
+
+ title.appendChild(document.createTextNode("PASS2"));
+ title.appendChild(document.createTextNode("PASS3"));
+ assert_equals(document.title, "PASSPASS2PASS3");
+}, "title element contains multiple child text nodes");
+</script>
diff --git a/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.title-09.html b/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.title-09.html
new file mode 100644
index 0000000000..a3273f626c
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.title-09.html
@@ -0,0 +1,97 @@
+<!DOCTYPE html>
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#document.title">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<script>
+var SVG_NAMESPACE = "http://www.w3.org/2000/svg";
+var HTML_NAMESPACE = "http://www.w3.org/1999/xhtml";
+
+function newSVGDocument() {
+ return document.implementation.createDocument(SVG_NAMESPACE, "svg", null);
+}
+
+function assertIsSVGTitle(element, expectedText) {
+ assert_equals(element.namespaceURI, SVG_NAMESPACE);
+ assert_equals(element.localName, "title");
+ assert_equals(element.textContent, expectedText);
+}
+
+test(function() {
+ var doc = newSVGDocument();
+ assert_equals(doc.title, "");
+ var child = doc.createElementNS(SVG_NAMESPACE, "x-child");
+ doc.documentElement.appendChild(child);
+ doc.title = "foo";
+ assertIsSVGTitle(doc.documentElement.firstChild, "foo");
+ assert_equals(doc.title, "foo");
+}, "No title element in SVG document");
+
+test(function() {
+ var doc = newSVGDocument();
+ var title = doc.createElementNS(SVG_NAMESPACE, "title");
+ title.textContent = "foo";
+ doc.documentElement.appendChild(title)
+ assert_equals(doc.title, "foo");
+ doc.title += "bar";
+ assert_equals(title.textContent, "foobar");
+ assert_equals(title.childNodes.length, 1);
+ assert_true(title.childNodes[0] instanceof Text);
+ assert_equals(doc.title, "foobar");
+ doc.title = "";
+ assert_equals(title.textContent, "");
+ assert_equals(doc.title, "");
+ assert_equals(title.childNodes.length, 0);
+}, "Title element in SVG document");
+
+test(function() {
+ var doc = newSVGDocument();
+ var title = doc.createElementNS(SVG_NAMESPACE, "title");
+ title.textContent = "foo";
+ var child = doc.createElementNS(SVG_NAMESPACE, "x-child");
+ child.appendChild(title);
+ doc.documentElement.appendChild(child);
+ assert_equals(doc.title, "");
+
+ // Now test that on setting, we create a new element and don't change the
+ // existing one
+ doc.title = "bar";
+ assert_equals(title.textContent, "foo");
+ assertIsSVGTitle(doc.documentElement.firstChild, "bar");
+ assert_equals(doc.title, "bar");
+}, "Title element not child of SVG root");
+
+test(function() {
+ var doc = newSVGDocument();
+ var title = doc.createElementNS(HTML_NAMESPACE, "title");
+ title.textContent = "foo";
+ doc.documentElement.appendChild(title);
+ assert_equals(doc.title, "");
+}, "Title element not in SVG namespace");
+
+test(function() {
+ // "SVG" != "svg"
+ var doc = document.implementation.createDocument(SVG_NAMESPACE, "SVG", null);
+
+ // Per spec, this does nothing
+ doc.title = "foo";
+ assert_equals(doc.documentElement.childNodes.length, 0);
+ assert_equals(doc.title, "");
+
+ // An SVG title is ignored by .title
+ doc.documentElement.appendChild(doc.createElementNS(SVG_NAMESPACE, "title"));
+ doc.documentElement.lastChild.textContent = "foo";
+ assert_equals(doc.title, "");
+
+ // But an HTML title is respected
+ doc.documentElement.appendChild(doc.createElementNS(HTML_NAMESPACE, "title"));
+ doc.documentElement.lastChild.textContent = "bar";
+ assert_equals(doc.title, "bar");
+
+ // Even if it's not a child of the root
+ var div = doc.createElementNS(HTML_NAMESPACE, "div");
+ div.appendChild(doc.documentElement.lastChild);
+ doc.documentElement.appendChild(div);
+ assert_equals(doc.title, "bar");
+}, 'Root element not named "svg"');
+</script>
diff --git a/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.title-not-in-html-svg.html b/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.title-not-in-html-svg.html
new file mode 100644
index 0000000000..40eccd3de3
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/document.title-not-in-html-svg.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<link rel="author" title="Rob Buis" href="mailto:rbuis@igalia.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#document.title">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<script>
+
+function newXMLDocument() {
+ return document.implementation.createDocument(null, "foo", null);
+}
+
+test(function() {
+ var doc = newXMLDocument();
+ assert_equals(doc.title, "");
+ doc.title = "fail";
+ assert_equals(doc.title, "");
+}, "Should not be able to set document title in XML document");
+
+test(function() {
+ var doc = newXMLDocument();
+ doc.documentElement.appendChild(document.createElementNS("http://www.w3.org/1999/xhtml", "html:title"));
+ assert_equals(doc.title, "");
+ doc.title = "fail";
+ assert_equals(doc.title, "");
+}, "Should not be able to set document title in XML document with html:title element");
+</script>
diff --git a/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/nameditem-01.html b/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/nameditem-01.html
new file mode 100644
index 0000000000..2b428aa65b
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/nameditem-01.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Named items: img id &amp; name</title>
+<link rel="author" title="Ms2ger" href="mailto:ms2ger@gmail.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-document-nameditem">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<div id="test">
+<img id="a" name="b">
+</div>
+<script>
+test(function() {
+ assert_equals(document.a, document.getElementsByTagName("img")[0]);
+ assert_equals(document['a'], document.getElementsByTagName("img")[0]);
+ assert_equals(document.b, document.getElementsByTagName("img")[0]);
+ assert_equals(document['b'], document.getElementsByTagName("img")[0]);
+}, "img elements that have a name and id attribute, should be accessible by both values.");
+</script>
diff --git a/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/nameditem-02.html b/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/nameditem-02.html
new file mode 100644
index 0000000000..8c3155e7e4
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/nameditem-02.html
@@ -0,0 +1,99 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Named items: iframes</title>
+<link rel="author" title="Ms2ger" href="mailto:ms2ger@gmail.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-document-nameditem">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<div id="test">
+<iframe name="test1"></iframe>
+
+<iframe name="test2"></iframe>
+<iframe name="test2"></iframe>
+
+<iframe name="test3"></iframe>
+<img name="test3">
+
+<img name="test4">
+<iframe name="test4"></iframe>
+
+<iframe id="test5"></iframe>
+
+<iframe name="test6" id="fail"></iframe>
+
+<iframe name="fail" id="test7"></iframe>
+
+<iframe name="42"></iframe>
+</div>
+<script>
+test(function() {
+ var iframe = document.getElementsByTagName("iframe")[0];
+ assert_equals(iframe.name, "test1");
+
+ assert_true("test1" in document, '"test1" in document should be true');
+ assert_equals(document.test1, iframe.contentWindow);
+}, "If the only named item is an iframe, the contentWindow should be returned.");
+
+test(function() {
+ var iframe1 = document.getElementsByTagName("iframe")[1];
+ assert_equals(iframe1.name, "test2");
+ var iframe2 = document.getElementsByTagName("iframe")[2];
+ assert_equals(iframe2.name, "test2");
+
+ assert_true("test2" in document, '"test2" in document should be true');
+ var collection = document.test2;
+ assert_class_string(collection, "HTMLCollection", "collection should be an HTMLCollection");
+ assert_array_equals(collection, [iframe1, iframe2]);
+}, "If there are two iframes, a collection should be returned.");
+
+test(function() {
+ var iframe = document.getElementsByTagName("iframe")[3];
+ assert_equals(iframe.name, "test3");
+ var img = document.getElementsByTagName("img")[0];
+ assert_equals(img.name, "test3");
+
+ assert_true("test3" in document, '"test3" in document should be true');
+ var collection = document.test3;
+ assert_class_string(collection, "HTMLCollection", "collection should be an HTMLCollection");
+ assert_array_equals(collection, [iframe, img]);
+}, "If there are an iframe and another element (iframe first), a collection should be returned.");
+
+test(function() {
+ var iframe = document.getElementsByTagName("iframe")[4];
+ assert_equals(iframe.name, "test4");
+ var img = document.getElementsByTagName("img")[1];
+ assert_equals(img.name, "test4");
+
+ assert_true("test4" in document, '"test4" in document should be true');
+ var collection = document.test4;
+ assert_class_string(collection, "HTMLCollection", "collection should be an HTMLCollection");
+ assert_array_equals(collection, [img, iframe]);
+}, "If there are an iframe and another element (iframe last), a collection should be returned.");
+
+test(function() {
+ assert_false("test5" in document, '"test5" in document should be false');
+ assert_equals(document.test5, undefined);
+}, "If an iframe has an id and no name, it should not be returned.");
+
+test(function() {
+ var iframe = document.getElementsByTagName("iframe")[6];
+ assert_equals(iframe.name, "test6");
+
+ assert_true("test6" in document, '"test6" in document should be true');
+ assert_equals(document.test6, iframe.contentWindow);
+}, "If an iframe has a name and a different id, it should be returned by its name.");
+
+test(function() {
+ assert_false("test7" in document, '"test7" in document should be false');
+ assert_equals(document.test7, undefined);
+}, "If an iframe has an id and a different name, it should not be returned by its id.");
+
+test(function() {
+ var iframe = document.getElementsByTagName("iframe")[8];
+ assert_equals(iframe.name, "42");
+
+ assert_true(42 in document, '42 in document should be true');
+ assert_equals(document[42], iframe.contentWindow);
+}, "An iframe whose name looks like an array index should work.");
+</script>
diff --git a/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/nameditem-03.html b/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/nameditem-03.html
new file mode 100644
index 0000000000..be2ca173b0
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/nameditem-03.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Named items: applets</title>
+<link rel="author" title="Ms2ger" href="mailto:ms2ger@gmail.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-document-nameditem">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<applet name=test1></applet>
+<script>
+test(function() {
+ var applet = document.getElementsByTagName("applet")[0];
+ assert_equals(applet.name, undefined);
+
+ assert_false("test1" in document, '"test1" in document should be false');
+ assert_equals(document.test1, undefined);
+}, "applet elements are (mostly) gone");
+</script>
diff --git a/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/nameditem-04.html b/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/nameditem-04.html
new file mode 100644
index 0000000000..b7c3ef8e9b
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/nameditem-04.html
@@ -0,0 +1,104 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Named items: forms</title>
+<link rel="author" title="Ms2ger" href="mailto:ms2ger@gmail.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-document-nameditem">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<div id="test">
+<form name=test1></form>
+
+<form name=test2></form>
+<form name=test2></form>
+
+<form id=test3></form>
+
+<form id=test4></form>
+<form id=test4></form>
+
+<form name=test5></form>
+<form id=test5></form>
+
+<form id=test6></form>
+<form name=test6></form>
+
+<form id=test7 name=fail></form>
+
+<form name=test8 id=fail></form>
+</div>
+<script>
+test(function() {
+ var form = document.getElementsByTagName("form")[0];
+ assert_equals(form.name, "test1");
+
+ assert_true("test1" in document, '"test1" in document should be true');
+ assert_equals(document.test1, form);
+}, "If there is one form, it should be returned (name)");
+
+test(function() {
+ var form1 = document.getElementsByTagName("form")[1];
+ assert_equals(form1.name, "test2");
+ var form2 = document.getElementsByTagName("form")[2];
+ assert_equals(form2.name, "test2");
+
+ assert_true("test2" in document, '"test2" in document should be true');
+ var collection = document.test2;
+ assert_class_string(collection, "HTMLCollection", "collection should be an HTMLCollection");
+ assert_array_equals(collection, [form1, form2]);
+}, "If there are two forms, a collection should be returned. (name)");
+
+test(function() {
+ var form = document.getElementsByTagName("form")[3];
+ assert_equals(form.id, "test3");
+
+ assert_false("test3" in document, '"test3" in document should be false');
+ assert_equals(document.test3, undefined);
+}, "If there is one form, it should not be returned (id)");
+
+test(function() {
+ var form1 = document.getElementsByTagName("form")[4];
+ assert_equals(form1.id, "test4");
+ var form2 = document.getElementsByTagName("form")[5];
+ assert_equals(form2.id, "test4");
+
+ assert_false("test4" in document, '"test4" in document should be false');
+ assert_equals(document.test4, undefined);
+}, "If there are two forms, nothing should be returned. (id)");
+
+test(function() {
+ var form1 = document.getElementsByTagName("form")[6];
+ assert_equals(form1.name, "test5");
+ var form2 = document.getElementsByTagName("form")[7];
+ assert_equals(form2.id, "test5");
+
+ assert_true("test5" in document, '"test5" in document should be true');
+ assert_equals(document.test5, form1);
+}, "If there are two forms, a collection should be returned. (name and id)");
+
+test(function() {
+ var form1 = document.getElementsByTagName("form")[8];
+ assert_equals(form1.id, "test6");
+ var form2 = document.getElementsByTagName("form")[9];
+ assert_equals(form2.name, "test6");
+
+ assert_true("test6" in document, '"test6" in document should be true');
+ assert_equals(document.test6, form2);
+}, "If there are two forms, a collection should be returned. (id and name)");
+
+test(function() {
+ var form = document.getElementsByTagName("form")[10];
+ assert_equals(form.id, "test7");
+
+ assert_false("test7" in document, '"test7" in document should be false');
+ assert_equals(document.test7, undefined);
+}, "A name shouldn't affect getting an form by id");
+
+test(function() {
+ var form = document.getElementsByTagName("form")[11];
+ assert_equals(form.name, "test8");
+
+ assert_true("test8" in document, '"test8" in document should be true');
+ assert_equals(document.test8, form);
+}, "An id shouldn't affect getting an form by name");
+</script>
diff --git a/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/nameditem-05.html b/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/nameditem-05.html
new file mode 100644
index 0000000000..843ce35796
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/nameditem-05.html
@@ -0,0 +1,104 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Named items: embeds</title>
+<link rel="author" title="Ms2ger" href="mailto:ms2ger@gmail.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-document-nameditem">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<div id="test">
+<embed name=test1></embed>
+
+<embed name=test2></embed>
+<embed name=test2></embed>
+
+<embed id=test3></embed>
+
+<embed id=test4></embed>
+<embed id=test4></embed>
+
+<embed name=test5></embed>
+<embed id=test5></embed>
+
+<embed id=test6></embed>
+<embed name=test6></embed>
+
+<embed id=test7 name=fail></embed>
+
+<embed name=test8 id=fail></embed>
+</div>
+<script>
+test(function() {
+ var embed = document.getElementsByTagName("embed")[0];
+ assert_equals(embed.name, "test1");
+
+ assert_true("test1" in document, '"test1" in document should be true');
+ assert_equals(document.test1, embed);
+}, "If there is one embed, it should be returned (name)");
+
+test(function() {
+ var embed1 = document.getElementsByTagName("embed")[1];
+ assert_equals(embed1.name, "test2");
+ var embed2 = document.getElementsByTagName("embed")[2];
+ assert_equals(embed2.name, "test2");
+
+ assert_true("test2" in document, '"test2" in document should be true');
+ var collection = document.test2;
+ assert_class_string(collection, "HTMLCollection", "collection should be an HTMLCollection");
+ assert_array_equals(collection, [embed1, embed2]);
+}, "If there are two embeds, a collection should be returned. (name)");
+
+test(function() {
+ var embed = document.getElementsByTagName("embed")[3];
+ assert_equals(embed.id, "test3");
+
+ assert_false("test3" in document, '"test3" in document should be false');
+ assert_equals(document.test3, undefined);
+}, "If there is one embed, it should not be returned (id)");
+
+test(function() {
+ var embed1 = document.getElementsByTagName("embed")[4];
+ assert_equals(embed1.id, "test4");
+ var embed2 = document.getElementsByTagName("embed")[5];
+ assert_equals(embed2.id, "test4");
+
+ assert_false("test4" in document, '"test4" in document should be false');
+ assert_equals(document.test4, undefined);
+}, "If there are two embeds, nothing should be returned. (id)");
+
+test(function() {
+ var embed1 = document.getElementsByTagName("embed")[6];
+ assert_equals(embed1.name, "test5");
+ var embed2 = document.getElementsByTagName("embed")[7];
+ assert_equals(embed2.id, "test5");
+
+ assert_true("test5" in document, '"test5" in document should be true');
+ assert_equals(document.test5, embed1);
+}, "If there are two embeds, a collection should be returned. (name and id)");
+
+test(function() {
+ var embed1 = document.getElementsByTagName("embed")[8];
+ assert_equals(embed1.id, "test6");
+ var embed2 = document.getElementsByTagName("embed")[9];
+ assert_equals(embed2.name, "test6");
+
+ assert_true("test6" in document, '"test6" in document should be true');
+ assert_equals(document.test6, embed2);
+}, "If there are two embeds, a collection should be returned. (id and name)");
+
+test(function() {
+ var embed = document.getElementsByTagName("embed")[10];
+ assert_equals(embed.id, "test7");
+
+ assert_false("test7" in document, '"test7" in document should be false');
+ assert_equals(document.test7, undefined);
+}, "A name shouldn't affect getting an embed by id");
+
+test(function() {
+ var embed = document.getElementsByTagName("embed")[11];
+ assert_equals(embed.name, "test8");
+
+ assert_true("test8" in document, '"test8" in document should be true');
+ assert_equals(document.test8, embed);
+}, "An id shouldn't affect getting an embed by name");
+</script>
diff --git a/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/nameditem-06.html b/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/nameditem-06.html
new file mode 100644
index 0000000000..15a72b5f6b
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/nameditem-06.html
@@ -0,0 +1,104 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Named items: imgs</title>
+<link rel="author" title="Ms2ger" href="mailto:ms2ger@gmail.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-document-nameditem">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<div id="test">
+<img name=test1>
+
+<img name=test2>
+<img name=test2>
+
+<img id=test3>
+
+<img id=test4>
+<img id=test4 name="">
+
+<img name=test5>
+<img id=test5>
+
+<img id=test6>
+<img name=test6>
+
+<img id=test7 name=fail>
+
+<img name=test8 id=fail>
+</div>
+<script>
+test(function() {
+ var img = document.getElementsByTagName("img")[0];
+ assert_equals(img.name, "test1");
+
+ assert_true("test1" in document, '"test1" in document should be true');
+ assert_equals(document.test1, img);
+}, "If there is one img, it should be returned (name)");
+
+test(function() {
+ var img1 = document.getElementsByTagName("img")[1];
+ assert_equals(img1.name, "test2");
+ var img2 = document.getElementsByTagName("img")[2];
+ assert_equals(img2.name, "test2");
+
+ assert_true("test2" in document, '"test2" in document should be true');
+ var collection = document.test2;
+ assert_class_string(collection, "HTMLCollection", "collection should be an HTMLCollection");
+ assert_array_equals(collection, [img1, img2]);
+}, "If there are two imgs, a collection should be returned. (name)");
+
+test(function() {
+ var img = document.getElementsByTagName("img")[3];
+ assert_equals(img.id, "test3");
+
+ assert_false("test3" in document, '"test3" in document should be false');
+ assert_equals(document.test3, undefined);
+}, "If there is one img, it should not be returned (id)");
+
+test(function() {
+ var img1 = document.getElementsByTagName("img")[4];
+ assert_equals(img1.id, "test4");
+ var img2 = document.getElementsByTagName("img")[5];
+ assert_equals(img2.id, "test4");
+
+ assert_false("test4" in document, '"test4" in document should be false');
+ assert_equals(document.test4, undefined);
+}, "If there are two imgs, nothing should be returned. (id)");
+
+test(function() {
+ var img1 = document.getElementsByTagName("img")[6];
+ assert_equals(img1.name, "test5");
+ var img2 = document.getElementsByTagName("img")[7];
+ assert_equals(img2.id, "test5");
+
+ assert_true("test5" in document, '"test5" in document should be true');
+ assert_equals(document.test5, img1);
+}, "If there are two imgs, the one with a name should be returned. (name and id)");
+
+test(function() {
+ var img1 = document.getElementsByTagName("img")[8];
+ assert_equals(img1.id, "test6");
+ var img2 = document.getElementsByTagName("img")[9];
+ assert_equals(img2.name, "test6");
+
+ assert_true("test6" in document, '"test6" in document should be true');
+ assert_equals(document.test6, img2);
+}, "If there are two imgs, the one with a name should be returned. (id and name)");
+
+test(function() {
+ var img = document.getElementsByTagName("img")[10];
+ assert_equals(img.id, "test7");
+
+ assert_true("test7" in document, '"test7" in document should be true');
+ assert_equals(document.test7, img);
+}, "A name should affect getting an img by id");
+
+test(function() {
+ var img = document.getElementsByTagName("img")[11];
+ assert_equals(img.name, "test8");
+
+ assert_true("test8" in document, '"test8" in document should be true');
+ assert_equals(document.test8, img);
+}, "An id shouldn't affect getting an img by name");
+</script>
diff --git a/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/nameditem-07.html b/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/nameditem-07.html
new file mode 100644
index 0000000000..fc3f06c01b
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/nameditem-07.html
@@ -0,0 +1,109 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Named items: objects</title>
+<link rel="help" href="https://html.spec.whatwg.org/multipage/dom.html#dom-document-nameditem">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<div id="test">
+<object name=test1></object>
+
+<object name=test2></object>
+<object name=test2></object>
+
+<object id=test3></object>
+
+<object id=test4></object>
+<object id=test4></object>
+
+<object name=test5></object>
+<object id=test5></object>
+
+<object id=test6></object>
+<object name=test6></object>
+
+<object id=test7 name=fail></object>
+
+<object name=test8 id=fail></object>
+</div>
+<script>
+test(function() {
+ var object = document.getElementsByTagName("object")[0];
+ assert_equals(object.name, "test1");
+
+ assert_true("test1" in document, '"test1" in document should be true');
+ assert_equals(document.test1, object);
+}, "If there is one object, it should be returned (name)");
+
+test(function() {
+ var object1 = document.getElementsByTagName("object")[1];
+ assert_equals(object1.name, "test2");
+ var object2 = document.getElementsByTagName("object")[2];
+ assert_equals(object2.name, "test2");
+
+ assert_true("test2" in document, '"test2" in document should be true');
+ var collection = document.test2;
+ assert_class_string(collection, "HTMLCollection", "collection should be an HTMLCollection");
+ assert_array_equals(collection, [object1, object2]);
+}, "If there are two objects, a collection should be returned. (name)");
+
+test(function() {
+ var object = document.getElementsByTagName("object")[3];
+ assert_equals(object.id, "test3");
+
+ assert_true("test3" in document, '"test3" in document should be true');
+ assert_equals(document.test3, object);
+}, "If there is one object, it should be returned (id)");
+
+test(function() {
+ var object1 = document.getElementsByTagName("object")[4];
+ assert_equals(object1.id, "test4");
+ var object2 = document.getElementsByTagName("object")[5];
+ assert_equals(object2.id, "test4");
+
+ assert_true("test4" in document, '"test4" in document should be true');
+ var collection = document.test4;
+ assert_class_string(collection, "HTMLCollection", "collection should be an HTMLCollection");
+ assert_array_equals(collection, [object1, object2]);
+}, "If there are two objects, a collection should be returned. (id)");
+
+test(function() {
+ var object1 = document.getElementsByTagName("object")[6];
+ assert_equals(object1.name, "test5");
+ var object2 = document.getElementsByTagName("object")[7];
+ assert_equals(object2.id, "test5");
+
+ assert_true("test5" in document, '"test5" in document should be true');
+ var collection = document.test5;
+ assert_class_string(collection, "HTMLCollection", "collection should be an HTMLCollection");
+ assert_array_equals(collection, [object1, object2]);
+}, "If there are two objects, a collection should be returned. (name and id)");
+
+test(function() {
+ var object1 = document.getElementsByTagName("object")[8];
+ assert_equals(object1.id, "test6");
+ var object2 = document.getElementsByTagName("object")[9];
+ assert_equals(object2.name, "test6");
+
+ assert_true("test6" in document, '"test6" in document should be true');
+ var collection = document.test6;
+ assert_class_string(collection, "HTMLCollection", "collection should be an HTMLCollection");
+ assert_array_equals(collection, [object1, object2]);
+}, "If there are two objects, a collection should be returned. (id and name)");
+
+test(function() {
+ var object = document.getElementsByTagName("object")[10];
+ assert_equals(object.id, "test7");
+
+ assert_true("test7" in document, '"test7" in document should be true');
+ assert_equals(document.test7, object);
+}, "A name shouldn't affect getting an object by id");
+
+test(function() {
+ var object = document.getElementsByTagName("object")[11];
+ assert_equals(object.name, "test8");
+
+ assert_true("test8" in document, '"test8" in document should be true');
+ assert_equals(document.test8, object);
+}, "An id shouldn't affect getting an object by name");
+</script>
diff --git a/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/nameditem-08.html b/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/nameditem-08.html
new file mode 100644
index 0000000000..bb024d9e78
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/nameditem-08.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Named items: duplicate id attributes for object and img</title>
+<link rel="help" href="https://html.spec.whatwg.org/multipage/dom.html#dom-document-nameditem">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<div id="test">
+<div id=test2></div>
+<object id=test2></object>
+
+<div id=test3></div>
+<img id=test3 name=non-empty>
+</div>
+<script>
+test(function() {
+ var object = document.querySelector("object");
+ assert_equals(object.id, "test2");
+
+ assert_true("test2" in document);
+ assert_equals(document.test2, object);
+}, "If there is a div and object with same id, the object should be returned");
+
+test(function() {
+ var img = document.querySelector("img");
+ assert_equals(img.id, "test3");
+
+ assert_true("test3" in document);
+ assert_equals(document.test3, img);
+}, "If there is a div and img with same id, the img should be returned");
+</script>
diff --git a/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/nameditem-names.html b/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/nameditem-names.html
new file mode 100644
index 0000000000..3f76d85a1b
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/documents/dom-tree-accessors/nameditem-names.html
@@ -0,0 +1,101 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Named items: supported property names</title>
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-document-nameditem">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<embed name="exposed_embed">
+ <embed name="not_exposed_embed">
+ </embed>
+</embed>
+<form name="form">
+</form>
+<iframe name="iframe">
+</iframe>
+<img name="img">
+<object name="exposed_object_with_name">
+ <object name="not_exposed_object_with_name">
+ </object>
+</object>
+<object id="exposed_object_with_id">
+ <object id="not_exposed_object_with_id">
+ </object>
+</object>
+<img name="img_with_id" id="img_id">
+<img id="img_with_just_id">
+<template id="template">
+ <img name="img_in_template">
+</template>
+<img name="42">
+<script>
+var names = Object.getOwnPropertyNames(document);
+
+test(function() {
+ assert_true(names.includes("exposed_embed"))
+}, "An embed name appears in a document's property names if the embed is exposed.");
+
+test(function() {
+ assert_false(names.includes("not_exposed_embed"))
+}, "An embed name does not appears in a document's property names if the embed is inside another embed.");
+
+test(function() {
+ assert_true(names.includes("form"))
+}, "A form name appears in a document's property names.");
+
+test(function() {
+ assert_true(names.includes("iframe"))
+}, "An iframe name appears in a document's property names.");
+
+test(function() {
+ assert_true(names.includes("img"))
+}, "An img name appears in a document's property names when the img has no id.");
+
+test(function() {
+ assert_true(names.includes("exposed_object"))
+}, "An object name appears in a document's property names if the object is exposed.");
+
+test(function() {
+ assert_true(names.includes("exposed_object_with_id"))
+}, "An object id appears in a document's property names if the object is exposed.");
+
+test(function() {
+ assert_false(names.includes("not_exposed_object_with_name"))
+}, "An object name does not appear in a document's property names if the object is inside another object.");
+
+test(function() {
+ assert_false(names.includes("not_exposed_object_with_id"))
+}, "An object id does not appear in a document's property names if the object is inside another object.");
+
+test(function() {
+ assert_true(names.includes("img_with_id"))
+}, "An img name appears in a document's property names when the img has an id.");
+
+test(function() {
+ assert_true(names.includes("img_id"))
+}, "An img id appears in a document's property names when the img has a name.");
+
+test(function() {
+ assert_false(names.includes("img_with_just_id"))
+}, "An img id does not appear in a document's property names when the img has no name.");
+
+test(function() {
+ assert_true(names.includes("42"))
+}, "A document's property names can include integer strings.");
+
+test(function() {
+ assert_false(names.includes("template"))
+}, "A template name does not appear in a document's property names.");
+
+test(function() {
+ assert_false(names.includes("img_in_template"))
+}, "An img name does not appear in a document's property names when the img is in a template's document fragment.");
+
+test(function() {
+ var form_index = names.indexOf("form");
+ assert_equals(names.indexOf("iframe"), form_index + 1);
+ assert_equals(names.indexOf("img"), form_index + 2);
+ assert_greater_than(names.indexOf("img_id"), names.indexOf("img"));
+ assert_greater_than(names.indexOf("42"), names.indexOf("img_id"));
+}, "A document's property names appear in tree order.");
+</script>
diff --git a/testing/web-platform/tests/html/dom/documents/resource-metadata-management/document-compatmode-01.html b/testing/web-platform/tests/html/dom/documents/resource-metadata-management/document-compatmode-01.html
new file mode 100644
index 0000000000..218a3fe843
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/documents/resource-metadata-management/document-compatmode-01.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<title>document.compatMode: Standards</title>
+<link rel="author" title="Ms2ger" href="mailto:ms2ger@gmail.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-document-compatmode">
+<body>
+<div id="log"></div>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+test(function() {
+ assert_equals(document.compatMode, "CSS1Compat");
+})
+</script>
diff --git a/testing/web-platform/tests/html/dom/documents/resource-metadata-management/document-compatmode-02.html b/testing/web-platform/tests/html/dom/documents/resource-metadata-management/document-compatmode-02.html
new file mode 100644
index 0000000000..6da40d61ee
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/documents/resource-metadata-management/document-compatmode-02.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<title>document.compatMode: Almost standards</title>
+<link rel="author" title="Ms2ger" href="mailto:ms2ger@gmail.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-document-compatmode">
+<body>
+<div id="log"></div>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+test(function() {
+ assert_equals(document.compatMode, "CSS1Compat");
+})
+</script>
diff --git a/testing/web-platform/tests/html/dom/documents/resource-metadata-management/document-compatmode-03.html b/testing/web-platform/tests/html/dom/documents/resource-metadata-management/document-compatmode-03.html
new file mode 100644
index 0000000000..3d55d6e835
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/documents/resource-metadata-management/document-compatmode-03.html
@@ -0,0 +1,12 @@
+<title>document.compatMode: Quirks</title>
+<link rel="author" title="Ms2ger" href="mailto:ms2ger@gmail.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-document-compatmode">
+<body>
+<div id="log"></div>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+test(function() {
+ assert_equals(document.compatMode, "BackCompat");
+})
+</script>
diff --git a/testing/web-platform/tests/html/dom/documents/resource-metadata-management/document-compatmode-04.xhtml b/testing/web-platform/tests/html/dom/documents/resource-metadata-management/document-compatmode-04.xhtml
new file mode 100644
index 0000000000..a71c1d9dd3
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/documents/resource-metadata-management/document-compatmode-04.xhtml
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title>document.compatMode: Standards</title>
+<link rel="author" title="Ms2ger" href="mailto:ms2ger@gmail.com"/>
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-document-compatmode"/>
+</head>
+<body>
+<div id="log"></div>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+test(function() {
+ assert_equals(document.compatMode, "CSS1Compat");
+})
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/documents/resource-metadata-management/document-compatmode-05.xhtml b/testing/web-platform/tests/html/dom/documents/resource-metadata-management/document-compatmode-05.xhtml
new file mode 100644
index 0000000000..3fde06e5af
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/documents/resource-metadata-management/document-compatmode-05.xhtml
@@ -0,0 +1,19 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title>document.compatMode: Standards</title>
+<link rel="author" title="Ms2ger" href="mailto:ms2ger@gmail.com"/>
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-document-compatmode"/>
+</head>
+<body>
+<div id="log"></div>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+test(function() {
+ assert_equals(document.compatMode, "CSS1Compat");
+})
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/documents/resource-metadata-management/document-compatmode-06.xhtml b/testing/web-platform/tests/html/dom/documents/resource-metadata-management/document-compatmode-06.xhtml
new file mode 100644
index 0000000000..eb64dfb90e
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/documents/resource-metadata-management/document-compatmode-06.xhtml
@@ -0,0 +1,17 @@
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title>document.compatMode: Standards</title>
+<link rel="author" title="Ms2ger" href="mailto:ms2ger@gmail.com"/>
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-document-compatmode"/>
+</head>
+<body>
+<div id="log"></div>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+test(function() {
+ assert_equals(document.compatMode, "CSS1Compat");
+})
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/documents/resource-metadata-management/document-cookie.html b/testing/web-platform/tests/html/dom/documents/resource-metadata-management/document-cookie.html
new file mode 100644
index 0000000000..2af65effeb
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/documents/resource-metadata-management/document-cookie.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>document.cookie</title>
+<link rel="author" title="Denis Ah-Kang" href="mailto:denis@w3.org">
+<link rel=help href="https://html.spec.whatwg.org/multipage/#resource-metadata-management">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<script>
+
+const TEST_CASES = [
+ {value: "", expected: "", test: "Empty value"},
+ {value: "a=b", expected: "a=b", test: "A simple cookie"},
+ {value: "b=A\0Z", expected: "", test: "A null char"},
+];
+
+test(function(){
+ assert_equals(document.cookie, "");
+}, "document has no cookie");
+
+for (const i in TEST_CASES) {
+ const t = TEST_CASES[i];
+ test(() => {
+ document.cookie = t.value;
+ assert_equals(document.cookie, t.expected);
+
+ // Cleanup
+ if (document.cookie.includes("=")) {
+ document.cookie = document.cookie.split("=")[0] + "=; expires=Thu, 01 Jan 1970 00:00:00 UTC";
+ assert_equals(document.cookie, "");
+ }
+ }, t.name);
+}
+
+test(function(){
+ var doc = document.implementation.createHTMLDocument("doc");
+ assert_equals(doc.cookie, "");
+ doc.cookie = "test=foobar";
+ assert_equals(doc.cookie, "");
+}, "getting cookie for a cookie-averse document returns empty string, setting does nothing");
+</script>
diff --git a/testing/web-platform/tests/html/dom/documents/resource-metadata-management/document-lastModified-01.html b/testing/web-platform/tests/html/dom/documents/resource-metadata-management/document-lastModified-01.html
new file mode 100644
index 0000000000..81f67390d1
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/documents/resource-metadata-management/document-lastModified-01.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<title>document.lastModified should return current local time</title>
+<meta name="timeout" content="long">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="support/document-lastModified-utils.js"></script>
+<div id="log"></div>
+<script>
+ var last_modified = document.lastModified;
+
+ test(function() {
+ assert_regexp_match(last_modified, DOCUMENT_LASTMODIFIED_REGEX,
+ "Format should match the pattern \"NN/NN/NNNN NN:NN:NN\".");
+ }, "Date returned by lastModified is in the form \"MM/DD/YYYY hh:mm:ss\".");
+
+ test(function() {
+ assert_document_lastmodified_string_approximately_now(last_modified);
+ }, "Date returned by lastModified is current at page load");
+
+ var t = async_test("Date returned by lastModified is current after timeout.");
+ t.step_timeout(function() {
+ assert_document_lastmodified_string_approximately_now(document.lastModified);
+ t.done();
+ }, 4000);
+</script>
diff --git a/testing/web-platform/tests/html/dom/documents/resource-metadata-management/document-lastModified.html b/testing/web-platform/tests/html/dom/documents/resource-metadata-management/document-lastModified.html
new file mode 100644
index 0000000000..9e0a07d8eb
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/documents/resource-metadata-management/document-lastModified.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>document.lastModified</title>
+<link rel="author" title="Denis Ah-Kang" href="mailto:denis@w3.org">
+<link rel=help href="https://html.spec.whatwg.org/multipage/#resource-metadata-management">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<script>
+ test(function(){
+ var date = new Date("Thu, 01 Jan 1970 01:23:45 GMT");
+ var result = ('0' + (date.getMonth()+1)).slice(-2) + '/' + ('0' + date.getDate()).slice(-2) + '/' + date.getFullYear() + " " + [date.getHours(),date.getMinutes(),date.getSeconds()].map(function(n){return ("0" + n).slice(-2);}).join(":");
+ assert_equals(document.lastModified, result);
+ }, "lastModified should return the last modified date and time");
+</script>
diff --git a/testing/web-platform/tests/html/dom/documents/resource-metadata-management/document-lastModified.html.headers b/testing/web-platform/tests/html/dom/documents/resource-metadata-management/document-lastModified.html.headers
new file mode 100644
index 0000000000..377e3b52dc
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/documents/resource-metadata-management/document-lastModified.html.headers
@@ -0,0 +1 @@
+Last-Modified: Thu, 01 Jan 1970 01:23:45 GMT
diff --git a/testing/web-platform/tests/html/dom/documents/resource-metadata-management/document-readyState.html b/testing/web-platform/tests/html/dom/documents/resource-metadata-management/document-readyState.html
new file mode 100644
index 0000000000..8c91e0a001
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/documents/resource-metadata-management/document-readyState.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>document.readyState</title>
+<link rel="author" title="Denis Ah-Kang" href="mailto:denis@w3.org">
+<link rel=help href="https://html.spec.whatwg.org/multipage/#resource-metadata-management">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<script>
+ var t1 = async_test("readyState equals 'complete' when the document has loaded"),
+ t2 = async_test("readyState equals 'interactive' when the document is finished parsing"),
+ t3 = async_test("readystatechange event is fired each time document.readyState changes");
+
+ window.onload = t1.step_func_done(function(){
+ assert_equals(document.readyState, "complete");
+ });
+
+ document.addEventListener("DOMContentLoaded", function(event) {
+ t2.step(function() {
+ assert_equals(document.readyState, "interactive")
+ });
+ t2.done();
+ });
+
+ var states = [document.readyState];
+ document.onreadystatechange = t3.step_func(function(){
+ states.push(document.readyState);
+ if (document.readyState === "complete") {
+ assert_array_equals(states, ["loading", "interactive", "complete"]);
+ t3.done();
+ }
+ })
+</script>
diff --git a/testing/web-platform/tests/html/dom/documents/resource-metadata-management/support/document-lastModified-utils.js b/testing/web-platform/tests/html/dom/documents/resource-metadata-management/support/document-lastModified-utils.js
new file mode 100644
index 0000000000..bbcde1894a
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/documents/resource-metadata-management/support/document-lastModified-utils.js
@@ -0,0 +1,78 @@
+const DOCUMENT_LASTMODIFIED_REGEX = /^([0-9]{2})\/([0-9]{2})\/([0-9]{4}) ([0-9]{2}):([0-9]{2}):([0-9]{2})$/;
+
+function assert_document_lastmodified_string_approximately_now(str) {
+ // We want to test that |str| was a time in the user's local
+ // timezone generated within a few seconds prior to the present.
+ // This requires some care, since it is possible that:
+ // - the few second difference may have crossed a
+ // year/month/day/hour/minute boundary
+ // - the few second difference may have crossed a change in the
+ // local timezone's UTC offset
+ // - the local time might be one that has multiple valid UTC
+ // representations (for example, because it's in the hour
+ // following a shift from summer time to winter time)
+ // We will make some assumptions to do this:
+ // - local time's UTC offset doesn't change more than once per
+ // minute
+ // - local time's UTC offset only changes by integral numbers of
+ // minutes
+
+ // The date must be equal to or earlier than the present time.
+ var dmax = new Date();
+
+ // The date must be equal to or later than 2.5 seconds ago.
+ var TOLERANCE_MILLISECONDS = 2500;
+ var dmin = new Date();
+ dmin.setTime(dmax.getTime() - TOLERANCE_MILLISECONDS);
+
+ // Extract the year/month/date/hours/minutes/seconds from str. It
+ // is important that we do *not* try to construct a Date object from
+ // these, since the core of the date object is a timestamp in UTC,
+ // and there are cases (such as the hour on each side of a change
+ // from summer time to winter time) where there are multiple
+ // possible UTC timestamps for a given YYYY-MM-DD HH:MM:SS, and
+ // constructing a Date object would pick one of them, which might be
+ // the wrong one. However, we already have the right one in dmin
+ // and dmax, so we should instead extract local time from those
+ // rather than converting these values to UTC.
+ var m = DOCUMENT_LASTMODIFIED_REGEX.exec(str);
+ var syear = Number(m[3]);
+ var smonth = Number(m[1]) - 1; // match Javascript 0-based months
+ var sdate = Number(m[2]);
+ var shours = Number(m[4]);
+ var sminutes = Number(m[5]);
+ var sseconds = Number(m[6]);
+
+ if (dmin.getFullYear() == dmax.getFullYear() &&
+ dmin.getMonth() == dmax.getMonth() &&
+ dmin.getDate() == dmax.getDate() &&
+ dmin.getHours() == dmax.getHours() &&
+ dmin.getMinutes() == dmax.getMinutes()) {
+ // min and max have the same minute
+ assert_equals(smonth, dmin.getMonth(), "month");
+ assert_equals(sdate, dmin.getDate(), "date");
+ assert_equals(syear, dmin.getFullYear(), "year");
+ assert_equals(shours, dmin.getHours(), "hours");
+ assert_equals(sminutes, dmin.getMinutes(), "minutes");
+ assert_true(dmin.getSeconds() <= sseconds &&
+ sseconds <= dmax.getSeconds(), "seconds");
+ } else if (dmin.getFullYear() == syear &&
+ dmin.getMonth() == smonth &&
+ dmin.getDate() == sdate &&
+ dmin.getHours() == shours &&
+ dmin.getMinutes() == sminutes) {
+ // actual value has the same minute as min
+ assert_true(dmin.getSeconds() <= sseconds, "dmin.getSeconds() <= sseconds");
+ assert_true(57 <= dmin.getSeconds(), "unexpected local time rules (dmin match)");
+ } else if (dmax.getFullYear() == syear &&
+ dmax.getMonth() == smonth &&
+ dmax.getDate() == sdate &&
+ dmax.getHours() == shours &&
+ dmax.getMinutes() == sminutes) {
+ // actual value has the same minute as max
+ assert_true(sseconds <= dmax.getSeconds(), "sseconds <= dmax.getSeconds()");
+ assert_true(dmax.getSeconds() <= 2, "unexpected local time rules (dmax match)");
+ } else {
+ assert_unreached("unexpected local time rules (no match)");
+ }
+}
diff --git a/testing/web-platform/tests/html/dom/elements-embedded.js b/testing/web-platform/tests/html/dom/elements-embedded.js
new file mode 100644
index 0000000000..c5b4520cc6
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements-embedded.js
@@ -0,0 +1,156 @@
+var embeddedElements = {
+ picture: {},
+ img: {
+ // Conforming
+ alt: "string",
+ src: "url",
+ srcset: "string",
+ crossOrigin: {type: "enum", keywords: ["anonymous", "use-credentials"], nonCanon:{"": "anonymous"}, isNullable: true, defaultVal: null, invalidVal: "anonymous"},
+ useMap: "string",
+ isMap: "boolean",
+ width: {type: "unsigned long", customGetter: true},
+ height: {type: "unsigned long", customGetter: true},
+ referrerPolicy: {type: "enum", keywords: ["", "no-referrer", "no-referrer-when-downgrade", "same-origin", "origin", "strict-origin", "origin-when-cross-origin", "strict-origin-when-cross-origin", "unsafe-url"]},
+ decoding: {type: "enum", keywords: ["async", "sync", "auto"], defaultVal: "auto", invalidVal: "auto"},
+
+ // Obsolete
+ name: "string",
+ lowsrc: {type: "url"},
+ align: "string",
+ hspace: "unsigned long",
+ vspace: "unsigned long",
+ longDesc: "url",
+ border: {type: "string", treatNullAsEmptyString: true},
+ },
+ iframe: {
+ // Conforming
+ src: "url",
+ srcdoc: "string",
+ name: "string",
+ sandbox: "settable tokenlist",
+ allowFullscreen: "boolean",
+ allowUserMedia: "boolean",
+ width: "string",
+ height: "string",
+ referrerPolicy: {type: "enum", keywords: ["", "no-referrer", "no-referrer-when-downgrade", "same-origin", "origin", "strict-origin", "origin-when-cross-origin", "strict-origin-when-cross-origin", "unsafe-url"]},
+ delegateStickyUserActivation: {type: "enum", keywords: ["vibration", "media"], defaultVal: null},
+
+ // Obsolete
+ align: "string",
+ scrolling: "string",
+ frameBorder: "string",
+ longDesc: "url",
+ marginHeight: {type: "string", treatNullAsEmptyString: true},
+ marginWidth: {type: "string", treatNullAsEmptyString: true}
+ },
+ embed: {
+ // Conforming
+ src: "url",
+ type: "string",
+ width: "string",
+ height: "string",
+
+ // Obsolete
+ align: "string",
+ name: "string"
+ },
+ object: {
+ // Conforming
+ data: "url",
+ type: "string",
+ name: "string",
+ useMap: "string",
+ width: "string",
+ height: "string",
+
+ // Obsolete
+ align: "string",
+ archive: "string",
+ code: "string",
+ declare: "boolean",
+ hspace: "unsigned long",
+ standby: "string",
+ vspace: "unsigned long",
+ codeBase: "url",
+ codeType: "string",
+ border: {type: "string", treatNullAsEmptyString: true}
+ },
+ param: {
+ // Conforming
+ name: "string",
+ value: "string",
+
+ // Obsolete
+ type: "string",
+ valueType: "string"
+ },
+ video: {
+ // HTMLMediaElement
+ src: "url",
+ crossOrigin: {type: "enum", keywords: ["anonymous", "use-credentials"], nonCanon:{"": "anonymous"}, isNullable: true, defaultVal: null, invalidVal: "anonymous"},
+ // As with "keytype", we have no missing value default defined here.
+ preload: {type: "enum", keywords: ["none", "metadata", "auto"], nonCanon: {"": "auto"}, defaultVal: null},
+ autoplay: "boolean",
+ loop: "boolean",
+ controls: "boolean",
+ controlsList: {type: "tokenlist", domAttrName: "controlsList"},
+ defaultMuted: {type: "boolean", domAttrName: "muted"},
+
+ width: "unsigned long",
+ height: "unsigned long",
+ poster: "url",
+ playsInline: "boolean",
+ },
+ audio: {
+ // HTMLMediaElement
+ src: "url",
+ crossOrigin: {type: "enum", keywords: ["anonymous", "use-credentials"], nonCanon:{"": "anonymous"}, isNullable: true, defaultVal: null, invalidVal: "anonymous"},
+ // As with "keytype", we have no missing value default defined here.
+ preload: {type: "enum", keywords: ["none", "metadata", "auto"], nonCanon: {"": "auto"}, defaultVal: null},
+ autoplay: "boolean",
+ loop: "boolean",
+ controls: "boolean",
+ defaultMuted: {type: "boolean", domAttrName: "muted"}
+ },
+ source: {
+ src: "url",
+ type: "string",
+ srcset: "string",
+ sizes: "string",
+ media: "string"
+ },
+ track: {
+ kind: {type: "enum", keywords: ["subtitles", "captions", "descriptions", "chapters", "metadata"], defaultVal: "subtitles", invalidVal: "metadata"},
+ src: "url",
+ srclang: "string",
+ label: "string",
+ "default": "boolean"
+ },
+ canvas: {
+ width: {type: "unsigned long", defaultVal: 300},
+ height: {type: "unsigned long", defaultVal: 150}
+ },
+ map: {
+ name: "string"
+ },
+ area: {
+ // Conforming
+ alt: "string",
+ coords: "string",
+ shape: "string",
+ target: "string",
+ download: "string",
+ ping: "string",
+ rel: "string",
+ relList: {type: "tokenlist", domAttrName: "rel"},
+ referrerPolicy: {type: "enum", keywords: ["", "no-referrer", "no-referrer-when-downgrade", "same-origin", "origin", "strict-origin", "origin-when-cross-origin", "strict-origin-when-cross-origin", "unsafe-url"]},
+
+ // HTMLHyperlinkElementUtils
+ href: "url",
+
+ // Obsolete
+ noHref: "boolean"
+ },
+};
+
+mergeElements(embeddedElements);
diff --git a/testing/web-platform/tests/html/dom/elements-forms-weekmonth.js b/testing/web-platform/tests/html/dom/elements-forms-weekmonth.js
new file mode 100644
index 0000000000..b13a21d6d8
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements-forms-weekmonth.js
@@ -0,0 +1,42 @@
+var formElements = {
+ input: {
+ // Conforming
+ accept: "string",
+ alt: "string",
+ autocomplete: {type: "string", customGetter: true},
+ defaultChecked: {type: "boolean", domAttrName: "checked"},
+ dirName: "string",
+ disabled: "boolean",
+ // "formAction" has magic hard-coded in reflection.js
+ formAction: "url",
+ formEnctype: {type: "enum", keywords: ["application/x-www-form-urlencoded", "multipart/form-data", "text/plain"], invalidVal: "application/x-www-form-urlencoded"},
+ formMethod: {type: "enum", keywords: ["get", "post"], invalidVal: "get"},
+ formNoValidate: "boolean",
+ formTarget: "string",
+ height: {type: "unsigned long", customGetter: true},
+ max: "string",
+ maxLength: "limited long",
+ min: "string",
+ minLength: "limited long",
+ multiple: "boolean",
+ name: "string",
+ pattern: "string",
+ placeholder: "string",
+ readOnly: "boolean",
+ required: "boolean",
+ // https://html.spec.whatwg.org/#attr-input-size
+ size: {type: "limited unsigned long", defaultVal: 20},
+ src: "url",
+ step: "string",
+ type: {type: "enum", keywords: ["month", "week"],
+ defaultVal: "text"},
+ width: {type: "unsigned long", customGetter: true},
+ defaultValue: {type: "string", domAttrName: "value"},
+
+ // Obsolete
+ align: "string",
+ useMap: "string",
+ },
+};
+
+mergeElements(formElements);
diff --git a/testing/web-platform/tests/html/dom/elements-forms.js b/testing/web-platform/tests/html/dom/elements-forms.js
new file mode 100644
index 0000000000..c43bab9dce
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements-forms.js
@@ -0,0 +1,128 @@
+var formElements = {
+ form: {
+ acceptCharset: {type: "string", domAttrName: "accept-charset"},
+ // "action" has magic hard-coded in reflection.js
+ action: "url",
+ autocomplete: {type: "enum", keywords: ["on", "off"], defaultVal: "on"},
+ enctype: {type: "enum", keywords: ["application/x-www-form-urlencoded", "multipart/form-data", "text/plain"], defaultVal: "application/x-www-form-urlencoded"},
+ encoding: {type: "enum", keywords: ["application/x-www-form-urlencoded", "multipart/form-data", "text/plain"], defaultVal: "application/x-www-form-urlencoded", domAttrName: "enctype"},
+ method: {type: "enum", keywords: ["get", "post", "dialog"], defaultVal: "get"},
+ name: "string",
+ noValidate: "boolean",
+ target: "string",
+ },
+ fieldset: {
+ disabled: "boolean",
+ name: "string",
+ },
+ legend: {
+ // Obsolete
+ align: "string",
+ },
+ label: {
+ htmlFor: {type: "string", domAttrName: "for"},
+ },
+ input: {
+ // Conforming
+ accept: "string",
+ alt: "string",
+ autocomplete: {type: "string", customGetter: true},
+ defaultChecked: {type: "boolean", domAttrName: "checked"},
+ dirName: "string",
+ disabled: "boolean",
+ // "formAction" has magic hard-coded in reflection.js
+ formAction: "url",
+ formEnctype: {type: "enum", keywords: ["application/x-www-form-urlencoded", "multipart/form-data", "text/plain"], invalidVal: "application/x-www-form-urlencoded"},
+ formMethod: {type: "enum", keywords: ["get", "post"], invalidVal: "get"},
+ formNoValidate: "boolean",
+ formTarget: "string",
+ height: {type: "unsigned long", customGetter: true},
+ max: "string",
+ maxLength: "limited long",
+ min: "string",
+ minLength: "limited long",
+ multiple: "boolean",
+ name: "string",
+ pattern: "string",
+ placeholder: "string",
+ readOnly: "boolean",
+ required: "boolean",
+ // https://html.spec.whatwg.org/#attr-input-size
+ size: {type: "limited unsigned long", defaultVal: 20},
+ src: "url",
+ step: "string",
+ type: {type: "enum", keywords: ["hidden", "text", "search", "tel",
+ "url", "email", "password", "date",
+ "time", "datetime-local", "number", "range", "color", "checkbox",
+ "radio", "file", "submit", "image", "reset", "button"], defaultVal:
+ "text"},
+ width: {type: "unsigned long", customGetter: true},
+ defaultValue: {type: "string", domAttrName: "value"},
+
+ // Obsolete
+ align: "string",
+ useMap: "string",
+ },
+ button: {
+ disabled: "boolean",
+ // "formAction" has magic hard-coded in reflection.js
+ formAction: "url",
+ formEnctype: {type: "enum", keywords: ["application/x-www-form-urlencoded", "multipart/form-data", "text/plain"], invalidVal: "application/x-www-form-urlencoded"},
+ formMethod: {type: "enum", keywords: ["get", "post", "dialog"], invalidVal: "get"},
+ formNoValidate: "boolean",
+ formTarget: "string",
+ name: "string",
+ type: {type: "enum", keywords: ["submit", "reset", "button"], defaultVal: "submit"},
+ value: "string"
+ },
+ select: {
+ autocomplete: {type: "string", customGetter: true},
+ disabled: "boolean",
+ multiple: "boolean",
+ name: "string",
+ required: "boolean",
+ size: {type: "unsigned long", defaultVal: 0},
+ },
+ datalist: {},
+ optgroup: {
+ disabled: "boolean",
+ label: "string",
+ },
+ option: {
+ disabled: "boolean",
+ label: {type: "string", customGetter: true},
+ defaultSelected: {type: "boolean", domAttrName: "selected"},
+ value: {type: "string", customGetter: true},
+ },
+ textarea: {
+ autocomplete: {type: "string", customGetter: true},
+ cols: {type: "limited unsigned long with fallback", defaultVal: 20},
+ dirName: "string",
+ disabled: "boolean",
+ maxLength: "limited long",
+ minLength: "limited long",
+ name: "string",
+ placeholder: "string",
+ readOnly: "boolean",
+ required: "boolean",
+ rows: {type: "limited unsigned long with fallback", defaultVal: 2},
+ wrap: "string",
+ },
+ output: {
+ htmlFor: {type: "settable tokenlist", domAttrName: "for" },
+ name: "string",
+ },
+ progress: {
+ max: {type: "limited double", defaultVal: 1.0},
+ },
+ meter: {
+ value: {type: "double", customGetter: true},
+ min: {type: "double", customGetter: true},
+ max: {type: "double", customGetter: true},
+ low: {type: "double", customGetter: true},
+ high: {type: "double", customGetter: true},
+ optimum: {type: "double", customGetter: true},
+ },
+};
+
+mergeElements(formElements);
diff --git a/testing/web-platform/tests/html/dom/elements-grouping.js b/testing/web-platform/tests/html/dom/elements-grouping.js
new file mode 100644
index 0000000000..4c9a29131a
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements-grouping.js
@@ -0,0 +1,57 @@
+var groupingElements = {
+ p: {
+ // Obsolete
+ align: "string",
+ },
+ hr: {
+ // Obsolete
+ align: "string",
+ color: "string",
+ noShade: "boolean",
+ size: "string",
+ width: "string",
+ },
+ pre: {
+ // Obsolete
+ width: "long",
+ },
+ blockquote: {
+ cite: "url",
+ },
+ ol: {
+ // Conforming
+ reversed: "boolean",
+ start: {type: "long", defaultVal: 1},
+ type: "string",
+
+ // Obsolete
+ compact: "boolean",
+ },
+ ul: {
+ // Obsolete
+ compact: "boolean",
+ type: "string",
+ },
+ li: {
+ // Conforming
+ value: "long",
+
+ // Obsolete
+ type: "string",
+ },
+ dl: {
+ // Obsolete
+ compact: "boolean",
+ },
+ dt: {},
+ dd: {},
+ figure: {},
+ figcaption: {},
+ main: {},
+ div: {
+ // Obsolete
+ align: "string",
+ },
+};
+
+mergeElements(groupingElements);
diff --git a/testing/web-platform/tests/html/dom/elements-metadata.js b/testing/web-platform/tests/html/dom/elements-metadata.js
new file mode 100644
index 0000000000..49d7bb25ad
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements-metadata.js
@@ -0,0 +1,50 @@
+var metadataElements = {
+ head: {},
+ title: {},
+ base: {
+ href: {type: "url", customGetter: true},
+ target: "string",
+ },
+ link: {
+ // Conforming
+ href: "url",
+ crossOrigin: {type: "enum", keywords: ["anonymous", "use-credentials"], nonCanon:{"": "anonymous"}, isNullable: true, defaultVal: null, invalidVal: "anonymous"},
+ rel: "string",
+ as: {
+ type: "enum",
+ keywords: ["fetch", "audio", "document", "embed", "font", "image", "manifest", "object", "report", "script", "sharedworker", "style", "track", "video", "worker", "xslt"],
+ defaultVal: "",
+ invalidVal: ""
+ },
+ relList: {type: "tokenlist", domAttrName: "rel"},
+ media: "string",
+ nonce: "string",
+ integrity: "string",
+ hreflang: "string",
+ type: "string",
+ sizes: "settable tokenlist",
+ referrerPolicy: {type: "enum", keywords: ["", "no-referrer", "no-referrer-when-downgrade", "same-origin", "origin", "strict-origin", "origin-when-cross-origin", "strict-origin-when-cross-origin", "unsafe-url"]},
+
+ // Obsolete
+ charset: "string",
+ rev: "string",
+ target: "string",
+ },
+ meta: {
+ // Conforming
+ name: "string",
+ httpEquiv: {type: "string", domAttrName: "http-equiv"},
+ content: "string",
+ media: "string",
+
+ // Obsolete
+ scheme: "string",
+ },
+ style: {
+ media: "string",
+ nonce: "string",
+ type: "string",
+ },
+};
+
+mergeElements(metadataElements);
diff --git a/testing/web-platform/tests/html/dom/elements-misc.js b/testing/web-platform/tests/html/dom/elements-misc.js
new file mode 100644
index 0000000000..1a74c54797
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements-misc.js
@@ -0,0 +1,60 @@
+var miscElements = {
+ // "The root element" section
+ html: {
+ // Obsolete
+ version: "string",
+ },
+
+ // "Scripting" section
+ script: {
+ src: "url",
+ type: "string",
+ noModule: "boolean",
+ charset: "string",
+ // TODO: async attribute (complicated).
+ defer: "boolean",
+ crossOrigin: {type: "enum", keywords: ["anonymous", "use-credentials"], nonCanon:{"": "anonymous"}, isNullable: true, defaultVal: null, invalidVal: "anonymous"},
+ integrity: "string",
+
+ // Obsolete
+ event: "string",
+ htmlFor: {type: "string", domAttrName: "for"},
+ },
+ noscript: {},
+
+ template: {},
+ slot: {
+ name: "string",
+ },
+
+ // "Edits" section
+ ins: {
+ cite: "url",
+ dateTime: "string",
+ },
+ del: {
+ cite: "url",
+ dateTime: "string",
+ },
+
+ // "Interactive elements" section
+ details: {
+ open: "boolean",
+ },
+ summary: {},
+ menu: {
+ // Obsolete
+ compact: "boolean",
+ },
+ dialog: {
+ open: "boolean",
+ },
+
+ // Global attributes should exist even on unknown elements
+ undefinedelement: {
+ enterKeyHint: {type: "enum", keywords: ["enter", "done", "go", "next", "previous", "search", "send"]},
+ inputMode: {type: "enum", keywords: ["none", "text", "tel", "url", "email", "numeric", "decimal", "search"]},
+ },
+};
+
+mergeElements(miscElements);
diff --git a/testing/web-platform/tests/html/dom/elements-obsolete.js b/testing/web-platform/tests/html/dom/elements-obsolete.js
new file mode 100644
index 0000000000..3ef9e9f997
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements-obsolete.js
@@ -0,0 +1,50 @@
+var obsoleteElements = {
+ marquee: {
+ behavior: {
+ type: {
+ type: "enum",
+ keywords: ["scroll", "slide", "alternate"],
+ defaultVal: "scroll"
+ },
+ },
+ bgColor: "string",
+ direction: {
+ type: {
+ type: "enum",
+ keywords: ["up", "right", "down", "left"],
+ defaultVal: "left"
+ },
+ },
+ height: "string",
+ hspace: "unsigned long",
+ scrollAmount: {type: "unsigned long", defaultVal: 6},
+ scrollDelay: {type: "unsigned long", defaultVal: 85},
+ trueSpeed: "boolean",
+ vspace: "unsigned long",
+ width: "string",
+ },
+ frameset: {
+ cols: "string",
+ rows: "string",
+ },
+ frame: {
+ name: "string",
+ scrolling: "string",
+ src: "url",
+ frameBorder: "string",
+ longDesc: "url",
+ noResize: "boolean",
+ marginHeight: {type: "string", treatNullAsEmptyString: true},
+ marginWidth: {type: "string", treatNullAsEmptyString: true},
+ },
+ dir: {
+ compact: "boolean",
+ },
+ font: {
+ color: {type: "string", treatNullAsEmptyString: true},
+ face: "string",
+ size: "string",
+ },
+};
+
+mergeElements(obsoleteElements);
diff --git a/testing/web-platform/tests/html/dom/elements-sections.js b/testing/web-platform/tests/html/dom/elements-sections.js
new file mode 100644
index 0000000000..bbad85e513
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements-sections.js
@@ -0,0 +1,64 @@
+var sectionElements = {
+ body: {
+ // Obsolete
+ text: {type: "string", treatNullAsEmptyString: true},
+ link: {type: "string", treatNullAsEmptyString: true},
+ vLink: {type: "string", treatNullAsEmptyString: true},
+ aLink: {type: "string", treatNullAsEmptyString: true},
+ bgColor: {type: "string", treatNullAsEmptyString: true},
+ background: "string",
+ },
+ article: {},
+ section: {},
+ nav: {},
+ aside: {},
+ h1: {
+ // Obsolete
+ align: "string",
+ },
+ h2: {
+ // Obsolete
+ align: "string",
+ },
+ h3: {
+ // Obsolete
+ align: "string",
+ },
+ h4: {
+ // Obsolete
+ align: "string",
+ },
+ h5: {
+ // Obsolete
+ align: "string",
+ },
+ h6: {
+ // Obsolete
+ align: "string",
+ },
+ hgroup: {},
+ header: {},
+ footer: {},
+ address: {},
+};
+
+mergeElements(sectionElements);
+
+extraTests.push(function() {
+ ReflectionTests.reflects({type: "enum", keywords: ["ltr", "rtl", "auto"]}, "dir", document, "dir", document.documentElement);
+ // TODO: these behave differently if the body element is a frameset. Also
+ // should probably test with multiple bodies.
+ ReflectionTests.reflects({type: "string", treatNullAsEmptyString: true}, "fgColor", document, "text", document.body);
+ ReflectionTests.reflects({type: "string", treatNullAsEmptyString: true}, "linkColor", document, "link", document.body);
+ ReflectionTests.reflects({type: "string", treatNullAsEmptyString: true}, "vlinkColor", document, "vlink", document.body);
+ ReflectionTests.reflects({type: "string", treatNullAsEmptyString: true}, "alinkColor", document, "alink", document.body);
+ ReflectionTests.reflects({type: "string", treatNullAsEmptyString: true}, "bgColor", document, "bgcolor", document.body);
+ // Edge remains RTL if we don't do this, despite removing the attribute
+ document.dir = "ltr";
+ // Don't mess up the colors :)
+ document.documentElement.removeAttribute("dir");
+ var attrs = ["text", "bgcolor", "link", "alink", "vlink"];
+ for (var i = 0; i < attrs.length; i++) {
+ document.body.removeAttribute(attrs[i]);
+ }
+});
diff --git a/testing/web-platform/tests/html/dom/elements-tabular.js b/testing/web-platform/tests/html/dom/elements-tabular.js
new file mode 100644
index 0000000000..88fc8d31ec
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements-tabular.js
@@ -0,0 +1,109 @@
+// Up-to-date as of 2013-04-12.
+var tabularElements = {
+ table: {
+ // Obsolete
+ align: "string",
+ border: "string",
+ frame: "string",
+ rules: "string",
+ summary: "string",
+ width: "string",
+ bgColor: {type: "string", treatNullAsEmptyString: true},
+ cellPadding: {type: "string", treatNullAsEmptyString: true},
+ cellSpacing: {type: "string", treatNullAsEmptyString: true},
+ },
+ caption: {
+ // Obsolete
+ align: "string",
+ },
+ colgroup: {
+ span: {type: "clamped unsigned long", defaultVal: 1, min: 1, max: 1000},
+
+ // Obsolete
+ align: "string",
+ ch: {type: "string", domAttrName: "char"},
+ chOff: {type: "string", domAttrName: "charoff"},
+ vAlign: "string",
+ width: "string",
+ },
+ col: {
+ // Conforming
+ span: {type: "clamped unsigned long", defaultVal: 1, min: 1, max: 1000},
+
+ // Obsolete
+ align: "string",
+ ch: {type: "string", domAttrName: "char"},
+ chOff: {type: "string", domAttrName: "charoff"},
+ vAlign: "string",
+ width: "string",
+ },
+ tbody: {
+ // Obsolete
+ align: "string",
+ ch: {type: "string", domAttrName: "char"},
+ chOff: {type: "string", domAttrName: "charoff"},
+ vAlign: "string",
+ },
+ thead: {
+ // Obsolete
+ align: "string",
+ ch: {type: "string", domAttrName: "char"},
+ chOff: {type: "string", domAttrName: "charoff"},
+ vAlign: "string",
+ },
+ tfoot: {
+ // Obsolete
+ align: "string",
+ ch: {type: "string", domAttrName: "char"},
+ chOff: {type: "string", domAttrName: "charoff"},
+ vAlign: "string",
+ },
+ tr: {
+ // Obsolete
+ align: "string",
+ ch: {type: "string", domAttrName: "char"},
+ chOff: {type: "string", domAttrName: "charoff"},
+ vAlign: "string",
+ bgColor: {type: "string", treatNullAsEmptyString: true},
+ },
+ td: {
+ // HTMLTableCellElement (Conforming)
+ colSpan: {type: "clamped unsigned long", defaultVal: 1, min: 1, max: 1000},
+ rowSpan: {type: "clamped unsigned long", defaultVal: 1, min: 0, max: 65534},
+ headers: "string",
+ scope: {type: "enum", keywords: ["row", "col", "rowgroup", "colgroup"]},
+ abbr: "string",
+
+ // HTMLTableCellElement (Obsolete)
+ align: "string",
+ axis: "string",
+ height: "string",
+ width: "string",
+ ch: {type: "string", domAttrName: "char"},
+ chOff: {type: "string", domAttrName: "charoff"},
+ noWrap: "boolean",
+ vAlign: "string",
+ bgColor: {type: "string", treatNullAsEmptyString: true},
+ },
+ th: {
+ // HTMLTableCellElement (Conforming)
+ colSpan: {type: "clamped unsigned long", defaultVal: 1, min: 1, max: 1000},
+ rowSpan: {type: "clamped unsigned long", defaultVal: 1, min: 0, max: 65534},
+ headers: "string",
+ scope: {type: "enum", keywords: ["row", "col", "rowgroup", "colgroup"]},
+ abbr: "string",
+
+ // HTMLTableCellElement (Obsolete)
+ align: "string",
+ axis: "string",
+ height: "string",
+ width: "string",
+ ch: {type: "string", domAttrName: "char"},
+ chOff: {type: "string", domAttrName: "charoff"},
+ noWrap: "boolean",
+ vAlign: "string",
+ bgColor: {type: "string", treatNullAsEmptyString: true},
+ },
+};
+
+mergeElements(tabularElements);
diff --git a/testing/web-platform/tests/html/dom/elements-text.js b/testing/web-platform/tests/html/dom/elements-text.js
new file mode 100644
index 0000000000..f71df48ee3
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements-text.js
@@ -0,0 +1,63 @@
+// Up-to-date as of 2013-04-19.
+var textElements = {
+ a: {
+ // Conforming
+ target: "string",
+ download: "string",
+ ping: "string",
+ rel: "string",
+ relList: {type: "tokenlist", domAttrName: "rel"},
+ hreflang: "string",
+ type: "string",
+ referrerPolicy: {type: "enum", keywords: ["", "no-referrer", "no-referrer-when-downgrade", "same-origin", "origin", "strict-origin", "origin-when-cross-origin", "strict-origin-when-cross-origin", "unsafe-url"]},
+
+ // HTMLHyperlinkElementUtils
+ href: "url",
+
+ // Obsolete
+ coords: "string",
+ charset: "string",
+ name: "string",
+ rev: "string",
+ shape: "string",
+ },
+ em: {},
+ strong: {},
+ small: {},
+ s: {},
+ cite: {},
+ q: {
+ cite: "url",
+ },
+ dfn: {},
+ abbr: {},
+ ruby: {},
+ rt: {},
+ rp: {},
+ data: {
+ value: "string",
+ },
+ time: {
+ dateTime: "string",
+ },
+ code: {},
+ var: {},
+ samp: {},
+ kbd: {},
+ sub: {},
+ sup: {},
+ i: {},
+ b: {},
+ u: {},
+ mark: {},
+ bdi: {},
+ bdo: {},
+ span: {},
+ br: {
+ // Obsolete
+ clear: "string",
+ },
+ wbr: {},
+};
+
+mergeElements(textElements);
diff --git a/testing/web-platform/tests/html/dom/elements/elements-in-the-dom/historical.html b/testing/web-platform/tests/html/dom/elements/elements-in-the-dom/historical.html
new file mode 100644
index 0000000000..078ce29cc0
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/elements-in-the-dom/historical.html
@@ -0,0 +1,24 @@
+<!doctype html>
+<title>Historical HTMLElement features</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<body>
+<script>
+[
+ // https://github.com/whatwg/html/commit/389ec2620d89e9480ef8847bf016abdfa92427bc
+ "commandType",
+ "commandLabel",
+ "commandIcon",
+ "commandHidden",
+ "commandDisabled",
+ "commandChecked",
+ "commandTriggers",
+ // https://github.com/whatwg/html/pull/2402
+ "dropzone",
+].forEach(function(member) {
+ test(function() {
+ assert_false(member in document.body);
+ assert_false(member in document.createElement('div'));
+ }, 'HTMLElement member must be nuked: ' + member);
+});
+</script>
diff --git a/testing/web-platform/tests/html/dom/elements/elements-in-the-dom/unknown-element.html b/testing/web-platform/tests/html/dom/elements/elements-in-the-dom/unknown-element.html
new file mode 100644
index 0000000000..16a53e5e88
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/elements-in-the-dom/unknown-element.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<title>HTMLUnknownElement</title>
+<link rel="author" title="Ms2ger" href="mailto:ms2ger@gmail.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#htmlunknownelement">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<script>
+[
+ "applet",
+ "attachment",
+ "layer",
+ "nolayer",
+ "xxx"
+].forEach(name => {
+ test(() => {
+ const elt = document.createElement("xxx");
+ assert_true(window.HTMLUnknownElement && elt instanceof HTMLUnknownElement, "not an instance of HTMLUnknownElement");
+ assert_true(window.HTMLSpanElement && !(elt instanceof HTMLSpanElement), "an instance of HTMLSpanElement");
+ }, `<${name}> is an HTMLUnknownElement`);
+});
+</script>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/.htaccess b/testing/web-platform/tests/html/dom/elements/global-attributes/.htaccess
new file mode 100644
index 0000000000..94e9a4f190
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/.htaccess
@@ -0,0 +1,16 @@
+AddType 'text/html; charset=UTF-8' html
+<Files 'the-lang-attribute-003.html'>
+AddLanguage 'ko' .html
+</Files>
+<Files 'the-lang-attribute-005.html'>
+AddLanguage 'zh' .html
+</Files>
+<Files 'the-lang-attribute-006.html'>
+AddLanguage 'zh' .html
+</Files>
+<Files 'the-lang-attribute-009.html'>
+AddLanguage 'ko' .html
+</Files>
+<Files 'the-lang-attribute-011.html'>
+AddLanguage 'ko,zh,ja' .html
+</Files>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/classlist-nonstring.html b/testing/web-platform/tests/html/dom/elements/global-attributes/classlist-nonstring.html
new file mode 100644
index 0000000000..044f5e8b1b
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/classlist-nonstring.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<title>classList: non-string contains</title>
+<link rel="author" title="Ms2ger" href="mailto:ms2ger@gmail.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#classes">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#domtokenlist">
+<link rel="help" href="https://webidl.spec.whatwg.org/#es-DOMString">
+<link rel="help" href="http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-262.pdf#page=57">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<div id="test">
+<ul>
+<li class=undefined>
+<li class=null>
+<li class=0>
+<li class=NaN>
+<li class=Infinity>
+<li class=-Infinity>
+</ul>
+<script>
+var items = document.getElementById("test")
+ .getElementsByTagName("li");
+var tests = [undefined, null, -0, +0, NaN, +Infinity, -Infinity];
+var results = [
+ [true, false, false, false, false, false, false], // "undefined"
+ [false, true, false, false, false, false, false], // "null"
+ [false, false, true, true, false, false, false], // "0"
+ [false, false, false, false, true, false, false], // "NaN"
+ [false, false, false, false, false, true, false], // "Infinity"
+ [false, false, false, false, false, false, true ] // "-Infinity"
+];
+</script>
+</div>
+<script>
+test(function() {
+ for (var i = 0, il = items.length; i < il; ++i) {
+ test(function() {
+ for (var j = 0, jl = tests.length; j < jl; ++j) {
+ assert_equals(items[i].classList.contains(tests[j]), results[i][j]);
+ }
+ })
+ }
+})
+</script>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/custom-attrs.html b/testing/web-platform/tests/html/dom/elements/global-attributes/custom-attrs.html
new file mode 100644
index 0000000000..a1e41dac25
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/custom-attrs.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>Element Custom Attributes</title>
+ <link rel="author" title="Bruno de Oliveira Abinader" href="mailto:bruno.d@partner.samsung.com">
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-dataset">
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#xml">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/dom/nodes/attributes.js"></script>
+ </head>
+ <body>
+ <h1>Element Custom Attributes</h1>
+ <div id="log"></div>
+ <script>
+ test(function() {
+ var div = document.createElement("div");
+ div.setAttributeNS("foo", "data-my-custom-attr", "first");
+ div.setAttributeNS("bar", "data-my-custom-attr", "second");
+ div.dataset.myCustomAttr = "third";
+
+ assert_equals(div.attributes.length, 3);
+ attributes_are(div, [["data-my-custom-attr", "first", "foo"],
+ ["data-my-custom-attr", "second", "bar"],
+ ["data-my-custom-attr", "third", null]]);
+ }, "Setting an Element's dataset property should not interfere with namespaced attributes with same name");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/data_unicode_attr.html b/testing/web-platform/tests/html/dom/elements/global-attributes/data_unicode_attr.html
new file mode 100644
index 0000000000..17077dafd1
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/data_unicode_attr.html
@@ -0,0 +1,22 @@
+<!DOCTYPE HTML>
+<meta charset="utf-8">
+<title>HTML Test: dataset attribute</title>
+<link rel="author" title="ElegantPig" href="mailto:neil.ep@hotmail.com">
+<link rel="author" title="Xiaojun Wu" href="mailto:xiaojunx.a.wu@intel.com">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id='log'></div>
+<div id="d1" data-weapons="laser 2" data-中文属性="中文"></div>
+<script>
+
+test(function() {
+ var d1 = document.getElementById("d1");
+ assert_equals(d1.dataset.weapons, "laser 2");
+}, "dataset - SBCS");
+
+test(function() {
+ var d1 = document.getElementById("d1");
+ assert_equals(d1.dataset.中文属性, "中文");
+}, "dataset - UNICODE");
+
+</script>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dataset-binding.window.js b/testing/web-platform/tests/html/dom/elements/global-attributes/dataset-binding.window.js
new file mode 100644
index 0000000000..e0e85677d1
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dataset-binding.window.js
@@ -0,0 +1,45 @@
+[9, "x"].forEach(function(key) {
+ test(function() {
+ var element = document.createElement("div");
+ var dataset = element.dataset;
+
+ var value = "value for " + this.name;
+
+ assert_equals(dataset[key], undefined);
+
+ element.setAttribute("data-" + key, value);
+ assert_equals(element.getAttribute("data-" + key), value);
+ assert_equals(dataset[key], value);
+
+ var propdesc = Object.getOwnPropertyDescriptor(dataset, key);
+ assert_not_equals(propdesc, undefined);
+ assert_equals(propdesc.value, value);
+ assert_true(propdesc.writable);
+ assert_true(propdesc.enumerable);
+ assert_true(propdesc.configurable);
+ }, "Getting property descriptor for key " + key);
+
+ test(function() {
+ var element = document.createElement("div");
+ var dataset = element.dataset;
+
+ var proto = "proto getter for " + this.name;
+ var calledSetter = [];
+ Object.defineProperty(DOMStringMap.prototype, key, {
+ "get": function() { return proto; },
+ "set": this.unreached_func("Should not call [[Set]] on prototype"),
+ "configurable": true,
+ });
+ this.add_cleanup(function() {
+ delete DOMStringMap.prototype[key];
+ });
+
+ var value = "value for " + this.name;
+
+ assert_equals(dataset[key], proto);
+ assert_equals(element.getAttribute("data-" + key), null);
+ assert_equals(dataset[key] = value, value);
+ assert_equals(dataset[key], value);
+ assert_equals(element.getAttribute("data-" + key), value);
+ }, "Setting property for key " + key + " with accessor property on prototype");
+});
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dataset-delete.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dataset-delete.html
new file mode 100644
index 0000000000..1440118f6d
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dataset-delete.html
@@ -0,0 +1,54 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>Dataset - Delete</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+ <body>
+ <h1>Dataset - Delete</h1>
+ <div id="log"></div>
+ <script>
+ function testDelete(attr, prop)
+ {
+ var d = document.createElement("div");
+ d.setAttribute(attr, "value");
+ delete d.dataset[prop];
+ return d.hasAttribute(attr) === false && d.getAttribute(attr) != "value";
+ }
+
+ function testDeleteNoAdd(prop)
+ {
+ var d = document.createElement("div");
+ delete d.dataset[prop];
+ return true;
+ }
+
+ test(function() { assert_true(testDelete('data-foo', 'foo')); },
+ "Deleting element.dataset['foo'] should also remove an attribute with name 'data-foo' should it exist.");
+ test(function() { assert_true(testDelete('data-foo-bar', 'fooBar')); },
+ "Deleting element.dataset['fooBar'] should also remove an attribute with name 'data-foo-bar' should it exist.");
+ test(function() { assert_true(testDelete('data--', '-')); },
+ "Deleting element.dataset['-'] should also remove an attribute with name 'data--' should it exist.");
+ test(function() { assert_true(testDelete('data--foo', 'Foo')); },
+ "Deleting element.dataset['Foo'] should also remove an attribute with name 'data--foo' should it exist.");
+ test(function() {
+ var d = document.createElement("div");
+ d.setAttribute('data--foo', "value");
+ assert_equals(d.dataset['-foo'], undefined);
+ assert_false('-foo' in d.dataset);
+ delete d.dataset['-foo'];
+ assert_true(d.hasAttribute('data--foo'));
+ assert_equals(d.getAttribute('data--foo'), "value");
+ }, "Deleting element.dataset['-foo'] should not remove an attribute with name 'data--foo' should it exist.");
+ test(function() { assert_true(testDelete('data---foo', '-Foo')); },
+ "Deleting element.dataset['-Foo'] should also remove an attribute with name 'data---foo' should it exist.");
+ test(function() { assert_true(testDelete('data-', '')); },
+ "Deleting element.dataset[''] should also remove an attribute with name 'data-' should it exist.");
+ test(function() { assert_true(testDelete('data-\xE0', '\xE0')); },
+ "Deleting element.dataset['\xE0'] should also remove an attribute with name 'data-\xE0' should it exist.");
+ test(function() { assert_true(testDeleteNoAdd('foo')); },
+ "Deleting element.dataset['foo'] should not throw if even if the element does now have an attribute with the name data-foo.");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dataset-enumeration.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dataset-enumeration.html
new file mode 100644
index 0000000000..4b1063379c
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dataset-enumeration.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>Dataset - Enumeration</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+ <body>
+ <h1>Dataset - Enumeration</h1>
+ <div id="log"></div>
+ <script>
+ function testEnumeration(array)
+ {
+ var d = document.createElement("div");
+ for (var i = 0; i < array.length; ++i)
+ d.setAttribute(array[i], "value");
+
+ var count = 0;
+ for (var item in d.dataset)
+ count++;
+
+ return count;
+ }
+
+ test(function() { assert_equals(testEnumeration(['data-foo', 'data-bar', 'data-baz']), 3); },
+ "A dataset should be enumeratable.");
+ test(function() { assert_equals(testEnumeration(['data-foo', 'data-bar', 'dataFoo']), 2); },
+ "Only attributes who qualify as dataset properties should be enumeratable in the dataset.");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dataset-get.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dataset-get.html
new file mode 100644
index 0000000000..ab4078c4fb
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dataset-get.html
@@ -0,0 +1,57 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>Dataset - Get</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+ <body>
+ <h1>Dataset - Get</h1>
+ <div id="log"></div>
+ <script>
+ function testGet(attr, expected)
+ {
+ var d = document.createElement("div");
+ d.setAttribute(attr, "value");
+ return d.dataset[expected] == "value";
+ }
+
+ test(function() { assert_true(testGet('data-foo', 'foo')); },
+ "Getting element.dataset['foo'] should return the value of element.getAttribute('data-foo')'");
+ test(function() { assert_true(testGet('data-foo-bar', 'fooBar')); },
+ "Getting element.dataset['fooBar'] should return the value of element.getAttribute('data-foo-bar')'");
+ test(function() { assert_true(testGet('data--', '-')); },
+ "Getting element.dataset['-'] should return the value of element.getAttribute('data--')'");
+ test(function() { assert_true(testGet('data--foo', 'Foo')); },
+ "Getting element.dataset['Foo'] should return the value of element.getAttribute('data--foo')'");
+ test(function() { assert_true(testGet('data---foo', '-Foo')); },
+ "Getting element.dataset['-Foo'] should return the value of element.getAttribute('data---foo')'");
+ test(function() { assert_true(testGet('data-Foo', 'foo')); },
+ "Getting element.dataset['foo'] should return the value of element.getAttribute('data-Foo')'");
+ test(function() { assert_true(testGet('data-', '')); },
+ "Getting element.dataset[''] should return the value of element.getAttribute('data-')'");
+ test(function() { assert_true(testGet('data-\xE0', '\xE0')); },
+ "Getting element.dataset['\xE0'] should return the value of element.getAttribute('data-\xE0')'");
+ test(function() { assert_true(testGet('data-to-string', 'toString')); },
+ "Getting element.dataset['toString'] should return the value of element.getAttribute('data-to-string')'");
+
+ function matchesNothingInDataset(attr)
+ {
+ var d = document.createElement("div");
+ d.setAttribute(attr, "value");
+
+ if (!d.dataset)
+ return false;
+
+ var count = 0;
+ for (var item in d.dataset)
+ count++;
+ return count == 0;
+ }
+
+ test(function() { assert_true(matchesNothingInDataset('dataFoo')); },
+ "Tests that an attribute named dataFoo does not make an entry in the dataset DOMStringMap.");
+
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dataset-prototype.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dataset-prototype.html
new file mode 100644
index 0000000000..6b16618461
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dataset-prototype.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>Dataset - element.dataset is an instance of DOMStringMap</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+ <body>
+ <h1>Dataset - element.dataset is an instance of DOMStringMap</h1>
+ <div id="log"></div>
+ <script>
+ test(function() { assert_true(document.createElement("div").dataset instanceof window.DOMStringMap); },
+ "An elements dataset property is an instance of a DOMStringMap");
+ test(function() {
+ var dataset = document.createElement("div").dataset;
+ assert_true("toString" in dataset, '"toString" in dataset');
+ assert_equals(dataset.toString, Object.prototype.toString);
+ assert_false("expando" in dataset, '"expando" in dataset');
+ assert_equals(dataset.expando, undefined);
+ Object.prototype.expando = 42;
+ assert_true("expando" in dataset, '"expando" in dataset');
+ assert_equals(dataset.expando, 42);
+ }, "Properties on Object.prototype should shine through.");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dataset-set.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dataset-set.html
new file mode 100644
index 0000000000..a5bc177f50
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dataset-set.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>Dataset - Set</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+ <body>
+ <h1>Dataset - Set</h1>
+ <div id="log"></div>
+ <script>
+ function testSet(prop, expected)
+ {
+ var d = document.createElement("div");
+ d.dataset[prop] = "value";
+ return d.getAttribute(expected) == "value";
+ }
+
+ test(function() { assert_true(testSet('foo', 'data-foo')); },
+ "Setting element.dataset['foo'] should also change the value of element.getAttribute('data-foo')");
+ test(function() { assert_true(testSet('fooBar', 'data-foo-bar')); },
+ "Setting element.dataset['fooBar'] should also change the value of element.getAttribute('data-foo-bar')");
+ test(function() { assert_true(testSet('-', 'data--')); },
+ "Setting element.dataset['-'] should also change the value of element.getAttribute('data--')");
+ test(function() { assert_true(testSet('Foo', 'data--foo')); },
+ "Setting element.dataset['Foo'] should also change the value of element.getAttribute('data--foo')");
+ test(function() { assert_true(testSet('-Foo', 'data---foo')); },
+ "Setting element.dataset['-Foo'] should also change the value of element.getAttribute('data---foo')");
+ test(function() { assert_true(testSet('', 'data-')); },
+ "Setting element.dataset[''] should also change the value of element.getAttribute('data-')");
+ test(function() { assert_true(testSet('\xE0', 'data-\xE0')); },
+ "Setting element.dataset['\xE0'] should also change the value of element.getAttribute('data-\xE0')");
+ test(function() { assert_throws_dom('SYNTAX_ERR', function() { testSet('-foo', 'dummy') }); },
+ "Setting element.dataset['-foo'] should throw a SYNTAX_ERR");
+ test(function() { assert_throws_dom('INVALID_CHARACTER_ERR', function() { testSet('foo\x20', 'dummy') }); },
+ "Setting element.dataset['foo\x20'] should throw an INVALID_CHARACTER_ERR");
+ test(function() { assert_throws_dom('INVALID_CHARACTER_ERR', function() { testSet('\u037Efoo', 'dummy') }); },
+ "Setting element.dataset['\u037Efoo'] should throw an INVALID_CHARACTER_ERR");
+ test(function() { assert_true(testSet('\u0BC6foo', 'data-\u0BC6foo')); },
+ "Setting element.dataset['\u0BC6foo'] should also change the value of element.getAttribute('\u0BC6foo')");
+
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dataset.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dataset.html
new file mode 100644
index 0000000000..a4a16d014d
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dataset.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<title>dataset: should exist and work on HTML and SVG elements, but not random elements</title>
+<link rel="author" title="Ms2ger" href="mailto:ms2ger@gmail.com">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<script>
+var div = document.createElement("div");
+test(function() {
+ assert_true(div.dataset instanceof DOMStringMap);
+}, "HTML elements should have a .dataset");
+test(function() {
+ assert_false("foo" in div.dataset);
+ assert_equals(div.dataset.foo, undefined);
+}, "Should return 'undefined' before setting an attribute")
+test(function() {
+ div.setAttribute("data-foo", "value");
+ assert_true("foo" in div.dataset);
+ assert_equals(div.dataset.foo, "value");
+}, "Should return 'value' if that's the value")
+test(function() {
+ div.setAttribute("data-foo", "");
+ assert_true("foo" in div.dataset);
+ assert_equals(div.dataset.foo, "");
+}, "Should return the empty string if that's the value")
+test(function() {
+ div.removeAttribute("data-foo");
+ assert_false("foo" in div.dataset);
+ assert_equals(div.dataset.foo, undefined);
+}, "Should return 'undefined' after removing an attribute")
+test(function() {
+ assert_equals(document.createElementNS("test", "test").dataset, undefined);
+}, "Should not have a .dataset on random elements");
+test(function() {
+ var svg = document.createElementNS("http://www.w3.org/2000/svg", "svg")
+ assert_true(svg.dataset instanceof DOMStringMap);
+}, "SVG elements should have a .dataset");
+</script>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir-assorted.window.js b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-assorted.window.js
new file mode 100644
index 0000000000..0d4e4b82d9
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-assorted.window.js
@@ -0,0 +1,115 @@
+test(() => {
+ assert_true(document.documentElement.matches(":dir(ltr)"));
+}, "Root element has a direction");
+
+test(() => {
+ const ele = document.createElement("foobar");
+ assert_true(ele.matches(":dir(ltr)"));
+}, "Element outside the document tree has a direction");
+
+test(() => {
+ const ele = document.createElementNS("foobar", "foobar");
+ assert_true(ele.matches(":dir(ltr)"));
+}, "Non-HTML element outside the document tree has a direction");
+
+test(() => {
+ const ele = document.createElement("foobar");
+ ele.dir = "rtl";
+ const ele2 = document.createElement("foobar");
+ ele.append(ele2);
+ assert_true(ele2.matches(":dir(rtl)"));
+ ele.dir = "ltr";
+ assert_true(ele2.matches(":dir(ltr)"), "direction after dynamic change");
+}, "Element without direction has parent element direction");
+
+test(() => {
+ const ele = document.createElement("foobar");
+ ele.dir = "rtl";
+ const ele2 = document.createElementNS("foobar", "foobar");
+ ele.append(ele2);
+ assert_true(ele2.matches(":dir(rtl)"));
+ ele.dir = "ltr";
+ assert_true(ele2.matches(":dir(ltr)"), "direction after dynamic change");
+}, "Non-HTML element without direction has parent element direction");
+
+test(() => {
+ let container1 = document.createElement("div");
+ document.body.appendChild(container1);
+ let container2 = document.createElement("div");
+
+ for (let container of [container1, container2]) {
+ container.dir = "rtl";
+ let e = document.createElement("div");
+ assert_true(e.matches(":dir(ltr)"));
+ container.appendChild(e);
+ assert_false(e.matches(":dir(ltr)"));
+ e.remove();
+ assert_true(e.matches(":dir(ltr)"));
+ }
+
+ container1.remove();
+}, "dir inheritance is correct after insertion and removal from document");
+
+test(() => {
+ const ele = document.createElement("foobar");
+ ele.dir = "auto";
+ const ele2 = document.createElementNS("foobar", "foobar");
+ ele.append(ele2);
+ const text = document.createTextNode("\u05D0\u05D1\u05D2");
+ ele2.append(text);
+ assert_true(ele.matches(":dir(rtl)"), "is RTL before change");
+ assert_true(ele2.matches(":dir(rtl)"), "child is RTL before change");
+ text.data = "ABC";
+ assert_true(ele.matches(":dir(ltr)"), "is LTR after change");
+ assert_true(ele2.matches(":dir(ltr)"), "child is LTR after change");
+}, "Non-HTML element text contents influence dir=auto");
+
+test(() => {
+ const e1 = document.createElement("div");
+ e1.dir = "auto";
+ const e2 = document.createElement("div");
+ e2.dir = "auto";
+ e2.innerText = "A";
+ e1.append(e2);
+ assert_true(e1.matches(":dir(ltr)"), "parent is LTR before changes");
+ assert_true(e2.matches(":dir(ltr)"), "child is LTR before changes");
+ e2.removeAttribute("dir");
+ assert_true(e1.matches(":dir(ltr)"), "parent is LTR after removing dir attribute on child");
+ assert_true(e2.matches(":dir(ltr)"), "child is LTR after removing dir attribute on child");
+ e2.firstChild.data = "\u05D0";
+ assert_false(e1.matches(":dir(ltr)"), "parent is RTL after changing text in child");
+ assert_false(e2.matches(":dir(ltr)"), "child is RTL after changing text in child");
+}, "text changes apply to dir=auto on further ancestor after removing dir=auto from closer ancestor");
+
+for (const bdi_test of [
+ { markup: "<bdi dir=ltr>A</bdi>", expected: "ltr", desc: "dir=ltr with LTR contents" },
+ { markup: "<bdi dir=ltr>\u05d0</bdi>", expected: "ltr", desc: "dir=ltr with RTL contents" },
+ { markup: "<bdi dir=ltr></bdi>", expected: "ltr", desc: "dir=ltr empty" },
+ { markup: "<bdi dir=rtl>A</bdi>", expected: "rtl", desc: "dir=rtl with LTR contents" },
+ { markup: "<bdi dir=rtl>\u05d0</bdi>", expected: "rtl", desc: "dir=rtl with RTL contents" },
+ { markup: "<bdi dir=rtl></bdi>", expected: "rtl", desc: "dir=rtl empty" },
+ { markup: "<bdi dir=auto>A</bdi>", expected: "ltr", desc: "dir=auto with LTR contents" },
+ { markup: "<bdi dir=auto>\u05d0</bdi>", expected: "rtl", desc: "dir=auto with RTL contents" },
+ { markup: "<bdi dir=auto></bdi>", expected: "parent", desc: "dir=auto empty" },
+ { markup: "<bdi>A</bdi>", expected: "ltr", desc: "no dir attribute with LTR contents" },
+ { markup: "<bdi>\u05d0</bdi>", expected: "rtl", desc: "no dir attribute with RTL contents" },
+ { markup: "<bdi></bdi>", expected: "parent", desc: "no dir attribute empty" },
+]) {
+ for (const parent_dir of [ "ltr", "rtl" ]) {
+ test(() => {
+ const parent_element = document.createElement("div");
+ parent_element.dir = parent_dir;
+ document.body.appendChild(parent_element);
+ parent_element.innerHTML = bdi_test.markup;
+ const bdi_element = parent_element.querySelector("bdi");
+ let expected = bdi_test.expected;
+ if (expected == "parent") {
+ expected = parent_dir;
+ }
+ const not_expected = (expected == "ltr") ? "rtl" : "ltr";
+ assert_true(bdi_element.matches(`:dir(${expected})`));
+ assert_false(bdi_element.matches(`:dir(${not_expected})`));
+ parent_element.remove();
+ }, `directionality of bdi elements: ${bdi_test.desc} in ${parent_dir} parent`);
+ }
+}
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir-auto-div-append-child.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-auto-div-append-child.html
new file mode 100644
index 0000000000..e69f64b3a9
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-auto-div-append-child.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<title>HTML Test: input with dir=auto, then append a child</title>
+<meta charset="utf-8">
+<meta name="assert" content="The dir global attribute set to auto applies when a child is appended" />
+<link rel="author" title="HTML5 bidi test WG" href="mailto:japhet@chromium.org" />
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#the-dir-attribute" />
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<body>
+<div id="div" dir="auto"></div>
+<script>
+test(() => {
+ assert_equals(getComputedStyle(div).direction, "ltr");
+ div.appendChild(document.createTextNode('اختبر SomeText'));
+ assert_equals(getComputedStyle(div).direction, "rtl");
+}, 'dir auto: updates on appendChild');
+</script>
+</body>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir-auto-dynamic-changes.window.js b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-auto-dynamic-changes.window.js
new file mode 100644
index 0000000000..a0cf4aae7b
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-auto-dynamic-changes.window.js
@@ -0,0 +1,276 @@
+function setup_tree(light_tree, shadow_tree) {
+ let body = document.body;
+ let old_length = body.childNodes.length;
+ body.insertAdjacentHTML("beforeend", light_tree.trim());
+ if (body.childNodes.length != old_length + 1) {
+ throw "unexpected markup";
+ }
+ let result = body.lastChild;
+ if (shadow_tree) {
+ let shadow = result.querySelector("#root").attachShadow({mode: "open"});
+ shadow.innerHTML = shadow_tree.trim();
+ return [result, shadow];
+ }
+ return result;
+}
+
+test(t => {
+ let a = setup_tree(`
+ <div id="a" dir="auto">
+ <div id="b"></div>
+ hello
+ </div>
+ `);
+
+ let acs = getComputedStyle(a);
+ assert_true(a.matches(":dir(ltr)"), ":dir(ltr) matches before insertion");
+ assert_false(a.matches(":dir(rtl)"), ":dir(rtl) does not match before insertion");
+ assert_equals(acs.direction, "ltr", "CSSdirection before insertion");
+ b.innerHTML = "\u05D0";
+ assert_false(a.matches(":dir(ltr)"), ":dir(ltr) does not match after insertion");
+ assert_true(a.matches(":dir(rtl)"), ":dir(rtl) matches after insertion");
+ assert_equals(acs.direction, "rtl", "CSSdirection after insertion");
+
+ a.remove();
+}, "dynamic insertion of RTL text in a child element");
+
+test(() => {
+ let div_rtlchar = document.createElement("div");
+ div_rtlchar.innerHTML = "\u05D0";
+
+ let container1 = document.createElement("div");
+ document.body.appendChild(container1);
+ let container2 = document.createElement("div");
+
+ for (let container of [container1, container2]) {
+ container.dir = "auto";
+ assert_true(container.matches(":dir(ltr)"));
+ container.appendChild(div_rtlchar);
+ assert_false(container.matches(":dir(ltr)"));
+ div_rtlchar.remove();
+ assert_true(container.matches(":dir(ltr)"));
+ }
+
+ container1.remove();
+}, "dir=auto changes for content insertion and removal, in and out of document");
+
+test(() => {
+ let tree, shadow;
+ [tree, shadow] = setup_tree(`
+ <div>
+ <div id="root">
+ <span id="l">A</span>
+ <span id="r">\u05D0</span>
+ </div>
+ </div>
+ `, `
+ <slot id="one" name="one" dir="auto">\u05D0</slot>
+ <slot id="two" dir="auto"></slot>
+ `);
+
+ let one = shadow.getElementById("one");
+ let two = shadow.getElementById("two");
+ let l = tree.querySelector("#l");
+ let r = tree.querySelector("#r");
+ assert_false(one.matches(":dir(ltr)"), "#one while empty");
+ assert_true(two.matches(":dir(ltr)"), "#two with both spans");
+ l.slot = "one";
+ assert_true(one.matches(":dir(ltr)"), "#one with LTR child span");
+ assert_false(two.matches(":dir(ltr)"), "#two with RTL child span");
+ r.slot = "one";
+ assert_true(one.matches(":dir(ltr)"), "#one with both child spans");
+ assert_true(two.matches(":dir(ltr)"), "#two while empty");
+ l.slot = "";
+ assert_false(one.matches(":dir(ltr)"), "#one with RTL child span");
+ assert_true(two.matches(":dir(ltr)"), "#two with LTR child span");
+
+ tree.remove();
+}, "dir=auto changes for slot reassignment");
+
+test(() => {
+ let tree, shadow;
+ [tree, shadow] = setup_tree(`
+ <div dir=auto>
+ <div id=root>
+ <div id=text>A</div>
+ </div>
+ </div>
+ `, `
+ <div dir=ltr>
+ <slot id=slot dir=auto></slot>
+ </div>
+ `);
+
+ let text = tree.querySelector("#text");
+ let slot = shadow.querySelector("#slot");
+
+ assert_true(tree.matches(":dir(ltr)"), "node tree ancestor before first text change");
+ assert_true(slot.matches(":dir(ltr)"), "slot before first text change");
+ text.innerText = "\u05D0";
+ assert_false(tree.matches(":dir(ltr)"), "node tree ancestor after first text change");
+ assert_false(slot.matches(":dir(ltr)"), "slot after first text change");
+ tree.dir = "rtl";
+ assert_false(tree.matches(":dir(ltr)"), "node tree ancestor before second text change");
+ assert_false(slot.matches(":dir(ltr)"), "slot before second text change");
+ text.innerText = "A";
+ assert_false(tree.matches(":dir(ltr)"), "node tree ancestor after second text change");
+ assert_true(slot.matches(":dir(ltr)"), "slot after second text change");
+ slot.dir = "ltr";
+ assert_false(tree.matches(":dir(ltr)"), "node tree ancestor before third text change");
+ assert_true(slot.matches(":dir(ltr)"), "slot before third text change");
+ text.innerText = "\u05D0";
+ assert_false(tree.matches(":dir(ltr)"), "node tree ancestor after third text change");
+ assert_true(slot.matches(":dir(ltr)"), "slot after third text change");
+ slot.dir = "auto";
+ tree.dir = "auto";
+ assert_false(tree.matches(":dir(ltr)"), "node tree ancestor after fourth text change");
+ assert_false(slot.matches(":dir(ltr)"), "slot after fourth text change");
+ text.innerText = "A";
+ assert_true(tree.matches(":dir(ltr)"), "node tree ancestor before fourth text change");
+ assert_true(slot.matches(":dir(ltr)"), "slot before fourth text change");
+ slot.dir = "rtl";
+ assert_true(tree.matches(":dir(ltr)"), "node tree ancestor before fifth text change");
+ assert_false(slot.matches(":dir(ltr)"), "slot before fifth text change");
+ text.innerText = "\u05D0";
+ assert_false(tree.matches(":dir(ltr)"), "node tree ancestor before fifth text change");
+ assert_false(slot.matches(":dir(ltr)"), "slot before fifth text change");
+
+ tree.remove();
+}, "text changes affecting both slot and ancestor with dir=auto");
+
+test(() => {
+ let tree = setup_tree(`
+ <div dir="auto">
+ <span id="a1">A</span>
+ <span id="aleph1">\u05D0</span>
+ <span id="a2">A</span>
+ <span id="aleph2">\u05D0</span>
+ </div>
+ `);
+
+ let a1 = tree.querySelector("#a1");
+ let aleph1 = tree.querySelector("#aleph1");
+ assert_true(tree.matches(":dir(ltr)"), "initial state");
+ assert_false(tree.matches(":dir(rtl)"), "initial state");
+ a1.dir = "ltr";
+ assert_false(tree.matches(":dir(ltr)"), "after change 1");
+ a1.dir = "invalid";
+ assert_true(tree.matches(":dir(ltr)"), "after change 2");
+ a1.dir = "rtl";
+ assert_false(tree.matches(":dir(ltr)"), "after change 3");
+ a1.removeAttribute("dir");
+ assert_true(tree.matches(":dir(ltr)"), "after change 4");
+ a1.dir = "invalid";
+ assert_true(tree.matches(":dir(ltr)"), "after change 5");
+ a1.dir = "rtl";
+ assert_false(tree.matches(":dir(ltr)"), "after change 6");
+ aleph1.dir = "auto";
+ assert_true(tree.matches(":dir(ltr)"), "after change 7");
+ aleph1.dir = "invalid";
+ assert_false(tree.matches(":dir(ltr)"), "after change 8");
+
+ tree.remove();
+}, "dynamic changes to subtrees excluded as a result of the dir attribute");
+
+test(() => {
+ let tree = setup_tree(`
+ <div dir="auto">
+ <!-- element goes here -->
+ </div>
+ `);
+
+ let element = document.createElementNS("namespace", "element");
+ let text = document.createTextNode("\u05D0");
+ element.appendChild(text);
+ tree.prepend(element);
+ assert_not_equals(element.namespaceURI, tree.namespaceURI);
+
+ assert_true(tree.matches(":dir(rtl)"), "initial state");
+ assert_false(tree.matches(":dir(ltr)"), "initial state");
+ text.data = "A";
+ assert_true(tree.matches(":dir(ltr)"), "after dynamic change");
+ assert_false(tree.matches(":dir(rtl)"), "after dynamic change");
+
+ tree.remove();
+}, "dynamic changes inside of non-HTML elements");
+
+test(() => {
+ let tree, shadow;
+ [tree, shadow] = setup_tree(`
+ <div dir="auto">
+ <div id="root">
+ <element xmlns="namespace">A</element>
+ \u05D0
+ </div>
+ </div>
+ `, `
+ <div dir="ltr">
+ <slot dir="auto">\u05D0</slot>
+ </div>
+ `);
+
+ let element = tree.querySelector("element");
+ let slot = shadow.querySelector("slot");
+ let text = element.firstChild;
+
+ assert_true(tree.matches(":dir(ltr)"), "initial state (tree)");
+ assert_true(element.matches(":dir(ltr)"), "initial state (element)");
+ assert_true(slot.matches(":dir(ltr)"), "initial state (slot)");
+
+ text.data = "\u05D0";
+
+ assert_true(tree.matches(":dir(rtl)"), "state after first change (tree)");
+ assert_true(element.matches(":dir(rtl)"), "state after first change (element)");
+ assert_true(slot.matches(":dir(rtl)"), "state after first change (slot)");
+
+ text.data = "";
+
+ assert_true(tree.matches(":dir(rtl)"), "state after second change (tree)");
+ assert_true(element.matches(":dir(rtl)"), "state after second change (element)");
+ assert_true(slot.matches(":dir(rtl)"), "state after second change (slot)");
+
+ tree.remove();
+}, "slotted non-HTML elements");
+
+test(() => {
+ let tree, shadow;
+ [tree, shadow] = setup_tree(`
+ <div>
+ <div id="root">
+ <!-- element goes here -->
+ \u05D0
+ </div>
+ </div>
+ `, `
+ <div dir="ltr">
+ <slot></slot>
+ </div>
+ `);
+
+ let element = document.createElementNS("namespace", "element");
+ let text = document.createTextNode("A");
+ element.appendChild(text);
+ tree.querySelector("#root").prepend(element);
+
+ assert_not_equals(element.namespaceURI, tree.namespaceURI);
+
+ assert_true(tree.matches(":dir(ltr)"), "initial state (tree)");
+ assert_true(element.matches(":dir(ltr)"), "initial state (element)");
+
+ tree.dir = "auto";
+
+ assert_true(tree.matches(":dir(ltr)"), "state after making dir=auto (tree)");
+ assert_true(element.matches(":dir(ltr)"), "state after making dir=auto (element)");
+
+ text.data = "\u05D0";
+
+ assert_true(tree.matches(":dir(rtl)"), "state after first change (tree)");
+ assert_true(element.matches(":dir(rtl)"), "state after first change (element)");
+
+ text.data = "";
+
+ assert_true(tree.matches(":dir(rtl)"), "state after second change (tree)");
+ assert_true(element.matches(":dir(rtl)"), "state after second change (element)");
+
+ tree.remove();
+}, "slotted non-HTML elements after dynamically assigning dir=auto, and dir attribute ignored on non-HTML elements");
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir-auto-form-associated.window.js b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-auto-form-associated.window.js
new file mode 100644
index 0000000000..3af7eb3c2e
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-auto-form-associated.window.js
@@ -0,0 +1,71 @@
+// Keep this mostly synchronized with
+// html/semantics/forms/attributes-common-to-form-controls/dirname-only-if-applies.html
+// except that won't have "reset" and "button" as those don't submit their value
+[
+ "hidden",
+ "text",
+ "search",
+ "tel",
+ "url",
+ "email",
+ "password",
+ "submit",
+ "reset",
+ "button"
+].forEach(type => {
+ test(t => {
+ const input = document.createElement("input");
+ t.add_cleanup(() => input.remove());
+ input.type = type;
+ assert_equals(input.type, type);
+ document.body.append(input);
+
+ input.setAttribute("value", "\u05D0"); // The Hebrew letter Alef (strongly RTL)
+ assert_true(input.matches(":dir(ltr)"));
+ input.removeAttribute("value");
+
+ input.dir = "auto";
+ input.setAttribute("value", "\u05D0");
+ assert_true(input.matches(":dir(rtl)"));
+ input.removeAttribute("value");
+ assert_true(input.matches(":dir(ltr)"));
+
+ input.value = "\u05D0";
+ assert_true(input.matches(":dir(rtl)"));
+ }, `<input dir=auto type=${type}> directionality`);
+});
+
+[
+ "date",
+ "month",
+ "week",
+ "time",
+ "datetime-local",
+ "number",
+ "range",
+ "color",
+ "checkbox",
+ "radio",
+ // "file" // value setter throws
+ "image"
+].forEach(type => {
+ test(t => {
+ const input = document.createElement("input");
+ t.add_cleanup(() => input.remove());
+ input.type = type;
+ assert_equals(input.type, type);
+ input.dir = "auto";
+ input.value = "\u05D0"; // The Hebrew letter Alef (strongly RTL)
+ document.body.append(input);
+ assert_true(input.matches(":dir(ltr)"));
+ }, `<input dir=auto type=${type}> directionality`);
+});
+
+test(t => {
+ const input = document.createElement("textarea");
+ t.add_cleanup(() => input.remove());
+ input.dir = "auto";
+ input.value = "\u05D0"; // The Hebrew letter Alef (strongly RTL)
+ document.body.append(input);
+ assert_true(input.matches(":dir(rtl)"));
+}, `<textarea dir=auto> directionality`);
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir-bdi-script.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-bdi-script.html
new file mode 100644
index 0000000000..3008043093
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-bdi-script.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<title>HTML Test: BDI: script adds a bdi element with R text and the direction should be RTL</title>
+<meta charset="utf-8">
+<meta name="assert" content="The dir global attribute defaults to auto on the bdi element" />
+<link rel="author" title="HTML5 bidi test WG" href="mailto:myid.shin@igalia.com" />
+<link rel="help" href="https://html.spec.whatwg.org/multipage/text-level-semantics.html#the-bdi-element" />
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<body>
+<div id="test1"><bdi>اختبر SomeText</bdi><br></div>
+<div id="test2"></div>
+<script>
+test(() => {
+ assert_equals(getComputedStyle(test1.firstChild).direction, "rtl");
+
+ const bdi = document.createElement("bdi");
+ var text = document.createTextNode('اختبر SomeText');
+ bdi.append(text);
+ test2.append(bdi);
+
+ assert_equals(getComputedStyle(test2.firstChild).direction, "rtl");
+}, 'BDI test: Directionality');
+</script>
+</body> \ No newline at end of file
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-01-ref.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-01-ref.html
new file mode 100644
index 0000000000..3462b908b3
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-01-ref.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>[dir] and shadow slots: dir=ltr on the slot, paragraph in the light tree</title>
+<link rel="author" title="Eric Meyer" href="mailto:emeyer@igalia.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/C#the-dir-attribute">
+<link rel="help" href="https://github.com/whatwg/html/issues/3699">
+<link rel="help" href="https://github.com/whatwg/html/pull/9796">
+<style type="text/css">
+body {width: 600px;}
+div {border: 1px solid gray; margin: 1em;}
+div p {width: 50%; border: 1px dotted;}
+</style>
+</head>
+<body>
+
+<p>`dir=ltr` on the &lt;slot&gt;, paragraph in the light tree</p>
+<div id="host"><p>paragraph.</p></div>
+<p id="result">The HTML direction / computed CSS `direction` value for the paragraph is: ltr / ltr.</p>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-01.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-01.html
new file mode 100644
index 0000000000..2d6983cb14
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-01.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>[dir] and shadow slots: dir=ltr on the slot, paragraph in the light tree</title>
+<link rel="author" title="Eric Meyer" href="mailto:emeyer@igalia.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/C#the-dir-attribute">
+<link rel="help" href="https://github.com/whatwg/html/issues/3699">
+<link rel="help" href="https://github.com/whatwg/html/pull/9796">
+<link rel="match" href="dir-shadow-01-ref.html">
+<style type="text/css">
+body {width: 600px;}
+div {border: 1px solid gray; margin: 1em;}
+div p {width: 50%; border: 1px dotted;}
+</style>
+<script src="dir-shadow-utils.js"></script>
+</head>
+<body>
+
+<p>`dir=ltr` on the &lt;slot&gt;, paragraph in the light tree</p>
+<div id="host"><p>paragraph.</p></div>
+<p id="result">The HTML direction / computed CSS `direction` value for the paragraph is: </p>
+
+<script type="text/javascript">
+ let root = host.attachShadow({mode:"open"});
+ root.innerHTML = `
+ <slot dir="ltr"></slot>
+ `;
+ result.innerHTML += html_direction(host.firstChild) + " / " + getComputedStyle(host.firstChild).direction + '.';
+</script>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-02-ref.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-02-ref.html
new file mode 100644
index 0000000000..8f358cf647
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-02-ref.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>[dir] and shadow slots: dir=ltr on the slot, paragraph in the light tree</title>
+<link rel="author" title="Eric Meyer" href="mailto:emeyer@igalia.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/C#the-dir-attribute">
+<link rel="help" href="https://github.com/whatwg/html/issues/3699">
+<link rel="help" href="https://github.com/whatwg/html/pull/9796">
+<style type="text/css">
+body {width: 600px;}
+div {border: 1px solid gray; margin: 1em;}
+div p {width: 50%; border: 1px dotted;}
+</style>
+</head>
+<body>
+
+<p>`dir=ltr` on the &lt;slot&gt;, paragraph in the light tree</p>
+<div id="host"><p>اختبر.</p></div>
+<p id="result">The HTML direction / computed CSS `direction` value for the paragraph is: ltr / ltr.</p>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-02.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-02.html
new file mode 100644
index 0000000000..0553ef9a33
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-02.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>[dir] and shadow slots: dir=ltr on the slot, paragraph in the light tree</title>
+<link rel="author" title="Eric Meyer" href="mailto:emeyer@igalia.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/C#the-dir-attribute">
+<link rel="help" href="https://github.com/whatwg/html/issues/3699">
+<link rel="help" href="https://github.com/whatwg/html/pull/9796">
+<link rel="match" href="dir-shadow-02-ref.html">
+<style type="text/css">
+body {width: 600px;}
+div {border: 1px solid gray; margin: 1em;}
+div p {width: 50%; border: 1px dotted;}
+</style>
+<script src="dir-shadow-utils.js"></script>
+</head>
+<body>
+
+<p>`dir=ltr` on the &lt;slot&gt;, paragraph in the light tree</p>
+<div id="host"><p>اختبر.</p></div>
+<p id="result">The HTML direction / computed CSS `direction` value for the paragraph is: </p>
+
+<script type="text/javascript">
+ let root = host.attachShadow({mode:"open"});
+ root.innerHTML = `
+ <slot dir="ltr"></slot>
+ `;
+ result.innerHTML += html_direction(host.firstChild) + " / " + getComputedStyle(host.firstChild).direction + '.';
+</script>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-03-ref.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-03-ref.html
new file mode 100644
index 0000000000..a2f574820f
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-03-ref.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>[dir] and shadow slots: dir=rtl on the slot, paragraph in the light tree</title>
+<link rel="author" title="Eric Meyer" href="mailto:emeyer@igalia.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/C#the-dir-attribute">
+<link rel="help" href="https://github.com/whatwg/html/issues/3699">
+<link rel="help" href="https://github.com/whatwg/html/pull/9796">
+<style type="text/css">
+body {width: 600px;}
+div {border: 1px solid gray; margin: 1em;}
+div p {width: 50%; border: 1px dotted;}
+</style>
+</head>
+<body>
+
+<p>`dir=rtl` on the &lt;slot&gt;, paragraph in the light tree</p>
+<div id="host"><p dir="rtl">paragraph.</p></div>
+<p id="result">The HTML direction / computed CSS `direction` value for the paragraph is: ltr / rtl.</p>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-03.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-03.html
new file mode 100644
index 0000000000..5986a9d0f7
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-03.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>[dir] and shadow slots: dir=rtl on the slot, paragraph in the light tree</title>
+<link rel="author" title="Eric Meyer" href="mailto:emeyer@igalia.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/C#the-dir-attribute">
+<link rel="help" href="https://github.com/whatwg/html/issues/3699">
+<link rel="help" href="https://github.com/whatwg/html/pull/9796">
+<link rel="match" href="dir-shadow-03-ref.html">
+<style type="text/css">
+body {width: 600px;}
+div {border: 1px solid gray; margin: 1em;}
+div p {width: 50%; border: 1px dotted;}
+</style>
+<script src="dir-shadow-utils.js"></script>
+</head>
+<body>
+
+<p>`dir=rtl` on the &lt;slot&gt;, paragraph in the light tree</p>
+<div id="host"><p>paragraph.</p></div>
+<p id="result">The HTML direction / computed CSS `direction` value for the paragraph is: </p>
+
+<script type="text/javascript">
+ let root = host.attachShadow({mode:"open"});
+ root.innerHTML = `
+ <slot dir="rtl"></slot>
+ `;
+ result.innerHTML += html_direction(host.firstChild) + " / " + getComputedStyle(host.firstChild).direction + '.';
+</script>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-04-ref.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-04-ref.html
new file mode 100644
index 0000000000..5724b5b84d
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-04-ref.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>[dir] and shadow slots: dir=rtl on the slot, paragraph in the light tree</title>
+<link rel="author" title="Eric Meyer" href="mailto:emeyer@igalia.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/C#the-dir-attribute">
+<link rel="help" href="https://github.com/whatwg/html/issues/3699">
+<link rel="help" href="https://github.com/whatwg/html/pull/9796">
+<style type="text/css">
+body {width: 600px;}
+div {border: 1px solid gray; margin: 1em;}
+div p {width: 50%; border: 1px dotted;}
+</style>
+</head>
+<body>
+
+<p>`dir=rtl` on the &lt;slot&gt;, paragraph in the light tree</p>
+<div id="host"><p dir="rtl">اختبر.</p></div>
+<p id="result">The HTML direction / computed CSS `direction` value for the paragraph is: ltr / rtl.</p>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-04.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-04.html
new file mode 100644
index 0000000000..aa2ab9dc93
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-04.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>[dir] and shadow slots: dir=rtl on the slot, paragraph in the light tree</title>
+<link rel="author" title="Eric Meyer" href="mailto:emeyer@igalia.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/C#the-dir-attribute">
+<link rel="help" href="https://github.com/whatwg/html/issues/3699">
+<link rel="help" href="https://github.com/whatwg/html/pull/9796">
+<link rel="match" href="dir-shadow-04-ref.html">
+<style type="text/css">
+body {width: 600px;}
+div {border: 1px solid gray; margin: 1em;}
+div p {width: 50%; border: 1px dotted;}
+</style>
+<script src="dir-shadow-utils.js"></script>
+</head>
+<body>
+
+<p>`dir=rtl` on the &lt;slot&gt;, paragraph in the light tree</p>
+<div id="host"><p>اختبر.</p></div>
+<p id="result">The HTML direction / computed CSS `direction` value for the paragraph is: </p>
+
+<script type="text/javascript">
+ let root = host.attachShadow({mode:"open"});
+ root.innerHTML = `
+ <slot dir="rtl"></slot>
+ `;
+ result.innerHTML += html_direction(host.firstChild) + " / " + getComputedStyle(host.firstChild).direction + '.';
+</script>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-05-ref.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-05-ref.html
new file mode 100644
index 0000000000..13c5b16240
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-05-ref.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>[dir] and shadow slots: dir=auto on the slot, paragraph in the light tree</title>
+<link rel="author" title="Eric Meyer" href="mailto:emeyer@igalia.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/C#the-dir-attribute">
+<link rel="help" href="https://github.com/whatwg/html/issues/3699">
+<link rel="help" href="https://github.com/whatwg/html/pull/9796">
+<style type="text/css">
+body {width: 600px;}
+div {border: 1px solid gray; margin: 1em;}
+div p {width: 50%; border: 1px dotted;}
+</style>
+</head>
+<body>
+
+<p>`dir=auto` on the &lt;slot&gt;, paragraph in the light tree</p>
+<div id="host"><p>paragraph.</p></div>
+<p id="result">The HTML direction / computed CSS `direction` value for the paragraph is: ltr / ltr.</p>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-05.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-05.html
new file mode 100644
index 0000000000..597cb8d5b8
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-05.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>[dir] and shadow slots: dir=auto on the slot, paragraph in the light tree</title>
+<link rel="author" title="Eric Meyer" href="mailto:emeyer@igalia.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/C#the-dir-attribute">
+<link rel="help" href="https://github.com/whatwg/html/issues/3699">
+<link rel="help" href="https://github.com/whatwg/html/pull/9796">
+<link rel="match" href="dir-shadow-05-ref.html">
+<style type="text/css">
+body {width: 600px;}
+div {border: 1px solid gray; margin: 1em;}
+div p {width: 50%; border: 1px dotted;}
+</style>
+<script src="dir-shadow-utils.js"></script>
+</head>
+<body>
+
+<p>`dir=auto` on the &lt;slot&gt;, paragraph in the light tree</p>
+<div id="host"><p>paragraph.</p></div>
+<p id="result">The HTML direction / computed CSS `direction` value for the paragraph is: </p>
+
+<script type="text/javascript">
+ let root = host.attachShadow({mode:"open"});
+ root.innerHTML = `
+ <slot dir="auto"></slot>
+ `;
+ result.innerHTML += html_direction(host.firstChild) + " / " + getComputedStyle(host.firstChild).direction + '.';
+</script>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-06-ref.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-06-ref.html
new file mode 100644
index 0000000000..ca54b3bb2c
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-06-ref.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>[dir] and shadow slots: dir=auto on the slot, paragraph in the light tree</title>
+<link rel="author" title="Eric Meyer" href="mailto:emeyer@igalia.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/C#the-dir-attribute">
+<link rel="help" href="https://github.com/whatwg/html/issues/3699">
+<link rel="help" href="https://github.com/whatwg/html/pull/9796">
+<style type="text/css">
+body {width: 600px;}
+div {border: 1px solid gray; margin: 1em;}
+div p {width: 50%; border: 1px dotted;}
+</style>
+</head>
+<body>
+
+<p>`dir=auto` on the &lt;slot&gt;, paragraph in the light tree</p>
+<div id="host"><p dir="rtl">اختبر.</p></div>
+<p id="result">The HTML direction / computed CSS `direction` value for the paragraph is: ltr / rtl.</p>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-06.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-06.html
new file mode 100644
index 0000000000..6cfaf7fcec
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-06.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>[dir] and shadow slots: dir=auto on the slot, paragraph in the light tree</title>
+<link rel="author" title="Eric Meyer" href="mailto:emeyer@igalia.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/C#the-dir-attribute">
+<link rel="help" href="https://github.com/whatwg/html/issues/3699">
+<link rel="help" href="https://github.com/whatwg/html/pull/9796">
+<link rel="match" href="dir-shadow-06-ref.html">
+<style type="text/css">
+body {width: 600px;}
+div {border: 1px solid gray; margin: 1em;}
+div p {width: 50%; border: 1px dotted;}
+</style>
+<script src="dir-shadow-utils.js"></script>
+</head>
+<body>
+
+<p>`dir=auto` on the &lt;slot&gt;, paragraph in the light tree</p>
+<div id="host"><p>اختبر.</p></div>
+<p id="result">The HTML direction / computed CSS `direction` value for the paragraph is: </p>
+
+<script type="text/javascript">
+ let root = host.attachShadow({mode:"open"});
+ root.innerHTML = `
+ <slot dir="auto"></slot>
+ `;
+ result.innerHTML += html_direction(host.firstChild) + " / " + getComputedStyle(host.firstChild).direction + '.';
+</script>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-07-ref.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-07-ref.html
new file mode 100644
index 0000000000..0a2de4d398
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-07-ref.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>[dir] and shadow slots: dir=ltr on the shadow host, paragraph in the light tree</title>
+<link rel="author" title="Eric Meyer" href="mailto:emeyer@igalia.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/C#the-dir-attribute">
+<link rel="help" href="https://github.com/whatwg/html/issues/3699">
+<link rel="help" href="https://github.com/whatwg/html/pull/9796">
+<style type="text/css">
+body {width: 600px;}
+div {border: 1px solid gray; margin: 1em;}
+div p {width: 50%; border: 1px dotted;}
+</style>
+</head>
+<body>
+
+<p>`dir=ltr` on the shadow host, paragraph in the light tree</p>
+<div id="host" dir="ltr"><p>paragraph.</p></div>
+<p id="result">The HTML direction / computed CSS `direction` value for the paragraph is: ltr / ltr.</p>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-07.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-07.html
new file mode 100644
index 0000000000..dd11f4a605
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-07.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>[dir] and shadow slots: dir=ltr on the shadow host, paragraph in the light tree</title>
+<link rel="author" title="Eric Meyer" href="mailto:emeyer@igalia.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/C#the-dir-attribute">
+<link rel="help" href="https://github.com/whatwg/html/issues/3699">
+<link rel="help" href="https://github.com/whatwg/html/pull/9796">
+<link rel="match" href="dir-shadow-07-ref.html">
+<style type="text/css">
+body {width: 600px;}
+div {border: 1px solid gray; margin: 1em;}
+div p {width: 50%; border: 1px dotted;}
+</style>
+<script src="dir-shadow-utils.js"></script>
+</head>
+<body>
+
+<p>`dir=ltr` on the shadow host, paragraph in the light tree</p>
+<div id="host" dir="ltr"><p>paragraph.</p></div>
+<p id="result">The HTML direction / computed CSS `direction` value for the paragraph is: </p>
+
+<script type="text/javascript">
+ let root = host.attachShadow({mode:"open"});
+ root.innerHTML = `
+ <slot></slot>
+ `;
+ result.innerHTML += html_direction(host.firstChild) + " / " + getComputedStyle(host.firstChild).direction + '.';
+</script>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-08-ref.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-08-ref.html
new file mode 100644
index 0000000000..09d8b24094
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-08-ref.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>[dir] and shadow slots: dir=ltr on the shadow host, paragraph in the light tree</title>
+<link rel="author" title="Eric Meyer" href="mailto:emeyer@igalia.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/C#the-dir-attribute">
+<link rel="help" href="https://github.com/whatwg/html/issues/3699">
+<link rel="help" href="https://github.com/whatwg/html/pull/9796">
+<style type="text/css">
+body {width: 600px;}
+div {border: 1px solid gray; margin: 1em;}
+div p {width: 50%; border: 1px dotted;}
+</style>
+</head>
+<body>
+
+<p>`dir=ltr` on the shadow host, paragraph in the light tree</p>
+<div id="host" dir="ltr"><p>اختبر.</p></div>
+<p id="result">The HTML direction / computed CSS `direction` value for the paragraph is: ltr / ltr.</p>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-08.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-08.html
new file mode 100644
index 0000000000..8b1377d32a
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-08.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>[dir] and shadow slots: dir=ltr on the shadow host, paragraph in the light tree</title>
+<link rel="author" title="Eric Meyer" href="mailto:emeyer@igalia.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/C#the-dir-attribute">
+<link rel="help" href="https://github.com/whatwg/html/issues/3699">
+<link rel="help" href="https://github.com/whatwg/html/pull/9796">
+<link rel="match" href="dir-shadow-08-ref.html">
+<style type="text/css">
+body {width: 600px;}
+div {border: 1px solid gray; margin: 1em;}
+div p {width: 50%; border: 1px dotted;}
+</style>
+<script src="dir-shadow-utils.js"></script>
+</head>
+<body>
+
+<p>`dir=ltr` on the shadow host, paragraph in the light tree</p>
+<div id="host" dir="ltr"><p>اختبر.</p></div>
+<p id="result">The HTML direction / computed CSS `direction` value for the paragraph is: </p>
+
+<script type="text/javascript">
+ let root = host.attachShadow({mode:"open"});
+ root.innerHTML = `
+ <slot></slot>
+ `;
+ result.innerHTML += html_direction(host.firstChild) + " / " + getComputedStyle(host.firstChild).direction + '.';
+</script>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-09-ref.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-09-ref.html
new file mode 100644
index 0000000000..73b9cb1487
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-09-ref.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>[dir] and shadow slots: dir=rtl on the shadow host, paragraph in the light tree</title>
+<link rel="author" title="Eric Meyer" href="mailto:emeyer@igalia.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/C#the-dir-attribute">
+<link rel="help" href="https://github.com/whatwg/html/issues/3699">
+<link rel="help" href="https://github.com/whatwg/html/pull/9796">
+<style type="text/css">
+body {width: 600px;}
+div {border: 1px solid gray; margin: 1em;}
+div p {width: 50%; border: 1px dotted;}
+</style>
+</head>
+<body>
+
+<p>`dir=rtl` on the shadow host, paragraph in the light tree</p>
+<div id="host" dir="rtl"><p>paragraph.</p></div>
+<p id="result">The HTML direction / computed CSS `direction` value for the paragraph is: rtl / rtl.</p>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-09.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-09.html
new file mode 100644
index 0000000000..d9c66e7931
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-09.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>[dir] and shadow slots: dir=rtl on the shadow host, paragraph in the light tree</title>
+<link rel="author" title="Eric Meyer" href="mailto:emeyer@igalia.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/C#the-dir-attribute">
+<link rel="help" href="https://github.com/whatwg/html/issues/3699">
+<link rel="help" href="https://github.com/whatwg/html/pull/9796">
+<link rel="match" href="dir-shadow-09-ref.html">
+<style type="text/css">
+body {width: 600px;}
+div {border: 1px solid gray; margin: 1em;}
+div p {width: 50%; border: 1px dotted;}
+</style>
+<script src="dir-shadow-utils.js"></script>
+</head>
+<body>
+
+<p>`dir=rtl` on the shadow host, paragraph in the light tree</p>
+<div id="host" dir="rtl"><p>paragraph.</p></div>
+<p id="result">The HTML direction / computed CSS `direction` value for the paragraph is: </p>
+
+<script type="text/javascript">
+ let root = host.attachShadow({mode:"open"});
+ root.innerHTML = `
+ <slot></slot>
+ `;
+ result.innerHTML += html_direction(host.firstChild) + " / " + getComputedStyle(host.firstChild).direction + '.';
+</script>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-10-ref.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-10-ref.html
new file mode 100644
index 0000000000..391e5047f9
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-10-ref.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>[dir] and shadow slots: dir=rtl on the shadow host, paragraph in the light tree</title>
+<link rel="author" title="Eric Meyer" href="mailto:emeyer@igalia.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/C#the-dir-attribute">
+<link rel="help" href="https://github.com/whatwg/html/issues/3699">
+<link rel="help" href="https://github.com/whatwg/html/pull/9796">
+<style type="text/css">
+body {width: 600px;}
+div {border: 1px solid gray; margin: 1em;}
+div p {width: 50%; border: 1px dotted;}
+</style>
+</head>
+<body>
+
+<p>`dir=rtl` on the shadow host, paragraph in the light tree</p>
+<div id="host" dir="rtl"><p>اختبر.</p></div>
+<p id="result">The HTML direction / computed CSS `direction` value for the paragraph is: rtl / rtl.</p>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-10.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-10.html
new file mode 100644
index 0000000000..ad35af808e
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-10.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>[dir] and shadow slots: dir=rtl on the shadow host, paragraph in the light tree</title>
+<link rel="author" title="Eric Meyer" href="mailto:emeyer@igalia.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/C#the-dir-attribute">
+<link rel="help" href="https://github.com/whatwg/html/issues/3699">
+<link rel="help" href="https://github.com/whatwg/html/pull/9796">
+<link rel="match" href="dir-shadow-10-ref.html">
+<style type="text/css">
+body {width: 600px;}
+div {border: 1px solid gray; margin: 1em;}
+div p {width: 50%; border: 1px dotted;}
+</style>
+<script src="dir-shadow-utils.js"></script>
+</head>
+<body>
+
+<p>`dir=rtl` on the shadow host, paragraph in the light tree</p>
+<div id="host" dir="rtl"><p>اختبر.</p></div>
+<p id="result">The HTML direction / computed CSS `direction` value for the paragraph is: </p>
+
+<script type="text/javascript">
+ let root = host.attachShadow({mode:"open"});
+ root.innerHTML = `
+ <slot></slot>
+ `;
+ result.innerHTML += html_direction(host.firstChild) + " / " + getComputedStyle(host.firstChild).direction + '.';
+</script>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-11-ref.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-11-ref.html
new file mode 100644
index 0000000000..ae7e849c97
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-11-ref.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>[dir] and shadow slots: dir=auto on the shadow host, paragraph in the light tree</title>
+<link rel="author" title="Eric Meyer" href="mailto:emeyer@igalia.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/C#the-dir-attribute">
+<link rel="help" href="https://github.com/whatwg/html/issues/3699">
+<link rel="help" href="https://github.com/whatwg/html/pull/9796">
+<style type="text/css">
+body {width: 600px;}
+div {border: 1px solid gray; margin: 1em;}
+div p {width: 50%; border: 1px dotted;}
+</style>
+</head>
+<body>
+
+<p>`dir=auto` on the shadow host, paragraph in the light tree</p>
+<div id="host" dir="auto"><p>paragraph.</p></div>
+<p id="result">The HTML direction / computed CSS `direction` value for the paragraph is: ltr / ltr.</p>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-11.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-11.html
new file mode 100644
index 0000000000..31e04f065e
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-11.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>[dir] and shadow slots: dir=auto on the shadow host, paragraph in the light tree</title>
+<link rel="author" title="Eric Meyer" href="mailto:emeyer@igalia.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/C#the-dir-attribute">
+<link rel="help" href="https://github.com/whatwg/html/issues/3699">
+<link rel="help" href="https://github.com/whatwg/html/pull/9796">
+<link rel="match" href="dir-shadow-11-ref.html">
+<style type="text/css">
+body {width: 600px;}
+div {border: 1px solid gray; margin: 1em;}
+div p {width: 50%; border: 1px dotted;}
+</style>
+<script src="dir-shadow-utils.js"></script>
+</head>
+<body>
+
+<p>`dir=auto` on the shadow host, paragraph in the light tree</p>
+<div id="host" dir="auto"><p>paragraph.</p></div>
+<p id="result">The HTML direction / computed CSS `direction` value for the paragraph is: </p>
+
+<script type="text/javascript">
+ let root = host.attachShadow({mode:"open"});
+ root.innerHTML = `
+ <slot></slot>
+ `;
+ result.innerHTML += html_direction(host.firstChild) + " / " + getComputedStyle(host.firstChild).direction + '.';
+</script>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-12-ref.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-12-ref.html
new file mode 100644
index 0000000000..6f6b40218a
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-12-ref.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>[dir] and shadow slots: dir=auto on the shadow host, paragraph in the light tree</title>
+<link rel="author" title="Eric Meyer" href="mailto:emeyer@igalia.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/C#the-dir-attribute">
+<link rel="help" href="https://github.com/whatwg/html/issues/3699">
+<link rel="help" href="https://github.com/whatwg/html/pull/9796">
+<style type="text/css">
+body {width: 600px;}
+div {border: 1px solid gray; margin: 1em;}
+div p {width: 50%; border: 1px dotted;}
+</style>
+</head>
+<body>
+
+<p>`dir=auto` on the shadow host, paragraph in the light tree</p>
+<div id="host" dir="rtl"><p>اختبر.</p></div>
+<p id="result">The HTML direction / computed CSS `direction` value for the paragraph is: rtl / rtl.</p>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-12.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-12.html
new file mode 100644
index 0000000000..f6183a98d9
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-12.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>[dir] and shadow slots: dir=auto on the shadow host, paragraph in the light tree</title>
+<link rel="author" title="Eric Meyer" href="mailto:emeyer@igalia.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/C#the-dir-attribute">
+<link rel="help" href="https://github.com/whatwg/html/issues/3699">
+<link rel="help" href="https://github.com/whatwg/html/pull/9796">
+<link rel="match" href="dir-shadow-12-ref.html">
+<style type="text/css">
+body {width: 600px;}
+div {border: 1px solid gray; margin: 1em;}
+div p {width: 50%; border: 1px dotted;}
+</style>
+<script src="dir-shadow-utils.js"></script>
+</head>
+<body>
+
+<p>`dir=auto` on the shadow host, paragraph in the light tree</p>
+<div id="host" dir="rtl"><p>اختبر.</p></div>
+<p id="result">The HTML direction / computed CSS `direction` value for the paragraph is: </p>
+
+<script type="text/javascript">
+ let root = host.attachShadow({mode:"open"});
+ root.innerHTML = `<slot></slot>`;
+ result.innerHTML += html_direction(host.firstChild) + " / " + getComputedStyle(host.firstChild).direction + '.';
+</script>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-13-ref.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-13-ref.html
new file mode 100644
index 0000000000..a6ec54186f
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-13-ref.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>[dir] and shadow slots: dir=ltr on the shadow host, paragraph in the shadow tree</title>
+<link rel="author" title="Eric Meyer" href="mailto:emeyer@igalia.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/C#the-dir-attribute">
+<link rel="help" href="https://github.com/whatwg/html/issues/3699">
+<link rel="help" href="https://github.com/whatwg/html/pull/9796">
+<style type="text/css">
+body {width: 600px;}
+div {border: 1px solid gray; margin: 1em;}
+div p {width: 50%; border: 1px dotted;}
+</style>
+</head>
+<body>
+
+<p>`dir=ltr` on the shadow host, paragraph in the shadow tree</p>
+<div id="host" dir="ltr"><p>paragraph.</p></div>
+<p id="result">The HTML direction / computed CSS `direction` value for the paragraph is: ltr / ltr.</p>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-13.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-13.html
new file mode 100644
index 0000000000..35a00e6d28
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-13.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>[dir] and shadow slots: dir=ltr on the shadow host, paragraph in the shadow tree</title>
+<link rel="author" title="Eric Meyer" href="mailto:emeyer@igalia.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/C#the-dir-attribute">
+<link rel="help" href="https://github.com/whatwg/html/issues/3699">
+<link rel="help" href="https://github.com/whatwg/html/pull/9796">
+<link rel="match" href="dir-shadow-13-ref.html">
+<style type="text/css">
+body {width: 600px;}
+div {border: 1px solid gray; margin: 1em;}
+</style>
+<script src="dir-shadow-utils.js"></script>
+</head>
+<body>
+
+<p>`dir=ltr` on the shadow host, paragraph in the shadow tree</p>
+<div id="host" dir="ltr"></div>
+<p id="result">The HTML direction / computed CSS `direction` value for the paragraph is: </p>
+
+<script type="text/javascript">
+ let root = host.attachShadow({mode:"open"});
+ root.innerHTML = `<style>p {width: 50%; border: 1px dotted;}</style><p>paragraph.</p>`;
+ result.innerHTML += html_direction(root.querySelector('p')) + " / " + getComputedStyle(root.querySelector('p')).direction + '.';
+</script>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-14-ref.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-14-ref.html
new file mode 100644
index 0000000000..73d4eab962
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-14-ref.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>[dir] and shadow slots: dir=ltr on the shadow host, paragraph in the shadow tree</title>
+<link rel="author" title="Eric Meyer" href="mailto:emeyer@igalia.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/C#the-dir-attribute">
+<link rel="help" href="https://github.com/whatwg/html/issues/3699">
+<link rel="help" href="https://github.com/whatwg/html/pull/9796">
+<style type="text/css">
+body {width: 600px;}
+div {border: 1px solid gray; margin: 1em;}
+div p {width: 50%; border: 1px dotted;}
+</style>
+</head>
+<body>
+
+<p>`dir=ltr` on the shadow host, paragraph in the shadow tree</p>
+<div id="host" dir="ltr"><p>اختبر.</p></div>
+<p id="result">The HTML direction / computed CSS `direction` value for the paragraph is: ltr / ltr.</p>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-14.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-14.html
new file mode 100644
index 0000000000..6aa4a639fd
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-14.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>[dir] and shadow slots: dir=ltr on the shadow host, paragraph in the shadow tree</title>
+<link rel="author" title="Eric Meyer" href="mailto:emeyer@igalia.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/C#the-dir-attribute">
+<link rel="help" href="https://github.com/whatwg/html/issues/3699">
+<link rel="help" href="https://github.com/whatwg/html/pull/9796">
+<link rel="match" href="dir-shadow-14-ref.html">
+<style type="text/css">
+body {width: 600px;}
+div {border: 1px solid gray; margin: 1em;}
+</style>
+<script src="dir-shadow-utils.js"></script>
+</head>
+<body>
+
+<p>`dir=ltr` on the shadow host, paragraph in the shadow tree</p>
+<div id="host" dir="ltr"></div>
+<p id="result">The HTML direction / computed CSS `direction` value for the paragraph is: </p>
+
+<script type="text/javascript">
+ let root = host.attachShadow({mode:"open"});
+ root.innerHTML = `<style>p {width: 50%; border: 1px dotted;}</style><p>اختبر.</p>`;
+ result.innerHTML += html_direction(root.querySelector('p')) + " / " + getComputedStyle(root.querySelector('p')).direction + '.';
+</script>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-15-ref.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-15-ref.html
new file mode 100644
index 0000000000..0139997e65
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-15-ref.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>[dir] and shadow slots: dir=rtl on the shadow host, paragraph in the shadow tree</title>
+<link rel="author" title="Eric Meyer" href="mailto:emeyer@igalia.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/C#the-dir-attribute">
+<link rel="help" href="https://github.com/whatwg/html/issues/3699">
+<link rel="help" href="https://github.com/whatwg/html/pull/9796">
+<style type="text/css">
+body {width: 600px;}
+div {border: 1px solid gray; margin: 1em;}
+div p {width: 50%; border: 1px dotted;}
+</style>
+</head>
+<body>
+
+<p>`dir=rtl` on the shadow host, paragraph in the shadow tree</p>
+<div id="host" dir="rtl"><p>paragraph.</p></div>
+<p id="result">The HTML direction / computed CSS `direction` value for the paragraph is: rtl / rtl.</p>
+
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-15.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-15.html
new file mode 100644
index 0000000000..37c05d283c
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-15.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>[dir] and shadow slots: dir=rtl on the shadow host, paragraph in the shadow tree</title>
+<link rel="author" title="Eric Meyer" href="mailto:emeyer@igalia.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/C#the-dir-attribute">
+<link rel="help" href="https://github.com/whatwg/html/issues/3699">
+<link rel="help" href="https://github.com/whatwg/html/pull/9796">
+<link rel="match" href="dir-shadow-15-ref.html">
+<style type="text/css">
+body {width: 600px;}
+div {border: 1px solid gray; margin: 1em;}
+</style>
+<script src="dir-shadow-utils.js"></script>
+</head>
+<body>
+
+<p>`dir=rtl` on the shadow host, paragraph in the shadow tree</p>
+<div id="host" dir="rtl"></div>
+<p id="result">The HTML direction / computed CSS `direction` value for the paragraph is: </p>
+
+<script type="text/javascript">
+ let root = host.attachShadow({mode:"open"});
+ root.innerHTML = `<style>p {width: 50%; border: 1px dotted;}</style><p>paragraph.</p>`;
+ result.innerHTML += html_direction(root.querySelector('p')) + " / " + getComputedStyle(root.querySelector('p')).direction + '.';
+</script>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-16-ref.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-16-ref.html
new file mode 100644
index 0000000000..926b7a900d
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-16-ref.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>[dir] and shadow slots: dir=rtl on the shadow host, paragraph in the shadow tree</title>
+<link rel="author" title="Eric Meyer" href="mailto:emeyer@igalia.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/C#the-dir-attribute">
+<link rel="help" href="https://github.com/whatwg/html/issues/3699">
+<link rel="help" href="https://github.com/whatwg/html/pull/9796">
+<style type="text/css">
+body {width: 600px;}
+div {border: 1px solid gray; margin: 1em;}
+div p {width: 50%; border: 1px dotted;}
+</style>
+</head>
+<body>
+
+<p>`dir=rtl` on the shadow host, paragraph in the shadow tree</p>
+<div id="host" dir="rtl"><p>اختبر.</p></div>
+<p id="result">The HTML direction / computed CSS `direction` value for the paragraph is: rtl / rtl.</p>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-16.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-16.html
new file mode 100644
index 0000000000..2a8bb64a1b
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-16.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>[dir] and shadow slots: dir=rtl on the shadow host, paragraph in the shadow tree</title>
+<link rel="author" title="Eric Meyer" href="mailto:emeyer@igalia.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/C#the-dir-attribute">
+<link rel="help" href="https://github.com/whatwg/html/issues/3699">
+<link rel="help" href="https://github.com/whatwg/html/pull/9796">
+<link rel="match" href="dir-shadow-16-ref.html">
+<style type="text/css">
+body {width: 600px;}
+div {border: 1px solid gray; margin: 1em;}
+</style>
+<script src="dir-shadow-utils.js"></script>
+</head>
+<body>
+
+<p>`dir=rtl` on the shadow host, paragraph in the shadow tree</p>
+<div id="host" dir="rtl"></div>
+<p id="result">The HTML direction / computed CSS `direction` value for the paragraph is: </p>
+
+<script type="text/javascript">
+ let root = host.attachShadow({mode:"open"});
+ root.innerHTML = `<style>p {width: 50%; border: 1px dotted;}</style><p>اختبر.</p>`;
+ result.innerHTML += html_direction(root.querySelector('p')) + " / " + getComputedStyle(root.querySelector('p')).direction + '.';
+</script>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-17-ref.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-17-ref.html
new file mode 100644
index 0000000000..b17c3e191d
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-17-ref.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>[dir] and shadow slots: dir=auto on the shadow host, paragraph in the shadow tree</title>
+<link rel="author" title="Eric Meyer" href="mailto:emeyer@igalia.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/C#the-dir-attribute">
+<link rel="help" href="https://github.com/whatwg/html/issues/3699">
+<link rel="help" href="https://github.com/whatwg/html/pull/9796">
+<style type="text/css">
+body {width: 600px;}
+div {border: 1px solid gray; margin: 1em;}
+div p {width: 50%; border: 1px dotted;}
+</style>
+</head>
+<body>
+
+<p>`dir=auto` on the shadow host, paragraph in the shadow tree</p>
+<div id="host" dir="auto"><p>paragraph.</p></div>
+<p id="result">The HTML direction / computed CSS `direction` value for the paragraph is: ltr / ltr.</p>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-17.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-17.html
new file mode 100644
index 0000000000..7016a27174
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-17.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>[dir] and shadow slots: dir=auto on the shadow host, paragraph in the shadow tree</title>
+<link rel="author" title="Eric Meyer" href="mailto:emeyer@igalia.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/C#the-dir-attribute">
+<link rel="help" href="https://github.com/whatwg/html/issues/3699">
+<link rel="help" href="https://github.com/whatwg/html/pull/9796">
+<link rel="match" href="dir-shadow-17-ref.html">
+<style type="text/css">
+body {width: 600px;}
+div {border: 1px solid gray; margin: 1em;}
+</style>
+<script src="dir-shadow-utils.js"></script>
+</head>
+<body>
+
+<p>`dir=auto` on the shadow host, paragraph in the shadow tree</p>
+<div id="host" dir="auto"></div>
+<p id="result">The HTML direction / computed CSS `direction` value for the paragraph is: </p>
+
+<script type="text/javascript">
+ let root = host.attachShadow({mode:"open"});
+ root.innerHTML = `<style>p {width: 50%; border: 1px dotted;}</style><p>paragraph.</p>`;
+ result.innerHTML += html_direction(root.querySelector('p')) + " / " + getComputedStyle(root.querySelector('p')).direction + '.';
+</script>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-18-ref.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-18-ref.html
new file mode 100644
index 0000000000..6155a9f2c9
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-18-ref.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>[dir] and shadow slots: dir=auto on the shadow host, paragraph in the shadow tree</title>
+<link rel="author" title="Eric Meyer" href="mailto:emeyer@igalia.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/C#the-dir-attribute">
+<link rel="help" href="https://github.com/whatwg/html/issues/3699">
+<link rel="help" href="https://github.com/whatwg/html/pull/9796">
+<style type="text/css">
+body {width: 600px;}
+div {border: 1px solid gray; margin: 1em;}
+div p {width: 50%; border: 1px dotted;}
+</style>
+</head>
+<body>
+
+<p>`dir=auto` on the shadow host, paragraph in the shadow tree</p>
+<div id="host" dir="ltr"><p dir="">اختبر.</p></div>
+<p id="result">The HTML direction / computed CSS `direction` value for the paragraph is: ltr / ltr.</p>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-18.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-18.html
new file mode 100644
index 0000000000..6796dd18ea
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-18.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>[dir] and shadow slots: dir=auto on the shadow host, paragraph in the shadow tree</title>
+<link rel="author" title="Eric Meyer" href="mailto:emeyer@igalia.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/C#the-dir-attribute">
+<link rel="help" href="https://github.com/whatwg/html/issues/3699">
+<link rel="help" href="https://github.com/whatwg/html/pull/9796">
+<link rel="match" href="dir-shadow-18-ref.html">
+<style type="text/css">
+body {width: 600px;}
+div {border: 1px solid gray; margin: 1em;}
+</style>
+<script src="dir-shadow-utils.js"></script>
+</head>
+<body>
+
+<p>`dir=auto` on the shadow host, paragraph in the shadow tree</p>
+<div id="host" dir="auto"></div>
+<p id="result">The HTML direction / computed CSS `direction` value for the paragraph is: </p>
+
+<script type="text/javascript">
+ let root = host.attachShadow({mode:"open"});
+ root.innerHTML = `<style>p {width: 50%; border: 1px dotted;}</style><p>اختبر.</p>`;
+ result.innerHTML += html_direction(root.querySelector('p')) + " / " + getComputedStyle(root.querySelector('p')).direction + '.';
+</script>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-19-ref.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-19-ref.html
new file mode 100644
index 0000000000..61a9592a4a
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-19-ref.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>[dir] and shadow slots: dir=ltr on the div (shadow host), text in the shadow tree</title>
+<link rel="author" title="Eric Meyer" href="mailto:emeyer@igalia.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/C#the-dir-attribute">
+<link rel="help" href="https://github.com/whatwg/html/issues/3699">
+<link rel="help" href="https://github.com/whatwg/html/pull/9796">
+<style type="text/css">
+body {width: 600px;}
+div {border: 1px solid gray; margin: 1em;}
+
+</style>
+</head>
+<body>
+
+<p>`dir=ltr` on the div (shadow host), text in the shadow tree</p>
+<div id="host" dir="ltr">text.</div>
+<p id="result">The HTML direction / computed CSS `direction` value for the host’s text is: ltr / ltr.</p>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-19.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-19.html
new file mode 100644
index 0000000000..a345a7b60d
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-19.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>[dir] and shadow slots: dir=ltr on the div (shadow host), text in the shadow tree</title>
+<link rel="author" title="Eric Meyer" href="mailto:emeyer@igalia.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/C#the-dir-attribute">
+<link rel="help" href="https://github.com/whatwg/html/issues/3699">
+<link rel="help" href="https://github.com/whatwg/html/pull/9796">
+<link rel="match" href="dir-shadow-19-ref.html">
+<style type="text/css">
+body {width: 600px;}
+div {border: 1px solid gray; margin: 1em;}
+</style>
+<script src="dir-shadow-utils.js"></script>
+</head>
+<body>
+
+<p>`dir=ltr` on the div (shadow host), text in the shadow tree</p>
+<div id="host" dir="ltr"></div>
+<p id="result">The HTML direction / computed CSS `direction` value for the host’s text is: </p>
+
+<script type="text/javascript">
+ let root = host.attachShadow({mode:"open"});
+ root.innerHTML = `text.`;
+ result.innerHTML += html_direction(host) + " / " + getComputedStyle(host).direction + '.';
+</script>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-20-ref.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-20-ref.html
new file mode 100644
index 0000000000..2e81381772
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-20-ref.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>[dir] and shadow slots: dir=ltr on the div (shadow host), text in the shadow tree</title>
+<link rel="author" title="Eric Meyer" href="mailto:emeyer@igalia.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/C#the-dir-attribute">
+<link rel="help" href="https://github.com/whatwg/html/issues/3699">
+<link rel="help" href="https://github.com/whatwg/html/pull/9796">
+<style type="text/css">
+body {width: 600px;}
+div {border: 1px solid gray; margin: 1em;}
+</style>
+</head>
+<body>
+
+<p>`dir=ltr` on the div (shadow host), text in the shadow tree</p>
+<div id="host" dir="ltr">اختبر.</div>
+<p id="result">The HTML direction / computed CSS `direction` value for the host’s text is: ltr / ltr.</p>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-20.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-20.html
new file mode 100644
index 0000000000..0072d9b6c9
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-20.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>[dir] and shadow slots: dir=ltr on the div (shadow host), text in the shadow tree</title>
+<link rel="author" title="Eric Meyer" href="mailto:emeyer@igalia.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/C#the-dir-attribute">
+<link rel="help" href="https://github.com/whatwg/html/issues/3699">
+<link rel="help" href="https://github.com/whatwg/html/pull/9796">
+<link rel="match" href="dir-shadow-20-ref.html">
+<style type="text/css">
+body {width: 600px;}
+div {border: 1px solid gray; margin: 1em;}
+</style>
+<script src="dir-shadow-utils.js"></script>
+</head>
+<body>
+
+<p>`dir=ltr` on the div (shadow host), text in the shadow tree</p>
+<div id="host" dir="ltr"></div>
+<p id="result">The HTML direction / computed CSS `direction` value for the host’s text is: </p>
+
+<script type="text/javascript">
+ let root = host.attachShadow({mode:"open"});
+ root.innerHTML = `اختبر.`;
+ result.innerHTML += html_direction(host) + " / " + getComputedStyle(host).direction + '.';
+</script>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-21-ref.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-21-ref.html
new file mode 100644
index 0000000000..58c8d426f2
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-21-ref.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>[dir] and shadow slots: dir=rtl on the div (shadow host), text in the shadow tree</title>
+<link rel="author" title="Eric Meyer" href="mailto:emeyer@igalia.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/C#the-dir-attribute">
+<link rel="help" href="https://github.com/whatwg/html/issues/3699">
+<link rel="help" href="https://github.com/whatwg/html/pull/9796">
+<style type="text/css">
+body {width: 600px;}
+div {border: 1px solid gray; margin: 1em;}
+</style>
+</head>
+<body>
+
+<p>`dir=rtl` on the div (shadow host), text in the shadow tree</p>
+<div id="host" dir="rtl">text.</div>
+<p id="result">The HTML direction / computed CSS `direction` value for the host’s text is: rtl / rtl.</p>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-21.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-21.html
new file mode 100644
index 0000000000..5b9a4aa184
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-21.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>[dir] and shadow slots: dir=rtl on the div (shadow host), text in the shadow tree</title>
+<link rel="author" title="Eric Meyer" href="mailto:emeyer@igalia.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/C#the-dir-attribute">
+<link rel="help" href="https://github.com/whatwg/html/issues/3699">
+<link rel="help" href="https://github.com/whatwg/html/pull/9796">
+<link rel="match" href="dir-shadow-21-ref.html">
+<style type="text/css">
+body {width: 600px;}
+div {border: 1px solid gray; margin: 1em;}
+</style>
+<script src="dir-shadow-utils.js"></script>
+</head>
+<body>
+
+<p>`dir=rtl` on the div (shadow host), text in the shadow tree</p>
+<div id="host" dir="rtl"></div>
+<p id="result">The HTML direction / computed CSS `direction` value for the host’s text is: </p>
+
+<script type="text/javascript">
+ let root = host.attachShadow({mode:"open"});
+ root.innerHTML = `text.`;
+ result.innerHTML += html_direction(host) + " / " + getComputedStyle(host).direction + '.';
+</script>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-22-ref.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-22-ref.html
new file mode 100644
index 0000000000..6721da534f
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-22-ref.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>[dir] and shadow slots: dir=rtl on the div (shadow host), text in the shadow tree</title>
+<link rel="author" title="Eric Meyer" href="mailto:emeyer@igalia.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/C#the-dir-attribute">
+<link rel="help" href="https://github.com/whatwg/html/issues/3699">
+<link rel="help" href="https://github.com/whatwg/html/pull/9796">
+<style type="text/css">
+body {width: 600px;}
+div {border: 1px solid gray; margin: 1em;}
+</style>
+</head>
+<body>
+
+<p>`dir=rtl` on the div (shadow host), text in the shadow tree</p>
+<div id="host" dir="rtl">اختبر.</div>
+<p id="result">The HTML direction / computed CSS `direction` value for the host’s text is: rtl / rtl.</p>
+
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-22.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-22.html
new file mode 100644
index 0000000000..009ba460ce
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-22.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>[dir] and shadow slots: dir=rtl on the div (shadow host), text in the shadow tree</title>
+<link rel="author" title="Eric Meyer" href="mailto:emeyer@igalia.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/C#the-dir-attribute">
+<link rel="help" href="https://github.com/whatwg/html/issues/3699">
+<link rel="help" href="https://github.com/whatwg/html/pull/9796">
+<link rel="match" href="dir-shadow-22-ref.html">
+<style type="text/css">
+body {width: 600px;}
+div {border: 1px solid gray; margin: 1em;}
+</style>
+<script src="dir-shadow-utils.js"></script>
+</head>
+<body>
+
+<p>`dir=rtl` on the div (shadow host), text in the shadow tree</p>
+<div id="host" dir="rtl"></div>
+<p id="result">The HTML direction / computed CSS `direction` value for the host’s text is: </p>
+
+<script type="text/javascript">
+ let root = host.attachShadow({mode:"open"});
+ root.innerHTML = `اختبر.`;
+ result.innerHTML += html_direction(host) + " / " + getComputedStyle(host).direction + '.';
+</script>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-23-ref.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-23-ref.html
new file mode 100644
index 0000000000..bf06a44847
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-23-ref.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>[dir] and shadow slots: dir=auto on the div (shadow host), text in the shadow tree</title>
+<link rel="author" title="Eric Meyer" href="mailto:emeyer@igalia.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/C#the-dir-attribute">
+<link rel="help" href="https://github.com/whatwg/html/issues/3699">
+<link rel="help" href="https://github.com/whatwg/html/pull/9796">
+<style type="text/css">
+body {width: 600px;}
+div {border: 1px solid gray; margin: 1em;}
+</style>
+</head>
+<body>
+
+<p>`dir=auto` on the div (shadow host), text in the shadow tree</p>
+<div id="host" dir="auto">text.</div>
+<p id="result">The HTML direction / computed CSS `direction` value for the host’s text is: ltr / ltr.</p>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-23.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-23.html
new file mode 100644
index 0000000000..dea79b93e1
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-23.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>[dir] and shadow slots: dir=auto on the div (shadow host), text in the shadow tree</title>
+<link rel="author" title="Eric Meyer" href="mailto:emeyer@igalia.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/C#the-dir-attribute">
+<link rel="help" href="https://github.com/whatwg/html/issues/3699">
+<link rel="help" href="https://github.com/whatwg/html/pull/9796">
+<link rel="match" href="dir-shadow-23-ref.html">
+<style type="text/css">
+body {width: 600px;}
+div {border: 1px solid gray; margin: 1em;}
+</style>
+<script src="dir-shadow-utils.js"></script>
+</head>
+<body>
+
+<p>`dir=auto` on the div (shadow host), text in the shadow tree</p>
+<div id="host" dir="auto"></div>
+<p id="result">The HTML direction / computed CSS `direction` value for the host’s text is: </p>
+
+<script type="text/javascript">
+ let root = host.attachShadow({mode:"open"});
+ root.innerHTML = `text.`;
+ result.innerHTML += html_direction(host) + " / " + getComputedStyle(host).direction + '.';
+</script>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-24-ref.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-24-ref.html
new file mode 100644
index 0000000000..8453e94533
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-24-ref.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>[dir] and shadow slots: dir=auto on the div (shadow host), text in the shadow tree</title>
+<link rel="author" title="Eric Meyer" href="mailto:emeyer@igalia.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/C#the-dir-attribute">
+<link rel="help" href="https://github.com/whatwg/html/issues/3699">
+<link rel="help" href="https://github.com/whatwg/html/pull/9796">
+<style type="text/css">
+body {width: 600px;}
+div {border: 1px solid gray; margin: 1em;}
+</style>
+</head>
+<body>
+
+<p>`dir=auto` on the div (shadow host), text in the shadow tree</p>
+<div id="host" dir="ltr">اختبر.</div>
+<p id="result">The HTML direction / computed CSS `direction` value for the host’s text is: ltr / ltr.</p>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-24.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-24.html
new file mode 100644
index 0000000000..d26ccb270a
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-24.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>[dir] and shadow slots: dir=auto on the div (shadow host), text in the shadow tree</title>
+<link rel="author" title="Eric Meyer" href="mailto:emeyer@igalia.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/C#the-dir-attribute">
+<link rel="help" href="https://github.com/whatwg/html/issues/3699">
+<link rel="help" href="https://github.com/whatwg/html/pull/9796">
+<link rel="match" href="dir-shadow-24-ref.html">
+<style type="text/css">
+body {width: 600px;}
+div {border: 1px solid gray; margin: 1em;}
+</style>
+<script src="dir-shadow-utils.js"></script>
+</head>
+<body>
+
+<p>`dir=auto` on the div (shadow host), text in the shadow tree</p>
+<div id="host" dir="auto"></div>
+<p id="result">The HTML direction / computed CSS `direction` value for the host’s text is: </p>
+
+<script type="text/javascript">
+ let root = host.attachShadow({mode:"open"});
+ root.innerHTML = `اختبر.`;
+ result.innerHTML += html_direction(host) + " / " + getComputedStyle(host).direction + '.';
+</script>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-25-ref.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-25-ref.html
new file mode 100644
index 0000000000..5a2f6d5777
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-25-ref.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>[dir] and shadow slots: dir=ltr on a paragraph in the shadow tree, text in the light tree</title>
+<link rel="author" title="Eric Meyer" href="mailto:emeyer@igalia.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/C#the-dir-attribute">
+<link rel="help" href="https://github.com/whatwg/html/issues/3699">
+<link rel="help" href="https://github.com/whatwg/html/pull/9796">
+<style type="text/css">
+body {width: 600px;}
+div {border: 1px solid gray; margin: 1em;}
+div p {width: 50%; border: 1px dotted;}
+</style>
+</head>
+<body>
+
+<p>`dir=ltr` on a paragraph in the shadow tree, text in the light tree</p>
+<div id="host">
+<p dir="ltr">paragraph.</p>
+</div>
+<p id="result">The HTML direction / computed CSS `direction` value for the paragraph is: ltr / ltr.</p>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-25.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-25.html
new file mode 100644
index 0000000000..508b8260ff
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-25.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>[dir] and shadow slots: dir=ltr on a paragraph in the shadow tree, text in the light tree</title>
+<link rel="author" title="Eric Meyer" href="mailto:emeyer@igalia.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/C#the-dir-attribute">
+<link rel="help" href="https://github.com/whatwg/html/issues/3699">
+<link rel="help" href="https://github.com/whatwg/html/pull/9796">
+<link rel="match" href="dir-shadow-25-ref.html">
+<style type="text/css">
+body {width: 600px;}
+div {border: 1px solid gray; margin: 1em;}
+</style>
+<script src="dir-shadow-utils.js"></script>
+</head>
+<body>
+
+<p>`dir=ltr` on a paragraph in the shadow tree, text in the light tree</p>
+<div id="host">
+paragraph.
+</div>
+<p id="result">The HTML direction / computed CSS `direction` value for the paragraph is: </p>
+
+<script type="text/javascript">
+ let root = host.attachShadow({mode:"open"});
+ root.innerHTML = `<style>p {width: 50%; border: 1px dotted;}</style><p dir="ltr"><slot></slot></p>`;
+ result.innerHTML += html_direction(root.querySelector('p')) + " / " + getComputedStyle(root.querySelector('p')).direction + '.';
+</script>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-26-ref.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-26-ref.html
new file mode 100644
index 0000000000..41e1dbc8a8
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-26-ref.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>[dir] and shadow slots: dir=ltr on a paragraph in the shadow tree, text in the light tree</title>
+<link rel="author" title="Eric Meyer" href="mailto:emeyer@igalia.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/C#the-dir-attribute">
+<link rel="help" href="https://github.com/whatwg/html/issues/3699">
+<link rel="help" href="https://github.com/whatwg/html/pull/9796">
+<style type="text/css">
+body {width: 600px;}
+div {border: 1px solid gray; margin: 1em;}
+div p {width: 50%; border: 1px dotted;}
+</style>
+</head>
+<body>
+
+<p>`dir=ltr` on a paragraph in the shadow tree, text in the light tree</p>
+<div id="host">
+<p dir="ltr">اختبر.</p>
+</div>
+<p id="result">The HTML direction / computed CSS `direction` value for the paragraph is: ltr / ltr.</p>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-26.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-26.html
new file mode 100644
index 0000000000..b19cb976f8
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-26.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>[dir] and shadow slots: dir=ltr on a paragraph in the shadow tree, text in the light tree</title>
+<link rel="author" title="Eric Meyer" href="mailto:emeyer@igalia.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/C#the-dir-attribute">
+<link rel="help" href="https://github.com/whatwg/html/issues/3699">
+<link rel="help" href="https://github.com/whatwg/html/pull/9796">
+<link rel="match" href="dir-shadow-26-ref.html">
+<style type="text/css">
+body {width: 600px;}
+div {border: 1px solid gray; margin: 1em;}
+</style>
+<script src="dir-shadow-utils.js"></script>
+</head>
+<body>
+
+<p>`dir=ltr` on a paragraph in the shadow tree, text in the light tree</p>
+<div id="host">
+اختبر.
+</div>
+<p id="result">The HTML direction / computed CSS `direction` value for the paragraph is: </p>
+
+<script type="text/javascript">
+ let root = host.attachShadow({mode:"open"});
+ root.innerHTML = `<style>p {width: 50%; border: 1px dotted;}</style><p dir="ltr"><slot></slot></p>`;
+ result.innerHTML += html_direction(root.querySelector('p')) + " / " + getComputedStyle(root.querySelector('p')).direction + '.';
+</script>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-27-ref.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-27-ref.html
new file mode 100644
index 0000000000..075230d055
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-27-ref.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>[dir] and shadow slots: dir=rtl on a paragraph in the shadow tree, text in the light tree</title>
+<link rel="author" title="Eric Meyer" href="mailto:emeyer@igalia.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/C#the-dir-attribute">
+<link rel="help" href="https://github.com/whatwg/html/issues/3699">
+<link rel="help" href="https://github.com/whatwg/html/pull/9796">
+<style type="text/css">
+body {width: 600px;}
+div {border: 1px solid gray; margin: 1em;}
+div p {width: 50%; border: 1px dotted;}
+</style>
+</head>
+<body>
+
+<p>`dir=rtl` on a paragraph in the shadow tree, text in the light tree</p>
+<div id="host">
+<p dir="rtl">paragraph.</p>
+</div>
+<p id="result">The HTML direction / computed CSS `direction` value for the paragraph is: rtl / rtl.</p>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-27.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-27.html
new file mode 100644
index 0000000000..8380f17b21
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-27.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>[dir] and shadow slots: dir=rtl on a paragraph in the shadow tree, text in the light tree</title>
+<link rel="author" title="Eric Meyer" href="mailto:emeyer@igalia.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/C#the-dir-attribute">
+<link rel="help" href="https://github.com/whatwg/html/issues/3699">
+<link rel="help" href="https://github.com/whatwg/html/pull/9796">
+<link rel="match" href="dir-shadow-27-ref.html">
+<style type="text/css">
+body {width: 600px;}
+div {border: 1px solid gray; margin: 1em;}
+</style>
+<script src="dir-shadow-utils.js"></script>
+</head>
+<body>
+
+<p>`dir=rtl` on a paragraph in the shadow tree, text in the light tree</p>
+<div id="host">
+paragraph.
+</div>
+<p id="result">The HTML direction / computed CSS `direction` value for the paragraph is: </p>
+
+<script type="text/javascript">
+ let root = host.attachShadow({mode:"open"});
+ root.innerHTML = `<style>p {width: 50%; border: 1px dotted;}</style><p dir="rtl"><slot></slot></p>`;
+ result.innerHTML += html_direction(root.querySelector('p')) + " / " + getComputedStyle(root.querySelector('p')).direction + '.';
+</script>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-28-ref.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-28-ref.html
new file mode 100644
index 0000000000..580f5fe3b1
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-28-ref.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>[dir] and shadow slots: dir=rtl on a paragraph in the shadow tree, text in the light tree</title>
+<link rel="author" title="Eric Meyer" href="mailto:emeyer@igalia.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/C#the-dir-attribute">
+<link rel="help" href="https://github.com/whatwg/html/issues/3699">
+<link rel="help" href="https://github.com/whatwg/html/pull/9796">
+<style type="text/css">
+body {width: 600px;}
+div {border: 1px solid gray; margin: 1em;}
+div p {width: 50%; border: 1px dotted;}
+</style>
+</head>
+<body>
+
+<p>`dir=rtl` on a paragraph in the shadow tree, text in the light tree</p>
+<div id="host">
+<p dir="rtl">اختبر.</p>
+</div>
+<p id="result">The HTML direction / computed CSS `direction` value for the paragraph is: rtl / rtl.</p>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-28.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-28.html
new file mode 100644
index 0000000000..3a0d6756b3
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-28.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>[dir] and shadow slots: dir=rtl on a paragraph in the shadow tree, text in the light tree</title>
+<link rel="author" title="Eric Meyer" href="mailto:emeyer@igalia.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/C#the-dir-attribute">
+<link rel="help" href="https://github.com/whatwg/html/issues/3699">
+<link rel="help" href="https://github.com/whatwg/html/pull/9796">
+<link rel="match" href="dir-shadow-28-ref.html">
+<style type="text/css">
+body {width: 600px;}
+div {border: 1px solid gray; margin: 1em;}
+</style>
+<script src="dir-shadow-utils.js"></script>
+</head>
+<body>
+
+<p>`dir=rtl` on a paragraph in the shadow tree, text in the light tree</p>
+<div id="host">
+اختبر.
+</div>
+<p id="result">The HTML direction / computed CSS `direction` value for the paragraph is: </p>
+
+<script type="text/javascript">
+ let root = host.attachShadow({mode:"open"});
+ root.innerHTML = `<style>p {width: 50%; border: 1px dotted;}</style><p dir="rtl"><slot></slot></p>`;
+ result.innerHTML += html_direction(root.querySelector('p')) + " / " + getComputedStyle(root.querySelector('p')).direction + '.';
+</script>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-29-ref.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-29-ref.html
new file mode 100644
index 0000000000..4b949acb09
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-29-ref.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>[dir] and shadow slots: dir=auto on a paragraph in the shadow tree, text in the light tree</title>
+<link rel="author" title="Eric Meyer" href="mailto:emeyer@igalia.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/C#the-dir-attribute">
+<link rel="help" href="https://github.com/whatwg/html/issues/3699">
+<link rel="help" href="https://github.com/whatwg/html/pull/9796">
+<style type="text/css">
+body {width: 600px;}
+div {border: 1px solid gray; margin: 1em;}
+div p {width: 50%; border: 1px dotted;}
+</style>
+</head>
+<body>
+
+<p>`dir=auto` on a paragraph in the shadow tree, text in the light tree</p>
+<div id="host">
+<p dir="ltr">para.</p>
+</div>
+<p id="result">The HTML direction / computed CSS `direction` value for the paragraph is: ltr / ltr.</p>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-29.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-29.html
new file mode 100644
index 0000000000..46cbf8d291
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-29.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>[dir] and shadow slots: dir=auto on a paragraph in the shadow tree, text in the light tree</title>
+<link rel="author" title="Eric Meyer" href="mailto:emeyer@igalia.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/C#the-dir-attribute">
+<link rel="help" href="https://github.com/whatwg/html/issues/3699">
+<link rel="help" href="https://github.com/whatwg/html/pull/9796">
+<link rel="match" href="dir-shadow-29-ref.html">
+<style type="text/css">
+body {width: 600px;}
+div {border: 1px solid gray; margin: 1em;}
+</style>
+<script src="dir-shadow-utils.js"></script>
+</head>
+<body>
+
+<p>`dir=auto` on a paragraph in the shadow tree, text in the light tree</p>
+<div id="host">
+para.
+</div>
+<p id="result">The HTML direction / computed CSS `direction` value for the paragraph is: </p>
+
+<script type="text/javascript">
+ let root = host.attachShadow({mode:"open"});
+ root.innerHTML = `<style>p {width: 50%; border: 1px dotted;}</style><p dir="auto"><slot></slot></p>`;
+ result.innerHTML += html_direction(root.querySelector('p')) + " / " + getComputedStyle(root.querySelector('p')).direction + '.';
+</script>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-30-ref.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-30-ref.html
new file mode 100644
index 0000000000..be2cc44abd
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-30-ref.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>[dir] and shadow slots: dir=auto on a paragraph in the shadow tree, text in the light tree</title>
+<link rel="author" title="Eric Meyer" href="mailto:emeyer@igalia.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/C#the-dir-attribute">
+<link rel="help" href="https://github.com/whatwg/html/issues/3699">
+<link rel="help" href="https://github.com/whatwg/html/pull/9796">
+<style type="text/css">
+body {width: 600px;}
+div {border: 1px solid gray; margin: 1em;}
+div p {width: 50%; border: 1px dotted;}
+</style>
+</head>
+<body>
+
+<p>`dir=auto` on a paragraph in the shadow tree, text in the light tree</p>
+<div id="host">
+<p dir="ltr">اختبر.</p>
+</div>
+<p id="result">The HTML direction / computed CSS `direction` value for the paragraph is: ltr / ltr.</p>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-30.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-30.html
new file mode 100644
index 0000000000..2a3e56e62c
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-30.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>[dir] and shadow slots: dir=auto on a paragraph in the shadow tree, text in the light tree</title>
+<link rel="author" title="Eric Meyer" href="mailto:emeyer@igalia.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/C#the-dir-attribute">
+<link rel="help" href="https://github.com/whatwg/html/issues/3699">
+<link rel="help" href="https://github.com/whatwg/html/pull/9796">
+<link rel="match" href="dir-shadow-30-ref.html">
+<style type="text/css">
+body {width: 600px;}
+div {border: 1px solid gray; margin: 1em;}
+</style>
+<script src="dir-shadow-utils.js"></script>
+</head>
+<body>
+
+<p>`dir=auto` on a paragraph in the shadow tree, text in the light tree</p>
+<div id="host">
+اختبر.
+</div>
+<p id="result">The HTML direction / computed CSS `direction` value for the paragraph is: </p>
+
+<script type="text/javascript">
+ let root = host.attachShadow({mode:"open"});
+ root.innerHTML = `<style>p {width: 50%; border: 1px dotted;}</style><p dir="auto"><slot></slot></p>`;
+ result.innerHTML += html_direction(root.querySelector('p')) + " / " + getComputedStyle(root.querySelector('p')).direction + '.';
+</script>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-31-ref.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-31-ref.html
new file mode 100644
index 0000000000..1c5b5b11a8
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-31-ref.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>[dir] and shadow slots: dir=rtl on the slot, span in the light tree</title>
+<link rel="author" title="Eric Meyer" href="mailto:emeyer@igalia.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/C#the-dir-attribute">
+<link rel="help" href="https://github.com/whatwg/html/issues/3699">
+<link rel="help" href="https://github.com/whatwg/html/pull/9796">
+<style type="text/css">
+body {width: 600px;}
+div {border: 1px solid gray; margin: 1em; padding: 0.25em;}
+span {border: 1px solid silver;}
+</style>
+</head>
+<body>
+
+<p>`dir=rtl` on the slot, span in the light tree</p>
+<div id="host" dir="ltr"><span dir="rtl" style="unicode-bidi: normal">RTL.</span></div>
+<p id="result">The HTML direction / computed CSS `direction` value for the span is: ltr / rtl.</p>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-31.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-31.html
new file mode 100644
index 0000000000..d48a0f8c04
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-31.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>[dir] and shadow slots: dir=rtl on the slot, span in the light tree</title>
+<link rel="author" title="Eric Meyer" href="mailto:emeyer@igalia.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/C#the-dir-attribute">
+<link rel="help" href="https://github.com/whatwg/html/issues/3699">
+<link rel="help" href="https://github.com/whatwg/html/pull/9796">
+<link rel="match" href="dir-shadow-31-ref.html">
+<style type="text/css">
+body {width: 600px;}
+div {border: 1px solid gray; margin: 1em; padding: 0.25em;}
+span {border: 1px solid silver;}
+
+</style>
+<script src="dir-shadow-utils.js"></script>
+</head>
+<body>
+
+<p>`dir=rtl` on the slot, span in the light tree</p>
+<div id="host" dir="ltr"><span>RTL.</span></div>
+<p id="result">The HTML direction / computed CSS `direction` value for the span is: </p>
+
+<script type="text/javascript">
+ let root = host.attachShadow({mode:"open"});
+ root.innerHTML = `<slot dir="rtl"></slot>`;
+ result.innerHTML += html_direction(host.querySelector('span')) + " / " + getComputedStyle(host.querySelector('span')).direction + '.';
+</script>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-32-ref.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-32-ref.html
new file mode 100644
index 0000000000..6e5d9a96e8
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-32-ref.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>[dir] and shadow slots: dir=rtl on the shadow host, span in the shadow tree</title>
+<link rel="author" title="Eric Meyer" href="mailto:emeyer@igalia.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/C#the-dir-attribute">
+<link rel="help" href="https://github.com/whatwg/html/issues/3699">
+<link rel="help" href="https://github.com/whatwg/html/pull/9796">
+<style type="text/css">
+body {width: 600px;}
+div {border: 1px solid gray; margin: 1em; padding: 0.25em;}
+span {border: 1px solid silver;}
+</style>
+</head>
+<body>
+
+<p>`dir=rtl` on the shadow host, span in the shadow tree</p>
+<div id="host" dir="rtl"><span>RTL.</span></div>
+<p id="result">The HTML direction / computed CSS `direction` value for the shadow span is: rtl / rtl.</p>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-32.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-32.html
new file mode 100644
index 0000000000..ac9c9e4579
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-32.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>[dir] and shadow slots: dir=rtl on the shadow host, span in the shadow tree</title>
+<link rel="author" title="Eric Meyer" href="mailto:emeyer@igalia.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/C#the-dir-attribute">
+<link rel="help" href="https://github.com/whatwg/html/issues/3699">
+<link rel="help" href="https://github.com/whatwg/html/pull/9796">
+<link rel="match" href="dir-shadow-32-ref.html">
+<style type="text/css">
+body {width: 600px;}
+div {border: 1px solid gray; margin: 1em; padding: 0.25em;}
+</style>
+<script src="dir-shadow-utils.js"></script>
+</head>
+<body>
+
+<p>`dir=rtl` on the shadow host, span in the shadow tree</p>
+<div id="host" dir="rtl"></div>
+<p id="result">The HTML direction / computed CSS `direction` value for the shadow span is: </p>
+
+<script type="text/javascript">
+ let root = host.attachShadow({mode:"open"});
+ root.innerHTML = `<style>span {border: 1px solid silver;}</style><span>RTL.</span>`;
+ result.innerHTML += html_direction(root.querySelector('span')) + " / " + getComputedStyle(root.querySelector('span')).direction + '.';
+</script>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-33-ref.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-33-ref.html
new file mode 100644
index 0000000000..cdf89d78bb
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-33-ref.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>[dir] and shadow slots: dir=auto on the span (shadow host), text in the shadow tree</title>
+<link rel="author" title="Eric Meyer" href="mailto:emeyer@igalia.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/C#the-dir-attribute">
+<link rel="help" href="https://github.com/whatwg/html/issues/3699">
+<link rel="help" href="https://github.com/whatwg/html/pull/9796">
+<style type="text/css">
+body {width: 600px;}
+div {border: 1px solid gray; margin: 1em; padding: 0.25em;}
+span {border: 1px solid silver;}
+</style>
+</head>
+<body>
+
+<p>`dir=auto` on the span (shadow host), text in the shadow tree</p>
+<span id="host" dir="ltr">اختبر.</span>
+<p id="result">The HTML direction / computed CSS `direction` value for the shadow host is: ltr / ltr.</p>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-33.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-33.html
new file mode 100644
index 0000000000..814e3b34d6
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-33.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>[dir] and shadow slots: dir=auto on the span (shadow host), text in the shadow tree</title>
+<link rel="author" title="Eric Meyer" href="mailto:emeyer@igalia.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/C#the-dir-attribute">
+<link rel="help" href="https://github.com/whatwg/html/issues/3699">
+<link rel="help" href="https://github.com/whatwg/html/pull/9796">
+<link rel="match" href="dir-shadow-33-ref.html">
+<style type="text/css">
+body {width: 600px;}
+div {border: 1px solid gray; margin: 1em; padding: 0.25em;}
+span {border: 1px solid silver;}
+
+</style>
+<script src="dir-shadow-utils.js"></script>
+</head>
+<body>
+
+<p>`dir=auto` on the span (shadow host), text in the shadow tree</p>
+<span id="host" dir="auto"></span>
+<p id="result">The HTML direction / computed CSS `direction` value for the shadow host is: </p>
+
+<script type="text/javascript">
+ let root = host.attachShadow({mode:"open"});
+ root.innerHTML = `اختبر.`;
+ result.innerHTML += html_direction(host) + " / " + getComputedStyle(host).direction + '.';
+</script>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-34-ref.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-34-ref.html
new file mode 100644
index 0000000000..4cedca8e50
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-34-ref.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>[dir] and shadow slots: dir=auto on a span in the shadow tree, text in the light tree</title>
+<link rel="author" title="Eric Meyer" href="mailto:emeyer@igalia.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/C#the-dir-attribute">
+<link rel="help" href="https://github.com/whatwg/html/issues/3699">
+<link rel="help" href="https://github.com/whatwg/html/pull/9796">
+<style type="text/css">
+body {width: 600px;}
+div {border: 1px solid gray; margin: 1em; padding: 0.25em;}
+</style>
+</head>
+<body>
+
+<p>`dir=auto` on a span in the shadow tree, text in the light tree</p>
+<div id="host"><span dir="ltr">اختبر.</span></div>
+<p id="result">The HTML direction / computed CSS `direction` value for the shadow span is: ltr / ltr.</p>
+
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-34.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-34.html
new file mode 100644
index 0000000000..07f75d216a
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-34.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>[dir] and shadow slots: dir=auto on a span in the shadow tree, text in the light tree</title>
+<link rel="author" title="Eric Meyer" href="mailto:emeyer@igalia.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/C#the-dir-attribute">
+<link rel="help" href="https://github.com/whatwg/html/issues/3699">
+<link rel="help" href="https://github.com/whatwg/html/pull/9796">
+<link rel="match" href="dir-shadow-34-ref.html">
+<style type="text/css">
+body {width: 600px;}
+div {border: 1px solid gray; margin: 1em; padding: 0.25em;}
+span {border: 1px solid silver;}
+
+</style>
+<script src="dir-shadow-utils.js"></script>
+</head>
+<body>
+
+<p>`dir=auto` on a span in the shadow tree, text in the light tree</p>
+<div id="host">اختبر.</div>
+<p id="result">The HTML direction / computed CSS `direction` value for the shadow span is: </p>
+
+<script type="text/javascript">
+ let root = host.attachShadow({mode:"open"});
+ root.innerHTML = `<span dir="auto"><slot></slot></span>`;
+ result.innerHTML += html_direction(root.querySelector("span")) + " / " + getComputedStyle(root.querySelector("span")).direction + '.';
+</script>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-35-ref.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-35-ref.html
new file mode 100644
index 0000000000..fdcc2657f3
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-35-ref.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>[dir] and shadow slots: dir=ltr on a div in the shadow tree, text in the light tree</title>
+<link rel="author" title="Eric Meyer" href="mailto:emeyer@igalia.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/C#the-dir-attribute">
+<link rel="help" href="https://github.com/whatwg/html/issues/3699">
+<link rel="help" href="https://github.com/whatwg/html/pull/9796">
+<style type="text/css">
+body {width: 600px;}
+div#host {border: 1px solid gray; margin: 1em; padding: 0.25em;}
+span {border: 1px solid silver;}
+</style>
+</head>
+<body>
+
+<p>`dir=ltr` on a div in the shadow tree, text in the light tree</p>
+<div id="host" dir="rtl"><div dir="ltr"><span>اختبر.</span></div></div>
+<p id="result">The HTML direction / computed CSS `direction` value for the slot is: ltr / ltr.</p>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-35.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-35.html
new file mode 100644
index 0000000000..8d063f44e6
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-35.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>[dir] and shadow slots: dir=ltr on a div in the shadow tree, text in the light tree</title>
+<link rel="author" title="Eric Meyer" href="mailto:emeyer@igalia.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/C#the-dir-attribute">
+<link rel="help" href="https://github.com/whatwg/html/issues/3699">
+<link rel="help" href="https://github.com/whatwg/html/pull/9796">
+<link rel="match" href="dir-shadow-35-ref.html">
+<style type="text/css">
+body {width: 600px;}
+div {border: 1px solid gray; margin: 1em; padding: 0.25em;}
+span {border: 1px solid silver;}
+
+</style>
+<script src="dir-shadow-utils.js"></script>
+</head>
+<body>
+
+<p>`dir=ltr` on a div in the shadow tree, text in the light tree</p>
+<div id="host" dir="rtl"><span>اختبر.</span></div>
+<p id="result">The HTML direction / computed CSS `direction` value for the slot is: </p>
+
+<script type="text/javascript">
+ let root = host.attachShadow({mode:"open"});
+ root.innerHTML = `<div dir="ltr"><slot></slot></div>`;
+ result.innerHTML += html_direction(root.querySelector("div").firstChild) + " / " + getComputedStyle(root.querySelector("div").firstChild).direction + '.';
+</script>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-36-ref.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-36-ref.html
new file mode 100644
index 0000000000..f8af117e3b
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-36-ref.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>[dir] and shadow slots: dir=auto and text in a slot in the shadow tree, text in the light tree</title>
+<link rel="author" title="Eric Meyer" href="mailto:emeyer@igalia.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/C#the-dir-attribute">
+<link rel="help" href="https://github.com/whatwg/html/issues/3699">
+<link rel="help" href="https://github.com/whatwg/html/pull/9796">
+<style type="text/css">
+body {width: 600px;}
+div {border: 1px solid gray; margin: 1em; padding: 0.25em;}
+span {border: 1px solid silver;}
+</style>
+</head>
+<body>
+
+<p>`dir=auto` and text in a slot in the shadow tree, text in the light tree</p>
+<div id="host">English.</div>
+<p id="result">The HTML direction / computed CSS `direction` value for the light tree text is: ltr / ltr (on the slot) and ltr / ltr (on the host).</p>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-36.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-36.html
new file mode 100644
index 0000000000..ff4f11b3a6
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-36.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>[dir] and shadow slots: dir=auto and text in a slot in the shadow tree, text in the light tree</title>
+<link rel="author" title="Eric Meyer" href="mailto:emeyer@igalia.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/C#the-dir-attribute">
+<link rel="help" href="https://github.com/whatwg/html/issues/3699">
+<link rel="help" href="https://github.com/whatwg/html/pull/9796">
+<link rel="match" href="dir-shadow-36-ref.html">
+<style type="text/css">
+body {width: 600px;}
+div {border: 1px solid gray; margin: 1em; padding: 0.25em;}
+span {border: 1px solid silver;}
+
+</style>
+<script src="dir-shadow-utils.js"></script>
+</head>
+<body>
+
+<p>`dir=auto` and text in a slot in the shadow tree, text in the light tree</p>
+<div id="host">English.</div>
+<p id="result">The HTML direction / computed CSS `direction` value for the light tree text is: </p>
+
+<script type="text/javascript">
+ let root = host.attachShadow({mode:"open"});
+ root.innerHTML = `<slot dir=auto>اختبر</slot>`;
+ result.innerHTML += html_direction(root.firstChild) + " / " + getComputedStyle(root.firstChild).direction + " (on the " + root.firstChild.localName + ') and ' + html_direction(host) + " / " + getComputedStyle(host).direction + ' (on the ' + host.id + ').';
+</script>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-37-ref.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-37-ref.html
new file mode 100644
index 0000000000..5941b23c02
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-37-ref.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>[dir] and shadow slots: dir=auto and text in a div in the shadow tree, text in the light tree</title>
+<link rel="author" title="Eric Meyer" href="mailto:emeyer@igalia.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/C#the-dir-attribute">
+<link rel="help" href="https://github.com/whatwg/html/issues/3699">
+<link rel="help" href="https://github.com/whatwg/html/pull/9796">
+<style type="text/css">
+body {width: 600px;}
+div {border: 1px solid gray; margin: 1em; padding: 0.25em;}
+span {border: 1px solid silver;}
+</style>
+</head>
+<body>
+
+<p>`dir=auto` and text in a div in the shadow tree, text in the light tree</p>
+<div id="host" dir="rtl">اختبر.123 456.</div>
+<p id="result">The HTML direction / computed CSS `direction` value for the light tree text is: rtl / rtl (on the div) and ltr / ltr (on the host).</p>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-37.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-37.html
new file mode 100644
index 0000000000..ba0480636a
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-37.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>[dir] and shadow slots: dir=auto and text in a div in the shadow tree, text in the light tree</title>
+<link rel="author" title="Eric Meyer" href="mailto:emeyer@igalia.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/C#the-dir-attribute">
+<link rel="help" href="https://github.com/whatwg/html/issues/3699">
+<link rel="help" href="https://github.com/whatwg/html/pull/9796">
+<link rel="match" href="dir-shadow-37-ref.html">
+<style type="text/css">
+body {width: 600px;}
+div {border: 1px solid gray; margin: 1em; padding: 0.25em;}
+span {border: 1px solid silver;}
+
+</style>
+<script src="dir-shadow-utils.js"></script>
+</head>
+<body>
+
+<p>`dir=auto` and text in a div in the shadow tree, text in the light tree</p>
+<div id="host">123 456.</div>
+<p id="result">The HTML direction / computed CSS `direction` value for the light tree text is: </p>
+
+<script type="text/javascript">
+ let root = host.attachShadow({mode:"open"});
+ root.innerHTML = `<div dir="auto">اختبر.<slot></slot></div>`;
+ result.innerHTML += html_direction(root.firstChild) + " / " + getComputedStyle(root.firstChild).direction + " (on the " + root.firstChild.localName + ') and ' + html_direction(host) + " / " + getComputedStyle(host).direction + ' (on the ' + host.id + ').';
+</script>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-38-ref.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-38-ref.html
new file mode 100644
index 0000000000..f8af117e3b
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-38-ref.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>[dir] and shadow slots: dir=auto and text in a slot in the shadow tree, text in the light tree</title>
+<link rel="author" title="Eric Meyer" href="mailto:emeyer@igalia.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/C#the-dir-attribute">
+<link rel="help" href="https://github.com/whatwg/html/issues/3699">
+<link rel="help" href="https://github.com/whatwg/html/pull/9796">
+<style type="text/css">
+body {width: 600px;}
+div {border: 1px solid gray; margin: 1em; padding: 0.25em;}
+span {border: 1px solid silver;}
+</style>
+</head>
+<body>
+
+<p>`dir=auto` and text in a slot in the shadow tree, text in the light tree</p>
+<div id="host">English.</div>
+<p id="result">The HTML direction / computed CSS `direction` value for the light tree text is: ltr / ltr (on the slot) and ltr / ltr (on the host).</p>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-38.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-38.html
new file mode 100644
index 0000000000..e8f25eb568
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-38.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>[dir] and shadow slots: dir=auto and text in a slot in the shadow tree, text in the light tree</title>
+<link rel="author" title="Eric Meyer" href="mailto:emeyer@igalia.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/C#the-dir-attribute">
+<link rel="help" href="https://github.com/whatwg/html/issues/3699">
+<link rel="help" href="https://github.com/whatwg/html/pull/9796">
+<link rel="match" href="dir-shadow-38-ref.html">
+<style type="text/css">
+body {width: 600px;}
+div {border: 1px solid gray; margin: 1em; padding: 0.25em;}
+span {border: 1px solid silver;}
+
+</style>
+<script src="dir-shadow-utils.js"></script>
+</head>
+<body>
+
+<p>`dir=auto` and text in a slot in the shadow tree, text in the light tree</p>
+<div id="host">English.</div>
+<p id="result">The HTML direction / computed CSS `direction` value for the light tree text is: </p>
+
+<script type="text/javascript">
+ let root = host.attachShadow({mode:"open"});
+ root.innerHTML = `<slot dir=auto>اختبر.</slot>`;
+ result.innerHTML += html_direction(root.firstChild) + " / " + getComputedStyle(root.firstChild).direction + " (on the " + root.firstChild.localName + ') and ' + html_direction(host) + " / " + getComputedStyle(host).direction + ' (on the ' + host.id + ').';
+</script>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-39-ref.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-39-ref.html
new file mode 100644
index 0000000000..8f75e9877c
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-39-ref.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>[dir] and shadow slots: text in the light tree, slotted node</title>
+<link rel="author" title="Eric Meyer" href="mailto:emeyer@igalia.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/C#the-dir-attribute">
+<link rel="help" href="https://github.com/whatwg/html/issues/3699">
+<link rel="help" href="https://github.com/whatwg/html/pull/9796">
+<style type="text/css">
+body {width: 600px;}
+div {border: 1px solid gray; margin: 1em; padding: 0.25em;}
+span {border: 1px solid silver;}
+
+</style>
+</head>
+<body>
+
+<p>text in the light tree, slotted node</p>
+<div id="host">slotted text.</div>
+<p id="result">The HTML direction / computed CSS `direction` value for the defaultContent when there is a slotted node: ltr / ltr (on the div).</p>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-39.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-39.html
new file mode 100644
index 0000000000..72fdd665fc
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-39.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>[dir] and shadow slots: text in the light tree, slotted node</title>
+<link rel="author" title="Eric Meyer" href="mailto:emeyer@igalia.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/C#the-dir-attribute">
+<link rel="help" href="https://github.com/whatwg/html/issues/3699">
+<link rel="help" href="https://github.com/whatwg/html/pull/9796">
+<link rel="match" href="dir-shadow-39-ref.html">
+<style type="text/css">
+body {width: 600px;}
+div {border: 1px solid gray; margin: 1em; padding: 0.25em;}
+span {border: 1px solid silver;}
+
+</style>
+<script src="dir-shadow-utils.js"></script>
+</head>
+<body>
+
+<p>text in the light tree, slotted node</p>
+<div id="host">slotted text.</div>
+<p id="result">The HTML direction / computed CSS `direction` value for the defaultContent when there is a slotted node: </p>
+
+<script type="text/javascript">
+ let root = host.attachShadow({mode:"open"});
+ root.innerHTML = `<slot dir=auto><div>&#1571;&#1582;&#1576;&#1575;&#1585;</div>.</slot>`;
+ result.innerHTML += html_direction(root.firstChild.firstChild) + " / " + getComputedStyle(root.firstChild.firstChild).direction + " (on the " + root.firstChild.firstChild.localName + ').';
+</script>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-40-ref.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-40-ref.html
new file mode 100644
index 0000000000..c1c074812b
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-40-ref.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>[dir] and shadow slots: text in the light tree, no slotted node</title>
+<link rel="author" title="Eric Meyer" href="mailto:emeyer@igalia.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/C#the-dir-attribute">
+<link rel="help" href="https://github.com/whatwg/html/issues/3699">
+<link rel="help" href="https://github.com/whatwg/html/pull/9796">
+<style type="text/css">
+body {width: 600px;}
+div {border: 1px solid gray; margin: 1em; padding: 0.25em;}
+span {border: 1px solid silver;}
+</style>
+</head>
+<body>
+
+<p>text in the light tree, no slotted node</p>
+<div id="host" dir="rtl">&#1571;&#1582;&#1576;&#1575;&#1585;.</div>
+<p id="result">The HTML direction / computed CSS `direction` value for the defaultContent when there is not a slotted node: rtl / rtl (on the div).</p>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-40.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-40.html
new file mode 100644
index 0000000000..567f4fa9da
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-40.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>[dir] and shadow slots: text in the light tree, no slotted node</title>
+<link rel="author" title="Eric Meyer" href="mailto:emeyer@igalia.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/C#the-dir-attribute">
+<link rel="help" href="https://github.com/whatwg/html/issues/3699">
+<link rel="help" href="https://github.com/whatwg/html/pull/9796">
+<link rel="match" href="dir-shadow-40-ref.html">
+<style type="text/css">
+body {width: 600px;}
+div {border: 1px solid gray; margin: 1em; padding: 0.25em;}
+span {border: 1px solid silver;}
+
+</style>
+<script src="dir-shadow-utils.js"></script>
+</head>
+<body>
+
+<p>text in the light tree, no slotted node</p>
+<div id="host"></div>
+<p id="result">The HTML direction / computed CSS `direction` value for the defaultContent when there is not a slotted node: </p>
+
+<script type="text/javascript">
+ let root = host.attachShadow({mode:"open"});
+ root.innerHTML = `<slot dir=auto><div>&#1571;&#1582;&#1576;&#1575;&#1585;.</div></slot>`;
+ result.innerHTML += html_direction(root.firstChild.firstChild) + " / " + getComputedStyle(root.firstChild.firstChild).direction + " (on the " + root.firstChild.firstChild.localName + ').';
+</script>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-41-ref.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-41-ref.html
new file mode 100644
index 0000000000..b52e08df20
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-41-ref.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>[dir] and shadow slots: dir=ltr on a div in the shadow tree, dir=rtl on the shadow host, no slotted text in the light or dark trees</title>
+<link rel="author" title="Eric Meyer" href="mailto:emeyer@igalia.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/C#the-dir-attribute">
+<link rel="help" href="https://github.com/whatwg/html/issues/3699">
+<link rel="help" href="https://github.com/whatwg/html/pull/9796">
+<style type="text/css">
+body {width: 600px;}
+#host {border: 1px solid gray; margin: 1em; padding: 0.25em;}
+span {border: 1px solid silver;}
+
+</style>
+</head>
+<body>
+
+<p>`dir=rtl` on a div in the shadow tree, `dir=ltr` on the shadow host, no slotted text in the light or dark trees</p>
+<div id="host" dir="ltr"><div dir="rtl"><span></span></div></div>
+<p id="result">The HTML direction / computed CSS `direction` value is: rtl / rtl (on the slot).</p>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-41.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-41.html
new file mode 100644
index 0000000000..6c025fb3de
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-41.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>[dir] and shadow slots: dir=ltr on a div in the shadow tree, dir=rtl on the shadow host, no slotted text in the light or dark trees</title>
+<link rel="author" title="Eric Meyer" href="mailto:emeyer@igalia.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/C#the-dir-attribute">
+<link rel="help" href="https://github.com/whatwg/html/issues/3699">
+<link rel="help" href="https://github.com/whatwg/html/pull/9796">
+<link rel="match" href="dir-shadow-41-ref.html">
+<style type="text/css">
+body {width: 600px;}
+#host {border: 1px solid gray; margin: 1em; padding: 0.25em;}
+span {border: 1px solid silver;}
+
+</style>
+<script src="dir-shadow-utils.js"></script>
+</head>
+<body>
+
+<p>`dir=rtl` on a div in the shadow tree, `dir=ltr` on the shadow host, no slotted text in the light or dark trees</p>
+<div id="host" dir="ltr"><span slot="x1"></span></div>
+<p id="result">The HTML direction / computed CSS `direction` value is: </p>
+
+<script type="text/javascript">
+ let root = host.attachShadow({mode:"open"});
+ root.innerHTML = `<div dir="rtl"><slot dir="auto" name="x1"></slot></div>`;
+ result.innerHTML += html_direction(root.querySelector("div[dir=rtl]").firstChild) + " / " + getComputedStyle(root.querySelector("div[dir=rtl]").firstChild).direction + " (on the " + root.querySelector("div[dir=rtl]").firstChild.localName + ').';
+</script>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-utils.js b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-utils.js
new file mode 100644
index 0000000000..c7d89cf908
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-shadow-utils.js
@@ -0,0 +1,8 @@
+function html_direction(element) {
+ let is_ltr = element.matches(":dir(ltr)");
+ let is_rtl = element.matches(":dir(rtl)");
+ if (is_ltr == is_rtl) {
+ return "error";
+ }
+ return is_ltr ? "ltr" : "rtl";
+}
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir-slots-directionality.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-slots-directionality.html
new file mode 100644
index 0000000000..db783fc55c
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir-slots-directionality.html
@@ -0,0 +1,97 @@
+<!doctype html>
+<title>HTML Test: dir=auto|rtl with slots, and direction should be RTL</title>
+<meta charset="UTF-8">
+<meta name="author" title="Miyoung Shin" href="mailto:myid.shin@igalia.com">
+<meta name="author" title="L. David Baron" href="mailto:dbaron@chromium.org">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#the-dir-attribute"/>
+<link rel="help" href="https://github.com/whatwg/html/issues/3699">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="host1"><span></span></div>
+<div id="host2" dir="rtl"></div>
+<span id="host3" dir="auto"></span>
+<div id="host4">اختبر</div>
+<div id="host5"></div>
+<div id="host6">اختبر</div>
+<script>
+
+test(() => {
+ let root1 = host1.attachShadow({mode:"open"});
+ root1.innerHTML = '<slot dir="rtl"></slot>';
+ let span = host1.firstChild;
+ assert_equals(getComputedStyle(span).direction, "rtl");
+ assert_true(span.matches(":dir(ltr)"));
+}, 'Slots: Directionality: dir=rtl on slot');
+
+test(() => {
+ let root2 = host2.attachShadow({mode:"open"});
+ root2.innerHTML = '<span></span>';
+ let span = root2.querySelector("span");
+ assert_equals(getComputedStyle(span).direction, "rtl");
+ assert_true(span.matches(":dir(rtl)"));
+}, 'Slots: Directionality: dir=rtl on host');
+
+test(() => {
+ let root3 = host3.attachShadow({mode:"open"});
+ root3.innerHTML = `اختبر`;
+ let span = host3;
+ assert_equals(getComputedStyle(span).direction, "ltr");
+ assert_true(span.matches(":dir(ltr)"));
+}, 'Slots: Directionality: dir=auto on host with Arabic shadow tree content');
+
+test(() => {
+ let root4 = host4.attachShadow({mode:"open"});
+ root4.innerHTML = '<span dir="auto"><slot></slot></span>';
+ let span = root4.querySelector("span");
+ assert_equals(getComputedStyle(span).direction, "ltr");
+ assert_true(span.matches(":dir(ltr)"));
+}, 'Slots: Directionality: dir=auto in shadow tree with Arabic light tree content');
+
+test(() => {
+ let root5 = host5.attachShadow({mode:"open"});
+ root5.innerHTML = '<span dir="auto"><slot>اختبر</slot></span>';
+ let span = root5.querySelector("span");
+ assert_equals(getComputedStyle(span).direction, "ltr");
+ assert_true(span.matches(":dir(ltr)"));
+}, 'Slots: Directionality: dir=auto in shadow tree with Arabic shadow tree content');
+
+test(() => {
+ let root6 = host6.attachShadow({mode:"open"});
+ root6.innerHTML = '<slot dir="auto"></slot>';
+ let span = root6.querySelector("slot");
+ assert_equals(getComputedStyle(span).direction, "rtl");
+ assert_true(span.matches(":dir(rtl)"));
+}, 'Slots: Directionality: dir=auto on slot with Arabic light tree content');
+
+test(() => {
+ let host = document.createElement("div");
+ host.dir = "rtl";
+ document.body.appendChild(host);
+ let root = host.attachShadow({mode:"open"});
+ root.innerHTML = '<section dir="ltr"><div dir="auto"><slot></slot>A</div></section>';
+ let div = root.querySelector("div");
+ assert_true(div.matches(":dir(rtl)"));
+ host.remove();
+}, 'slot provides its directionality (from host) to a dir=auto container');
+
+test(() => {
+ let host = document.createElement("div");
+ document.body.appendChild(host);
+ let root = host.attachShadow({mode:"open"});
+ root.innerHTML = '<div dir="auto"><span dir="ltr">A</span>\u05D0</div><slot></slot>';
+ let div = root.querySelector("div");
+ assert_true(div.matches(":dir(rtl)"));
+ host.remove();
+}, 'children with dir attribute are skipped by dir=auto');
+
+test(() => {
+ let host = document.createElement("div");
+ document.body.appendChild(host);
+ let root = host.attachShadow({mode:"open"});
+ root.innerHTML = '<div dir="auto"><slot dir="ltr"></slot>\u05D0</div>';
+ let div = root.querySelector("div");
+ assert_true(div.matches(":dir(rtl)"));
+ host.remove();
+}, 'slot with dir attribute is skipped by dir=auto');
+
+</script>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-EN-L-ref.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-EN-L-ref.html
new file mode 100644
index 0000000000..de6e13b3a3
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-EN-L-ref.html
@@ -0,0 +1,57 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>HTML Test: dir=auto, start with EN, then L</title>
+ <link rel="author" title="Matitiahu Allouche" href="mailto:matitiahu.allouche@google.com" />
+ <link rel="author" title="Oren Roth" href="mailto:oren.roth@gmail.com" />
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-dir-attribute" />
+ <meta name="assert" content="
+ When dir='auto', the direction is set according to the first strong character
+ of the text.
+ In this test, it is the Latin letter A since digits are not strongly
+ directional, thus the direction must be resolved as LTR." />
+ <style>
+ input, textarea {
+ font-size:1em;
+ }
+ body {
+ font-size:2em;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments {
+ display: none;
+ }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="comments">
+ Key to entities used below:
+ &#x05D0; - The Hebrew letter Alef (strongly RTL).
+ &#x05D1; - The Hebrew letter Bet (strongly RTL).
+ &#x05D2; - The Hebrew letter Gimel (strongly RTL).
+ </div>
+ <div class="test">
+ <div dir="ltr">
+ <p dir="ltr">123ABC&#x05D0;&#x05D1;&#x05D2;.</p>
+ </div>
+ <div dir="rtl">
+ <p dir="ltr">123ABC&#x05D0;&#x05D1;&#x05D2;.</p>
+ </div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">
+ <p dir="ltr">123ABC&#x05D0;&#x05D1;&#x05D2;.</p>
+ </div>
+ <div dir="rtl">
+ <p dir="ltr">123ABC&#x05D0;&#x05D1;&#x05D2;.</p>
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-EN-L.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-EN-L.html
new file mode 100644
index 0000000000..fa8d793bd0
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-EN-L.html
@@ -0,0 +1,58 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>HTML Test: dir=auto, start with EN, then L</title>
+ <link rel="match" href="dir_auto-EN-L-ref.html" />
+ <link rel="author" title="Matitiahu Allouche" href="mailto:matitiahu.allouche@google.com" />
+ <link rel="author" title="Oren Roth" href="mailto:oren.roth@gmail.com" />
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-dir-attribute" />
+ <meta name="assert" content="
+ When dir='auto', the direction is set according to the first strong character
+ of the text.
+ In this test, it is the Latin letter A since digits are not strongly
+ directional, thus the direction must be resolved as LTR." />
+ <style>
+ input, textarea {
+ font-size:1em;
+ }
+ body {
+ font-size:2em;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments {
+ display: none;
+ }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="comments">
+ Key to entities used below:
+ &#x05D0; - The Hebrew letter Alef (strongly RTL).
+ &#x05D1; - The Hebrew letter Bet (strongly RTL).
+ &#x05D2; - The Hebrew letter Gimel (strongly RTL).
+ </div>
+ <div class="test">
+ <div dir="ltr">
+ <p dir="auto">123ABC&#x05D0;&#x05D1;&#x05D2;.</p>
+ </div>
+ <div dir="rtl">
+ <p dir="auto">123ABC&#x05D0;&#x05D1;&#x05D2;.</p>
+ </div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">
+ <p dir="ltr">123ABC&#x05D0;&#x05D1;&#x05D2;.</p>
+ </div>
+ <div dir="rtl">
+ <p dir="ltr">123ABC&#x05D0;&#x05D1;&#x05D2;.</p>
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-EN-R-ref.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-EN-R-ref.html
new file mode 100644
index 0000000000..15bd618dc1
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-EN-R-ref.html
@@ -0,0 +1,57 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>HTML Test: dir=auto, start with EN, then R</title>
+ <link rel="author" title="Matitiahu Allouche" href="mailto:matitiahu.allouche@google.com" />
+ <link rel="author" title="Oren Roth" href="mailto:oren.roth@gmail.com" />
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-dir-attribute" />
+ <meta name="assert" content="
+ When dir='auto', the direction is set according to the first strong character
+ of the text.
+ In this test, it is the Hebrew letter Alef since digits are not strongly
+ directional, thus the direction must be resolved as RTL." />
+ <style>
+ input, textarea {
+ font-size:1em;
+ }
+ body {
+ font-size:2em;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments {
+ display: none;
+ }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="comments">
+ Key to entities used below:
+ &#x05D0; - The Hebrew letter Alef (strongly RTL).
+ &#x05D1; - The Hebrew letter Bet (strongly RTL).
+ &#x05D2; - The Hebrew letter Gimel (strongly RTL).
+ </div>
+ <div class="test">
+ <div dir="ltr">
+ <p dir="rtl">123&#x05D0;&#x05D1;&#x05D2;ABC.</p>
+ </div>
+ <div dir="rtl">
+ <p dir="rtl">123&#x05D0;&#x05D1;&#x05D2;ABC.</p>
+ </div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">
+ <p dir="rtl">123&#x05D0;&#x05D1;&#x05D2;ABC.</p>
+ </div>
+ <div dir="rtl">
+ <p dir="rtl">123&#x05D0;&#x05D1;&#x05D2;ABC.</p>
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-EN-R.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-EN-R.html
new file mode 100644
index 0000000000..7165de583d
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-EN-R.html
@@ -0,0 +1,58 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>HTML Test: dir=auto, start with EN, then R</title>
+ <link rel="match" href="dir_auto-EN-R-ref.html" />
+ <link rel="author" title="Matitiahu Allouche" href="mailto:matitiahu.allouche@google.com" />
+ <link rel="author" title="Oren Roth" href="mailto:oren.roth@gmail.com" />
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-dir-attribute" />
+ <meta name="assert" content="
+ When dir='auto', the direction is set according to the first strong character
+ of the text.
+ In this test, it is the Hebrew letter Alef since digits are not strongly
+ directional, thus the direction must be resolved as RTL." />
+ <style>
+ input, textarea {
+ font-size:1em;
+ }
+ body {
+ font-size:2em;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments {
+ display: none;
+ }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="comments">
+ Key to entities used below:
+ &#x05D0; - The Hebrew letter Alef (strongly RTL).
+ &#x05D1; - The Hebrew letter Bet (strongly RTL).
+ &#x05D2; - The Hebrew letter Gimel (strongly RTL).
+ </div>
+ <div class="test">
+ <div dir="ltr">
+ <p dir="auto">123&#x05D0;&#x05D1;&#x05D2;ABC.</p>
+ </div>
+ <div dir="rtl">
+ <p dir="auto">123&#x05D0;&#x05D1;&#x05D2;ABC.</p>
+ </div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">
+ <p dir="rtl">123&#x05D0;&#x05D1;&#x05D2;ABC.</p>
+ </div>
+ <div dir="rtl">
+ <p dir="rtl">123&#x05D0;&#x05D1;&#x05D2;ABC.</p>
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-L-ref.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-L-ref.html
new file mode 100644
index 0000000000..23da64ed9b
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-L-ref.html
@@ -0,0 +1,57 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>HTML Test: dir=auto, start with L</title>
+ <link rel="author" title="Matitiahu Allouche" href="mailto:matitiahu.allouche@google.com" />
+ <link rel="author" title="Oren Roth" href="mailto:oren.roth@gmail.com" />
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-dir-attribute" />
+ <meta name="assert" content="
+ When dir='auto', the direction is set according to the first strong character
+ of the text.
+ In this test, it is the Latin letter A, thus the direction must be
+ resolved as LTR." />
+ <style>
+ input, textarea {
+ font-size:1em;
+ }
+ body {
+ font-size:2em;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments {
+ display: none;
+ }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="comments">
+ Key to entities used below:
+ &#x05D0; - The Hebrew letter Alef (strongly RTL).
+ &#x05D1; - The Hebrew letter Bet (strongly RTL).
+ &#x05D2; - The Hebrew letter Gimel (strongly RTL).
+ </div>
+ <div class="test">
+ <div dir="ltr">
+ <p dir="ltr">ABC&#x05D0;&#x05D1;&#x05D2;.</p>
+ </div>
+ <div dir="rtl">
+ <p dir="ltr">ABC&#x05D0;&#x05D1;&#x05D2;.</p>
+ </div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">
+ <p dir="ltr">ABC&#x05D0;&#x05D1;&#x05D2;.</p>
+ </div>
+ <div dir="rtl">
+ <p dir="ltr">ABC&#x05D0;&#x05D1;&#x05D2;.</p>
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-L.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-L.html
new file mode 100644
index 0000000000..3896bcb76b
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-L.html
@@ -0,0 +1,58 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>HTML Test: dir=auto, start with L</title>
+ <link rel="match" href="dir_auto-L-ref.html" />
+ <link rel="author" title="Matitiahu Allouche" href="mailto:matitiahu.allouche@google.com" />
+ <link rel="author" title="Oren Roth" href="mailto:oren.roth@gmail.com" />
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-dir-attribute" />
+ <meta name="assert" content="
+ When dir='auto', the direction is set according to the first strong character
+ of the text.
+ In this test, it is the Latin letter A, thus the direction must be
+ resolved as LTR." />
+ <style>
+ input, textarea {
+ font-size:1em;
+ }
+ body {
+ font-size:2em;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments {
+ display: none;
+ }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="comments">
+ Key to entities used below:
+ &#x05D0; - The Hebrew letter Alef (strongly RTL).
+ &#x05D1; - The Hebrew letter Bet (strongly RTL).
+ &#x05D2; - The Hebrew letter Gimel (strongly RTL).
+ </div>
+ <div class="test">
+ <div dir="ltr">
+ <p dir="auto">ABC&#x05D0;&#x05D1;&#x05D2;.</p>
+ </div>
+ <div dir="rtl">
+ <p dir="auto">ABC&#x05D0;&#x05D1;&#x05D2;.</p>
+ </div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">
+ <p dir="ltr">ABC&#x05D0;&#x05D1;&#x05D2;.</p>
+ </div>
+ <div dir="rtl">
+ <p dir="ltr">ABC&#x05D0;&#x05D1;&#x05D2;.</p>
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-N-EN-L-ref.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-N-EN-L-ref.html
new file mode 100644
index 0000000000..c7977d189f
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-N-EN-L-ref.html
@@ -0,0 +1,57 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>HTML Test: dir=auto, start with N, then EN, then L</title>
+ <link rel="author" title="Matitiahu Allouche" href="mailto:matitiahu.allouche@google.com" />
+ <link rel="author" title="Oren Roth" href="mailto:oren.roth@gmail.com" />
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-dir-attribute" />
+ <meta name="assert" content="
+ When dir='auto', the direction is set according to the first strong character
+ of the text.
+ In this test, it is the Latin letter A since neutrals and digits are not
+ strongly directional, thus the direction must be resolved as LTR." />
+ <style>
+ input, textarea {
+ font-size:1em;
+ }
+ body {
+ font-size:2em;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments {
+ display: none;
+ }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="comments">
+ Key to entities used below:
+ &#x05D0; - The Hebrew letter Alef (strongly RTL).
+ &#x05D1; - The Hebrew letter Bet (strongly RTL).
+ &#x05D2; - The Hebrew letter Gimel (strongly RTL).
+ </div>
+ <div class="test">
+ <div dir="ltr">
+ <p dir="ltr">.-=123ABC&#x05D0;&#x05D1;&#x05D2;.</p>
+ </div>
+ <div dir="rtl">
+ <p dir="ltr">.-=123ABC&#x05D0;&#x05D1;&#x05D2;.</p>
+ </div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">
+ <p dir="ltr">.-=123ABC&#x05D0;&#x05D1;&#x05D2;.</p>
+ </div>
+ <div dir="rtl">
+ <p dir="ltr">.-=123ABC&#x05D0;&#x05D1;&#x05D2;.</p>
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-N-EN-L.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-N-EN-L.html
new file mode 100644
index 0000000000..21ca0338dc
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-N-EN-L.html
@@ -0,0 +1,58 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>HTML Test: dir=auto, start with N, then EN, then L</title>
+ <link rel="match" href="dir_auto-N-EN-L-ref.html" />
+ <link rel="author" title="Matitiahu Allouche" href="mailto:matitiahu.allouche@google.com" />
+ <link rel="author" title="Oren Roth" href="mailto:oren.roth@gmail.com" />
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-dir-attribute" />
+ <meta name="assert" content="
+ When dir='auto', the direction is set according to the first strong character
+ of the text.
+ In this test, it is the Latin letter A since neutrals and digits are not
+ strongly directional, thus the direction must be resolved as LTR." />
+ <style>
+ input, textarea {
+ font-size:1em;
+ }
+ body {
+ font-size:2em;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments {
+ display: none;
+ }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="comments">
+ Key to entities used below:
+ &#x05D0; - The Hebrew letter Alef (strongly RTL).
+ &#x05D1; - The Hebrew letter Bet (strongly RTL).
+ &#x05D2; - The Hebrew letter Gimel (strongly RTL).
+ </div>
+ <div class="test">
+ <div dir="ltr">
+ <p dir="auto">.-=123ABC&#x05D0;&#x05D1;&#x05D2;.</p>
+ </div>
+ <div dir="rtl">
+ <p dir="auto">.-=123ABC&#x05D0;&#x05D1;&#x05D2;.</p>
+ </div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">
+ <p dir="ltr">.-=123ABC&#x05D0;&#x05D1;&#x05D2;.</p>
+ </div>
+ <div dir="rtl">
+ <p dir="ltr">.-=123ABC&#x05D0;&#x05D1;&#x05D2;.</p>
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-N-EN-R-ref.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-N-EN-R-ref.html
new file mode 100644
index 0000000000..aae50bc721
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-N-EN-R-ref.html
@@ -0,0 +1,57 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>HTML Test: dir=auto, start with N, then EN, then R</title>
+ <link rel="author" title="Matitiahu Allouche" href="mailto:matitiahu.allouche@google.com" />
+ <link rel="author" title="Oren Roth" href="mailto:oren.roth@gmail.com" />
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-dir-attribute" />
+ <meta name="assert" content="
+ When dir='auto', the direction is set according to the first strong character
+ of the text.
+ In this test, it is the Hebrew letter Alef since neutrals and digits are not
+ strongly directional, thus the direction must be resolved as RTL." />
+ <style>
+ input, textarea {
+ font-size:1em;
+ }
+ body {
+ font-size:2em;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments {
+ display: none;
+ }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="comments">
+ Key to entities used below:
+ &#x05D0; - The Hebrew letter Alef (strongly RTL).
+ &#x05D1; - The Hebrew letter Bet (strongly RTL).
+ &#x05D2; - The Hebrew letter Gimel (strongly RTL).
+ </div>
+ <div class="test">
+ <div dir="ltr">
+ <p dir="rtl">.-=123&#x05D0;&#x05D1;&#x05D2;ABC.</p>
+ </div>
+ <div dir="rtl">
+ <p dir="rtl">.-=123&#x05D0;&#x05D1;&#x05D2;ABC.</p>
+ </div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">
+ <p dir="rtl">.-=123&#x05D0;&#x05D1;&#x05D2;ABC.</p>
+ </div>
+ <div dir="rtl">
+ <p dir="rtl">.-=123&#x05D0;&#x05D1;&#x05D2;ABC.</p>
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-N-EN-R.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-N-EN-R.html
new file mode 100644
index 0000000000..b10a52b1a8
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-N-EN-R.html
@@ -0,0 +1,58 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>HTML Test: dir=auto, start with N, then EN, then R</title>
+ <link rel="match" href="dir_auto-N-EN-R-ref.html" />
+ <link rel="author" title="Matitiahu Allouche" href="mailto:matitiahu.allouche@google.com" />
+ <link rel="author" title="Oren Roth" href="mailto:oren.roth@gmail.com" />
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-dir-attribute" />
+ <meta name="assert" content="
+ When dir='auto', the direction is set according to the first strong character
+ of the text.
+ In this test, it is the Hebrew letter Alef since neutrals and digits are not
+ strongly directional, thus the direction must be resolved as RTL." />
+ <style>
+ input, textarea {
+ font-size:1em;
+ }
+ body {
+ font-size:2em;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments {
+ display: none;
+ }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="comments">
+ Key to entities used below:
+ &#x05D0; - The Hebrew letter Alef (strongly RTL).
+ &#x05D1; - The Hebrew letter Bet (strongly RTL).
+ &#x05D2; - The Hebrew letter Gimel (strongly RTL).
+ </div>
+ <div class="test">
+ <div dir="ltr">
+ <p dir="auto">.-=123&#x05D0;&#x05D1;&#x05D2;ABC.</p>
+ </div>
+ <div dir="rtl">
+ <p dir="auto">.-=123&#x05D0;&#x05D1;&#x05D2;ABC.</p>
+ </div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">
+ <p dir="rtl">.-=123&#x05D0;&#x05D1;&#x05D2;ABC.</p>
+ </div>
+ <div dir="rtl">
+ <p dir="rtl">.-=123&#x05D0;&#x05D1;&#x05D2;ABC.</p>
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-N-EN-ref.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-N-EN-ref.html
new file mode 100644
index 0000000000..0d938b2e16
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-N-EN-ref.html
@@ -0,0 +1,50 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>HTML Test: dir=auto, start with N, then EN, then L</title>
+ <link rel="author" title="Matitiahu Allouche" href="mailto:matitiahu.allouche@google.com" />
+ <link rel="author" title="Oren Roth" href="mailto:oren.roth@gmail.com" />
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-dir-attribute" />
+ <meta name="assert" content="
+ When dir='auto', the direction is set according to the first strong character
+ of the text, ignoring neutrals and numbers.
+ If there is no strong character, as in this test, the direction defaults to the parent." />
+ <style>
+ input, textarea {
+ font-size:1em;
+ }
+ body {
+ font-size:2em;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments {
+ display: none;
+ }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="test">
+ <div dir="ltr">
+ <p dir="ltr">@123!</p>
+ </div>
+ <div dir="rtl">
+ <p dir="rtl">@123!</p>
+ </div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">
+ <p dir="ltr">@123!</p>
+ </div>
+ <div dir="rtl">
+ <p dir="rtl">@123!</p>
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-N-EN.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-N-EN.html
new file mode 100644
index 0000000000..467b4d0939
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-N-EN.html
@@ -0,0 +1,51 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>HTML Test: dir=auto, start with N, then EN, then L</title>
+ <link rel="match" href="dir_auto-N-EN-ref.html" />
+ <link rel="author" title="Matitiahu Allouche" href="mailto:matitiahu.allouche@google.com" />
+ <link rel="author" title="Oren Roth" href="mailto:oren.roth@gmail.com" />
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-dir-attribute" />
+ <meta name="assert" content="
+ When dir='auto', the direction is set according to the first strong character
+ of the text, ignoring neutrals and numbers.
+ If there is no strong character, as in this test, the direction defaults to the parent." />
+ <style>
+ input, textarea {
+ font-size:1em;
+ }
+ body {
+ font-size:2em;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments {
+ display: none;
+ }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="test">
+ <div dir="ltr">
+ <p dir="auto">@123!</p>
+ </div>
+ <div dir="rtl">
+ <p dir="auto">@123!</p>
+ </div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">
+ <p dir="ltr">@123!</p>
+ </div>
+ <div dir="rtl">
+ <p dir="rtl">@123!</p>
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-N-L-ref.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-N-L-ref.html
new file mode 100644
index 0000000000..4bbaca1e31
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-N-L-ref.html
@@ -0,0 +1,57 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>HTML Test: dir=auto, start with N, then L</title>
+ <link rel="author" title="Matitiahu Allouche" href="mailto:matitiahu.allouche@google.com" />
+ <link rel="author" title="Oren Roth" href="mailto:oren.roth@gmail.com" />
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-dir-attribute" />
+ <meta name="assert" content="
+ When dir='auto', the direction is set according to the first strong character
+ of the text.
+ In this test, it is the Latin letter A since neutrals are not
+ strongly directional, thus the direction must be resolved as LTR." />
+ <style>
+ input, textarea {
+ font-size:1em;
+ }
+ body {
+ font-size:2em;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments {
+ display: none;
+ }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="comments">
+ Key to entities used below:
+ &#x05D0; - The Hebrew letter Alef (strongly RTL).
+ &#x05D1; - The Hebrew letter Bet (strongly RTL).
+ &#x05D2; - The Hebrew letter Gimel (strongly RTL).
+ </div>
+ <div class="test">
+ <div dir="ltr">
+ <p dir="ltr">.-=ABC&#x05D0;&#x05D1;&#x05D2;.</p>
+ </div>
+ <div dir="rtl">
+ <p dir="ltr">.-=ABC&#x05D0;&#x05D1;&#x05D2;.</p>
+ </div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">
+ <p dir="ltr">.-=ABC&#x05D0;&#x05D1;&#x05D2;.</p>
+ </div>
+ <div dir="rtl">
+ <p dir="ltr">.-=ABC&#x05D0;&#x05D1;&#x05D2;.</p>
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-N-L.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-N-L.html
new file mode 100644
index 0000000000..945fa06779
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-N-L.html
@@ -0,0 +1,58 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>HTML Test: dir=auto, start with N, then L</title>
+ <link rel="match" href="dir_auto-N-L-ref.html" />
+ <link rel="author" title="Matitiahu Allouche" href="mailto:matitiahu.allouche@google.com" />
+ <link rel="author" title="Oren Roth" href="mailto:oren.roth@gmail.com" />
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-dir-attribute" />
+ <meta name="assert" content="
+ When dir='auto', the direction is set according to the first strong character
+ of the text.
+ In this test, it is the Latin letter A since neutrals are not
+ strongly directional, thus the direction must be resolved as LTR." />
+ <style>
+ input, textarea {
+ font-size:1em;
+ }
+ body {
+ font-size:2em;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments {
+ display: none;
+ }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="comments">
+ Key to entities used below:
+ &#x05D0; - The Hebrew letter Alef (strongly RTL).
+ &#x05D1; - The Hebrew letter Bet (strongly RTL).
+ &#x05D2; - The Hebrew letter Gimel (strongly RTL).
+ </div>
+ <div class="test">
+ <div dir="ltr">
+ <p dir="auto">.-=ABC&#x05D0;&#x05D1;&#x05D2;.</p>
+ </div>
+ <div dir="rtl">
+ <p dir="auto">.-=ABC&#x05D0;&#x05D1;&#x05D2;.</p>
+ </div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">
+ <p dir="ltr">.-=ABC&#x05D0;&#x05D1;&#x05D2;.</p>
+ </div>
+ <div dir="rtl">
+ <p dir="ltr">.-=ABC&#x05D0;&#x05D1;&#x05D2;.</p>
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-N-R-ref.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-N-R-ref.html
new file mode 100644
index 0000000000..7a1daeddde
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-N-R-ref.html
@@ -0,0 +1,57 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>HTML Test: dir=auto, start with N, then R</title>
+ <link rel="author" title="Matitiahu Allouche" href="mailto:matitiahu.allouche@google.com" />
+ <link rel="author" title="Oren Roth" href="mailto:oren.roth@gmail.com" />
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-dir-attribute" />
+ <meta name="assert" content="
+ When dir='auto', the direction is set according to the first strong character
+ of the text.
+ In this test, it is the Hebrew letter Alef since neutrals are not
+ strongly directional, thus the direction must be resolved as RTL." />
+ <style>
+ input, textarea {
+ font-size:1em;
+ }
+ body {
+ font-size:2em;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments {
+ display: none;
+ }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="comments">
+ Key to entities used below:
+ &#x05D0; - The Hebrew letter Alef (strongly RTL).
+ &#x05D1; - The Hebrew letter Bet (strongly RTL).
+ &#x05D2; - The Hebrew letter Gimel (strongly RTL).
+ </div>
+ <div class="test">
+ <div dir="ltr">
+ <p dir="rtl">.-=&#x05D0;&#x05D1;&#x05D2;ABC.</p>
+ </div>
+ <div dir="rtl">
+ <p dir="rtl">.-=&#x05D0;&#x05D1;&#x05D2;ABC.</p>
+ </div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">
+ <p dir="rtl">.-=&#x05D0;&#x05D1;&#x05D2;ABC.</p>
+ </div>
+ <div dir="rtl">
+ <p dir="rtl">.-=&#x05D0;&#x05D1;&#x05D2;ABC.</p>
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-N-R.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-N-R.html
new file mode 100644
index 0000000000..bf27a16a22
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-N-R.html
@@ -0,0 +1,58 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>HTML Test: dir=auto, start with N, then R</title>
+ <link rel="match" href="dir_auto-N-R-ref.html" />
+ <link rel="author" title="Matitiahu Allouche" href="mailto:matitiahu.allouche@google.com" />
+ <link rel="author" title="Oren Roth" href="mailto:oren.roth@gmail.com" />
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-dir-attribute" />
+ <meta name="assert" content="
+ When dir='auto', the direction is set according to the first strong character
+ of the text.
+ In this test, it is the Hebrew letter Alef since neutrals are not
+ strongly directional, thus the direction must be resolved as RTL." />
+ <style>
+ input, textarea {
+ font-size:1em;
+ }
+ body {
+ font-size:2em;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments {
+ display: none;
+ }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="comments">
+ Key to entities used below:
+ &#x05D0; - The Hebrew letter Alef (strongly RTL).
+ &#x05D1; - The Hebrew letter Bet (strongly RTL).
+ &#x05D2; - The Hebrew letter Gimel (strongly RTL).
+ </div>
+ <div class="test">
+ <div dir="ltr">
+ <p dir="auto">.-=&#x05D0;&#x05D1;&#x05D2;ABC.</p>
+ </div>
+ <div dir="rtl">
+ <p dir="auto">.-=&#x05D0;&#x05D1;&#x05D2;ABC.</p>
+ </div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">
+ <p dir="rtl">.-=&#x05D0;&#x05D1;&#x05D2;ABC.</p>
+ </div>
+ <div dir="rtl">
+ <p dir="rtl">.-=&#x05D0;&#x05D1;&#x05D2;ABC.</p>
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-R-ref.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-R-ref.html
new file mode 100644
index 0000000000..c9dc5301b4
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-R-ref.html
@@ -0,0 +1,58 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>HTML Test: dir=auto, start with R</title>
+ <link rel="author" title="Matitiahu Allouche" href="mailto:matitiahu.allouche@google.com" />
+ <link rel="author" title="Oren Roth" href="mailto:oren.roth@gmail.com" />
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-dir-attribute" />
+ <meta name="assert" content="
+ When dir='auto', the direction is set according to the first strong character
+ of the text.
+ In this test, it is the Hebrew letter Alef, thus the direction must be
+ resolved as RTL." />
+ <style>
+ input, textarea {
+ font-size:1em;
+ }
+ body {
+ font-size:2em;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments {
+ display: none;
+ }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="comments">
+ Key to entities used below:
+ &#x05D0; - The Hebrew letter Alef (strongly RTL).
+ &#x05D1; - The Hebrew letter Bet (strongly RTL).
+ &#x05D2; - The Hebrew letter Gimel (strongly RTL).
+ </div>
+ </div>
+ <div class="test">
+ <div dir="ltr">
+ <p dir="rtl">&#x05D0;&#x05D1;&#x05D2;ABC.</p>
+ </div>
+ <div dir="rtl">
+ <p dir="rtl">&#x05D0;&#x05D1;&#x05D2;ABC.</p>
+ </div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">
+ <p dir="rtl">&#x05D0;&#x05D1;&#x05D2;ABC.</p>
+ </div>
+ <div dir="rtl">
+ <p dir="rtl">&#x05D0;&#x05D1;&#x05D2;ABC.</p>
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-R.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-R.html
new file mode 100644
index 0000000000..69a62fc637
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-R.html
@@ -0,0 +1,58 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>HTML Test: dir=auto, start with R</title>
+ <link rel="match" href="dir_auto-R-ref.html" />
+ <link rel="author" title="Matitiahu Allouche" href="mailto:matitiahu.allouche@google.com" />
+ <link rel="author" title="Oren Roth" href="mailto:oren.roth@gmail.com" />
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-dir-attribute" />
+ <meta name="assert" content="
+ When dir='auto', the direction is set according to the first strong character
+ of the text.
+ In this test, it is the Hebrew letter Alef, thus the direction must be
+ resolved as RTL." />
+ <style>
+ input, textarea {
+ font-size:1em;
+ }
+ body {
+ font-size:2em;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments {
+ display: none;
+ }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="comments">
+ Key to entities used below:
+ &#x05D0; - The Hebrew letter Alef (strongly RTL).
+ &#x05D1; - The Hebrew letter Bet (strongly RTL).
+ &#x05D2; - The Hebrew letter Gimel (strongly RTL).
+ </div>
+ <div class="test">
+ <div dir="ltr">
+ <p dir="auto">&#x05D0;&#x05D1;&#x05D2;ABC.</p>
+ </div>
+ <div dir="rtl">
+ <p dir="auto">&#x05D0;&#x05D1;&#x05D2;ABC.</p>
+ </div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">
+ <p dir="rtl">&#x05D0;&#x05D1;&#x05D2;ABC.</p>
+ </div>
+ <div dir="rtl">
+ <p dir="rtl">&#x05D0;&#x05D1;&#x05D2;ABC.</p>
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-contained-L-ref.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-contained-L-ref.html
new file mode 100644
index 0000000000..4e42a11a91
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-contained-L-ref.html
@@ -0,0 +1,61 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>HTML Test: dir=auto, start with L within contained element</title>
+ <link rel="author" title="Matitiahu Allouche" href="mailto:matitiahu.allouche@google.com" />
+ <link rel="author" title="Oren Roth" href="mailto:oren.roth@gmail.com" />
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-dir-attribute" />
+ <meta name="assert" content="
+ When dir='auto', the direction is set according to the first strong character
+ of the text, including text within contained elements.
+ In this test, it is the Latin letter A, thus the direction must be
+ resolved as LTR." />
+ <style>
+ input, textarea {
+ font-size:1em;
+ }
+ body {
+ font-size:2em;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments {
+ display: none;
+ }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="comments">
+ Key to entities used below:
+ &#x05D0; - The Hebrew letter Alef (strongly RTL).
+ &#x05D1; - The Hebrew letter Bet (strongly RTL).
+ &#x05D2; - The Hebrew letter Gimel (strongly RTL).
+ &#x05D3; - The Hebrew letter Dalet (strongly RTL).
+ &#x05D4; - The Hebrew letter He (strongly RTL).
+ &#x05D5; - The Hebrew letter Vav (strongly RTL).
+ &#x05D6; - The Hebrew letter Zayin (strongly RTL).
+ </div>
+ <div class="test">
+ <div dir="ltr">
+ <div dir="ltr"><div><div>ABC&#x05D0;&#x05D1;&#x05D2;.</div>&#x05D3;&#x05D4;</div>&#x05D5;</div>
+ </div>
+ <div dir="rtl">
+ <div dir="ltr"><div><div>ABC&#x05D0;&#x05D1;&#x05D2;.</div>&#x05D3;&#x05D4;</div>&#x05D5;</div>
+ </div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">
+ <div dir="ltr"><div><div>ABC&#x05D0;&#x05D1;&#x05D2;.</div>&#x05D3;&#x05D4;</div>&#x05D5;</div>
+ </div>
+ <div dir="rtl">
+ <div dir="ltr"><div><div>ABC&#x05D0;&#x05D1;&#x05D2;.</div>&#x05D3;&#x05D4;</div>&#x05D5;</div>
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-contained-L.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-contained-L.html
new file mode 100644
index 0000000000..f71f318bfd
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-contained-L.html
@@ -0,0 +1,62 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>HTML Test: dir=auto, start with L within contained element</title>
+ <link rel="match" href="dir_auto-contained-L-ref.html" />
+ <link rel="author" title="Matitiahu Allouche" href="mailto:matitiahu.allouche@google.com" />
+ <link rel="author" title="Oren Roth" href="mailto:oren.roth@gmail.com" />
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-dir-attribute" />
+ <meta name="assert" content="
+ When dir='auto', the direction is set according to the first strong character
+ of the text, including text within contained elements.
+ In this test, it is the Latin letter A, thus the direction must be
+ resolved as LTR." />
+ <style>
+ input, textarea {
+ font-size:1em;
+ }
+ body {
+ font-size:2em;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments {
+ display: none;
+ }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="comments">
+ Key to entities used below:
+ &#x05D0; - The Hebrew letter Alef (strongly RTL).
+ &#x05D1; - The Hebrew letter Bet (strongly RTL).
+ &#x05D2; - The Hebrew letter Gimel (strongly RTL).
+ &#x05D3; - The Hebrew letter Dalet (strongly RTL).
+ &#x05D4; - The Hebrew letter He (strongly RTL).
+ &#x05D5; - The Hebrew letter Vav (strongly RTL).
+ &#x05D6; - The Hebrew letter Zayin (strongly RTL).
+ </div>
+ <div class="test">
+ <div dir="ltr">
+ <div dir="auto"><div><div>ABC&#x05D0;&#x05D1;&#x05D2;.</div>&#x05D3;&#x05D4;</div>&#x05D5;</div>
+ </div>
+ <div dir="rtl">
+ <div dir="auto"><div><div>ABC&#x05D0;&#x05D1;&#x05D2;.</div>&#x05D3;&#x05D4;</div>&#x05D5;</div>
+ </div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">
+ <div dir="ltr"><div><div>ABC&#x05D0;&#x05D1;&#x05D2;.</div>&#x05D3;&#x05D4;</div>&#x05D5;</div>
+ </div>
+ <div dir="rtl">
+ <div dir="ltr"><div><div>ABC&#x05D0;&#x05D1;&#x05D2;.</div>&#x05D3;&#x05D4;</div>&#x05D5;</div>
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-contained-R-ref.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-contained-R-ref.html
new file mode 100644
index 0000000000..a3938bdf85
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-contained-R-ref.html
@@ -0,0 +1,57 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>HTML Test: dir=auto, start with R within contained element</title>
+ <link rel="author" title="Matitiahu Allouche" href="mailto:matitiahu.allouche@google.com" />
+ <link rel="author" title="Oren Roth" href="mailto:oren.roth@gmail.com" />
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-dir-attribute" />
+ <meta name="assert" content="
+ When dir='auto', the direction is set according to the first strong character
+ of the text, including text within contained elements.
+ In this test, it is the Hebrew letter Alef, thus the direction must be
+ resolved as RTL." />
+ <style>
+ input, textarea {
+ font-size:1em;
+ }
+ body {
+ font-size:2em;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments {
+ display: none;
+ }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="comments">
+ Key to entities used below:
+ &#x05D0; - The Hebrew letter Alef (strongly RTL).
+ &#x05D1; - The Hebrew letter Bet (strongly RTL).
+ &#x05D2; - The Hebrew letter Gimel (strongly RTL).
+ </div>
+ <div class="test">
+ <div dir="ltr">
+ <div dir="rtl"><div><div>&#x05D0;&#x05D1;&#x05D2;ABC.</div>XY</div>Z</div>
+ </div>
+ <div dir="rtl">
+ <div dir="rtl"><div><div>&#x05D0;&#x05D1;&#x05D2;ABC.</div>XY</div>Z</div>
+ </div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">
+ <div dir="rtl"><div><div>&#x05D0;&#x05D1;&#x05D2;ABC.</div>XY</div>Z</div>
+ </div>
+ <div dir="rtl">
+ <div dir="rtl"><div><div>&#x05D0;&#x05D1;&#x05D2;ABC.</div>XY</div>Z</div>
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-contained-R.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-contained-R.html
new file mode 100644
index 0000000000..2ba63426e3
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-contained-R.html
@@ -0,0 +1,58 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>HTML Test: dir=auto, start with R within contained element</title>
+ <link rel="match" href="dir_auto-contained-R-ref.html" />
+ <link rel="author" title="Matitiahu Allouche" href="mailto:matitiahu.allouche@google.com" />
+ <link rel="author" title="Oren Roth" href="mailto:oren.roth@gmail.com" />
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-dir-attribute" />
+ <meta name="assert" content="
+ When dir='auto', the direction is set according to the first strong character
+ of the text, including text within contained elements.
+ In this test, it is the Hebrew letter Alef, thus the direction must be
+ resolved as RTL." />
+ <style>
+ input, textarea {
+ font-size:1em;
+ }
+ body {
+ font-size:2em;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments {
+ display: none;
+ }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="comments">
+ Key to entities used below:
+ &#x05D0; - The Hebrew letter Alef (strongly RTL).
+ &#x05D1; - The Hebrew letter Bet (strongly RTL).
+ &#x05D2; - The Hebrew letter Gimel (strongly RTL).
+ </div>
+ <div class="test">
+ <div dir="ltr">
+ <div dir="auto"><div><div>&#x05D0;&#x05D1;&#x05D2;ABC.</div>XY</div>Z</div>
+ </div>
+ <div dir="rtl">
+ <div dir="auto"><div><div>&#x05D0;&#x05D1;&#x05D2;ABC.</div>XY</div>Z</div>
+ </div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">
+ <div dir="rtl"><div><div>&#x05D0;&#x05D1;&#x05D2;ABC.</div>XY</div>Z</div>
+ </div>
+ <div dir="rtl">
+ <div dir="rtl"><div><div>&#x05D0;&#x05D1;&#x05D2;ABC.</div>XY</div>Z</div>
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-contained-bdi-L-ref.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-contained-bdi-L-ref.html
new file mode 100644
index 0000000000..470220c80d
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-contained-bdi-L-ref.html
@@ -0,0 +1,60 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>HTML Test: dir=auto, start with bdi, then L</title>
+ <link rel="author" title="Matitiahu Allouche" href="mailto:matitiahu.allouche@google.com" />
+ <link rel="author" title="Oren Roth" href="mailto:oren.roth@gmail.com" />
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-dir-attribute" />
+ <meta name="assert" content="
+ When dir='auto', the direction is set according to the first strong character
+ of the text while ignoring bdi elements.
+ In this test, it is the Latin letter A, thus the direction must be
+ resolved as LTR." />
+ <style>
+ input, textarea {
+ font-size:1em;
+ }
+ body {
+ font-size:2em;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments {
+ display: none;
+ }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="comments">
+ Key to entities used below:
+ &#x05D0; - The Hebrew letter Alef (strongly RTL).
+ &#x05D1; - The Hebrew letter Bet (strongly RTL).
+ &#x05D2; - The Hebrew letter Gimel (strongly RTL).
+ &#x05D3; - The Hebrew letter Dalet (strongly RTL).
+ &#x05D4; - The Hebrew letter He (strongly RTL).
+ &#x05D5; - The Hebrew letter Vav (strongly RTL).
+ </div>
+ <div class="test">
+ <div dir="ltr">
+ <div dir="ltr"><bdi>&#x05D3;&#x05D4;&#x05D5;</bdi>ABC&#x05D0;&#x05D1;&#x05D2;.</div>
+ </div>
+ <div dir="rtl">
+ <div dir="ltr"><bdi>&#x05D3;&#x05D4;&#x05D5;</bdi>ABC&#x05D0;&#x05D1;&#x05D2;.</div>
+ </div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">
+ <div dir="ltr"><bdi>&#x05D3;&#x05D4;&#x05D5;</bdi>ABC&#x05D0;&#x05D1;&#x05D2;.</div>
+ </div>
+ <div dir="rtl">
+ <div dir="ltr"><bdi>&#x05D3;&#x05D4;&#x05D5;</bdi>ABC&#x05D0;&#x05D1;&#x05D2;.</div>
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-contained-bdi-L.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-contained-bdi-L.html
new file mode 100644
index 0000000000..f35abfe3fd
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-contained-bdi-L.html
@@ -0,0 +1,61 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>HTML Test: dir=auto, start with bdi, then L</title>
+ <link rel="match" href="dir_auto-contained-bdi-L-ref.html" />
+ <link rel="author" title="Matitiahu Allouche" href="mailto:matitiahu.allouche@google.com" />
+ <link rel="author" title="Oren Roth" href="mailto:oren.roth@gmail.com" />
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-dir-attribute" />
+ <meta name="assert" content="
+ When dir='auto', the direction is set according to the first strong character
+ of the text while ignoring bdi elements.
+ In this test, it is the Latin letter A, thus the direction must be
+ resolved as LTR." />
+ <style>
+ input, textarea {
+ font-size:1em;
+ }
+ body {
+ font-size:2em;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments {
+ display: none;
+ }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="comments">
+ Key to entities used below:
+ &#x05D0; - The Hebrew letter Alef (strongly RTL).
+ &#x05D1; - The Hebrew letter Bet (strongly RTL).
+ &#x05D2; - The Hebrew letter Gimel (strongly RTL).
+ &#x05D3; - The Hebrew letter Dalet (strongly RTL).
+ &#x05D4; - The Hebrew letter He (strongly RTL).
+ &#x05D5; - The Hebrew letter Vav (strongly RTL).
+ </div>
+ <div class="test">
+ <div dir="ltr">
+ <div dir="auto"><bdi>&#x05D3;&#x05D4;&#x05D5;</bdi>ABC&#x05D0;&#x05D1;&#x05D2;.</div>
+ </div>
+ <div dir="rtl">
+ <div dir="auto"><bdi>&#x05D3;&#x05D4;&#x05D5;</bdi>ABC&#x05D0;&#x05D1;&#x05D2;.</div>
+ </div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">
+ <div dir="ltr"><bdi>&#x05D3;&#x05D4;&#x05D5;</bdi>ABC&#x05D0;&#x05D1;&#x05D2;.</div>
+ </div>
+ <div dir="rtl">
+ <div dir="ltr"><bdi>&#x05D3;&#x05D4;&#x05D5;</bdi>ABC&#x05D0;&#x05D1;&#x05D2;.</div>
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-contained-bdi-R-ref.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-contained-bdi-R-ref.html
new file mode 100644
index 0000000000..94475aaa92
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-contained-bdi-R-ref.html
@@ -0,0 +1,57 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>HTML Test: dir=auto, start with bdi, then R</title>
+ <link rel="author" title="Matitiahu Allouche" href="mailto:matitiahu.allouche@google.com" />
+ <link rel="author" title="Oren Roth" href="mailto:oren.roth@gmail.com" />
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-dir-attribute" />
+ <meta name="assert" content="
+ When dir='auto', the direction is set according to the first strong character
+ of the text while ignoring bdi elements.
+ In this test, it is the Hebrew letter Alef, thus the direction must be
+ resolved as RTL." />
+ <style>
+ input, textarea {
+ font-size:1em;
+ }
+ body {
+ font-size:2em;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments {
+ display: none;
+ }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="comments">
+ Key to entities used below:
+ &#x05D0; - The Hebrew letter Alef (strongly RTL).
+ &#x05D1; - The Hebrew letter Bet (strongly RTL).
+ &#x05D2; - The Hebrew letter Gimel (strongly RTL).
+ </div>
+ <div class="test">
+ <div dir="ltr">
+ <div dir="rtl"><bdi>DEF</bdi>&#x05D0;&#x05D1;&#x05D2;ABC.</div>
+ </div>
+ <div dir="rtl">
+ <div dir="rtl"><bdi>DEF</bdi>&#x05D0;&#x05D1;&#x05D2;ABC.</div>
+ </div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">
+ <div dir="rtl"><bdi>DEF</bdi>&#x05D0;&#x05D1;&#x05D2;ABC.</div>
+ </div>
+ <div dir="rtl">
+ <div dir="rtl"><bdi>DEF</bdi>&#x05D0;&#x05D1;&#x05D2;ABC.</div>
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-contained-bdi-R.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-contained-bdi-R.html
new file mode 100644
index 0000000000..8ac3244618
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-contained-bdi-R.html
@@ -0,0 +1,58 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>HTML Test: dir=auto, start with bdi, then R</title>
+ <link rel="match" href="dir_auto-contained-bdi-R-ref.html" />
+ <link rel="author" title="Matitiahu Allouche" href="mailto:matitiahu.allouche@google.com" />
+ <link rel="author" title="Oren Roth" href="mailto:oren.roth@gmail.com" />
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-dir-attribute" />
+ <meta name="assert" content="
+ When dir='auto', the direction is set according to the first strong character
+ of the text while ignoring bdi elements.
+ In this test, it is the Hebrew letter Alef, thus the direction must be
+ resolved as RTL." />
+ <style>
+ input, textarea {
+ font-size:1em;
+ }
+ body {
+ font-size:2em;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments {
+ display: none;
+ }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="comments">
+ Key to entities used below:
+ &#x05D0; - The Hebrew letter Alef (strongly RTL).
+ &#x05D1; - The Hebrew letter Bet (strongly RTL).
+ &#x05D2; - The Hebrew letter Gimel (strongly RTL).
+ </div>
+ <div class="test">
+ <div dir="ltr">
+ <div dir="auto"><bdi>DEF</bdi>&#x05D0;&#x05D1;&#x05D2;ABC.</div>
+ </div>
+ <div dir="rtl">
+ <div dir="auto"><bdi>DEF</bdi>&#x05D0;&#x05D1;&#x05D2;ABC.</div>
+ </div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">
+ <div dir="rtl"><bdi>DEF</bdi>&#x05D0;&#x05D1;&#x05D2;ABC.</div>
+ </div>
+ <div dir="rtl">
+ <div dir="rtl"><bdi>DEF</bdi>&#x05D0;&#x05D1;&#x05D2;ABC.</div>
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-contained-dir-L-ref.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-contained-dir-L-ref.html
new file mode 100644
index 0000000000..7c9f931d3d
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-contained-dir-L-ref.html
@@ -0,0 +1,60 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>HTML Test: dir=auto, start with dir, then L</title>
+ <link rel="author" title="Matitiahu Allouche" href="mailto:matitiahu.allouche@google.com" />
+ <link rel="author" title="Oren Roth" href="mailto:oren.roth@gmail.com" />
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-dir-attribute" />
+ <meta name="assert" content="
+ When dir='auto', the direction is set according to the first strong character
+ of the text while ignoring contained elements with an explicit dir of their own.
+ In this test, it is the Latin letter A, thus the direction must be
+ resolved as LTR." />
+ <style>
+ input, textarea {
+ font-size:1em;
+ }
+ body {
+ font-size:2em;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments {
+ display: none;
+ }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="comments">
+ Key to entities used below:
+ &#x05D0; - The Hebrew letter Alef (strongly RTL).
+ &#x05D1; - The Hebrew letter Bet (strongly RTL).
+ &#x05D2; - The Hebrew letter Gimel (strongly RTL).
+ &#x05D3; - The Hebrew letter Dalet (strongly RTL).
+ &#x05D4; - The Hebrew letter He (strongly RTL).
+ &#x05D5; - The Hebrew letter Vav (strongly RTL).
+ </div>
+ <div class="test">
+ <div dir="ltr">
+ <div dir="ltr"><p dir="rtl">&#x05D3;&#x05D4;&#x05D5;</p>ABC&#x05D0;&#x05D1;&#x05D2;.</div>
+ </div>
+ <div dir="rtl">
+ <div dir="ltr"><p dir="rtl">&#x05D3;&#x05D4;&#x05D5;</p>ABC&#x05D0;&#x05D1;&#x05D2;.</div>
+ </div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">
+ <div dir="ltr"><p dir="rtl">&#x05D3;&#x05D4;&#x05D5;</p>ABC&#x05D0;&#x05D1;&#x05D2;.</div>
+ </div>
+ <div dir="rtl">
+ <div dir="ltr"><p dir="rtl">&#x05D3;&#x05D4;&#x05D5;</p>ABC&#x05D0;&#x05D1;&#x05D2;.</div>
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-contained-dir-L.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-contained-dir-L.html
new file mode 100644
index 0000000000..1f424682fa
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-contained-dir-L.html
@@ -0,0 +1,61 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>HTML Test: dir=auto, start with dir, then L</title>
+ <link rel="match" href="dir_auto-contained-dir-L-ref.html" />
+ <link rel="author" title="Matitiahu Allouche" href="mailto:matitiahu.allouche@google.com" />
+ <link rel="author" title="Oren Roth" href="mailto:oren.roth@gmail.com" />
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-dir-attribute" />
+ <meta name="assert" content="
+ When dir='auto', the direction is set according to the first strong character
+ of the text while ignoring contained elements with an explicit dir of their own.
+ In this test, it is the Latin letter A, thus the direction must be
+ resolved as LTR." />
+ <style>
+ input, textarea {
+ font-size:1em;
+ }
+ body {
+ font-size:2em;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments {
+ display: none;
+ }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="comments">
+ Key to entities used below:
+ &#x05D0; - The Hebrew letter Alef (strongly RTL).
+ &#x05D1; - The Hebrew letter Bet (strongly RTL).
+ &#x05D2; - The Hebrew letter Gimel (strongly RTL).
+ &#x05D3; - The Hebrew letter Dalet (strongly RTL).
+ &#x05D4; - The Hebrew letter He (strongly RTL).
+ &#x05D5; - The Hebrew letter Vav (strongly RTL).
+ </div>
+ <div class="test">
+ <div dir="ltr">
+ <div dir="auto"><p dir="rtl">&#x05D3;&#x05D4;&#x05D5;</p>ABC&#x05D0;&#x05D1;&#x05D2;.</div>
+ </div>
+ <div dir="rtl">
+ <div dir="auto"><p dir="rtl">&#x05D3;&#x05D4;&#x05D5;</p>ABC&#x05D0;&#x05D1;&#x05D2;.</div>
+ </div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">
+ <div dir="ltr"><p dir="rtl">&#x05D3;&#x05D4;&#x05D5;</p>ABC&#x05D0;&#x05D1;&#x05D2;.</div>
+ </div>
+ <div dir="rtl">
+ <div dir="ltr"><p dir="rtl">&#x05D3;&#x05D4;&#x05D5;</p>ABC&#x05D0;&#x05D1;&#x05D2;.</div>
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-contained-dir-R-ref.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-contained-dir-R-ref.html
new file mode 100644
index 0000000000..c6748dc85f
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-contained-dir-R-ref.html
@@ -0,0 +1,57 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>HTML Test: dir=auto, start with dir, then R</title>
+ <link rel="author" title="Matitiahu Allouche" href="mailto:matitiahu.allouche@google.com" />
+ <link rel="author" title="Oren Roth" href="mailto:oren.roth@gmail.com" />
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-dir-attribute" />
+ <meta name="assert" content="
+ When dir='auto', the direction is set according to the first strong character
+ of the text while ignoring contained elements with an explicit dir of their own.
+ In this test, it is the Hebrew letter Alef, thus the direction must be
+ resolved as RTL." />
+ <style>
+ input, textarea {
+ font-size:1em;
+ }
+ body {
+ font-size:2em;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments {
+ display: none;
+ }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="comments">
+ Key to entities used below:
+ &#x05D0; - The Hebrew letter Alef (strongly RTL).
+ &#x05D1; - The Hebrew letter Bet (strongly RTL).
+ &#x05D2; - The Hebrew letter Gimel (strongly RTL).
+ </div>
+ <div class="test">
+ <div dir="ltr">
+ <div dir="rtl"><p dir="ltr">DEF</p>&#x05D0;&#x05D1;&#x05D2;ABC.</div>
+ </div>
+ <div dir="rtl">
+ <div dir="rtl"><p dir="ltr">DEF</p>&#x05D0;&#x05D1;&#x05D2;ABC.</div>
+ </div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">
+ <div dir="rtl"><p dir="ltr">DEF</p>&#x05D0;&#x05D1;&#x05D2;ABC.</div>
+ </div>
+ <div dir="rtl">
+ <div dir="rtl"><p dir="ltr">DEF</p>&#x05D0;&#x05D1;&#x05D2;ABC.</div>
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-contained-dir-R.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-contained-dir-R.html
new file mode 100644
index 0000000000..daab191498
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-contained-dir-R.html
@@ -0,0 +1,58 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>HTML Test: dir=auto, start with dir, then R</title>
+ <link rel="match" href="dir_auto-contained-dir-R-ref.html" />
+ <link rel="author" title="Matitiahu Allouche" href="mailto:matitiahu.allouche@google.com" />
+ <link rel="author" title="Oren Roth" href="mailto:oren.roth@gmail.com" />
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-dir-attribute" />
+ <meta name="assert" content="
+ When dir='auto', the direction is set according to the first strong character
+ of the text while ignoring contained elements with an explicit dir of their own.
+ In this test, it is the Hebrew letter Alef, thus the direction must be
+ resolved as RTL." />
+ <style>
+ input, textarea {
+ font-size:1em;
+ }
+ body {
+ font-size:2em;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments {
+ display: none;
+ }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="comments">
+ Key to entities used below:
+ &#x05D0; - The Hebrew letter Alef (strongly RTL).
+ &#x05D1; - The Hebrew letter Bet (strongly RTL).
+ &#x05D2; - The Hebrew letter Gimel (strongly RTL).
+ </div>
+ <div class="test">
+ <div dir="ltr">
+ <div dir="auto"><p dir="ltr">DEF</p>&#x05D0;&#x05D1;&#x05D2;ABC.</div>
+ </div>
+ <div dir="rtl">
+ <div dir="auto"><p dir="ltr">DEF</p>&#x05D0;&#x05D1;&#x05D2;ABC.</div>
+ </div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">
+ <div dir="rtl"><p dir="ltr">DEF</p>&#x05D0;&#x05D1;&#x05D2;ABC.</div>
+ </div>
+ <div dir="rtl">
+ <div dir="rtl"><p dir="ltr">DEF</p>&#x05D0;&#x05D1;&#x05D2;ABC.</div>
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-contained-dir_auto-L-ref.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-contained-dir_auto-L-ref.html
new file mode 100644
index 0000000000..53c60421f8
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-contained-dir_auto-L-ref.html
@@ -0,0 +1,60 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>HTML Test: dir=auto, start with dir=auto, then L</title>
+ <link rel="author" title="Matitiahu Allouche" href="mailto:matitiahu.allouche@google.com" />
+ <link rel="author" title="Oren Roth" href="mailto:oren.roth@gmail.com" />
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-dir-attribute" />
+ <meta name="assert" content="
+ When dir='auto', the direction is set according to the first strong character
+ of the text while ignoring contained elements with an explicit dir of their own.
+ In this test, it is the Latin letter A, thus the direction must be
+ resolved as LTR." />
+ <style>
+ input, textarea {
+ font-size:1em;
+ }
+ body {
+ font-size:2em;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments {
+ display: none;
+ }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="comments">
+ Key to entities used below:
+ &#x05D0; - The Hebrew letter Alef (strongly RTL).
+ &#x05D1; - The Hebrew letter Bet (strongly RTL).
+ &#x05D2; - The Hebrew letter Gimel (strongly RTL).
+ &#x05D3; - The Hebrew letter Dalet (strongly RTL).
+ &#x05D4; - The Hebrew letter He (strongly RTL).
+ &#x05D5; - The Hebrew letter Vav (strongly RTL).
+ </div>
+ <div class="test">
+ <div dir="ltr">
+ <div dir="ltr"><p dir="rtl">&#x05D3;&#x05D4;&#x05D5;</p>ABC&#x05D0;&#x05D1;&#x05D2;.</div>
+ </div>
+ <div dir="rtl">
+ <div dir="ltr"><p dir="rtl">&#x05D3;&#x05D4;&#x05D5;</p>ABC&#x05D0;&#x05D1;&#x05D2;.</div>
+ </div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">
+ <div dir="ltr"><p dir="rtl">&#x05D3;&#x05D4;&#x05D5;</p>ABC&#x05D0;&#x05D1;&#x05D2;.</div>
+ </div>
+ <div dir="rtl">
+ <div dir="ltr"><p dir="rtl">&#x05D3;&#x05D4;&#x05D5;</p>ABC&#x05D0;&#x05D1;&#x05D2;.</div>
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-contained-dir_auto-L.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-contained-dir_auto-L.html
new file mode 100644
index 0000000000..f491f61658
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-contained-dir_auto-L.html
@@ -0,0 +1,61 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>HTML Test: dir=auto, start with dir=auto, then L</title>
+ <link rel="match" href="dir_auto-contained-dir_auto-L-ref.html" />
+ <link rel="author" title="Matitiahu Allouche" href="mailto:matitiahu.allouche@google.com" />
+ <link rel="author" title="Oren Roth" href="mailto:oren.roth@gmail.com" />
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-dir-attribute" />
+ <meta name="assert" content="
+ When dir='auto', the direction is set according to the first strong character
+ of the text while ignoring contained elements with an explicit dir of their own.
+ In this test, it is the Latin letter A, thus the direction must be
+ resolved as LTR." />
+ <style>
+ input, textarea {
+ font-size:1em;
+ }
+ body {
+ font-size:2em;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments {
+ display: none;
+ }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="comments">
+ Key to entities used below:
+ &#x05D0; - The Hebrew letter Alef (strongly RTL).
+ &#x05D1; - The Hebrew letter Bet (strongly RTL).
+ &#x05D2; - The Hebrew letter Gimel (strongly RTL).
+ &#x05D3; - The Hebrew letter Dalet (strongly RTL).
+ &#x05D4; - The Hebrew letter He (strongly RTL).
+ &#x05D5; - The Hebrew letter Vav (strongly RTL).
+ </div>
+ <div class="test">
+ <div dir="ltr">
+ <div dir="auto"><p dir="auto">&#x05D3;&#x05D4;&#x05D5;</p>ABC&#x05D0;&#x05D1;&#x05D2;.</div>
+ </div>
+ <div dir="rtl">
+ <div dir="auto"><p dir="auto">&#x05D3;&#x05D4;&#x05D5;</p>ABC&#x05D0;&#x05D1;&#x05D2;.</div>
+ </div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">
+ <div dir="ltr"><p dir="rtl">&#x05D3;&#x05D4;&#x05D5;</p>ABC&#x05D0;&#x05D1;&#x05D2;.</div>
+ </div>
+ <div dir="rtl">
+ <div dir="ltr"><p dir="rtl">&#x05D3;&#x05D4;&#x05D5;</p>ABC&#x05D0;&#x05D1;&#x05D2;.</div>
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-contained-dir_auto-R-ref.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-contained-dir_auto-R-ref.html
new file mode 100644
index 0000000000..41871f04a1
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-contained-dir_auto-R-ref.html
@@ -0,0 +1,57 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>HTML Test: dir=auto, start with dir=auto, then R</title>
+ <link rel="author" title="Matitiahu Allouche" href="mailto:matitiahu.allouche@google.com" />
+ <link rel="author" title="Oren Roth" href="mailto:oren.roth@gmail.com" />
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-dir-attribute" />
+ <meta name="assert" content="
+ When dir='auto', the direction is set according to the first strong character
+ of the text while ignoring contained elements with an explicit dir of their own.
+ In this test, it is the Hebrew letter Alef, thus the direction must be
+ resolved as RTL." />
+ <style>
+ input, textarea {
+ font-size:1em;
+ }
+ body {
+ font-size:2em;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments {
+ display: none;
+ }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="comments">
+ Key to entities used below:
+ &#x05D0; - The Hebrew letter Alef (strongly RTL).
+ &#x05D1; - The Hebrew letter Bet (strongly RTL).
+ &#x05D2; - The Hebrew letter Gimel (strongly RTL).
+ </div>
+ <div class="test">
+ <div dir="ltr">
+ <div dir="rtl"><p dir="ltr">DEF</p>.-=123&#x05D0;&#x05D1;&#x05D2;ABC.</div>
+ </div>
+ <div dir="rtl">
+ <div dir="rtl"><p dir="ltr">DEF</p>.-=123&#x05D0;&#x05D1;&#x05D2;ABC.</div>
+ </div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">
+ <div dir="rtl"><p dir="ltr">DEF</p>.-=123&#x05D0;&#x05D1;&#x05D2;ABC.</div>
+ </div>
+ <div dir="rtl">
+ <div dir="rtl"><p dir="ltr">DEF</p>.-=123&#x05D0;&#x05D1;&#x05D2;ABC.</div>
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-contained-dir_auto-R.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-contained-dir_auto-R.html
new file mode 100644
index 0000000000..e3131c89b3
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-contained-dir_auto-R.html
@@ -0,0 +1,58 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>HTML Test: dir=auto, start with dir=auto, then R</title>
+ <link rel="match" href="dir_auto-contained-dir_auto-R-ref.html" />
+ <link rel="author" title="Matitiahu Allouche" href="mailto:matitiahu.allouche@google.com" />
+ <link rel="author" title="Oren Roth" href="mailto:oren.roth@gmail.com" />
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-dir-attribute" />
+ <meta name="assert" content="
+ When dir='auto', the direction is set according to the first strong character
+ of the text while ignoring contained elements with an explicit dir of their own.
+ In this test, it is the Hebrew letter Alef, thus the direction must be
+ resolved as RTL." />
+ <style>
+ input, textarea {
+ font-size:1em;
+ }
+ body {
+ font-size:2em;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments {
+ display: none;
+ }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="comments">
+ Key to entities used below:
+ &#x05D0; - The Hebrew letter Alef (strongly RTL).
+ &#x05D1; - The Hebrew letter Bet (strongly RTL).
+ &#x05D2; - The Hebrew letter Gimel (strongly RTL).
+ </div>
+ <div class="test">
+ <div dir="ltr">
+ <div dir="auto"><p dir="auto">DEF</p>.-=123&#x05D0;&#x05D1;&#x05D2;ABC.</div>
+ </div>
+ <div dir="rtl">
+ <div dir="auto"><p dir="auto">DEF</p>.-=123&#x05D0;&#x05D1;&#x05D2;ABC.</div>
+ </div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">
+ <div dir="rtl"><p dir="ltr">DEF</p>.-=123&#x05D0;&#x05D1;&#x05D2;ABC.</div>
+ </div>
+ <div dir="rtl">
+ <div dir="rtl"><p dir="ltr">DEF</p>.-=123&#x05D0;&#x05D1;&#x05D2;ABC.</div>
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-contained-script-L-ref.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-contained-script-L-ref.html
new file mode 100644
index 0000000000..aca07de7ef
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-contained-script-L-ref.html
@@ -0,0 +1,57 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>HTML Test: dir=auto, start with script, then L</title>
+ <link rel="author" title="Matitiahu Allouche" href="mailto:matitiahu.allouche@google.com" />
+ <link rel="author" title="Oren Roth" href="mailto:oren.roth@gmail.com" />
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-dir-attribute" />
+ <meta name="assert" content="
+ When dir='auto', the direction is set according to the first strong character
+ of descendant text while ignoring descendant script elements.
+ In this test, it is the Latin letter A, thus the direction must be
+ resolved as LTR." />
+ <style>
+ input, textarea {
+ font-size:1em;
+ }
+ body {
+ font-size:2em;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments {
+ display: none;
+ }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="comments">
+ Key to entities used below:
+ &#x05D0; - The Hebrew letter Alef (strongly RTL).
+ &#x05D1; - The Hebrew letter Bet (strongly RTL).
+ &#x05D2; - The Hebrew letter Gimel (strongly RTL).
+ </div>
+ <div class="test">
+ <div dir="ltr">
+ <div dir="ltr"><script>&#x05D0; = 3;</script>ABC&#x05D0;&#x05D1;&#x05D2;.</div>
+ </div>
+ <div dir="rtl">
+ <div dir="ltr"><script>&#x05D0; = 3;</script>ABC&#x05D0;&#x05D1;&#x05D2;.</div>
+ </div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">
+ <div dir="ltr"><script>&#x05D0; = 3;</script>ABC&#x05D0;&#x05D1;&#x05D2;.</div>
+ </div>
+ <div dir="rtl">
+ <div dir="ltr"><script>&#x05D0; = 3;</script>ABC&#x05D0;&#x05D1;&#x05D2;.</div>
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-contained-script-L.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-contained-script-L.html
new file mode 100644
index 0000000000..59a2e77751
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-contained-script-L.html
@@ -0,0 +1,58 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>HTML Test: dir=auto, start with script, then L</title>
+ <link rel="match" href="dir_auto-contained-script-L-ref.html" />
+ <link rel="author" title="Matitiahu Allouche" href="mailto:matitiahu.allouche@google.com" />
+ <link rel="author" title="Oren Roth" href="mailto:oren.roth@gmail.com" />
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-dir-attribute" />
+ <meta name="assert" content="
+ When dir='auto', the direction is set according to the first strong character
+ of descendant text while ignoring descendant script elements.
+ In this test, it is the Latin letter A, thus the direction must be
+ resolved as LTR." />
+ <style>
+ input, textarea {
+ font-size:1em;
+ }
+ body {
+ font-size:2em;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments {
+ display: none;
+ }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="comments">
+ Key to entities used below:
+ &#x05D0; - The Hebrew letter Alef (strongly RTL).
+ &#x05D1; - The Hebrew letter Bet (strongly RTL).
+ &#x05D2; - The Hebrew letter Gimel (strongly RTL).
+ </div>
+ <div class="test">
+ <div dir="ltr">
+ <div dir="auto"><script>&#x05D0; = 3;</script>ABC&#x05D0;&#x05D1;&#x05D2;.</div>
+ </div>
+ <div dir="rtl">
+ <div dir="auto"><script>&#x05D0; = 3;</script>ABC&#x05D0;&#x05D1;&#x05D2;.</div>
+ </div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">
+ <div dir="ltr"><script>&#x05D0; = 3;</script>ABC&#x05D0;&#x05D1;&#x05D2;.</div>
+ </div>
+ <div dir="rtl">
+ <div dir="ltr"><script>&#x05D0; = 3;</script>ABC&#x05D0;&#x05D1;&#x05D2;.</div>
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-contained-script-R-ref.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-contained-script-R-ref.html
new file mode 100644
index 0000000000..aa27d2f45b
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-contained-script-R-ref.html
@@ -0,0 +1,58 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>HTML Test: dir=auto, start with script, then R</title>
+ <link rel="author" title="Matitiahu Allouche" href="mailto:matitiahu.allouche@google.com" />
+ <link rel="author" title="Oren Roth" href="mailto:oren.roth@gmail.com" />
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-dir-attribute" />
+ <meta name="assert" content="
+ When dir='auto', the direction is set according to the first strong character
+ of descendant text while ignoring descendant script elements.
+ In this test, it is the Hebrew letter Alef, thus the direction must be
+ resolved as RTL." />
+ <style>
+ input, textarea {
+ font-size:1em;
+ }
+ body {
+ font-size:2em;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments {
+ display: none;
+ }
+ </style>
+ <script>var x;</script>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="comments">
+ Key to entities used below:
+ &#x05D0; - The Hebrew letter Alef (strongly RTL).
+ &#x05D1; - The Hebrew letter Bet (strongly RTL).
+ &#x05D2; - The Hebrew letter Gimel (strongly RTL).
+ </div>
+ <div class="test">
+ <div dir="ltr">
+ <div dir="rtl"><script>x = 3;</script>&#x05D0;&#x05D1;&#x05D2;ABC.</div>
+ </div>
+ <div dir="rtl">
+ <div dir="rtl"><script>x = 3;</script>&#x05D0;&#x05D1;&#x05D2;ABC.</div>
+ </div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">
+ <div dir="rtl"><script>x = 3;</script>&#x05D0;&#x05D1;&#x05D2;ABC.</div>
+ </div>
+ <div dir="rtl">
+ <div dir="rtl"><script>x = 3;</script>&#x05D0;&#x05D1;&#x05D2;ABC.</div>
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-contained-script-R.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-contained-script-R.html
new file mode 100644
index 0000000000..ee002766a0
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-contained-script-R.html
@@ -0,0 +1,59 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>HTML Test: dir=auto, start with script, then R</title>
+ <link rel="match" href="dir_auto-contained-script-R-ref.html" />
+ <link rel="author" title="Matitiahu Allouche" href="mailto:matitiahu.allouche@google.com" />
+ <link rel="author" title="Oren Roth" href="mailto:oren.roth@gmail.com" />
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-dir-attribute" />
+ <meta name="assert" content="
+ When dir='auto', the direction is set according to the first strong character
+ of descendant text while ignoring descendant script elements.
+ In this test, it is the Hebrew letter Alef, thus the direction must be
+ resolved as RTL." />
+ <style>
+ input, textarea {
+ font-size:1em;
+ }
+ body {
+ font-size:2em;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments {
+ display: none;
+ }
+ </style>
+ <script>var x;</script>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="comments">
+ Key to entities used below:
+ &#x05D0; - The Hebrew letter Alef (strongly RTL).
+ &#x05D1; - The Hebrew letter Bet (strongly RTL).
+ &#x05D2; - The Hebrew letter Gimel (strongly RTL).
+ </div>
+ <div class="test">
+ <div dir="ltr">
+ <div dir="auto"><script>x = 3;</script>&#x05D0;&#x05D1;&#x05D2;ABC.</div>
+ </div>
+ <div dir="rtl">
+ <div dir="auto"><script>x = 3;</script>&#x05D0;&#x05D1;&#x05D2;ABC.</div>
+ </div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">
+ <div dir="rtl"><script>x = 3;</script>&#x05D0;&#x05D1;&#x05D2;ABC.</div>
+ </div>
+ <div dir="rtl">
+ <div dir="rtl"><script>x = 3;</script>&#x05D0;&#x05D1;&#x05D2;ABC.</div>
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-contained-style-L-ref.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-contained-style-L-ref.html
new file mode 100644
index 0000000000..2ec4f02ec2
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-contained-style-L-ref.html
@@ -0,0 +1,57 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>HTML Test: dir=auto, start with style, then L</title>
+ <link rel="author" title="Matitiahu Allouche" href="mailto:matitiahu.allouche@google.com" />
+ <link rel="author" title="Oren Roth" href="mailto:oren.roth@gmail.com" />
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-dir-attribute" />
+ <meta name="assert" content="
+ When dir='auto', the direction is set according to the first strong character
+ of descendant text while ignoring descendant style elements.
+ In this test, it is the Latin letter A, thus the direction must be
+ resolved as LTR." />
+ <style>
+ input, textarea {
+ font-size:1em;
+ }
+ body {
+ font-size:2em;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments {
+ display: none;
+ }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="comments">
+ Key to entities used below:
+ &#x05D0; - The Hebrew letter Alef (strongly RTL).
+ &#x05D1; - The Hebrew letter Bet (strongly RTL).
+ &#x05D2; - The Hebrew letter Gimel (strongly RTL).
+ </div>
+ <div class="test">
+ <div dir="ltr">
+ <div dir="ltr"><style>body {color:black;}</style>ABC&#x05D0;&#x05D1;&#x05D2;.</div>
+ </div>
+ <div dir="rtl">
+ <div dir="ltr"><style>body {color:black;}</style>ABC&#x05D0;&#x05D1;&#x05D2;.</div>
+ </div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">
+ <div dir="ltr"><style>body {color:black;}</style>ABC&#x05D0;&#x05D1;&#x05D2;.</div>
+ </div>
+ <div dir="rtl">
+ <div dir="ltr"><style>body {color:black;}</style>ABC&#x05D0;&#x05D1;&#x05D2;.</div>
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-contained-style-L.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-contained-style-L.html
new file mode 100644
index 0000000000..cc74d4c939
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-contained-style-L.html
@@ -0,0 +1,58 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>HTML Test: dir=auto, start with style, then L</title>
+ <link rel="match" href="dir_auto-contained-style-L-ref.html" />
+ <link rel="author" title="Matitiahu Allouche" href="mailto:matitiahu.allouche@google.com" />
+ <link rel="author" title="Oren Roth" href="mailto:oren.roth@gmail.com" />
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-dir-attribute" />
+ <meta name="assert" content="
+ When dir='auto', the direction is set according to the first strong character
+ of descendant text while ignoring descendant style elements.
+ In this test, it is the Latin letter A, thus the direction must be
+ resolved as LTR." />
+ <style>
+ input, textarea {
+ font-size:1em;
+ }
+ body {
+ font-size:2em;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments {
+ display: none;
+ }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="comments">
+ Key to entities used below:
+ &#x05D0; - The Hebrew letter Alef (strongly RTL).
+ &#x05D1; - The Hebrew letter Bet (strongly RTL).
+ &#x05D2; - The Hebrew letter Gimel (strongly RTL).
+ </div>
+ <div class="test">
+ <div dir="ltr">
+ <div dir="auto"><style>body {color:black;}</style>ABC&#x05D0;&#x05D1;&#x05D2;.</div>
+ </div>
+ <div dir="rtl">
+ <div dir="auto"><style>body {color:black;}</style>ABC&#x05D0;&#x05D1;&#x05D2;.</div>
+ </div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">
+ <div dir="ltr"><style>body {color:black;}</style>ABC&#x05D0;&#x05D1;&#x05D2;.</div>
+ </div>
+ <div dir="rtl">
+ <div dir="ltr"><style>body {color:black;}</style>ABC&#x05D0;&#x05D1;&#x05D2;.</div>
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-contained-style-R-ref.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-contained-style-R-ref.html
new file mode 100644
index 0000000000..9ad9d7109a
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-contained-style-R-ref.html
@@ -0,0 +1,57 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>HTML Test: dir=auto, start with style, then R</title>
+ <link rel="author" title="Matitiahu Allouche" href="mailto:matitiahu.allouche@google.com" />
+ <link rel="author" title="Oren Roth" href="mailto:oren.roth@gmail.com" />
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-dir-attribute" />
+ <meta name="assert" content="
+ When dir='auto', the direction is set according to the first strong character
+ of descendant text while ignoring descendant style elements.
+ In this test, it is the Hebrew letter Alef, thus the direction must be
+ resolved as RTL." />
+ <style>
+ input, textarea {
+ font-size:1em;
+ }
+ body {
+ font-size:2em;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments {
+ display: none;
+ }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="comments">
+ Key to entities used below:
+ &#x05D0; - The Hebrew letter Alef (strongly RTL).
+ &#x05D1; - The Hebrew letter Bet (strongly RTL).
+ &#x05D2; - The Hebrew letter Gimel (strongly RTL).
+ </div>
+ <div class="test">
+ <div dir="ltr">
+ <div dir="rtl"><style>body {color:black;}</style>&#x05D0;&#x05D1;&#x05D2;ABC.</div>
+ </div>
+ <div dir="rtl">
+ <div dir="rtl"><style>body {color:black;}</style>&#x05D0;&#x05D1;&#x05D2;ABC.</div>
+ </div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">
+ <div dir="rtl"><style>body {color:black;}</style>&#x05D0;&#x05D1;&#x05D2;ABC.</div>
+ </div>
+ <div dir="rtl">
+ <div dir="rtl"><style>body {color:black;}</style>&#x05D0;&#x05D1;&#x05D2;ABC.</div>
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-contained-style-R.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-contained-style-R.html
new file mode 100644
index 0000000000..4aa70cdb2e
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-contained-style-R.html
@@ -0,0 +1,58 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>HTML Test: dir=auto, start with style, then R</title>
+ <link rel="match" href="dir_auto-contained-style-R-ref.html" />
+ <link rel="author" title="Matitiahu Allouche" href="mailto:matitiahu.allouche@google.com" />
+ <link rel="author" title="Oren Roth" href="mailto:oren.roth@gmail.com" />
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-dir-attribute" />
+ <meta name="assert" content="
+ When dir='auto', the direction is set according to the first strong character
+ of descendant text while ignoring descendant style elements.
+ In this test, it is the Hebrew letter Alef, thus the direction must be
+ resolved as RTL." />
+ <style>
+ input, textarea {
+ font-size:1em;
+ }
+ body {
+ font-size:2em;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments {
+ display: none;
+ }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="comments">
+ Key to entities used below:
+ &#x05D0; - The Hebrew letter Alef (strongly RTL).
+ &#x05D1; - The Hebrew letter Bet (strongly RTL).
+ &#x05D2; - The Hebrew letter Gimel (strongly RTL).
+ </div>
+ <div class="test">
+ <div dir="ltr">
+ <div dir="auto"><style>body {color:black;}</style>&#x05D0;&#x05D1;&#x05D2;ABC.</div>
+ </div>
+ <div dir="rtl">
+ <div dir="auto"><style>body {color:black;}</style>&#x05D0;&#x05D1;&#x05D2;ABC.</div>
+ </div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">
+ <div dir="rtl"><style>body {color:black;}</style>&#x05D0;&#x05D1;&#x05D2;ABC.</div>
+ </div>
+ <div dir="rtl">
+ <div dir="rtl"><style>body {color:black;}</style>&#x05D0;&#x05D1;&#x05D2;ABC.</div>
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-contained-textarea-L-ref.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-contained-textarea-L-ref.html
new file mode 100644
index 0000000000..411099f7b4
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-contained-textarea-L-ref.html
@@ -0,0 +1,60 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>HTML Test: dir=auto, start with textarea, then L</title>
+ <link rel="author" title="Matitiahu Allouche" href="mailto:matitiahu.allouche@google.com" />
+ <link rel="author" title="Oren Roth" href="mailto:oren.roth@gmail.com" />
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-dir-attribute" />
+ <meta name="assert" content="
+ When dir='auto', the direction is set according to the first strong character
+ of descendant text while ignoring descendant textarea elements.
+ In this test, it is the Latin letter A, thus the direction must be
+ resolved as LTR." />
+ <style>
+ input, textarea {
+ font-size:1em;
+ }
+ body {
+ font-size:2em;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments {
+ display: none;
+ }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="comments">
+ Key to entities used below:
+ &#x05D0; - The Hebrew letter Alef (strongly RTL).
+ &#x05D1; - The Hebrew letter Bet (strongly RTL).
+ &#x05D2; - The Hebrew letter Gimel (strongly RTL).
+ &#x05D3; - The Hebrew letter Dalet (strongly RTL).
+ &#x05D4; - The Hebrew letter He (strongly RTL).
+ &#x05D5; - The Hebrew letter Vav (strongly RTL).
+ </div>
+ <div class="test">
+ <div dir="ltr">
+ <div dir="ltr"><textarea>&#x05D3;&#x05D4;&#x05D5;</textarea>ABC&#x05D0;&#x05D1;&#x05D2;.</div>
+ </div>
+ <div dir="rtl">
+ <div dir="ltr"><textarea>&#x05D3;&#x05D4;&#x05D5;</textarea>ABC&#x05D0;&#x05D1;&#x05D2;.</div>
+ </div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">
+ <div dir="ltr"><textarea>&#x05D3;&#x05D4;&#x05D5;</textarea>ABC&#x05D0;&#x05D1;&#x05D2;.</div>
+ </div>
+ <div dir="rtl">
+ <div dir="ltr"><textarea>&#x05D3;&#x05D4;&#x05D5;</textarea>ABC&#x05D0;&#x05D1;&#x05D2;.</div>
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-contained-textarea-L.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-contained-textarea-L.html
new file mode 100644
index 0000000000..0de041fe01
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-contained-textarea-L.html
@@ -0,0 +1,61 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>HTML Test: dir=auto, start with textarea, then L</title>
+ <link rel="match" href="dir_auto-contained-textarea-L-ref.html" />
+ <link rel="author" title="Matitiahu Allouche" href="mailto:matitiahu.allouche@google.com" />
+ <link rel="author" title="Oren Roth" href="mailto:oren.roth@gmail.com" />
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-dir-attribute" />
+ <meta name="assert" content="
+ When dir='auto', the direction is set according to the first strong character
+ of descendant text while ignoring descendant textarea elements.
+ In this test, it is the Latin letter A, thus the direction must be
+ resolved as LTR." />
+ <style>
+ input, textarea {
+ font-size:1em;
+ }
+ body {
+ font-size:2em;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments {
+ display: none;
+ }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="comments">
+ Key to entities used below:
+ &#x05D0; - The Hebrew letter Alef (strongly RTL).
+ &#x05D1; - The Hebrew letter Bet (strongly RTL).
+ &#x05D2; - The Hebrew letter Gimel (strongly RTL).
+ &#x05D3; - The Hebrew letter Dalet (strongly RTL).
+ &#x05D4; - The Hebrew letter He (strongly RTL).
+ &#x05D5; - The Hebrew letter Vav (strongly RTL).
+ </div>
+ <div class="test">
+ <div dir="ltr">
+ <div dir="auto"><textarea>&#x05D3;&#x05D4;&#x05D5;</textarea>ABC&#x05D0;&#x05D1;&#x05D2;.</div>
+ </div>
+ <div dir="rtl">
+ <div dir="auto"><textarea>&#x05D3;&#x05D4;&#x05D5;</textarea>ABC&#x05D0;&#x05D1;&#x05D2;.</div>
+ </div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">
+ <div dir="ltr"><textarea>&#x05D3;&#x05D4;&#x05D5;</textarea>ABC&#x05D0;&#x05D1;&#x05D2;.</div>
+ </div>
+ <div dir="rtl">
+ <div dir="ltr"><textarea>&#x05D3;&#x05D4;&#x05D5;</textarea>ABC&#x05D0;&#x05D1;&#x05D2;.</div>
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-contained-textarea-R-ref.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-contained-textarea-R-ref.html
new file mode 100644
index 0000000000..351431fb2b
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-contained-textarea-R-ref.html
@@ -0,0 +1,57 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>HTML Test: dir=auto, start with textarea, then R</title>
+ <link rel="author" title="Matitiahu Allouche" href="mailto:matitiahu.allouche@google.com" />
+ <link rel="author" title="Oren Roth" href="mailto:oren.roth@gmail.com" />
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-dir-attribute" />
+ <meta name="assert" content="
+ When dir='auto', the direction is set according to the first strong character
+ of descendant text while ignoring descendant textarea elements.
+ In this test, it is the Hebrew letter Alef, thus the direction must be
+ resolved as RTL." />
+ <style>
+ input, textarea {
+ font-size:1em;
+ }
+ body {
+ font-size:2em;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments {
+ display: none;
+ }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="comments">
+ Key to entities used below:
+ &#x05D0; - The Hebrew letter Alef (strongly RTL).
+ &#x05D1; - The Hebrew letter Bet (strongly RTL).
+ &#x05D2; - The Hebrew letter Gimel (strongly RTL).
+ </div>
+ <div class="test">
+ <div dir="ltr">
+ <div dir="rtl"><textarea>DEF</textarea>&#x05D0;&#x05D1;&#x05D2;ABC.</div>
+ </div>
+ <div dir="rtl">
+ <div dir="rtl"><textarea>DEF</textarea>&#x05D0;&#x05D1;&#x05D2;ABC.</div>
+ </div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">
+ <div dir="rtl"><textarea>DEF</textarea>&#x05D0;&#x05D1;&#x05D2;ABC.</div>
+ </div>
+ <div dir="rtl">
+ <div dir="rtl"><textarea>DEF</textarea>&#x05D0;&#x05D1;&#x05D2;ABC.</div>
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-contained-textarea-R.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-contained-textarea-R.html
new file mode 100644
index 0000000000..852de6073c
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-contained-textarea-R.html
@@ -0,0 +1,58 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>HTML Test: dir=auto, start with textarea, then R</title>
+ <link rel="match" href="dir_auto-contained-textarea-R-ref.html" />
+ <link rel="author" title="Matitiahu Allouche" href="mailto:matitiahu.allouche@google.com" />
+ <link rel="author" title="Oren Roth" href="mailto:oren.roth@gmail.com" />
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-dir-attribute" />
+ <meta name="assert" content="
+ When dir='auto', the direction is set according to the first strong character
+ of descendant text while ignoring descendant textarea elements.
+ In this test, it is the Hebrew letter Alef, thus the direction must be
+ resolved as RTL." />
+ <style>
+ input, textarea {
+ font-size:1em;
+ }
+ body {
+ font-size:2em;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments {
+ display: none;
+ }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="comments">
+ Key to entities used below:
+ &#x05D0; - The Hebrew letter Alef (strongly RTL).
+ &#x05D1; - The Hebrew letter Bet (strongly RTL).
+ &#x05D2; - The Hebrew letter Gimel (strongly RTL).
+ </div>
+ <div class="test">
+ <div dir="ltr">
+ <div dir="auto"><textarea>DEF</textarea>&#x05D0;&#x05D1;&#x05D2;ABC.</div>
+ </div>
+ <div dir="rtl">
+ <div dir="auto"><textarea>DEF</textarea>&#x05D0;&#x05D1;&#x05D2;ABC.</div>
+ </div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">
+ <div dir="rtl"><textarea>DEF</textarea>&#x05D0;&#x05D1;&#x05D2;ABC.</div>
+ </div>
+ <div dir="rtl">
+ <div dir="rtl"><textarea>DEF</textarea>&#x05D0;&#x05D1;&#x05D2;ABC.</div>
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-EN-L-ref.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-EN-L-ref.html
new file mode 100644
index 0000000000..198d081c26
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-EN-L-ref.html
@@ -0,0 +1,58 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>HTML Test: input with dir=auto, start with EN+L</title>
+ <link rel="author" title="Matitiahu Allouche" href="mailto:matitiahu.allouche@google.com" />
+ <link rel="author" title="Oren Roth" href="mailto:oren.roth@gmail.com" />
+ <link rel="author" title="Shai Berger" href="mailto:shai@platonix.com" />
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-dir-attribute" />
+ <meta name="assert" content="
+ When dir='auto', the direction of an input element is set according to
+ the first strong character of its value.
+ In this test, it is the Latin letter A since digits are not strongly
+ directional, thus the direction must be resolved as LTR." />
+ <style>
+ input, textarea {
+ font-size:1em;
+ }
+ body {
+ font-size:2em;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments {
+ display: none;
+ }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="comments">
+ Key to entities used below:
+ &#x05D0; - The Hebrew letter Alef (strongly RTL).
+ &#x05D1; - The Hebrew letter Bet (strongly RTL).
+ &#x05D2; - The Hebrew letter Gimel (strongly RTL).
+ </div>
+ <div class="test">
+ <div dir="ltr">
+ <input type="text" dir="ltr" value="123ABC&#x05D0;&#x05D1;&#x05D2;." />
+ </div>
+ <div dir="rtl">
+ <input type="text" dir="ltr" value="123ABC&#x05D0;&#x05D1;&#x05D2;." />
+ </div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">
+ <input type="text" dir="ltr" value="123ABC&#x05D0;&#x05D1;&#x05D2;." />
+ </div>
+ <div dir="rtl">
+ <input type="text" dir="ltr" value="123ABC&#x05D0;&#x05D1;&#x05D2;." />
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-EN-L.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-EN-L.html
new file mode 100644
index 0000000000..d5ade6c096
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-EN-L.html
@@ -0,0 +1,59 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>HTML Test: input with dir=auto, start with EN+L</title>
+ <link rel="match" href="dir_auto-input-EN-L-ref.html" />
+ <link rel="author" title="Matitiahu Allouche" href="mailto:matitiahu.allouche@google.com" />
+ <link rel="author" title="Oren Roth" href="mailto:oren.roth@gmail.com" />
+ <link rel="author" title="Shai Berger" href="mailto:shai@platonix.com" />
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-dir-attribute" />
+ <meta name="assert" content="
+ When dir='auto', the direction of an input element is set according to
+ the first strong character of its value.
+ In this test, it is the Latin letter A since digits are not strongly
+ directional, thus the direction must be resolved as LTR." />
+ <style>
+ input, textarea {
+ font-size:1em;
+ }
+ body {
+ font-size:2em;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments {
+ display: none;
+ }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="comments">
+ Key to entities used below:
+ &#x05D0; - The Hebrew letter Alef (strongly RTL).
+ &#x05D1; - The Hebrew letter Bet (strongly RTL).
+ &#x05D2; - The Hebrew letter Gimel (strongly RTL).
+ </div>
+ <div class="test">
+ <div dir="ltr">
+ <input type="text" dir="auto" value="123ABC&#x05D0;&#x05D1;&#x05D2;." />
+ </div>
+ <div dir="rtl">
+ <input type="text" dir="auto" value="123ABC&#x05D0;&#x05D1;&#x05D2;." />
+ </div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">
+ <input type="text" dir="ltr" value="123ABC&#x05D0;&#x05D1;&#x05D2;." />
+ </div>
+ <div dir="rtl">
+ <input type="text" dir="ltr" value="123ABC&#x05D0;&#x05D1;&#x05D2;." />
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-EN-R-ref.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-EN-R-ref.html
new file mode 100644
index 0000000000..303afc3c6b
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-EN-R-ref.html
@@ -0,0 +1,58 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>HTML Test: input with dir=auto, start with EN+R</title>
+ <link rel="author" title="Matitiahu Allouche" href="mailto:matitiahu.allouche@google.com" />
+ <link rel="author" title="Oren Roth" href="mailto:oren.roth@gmail.com" />
+ <link rel="author" title="Shai Berger" href="mailto:shai@platonix.com" />
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-dir-attribute" />
+ <meta name="assert" content="
+ When dir='auto', the direction of an input element is set according to
+ the first strong character of its value.
+ In this test, it is the Hebrew letter Alef since digits are not strongly
+ directional, thus the direction must be resolved as RTL." />
+ <style>
+ input, textarea {
+ font-size:1em;
+ }
+ body {
+ font-size:2em;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments {
+ display: none;
+ }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="comments">
+ Key to entities used below:
+ &#x05D0; - The Hebrew letter Alef (strongly RTL).
+ &#x05D1; - The Hebrew letter Bet (strongly RTL).
+ &#x05D2; - The Hebrew letter Gimel (strongly RTL).
+ </div>
+ <div class="test">
+ <div dir="ltr">
+ <input type="text" dir="rtl" value="123&#x05D0;&#x05D1;&#x05D2;ABC." />
+ </div>
+ <div dir="rtl">
+ <input type="text" dir="rtl" value="123&#x05D0;&#x05D1;&#x05D2;ABC." />
+ </div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">
+ <input type="text" dir="rtl" value="123&#x05D0;&#x05D1;&#x05D2;ABC." />
+ </div>
+ <div dir="rtl">
+ <input type="text" dir="rtl" value="123&#x05D0;&#x05D1;&#x05D2;ABC." />
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-EN-R.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-EN-R.html
new file mode 100644
index 0000000000..08ef3ecd70
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-EN-R.html
@@ -0,0 +1,59 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>HTML Test: input with dir=auto, start with EN+R</title>
+ <link rel="match" href="dir_auto-input-EN-R-ref.html" />
+ <link rel="author" title="Matitiahu Allouche" href="mailto:matitiahu.allouche@google.com" />
+ <link rel="author" title="Oren Roth" href="mailto:oren.roth@gmail.com" />
+ <link rel="author" title="Shai Berger" href="mailto:shai@platonix.com" />
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-dir-attribute" />
+ <meta name="assert" content="
+ When dir='auto', the direction of an input element is set according to
+ the first strong character of its value.
+ In this test, it is the Hebrew letter Alef since digits are not strongly
+ directional, thus the direction must be resolved as RTL." />
+ <style>
+ input, textarea {
+ font-size:1em;
+ }
+ body {
+ font-size:2em;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments {
+ display: none;
+ }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="comments">
+ Key to entities used below:
+ &#x05D0; - The Hebrew letter Alef (strongly RTL).
+ &#x05D1; - The Hebrew letter Bet (strongly RTL).
+ &#x05D2; - The Hebrew letter Gimel (strongly RTL).
+ </div>
+ <div class="test">
+ <div dir="ltr">
+ <input type="text" dir="auto" value="123&#x05D0;&#x05D1;&#x05D2;ABC." />
+ </div>
+ <div dir="rtl">
+ <input type="text" dir="auto" value="123&#x05D0;&#x05D1;&#x05D2;ABC." />
+ </div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">
+ <input type="text" dir="rtl" value="123&#x05D0;&#x05D1;&#x05D2;ABC." />
+ </div>
+ <div dir="rtl">
+ <input type="text" dir="rtl" value="123&#x05D0;&#x05D1;&#x05D2;ABC." />
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-L-ref.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-L-ref.html
new file mode 100644
index 0000000000..cb3621aa61
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-L-ref.html
@@ -0,0 +1,58 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>HTML Test: input with dir=auto, start with L</title>
+ <link rel="author" title="Matitiahu Allouche" href="mailto:matitiahu.allouche@google.com" />
+ <link rel="author" title="Oren Roth" href="mailto:oren.roth@gmail.com" />
+ <link rel="author" title="Shai Berger" href="mailto:shai@platonix.com" />
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-dir-attribute" />
+ <meta name="assert" content="
+ When dir='auto', the direction of an input element is set according to
+ the first strong character of its value.
+ In this test, it is the Latin letter A, thus the direction must be
+ resolved as LTR." />
+ <style>
+ input, textarea {
+ font-size:1em;
+ }
+ body {
+ font-size:2em;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments {
+ display: none;
+ }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="comments">
+ Key to entities used below:
+ &#x05D0; - The Hebrew letter Alef (strongly RTL).
+ &#x05D1; - The Hebrew letter Bet (strongly RTL).
+ &#x05D2; - The Hebrew letter Gimel (strongly RTL).
+ </div>
+ <div class="test">
+ <div dir="ltr">
+ <input type="text" dir="ltr" value="ABC&#x05d0;&#x05d1;&#x05d2;." />
+ </div>
+ <div dir="rtl">
+ <input type="text" dir="ltr" value="ABC&#x05d0;&#x05d1;&#x05d2;." />
+ </div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">
+ <input type="text" dir="ltr" value="ABC&#x05d0;&#x05d1;&#x05d2;." />
+ </div>
+ <div dir="rtl">
+ <input type="text" dir="ltr" value="ABC&#x05d0;&#x05d1;&#x05d2;." />
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-L.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-L.html
new file mode 100644
index 0000000000..0a23f2b86d
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-L.html
@@ -0,0 +1,59 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>HTML Test: input with dir=auto, start with L</title>
+ <link rel="match" href="dir_auto-input-L-ref.html" />
+ <link rel="author" title="Matitiahu Allouche" href="mailto:matitiahu.allouche@google.com" />
+ <link rel="author" title="Oren Roth" href="mailto:oren.roth@gmail.com" />
+ <link rel="author" title="Shai Berger" href="mailto:shai@platonix.com" />
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-dir-attribute" />
+ <meta name="assert" content="
+ When dir='auto', the direction of an input element is set according to
+ the first strong character of its value.
+ In this test, it is the Latin letter A, thus the direction must be
+ resolved as LTR." />
+ <style>
+ input, textarea {
+ font-size:1em;
+ }
+ body {
+ font-size:2em;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments {
+ display: none;
+ }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="comments">
+ Key to entities used below:
+ &#x05D0; - The Hebrew letter Alef (strongly RTL).
+ &#x05D1; - The Hebrew letter Bet (strongly RTL).
+ &#x05D2; - The Hebrew letter Gimel (strongly RTL).
+ </div>
+ <div class="test">
+ <div dir="ltr">
+ <input type="text" dir="auto" value="ABC&#x05d0;&#x05d1;&#x05d2;." />
+ </div>
+ <div dir="rtl">
+ <input type="text" dir="auto" value="ABC&#x05d0;&#x05d1;&#x05d2;." />
+ </div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">
+ <input type="text" dir="ltr" value="ABC&#x05d0;&#x05d1;&#x05d2;." />
+ </div>
+ <div dir="rtl">
+ <input type="text" dir="ltr" value="ABC&#x05d0;&#x05d1;&#x05d2;." />
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-N-EN-L-ref.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-N-EN-L-ref.html
new file mode 100644
index 0000000000..3d0f2cf3cc
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-N-EN-L-ref.html
@@ -0,0 +1,58 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>HTML Test: input with dir=auto, start with N+EN+L</title>
+ <link rel="author" title="Matitiahu Allouche" href="mailto:matitiahu.allouche@google.com" />
+ <link rel="author" title="Oren Roth" href="mailto:oren.roth@gmail.com" />
+ <link rel="author" title="Shai Berger" href="mailto:shai@platonix.com" />
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-dir-attribute" />
+ <meta name="assert" content="
+ When dir='auto', the direction of an input element is set according to
+ the first strong character of its value.
+ In this test, it is the Latin letter A since neutrals and digits are not
+ strongly directional, thus the direction must be resolved as LTR." />
+ <style>
+ input, textarea {
+ font-size:1em;
+ }
+ body {
+ font-size:2em;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments {
+ display: none;
+ }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="comments">
+ Key to entities used below:
+ &#x05D0; - The Hebrew letter Alef (strongly RTL).
+ &#x05D1; - The Hebrew letter Bet (strongly RTL).
+ &#x05D2; - The Hebrew letter Gimel (strongly RTL).
+ </div>
+ <div class="test">
+ <div dir="ltr">
+ <input type="text" dir="ltr" value=".-=123ABC&#x05D0;&#x05D1;&#x05D2;." />
+ </div>
+ <div dir="rtl">
+ <input type="text" dir="ltr" value=".-=123ABC&#x05D0;&#x05D1;&#x05D2;." />
+ </div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">
+ <input type="text" dir="ltr" value=".-=123ABC&#x05D0;&#x05D1;&#x05D2;." />
+ </div>
+ <div dir="rtl">
+ <input type="text" dir="ltr" value=".-=123ABC&#x05D0;&#x05D1;&#x05D2;." />
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-N-EN-L.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-N-EN-L.html
new file mode 100644
index 0000000000..03f85526da
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-N-EN-L.html
@@ -0,0 +1,59 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>HTML Test: input with dir=auto, start with N+EN+L</title>
+ <link rel="match" href="dir_auto-input-N-EN-L-ref.html" />
+ <link rel="author" title="Matitiahu Allouche" href="mailto:matitiahu.allouche@google.com" />
+ <link rel="author" title="Oren Roth" href="mailto:oren.roth@gmail.com" />
+ <link rel="author" title="Shai Berger" href="mailto:shai@platonix.com" />
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-dir-attribute" />
+ <meta name="assert" content="
+ When dir='auto', the direction of an input element is set according to
+ the first strong character of its value.
+ In this test, it is the Latin letter A since neutrals and digits are not
+ strongly directional, thus the direction must be resolved as LTR." />
+ <style>
+ input, textarea {
+ font-size:1em;
+ }
+ body {
+ font-size:2em;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments {
+ display: none;
+ }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="comments">
+ Key to entities used below:
+ &#x05D0; - The Hebrew letter Alef (strongly RTL).
+ &#x05D1; - The Hebrew letter Bet (strongly RTL).
+ &#x05D2; - The Hebrew letter Gimel (strongly RTL).
+ </div>
+ <div class="test">
+ <div dir="ltr">
+ <input type="text" dir="auto" value=".-=123ABC&#x05D0;&#x05D1;&#x05D2;." />
+ </div>
+ <div dir="rtl">
+ <input type="text" dir="auto" value=".-=123ABC&#x05D0;&#x05D1;&#x05D2;." />
+ </div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">
+ <input type="text" dir="ltr" value=".-=123ABC&#x05D0;&#x05D1;&#x05D2;." />
+ </div>
+ <div dir="rtl">
+ <input type="text" dir="ltr" value=".-=123ABC&#x05D0;&#x05D1;&#x05D2;." />
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-N-EN-R-ref.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-N-EN-R-ref.html
new file mode 100644
index 0000000000..26bf27d619
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-N-EN-R-ref.html
@@ -0,0 +1,58 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>HTML Test: input with dir=auto, start with N+EN+R</title>
+ <link rel="author" title="Matitiahu Allouche" href="mailto:matitiahu.allouche@google.com" />
+ <link rel="author" title="Oren Roth" href="mailto:oren.roth@gmail.com" />
+ <link rel="author" title="Shai Berger" href="mailto:shai@platonix.com" />
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-dir-attribute" />
+ <meta name="assert" content="
+ When dir='auto', the direction of an input element is set according to
+ the first strong character of its value.
+ In this test, it is the Hebrew letter Alef since neutrals and digits are not
+ strongly directional, thus the direction must be resolved as RTL." />
+ <style>
+ input, textarea {
+ font-size:1em;
+ }
+ body {
+ font-size:2em;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments {
+ display: none;
+ }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="comments">
+ Key to entities used below:
+ &#x05D0; - The Hebrew letter Alef (strongly RTL).
+ &#x05D1; - The Hebrew letter Bet (strongly RTL).
+ &#x05D2; - The Hebrew letter Gimel (strongly RTL).
+ </div>
+ <div class="test">
+ <div dir="ltr">
+ <input type="text" dir="rtl" value=".-=123&#x05D0;&#x05D1;&#x05D2;ABC." />
+ </div>
+ <div dir="rtl">
+ <input type="text" dir="rtl" value=".-=123&#x05D0;&#x05D1;&#x05D2;ABC." />
+ </div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">
+ <input type="text" dir="rtl" value=".-=123&#x05D0;&#x05D1;&#x05D2;ABC." />
+ </div>
+ <div dir="rtl">
+ <input type="text" dir="rtl" value=".-=123&#x05D0;&#x05D1;&#x05D2;ABC." />
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-N-EN-R.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-N-EN-R.html
new file mode 100644
index 0000000000..13193d3d72
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-N-EN-R.html
@@ -0,0 +1,59 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>HTML Test: input with dir=auto, start with N+EN+R</title>
+ <link rel="match" href="dir_auto-input-N-EN-R-ref.html" />
+ <link rel="author" title="Matitiahu Allouche" href="mailto:matitiahu.allouche@google.com" />
+ <link rel="author" title="Oren Roth" href="mailto:oren.roth@gmail.com" />
+ <link rel="author" title="Shai Berger" href="mailto:shai@platonix.com" />
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-dir-attribute" />
+ <meta name="assert" content="
+ When dir='auto', the direction of an input element is set according to
+ the first strong character of its value.
+ In this test, it is the Hebrew letter Alef since neutrals and digits are not
+ strongly directional, thus the direction must be resolved as RTL." />
+ <style>
+ input, textarea {
+ font-size:1em;
+ }
+ body {
+ font-size:2em;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments {
+ display: none;
+ }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="comments">
+ Key to entities used below:
+ &#x05D0; - The Hebrew letter Alef (strongly RTL).
+ &#x05D1; - The Hebrew letter Bet (strongly RTL).
+ &#x05D2; - The Hebrew letter Gimel (strongly RTL).
+ </div>
+ <div class="test">
+ <div dir="ltr">
+ <input type="text" dir="auto" value=".-=123&#x05D0;&#x05D1;&#x05D2;ABC." />
+ </div>
+ <div dir="rtl">
+ <input type="text" dir="auto" value=".-=123&#x05D0;&#x05D1;&#x05D2;ABC." />
+ </div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">
+ <input type="text" dir="rtl" value=".-=123&#x05D0;&#x05D1;&#x05D2;ABC." />
+ </div>
+ <div dir="rtl">
+ <input type="text" dir="rtl" value=".-=123&#x05D0;&#x05D1;&#x05D2;ABC." />
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-N-EN-ref.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-N-EN-ref.html
new file mode 100644
index 0000000000..33f75b730b
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-N-EN-ref.html
@@ -0,0 +1,53 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>HTML Test: input with dir=auto, all N+EN</title>
+ <link rel="author" title="Matitiahu Allouche" href="mailto:matitiahu.allouche@google.com" />
+ <link rel="author" title="Oren Roth" href="mailto:oren.roth@gmail.com" />
+ <link rel="author" title="Shai Berger" href="mailto:shai@platonix.com" />
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-dir-attribute" />
+ <meta name="assert" content="
+ When dir='auto', the direction of an input element is set according to
+ the first strong character of its value, or to LTR if there is no such
+ character.
+ In this test, there is no strongly directional character in the value,
+ thus the direction must be resolved as LTR." />
+ <style>
+ input, textarea {
+ font-size:1em;
+ }
+ body {
+ font-size:2em;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments {
+ display: none;
+ }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="test">
+ <div dir="ltr">
+ <input type="text" dir="ltr" value="@123!" />
+ </div>
+ <div dir="rtl">
+ <input type="text" dir="ltr" value="@123!" />
+ </div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">
+ <input type="text" dir="ltr" value="@123!" />
+ </div>
+ <div dir="rtl">
+ <input type="text" dir="ltr" value="@123!" />
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-N-EN.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-N-EN.html
new file mode 100644
index 0000000000..03df3c6dcc
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-N-EN.html
@@ -0,0 +1,54 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>HTML Test: input with dir=auto, all N+EN</title>
+ <link rel="match" href="dir_auto-input-N-EN-ref.html" />
+ <link rel="author" title="Matitiahu Allouche" href="mailto:matitiahu.allouche@google.com" />
+ <link rel="author" title="Oren Roth" href="mailto:oren.roth@gmail.com" />
+ <link rel="author" title="Shai Berger" href="mailto:shai@platonix.com" />
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-dir-attribute" />
+ <meta name="assert" content="
+ When dir='auto', the direction of an input element is set according to
+ the first strong character of its value, or to LTR if there is no such
+ character.
+ In this test, there is no strongly directional character in the value,
+ thus the direction must be resolved as LTR." />
+ <style>
+ input, textarea {
+ font-size:1em;
+ }
+ body {
+ font-size:2em;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments {
+ display: none;
+ }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="test">
+ <div dir="ltr">
+ <input type="text" dir="auto" value="@123!" />
+ </div>
+ <div dir="rtl">
+ <input type="text" dir="auto" value="@123!" />
+ </div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">
+ <input type="text" dir="ltr" value="@123!" />
+ </div>
+ <div dir="rtl">
+ <input type="text" dir="ltr" value="@123!" />
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-N-L-ref.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-N-L-ref.html
new file mode 100644
index 0000000000..b6a89a1d72
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-N-L-ref.html
@@ -0,0 +1,58 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>HTML Test: input with dir=auto, start with N+L</title>
+ <link rel="author" title="Matitiahu Allouche" href="mailto:matitiahu.allouche@google.com" />
+ <link rel="author" title="Oren Roth" href="mailto:oren.roth@gmail.com" />
+ <link rel="author" title="Shai Berger" href="mailto:shai@platonix.com" />
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-dir-attribute" />
+ <meta name="assert" content="
+ When dir='auto', the direction of an input element is set according to
+ the first strong character of its value.
+ In this test, it is the Latin letter A since neutrals are not
+ strongly directional, thus the direction must be resolved as LTR." />
+ <style>
+ input, textarea {
+ font-size:1em;
+ }
+ body {
+ font-size:2em;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments {
+ display: none;
+ }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="comments">
+ Key to entities used below:
+ &#x05D0; - The Hebrew letter Alef (strongly RTL).
+ &#x05D1; - The Hebrew letter Bet (strongly RTL).
+ &#x05D2; - The Hebrew letter Gimel (strongly RTL).
+ </div>
+ <div class="test">
+ <div dir="ltr">
+ <input type="text" dir="ltr" value=".-=ABC&#x05D0;&#x05D1;&#x05D2;." />
+ </div>
+ <div dir="rtl">
+ <input type="text" dir="ltr" value=".-=ABC&#x05D0;&#x05D1;&#x05D2;." />
+ </div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">
+ <input type="text" dir="ltr" value=".-=ABC&#x05D0;&#x05D1;&#x05D2;." />
+ </div>
+ <div dir="rtl">
+ <input type="text" dir="ltr" value=".-=ABC&#x05D0;&#x05D1;&#x05D2;." />
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-N-L.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-N-L.html
new file mode 100644
index 0000000000..9c1d3bceec
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-N-L.html
@@ -0,0 +1,59 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>HTML Test: input with dir=auto, start with N+L</title>
+ <link rel="match" href="dir_auto-input-N-L-ref.html" />
+ <link rel="author" title="Matitiahu Allouche" href="mailto:matitiahu.allouche@google.com" />
+ <link rel="author" title="Oren Roth" href="mailto:oren.roth@gmail.com" />
+ <link rel="author" title="Shai Berger" href="mailto:shai@platonix.com" />
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-dir-attribute" />
+ <meta name="assert" content="
+ When dir='auto', the direction of an input element is set according to
+ the first strong character of its value.
+ In this test, it is the Latin letter A since neutrals are not
+ strongly directional, thus the direction must be resolved as LTR." />
+ <style>
+ input, textarea {
+ font-size:1em;
+ }
+ body {
+ font-size:2em;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments {
+ display: none;
+ }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="comments">
+ Key to entities used below:
+ &#x05D0; - The Hebrew letter Alef (strongly RTL).
+ &#x05D1; - The Hebrew letter Bet (strongly RTL).
+ &#x05D2; - The Hebrew letter Gimel (strongly RTL).
+ </div>
+ <div class="test">
+ <div dir="ltr">
+ <input type="text" dir="auto" value=".-=ABC&#x05D0;&#x05D1;&#x05D2;." />
+ </div>
+ <div dir="rtl">
+ <input type="text" dir="auto" value=".-=ABC&#x05D0;&#x05D1;&#x05D2;." />
+ </div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">
+ <input type="text" dir="ltr" value=".-=ABC&#x05D0;&#x05D1;&#x05D2;." />
+ </div>
+ <div dir="rtl">
+ <input type="text" dir="ltr" value=".-=ABC&#x05D0;&#x05D1;&#x05D2;." />
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-N-R-ref.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-N-R-ref.html
new file mode 100644
index 0000000000..bcd5430441
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-N-R-ref.html
@@ -0,0 +1,58 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>HTML Test: input with dir=auto, start with N+R</title>
+ <link rel="author" title="Matitiahu Allouche" href="mailto:matitiahu.allouche@google.com" />
+ <link rel="author" title="Oren Roth" href="mailto:oren.roth@gmail.com" />
+ <link rel="author" title="Shai Berger" href="mailto:shai@platonix.com" />
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-dir-attribute" />
+ <meta name="assert" content="
+ When dir='auto', the direction of an input element is set according to
+ the first strong character of its value.
+ In this test, it is the Hebrew letter Alef since neutrals are not
+ strongly directional, thus the direction must be resolved as RTL." />
+ <style>
+ input, textarea {
+ font-size:1em;
+ }
+ body {
+ font-size:2em;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments {
+ display: none;
+ }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="comments">
+ Key to entities used below:
+ &#x05D0; - The Hebrew letter Alef (strongly RTL).
+ &#x05D1; - The Hebrew letter Bet (strongly RTL).
+ &#x05D2; - The Hebrew letter Gimel (strongly RTL).
+ </div>
+ <div class="test">
+ <div dir="ltr">
+ <input type="text" dir="rtl" value=".-=&#x05D0;&#x05D1;&#x05D2;ABC." />
+ </div>
+ <div dir="rtl">
+ <input type="text" dir="rtl" value=".-=&#x05D0;&#x05D1;&#x05D2;ABC." />
+ </div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">
+ <input type="text" dir="rtl" value=".-=&#x05D0;&#x05D1;&#x05D2;ABC." />
+ </div>
+ <div dir="rtl">
+ <input type="text" dir="rtl" value=".-=&#x05D0;&#x05D1;&#x05D2;ABC." />
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-N-R.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-N-R.html
new file mode 100644
index 0000000000..dbf54f7344
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-N-R.html
@@ -0,0 +1,59 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>HTML Test: input with dir=auto, start with N+R</title>
+ <link rel="match" href="dir_auto-input-N-R-ref.html" />
+ <link rel="author" title="Matitiahu Allouche" href="mailto:matitiahu.allouche@google.com" />
+ <link rel="author" title="Oren Roth" href="mailto:oren.roth@gmail.com" />
+ <link rel="author" title="Shai Berger" href="mailto:shai@platonix.com" />
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-dir-attribute" />
+ <meta name="assert" content="
+ When dir='auto', the direction of an input element is set according to
+ the first strong character of its value.
+ In this test, it is the Hebrew letter Alef since neutrals are not
+ strongly directional, thus the direction must be resolved as RTL." />
+ <style>
+ input, textarea {
+ font-size:1em;
+ }
+ body {
+ font-size:2em;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments {
+ display: none;
+ }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="comments">
+ Key to entities used below:
+ &#x05D0; - The Hebrew letter Alef (strongly RTL).
+ &#x05D1; - The Hebrew letter Bet (strongly RTL).
+ &#x05D2; - The Hebrew letter Gimel (strongly RTL).
+ </div>
+ <div class="test">
+ <div dir="ltr">
+ <input type="text" dir="auto" value=".-=&#x05D0;&#x05D1;&#x05D2;ABC." />
+ </div>
+ <div dir="rtl">
+ <input type="text" dir="auto" value=".-=&#x05D0;&#x05D1;&#x05D2;ABC." />
+ </div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">
+ <input type="text" dir="rtl" value=".-=&#x05D0;&#x05D1;&#x05D2;ABC." />
+ </div>
+ <div dir="rtl">
+ <input type="text" dir="rtl" value=".-=&#x05D0;&#x05D1;&#x05D2;ABC." />
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-R-ref.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-R-ref.html
new file mode 100644
index 0000000000..217972e82d
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-R-ref.html
@@ -0,0 +1,58 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>HTML Test: input with dir=auto, start with R</title>
+ <link rel="author" title="Matitiahu Allouche" href="mailto:matitiahu.allouche@google.com" />
+ <link rel="author" title="Oren Roth" href="mailto:oren.roth@gmail.com" />
+ <link rel="author" title="Shai Berger" href="mailto:shai@platonix.com" />
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-dir-attribute" />
+ <meta name="assert" content="
+ When dir='auto', the direction of an input element is set according to
+ the first strong character of its value.
+ In this test, it is the Hebrew letter Alef, thus the direction must be
+ resolved as RTL." />
+ <style>
+ input, textarea {
+ font-size:1em;
+ }
+ body {
+ font-size:2em;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments {
+ display: none;
+ }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="comments">
+ Key to entities used below:
+ &#x05D0; - The Hebrew letter Alef (strongly RTL).
+ &#x05D1; - The Hebrew letter Bet (strongly RTL).
+ &#x05D2; - The Hebrew letter Gimel (strongly RTL).
+ </div>
+ <div class="test">
+ <div dir="ltr">
+ <input type="text" dir="rtl" value="&#x05D0;&#x05D1;&#x05D2;ABC." />
+ </div>
+ <div dir="rtl">
+ <input type="text" dir="rtl" value="&#x05D0;&#x05D1;&#x05D2;ABC." />
+ </div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">
+ <input type="text" dir="rtl" value="&#x05D0;&#x05D1;&#x05D2;ABC." />
+ </div>
+ <div dir="rtl">
+ <input type="text" dir="rtl" value="&#x05D0;&#x05D1;&#x05D2;ABC." />
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-R.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-R.html
new file mode 100644
index 0000000000..6d2612b316
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-R.html
@@ -0,0 +1,59 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>HTML Test: input with dir=auto, start with R</title>
+ <link rel="match" href="dir_auto-input-R-ref.html" />
+ <link rel="author" title="Matitiahu Allouche" href="mailto:matitiahu.allouche@google.com" />
+ <link rel="author" title="Oren Roth" href="mailto:oren.roth@gmail.com" />
+ <link rel="author" title="Shai Berger" href="mailto:shai@platonix.com" />
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-dir-attribute" />
+ <meta name="assert" content="
+ When dir='auto', the direction of an input element is set according to
+ the first strong character of its value.
+ In this test, it is the Hebrew letter Alef, thus the direction must be
+ resolved as RTL." />
+ <style>
+ input, textarea {
+ font-size:1em;
+ }
+ body {
+ font-size:2em;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments {
+ display: none;
+ }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="comments">
+ Key to entities used below:
+ &#x05D0; - The Hebrew letter Alef (strongly RTL).
+ &#x05D1; - The Hebrew letter Bet (strongly RTL).
+ &#x05D2; - The Hebrew letter Gimel (strongly RTL).
+ </div>
+ <div class="test">
+ <div dir="ltr">
+ <input type="text" dir="auto" value="&#x05D0;&#x05D1;&#x05D2;ABC." />
+ </div>
+ <div dir="rtl">
+ <input type="text" dir="auto" value="&#x05D0;&#x05D1;&#x05D2;ABC." />
+ </div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">
+ <input type="text" dir="rtl" value="&#x05D0;&#x05D1;&#x05D2;ABC." />
+ </div>
+ <div dir="rtl">
+ <input type="text" dir="rtl" value="&#x05D0;&#x05D1;&#x05D2;ABC." />
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-script-EN-L-ref.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-script-EN-L-ref.html
new file mode 100644
index 0000000000..879e20d6cf
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-script-EN-L-ref.html
@@ -0,0 +1,58 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>HTML Test: input with dir=auto, script assigns to start with EN+L</title>
+ <link rel="author" title="Matitiahu Allouche" href="mailto:matitiahu.allouche@google.com" />
+ <link rel="author" title="Oren Roth" href="mailto:oren.roth@gmail.com" />
+ <link rel="author" title="Shai Berger" href="mailto:shai@platonix.com" />
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-dir-attribute" />
+ <meta name="assert" content="
+ When dir='auto', the direction of an input element is set according to
+ the first strong character of its value.
+ In this test, it is the Latin letter A since digits are not strongly
+ directional, thus the direction must be resolved as LTR." />
+ <style>
+ input, textarea {
+ font-size:1em;
+ }
+ body {
+ font-size:2em;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments {
+ display: none;
+ }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="comments">
+ Key to entities used below:
+ &#x05D0; - The Hebrew letter Alef (strongly RTL).
+ &#x05D1; - The Hebrew letter Bet (strongly RTL).
+ &#x05D2; - The Hebrew letter Gimel (strongly RTL).
+ </div>
+ <div class="test">
+ <div dir="ltr">
+ <input type="text" dir="ltr" value="123ABC&#x05D0;&#x05D1;&#x05D2;." />
+ </div>
+ <div dir="rtl">
+ <input type="text" dir="ltr" value="123ABC&#x05D0;&#x05D1;&#x05D2;." />
+ </div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">
+ <input type="text" dir="ltr" value="123ABC&#x05D0;&#x05D1;&#x05D2;." />
+ </div>
+ <div dir="rtl">
+ <input type="text" dir="ltr" value="123ABC&#x05D0;&#x05D1;&#x05D2;." />
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-script-EN-L.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-script-EN-L.html
new file mode 100644
index 0000000000..d0a9e2bb9b
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-script-EN-L.html
@@ -0,0 +1,70 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>HTML Test: input with dir=auto, script assigns to start with EN+L</title>
+ <link rel="match" href="dir_auto-input-script-EN-L-ref.html" />
+ <link rel="author" title="Matitiahu Allouche" href="mailto:matitiahu.allouche@google.com" />
+ <link rel="author" title="Oren Roth" href="mailto:oren.roth@gmail.com" />
+ <link rel="author" title="Shai Berger" href="mailto:shai@platonix.com" />
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-dir-attribute" />
+ <meta name="assert" content="
+ When dir='auto', the direction of an input element is set according to
+ the first strong character of its value.
+ In this test, it is the Latin letter A since digits are not strongly
+ directional, thus the direction must be resolved as LTR." />
+ <style>
+ input, textarea {
+ font-size:1em;
+ }
+ body {
+ font-size:2em;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments {
+ display: none;
+ }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="comments">
+ Key to entities used below:
+ &#x05D0; - The Hebrew letter Alef (strongly RTL).
+ &#x05D1; - The Hebrew letter Bet (strongly RTL).
+ &#x05D2; - The Hebrew letter Gimel (strongly RTL).
+ This test makes sure that the direction is set correctly for an input whose value is set
+ dynamically by script.
+ </div>
+ <div id="test" class="test">
+ <script>
+ window.onload = function() {
+ var test = document.getElementById('test');
+ var inputs = test.getElementsByTagName('input');
+ for (var i = 0; i != inputs.length; i++) {
+ inputs[i].value = '123ABC\u05D0\u05D1\u05D2.';
+ }
+ }
+ </script>
+ <div dir="ltr">
+ <input type="text" dir="auto" value="&#x05D0;" />
+ </div>
+ <div dir="rtl">
+ <input type="text" dir="auto" value="&#x05D0;" />
+ </div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">
+ <input type="text" dir="ltr" value="123ABC&#x05D0;&#x05D1;&#x05D2;." />
+ </div>
+ <div dir="rtl">
+ <input type="text" dir="ltr" value="123ABC&#x05D0;&#x05D1;&#x05D2;." />
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-script-EN-R-ref.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-script-EN-R-ref.html
new file mode 100644
index 0000000000..15781e2524
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-script-EN-R-ref.html
@@ -0,0 +1,58 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>HTML Test: input with dir=auto, script assigns to start with EN+R</title>
+ <link rel="author" title="Matitiahu Allouche" href="mailto:matitiahu.allouche@google.com" />
+ <link rel="author" title="Oren Roth" href="mailto:oren.roth@gmail.com" />
+ <link rel="author" title="Shai Berger" href="mailto:shai@platonix.com" />
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-dir-attribute" />
+ <meta name="assert" content="
+ When dir='auto', the direction of an input element is set according to
+ the first strong character of its value.
+ In this test, it is the Hebrew letter Alef since digits are not strongly
+ directional, thus the direction must be resolved as RTL." />
+ <style>
+ input, textarea {
+ font-size:1em;
+ }
+ body {
+ font-size:2em;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments {
+ display: none;
+ }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="comments">
+ Key to entities used below:
+ &#x05D0; - The Hebrew letter Alef (strongly RTL).
+ &#x05D1; - The Hebrew letter Bet (strongly RTL).
+ &#x05D2; - The Hebrew letter Gimel (strongly RTL).
+ </div>
+ <div class="test">
+ <div dir="ltr">
+ <input type="text" dir="rtl" value="123&#x05D0;&#x05D1;&#x05D2;ABC." />
+ </div>
+ <div dir="rtl">
+ <input type="text" dir="rtl" value="123&#x05D0;&#x05D1;&#x05D2;ABC." />
+ </div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">
+ <input type="text" dir="rtl" value="123&#x05D0;&#x05D1;&#x05D2;ABC." />
+ </div>
+ <div dir="rtl">
+ <input type="text" dir="rtl" value="123&#x05D0;&#x05D1;&#x05D2;ABC." />
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-script-EN-R.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-script-EN-R.html
new file mode 100644
index 0000000000..e444b90dc2
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-script-EN-R.html
@@ -0,0 +1,70 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>HTML Test: input with dir=auto, script assigns to start with EN+R</title>
+ <link rel="match" href="dir_auto-input-script-EN-R-ref.html" />
+ <link rel="author" title="Matitiahu Allouche" href="mailto:matitiahu.allouche@google.com" />
+ <link rel="author" title="Oren Roth" href="mailto:oren.roth@gmail.com" />
+ <link rel="author" title="Shai Berger" href="mailto:shai@platonix.com" />
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-dir-attribute" />
+ <meta name="assert" content="
+ When dir='auto', the direction of an input element is set according to
+ the first strong character of its value.
+ In this test, it is the Hebrew letter Alef since digits are not strongly
+ directional, thus the direction must be resolved as RTL." />
+ <style>
+ input, textarea {
+ font-size:1em;
+ }
+ body {
+ font-size:2em;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments {
+ display: none;
+ }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="comments">
+ Key to entities used below:
+ &#x05D0; - The Hebrew letter Alef (strongly RTL).
+ &#x05D1; - The Hebrew letter Bet (strongly RTL).
+ &#x05D2; - The Hebrew letter Gimel (strongly RTL).
+ This test makes sure that the direction is set correctly for an input whose value is set
+ dynamically by script.
+ </div>
+ <div id="test" class="test">
+ <script>
+ window.onload = function() {
+ var test = document.getElementById('test');
+ var inputs = test.getElementsByTagName('input');
+ for (var i = 0; i != inputs.length; i++) {
+ inputs[i].value = '123\u05D0\u05D1\u05D2ABC.';
+ }
+ }
+ </script>
+ <div dir="ltr">
+ <input type="text" dir="auto" value="a" />
+ </div>
+ <div dir="rtl">
+ <input type="text" dir="auto" value="a" />
+ </div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">
+ <input type="text" dir="rtl" value="123&#x05D0;&#x05D1;&#x05D2;ABC." />
+ </div>
+ <div dir="rtl">
+ <input type="text" dir="rtl" value="123&#x05D0;&#x05D1;&#x05D2;ABC." />
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-script-L-ref.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-script-L-ref.html
new file mode 100644
index 0000000000..0feef25047
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-script-L-ref.html
@@ -0,0 +1,58 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>HTML Test: input with dir=auto, script assigns to start with L</title>
+ <link rel="author" title="Matitiahu Allouche" href="mailto:matitiahu.allouche@google.com" />
+ <link rel="author" title="Oren Roth" href="mailto:oren.roth@gmail.com" />
+ <link rel="author" title="Shai Berger" href="mailto:shai@platonix.com" />
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-dir-attribute" />
+ <meta name="assert" content="
+ When dir='auto', the direction of an input element is set according to
+ the first strong character of its value.
+ In this test, it is the Latin letter A, thus the direction must be
+ resolved as LTR." />
+ <style>
+ input, textarea {
+ font-size:1em;
+ }
+ body {
+ font-size:2em;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments {
+ display: none;
+ }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="comments">
+ Key to entities used below:
+ &#x05D0; - The Hebrew letter Alef (strongly RTL).
+ &#x05D1; - The Hebrew letter Bet (strongly RTL).
+ &#x05D2; - The Hebrew letter Gimel (strongly RTL).
+ </div>
+ <div class="test">
+ <div dir="ltr">
+ <input type="text" dir="ltr" value="ABC&#x05D0;&#x05D1;&#x05D2;." />
+ </div>
+ <div dir="rtl">
+ <input type="text" dir="ltr" value="ABC&#x05D0;&#x05D1;&#x05D2;." />
+ </div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">
+ <input type="text" dir="ltr" value="ABC&#x05D0;&#x05D1;&#x05D2;." />
+ </div>
+ <div dir="rtl">
+ <input type="text" dir="ltr" value="ABC&#x05D0;&#x05D1;&#x05D2;." />
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-script-L.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-script-L.html
new file mode 100644
index 0000000000..e6aa700ad0
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-script-L.html
@@ -0,0 +1,70 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>HTML Test: input with dir=auto, script assigns to start with L</title>
+ <link rel="match" href="dir_auto-input-script-L-ref.html" />
+ <link rel="author" title="Matitiahu Allouche" href="mailto:matitiahu.allouche@google.com" />
+ <link rel="author" title="Oren Roth" href="mailto:oren.roth@gmail.com" />
+ <link rel="author" title="Shai Berger" href="mailto:shai@platonix.com" />
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-dir-attribute" />
+ <meta name="assert" content="
+ When dir='auto', the direction of an input element is set according to
+ the first strong character of its value.
+ In this test, it is the Latin letter A, thus the direction must be
+ resolved as LTR." />
+ <style>
+ input, textarea {
+ font-size:1em;
+ }
+ body {
+ font-size:2em;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments {
+ display: none;
+ }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="comments">
+ Key to entities used below:
+ &#x05D0; - The Hebrew letter Alef (strongly RTL).
+ &#x05D1; - The Hebrew letter Bet (strongly RTL).
+ &#x05D2; - The Hebrew letter Gimel (strongly RTL).
+ This test makes sure that the direction is set correctly for an input whose value is set
+ dynamically by script.
+ </div>
+ <div id="test" class="test">
+ <script>
+ window.onload = function() {
+ var test = document.getElementById('test');
+ var inputs = test.getElementsByTagName('input');
+ for (var i = 0; i != inputs.length; i++) {
+ inputs[i].value = 'ABC\u05D0\u05D1\u05D2.';
+ }
+ }
+ </script>
+ <div dir="ltr">
+ <input type="text" dir="auto" value="&#x05D0;" />
+ </div>
+ <div dir="rtl">
+ <input type="text" dir="auto" value="&#x05D0;" />
+ </div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">
+ <input type="text" dir="ltr" value="ABC&#x05D0;&#x05D1;&#x05D2;." />
+ </div>
+ <div dir="rtl">
+ <input type="text" dir="ltr" value="ABC&#x05D0;&#x05D1;&#x05D2;." />
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-script-N-EN-L-ref.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-script-N-EN-L-ref.html
new file mode 100644
index 0000000000..6d6902f314
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-script-N-EN-L-ref.html
@@ -0,0 +1,58 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>HTML Test: input with dir=auto, script assigns to start with N+EN+L</title>
+ <link rel="author" title="Matitiahu Allouche" href="mailto:matitiahu.allouche@google.com" />
+ <link rel="author" title="Oren Roth" href="mailto:oren.roth@gmail.com" />
+ <link rel="author" title="Shai Berger" href="mailto:shai@platonix.com" />
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-dir-attribute" />
+ <meta name="assert" content="
+ When dir='auto', the direction of an input element is set according to
+ the first strong character of its value.
+ In this test, it is the Latin letter A since neutrals and digits are not
+ strongly directional, thus the direction must be resolved as LTR." />
+ <style>
+ input, textarea {
+ font-size:1em;
+ }
+ body {
+ font-size:2em;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments {
+ display: none;
+ }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="comments">
+ Key to entities used below:
+ &#x05D0; - The Hebrew letter Alef (strongly RTL).
+ &#x05D1; - The Hebrew letter Bet (strongly RTL).
+ &#x05D2; - The Hebrew letter Gimel (strongly RTL).
+ </div>
+ <div class="test">
+ <div dir="ltr">
+ <input type="text" dir="ltr" value=".-=123ABC&#x05D0;&#x05D1;&#x05D2;." />
+ </div>
+ <div dir="rtl">
+ <input type="text" dir="ltr" value=".-=123ABC&#x05D0;&#x05D1;&#x05D2;." />
+ </div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">
+ <input type="text" dir="ltr" value=".-=123ABC&#x05D0;&#x05D1;&#x05D2;." />
+ </div>
+ <div dir="rtl">
+ <input type="text" dir="ltr" value=".-=123ABC&#x05D0;&#x05D1;&#x05D2;." />
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-script-N-EN-L.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-script-N-EN-L.html
new file mode 100644
index 0000000000..7905cee946
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-script-N-EN-L.html
@@ -0,0 +1,70 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>HTML Test: input with dir=auto, script assigns to start with N+EN+L</title>
+ <link rel="match" href="dir_auto-input-script-N-EN-L-ref.html" />
+ <link rel="author" title="Matitiahu Allouche" href="mailto:matitiahu.allouche@google.com" />
+ <link rel="author" title="Oren Roth" href="mailto:oren.roth@gmail.com" />
+ <link rel="author" title="Shai Berger" href="mailto:shai@platonix.com" />
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-dir-attribute" />
+ <meta name="assert" content="
+ When dir='auto', the direction of an input element is set according to
+ the first strong character of its value.
+ In this test, it is the Latin letter A since neutrals and digits are not
+ strongly directional, thus the direction must be resolved as LTR." />
+ <style>
+ input, textarea {
+ font-size:1em;
+ }
+ body {
+ font-size:2em;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments {
+ display: none;
+ }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="comments">
+ Key to entities used below:
+ &#x05D0; - The Hebrew letter Alef (strongly RTL).
+ &#x05D1; - The Hebrew letter Bet (strongly RTL).
+ &#x05D2; - The Hebrew letter Gimel (strongly RTL).
+ This test makes sure that the direction is set correctly for an input whose value is set
+ dynamically by script.
+ </div>
+ <div id="test" class="test">
+ <script>
+ window.onload = function() {
+ var test = document.getElementById('test');
+ var inputs = test.getElementsByTagName('input');
+ for (var i = 0; i != inputs.length; i++) {
+ inputs[i].value = '.-=123ABC\u05D0\u05D1\u05D2.';
+ }
+ }
+ </script>
+ <div dir="ltr">
+ <input type="text" dir="auto" value="&#x05D0;" />
+ </div>
+ <div dir="rtl">
+ <input type="text" dir="auto" value="&#x05D0;" />
+ </div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">
+ <input type="text" dir="ltr" value=".-=123ABC&#x05D0;&#x05D1;&#x05D2;." />
+ </div>
+ <div dir="rtl">
+ <input type="text" dir="ltr" value=".-=123ABC&#x05D0;&#x05D1;&#x05D2;." />
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-script-N-EN-R-ref.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-script-N-EN-R-ref.html
new file mode 100644
index 0000000000..53dd892096
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-script-N-EN-R-ref.html
@@ -0,0 +1,58 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>HTML Test: input with dir=auto, script assigns to start with N+EN+R</title>
+ <link rel="author" title="Matitiahu Allouche" href="mailto:matitiahu.allouche@google.com" />
+ <link rel="author" title="Oren Roth" href="mailto:oren.roth@gmail.com" />
+ <link rel="author" title="Shai Berger" href="mailto:shai@platonix.com" />
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-dir-attribute" />
+ <meta name="assert" content="
+ When dir='auto', the direction of an input element is set according to
+ the first strong character of its value.
+ In this test, it is the Hebrew letter Alef since neutrals and digits are not
+ strongly directional, thus the direction must be resolved as RTL." />
+ <style>
+ input, textarea {
+ font-size:1em;
+ }
+ body {
+ font-size:2em;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments {
+ display: none;
+ }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="comments">
+ Key to entities used below:
+ &#x05D0; - The Hebrew letter Alef (strongly RTL).
+ &#x05D1; - The Hebrew letter Bet (strongly RTL).
+ &#x05D2; - The Hebrew letter Gimel (strongly RTL).
+ </div>
+ <div class="test">
+ <div dir="ltr">
+ <input type="text" dir="rtl" value=".-=123&#x05D0;&#x05D1;&#x05D2;ABC." />
+ </div>
+ <div dir="rtl">
+ <input type="text" dir="rtl" value=".-=123&#x05D0;&#x05D1;&#x05D2;ABC." />
+ </div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">
+ <input type="text" dir="rtl" value=".-=123&#x05D0;&#x05D1;&#x05D2;ABC." />
+ </div>
+ <div dir="rtl">
+ <input type="text" dir="rtl" value=".-=123&#x05D0;&#x05D1;&#x05D2;ABC." />
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-script-N-EN-R.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-script-N-EN-R.html
new file mode 100644
index 0000000000..95faa72ea7
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-script-N-EN-R.html
@@ -0,0 +1,70 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>HTML Test: input with dir=auto, script assigns to start with N+EN+R</title>
+ <link rel="match" href="dir_auto-input-script-N-EN-R-ref.html" />
+ <link rel="author" title="Matitiahu Allouche" href="mailto:matitiahu.allouche@google.com" />
+ <link rel="author" title="Oren Roth" href="mailto:oren.roth@gmail.com" />
+ <link rel="author" title="Shai Berger" href="mailto:shai@platonix.com" />
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-dir-attribute" />
+ <meta name="assert" content="
+ When dir='auto', the direction of an input element is set according to
+ the first strong character of its value.
+ In this test, it is the Hebrew letter Alef since neutrals and digits are not
+ strongly directional, thus the direction must be resolved as RTL." />
+ <style>
+ input, textarea {
+ font-size:1em;
+ }
+ body {
+ font-size:2em;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments {
+ display: none;
+ }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="comments">
+ Key to entities used below:
+ &#x05D0; - The Hebrew letter Alef (strongly RTL).
+ &#x05D1; - The Hebrew letter Bet (strongly RTL).
+ &#x05D2; - The Hebrew letter Gimel (strongly RTL).
+ This test makes sure that the direction is set correctly for an input whose value is set
+ dynamically by script.
+ </div>
+ <div id="test" class="test">
+ <script>
+ window.onload = function() {
+ var test = document.getElementById('test');
+ var inputs = test.getElementsByTagName('input');
+ for (var i = 0; i != inputs.length; i++) {
+ inputs[i].value = '.-=123\u05D0\u05D1\u05D2ABC.';
+ }
+ }
+ </script>
+ <div dir="ltr">
+ <input type="text" dir="auto" value="a" />
+ </div>
+ <div dir="rtl">
+ <input type="text" dir="auto" value="a" />
+ </div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">
+ <input type="text" dir="rtl" value=".-=123&#x05D0;&#x05D1;&#x05D2;ABC." />
+ </div>
+ <div dir="rtl">
+ <input type="text" dir="rtl" value=".-=123&#x05D0;&#x05D1;&#x05D2;ABC." />
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-script-N-EN-ref.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-script-N-EN-ref.html
new file mode 100644
index 0000000000..11697e53eb
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-script-N-EN-ref.html
@@ -0,0 +1,53 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>HTML Test: input with dir=auto, script assigns to all N+EN</title>
+ <link rel="author" title="Matitiahu Allouche" href="mailto:matitiahu.allouche@google.com" />
+ <link rel="author" title="Oren Roth" href="mailto:oren.roth@gmail.com" />
+ <link rel="author" title="Shai Berger" href="mailto:shai@platonix.com" />
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-dir-attribute" />
+ <meta name="assert" content="
+ When dir='auto', the direction of an input element is set according to
+ the first strong character of its value, or to LTR if there is no such
+ character.
+ In this test, there is no strongly directional character in the value,
+ thus the direction must be resolved as LTR." />
+ <style>
+ input, textarea {
+ font-size:1em;
+ }
+ body {
+ font-size:2em;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments {
+ display: none;
+ }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="test">
+ <div dir="ltr">
+ <input type="text" dir="ltr" value="@123!" />
+ </div>
+ <div dir="rtl">
+ <input type="text" dir="ltr" value="@123!" />
+ </div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">
+ <input type="text" dir="ltr" value="@123!" />
+ </div>
+ <div dir="rtl">
+ <input type="text" dir="ltr" value="@123!" />
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-script-N-EN.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-script-N-EN.html
new file mode 100644
index 0000000000..2721affaef
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-script-N-EN.html
@@ -0,0 +1,69 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>HTML Test: input with dir=auto, script assigns to all N+EN</title>
+ <link rel="match" href="dir_auto-input-script-N-EN-ref.html" />
+ <link rel="author" title="Matitiahu Allouche" href="mailto:matitiahu.allouche@google.com" />
+ <link rel="author" title="Oren Roth" href="mailto:oren.roth@gmail.com" />
+ <link rel="author" title="Shai Berger" href="mailto:shai@platonix.com" />
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-dir-attribute" />
+ <meta name="assert" content="
+ When dir='auto', the direction of an input element is set according to
+ the first strong character of its value, or to LTR if there is no such
+ character.
+ In this test, there is no strongly directional character in the value,
+ thus the direction must be resolved as LTR." />
+ <style>
+ input, textarea {
+ font-size:1em;
+ }
+ body {
+ font-size:2em;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments {
+ display: none;
+ }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="comments">
+ Key to entities used below:
+ &#x05D0; - The Hebrew letter Alef (strongly RTL).
+ This test makes sure that the direction is set correctly for an input whose value is set
+ dynamically by script.
+ </div>
+ <div id="test" class="test">
+ <script>
+ window.onload = function() {
+ var test = document.getElementById('test');
+ var inputs = test.getElementsByTagName('input');
+ for (var i = 0; i != inputs.length; i++) {
+ inputs[i].value = '@123!';
+ }
+ };
+ </script>
+ <div dir="ltr">
+ <input type="text" dir="auto" value="&#x05D0;" />
+ </div>
+ <div dir="rtl">
+ <input type="text" dir="auto" value="&#x05D0;" />
+ </div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">
+ <input type="text" dir="ltr" value="@123!" />
+ </div>
+ <div dir="rtl">
+ <input type="text" dir="ltr" value="@123!" />
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-script-N-L-ref.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-script-N-L-ref.html
new file mode 100644
index 0000000000..fd7cb10fbd
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-script-N-L-ref.html
@@ -0,0 +1,58 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>HTML Test: input with dir=auto, script assigns to start with N+L</title>
+ <link rel="author" title="Matitiahu Allouche" href="mailto:matitiahu.allouche@google.com" />
+ <link rel="author" title="Oren Roth" href="mailto:oren.roth@gmail.com" />
+ <link rel="author" title="Shai Berger" href="mailto:shai@platonix.com" />
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-dir-attribute" />
+ <meta name="assert" content="
+ When dir='auto', the direction of an input element is set according to
+ the first strong character of its value.
+ In this test, it is the Latin letter A since neutrals are not
+ strongly directional, thus the direction must be resolved as LTR." />
+ <style>
+ input, textarea {
+ font-size:1em;
+ }
+ body {
+ font-size:2em;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments {
+ display: none;
+ }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="comments">
+ Key to entities used below:
+ &#x05D0; - The Hebrew letter Alef (strongly RTL).
+ &#x05D1; - The Hebrew letter Bet (strongly RTL).
+ &#x05D2; - The Hebrew letter Gimel (strongly RTL).
+ </div>
+ <div class="test">
+ <div dir="ltr">
+ <input type="text" dir="ltr" value=".-=ABC&#x05D0;&#x05D1;&#x05D2;." />
+ </div>
+ <div dir="rtl">
+ <input type="text" dir="ltr" value=".-=ABC&#x05D0;&#x05D1;&#x05D2;." />
+ </div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">
+ <input type="text" dir="ltr" value=".-=ABC&#x05D0;&#x05D1;&#x05D2;." />
+ </div>
+ <div dir="rtl">
+ <input type="text" dir="ltr" value=".-=ABC&#x05D0;&#x05D1;&#x05D2;." />
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-script-N-L.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-script-N-L.html
new file mode 100644
index 0000000000..2ff24db28c
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-script-N-L.html
@@ -0,0 +1,70 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>HTML Test: input with dir=auto, script assigns to start with N+L</title>
+ <link rel="match" href="dir_auto-input-script-N-L-ref.html" />
+ <link rel="author" title="Matitiahu Allouche" href="mailto:matitiahu.allouche@google.com" />
+ <link rel="author" title="Oren Roth" href="mailto:oren.roth@gmail.com" />
+ <link rel="author" title="Shai Berger" href="mailto:shai@platonix.com" />
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-dir-attribute" />
+ <meta name="assert" content="
+ When dir='auto', the direction of an input element is set according to
+ the first strong character of its value.
+ In this test, it is the Latin letter A since neutrals are not
+ strongly directional, thus the direction must be resolved as LTR." />
+ <style>
+ input, textarea {
+ font-size:1em;
+ }
+ body {
+ font-size:2em;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments {
+ display: none;
+ }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="comments">
+ Key to entities used below:
+ &#x05D0; - The Hebrew letter Alef (strongly RTL).
+ &#x05D1; - The Hebrew letter Bet (strongly RTL).
+ &#x05D2; - The Hebrew letter Gimel (strongly RTL).
+ This test makes sure that the direction is set correctly for an input whose value is set
+ dynamically by script.
+ </div>
+ <div id="test" class="test">
+ <script>
+ window.onload = function() {
+ var test = document.getElementById('test');
+ var inputs = test.getElementsByTagName('input');
+ for (var i = 0; i != inputs.length; i++) {
+ inputs[i].value = '.-=ABC\u05D0\u05D1\u05D2.';
+ }
+ }
+ </script>
+ <div dir="ltr">
+ <input type="text" dir="auto" value="&#x05D0;" />
+ </div>
+ <div dir="rtl">
+ <input type="text" dir="auto" value="&#x05D0;" />
+ </div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">
+ <input type="text" dir="ltr" value=".-=ABC&#x05D0;&#x05D1;&#x05D2;." />
+ </div>
+ <div dir="rtl">
+ <input type="text" dir="ltr" value=".-=ABC&#x05D0;&#x05D1;&#x05D2;." />
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-script-N-R-ref.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-script-N-R-ref.html
new file mode 100644
index 0000000000..0fa6da249a
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-script-N-R-ref.html
@@ -0,0 +1,58 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>HTML Test: input with dir=auto, script assigns to start with N+R</title>
+ <link rel="author" title="Matitiahu Allouche" href="mailto:matitiahu.allouche@google.com" />
+ <link rel="author" title="Oren Roth" href="mailto:oren.roth@gmail.com" />
+ <link rel="author" title="Shai Berger" href="mailto:shai@platonix.com" />
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-dir-attribute" />
+ <meta name="assert" content="
+ When dir='auto', the direction of an input element is set according to
+ the first strong character of its value.
+ In this test, it is the Hebrew letter Alef since neutrals are not
+ strongly directional, thus the direction must be resolved as RTL." />
+ <style>
+ input, textarea {
+ font-size:1em;
+ }
+ body {
+ font-size:2em;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments {
+ display: none;
+ }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="comments">
+ Key to entities used below:
+ &#x05D0; - The Hebrew letter Alef (strongly RTL).
+ &#x05D1; - The Hebrew letter Bet (strongly RTL).
+ &#x05D2; - The Hebrew letter Gimel (strongly RTL).
+ </div>
+ <div class="test">
+ <div dir="ltr">
+ <input type="text" dir="rtl" value=".-=&#x05D0;&#x05D1;&#x05D2;ABC." />
+ </div>
+ <div dir="rtl">
+ <input type="text" dir="rtl" value=".-=&#x05D0;&#x05D1;&#x05D2;ABC." />
+ </div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">
+ <input type="text" dir="rtl" value=".-=&#x05D0;&#x05D1;&#x05D2;ABC." />
+ </div>
+ <div dir="rtl">
+ <input type="text" dir="rtl" value=".-=&#x05D0;&#x05D1;&#x05D2;ABC." />
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-script-N-R.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-script-N-R.html
new file mode 100644
index 0000000000..0663b28ad2
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-script-N-R.html
@@ -0,0 +1,70 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>HTML Test: input with dir=auto, script assigns to start with N+R</title>
+ <link rel="match" href="dir_auto-input-script-N-R-ref.html" />
+ <link rel="author" title="Matitiahu Allouche" href="mailto:matitiahu.allouche@google.com" />
+ <link rel="author" title="Oren Roth" href="mailto:oren.roth@gmail.com" />
+ <link rel="author" title="Shai Berger" href="mailto:shai@platonix.com" />
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-dir-attribute" />
+ <meta name="assert" content="
+ When dir='auto', the direction of an input element is set according to
+ the first strong character of its value.
+ In this test, it is the Hebrew letter Alef since neutrals are not
+ strongly directional, thus the direction must be resolved as RTL." />
+ <style>
+ input, textarea {
+ font-size:1em;
+ }
+ body {
+ font-size:2em;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments {
+ display: none;
+ }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="comments">
+ Key to entities used below:
+ &#x05D0; - The Hebrew letter Alef (strongly RTL).
+ &#x05D1; - The Hebrew letter Bet (strongly RTL).
+ &#x05D2; - The Hebrew letter Gimel (strongly RTL).
+ This test makes sure that the direction is set correctly for an input whose value is set
+ dynamically by script.
+ </div>
+ <div id="test" class="test">
+ <script>
+ window.onload = function() {
+ var test = document.getElementById('test');
+ var inputs = test.getElementsByTagName('input');
+ for (var i = 0; i != inputs.length; i++) {
+ inputs[i].value = '.-=\u05D0\u05D1\u05D2ABC.';
+ }
+ }
+ </script>
+ <div dir="ltr">
+ <input type="text" dir="auto" value="a" />
+ </div>
+ <div dir="rtl">
+ <input type="text" dir="auto" value="a" />
+ </div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">
+ <input type="text" dir="rtl" value=".-=&#x05D0;&#x05D1;&#x05D2;ABC." />
+ </div>
+ <div dir="rtl">
+ <input type="text" dir="rtl" value=".-=&#x05D0;&#x05D1;&#x05D2;ABC." />
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-script-R-ref.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-script-R-ref.html
new file mode 100644
index 0000000000..12b2d1925f
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-script-R-ref.html
@@ -0,0 +1,58 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>HTML Test: input with dir=auto, script assigns to start with R</title>
+ <link rel="author" title="Matitiahu Allouche" href="mailto:matitiahu.allouche@google.com" />
+ <link rel="author" title="Oren Roth" href="mailto:oren.roth@gmail.com" />
+ <link rel="author" title="Shai Berger" href="mailto:shai@platonix.com" />
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-dir-attribute" />
+ <meta name="assert" content="
+ When dir='auto', the direction of an input element is set according to
+ the first strong character of its value.
+ In this test, it is the Hebrew letter Alef, thus the direction must be
+ resolved as RTL." />
+ <style>
+ input, textarea {
+ font-size:1em;
+ }
+ body {
+ font-size:2em;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments {
+ display: none;
+ }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="comments">
+ Key to entities used below:
+ &#x05D0; - The Hebrew letter Alef (strongly RTL).
+ &#x05D1; - The Hebrew letter Bet (strongly RTL).
+ &#x05D2; - The Hebrew letter Gimel (strongly RTL).
+ </div>
+ <div class="test">
+ <div dir="ltr">
+ <input type="text" dir="rtl" value="&#x05D0;&#x05D1;&#x05D2;ABC." />
+ </div>
+ <div dir="rtl">
+ <input type="text" dir="rtl" value="&#x05D0;&#x05D1;&#x05D2;ABC." />
+ </div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">
+ <input type="text" dir="rtl" value="&#x05D0;&#x05D1;&#x05D2;ABC." />
+ </div>
+ <div dir="rtl">
+ <input type="text" dir="rtl" value="&#x05D0;&#x05D1;&#x05D2;ABC." />
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-script-R.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-script-R.html
new file mode 100644
index 0000000000..07becaaccd
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-input-script-R.html
@@ -0,0 +1,70 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>HTML Test: input with dir=auto, script assigns to start with R</title>
+ <link rel="match" href="dir_auto-input-script-R-ref.html" />
+ <link rel="author" title="Matitiahu Allouche" href="mailto:matitiahu.allouche@google.com" />
+ <link rel="author" title="Oren Roth" href="mailto:oren.roth@gmail.com" />
+ <link rel="author" title="Shai Berger" href="mailto:shai@platonix.com" />
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-dir-attribute" />
+ <meta name="assert" content="
+ When dir='auto', the direction of an input element is set according to
+ the first strong character of its value.
+ In this test, it is the Hebrew letter Alef, thus the direction must be
+ resolved as RTL." />
+ <style>
+ input, textarea {
+ font-size:1em;
+ }
+ body {
+ font-size:2em;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments {
+ display: none;
+ }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="comments">
+ Key to entities used below:
+ &#x05D0; - The Hebrew letter Alef (strongly RTL).
+ &#x05D1; - The Hebrew letter Bet (strongly RTL).
+ &#x05D2; - The Hebrew letter Gimel (strongly RTL).
+ This test makes sure that the direction is set correctly for an input whose value is set
+ dynamically by script.
+ </div>
+ <div id="test" class="test">
+ <script>
+ window.onload = function() {
+ var test = document.getElementById('test');
+ var inputs = test.getElementsByTagName('input');
+ for (var i = 0; i != inputs.length; i++) {
+ inputs[i].value = '\u05D0\u05D1\u05D2ABC.';
+ }
+ }
+ </script>
+ <div dir="ltr">
+ <input type="text" dir="auto" value="a" />
+ </div>
+ <div dir="rtl">
+ <input type="text" dir="auto" value="a" />
+ </div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">
+ <input type="text" dir="rtl" value="&#x05D0;&#x05D1;&#x05D2;ABC." />
+ </div>
+ <div dir="rtl">
+ <input type="text" dir="rtl" value="&#x05D0;&#x05D1;&#x05D2;ABC." />
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-isolate-ref.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-isolate-ref.html
new file mode 100644
index 0000000000..858a7db233
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-isolate-ref.html
@@ -0,0 +1,57 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>HTML Test: dir=auto, isolated in LTR text</title>
+ <link rel="author" title="Matitiahu Allouche" href="mailto:matitiahu.allouche@google.com" />
+ <link rel="author" title="Oren Roth" href="mailto:oren.roth@gmail.com" />
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-dir-attribute" />
+ <meta name="assert" content="
+ When dir='auto', the direction is set according to the first strong character
+ of the text, but the element behaves externally as a neutral character.
+ In this test, it allows a preceding R to form a single directional run
+ with a succeeding number." />
+ <style>
+ input, textarea {
+ font-size:1em;
+ }
+ body {
+ font-size:2em;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments {
+ display: none;
+ }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="comments">
+ Key to entities used below:
+ &#x05D0; - The Hebrew letter Alef (strongly RTL).
+ &#x202D; - The LRO (left-to-right override) formatting character.
+ &#x202C; - The PDF (pop directional formatting) formatting character; closes LRO.
+ </div>
+ <div class="test">
+ <div dir="ltr">
+ &#x202D;1 a! &#x05D0;&#x202C;
+ </div>
+ <div dir="rtl">
+ &#x202D;a !&#x05D0; 1&#x202C;
+ </div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">
+ &#x202D;1 a! &#x05D0;&#x202C;
+ </div>
+ <div dir="rtl">
+ &#x202D;a !&#x05D0; 1&#x202C;
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-isolate.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-isolate.html
new file mode 100644
index 0000000000..14272c0531
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-isolate.html
@@ -0,0 +1,58 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>HTML Test: dir=auto, isolated in LTR text</title>
+ <link rel="match" href="dir_auto-isolate-ref.html" />
+ <link rel="author" title="Matitiahu Allouche" href="mailto:matitiahu.allouche@google.com" />
+ <link rel="author" title="Oren Roth" href="mailto:oren.roth@gmail.com" />
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-dir-attribute" />
+ <meta name="assert" content="
+ When dir='auto', the direction is set according to the first strong character
+ of the text, but the element behaves externally as a neutral character.
+ In this test, it allows a preceding R to form a single directional run
+ with a succeeding number." />
+ <style>
+ input, textarea {
+ font-size:1em;
+ }
+ body {
+ font-size:2em;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments {
+ display: none;
+ }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="comments">
+ Key to entities used below:
+ &#x05D0; - The Hebrew letter Alef (strongly RTL).
+ &#x202D; - The LRO (left-to-right override) formatting character.
+ &#x202C; - The PDF (pop directional formatting) formatting character; closes LRO.
+ </div>
+ <div class="test">
+ <div dir="ltr">
+ &#x05D0; <span dir="auto">a!</span> 1
+ </div>
+ <div dir="rtl">
+ a <span dir="auto">&#x05D0;!</span> 1
+ </div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">
+ &#x202D;1 a! &#x05D0;&#x202C;
+ </div>
+ <div dir="rtl">
+ &#x202D;a !&#x05D0; 1&#x202C;
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-pre-N-EN-ref.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-pre-N-EN-ref.html
new file mode 100644
index 0000000000..c951c30b20
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-pre-N-EN-ref.html
@@ -0,0 +1,49 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <link rel="author" title="Aharon Lanin" href="mailto:aharon@google.com" />
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com" />
+ <style>
+ body {
+ font-size:18px;
+ text-align:left;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments {
+ display: none;
+ }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="test">
+ <div dir="ltr">
+ <pre dir="ltr">
+@123!
+ </pre>
+ </div>
+ <div dir="rtl">
+ <pre dir="ltr">
+@123!
+ </pre>
+ </div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">
+ <pre dir="ltr">
+@123!
+ </pre>
+ </div>
+ <div dir="rtl">
+ <pre dir="ltr">
+@123!
+ </pre>
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-pre-N-EN.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-pre-N-EN.html
new file mode 100644
index 0000000000..cd721d725e
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-pre-N-EN.html
@@ -0,0 +1,66 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>HTML Test: pre with dir=auto, all N+EN</title>
+ <link rel="match" href="dir_auto-pre-N-EN-ref.html" />
+ <link rel="author" title="Aharon Lanin" href="mailto:aharon@google.com" />
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-dir-attribute" />
+ <link rel="help" href="http://dev.w3.org/csswg/css3-writing-modes/#unicode-bidi0" />
+ <meta name="assert" content="
+ When dir='auto', the direction is set according to the first strong character
+ of the text.
+ For textarea and pre elements, the heuristic is applied on a per-paragraph level.
+ If there is no strong character, as in this test, the direction defaults to LTR." />
+ <style>
+ body {
+ font-size:18px;
+ text-align:left;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments {
+ display: none;
+ }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="comments">
+ Key to entities used below:
+ &#x200E; - LRM, the invisible left-to-right mark (strongly LTR).
+ &#x200F; - RLM, the invisible right-to-left mark (strongly RTL).
+ We use text-align:left because neither the dir="auto" nor the unicode-bidi:plaintext
+ specification states whether text-align:start and text-align:end should obey the paragraph
+ direction or the direction property in a unicode-bidi:plaintext element.
+ </div>
+ <div class="test">
+ <div dir="ltr">
+ <pre dir="auto">
+@123!
+ </pre>
+ </div>
+ <div dir="rtl">
+ <pre dir="auto">
+@123!
+ </pre>
+ </div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">
+ <pre dir="ltr">
+@123!
+ </pre>
+ </div>
+ <div dir="rtl">
+ <pre dir="ltr">
+@123!
+ </pre>
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-pre-N-between-Rs-ref.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-pre-N-between-Rs-ref.html
new file mode 100644
index 0000000000..2d9caf062d
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-pre-N-between-Rs-ref.html
@@ -0,0 +1,61 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <link rel="author" title="Aharon Lanin" href="mailto:aharon@google.com" />
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com" />
+ <style>
+ body {
+ font-size:18px;
+ text-align:left;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments {
+ display: none;
+ }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="comments">
+ Key to entities used below:
+ &#x05D0; - The Hebrew letter Alef (strongly RTL).
+ </div>
+ <div class="test">
+ <div dir="ltr">
+ <pre dir="rtl">
+&#x05D0;
+!...
+&#x05D0;
+ </pre>
+ </div>
+ <div dir="rtl">
+ <pre dir="rtl">
+&#x05D0;
+!...
+&#x05D0;
+ </pre>
+ </div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">
+ <pre dir="rtl">
+&#x05D0;
+!...
+&#x05D0;
+ </pre>
+ </div>
+ <div dir="rtl">
+ <pre dir="rtl">
+&#x05D0;
+!...
+&#x05D0;
+ </pre>
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-pre-N-between-Rs.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-pre-N-between-Rs.html
new file mode 100644
index 0000000000..adca24d88f
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-pre-N-between-Rs.html
@@ -0,0 +1,76 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>HTML Test: pre with dir=auto, all-N between all-Rs</title>
+ <link rel="match" href="dir_auto-pre-N-between-Rs-ref.html" />
+ <link rel="author" title="Aharon Lanin" href="mailto:aharon@google.com" />
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-dir-attribute" />
+ <link rel="help" href="http://dev.w3.org/csswg/css3-writing-modes/#unicode-bidi0" />
+ <meta name="assert" content="
+ When dir='auto', the direction is set according to the first strong character
+ of the text.
+ For textarea and pre elements, the heuristic is applied on a per-paragraph level.
+ If there is no strong character, as in this test, the direction defaults to LTR." />
+ <style>
+ body {
+ font-size:18px;
+ text-align:left;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments {
+ display: none;
+ }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="comments">
+ Key to entities used below:
+ &#x05D0; - The Hebrew letter Alef (strongly RTL).
+ We use text-align:left because neither the dir="auto" nor the unicode-bidi:plaintext
+ specification states whether text-align:start and text-align:end should obey the paragraph
+ direction or the direction property in a unicode-bidi:plaintext element.
+ The ...! paragraph, being neutral, is supposed to be displayed LTR (i.e. as ...!, not as !...)
+ despite both the paragraph before it and the paragraph after it being all-RTL, which makes the
+ element as a whole RTL.
+ </div>
+ <div class="test">
+ <div dir="ltr">
+ <pre dir="auto">
+&#x05D0;
+...!
+&#x05D0;
+ </pre>
+ </div>
+ <div dir="rtl">
+ <pre dir="auto">
+&#x05D0;
+...!
+&#x05D0;
+ </pre>
+ </div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">
+ <pre dir="rtl">
+&#x05D0;
+!...
+&#x05D0;
+ </pre>
+ </div>
+ <div dir="rtl">
+ <pre dir="rtl">
+&#x05D0;
+!...
+&#x05D0;
+ </pre>
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-pre-mixed-ref.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-pre-mixed-ref.html
new file mode 100644
index 0000000000..10bd02433b
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-pre-mixed-ref.html
@@ -0,0 +1,61 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <link rel="author" title="Aharon Lanin" href="mailto:aharon@google.com" />
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com" />
+ <style>
+ body {
+ font-size:18px;
+ text-align:left;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments {
+ display: none;
+ }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="test">
+ <div dir="ltr">
+ <pre dir="ltr">
+@123!
+@123!
+@123!
+@123!
+ </pre>
+ </div>
+ <div dir="rtl">
+ <pre dir="ltr">
+@123!
+@123!
+@123!
+@123!
+ </pre>
+ </div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">
+ <pre dir="ltr">
+@123!
+@123!
+@123!
+@123!
+ </pre>
+ </div>
+ <div dir="rtl">
+ <pre dir="ltr">
+@123!
+@123!
+@123!
+@123!
+ </pre>
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-pre-mixed.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-pre-mixed.html
new file mode 100644
index 0000000000..906365621d
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-pre-mixed.html
@@ -0,0 +1,77 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>HTML Test: pre with dir=auto, mixed L and R paragraphs</title>
+ <link rel="match" href="dir_auto-pre-mixed-ref.html" />
+ <link rel="author" title="Aharon Lanin" href="mailto:aharon@google.com" />
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-dir-attribute" />
+ <link rel="help" href="http://dev.w3.org/csswg/css3-writing-modes/#unicode-bidi0" />
+ <meta name="assert" content="
+ When dir='auto', the direction is set according to the first strong character
+ of the text.
+ For textarea and pre elements, the heuristic is applied on a per-paragraph level." />
+ <style>
+ body {
+ font-size:18px;
+ text-align:left;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments {
+ display: none;
+ }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="comments">
+ Key to entities used below:
+ &#x200E; - LRM, the invisible left-to-right mark (strongly LTR).
+ &#x200F; - RLM, the invisible right-to-left mark (strongly RTL).
+ We use text-align:left because neither the dir="auto" nor the unicode-bidi:plaintext
+ specification states whether text-align:start and text-align:end should obey the paragraph
+ direction or the direction property in a unicode-bidi:plaintext element.
+ </div>
+ <div class="test">
+ <div dir="ltr">
+ <pre dir="auto">
+@&#x200E;123&#x200F;!
+!&#x200F;123&#x200E;@
+@123&#x200E;&#x200F;!
+!123&#x200F;&#x200E;@
+ </pre>
+ </div>
+ <div dir="rtl">
+ <pre dir="auto">
+@&#x200E;123&#x200F;!
+!&#x200F;123&#x200E;@
+@123&#x200E;&#x200F;!
+!123&#x200F;&#x200E;@
+ </pre>
+ </div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">
+ <pre dir="ltr">
+@123!
+@123!
+@123!
+@123!
+ </pre>
+ </div>
+ <div dir="rtl">
+ <pre dir="ltr">
+@123!
+@123!
+@123!
+@123!
+ </pre>
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-textarea-N-EN-ref.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-textarea-N-EN-ref.html
new file mode 100644
index 0000000000..253b84459e
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-textarea-N-EN-ref.html
@@ -0,0 +1,49 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <link rel="author" title="Aharon Lanin" href="mailto:aharon@google.com" />
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com" />
+ <style>
+ body, textarea {
+ font-size:18px;
+ text-align:left;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments {
+ display: none;
+ }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="test">
+ <div dir="ltr">
+ <textarea rows="2" dir="ltr">
+@123!
+ </textarea>
+ </div>
+ <div dir="rtl">
+ <textarea rows="2" dir="ltr">
+@123!
+ </textarea>
+ </div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">
+ <textarea rows="2" dir="ltr">
+@123!
+ </textarea>
+ </div>
+ <div dir="rtl">
+ <textarea rows="2" dir="ltr">
+@123!
+ </textarea>
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-textarea-N-EN.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-textarea-N-EN.html
new file mode 100644
index 0000000000..f0fa2161a1
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-textarea-N-EN.html
@@ -0,0 +1,66 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>HTML Test: textarea with dir=auto, all N+EN</title>
+ <link rel="match" href="dir_auto-textarea-N-EN-ref.html" />
+ <link rel="author" title="Aharon Lanin" href="mailto:aharon@google.com" />
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-dir-attribute" />
+ <link rel="help" href="http://dev.w3.org/csswg/css3-writing-modes/#unicode-bidi0" />
+ <meta name="assert" content="
+ When dir='auto', the direction is set according to the first strong character
+ of the text.
+ For textarea and pre elements, the heuristic is applied on a per-paragraph level.
+ If there is no strong character, as in this test, the direction defaults to LTR." />
+ <style>
+ body, textarea {
+ font-size:18px;
+ text-align:left;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments {
+ display: none;
+ }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="comments">
+ Key to entities used below:
+ &#x200E; - LRM, the invisible left-to-right mark (strongly LTR).
+ &#x200F; - RLM, the invisible right-to-left mark (strongly RTL).
+ We use text-align:left because neither the dir="auto" nor the unicode-bidi:plaintext
+ specification states whether text-align:start and text-align:end should obey the paragraph
+ direction or the direction property in a unicode-bidi:plaintext element.
+ </div>
+ <div class="test">
+ <div dir="ltr">
+ <textarea rows="2" dir="auto">
+@123!
+ </textarea>
+ </div>
+ <div dir="rtl">
+ <textarea rows="2" dir="auto">
+@123!
+ </textarea>
+ </div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">
+ <textarea rows="2" dir="ltr">
+@123!
+ </textarea>
+ </div>
+ <div dir="rtl">
+ <textarea rows="2" dir="ltr">
+@123!
+ </textarea>
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-textarea-N-between-Rs-ref.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-textarea-N-between-Rs-ref.html
new file mode 100644
index 0000000000..afeef08cbf
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-textarea-N-between-Rs-ref.html
@@ -0,0 +1,64 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <link rel="author" title="Aharon Lanin" href="mailto:aharon@google.com" />
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com" />
+ <style>
+ body, textarea {
+ font-size:18px;
+ text-align:left;
+ }
+ textarea {
+ resize: none;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments {
+ display: none;
+ }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="comments">
+ Key to entities used below:
+ &#x05D0; - The Hebrew letter Alef (strongly RTL).
+ </div>
+ <div class="test">
+ <div dir="ltr">
+ <textarea rows="4" dir="rtl">
+&#x05D0;
+!...
+&#x05D0;
+ </textarea>
+ </div>
+ <div dir="rtl">
+ <textarea rows="4" dir="rtl">
+&#x05D0;
+!...
+&#x05D0;
+ </textarea>
+ </div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">
+ <textarea rows="4" dir="rtl">
+&#x05D0;
+!...
+&#x05D0;
+ </textarea>
+ </div>
+ <div dir="rtl">
+ <textarea rows="4" dir="rtl">
+&#x05D0;
+!...
+&#x05D0;
+ </textarea>
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-textarea-N-between-Rs.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-textarea-N-between-Rs.html
new file mode 100644
index 0000000000..b5850e1c3c
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-textarea-N-between-Rs.html
@@ -0,0 +1,79 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>HTML Test: textarea with dir=auto, all-N between all-Rs</title>
+ <link rel="match" href="dir_auto-textarea-N-between-Rs-ref.html" />
+ <link rel="author" title="Aharon Lanin" href="mailto:aharon@google.com" />
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-dir-attribute" />
+ <link rel="help" href="http://dev.w3.org/csswg/css3-writing-modes/#unicode-bidi0" />
+ <meta name="assert" content="
+ When dir='auto', the direction is set according to the first strong character
+ of the text.
+ For textarea and pre elements, the heuristic is applied on a per-paragraph level.
+ If there is no strong character, the direction defaults to LTR." />
+ <style>
+ body, textarea {
+ font-size:18px;
+ text-align:left;
+ }
+ textarea {
+ resize: none;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments {
+ display: none;
+ }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="comments">
+ Key to entities used below:
+ &#x05D0; - The Hebrew letter Alef (strongly RTL).
+ We use text-align:left because neither the dir="auto" nor the unicode-bidi:plaintext
+ specification states whether text-align:start and text-align:end should obey the paragraph
+ direction or the direction property in a unicode-bidi:plaintext element.
+ The ...! paragraph, being neutral, is supposed to be displayed LTR (i.e. as ...!, not as !...)
+ despite both the paragraph before it and the paragraph after it being all-RTL, which makes the
+ element as a whole RTL.
+ </div>
+ <div class="test">
+ <div dir="ltr">
+ <textarea rows="4" dir="auto">
+&#x05D0;
+...!
+&#x05D0;
+ </textarea>
+ </div>
+ <div dir="rtl">
+ <textarea rows="4" dir="auto">
+&#x05D0;
+...!
+&#x05D0;
+ </textarea>
+ </div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">
+ <textarea rows="4" dir="rtl">
+&#x05D0;
+!...
+&#x05D0;
+ </textarea>
+ </div>
+ <div dir="rtl">
+ <textarea rows="4" dir="rtl">
+&#x05D0;
+!...
+&#x05D0;
+ </textarea>
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-textarea-mixed-ref.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-textarea-mixed-ref.html
new file mode 100644
index 0000000000..a5a84480f6
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-textarea-mixed-ref.html
@@ -0,0 +1,64 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <link rel="author" title="Aharon Lanin" href="mailto:aharon@google.com" />
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com" />
+ <style>
+ body, textarea {
+ font-size:18px;
+ text-align:left;
+ }
+ textarea {
+ resize: none;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments {
+ display: none;
+ }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="test">
+ <div dir="ltr">
+ <textarea rows="5" dir="rtl">
+!123@
+!123@
+!123@
+!123@
+ </textarea>
+ </div>
+ <div dir="rtl">
+ <textarea rows="5" dir="ltr">
+@123!
+@123!
+@123!
+@123!
+ </textarea>
+ </div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">
+ <textarea rows="5" dir="rtl">
+!123@
+!123@
+!123@
+!123@
+ </textarea>
+ </div>
+ <div dir="rtl">
+ <textarea rows="5" dir="ltr">
+@123!
+@123!
+@123!
+@123!
+ </textarea>
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-textarea-mixed.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-textarea-mixed.html
new file mode 100644
index 0000000000..4947124c99
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-textarea-mixed.html
@@ -0,0 +1,80 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>HTML Test: textarea with dir=auto, mixed L and R paragraphs</title>
+ <link rel="match" href="dir_auto-textarea-mixed-ref.html" />
+ <link rel="author" title="Aharon Lanin" href="mailto:aharon@google.com" />
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-dir-attribute" />
+ <link rel="help" href="http://dev.w3.org/csswg/css3-writing-modes/#unicode-bidi0" />
+ <meta name="assert" content="
+ When dir='auto', the direction is set according to the first strong character
+ of the text.
+ For textarea and pre elements, the heuristic is applied on a per-paragraph level." />
+ <style>
+ body, textarea {
+ font-size:18px;
+ text-align:left;
+ }
+ textarea {
+ resize: none;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments {
+ display: none;
+ }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="comments">
+ Key to entities used below:
+ &#x200E; - LRM, the invisible left-to-right mark (strongly LTR).
+ &#x200F; - RLM, the invisible right-to-left mark (strongly RTL).
+ We use text-align:left because neither the dir="auto" nor the unicode-bidi:plaintext
+ specification states whether text-align:start and text-align:end should obey the paragraph
+ direction or the direction property in a unicode-bidi:plaintext element.
+ </div>
+ <div class="test">
+ <div dir="ltr">
+ <textarea rows="5" dir="auto">
+!&#x200F;123&#x200E;@
+@&#x200E;123&#x200F;!
+!123&#x200F;&#x200E;@
+@123&#x200E;&#x200F;!
+ </textarea>
+ </div>
+ <div dir="rtl">
+ <textarea rows="5" dir="auto">
+@&#x200E;123&#x200F;!
+!&#x200F;123&#x200E;@
+@123&#x200E;&#x200F;!
+!123&#x200F;&#x200E;@
+ </textarea>
+ </div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">
+ <textarea rows="5" dir="rtl">
+!123@
+!123@
+!123@
+!123@
+ </textarea>
+ </div>
+ <div dir="rtl">
+ <textarea rows="5" dir="ltr">
+@123!
+@123!
+@123!
+@123!
+ </textarea>
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-textarea-script-N-EN-ref.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-textarea-script-N-EN-ref.html
new file mode 100644
index 0000000000..253b84459e
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-textarea-script-N-EN-ref.html
@@ -0,0 +1,49 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <link rel="author" title="Aharon Lanin" href="mailto:aharon@google.com" />
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com" />
+ <style>
+ body, textarea {
+ font-size:18px;
+ text-align:left;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments {
+ display: none;
+ }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="test">
+ <div dir="ltr">
+ <textarea rows="2" dir="ltr">
+@123!
+ </textarea>
+ </div>
+ <div dir="rtl">
+ <textarea rows="2" dir="ltr">
+@123!
+ </textarea>
+ </div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">
+ <textarea rows="2" dir="ltr">
+@123!
+ </textarea>
+ </div>
+ <div dir="rtl">
+ <textarea rows="2" dir="ltr">
+@123!
+ </textarea>
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-textarea-script-N-EN.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-textarea-script-N-EN.html
new file mode 100644
index 0000000000..3c674e2f82
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-textarea-script-N-EN.html
@@ -0,0 +1,77 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>HTML Test: textarea with dir=auto, script assigns to all N+EN</title>
+ <link rel="match" href="dir_auto-textarea-script-N-EN-ref.html" />
+ <link rel="author" title="Aharon Lanin" href="mailto:aharon@google.com" />
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-dir-attribute" />
+ <link rel="help" href="http://dev.w3.org/csswg/css3-writing-modes/#unicode-bidi0" />
+ <meta name="assert" content="
+ When dir='auto', the direction is set according to the first strong character
+ of the text.
+ For textarea and pre elements, the heuristic is applied on a per-paragraph level.
+ If there is no strong character, as in this test, the direction defaults to LTR." />
+ <style>
+ body, textarea {
+ font-size:18px;
+ text-align:left;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments {
+ display: none;
+ }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="comments">
+ Key to entities used below:
+ &#x200E; - LRM, the invisible left-to-right mark (strongly LTR).
+ &#x200F; - RLM, the invisible right-to-left mark (strongly RTL).
+ This test makes sure that the direction is set correctly for a textarea whose value is set
+ dynamically by script.
+ We use text-align:left because neither the dir="auto" nor the unicode-bidi:plaintext
+ specification states whether text-align:start and text-align:end should obey the paragraph
+ direction or the direction property in a unicode-bidi:plaintext element.
+ </div>
+ <div id="test" class="test">
+ <script>
+ window.onload = function() {
+ var test = document.getElementById('test');
+ var textareas = test.getElementsByTagName('textarea');
+ for (var i = 0; i != textareas.length; i++) {
+ textareas[i].value = '@123!\n';
+ }
+ }
+ </script>
+ <div dir="ltr">
+ <textarea rows="2" dir="auto">
+&#x200F;
+ </textarea>
+ </div>
+ <div dir="rtl">
+ <textarea rows="2" dir="auto">
+&#x200F;
+ </textarea>
+ </div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">
+ <textarea rows="2" dir="ltr">
+@123!
+ </textarea>
+ </div>
+ <div dir="rtl">
+ <textarea rows="2" dir="ltr">
+@123!
+ </textarea>
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-textarea-script-N-between-Rs-ref.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-textarea-script-N-between-Rs-ref.html
new file mode 100644
index 0000000000..e523313252
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-textarea-script-N-between-Rs-ref.html
@@ -0,0 +1,60 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <link rel="author" title="Aharon Lanin" href="mailto:aharon@google.com" />
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com" />
+ <style>
+ body, textarea {
+ font-size:18px;
+ text-align:left;
+ }
+ textarea {
+ resize: none;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments {
+ display: none;
+ }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="comments">
+ Key to entities used below:
+ &#x05D0; - The Hebrew letter Alef (strongly RTL).
+ </div>
+ <div class="test">
+ <div dir="ltr">
+ <textarea rows="4" dir="rtl">
+&#x05D0;
+!...
+&#x05D0;</textarea>
+ </div>
+ <div dir="rtl">
+ <textarea rows="4" dir="rtl">
+&#x05D0;
+!...
+&#x05D0;</textarea>
+ </div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">
+ <textarea rows="4" dir="rtl">
+&#x05D0;
+!...
+&#x05D0;</textarea>
+ </div>
+ <div dir="rtl">
+ <textarea rows="4" dir="rtl">
+&#x05D0;
+!...
+&#x05D0;</textarea>
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-textarea-script-N-between-Rs.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-textarea-script-N-between-Rs.html
new file mode 100644
index 0000000000..f5e53667e5
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-textarea-script-N-between-Rs.html
@@ -0,0 +1,84 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>HTML Test: textarea with dir=auto, script assigns to all-N between all-Rs</title>
+ <link rel="match" href="dir_auto-textarea-script-N-between-Rs-ref.html" />
+ <link rel="author" title="Aharon Lanin" href="mailto:aharon@google.com" />
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-dir-attribute" />
+ <link rel="help" href="http://dev.w3.org/csswg/css3-writing-modes/#unicode-bidi0" />
+ <meta name="assert" content="
+ When dir='auto', the direction is set according to the first strong character
+ of the text.
+ For textarea and pre elements, the heuristic is applied on a per-paragraph level.
+ If there is no strong character, as in this test, the direction defaults to LTR." />
+ <style>
+ body, textarea {
+ font-size:18px;
+ text-align:left;
+ }
+ textarea {
+ resize: none;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments {
+ display: none;
+ }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="comments">
+ Key to entities used below:
+ &#x05D0; - The Hebrew letter Alef (strongly RTL).
+ This test makes sure that the direction is set correctly for a textarea whose value is set
+ dynamically by script.
+ We use text-align:left because neither the dir="auto" nor the unicode-bidi:plaintext
+ specification states whether text-align:start and text-align:end should obey the paragraph
+ direction or the direction property in a unicode-bidi:plaintext element.
+ The ...! paragraph, being neutral, is supposed to be displayed LTR (i.e. as ...!, not as !...)
+ despite both the paragraph before it and the paragraph after it being all-RTL, which makes the
+ element as a whole RTL.
+ </div>
+ <div id="test" class="test">
+ <script>
+ window.onload = function() {
+ var test = document.getElementById('test');
+ var textareas = test.getElementsByTagName('textarea');
+ for (var i = 0; i != textareas.length; i++) {
+ textareas[i].value = '\u05D0\n...!\n\u05D0';
+ }
+ }
+ </script>
+ <div dir="ltr">
+ <textarea rows="4" dir="auto">
+LTR text
+ </textarea>
+ </div>
+ <div dir="rtl">
+ <textarea rows="4" dir="auto">
+LTR text
+ </textarea>
+ </div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">
+ <textarea rows="4" dir="rtl">
+&#x05D0;
+!...
+&#x05D0;</textarea>
+ </div>
+ <div dir="rtl">
+ <textarea rows="4" dir="rtl">
+&#x05D0;
+!...
+&#x05D0;</textarea>
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-textarea-script-mixed-ref.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-textarea-script-mixed-ref.html
new file mode 100644
index 0000000000..a5a84480f6
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-textarea-script-mixed-ref.html
@@ -0,0 +1,64 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <link rel="author" title="Aharon Lanin" href="mailto:aharon@google.com" />
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com" />
+ <style>
+ body, textarea {
+ font-size:18px;
+ text-align:left;
+ }
+ textarea {
+ resize: none;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments {
+ display: none;
+ }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="test">
+ <div dir="ltr">
+ <textarea rows="5" dir="rtl">
+!123@
+!123@
+!123@
+!123@
+ </textarea>
+ </div>
+ <div dir="rtl">
+ <textarea rows="5" dir="ltr">
+@123!
+@123!
+@123!
+@123!
+ </textarea>
+ </div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">
+ <textarea rows="5" dir="rtl">
+!123@
+!123@
+!123@
+!123@
+ </textarea>
+ </div>
+ <div dir="rtl">
+ <textarea rows="5" dir="ltr">
+@123!
+@123!
+@123!
+@123!
+ </textarea>
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-textarea-script-mixed.html b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-textarea-script-mixed.html
new file mode 100644
index 0000000000..f0c6d4fe44
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/dir_auto-textarea-script-mixed.html
@@ -0,0 +1,100 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>HTML Test: textarea with dir=auto, script assigns to mixed L and R paragraphs</title>
+ <link rel="match" href="dir_auto-textarea-script-mixed-ref.html" />
+ <link rel="author" title="Aharon Lanin" href="mailto:aharon@google.com" />
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-dir-attribute" />
+ <link rel="help" href="http://dev.w3.org/csswg/css3-writing-modes/#unicode-bidi0" />
+ <meta name="assert" content="
+ When dir='auto', the direction is set according to the first strong character
+ of the text.
+ For textarea and pre elements, the heuristic is applied on a per-paragraph level." />
+ <style>
+ body, textarea {
+ font-size:18px;
+ text-align:left;
+ }
+ textarea {
+ resize: none;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments {
+ display: none;
+ }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="comments">
+ Key to entities used below:
+ &#x200E; - LRM, the invisible left-to-right mark (strongly LTR).
+ &#x200F; - RLM, the invisible right-to-left mark (strongly RTL).
+ This test makes sure that the direction is set correctly for a textarea whose value is set
+ dynamically by script.
+ We use text-align:left because neither the dir="auto" nor the unicode-bidi:plaintext
+ specification states whether text-align:start and text-align:end should obey the paragraph
+ direction or the direction property in a unicode-bidi:plaintext element.
+ </div>
+ <div id="test" class="test">
+ <script>
+ window.onload = function() {
+ var test = document.getElementById('test');
+ var textareas = test.getElementsByTagName('textarea');
+ for (var i = 0; i != textareas.length; i++) {
+ var input = textareas[i];
+ if (input.parentNode.dir == 'ltr') {
+ // Assign a value whose first strong is RTL.
+ input.value =
+ '!\u200F123\u200E@\n' +
+ '@\u200E123\u200F!\n' +
+ '!123\u200F\u200E@\n' +
+ '@123\u200E\u200F!\n';
+ } else {
+ // Assign a value whose first strong is LTR.
+ input.value =
+ '@\u200E123\u200F!\n' +
+ '!\u200F123\u200E@\n' +
+ '@123\u200E\u200F!\n' +
+ '!123\u200F\u200E@\n';
+ }
+ }
+ }
+ </script>
+ <div dir="ltr">
+ <textarea rows="5" dir="auto">
+&#x200E;
+ </textarea>
+ </div>
+ <div dir="rtl">
+ <textarea rows="5" dir="auto">
+&#x200F;
+ </textarea>
+ </div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">
+ <textarea rows="5" dir="rtl">
+!123@
+!123@
+!123@
+!123@
+ </textarea>
+ </div>
+ <div dir="rtl">
+ <textarea rows="5" dir="ltr">
+@123!
+@123!
+@123!
+@123!
+ </textarea>
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/document-dir.html b/testing/web-platform/tests/html/dom/elements/global-attributes/document-dir.html
new file mode 100644
index 0000000000..675b4bc9d9
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/document-dir.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<html dir="LTR">
+<title>document.dir</title>
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-document-dir">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#reflect">
+<link rel="author" title="Ms2ger" href="mailto:ms2ger@gmail.com">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<script>
+test(function() {
+ assert_equals(document.dir, "ltr");
+ assert_equals(document.documentElement.getAttribute("dir"), "LTR");
+}, "Markup attribute")
+test(function() {
+ document.dir = "x-garbage";
+ assert_equals(document.dir, "");
+ assert_equals(document.documentElement.getAttribute("dir"), "x-garbage");
+}, "Setting the idl attribute to a garbage value")
+test(function() {
+ document.dir = "";
+ assert_true(document.documentElement.hasAttribute("dir"), "Attribute should still be around");
+ assert_equals(document.dir, "");
+ assert_equals(document.documentElement.getAttribute("dir"), "");
+}, "Setting the idl attribute to the empty string")
+</script>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/id-attribute.html b/testing/web-platform/tests/html/dom/elements/global-attributes/id-attribute.html
new file mode 100644
index 0000000000..660a7274a3
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/id-attribute.html
@@ -0,0 +1,130 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+<title>The id attribute</title>
+<meta charset=utf8>
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#the-id-attribute">
+<style>
+
+#abcd {
+ position: absolute;
+ z-index: 1;
+}
+
+#ABCD {
+ position: absolute;
+ z-index: 2;
+}
+
+#a\ b {
+ position: absolute;
+ z-index: 3;
+}
+
+#xyz {
+ position: absolute;
+ z-index: 4;
+}
+
+#foobar {
+ position: absolute;
+ z-index: 5;
+}
+
+#åèiöú {
+ position: absolute;
+ z-index: 6;
+}
+
+</style>
+</head>
+<body>
+<h1>The id attribute</h1>
+<div id="log"></div>
+<i id="abcd"></i>
+<i id="ABCD"></i>
+<i id="a b"></i>
+<i id="åèiöú"></i>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+ // id is associated for purposes of getElementById
+ test(function() {
+ assert_equals(document.getElementById("abcd"), document.getElementsByTagName("i")[0]);
+ }, "User agents must associate the element with an id value for purposes of getElementById.");
+
+ test(function() {
+ assert_equals(document.getElementById("ABCD"), document.getElementsByTagName("i")[1]);
+ }, "Association is exact and therefore case-sensitive for getElementById.");
+
+ test(function() {
+ assert_equals(document.getElementById("a b"), document.getElementsByTagName("i")[2]);
+ }, "Spaces are allowed in an id and still make an association for getElementByID.");
+
+ test(function() {
+ assert_equals(document.getElementById("åèiöú"), document.getElementsByTagName("i")[3]);
+ }, "Non-ASCII is allowed in an id and still make an association for getElementById.");
+
+
+ // id is associated for purposes of CSS
+ test(function() {
+ assert_equals(document.defaultView.getComputedStyle(document.getElementById("abcd")).zIndex, "1");
+ }, "User agents must associate the element with an id value for purposes of CSS.");
+
+ test(function() {
+ assert_equals(document.defaultView.getComputedStyle(document.getElementById("ABCD")).zIndex, "2");
+ }, "Association for CSS is exact and therefore case-sensitive.");
+
+ test(function() {
+ assert_equals(document.defaultView.getComputedStyle(document.getElementById("a b")).zIndex, "3");
+ }, "Spaces are allowed in an id and still make an association.");
+
+ test(function() {
+ assert_equals(document.defaultView.getComputedStyle(document.getElementById("åèiöú")).zIndex, "6");
+ }, "Non-ASCII is allowed in an id and still make an association for CSS.");
+
+
+ // id IDL attribute reflects the content attribute
+ var firstSpan = document.getElementById("abcd");
+
+ test(function() {
+ assert_equals(firstSpan.id, "abcd");
+ }, "The id IDL attribute must reflect the id content attribute, for getting.");
+
+ test(function() {
+ firstSpan.id = "xyz";
+ assert_equals(firstSpan.getAttribute("id"), "xyz");
+ }, "The id IDL attribute must reflect the id content attribute, for setting via IDL attribute.");
+
+ test(function() {
+ assert_equals(document.getElementById("xyz"), firstSpan);
+ }, "After setting id via id attribute, getElementById find the element by the new id.");
+
+ test(function() {
+ assert_equals(document.getElementById("abcd"), null);
+ }, "After setting id via id attribute, getElementById doesn't find the element by the old id.");
+
+ test(function() {
+ assert_equals(document.defaultView.getComputedStyle(firstSpan).zIndex, "4");
+ }, "After setting id via id attribute, CSS association is via the new ID.");
+
+ test(function() {
+ firstSpan.setAttribute("id", "foobar");
+ assert_equals(firstSpan.id, "foobar");
+ }, "The id IDL attribute must reflect the id content attribute, for setting via setAttribute.");
+
+ test(function() {
+ assert_equals(document.getElementById("foobar"), firstSpan);
+ }, "After setting id via setAttribute attribute, getElementById find the element by the new id.");
+
+ test(function() {
+ assert_equals(document.getElementById("xyz"), null);
+ }, "After setting id via setAttribute attribute, getElementById doesn't find the element by the old id.");
+
+ test(function() {
+ assert_equals(document.defaultView.getComputedStyle(firstSpan).zIndex, "5");
+ }, "After setting id via setAttribute attribute, CSS association is via the new ID.");
+
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/id-name-specialcase.html b/testing/web-platform/tests/html/dom/elements/global-attributes/id-name-specialcase.html
new file mode 100644
index 0000000000..77e4100b70
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/id-name-specialcase.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<title>HTML5: test id with none pure alpha characters </title>
+<link rel="author" title="justin.shen" href=mailto:cosmichut@msn.com">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<div style="display:none">
+ <input id="123" value="123"></input>
+ <input id="1test" value="1test"></input>
+ <input id="_test" value="_test"></input>
+ <input id="." value="."></input>
+ <input id="中国" value="china"></input>
+</div>
+<script>
+test(function() {
+ assert_equals(document.getElementById("123").value, "123");
+}, "id with digits only");
+test(function() {
+ assert_equals(document.getElementById("1test").value, "1test");
+},"id start with digits");
+test(function() {
+ assert_equals(document.getElementById("_test").value, "_test");
+},"id start with underscore");
+test(function() {
+ assert_equals(document.getElementById(".").value, ".");
+},"id with punctuation only");
+test(function() {
+ assert_equals(document.getElementById("中国").value, "china");
+},"id with chinese character");
+</script>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/id-name.html b/testing/web-platform/tests/html/dom/elements/global-attributes/id-name.html
new file mode 100644
index 0000000000..7fdac993b2
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/id-name.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<title>id and name attributes and getElementById</title>
+<link rel="author" title="Ms2ger" href="mailto:ms2ger@gmail.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#the-id-attribute">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<div id="test">
+<div name="abcd"></div>
+<p name="abcd" id="abcd"></p>
+</div>
+<script>
+test(function() {
+ assert_equals(document.getElementById("abcd").nodeName, "P");
+ assert_equals(document.getElementById("abcd").localName, "p");
+});
+</script>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/lang-attribute-shadow.window.js b/testing/web-platform/tests/html/dom/elements/global-attributes/lang-attribute-shadow.window.js
new file mode 100644
index 0000000000..2a59a56c05
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/lang-attribute-shadow.window.js
@@ -0,0 +1,81 @@
+const TESTS = [
+ {
+ title: "lang only on slot",
+ light_tree: `
+ <div id="host" data-expected="en-US"><span data-expected="en-US"></span></div>
+ `,
+ shadow_tree: `
+ <slot lang="en-AU" data-expected="en-AU"></slot>
+ `,
+ },
+ {
+ title: "lang only on host",
+ light_tree: `
+ <div id="host" lang="en-AU" data-expected="en-AU"><span data-expected="en-AU"></span></div>
+ `,
+ shadow_tree: `
+ <slot data-expected="en-AU"></slot>
+ `,
+ },
+ {
+ title: "lang on host and slot",
+ light_tree: `
+ <div id="host" lang="en-AU" data-expected="en-AU"><span data-expected="en-AU"></span></div>
+ `,
+ shadow_tree: `
+ <slot lang="en-GB" data-expected="en-GB"></slot>
+ `,
+ },
+ {
+ title: "lang on host and slotted element",
+ light_tree: `
+ <div id="host" lang="en-AU" data-expected="en-AU"><span lang="en-GB" data-expected="en-GB"></span></div>
+ `,
+ shadow_tree: `
+ <slot data-expected="en-AU"></slot>
+ `,
+ },
+ {
+ title: "lang on host and slot and slotted element",
+ light_tree: `
+ <div id="host" lang="en-AU" data-expected="en-AU"><span lang="en-GB" data-expected="en-GB"></span></div>
+ `,
+ shadow_tree: `
+ <slot lang="en-NZ" data-expected="en-NZ"></slot>
+ `,
+ },
+ {
+ title: "lang on slot inherits from parent",
+ light_tree: `
+ <div id="host" lang="en-GB" data-expected="en-GB"><span lang="en-US" data-expected="en-US"></span></div>
+ `,
+ shadow_tree: `
+ <div lang="en-CA" data-expected="en-CA">
+ <slot data-expected="en-CA"></slot>
+ </div>
+ `,
+ },
+];
+
+const container = document.createElement("div");
+document.body.append(container);
+container.lang = "en-US";
+
+for (const obj of TESTS) {
+ test(() => {
+ container.innerHTML = obj.light_tree;
+ let shadow = container.querySelector("#host").attachShadow({mode: "open"});
+ shadow.innerHTML = obj.shadow_tree;
+ for (const element of Array.from(container.querySelectorAll("[data-expected]")).concat(Array.from(shadow.querySelectorAll("[data-expected]")))) {
+ const expected = element.getAttribute("data-expected");
+ assert_true(element.matches(`:lang(${expected})`), `element matches expected language ${expected}`);
+ for (const other_lang of ["en-US", "en-AU", "en-GB", "en-NZ", "en-CA"]) {
+ if (expected != other_lang) {
+ assert_false(element.matches(`:lang(${other_lang})`), `element does not match language ${other_lang}`);
+ }
+ }
+ }
+ }, obj.title);
+}
+
+container.remove();
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/lang-attribute.window.js b/testing/web-platform/tests/html/dom/elements/global-attributes/lang-attribute.window.js
new file mode 100644
index 0000000000..de0c03e6f8
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/lang-attribute.window.js
@@ -0,0 +1,16 @@
+test(() => {
+ const container = document.createElement("div");
+ document.body.append(container);
+ container.setAttribute("lang", "en-CA");
+
+ const child = document.createElementNS("div", "test");
+ container.append(child);
+ child.setAttribute("lang", "en-NZ");
+
+ assert_true(container.matches(":lang(en-CA)"), "container matches en-CA");
+ assert_true(child.matches(":lang(en-CA)"), "child matches en-CA");
+ assert_false(container.matches(":lang(en-NZ)"), "container does not match en-NZ");
+ assert_false(child.matches(":lang(en-NZ)"), "child does not match en-NZ");
+
+ container.remove();
+}, "unnamespaced lang attribute only works on elements in the HTML namespace");
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/lang-xmllang-01-ref.html b/testing/web-platform/tests/html/dom/elements/global-attributes/lang-xmllang-01-ref.html
new file mode 100644
index 0000000000..eacf73da16
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/lang-xmllang-01-ref.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<title>Languages</title>
+<link rel="author" title="Ms2ger" href="mailto:ms2ger@gmail.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#the-lang-and-xml:lang-attributes">
+<link rel="help" href="http://www.w3.org/TR/CSS2/selector.html#lang">
+<meta name="flags" content="css21">
+<style>
+#test > * { background: limegreen; }
+</style>
+<body>
+<p>All lines below should have a green background.</p>
+<div id="test">
+<div><p>{}{lang}{en}</p></div>
+<div><p>{}{xml:lang}{en}</p></div>
+<div><div><p>Parent: {}{lang}{en}</p></div></div>
+<div><div><p>Parent: {}{xml:lang}{en}</p></div></div>
+<div><p>{xml}{lang}{en}</p></div>
+<div><p>{xml}{lang}{en} - {lang}{de}</p></div>
+<div><p>{xml}{lang}{de} - {lang}{en}</p></div>
+</div>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/lang-xmllang-01.html b/testing/web-platform/tests/html/dom/elements/global-attributes/lang-xmllang-01.html
new file mode 100644
index 0000000000..04d8b74e2d
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/lang-xmllang-01.html
@@ -0,0 +1,58 @@
+<!DOCTYPE html>
+<title>Languages</title>
+<link rel="match" href="lang-xmllang-01-ref.html">
+<link rel="author" title="Ms2ger" href="mailto:ms2ger@gmail.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#the-lang-and-xml:lang-attributes">
+<link rel="help" href="http://www.w3.org/TR/CSS2/selector.html#lang">
+<meta name="flags" content="css21">
+<style>
+#test #a :lang(en) { background: limegreen; }
+#test #b :lang(nl) { background: limegreen; }
+#test #c :lang(en) { background: limegreen; }
+#test #d :lang(nl) { background: limegreen; }
+#test #e :lang(en) { background: limegreen; }
+#test #f :lang(en) { background: limegreen; }
+#test #g :lang(de) { background: limegreen; }
+</style>
+<body>
+<p>All lines below should have a green background.</p>
+<div id="test" lang="nl">
+<div id="a"><p lang="en">{}{lang}{en}</p></div>
+<div id="b"><p xml:lang="en">{}{xml:lang}{en}</p></div>
+<div id="c"><div lang="en"><p>Parent: {}{lang}{en}</p></div></div>
+<div id="d"><div xml:lang="en"><p>Parent: {}{xml:lang}{en}</p></div></div>
+</div>
+<script>
+try {
+ var XML = "http://www.w3.org/XML/1998/namespace";
+ var container = document.getElementById("test");
+
+ var div = document.createElement("div");
+ div.id = "e";
+ var testNode = document.createElement("p");
+ testNode.appendChild(document.createTextNode("{xml}{lang}{en}"));
+ testNode.setAttributeNS(XML, "xml:lang", "en");
+ div.appendChild(testNode);
+ container.appendChild(div);
+
+ div = document.createElement("div");
+ div.id = "f";
+ testNode = document.createElement("p");
+ testNode.appendChild(document.createTextNode("{xml}{lang}{en} - {lang}{de}"));
+ testNode.setAttributeNS(XML, "xml:lang", "en");
+ testNode.setAttributeNS(null, "lang", "de");
+ div.appendChild(testNode);
+ container.appendChild(div);
+
+ div = document.createElement("div");
+ div.id = "g";
+ testNode = document.createElement("p");
+ testNode.appendChild(document.createTextNode("{xml}{lang}{de} - {lang}{en}"));
+ testNode.setAttributeNS(XML, "xml:lang", "de");
+ testNode.setAttributeNS(null, "lang", "en");
+ container.appendChild(testNode);
+ div.appendChild(testNode);
+ container.appendChild(div);
+} catch (e) {
+}
+</script>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/lang-xyzzy-ref.html b/testing/web-platform/tests/html/dom/elements/global-attributes/lang-xyzzy-ref.html
new file mode 100644
index 0000000000..b2037182b9
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/lang-xyzzy-ref.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<title>Invalid languages</title>
+<link rel="author" title="Ms2ger" href="mailto:ms2ger@gmail.com">
+<meta name="flags" content="css21">
+<style>#testp { color: green; }</style>
+<body>
+<div id="test">
+<p id="testp" lang="xyzzy">ABC</p>
+</div>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/lang-xyzzy.html b/testing/web-platform/tests/html/dom/elements/global-attributes/lang-xyzzy.html
new file mode 100644
index 0000000000..b950e1fac9
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/lang-xyzzy.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<title>Invalid languages</title>
+<link rel="match" href="lang-xyzzy-ref.html">
+<link rel="author" title="Ms2ger" href="mailto:ms2ger@gmail.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#the-lang-and-xml:lang-attributes">
+<link rel="help" href="http://www.w3.org/TR/CSS2/selector.html#lang">
+<meta name="flags" content="css21">
+<style>:lang(xyzzy) { color: green; }</style>
+<body>
+<div id="test">
+<p id="testp" lang="xyzzy">ABC</p>
+</div>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/mapped-attribute-adopt-001.html b/testing/web-platform/tests/html/dom/elements/global-attributes/mapped-attribute-adopt-001.html
new file mode 100644
index 0000000000..66ff3d64f1
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/mapped-attribute-adopt-001.html
@@ -0,0 +1,23 @@
+<!doctype html>
+<title>Adoption doesn't mess with mapped attributes</title>
+<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
+<link rel="author" title="Mozilla" href="https://mozilla.org">
+<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1636516">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div hidden="unlikely">Should be hidden</div>
+<script>
+test(function() {
+ var tmpl = document.createElement("template");
+ var fragment = tmpl.content;
+ var newEl = document.createElement("div");
+ newEl.setAttribute("hidden", "unlikely");
+ fragment.append(newEl);
+ document.adoptNode(newEl);
+ assert_equals(
+ getComputedStyle(document.querySelector("div")).display,
+ "none",
+ "hidden attribute should have an effect"
+ );
+}, "Adoption of an unrelated node shouldn't prevent mapped attributes from applying");
+</script>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/style-01-ref.html b/testing/web-platform/tests/html/dom/elements/global-attributes/style-01-ref.html
new file mode 100644
index 0000000000..be8175e61d
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/style-01-ref.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<title>The style attribute</title>
+<link rel="author" title="Ms2ger" href="mailto:ms2ger@gmail.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#the-style-attribute">
+<link rel="help" href="http://www.w3.org/TR/css-style-attr/#syntax">
+<link rel="help" href="http://www.w3.org/TR/CSS21/cascade.html#cascading-order">
+<link rel="help" href="http://www.w3.org/TR/CSS21/cascade.html#specificity">
+<style>
+#test p { background: limegreen; }
+</style>
+<div id="test">
+<p>This line should have a green background.
+<p>This line should have a green background.
+<p>This line should have a green background.
+<p>This line should have a green background.
+<p>This line should have a green background.
+<p>This line should have a green background.
+<p>This line should have a green background.
+<p>This line should have a green background.
+<p>This line should have a green background.
+<p>This line should have a green background.
+<p>This line should have a green background.
+<p>This line should have a green background.
+</div>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/style-01.html b/testing/web-platform/tests/html/dom/elements/global-attributes/style-01.html
new file mode 100644
index 0000000000..c0e0995806
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/style-01.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<title>The style attribute</title>
+<link rel="match" href="style-01-ref.html">
+<link rel="author" title="Ms2ger" href="mailto:ms2ger@gmail.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#the-style-attribute">
+<link rel="help" href="http://www.w3.org/TR/css-style-attr/#syntax">
+<link rel="help" href="http://www.w3.org/TR/CSS21/cascade.html#cascading-order">
+<link rel="help" href="http://www.w3.org/TR/CSS21/cascade.html#specificity">
+<style>
+#idsel { background: red; }
+#idsel2 { background: limegreen !important; }
+</style>
+<div id="test">
+<p style="background:limegreen">This line should have a green background.
+<p style="/**/background:limegreen">This line should have a green background.
+<p style="background/**/:limegreen">This line should have a green background.
+<p style="background:/**/limegreen">This line should have a green background.
+<p style="background:limegreen/**/">This line should have a green background.
+<p id="idsel1" style="background:limegreen">This line should have a green background.
+<p id="idsel2" style="background:red">This line should have a green background.
+<p style="background:limegreen; background:r/**/ed">This line should have a green background.
+<p style="background:limegreen;}">This line should have a green background.
+<p style="};background:limegreen">This line should have a green background.
+<p style="background:red;};background:limegreen">This line should have a green background.
+<p style="background:limegreen;{background:red}">This line should have a green background.
+</div>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/the-anchor-attribute-001.tentative.html b/testing/web-platform/tests/html/dom/elements/global-attributes/the-anchor-attribute-001.tentative.html
new file mode 100644
index 0000000000..c9faa6908a
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/the-anchor-attribute-001.tentative.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<link rel="help" href="https://github.com/whatwg/html/pull/9144">
+<link rel="author" href="mailto:xiaochengh@chromium.org">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<style>
+body {
+ margin: 0;
+}
+#anchor {
+ width: 100px;
+ height: 100px;
+ margin-left: 50px;
+ margin-top: 50px;
+ background: orange;
+}
+#target {
+ position: absolute;
+ left: anchor(right);
+ top: anchor(top);
+ width: 100px;
+ height: 100px;
+ background: lime;
+}
+</style>
+<div id="anchor"></div>
+<div id="target" anchor="anchor"></div>
+
+<script>
+test(() => {
+ assert_equals(target.offsetLeft, 150);
+ assert_equals(target.offsetTop, 50);
+}, 'The anchor attribute should position the target element next to its implicit anchor');
+
+test(() => {
+ assert_equals(target.anchorElement, anchor);
+}, 'The element.anchorElement IDL should reflect the element pointed to by the anchor attribute');
+</script>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/the-anchor-attribute-002.tentative.html b/testing/web-platform/tests/html/dom/elements/global-attributes/the-anchor-attribute-002.tentative.html
new file mode 100644
index 0000000000..a1a237a2ee
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/the-anchor-attribute-002.tentative.html
@@ -0,0 +1,50 @@
+<!DOCTYPE html>
+<link rel="help" href="https://github.com/whatwg/html/pull/9144">
+<link rel="author" href="mailto:xiaochengh@chromium.org">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<style>
+body {
+ margin: 0;
+}
+.anchor {
+ width: 100px;
+ height: 100px;
+ margin-left: 50px;
+ margin-top: 50px;
+ background: orange;
+}
+.target {
+ position: absolute;
+ left: anchor(right, 123px);
+ top: anchor(top, 456px);
+ width: 100px;
+ height: 100px;
+ background: lime;
+}
+</style>
+<div class="anchor" id="anchor1"></div>
+<div class="anchor" id="anchor2"></div>
+<div class="target" id="target1" anchor="anchor1"></div>
+<div class="target" id="target2" anchor="anchor1"></div>
+
+<script>
+test(() => {
+ document.body.offsetLeft; // Force layout
+ target1.setAttribute('anchor', 'anchor2');
+ assert_equals(target1.offsetLeft, 150);
+ assert_equals(target1.offsetTop, 200);
+
+ target1.setAttribute('anchor', 'anchor1');
+ assert_equals(target1.offsetLeft, 150);
+ assert_equals(target1.offsetTop, 50);
+}, 'Layout should be updated when anchor attribute changes to another element');
+
+test(() => {
+ document.body.offsetLeft; // Force layout
+ target2.setAttribute('anchor', 'nonexist-anchor');
+ assert_equals(target2.offsetLeft, 123);
+ assert_equals(target2.offsetTop, 456);
+}, 'Layout should be updated when anchor attribute changes to a non-existent element');
+</script>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/the-anchor-attribute-003-crash.tentative.html b/testing/web-platform/tests/html/dom/elements/global-attributes/the-anchor-attribute-003-crash.tentative.html
new file mode 100644
index 0000000000..207275d9db
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/the-anchor-attribute-003-crash.tentative.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<title>Tests that using the `anchor` attribute with inline containing block does not crash</title>
+<link rel="help" href="https://github.com/whatwg/html/pull/9144">
+<link rel="help" href="https://crbug.com/1486148">
+<link rel="author" href="mailto:xiaochengh@chromium.org">
+
+<style>
+.target {
+ position: absolute;
+ top: anchor(top);
+ left: anchor(right);
+}
+</style>
+
+<div id="anchor">foo</div>
+
+<span style="position: relative">
+ <div anchor="anchor2" class="target">bar</div>
+</span>
+
+<span style="position: sticky">
+ <div anchor="anchor2" class="target">bar</div>
+</span>
+
+<span style="backdrop-filter: blur(1px)">
+ <div anchor="anchor2" class="target">bar</div>
+</span>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/the-anchor-attribute-003.tentative.html b/testing/web-platform/tests/html/dom/elements/global-attributes/the-anchor-attribute-003.tentative.html
new file mode 100644
index 0000000000..ec2d8d5ead
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/the-anchor-attribute-003.tentative.html
@@ -0,0 +1,71 @@
+<!DOCTYPE html>
+<title>Tests that ::before, ::after and ::backdrop pseudo elements use originating element's implicit anchor</title>
+<link rel="help" href="https://github.com/whatwg/html/pull/9144">
+<link rel="help" href="https://drafts.csswg.org/css-anchor-position-1/#implicit">
+<link rel="author" href="mailto:xiaochengh@chromium.org">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<style>
+body {
+ margin: 0;
+}
+#anchor {
+ width: 100px;
+ height: 100px;
+ margin-left: 150px;
+ margin-top: 50px;
+ background: orange;
+}
+#target::before, #target::after {
+ position: absolute;
+ width: 100px;
+ height: 100px;
+ background: lime;
+}
+#target::before{
+ content: '';
+ right: anchor(left);
+ top: anchor(top);
+}
+#target::after{
+ content: '';
+ left: anchor(right);
+ top: anchor(top);
+}
+
+dialog::backdrop {
+ top: calc(anchor(top) - 10px);
+ right: calc(anchor(right) - 10px);
+ bottom: calc(anchor(bottom) - 10px);
+ left: calc(anchor(left) - 10px);
+ background: lime;
+}
+
+</style>
+<div id="anchor"></div>
+<div id="target" anchor="anchor"></div>
+<dialog id="dialog" anchor="anchor"></div>
+
+<script>
+test(() => {
+ let style = getComputedStyle(target, '::before');
+ assert_equals(style.left, '50px');
+ assert_equals(style.top, '50px');
+}, "::before uses originating element's implicit anchor");
+
+test(() => {
+ let style = getComputedStyle(target, '::after');
+ assert_equals(style.left, '250px');
+ assert_equals(style.top, '50px');
+}, "::after uses originating element's implicit anchor");
+
+test(() => {
+ dialog.showModal();
+ let style = getComputedStyle(dialog, '::backdrop');
+ assert_equals(style.left, '140px');
+ assert_equals(style.top, '40px');
+ assert_equals(style.width, '120px');
+ assert_equals(style.height, '120px');
+}, "::backdrop uses originating element's implicit anchor");
+</script>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/the-lang-attribute-001.html b/testing/web-platform/tests/html/dom/elements/global-attributes/the-lang-attribute-001.html
new file mode 100644
index 0000000000..c2966f3620
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/the-lang-attribute-001.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<html lang="ko" >
+<head>
+<meta charset="utf-8"/>
+<title>lang attribute in html tag</title>
+<link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'>
+<link rel='help' href='https://html.spec.whatwg.org/multipage/#the-lang-and-xml:lang-attributes'>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<meta name='flags' content='dom'>
+<style type='text/css'>
+ #colonlangcontroltest { color: red; font-weight: bold; width: 400px; }
+ #colonlangcontroltest:lang(xx) { display:none; }
+.test div { width: 50px; }
+#box:lang(ko) { width: 100px; }
+</style>
+</head>
+<body>
+
+
+
+<div class="test"><div id="box">&#xA0;</div></div>
+<p lang='xx' id='colonlangcontroltest'>This test failed because it relies on :lang for results, but :lang is not supported by this browser.</p>
+
+
+<!--Notes:
+
+This test uses :lang to detect whether the language has been set. If :lang is not supported, a message will appear and the test will fail.
+
+-->
+<script>
+test(function() {
+assert_equals(document.getElementById('colonlangcontroltest').offsetWidth, 0)
+assert_equals(document.getElementById('box').offsetWidth, 100);
+}, "The browser will recognize a language declared in a lang attribute on the html tag.");
+</script>
+
+<div id='log'></div>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/the-lang-attribute-002.html b/testing/web-platform/tests/html/dom/elements/global-attributes/the-lang-attribute-002.html
new file mode 100644
index 0000000000..205bc35f2d
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/the-lang-attribute-002.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<html xml:lang="ko" >
+<head>
+<meta charset="utf-8"/>
+<title>xml:lang attribute in html tag</title>
+<link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'>
+<link rel='help' href='https://html.spec.whatwg.org/multipage/#the-lang-and-xml:lang-attributes'>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<meta name='flags' content='dom'>
+<style type='text/css'>
+ #colonlangcontroltest { color: red; font-weight: bold; width: 400px; }
+ #colonlangcontroltest:lang(xx) { display:none; }
+.test div { width: 50px; }
+#box:lang(ko) { width: 100px; }
+</style>
+</head>
+<body>
+
+
+
+<div class="test"><div id="box">&#xA0;</div></div>
+<p lang='xx' id='colonlangcontroltest'>This test failed because it relies on :lang for results, but :lang is not supported by this browser.</p>
+
+
+<!--Notes:
+
+This test uses :lang to detect whether the language has been set. If :lang is not supported, a message will appear and the test will fail.
+
+-->
+<script>
+test(function() {
+assert_equals(document.getElementById('colonlangcontroltest').offsetWidth, 0)
+assert_equals(document.getElementById('box').offsetWidth, 50);
+}, "The browser will NOT recognize a language declared in an xml:lang attribute on the html tag.");
+</script>
+
+<div id='log'></div>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/the-lang-attribute-003.html b/testing/web-platform/tests/html/dom/elements/global-attributes/the-lang-attribute-003.html
new file mode 100644
index 0000000000..717aa12e68
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/the-lang-attribute-003.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<html >
+<head>
+<meta charset="utf-8"/>
+<title>HTTP header</title>
+<link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'>
+<link rel='help' href='https://html.spec.whatwg.org/multipage/#the-lang-and-xml:lang-attributes'>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<meta name='flags' content='http dom'>
+<style type='text/css'>
+ #colonlangcontroltest { color: red; font-weight: bold; width: 400px; }
+ #colonlangcontroltest:lang(xx) { display:none; }
+.test div { width: 50px; }
+#box:lang(ko) { width: 100px; }
+</style>
+</head>
+<body>
+
+
+
+<div class="test"><div id="box">&#xA0;</div></div>
+<p lang='xx' id='colonlangcontroltest'>This test failed because it relies on :lang for results, but :lang is not supported by this browser.</p>
+
+
+<!--Notes:
+
+This test uses :lang to detect whether the language has been set. If :lang is not supported, a message will appear and the test will fail.
+
+-->
+<script>
+test(function() {
+assert_equals(document.getElementById('colonlangcontroltest').offsetWidth, 0)
+assert_equals(document.getElementById('box').offsetWidth, 100);
+}, "The browser will recognize a language declared in the HTTP header, when there is no internal language declaration.");
+</script>
+
+<div id='log'></div>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/the-lang-attribute-003.html.headers b/testing/web-platform/tests/html/dom/elements/global-attributes/the-lang-attribute-003.html.headers
new file mode 100644
index 0000000000..0c47ecd4fa
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/the-lang-attribute-003.html.headers
@@ -0,0 +1 @@
+Content-Language: ko
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/the-lang-attribute-004.html b/testing/web-platform/tests/html/dom/elements/global-attributes/the-lang-attribute-004.html
new file mode 100644
index 0000000000..ff36f75add
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/the-lang-attribute-004.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<html >
+<head>
+<meta charset="utf-8"/>
+ <meta http-equiv="Content-Language" content="ko" >
+<title>pragma-set default</title>
+<link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'>
+<link rel='help' href='https://html.spec.whatwg.org/multipage/#the-lang-and-xml:lang-attributes'>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<meta name='flags' content='dom'>
+<style type='text/css'>
+ #colonlangcontroltest { color: red; font-weight: bold; width: 400px; }
+ #colonlangcontroltest:lang(xx) { display:none; }
+.test div { width: 50px; }
+#box:lang(ko) { width: 100px; }
+</style>
+</head>
+<body>
+
+
+
+<div class="test"><div id="box">&#xA0;</div></div>
+<p lang='xx' id='colonlangcontroltest'>This test failed because it relies on :lang for results, but :lang is not supported by this browser.</p>
+
+
+<!--Notes:
+
+This test uses :lang to detect whether the language has been set. If :lang is not supported, a message will appear and the test will fail.
+
+-->
+<script>
+test(function() {
+assert_equals(document.getElementById('colonlangcontroltest').offsetWidth, 0)
+assert_equals(document.getElementById('box').offsetWidth, 100);
+}, "The browser will recognize a language declared in a meta element in the head using http-equiv='Content-Language' content='..' (with a single language tag value), when there is no other language declaration inside the document.");
+</script>
+
+<div id='log'></div>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/the-lang-attribute-005.html b/testing/web-platform/tests/html/dom/elements/global-attributes/the-lang-attribute-005.html
new file mode 100644
index 0000000000..63fb8e3bbb
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/the-lang-attribute-005.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<html lang="ko" >
+<head>
+<meta charset="utf-8"/>
+<title>HTTP header and html lang</title>
+<link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'>
+<link rel='help' href='https://html.spec.whatwg.org/multipage/#the-lang-and-xml:lang-attributes'>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<meta name='flags' content='http dom'>
+<style type='text/css'>
+ #colonlangcontroltest { color: red; font-weight: bold; width: 400px; }
+ #colonlangcontroltest:lang(xx) { display:none; }
+.test div { width: 50px; }
+#box:lang(ko) { width: 100px; }
+</style>
+</head>
+<body>
+
+
+
+<div class="test"><div id="box">&#xA0;</div></div>
+<p lang='xx' id='colonlangcontroltest'>This test failed because it relies on :lang for results, but :lang is not supported by this browser.</p>
+
+
+<!--Notes:
+
+This test uses :lang to detect whether the language has been set. If :lang is not supported, a message will appear and the test will fail.
+
+-->
+<script>
+test(function() {
+assert_equals(document.getElementById('colonlangcontroltest').offsetWidth, 0)
+assert_equals(document.getElementById('box').offsetWidth, 100);
+}, "If there is a conflict between the language declarations in the HTTP header and the html element using lang, the browser will recognize the language declared in the html element.");
+</script>
+
+<div id='log'></div>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/the-lang-attribute-005.html.headers b/testing/web-platform/tests/html/dom/elements/global-attributes/the-lang-attribute-005.html.headers
new file mode 100644
index 0000000000..1b971b697a
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/the-lang-attribute-005.html.headers
@@ -0,0 +1 @@
+Content-Language: zh
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/the-lang-attribute-006.html b/testing/web-platform/tests/html/dom/elements/global-attributes/the-lang-attribute-006.html
new file mode 100644
index 0000000000..ede4912025
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/the-lang-attribute-006.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<html >
+<head>
+<meta charset="utf-8"/>
+ <meta http-equiv="Content-Language" content="ko" >
+<title>HTTP header and meta element</title>
+<link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'>
+<link rel='help' href='https://html.spec.whatwg.org/multipage/#the-lang-and-xml:lang-attributes'>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<meta name='flags' content='http dom'>
+<style type='text/css'>
+ #colonlangcontroltest { color: red; font-weight: bold; width: 400px; }
+ #colonlangcontroltest:lang(xx) { display:none; }
+.test div { width: 50px; }
+#box:lang(ko) { width: 100px; }
+</style>
+</head>
+<body>
+
+
+
+<div class="test"><div id="box">&#xA0;</div></div>
+<p lang='xx' id='colonlangcontroltest'>This test failed because it relies on :lang for results, but :lang is not supported by this browser.</p>
+
+
+<!--Notes:
+
+This test uses :lang to detect whether the language has been set. If :lang is not supported, a message will appear and the test will fail.
+
+-->
+<script>
+test(function() {
+assert_equals(document.getElementById('colonlangcontroltest').offsetWidth, 0)
+assert_equals(document.getElementById('box').offsetWidth, 100);
+}, "If there is a conflict between the language declarations in the HTTP header and the Content-Language meta element, the UA will recognize the language declared in the meta element.");
+</script>
+
+<div id='log'></div>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/the-lang-attribute-006.html.headers b/testing/web-platform/tests/html/dom/elements/global-attributes/the-lang-attribute-006.html.headers
new file mode 100644
index 0000000000..1b971b697a
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/the-lang-attribute-006.html.headers
@@ -0,0 +1 @@
+Content-Language: zh
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/the-lang-attribute-007.html b/testing/web-platform/tests/html/dom/elements/global-attributes/the-lang-attribute-007.html
new file mode 100644
index 0000000000..8fafef036f
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/the-lang-attribute-007.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<html lang="ko" >
+<head>
+<meta charset="utf-8"/>
+ <meta http-equiv="Content-Language" content="zh" >
+<title>html lang and meta elements</title>
+<link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'>
+<link rel='help' href='https://html.spec.whatwg.org/multipage/#the-lang-and-xml:lang-attributes'>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<meta name='flags' content='dom'>
+<style type='text/css'>
+ #colonlangcontroltest { color: red; font-weight: bold; width: 400px; }
+ #colonlangcontroltest:lang(xx) { display:none; }
+.test div { width: 50px; }
+#box:lang(ko) { width: 100px; }
+</style>
+</head>
+<body>
+
+
+
+<div class="test"><div id="box">&#xA0;</div></div>
+<p lang='xx' id='colonlangcontroltest'>This test failed because it relies on :lang for results, but :lang is not supported by this browser.</p>
+
+
+<!--Notes:
+
+This test uses :lang to detect whether the language has been set. If :lang is not supported, a message will appear and the test will fail.
+
+-->
+<script>
+test(function() {
+assert_equals(document.getElementById('colonlangcontroltest').offsetWidth, 0)
+assert_equals(document.getElementById('box').offsetWidth, 100);
+}, "If there is a conflict between the language declared using lang in the html element and that in the meta element, the UA will recognize the language declared in the html element.");
+</script>
+
+<div id='log'></div>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/the-lang-attribute-008.html b/testing/web-platform/tests/html/dom/elements/global-attributes/the-lang-attribute-008.html
new file mode 100644
index 0000000000..3be54154c1
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/the-lang-attribute-008.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<html >
+<head>
+<meta charset="utf-8"/>
+<title>lang="..." vs lang=""</title>
+<link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'>
+<link rel='help' href='https://html.spec.whatwg.org/multipage/#the-lang-and-xml:lang-attributes'>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<meta name='flags' content='dom'>
+<style type='text/css'>
+ #colonlangcontroltest { color: red; font-weight: bold; width: 400px; }
+ #colonlangcontroltest:lang(xx) { display:none; }
+.test div { width: 50px; }
+#box:lang(ko) { width: 100px; }
+</style>
+</head>
+<body>
+
+
+
+<div class="test" lang="ko"><div id="box" lang="">&#xA0;</div></div>
+<p lang='xx' id='colonlangcontroltest'>This test failed because it relies on :lang for results, but :lang is not supported by this browser.</p>
+
+
+<!--Notes:
+
+This test uses :lang to detect whether the language has been set. If :lang is not supported, a message will appear and the test will fail.
+
+-->
+<script>
+test(function() {
+assert_equals(document.getElementById('colonlangcontroltest').offsetWidth, 0)
+assert_equals(document.getElementById('box').offsetWidth, 50);
+}, "If an element contains a lang attribute with an empty value, the value of a lang attribute higher up the document tree will no longer be applied to the content of that element.");
+</script>
+
+<div id='log'></div>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/the-lang-attribute-009.html b/testing/web-platform/tests/html/dom/elements/global-attributes/the-lang-attribute-009.html
new file mode 100644
index 0000000000..3a927028ef
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/the-lang-attribute-009.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<html lang="" >
+<head>
+<meta charset="utf-8"/>
+<title>lang="" vs HTTP</title>
+<link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'>
+<link rel='help' href='https://html.spec.whatwg.org/multipage/#the-lang-and-xml:lang-attributes'>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<meta name='flags' content='http dom'>
+<style type='text/css'>
+ #colonlangcontroltest { color: red; font-weight: bold; width: 400px; }
+ #colonlangcontroltest:lang(xx) { display:none; }
+.test div { width: 50px; }
+#box:lang(ko) { width: 100px; }
+</style>
+</head>
+<body>
+
+
+
+<div class="test"><div id="box">&#xA0;</div></div>
+<p lang='xx' id='colonlangcontroltest'>This test failed because it relies on :lang for results, but :lang is not supported by this browser.</p>
+
+
+<!--Notes:
+
+This test uses :lang to detect whether the language has been set. If :lang is not supported, a message will appear and the test will fail.
+
+-->
+<script>
+test(function() {
+assert_equals(document.getElementById('colonlangcontroltest').offsetWidth, 0)
+assert_equals(document.getElementById('box').offsetWidth, 50);
+}, "If the HTTP header contains a language declaration but the html element uses an empty lang value, the UA will not recognize the language declared in the HTTP header.");
+</script>
+
+<div id='log'></div>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/the-lang-attribute-009.html.headers b/testing/web-platform/tests/html/dom/elements/global-attributes/the-lang-attribute-009.html.headers
new file mode 100644
index 0000000000..0c47ecd4fa
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/the-lang-attribute-009.html.headers
@@ -0,0 +1 @@
+Content-Language: ko
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/the-lang-attribute-010.html b/testing/web-platform/tests/html/dom/elements/global-attributes/the-lang-attribute-010.html
new file mode 100644
index 0000000000..2c21737471
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/the-lang-attribute-010.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<html lang="" >
+<head>
+<meta charset="utf-8"/>
+ <meta http-equiv="Content-Language" content="ko" >
+<title>lang="" vs meta Content-Language</title>
+<link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'>
+<link rel='help' href='https://html.spec.whatwg.org/multipage/#the-lang-and-xml:lang-attributes'>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<meta name='flags' content='dom'>
+<style type='text/css'>
+ #colonlangcontroltest { color: red; font-weight: bold; width: 400px; }
+ #colonlangcontroltest:lang(xx) { display:none; }
+.test div { width: 50px; }
+#box:lang(ko) { width: 100px; }
+</style>
+</head>
+<body>
+
+
+
+<div class="test"><div id="box">&#xA0;</div></div>
+<p lang='xx' id='colonlangcontroltest'>This test failed because it relies on :lang for results, but :lang is not supported by this browser.</p>
+
+
+<!--Notes:
+
+This test uses :lang to detect whether the language has been set. If :lang is not supported, a message will appear and the test will fail.
+
+-->
+<script>
+test(function() {
+assert_equals(document.getElementById('colonlangcontroltest').offsetWidth, 0)
+assert_equals(document.getElementById('box').offsetWidth, 50);
+}, "If the meta Content-Language element contains a language declaration but the html element uses an empty lang value, the UA will not recognize the language declared in the meta Content-Language element.");
+</script>
+
+<div id='log'></div>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/the-lang-attribute-011.html.headers b/testing/web-platform/tests/html/dom/elements/global-attributes/the-lang-attribute-011.html.headers
new file mode 100644
index 0000000000..827b4348f4
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/the-lang-attribute-011.html.headers
@@ -0,0 +1 @@
+Content-Language: ko,zh,ja
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/the-translate-attribute-007.html b/testing/web-platform/tests/html/dom/elements/global-attributes/the-translate-attribute-007.html
new file mode 100644
index 0000000000..abce2858a2
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/the-translate-attribute-007.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<html lang="en" >
+<head>
+<meta charset="utf-8"/>
+<title>no translate attribute</title>
+<link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'>
+<link rel='help' href='https://html.spec.whatwg.org/multipage/#the-translate-attribute'>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<style type='text/css'>
+</style>
+</head>
+<body>
+
+
+
+<div class="test"><div id="box">&nbsp;</div></div>
+
+
+<script>
+test(function() {
+assert_true(document.getElementById('box').translate);
+}, "In the default case, ie. with no translate attribute in the page, javascript will detect the translation mode of text as translate-enabled.");
+</script>
+
+<div id='log'></div>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/the-translate-attribute-008.html b/testing/web-platform/tests/html/dom/elements/global-attributes/the-translate-attribute-008.html
new file mode 100644
index 0000000000..70486fe59b
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/the-translate-attribute-008.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<html lang="en" >
+<head>
+<meta charset="utf-8"/>
+<title>translate=yes</title>
+<link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'>
+<link rel='help' href='https://html.spec.whatwg.org/multipage/#the-translate-attribute'>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<style type='text/css'>
+</style>
+</head>
+<body>
+
+
+
+<div class="test"><div id="box" translate="yes">&nbsp;</div></div>
+
+
+<script>
+test(function() {
+assert_true(document.getElementById('box').translate);
+}, "If the translate attribute is set to yes, javascript will detect the translation mode of text as translate-enabled.");
+</script>
+
+<div id='log'></div>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/the-translate-attribute-009.html b/testing/web-platform/tests/html/dom/elements/global-attributes/the-translate-attribute-009.html
new file mode 100644
index 0000000000..1ab49b0307
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/the-translate-attribute-009.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<html lang="en" >
+<head>
+<meta charset="utf-8"/>
+<title>translate=no</title>
+<link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'>
+<link rel='help' href='https://html.spec.whatwg.org/multipage/#the-translate-attribute'>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<style type='text/css'>
+</style>
+</head>
+<body>
+
+
+
+<div class="test"><div id="box" translate="no">&nbsp;</div></div>
+
+
+<script>
+test(function() {
+assert_false(document.getElementById('box').translate);
+}, "If the translate attribute is set to no, javascript will detect the translation mode of text as no-translate.");
+</script>
+
+<div id='log'></div>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/the-translate-attribute-010.html b/testing/web-platform/tests/html/dom/elements/global-attributes/the-translate-attribute-010.html
new file mode 100644
index 0000000000..c45965e004
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/the-translate-attribute-010.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<html lang="en" >
+<head>
+<meta charset="utf-8"/>
+<title>translate inherits no</title>
+<link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'>
+<link rel='help' href='https://html.spec.whatwg.org/multipage/#the-translate-attribute'>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<style type='text/css'>
+</style>
+</head>
+<body>
+
+
+
+<div class="test"><div id="box" translate="no">&nbsp; <span id="spantest">&nbsp;</span></div></div>
+
+
+<script>
+test(function() {
+assert_false(document.getElementById('spantest').translate);
+}, "If the translate attribute is set to no, javascript will detect the translation mode of elements inside that element with no translate flag as no-translate.");
+</script>
+
+<div id='log'></div>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/the-translate-attribute-011.html b/testing/web-platform/tests/html/dom/elements/global-attributes/the-translate-attribute-011.html
new file mode 100644
index 0000000000..101f70e2e7
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/the-translate-attribute-011.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<html lang="en" >
+<head>
+<meta charset="utf-8"/>
+<title>translate=yes inside translate=no</title>
+<link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'>
+<link rel='help' href='https://html.spec.whatwg.org/multipage/#the-translate-attribute'>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<style type='text/css'>
+</style>
+</head>
+<body>
+
+
+
+<div class="test"><div id="box" translate="no">&nbsp; <span id="spantest" translate="yes">&nbsp;</span></div></div>
+
+
+<script>
+test(function() {
+assert_true(document.getElementById('spantest').translate);
+}, "If the translate attribute is set to yes on an element inside an element with the translate attribute set to no, javascript will detect the translation mode of text in the inner element as translate-enabled.");
+</script>
+
+<div id='log'></div>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/the-translate-attribute-012.html b/testing/web-platform/tests/html/dom/elements/global-attributes/the-translate-attribute-012.html
new file mode 100644
index 0000000000..1d81cfd8b1
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/the-translate-attribute-012.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<html lang="en" >
+<head>
+<meta charset="utf-8"/>
+<title>translate=""</title>
+<link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'>
+<link rel='help' href='https://html.spec.whatwg.org/multipage/#the-translate-attribute'>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<style type='text/css'>
+</style>
+</head>
+<body>
+
+
+
+<div class="test"><div id="box" translate="">&nbsp;</div></div>
+
+
+<script>
+test(function() {
+assert_true(document.getElementById('box').translate);
+}, "If the translate attribute is set to a null string, javascript will detect the translation mode of text as translate-enabled.");
+</script>
+
+<div id='log'></div>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/title-manual.html b/testing/web-platform/tests/html/dom/elements/global-attributes/title-manual.html
new file mode 100644
index 0000000000..d781172bba
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/title-manual.html
@@ -0,0 +1,8 @@
+<!DOCTYPE html>
+<title>The title attribute</title>
+<style>
+div > * { display: inline }
+link::before { content: "link" }
+</style>
+<p>Hover each word below. The tooltip for each of them should be "PASS".</p>
+<div title=PASS>div <link> <style>style</style> <dfn>dfn</dfn> <abbr>abbr</abbr> <menuitem>menuitem</menuitem></div>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/translate-enumerated-ascii-case-insensitive.html b/testing/web-platform/tests/html/dom/elements/global-attributes/translate-enumerated-ascii-case-insensitive.html
new file mode 100644
index 0000000000..dedf559b98
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/translate-enumerated-ascii-case-insensitive.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<link rel="help" href="https://html.spec.whatwg.org/#attr-translate">
+<link rel="help" href="https://html.spec.whatwg.org/#enumerated-attribute">
+<meta name="assert" content="@translate values are ASCII case-insensitive">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<!--
+ We wrap the <span> elements under test with <div> elements so the invalid
+ value default (inherit) can be distinguished from true through the IDL
+ attribute. The inherit state would otherwise yield true because inheritance
+ would go all the way to :root, whose translation mode is translate-enabled
+ because it’s also in the inherit state.
+-->
+<div translate="no"><span translate="yes"></span></div>
+<div translate="no"><span translate="YeS"></span></div>
+<div translate="no"><span translate="yeſ"></span></div>
+<script>
+const span = document.querySelectorAll("span");
+
+test(() => {
+ assert_equals(span[0].translate, true, "lowercase valid");
+ assert_equals(span[1].translate, true, "mixed case valid");
+ assert_equals(span[2].translate, false, "non-ASCII invalid");
+}, "keyword yes");
+</script>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/translate-inherit-no-parent-element.html b/testing/web-platform/tests/html/dom/elements/global-attributes/translate-inherit-no-parent-element.html
new file mode 100644
index 0000000000..370225c7f7
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/translate-inherit-no-parent-element.html
@@ -0,0 +1,33 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>The translate attribute inherit state when there's no parent element</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+test(() => {
+ const div = document.createElement("div");
+ assert_true(div.translate);
+}, 'No parent node');
+
+test(() => {
+ const div = document.createElement("div");
+ const frag = document.createDocumentFragment();
+ frag.append(div);
+ assert_true(div.translate);
+}, 'DocumentFragment parent node');
+
+for (const translateValue of ['yes', 'no']) {
+ test(() => {
+ const div = document.createElement("div");
+ const myElement = document.createElement("my-element");
+ myElement.setAttribute('translate', translateValue);
+ myElement.attachShadow({mode: 'open'});
+ myElement.shadowRoot.append(div);
+ assert_true(div.translate);
+ }, `ShadowRoot parent node whose shadow host has translate=${translateValue}`);
+}
+
+test(() => {
+ assert_true(document.documentElement.translate);
+}, 'Document parent node');
+</script>
diff --git a/testing/web-platform/tests/html/dom/elements/global-attributes/translate-non-html-translation-mode.html b/testing/web-platform/tests/html/dom/elements/global-attributes/translate-non-html-translation-mode.html
new file mode 100644
index 0000000000..3bd7f6ace9
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/global-attributes/translate-non-html-translation-mode.html
@@ -0,0 +1,46 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Non-HTML elements have a translation mode</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+ test(() => {
+ const svgContainer = document.createElement("svg");
+ const foreignObject = document.createElement("foreignObject");
+ svgContainer.appendChild(foreignObject);
+ const div = document.createElement("div");
+ foreignObject.appendChild(div);
+
+ assert_true(div.translate);
+ }, 'Non-HTML elements default to translate-enabled');
+
+ test(() => {
+ const outerDiv = document.createElement("div");
+ outerDiv.translate = true;
+ assert_true(outerDiv.translate);
+
+ const svgContainer = document.createElement("svg");
+ outerDiv.appendChild(svgContainer);
+ const foreignObject = document.createElement("foreignObject");
+ svgContainer.appendChild(foreignObject);
+ const div = document.createElement("div");
+ foreignObject.appendChild(div);
+
+ assert_true(div.translate);
+ }, "Non-HTML elements inherit their parent's translation-enabled state");
+
+ test(() => {
+ const outerDiv = document.createElement("div");
+ outerDiv.translate = false;
+ assert_false(outerDiv.translate);
+
+ const svgContainer = document.createElement("svg");
+ outerDiv.appendChild(svgContainer);
+ const foreignObject = document.createElement("foreignObject");
+ svgContainer.appendChild(foreignObject);
+ const div = document.createElement("div");
+ foreignObject.appendChild(div);
+
+ assert_false(div.translate);
+ }, "Non-HTML elements inherit their parent's no-translation state");
+</script>
diff --git a/testing/web-platform/tests/html/dom/elements/images/bypass-cache-revalidation.html b/testing/web-platform/tests/html/dom/elements/images/bypass-cache-revalidation.html
new file mode 100644
index 0000000000..38cdd876da
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/images/bypass-cache-revalidation.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<title>Cached images can bypass revalidation</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/utils.js"></script>
+<div id="imageDiv1"></div>
+<div id="imageDiv2"></div>
+<canvas id="canvas"></canvas>
+<script>
+
+function getImagePixel(image)
+{
+ canvas.getContext("2d").drawImage(image, 0, 0, 10, 10);
+ return canvas.getContext("2d").getImageData(0, 0, 1, 1).data;
+}
+
+let resolve;
+promise_test(async (t) => {
+ const url = "image.py?id=" + token();
+
+ let promise = new Promise(r => resolve = r);
+ imageDiv1.innerHTML = `<img src="${url}" onload="resolve()"></img>`;
+ await promise;
+
+ const url2 = "image.py?id=" + token();
+ promise = new Promise(r => resolve = r);
+ imageDiv1.innerHTML = `<img src="${url2}" onload="resolve()"></img>`;
+ await promise;
+
+ promise = new Promise(r => resolve = r);
+ imageDiv2.innerHTML = `<img id="image2" src="${url}" onload="resolve()"></img>`;
+ await promise;
+
+ assert_array_equals(getImagePixel(image2), [0, 255, 0, 255]);
+}, "Images can bypass no-cache");
+</script>
+
diff --git a/testing/web-platform/tests/html/dom/elements/images/image.py b/testing/web-platform/tests/html/dom/elements/images/image.py
new file mode 100644
index 0000000000..b8bb34e618
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/images/image.py
@@ -0,0 +1,28 @@
+import os.path
+
+from wptserve.utils import isomorphic_decode
+
+def main(request, response):
+
+ key = request.GET[b'id']
+ alreadyServedRequest = False
+ try:
+ alreadyServedRequest = request.server.stash.take(key)
+ except (KeyError, ValueError) as e:
+ pass
+
+ if alreadyServedRequest:
+ body = open(os.path.join(os.path.dirname(isomorphic_decode(__file__)), u"../../../../images/red.png"), u"rb").read()
+ else:
+ request.server.stash.put(key, True);
+ body = open(os.path.join(os.path.dirname(isomorphic_decode(__file__)), u"../../../../images/green.png"), u"rb").read()
+ pass
+
+ response.writer.write_status(200)
+ response.writer.write_header(b"etag", b"abcdef")
+ response.writer.write_header(b"content-length", len(body))
+ response.writer.write_header(b"content-type", b"image/png")
+ response.writer.write_header(b"cache-control", b"public, max-age=31536000, no-cache")
+ response.writer.end_headers()
+
+ response.writer.write(body)
diff --git a/testing/web-platform/tests/html/dom/elements/name-content-attribute-and-property.html b/testing/web-platform/tests/html/dom/elements/name-content-attribute-and-property.html
new file mode 100644
index 0000000000..082ed281fe
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/name-content-attribute-and-property.html
@@ -0,0 +1,57 @@
+<!DOCTYPE html>
+<title>Only certain HTML elements reflect the name content attribute as a property</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/resources/common.js"></script>
+<div id="log"></div>
+<script>
+ function doesReflect(tagName) {
+ var element = document.createElement(tagName);
+ element.setAttribute("name", "foo");
+ assert_equals(element.getAttribute("name"), "foo", "setAttribute should change content attribute");
+ element.name = "bar";
+ assert_equals(element.getAttribute("name"), "bar", "assignment to .name should change content attribute");
+ }
+
+ function doesNotReflect(tagName) {
+ var element = document.createElement(tagName);
+ element.setAttribute("name", "foo");
+ assert_equals(element.getAttribute("name"), "foo", "setAttribute should change content attribute");
+ element.name = "bar";
+ assert_equals(element.getAttribute("name"), "foo", "assignment to .name should not change content attribute");
+ }
+
+ var reflectingTagNames = [
+ "a", "button", "embed", "fieldset", "form", "frame",
+ "iframe", "img", "input", "map", "meta", "object", "output",
+ "param", "select", "slot", "textarea",
+ ];
+
+ // Optionally add "details" to reflectingTagNames since Chromium is
+ // prototyping the proposal at
+ // https://open-ui.org/components/accordion.explainer that adds this
+ // reflection to "details" as well.
+ // TODO(https://crbug.com/1444057): This runtime check should eventually be
+ // removed, and depending on the outcome of the proposal details should
+ // possibly be added to reflectingTagNames unconditionally.
+ if ("name" in HTMLDetailsElement.prototype) {
+ reflectingTagNames.push("details");
+ }
+
+ const old_and_new_elements = [...HTML5_ELEMENTS, ...HTML5_DEPRECATED_ELEMENTS];
+
+ const nonReflectingTagNames = old_and_new_elements.filter(x => !reflectingTagNames.includes(x));
+
+ reflectingTagNames.forEach(function(tagName) {
+ test(function() {
+ doesReflect(tagName)
+ }, tagName + " element's name property reflects its content attribute");
+ });
+
+ nonReflectingTagNames.forEach(function(tagName) {
+ test(function() {
+ doesNotReflect(tagName)
+ }, tagName + " element's name property does not reflect its content attribute");
+ });
+</script>
+
diff --git a/testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-001a.html b/testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-001a.html
new file mode 100644
index 0000000000..16a308a2f7
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-001a.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="utf-8">
+<title>The dir attribute: isolated from following number, opposite direction</title>
+<link rel="author" title="Richard Ishida" href='mailto:ishida@w3.org'>
+<link rel="help" href='http://www.w3.org/TR/html5/dom.html#requirements-relating-to-the-bidirectional-algorithm'>
+<link rel="match" href='reference/dir-isolation-001-ref.html'>
+<meta name="assert" content='Element content with a dir attribute is treated as a neutral character and directionally isolated from a following number.'>
+<style type="text/css">
+.test, .ref { font-size: 150%; border: 1px solid orange; margin: 10px; margin-right: 200px; padding: 5px; clear: both; }
+input { margin: 5px; }
+</style>
+</head>
+<body>
+<p class="instructions" dir="ltr">Test passes if the two boxes are identical.</p>
+<!--Notes:
+Key to entities used below:
+&#x5d0; ... &#x5d5; - The first six Hebrew letters (strongly RTL).
+&#x202d; - The LRO (left-to-right-override) formatting character.
+&#x202c; - The PDF (pop directional formatting) formatting character; closes LRO.
+The punctuation is moved around in the source to make it easier to do visual comparisons when the test is run.
+-->
+<div class="test">
+<div dir="ltr"><span dir="rtl">&#x5d0;</span> 3</div>
+<div dir="ltr"><span dir="rtl">a</span> 3</div>
+<div dir="rtl"><span dir="ltr">&#x5d0;</span> 3</div>
+<div dir="rtl"><span dir="ltr">a</span> 3</div>
+</div>
+<div class="ref">
+<div dir="ltr">&#x202d;&#x5d0; 3&#x202c;</div>
+<div dir="ltr">&#x202d;a 3&#x202c;</div>
+<div dir="rtl">&#x202d;3 &#x5d0;&#x202c;</div>
+<div dir="rtl">&#x202d;3 a&#x202c;</div>
+</div>
+</body></html> \ No newline at end of file
diff --git a/testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-001b.html b/testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-001b.html
new file mode 100644
index 0000000000..197f49aa24
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-001b.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="utf-8">
+<title>The dir attribute: isolated from following number, auto</title>
+<link rel="author" title="Richard Ishida" href='mailto:ishida@w3.org'>
+<link rel="help" href='http://www.w3.org/TR/html5/dom.html#requirements-relating-to-the-bidirectional-algorithm'>
+<link rel="match" href='reference/dir-isolation-001-ref.html'>
+<meta name="assert" content='Element content with a dir attribute is treated as a neutral character and directionally isolated from a following number.'>
+<style type="text/css">
+.test, .ref { font-size: 150%; border: 1px solid orange; margin: 10px; margin-right: 200px; padding: 5px; clear: both; }
+input { margin: 5px; }
+</style>
+</head>
+<body>
+<p class="instructions" dir="ltr">Test passes if the two boxes are identical.</p>
+<!--Notes:
+Key to entities used below:
+&#x5d0; ... &#x5d5; - The first six Hebrew letters (strongly RTL).
+&#x202d; - The LRO (left-to-right-override) formatting character.
+&#x202c; - The PDF (pop directional formatting) formatting character; closes LRO.
+The punctuation is moved around in the source to make it easier to do visual comparisons when the test is run.
+-->
+<div class="test">
+<div dir="ltr"><span dir="auto">&#x5d0;</span> 3</div>
+<div dir="ltr"><span dir="auto">a</span> 3</div>
+<div dir="rtl"><span dir="auto">&#x5d0;</span> 3</div>
+<div dir="rtl"><span dir="auto">a</span> 3</div>
+</div>
+<div class="ref">
+<div dir="ltr">&#x202d;&#x5d0; 3&#x202c;</div>
+<div dir="ltr">&#x202d;a 3&#x202c;</div>
+<div dir="rtl">&#x202d;3 &#x5d0;&#x202c;</div>
+<div dir="rtl">&#x202d;3 a&#x202c;</div>
+</div>
+</body></html> \ No newline at end of file
diff --git a/testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-001c.html b/testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-001c.html
new file mode 100644
index 0000000000..95ec6c739d
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-001c.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="utf-8">
+<title>The dir attribute: isolated from following number, same direction</title>
+<link rel="author" title="Richard Ishida" href='mailto:ishida@w3.org'>
+<link rel="help" href='http://www.w3.org/TR/html5/dom.html#requirements-relating-to-the-bidirectional-algorithm'>
+<link rel="match" href='reference/dir-isolation-001-ref.html'>
+<meta name="assert" content='Element content with a dir attribute is treated as a neutral character and directionally isolated from a following number.'>
+<style type="text/css">
+.test, .ref { font-size: 150%; border: 1px solid orange; margin: 10px; margin-right: 200px; padding: 5px; clear: both; }
+input { margin: 5px; }
+</style>
+</head>
+<body>
+<p class="instructions" dir="ltr">Test passes if the two boxes are identical.</p>
+<!--Notes:
+Key to entities used below:
+&#x5d0; ... &#x5d5; - The first six Hebrew letters (strongly RTL).
+&#x202d; - The LRO (left-to-right-override) formatting character.
+&#x202c; - The PDF (pop directional formatting) formatting character; closes LRO.
+The punctuation is moved around in the source to make it easier to do visual comparisons when the test is run.
+-->
+<div class="test">
+<div dir="ltr"><span dir="ltr">&#x5d0;</span> 3</div>
+<div dir="ltr"><span dir="ltr">a</span> 3</div>
+<div dir="rtl"><span dir="rtl">&#x5d0;</span> 3</div>
+<div dir="rtl"><span dir="rtl">a</span> 3</div>
+</div>
+<div class="ref">
+<div dir="ltr">&#x202d;&#x5d0; 3&#x202c;</div>
+<div dir="ltr">&#x202d;a 3&#x202c;</div>
+<div dir="rtl">&#x202d;3 &#x5d0;&#x202c;</div>
+<div dir="rtl">&#x202d;3 a&#x202c;</div>
+</div>
+</body></html> \ No newline at end of file
diff --git a/testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-002a.html b/testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-002a.html
new file mode 100644
index 0000000000..7b7029a269
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-002a.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="utf-8">
+<title>The dir attribute: isolated from following number with intervening neutrals, opposite direction</title>
+<link rel="author" title='Richard Ishida' href='mailto:ishida@w3.org'>
+<link rel="help" href='http://www.w3.org/TR/html5/dom.html#requirements-relating-to-the-bidirectional-algorithm'>
+<link rel='match' href='reference/dir-isolation-002a-ref.html'>
+<meta name='assert' content='Element content with a dir attribute is treated as a neutral character and directionally isolated from a following number.'>
+<style type="text/css">
+.test, .ref { font-size: 150%; border: 1px solid orange; margin: 10px; margin-right: 200px; padding: 5px; clear: both; }
+input { margin: 5px; }
+</style>
+</head>
+<body>
+<p class="instructions" dir="ltr">Test passes if the two boxes are identical.</p>
+<!--Notes:
+Key to entities used below:
+&#x5d0; ... &#x5d5; - The first six Hebrew letters (strongly RTL).
+&#x202d; - The LRO (left-to-right-override) formatting character.
+&#x202c; - The PDF (pop directional formatting) formatting character; closes LRO.
+The punctuation is moved around in the source to make it easier to do visual comparisons when the test is run.
+-->
+<div class="test">
+<div dir="ltr"><span dir="rtl">> &#x5d0; ></span> > 3 ></div>
+<div dir="ltr"><span dir="rtl">> a ></span> > 3 ></div>
+<div dir="rtl"><span dir="ltr">> &#x5d0; ></span> > 3 ></div>
+<div dir="rtl"><span dir="ltr">> a ></span> > 3 ></div>
+</div>
+<div class="ref">
+<div dir="ltr">&#x202d;&lt; &#x5d0; &lt; &gt; 3 &gt;&#x202c;</div>
+<div dir="ltr">&#x202d;&lt; a &lt; &gt; 3 &gt;&#x202c;</div>
+<div dir="rtl">&#x202d;&lt; 3 &lt; &gt; &#x5d0; &gt;&#x202c;</div>
+<div dir="rtl">&#x202d;&lt; 3 &lt; &gt; a &gt;&#x202c;</div>
+</div>
+</body></html> \ No newline at end of file
diff --git a/testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-002b.html b/testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-002b.html
new file mode 100644
index 0000000000..d448de5080
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-002b.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="utf-8">
+<title>The dir attribute: isolated from following number with intervening neutrals, auto</title>
+<link rel="author" title='Richard Ishida' href='mailto:ishida@w3.org'>
+<link rel="help" href='http://www.w3.org/TR/html5/dom.html#requirements-relating-to-the-bidirectional-algorithm'>
+<link rel='match' href='reference/dir-isolation-002b-ref.html'>
+<meta name='assert' content='Element content with a dir attribute is treated as a neutral character and directionally isolated from a following number.'>
+<style type="text/css">
+.test, .ref { font-size: 150%; border: 1px solid orange; margin: 10px; margin-right: 200px; padding: 5px; clear: both; }
+input { margin: 5px; }
+</style>
+</head>
+<body>
+<p class="instructions" dir="ltr">Test passes if the two boxes are identical.</p>
+<!--Notes:
+Key to entities used below:
+&#x5d0; ... &#x5d5; - The first six Hebrew letters (strongly RTL).
+&#x202d; - The LRO (left-to-right-override) formatting character.
+&#x202c; - The PDF (pop directional formatting) formatting character; closes LRO.
+The punctuation is moved around in the source to make it easier to do visual comparisons when the test is run.
+-->
+<div class="test">
+<div dir="ltr"><span dir="auto">> &#x5d0; ></span> > 3 ></div>
+<div dir="ltr"><span dir="auto">> a ></span> > 3 ></div>
+<div dir="rtl"><span dir="auto">> &#x5d0; ></span> > 3 ></div>
+<div dir="rtl"><span dir="auto">> a ></span> > 3 ></div>
+</div>
+<div class="ref">
+<div dir="ltr">&#x202d;&lt; &#x5d0; &lt; &gt; 3 &gt;&#x202c;</div>
+<div dir="ltr">&#x202d;&gt; a &gt; &gt; 3 &gt;&#x202c;</div>
+<div dir="rtl">&#x202d;&lt; 3 &lt; &lt; &#x5d0; &lt;&#x202c;</div>
+<div dir="rtl">&#x202d;&lt; 3 &lt; &gt; a &gt;&#x202c;</div>
+</div>
+</body></html> \ No newline at end of file
diff --git a/testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-002c.html b/testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-002c.html
new file mode 100644
index 0000000000..e88fb1c845
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-002c.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="utf-8">
+<title>The dir attribute: isolated from following number with intervening neutrals, same direction</title>
+<link rel="author" title='Richard Ishida' href='mailto:ishida@w3.org'>
+<link rel="help" href='http://www.w3.org/TR/html5/dom.html#requirements-relating-to-the-bidirectional-algorithm'>
+<link rel='match' href='reference/dir-isolation-002c-ref.html'>
+<meta name='assert' content='Element content with a dir attribute is treated as a neutral character and directionally isolated from a following number.'>
+<style type="text/css">
+.test, .ref { font-size: 150%; border: 1px solid orange; margin: 10px; margin-right: 200px; padding: 5px; clear: both; }
+input { margin: 5px; }
+</style>
+</head>
+<body>
+<p class="instructions" dir="ltr">Test passes if the two boxes are identical.</p>
+<!--Notes:
+Key to entities used below:
+&#x5d0; ... &#x5d5; - The first six Hebrew letters (strongly RTL).
+&#x202d; - The LRO (left-to-right-override) formatting character.
+&#x202c; - The PDF (pop directional formatting) formatting character; closes LRO.
+The punctuation is moved around in the source to make it easier to do visual comparisons when the test is run.
+-->
+<div class="test">
+<div dir="ltr"><span dir="ltr">&gt; &#x5d0; &gt;</span> &gt; 3 &gt;</div>
+<div dir="ltr"><span dir="ltr">&gt; a &gt;</span> &gt; 3 &gt;</div>
+<div dir="rtl"><span dir="rtl">&gt; &#x5d0; &gt;</span> &gt; 3 &gt;</div>
+<div dir="rtl"><span dir="rtl">&gt; a &gt;</span> &gt; 3 &gt;</div>
+</div>
+<div class="ref">
+<div dir="ltr">&#x202d;&gt; &#x5d0; &gt; &gt; 3 &gt;&#x202c;</div>
+<div dir="ltr">&#x202d;&gt; a &gt; &gt; 3 &gt;&#x202c;</div>
+<div dir="rtl">&#x202d;&lt; 3 &lt; &lt; &#x5d0; &lt;&#x202c;</div>
+<div dir="rtl">&#x202d;&lt; 3 &lt; &lt; a &lt;&#x202c;</div>
+</div>
+</body></html> \ No newline at end of file
diff --git a/testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-003a.html b/testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-003a.html
new file mode 100644
index 0000000000..9cf65c8184
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-003a.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="utf-8">
+<title>The dir attribute: isolated from immediately following number, opposite direction</title>
+<link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'>
+<link rel="help" href='http://www.w3.org/TR/html5/dom.html#requirements-relating-to-the-bidirectional-algorithm'>
+<link rel='match' href='reference/dir-isolation-003-ref.html'>
+<meta name='assert' content='Element content with a dir attribute is treated as a neutral character and is directionally isolated from a following number, even with no intervening white space.'>
+<style type="text/css">
+.test, .ref { font-size: 150%; border: 1px solid orange; margin: 10px; margin-right: 200px; padding: 5px; clear: both; }
+input { margin: 5px; }
+</style>
+</head>
+<body>
+<p class="instructions" dir="ltr">Test passes if the two boxes are identical.</p>
+<!--Notes:
+Key to entities used below:
+&#x5d0; ... &#x5d5; - The first six Hebrew letters (strongly RTL).
+&#x202d; - The LRO (left-to-right-override) formatting character.
+&#x202c; - The PDF (pop directional formatting) formatting character; closes LRO.
+The punctuation is moved around in the source to make it easier to do visual comparisons when the test is run.
+-->
+<div class="test">
+<div dir="ltr"><span dir="rtl">&#x5d0;</span>3</div>
+<div dir="ltr"><span dir="rtl">a</span>3</div>
+<div dir="rtl"><span dir="ltr">&#x5d0;</span>3</div>
+<div dir="rtl"><span dir="ltr">a</span>3</div>
+</div>
+<div class="ref">
+<div dir="ltr">&#x202d;&#x5d0;3&#x202c;</div>
+<div dir="ltr">&#x202d;a3&#x202c;</div>
+<div dir="rtl">&#x202d;3&#x5d0;&#x202c;</div>
+<div dir="rtl">&#x202d;3a&#x202c;</div>
+</div>
+</body></html> \ No newline at end of file
diff --git a/testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-003b.html b/testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-003b.html
new file mode 100644
index 0000000000..2c6b553089
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-003b.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="utf-8">
+<title>The dir attribute: isolated from immediately following number, auto</title>
+<link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'>
+<link rel="help" href='http://www.w3.org/TR/html5/dom.html#requirements-relating-to-the-bidirectional-algorithm'>
+<link rel='match' href='reference/dir-isolation-003-ref.html'>
+<meta name='assert' content='Element content with a dir attribute is treated as a neutral character and is directionally isolated from a following number, even with no intervening white space.'>
+<style type="text/css">
+.test, .ref { font-size: 150%; border: 1px solid orange; margin: 10px; margin-right: 200px; padding: 5px; clear: both; }
+input { margin: 5px; }
+</style>
+</head>
+<body>
+<p class="instructions" dir="ltr">Test passes if the two boxes are identical.</p>
+<!--Notes:
+Key to entities used below:
+&#x5d0; ... &#x5d5; - The first six Hebrew letters (strongly RTL).
+&#x202d; - The LRO (left-to-right-override) formatting character.
+&#x202c; - The PDF (pop directional formatting) formatting character; closes LRO.
+The punctuation is moved around in the source to make it easier to do visual comparisons when the test is run.
+-->
+<div class="test">
+<div dir="ltr"><span dir="auto">&#x5d0;</span>3</div>
+<div dir="ltr"><span dir="auto">a</span>3</div>
+<div dir="rtl"><span dir="auto">&#x5d0;</span>3</div>
+<div dir="rtl"><span dir="auto">a</span>3</div>
+</div>
+<div class="ref">
+<div dir="ltr">&#x202d;&#x5d0;3&#x202c;</div>
+<div dir="ltr">&#x202d;a3&#x202c;</div>
+<div dir="rtl">&#x202d;3&#x5d0;&#x202c;</div>
+<div dir="rtl">&#x202d;3a&#x202c;</div>
+</div>
+</body></html> \ No newline at end of file
diff --git a/testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-003c.html b/testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-003c.html
new file mode 100644
index 0000000000..ac8735122b
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-003c.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="utf-8">
+<title>The dir attribute: isolated from immediately following number, same direction</title>
+<link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'>
+<link rel="help" href='http://www.w3.org/TR/html5/dom.html#requirements-relating-to-the-bidirectional-algorithm'>
+<link rel='match' href='reference/dir-isolation-003-ref.html'>
+<meta name='assert' content='Element content with a dir attribute is treated as a neutral character and is directionally isolated from a following number, even with no intervening white space.'>
+<style type="text/css">
+.test, .ref { font-size: 150%; border: 1px solid orange; margin: 10px; margin-right: 200px; padding: 5px; clear: both; }
+input { margin: 5px; }
+</style>
+</head>
+<body>
+<p class="instructions" dir="ltr">Test passes if the two boxes are identical.</p>
+<!--Notes:
+Key to entities used below:
+&#x5d0; ... &#x5d5; - The first six Hebrew letters (strongly RTL).
+&#x202d; - The LRO (left-to-right-override) formatting character.
+&#x202c; - The PDF (pop directional formatting) formatting character; closes LRO.
+The punctuation is moved around in the source to make it easier to do visual comparisons when the test is run.
+-->
+<div class="test">
+<div dir="ltr"><span dir="ltr">&#x5d0;</span>3</div>
+<div dir="ltr"><span dir="ltr">a</span>3</div>
+<div dir="rtl"><span dir="rtl">&#x5d0;</span>3</div>
+<div dir="rtl"><span dir="rtl">a</span>3</div>
+</div>
+<div class="ref">
+<div dir="ltr">&#x202d;&#x5d0;3&#x202c;</div>
+<div dir="ltr">&#x202d;a3&#x202c;</div>
+<div dir="rtl">&#x202d;3&#x5d0;&#x202c;</div>
+<div dir="rtl">&#x202d;3a&#x202c;</div>
+</div>
+</body></html> \ No newline at end of file
diff --git a/testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-004a.html b/testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-004a.html
new file mode 100644
index 0000000000..27a674ccdc
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-004a.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="utf-8">
+<title>The dir attribute: numbers isolated from preceding text, opposite direction</title>
+<link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'>
+<link rel="help" href='http://www.w3.org/TR/html5/dom.html#requirements-relating-to-the-bidirectional-algorithm'>
+<link rel='match' href='reference/dir-isolation-004-ref.html'>
+<meta name='assert' content='Numeric element content with a dir attribute is treated as a neutral character and directionally isolated from preceding text.'>
+<style type="text/css">
+.test, .ref { font-size: 150%; border: 1px solid orange; margin: 10px; margin-right: 200px; padding: 5px; clear: both; }
+input { margin: 5px; }
+</style>
+</head>
+<body>
+<p class="instructions" dir="ltr">Test passes if the two boxes are identical.</p>
+<!--Notes:
+Key to entities used below:
+&#x5d0; ... &#x5d5; - The first six Hebrew letters (strongly RTL).
+&#x202d; - The LRO (left-to-right-override) formatting character.
+&#x202c; - The PDF (pop directional formatting) formatting character; closes LRO.
+The punctuation is moved around in the source to make it easier to do visual comparisons when the test is run.
+-->
+<div class="test">
+<div dir="ltr">&#x5d0; <span dir="rtl">3</span></div>
+<div dir="ltr">a <span dir="rtl">3</span></div>
+<div dir="rtl">&#x5d0; <span dir="ltr">3</span></div>
+<div dir="rtl">a <span dir="ltr">3</span></div>
+</div>
+<div class="ref">
+<div dir="ltr">&#x202d;&#x5d0; 3&#x202c;</div>
+<div dir="ltr">&#x202d;a 3&#x202c;</div>
+<div dir="rtl">&#x202d;3 &#x5d0;&#x202c;</div>
+<div dir="rtl">&#x202d;3 a&#x202c;</div>
+</div>
+</body></html> \ No newline at end of file
diff --git a/testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-004b.html b/testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-004b.html
new file mode 100644
index 0000000000..6fe74393ae
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-004b.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="utf-8">
+<title>The dir attribute: numbers isolated from preceding text, auto</title>
+<link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'>
+<link rel="help" href='http://www.w3.org/TR/html5/dom.html#requirements-relating-to-the-bidirectional-algorithm'>
+<link rel='match' href='reference/dir-isolation-004-ref.html'>
+<meta name='assert' content='Numeric element content with a dir attribute is treated as a neutral character and directionally isolated from preceding text.'>
+<style type="text/css">
+.test, .ref { font-size: 150%; border: 1px solid orange; margin: 10px; margin-right: 200px; padding: 5px; clear: both; }
+input { margin: 5px; }
+</style>
+</head>
+<body>
+<p class="instructions" dir="ltr">Test passes if the two boxes are identical.</p>
+<!--Notes:
+Key to entities used below:
+&#x5d0; ... &#x5d5; - The first six Hebrew letters (strongly RTL).
+&#x202d; - The LRO (left-to-right-override) formatting character.
+&#x202c; - The PDF (pop directional formatting) formatting character; closes LRO.
+The punctuation is moved around in the source to make it easier to do visual comparisons when the test is run.
+-->
+<div class="test">
+<div dir="ltr">&#x5d0; <span dir="auto">3</span></div>
+<div dir="ltr">a <span dir="auto">3</span></div>
+<div dir="rtl">&#x5d0; <span dir="auto">3</span></div>
+<div dir="rtl">a <span dir="auto">3</span></div>
+</div>
+<div class="ref">
+<div dir="ltr">&#x202d;&#x5d0; 3&#x202c;</div>
+<div dir="ltr">&#x202d;a 3&#x202c;</div>
+<div dir="rtl">&#x202d;3 &#x5d0;&#x202c;</div>
+<div dir="rtl">&#x202d;3 a&#x202c;</div>
+</div>
+</body></html> \ No newline at end of file
diff --git a/testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-004c.html b/testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-004c.html
new file mode 100644
index 0000000000..43d994b2f0
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-004c.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="utf-8">
+<title>The dir attribute: numbers isolated from preceding text, same direction</title>
+<link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'>
+<link rel="help" href='http://www.w3.org/TR/html5/dom.html#requirements-relating-to-the-bidirectional-algorithm'>
+<link rel='match' href='reference/dir-isolation-004-ref.html'>
+<meta name='assert' content='Numeric element content with a dir attribute is treated as a neutral character and directionally isolated from preceding text.'>
+<style type="text/css">
+.test, .ref { font-size: 150%; border: 1px solid orange; margin: 10px; margin-right: 200px; padding: 5px; clear: both; }
+input { margin: 5px; }
+</style>
+</head>
+<body>
+<p class="instructions" dir="ltr">Test passes if the two boxes are identical.</p>
+<!--Notes:
+Key to entities used below:
+&#x5d0; ... &#x5d5; - The first six Hebrew letters (strongly RTL).
+&#x202d; - The LRO (left-to-right-override) formatting character.
+&#x202c; - The PDF (pop directional formatting) formatting character; closes LRO.
+The punctuation is moved around in the source to make it easier to do visual comparisons when the test is run.
+-->
+<div class="test">
+<div dir="ltr">&#x5d0; <span dir="ltr">3</span></div>
+<div dir="ltr">a <span dir="ltr">3</span></div>
+<div dir="rtl">&#x5d0; <span dir="rtl">3</span></div>
+<div dir="rtl">a <span dir="rtl">3</span></div>
+</div>
+<div class="ref">
+<div dir="ltr">&#x202d;&#x5d0; 3&#x202c;</div>
+<div dir="ltr">&#x202d;a 3&#x202c;</div>
+<div dir="rtl">&#x202d;3 &#x5d0;&#x202c;</div>
+<div dir="rtl">&#x202d;3 a&#x202c;</div>
+</div>
+</body></html> \ No newline at end of file
diff --git a/testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-005a.html b/testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-005a.html
new file mode 100644
index 0000000000..2fbddbd71f
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-005a.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="utf-8">
+<title>The dir attribute: isolated from following text, opposite direction</title>
+<link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'>
+<link rel="help" href='http://www.w3.org/TR/html5/dom.html#requirements-relating-to-the-bidirectional-algorithm'>
+<link rel='match' href='reference/dir-isolation-005-ref.html'>
+<meta name='assert' content='Element content with a dir attribute is treated as a neutral character and directionally isolated from following text.'>
+<style type="text/css">
+.test, .ref { font-size: 150%; border: 1px solid orange; margin: 10px; margin-right: 200px; padding: 5px; clear: both; }
+input { margin: 5px; }
+</style>
+</head>
+<body>
+<p class="instructions" dir="ltr">Test passes if the two boxes are identical.</p>
+<!--Notes:
+Key to entities used below:
+&#x5d0; ... &#x5d5; - The first six Hebrew letters (strongly RTL).
+&#x202d; - The LRO (left-to-right-override) formatting character.
+&#x202c; - The PDF (pop directional formatting) formatting character; closes LRO.
+The punctuation is moved around in the source to make it easier to do visual comparisons when the test is run.
+-->
+<div class="test">
+<div dir="ltr"><span dir="rtl">&#x5d0;</span> &#x5d1;...</div>
+<div dir="ltr"><span dir="rtl">a</span> b...</div>
+<div dir="rtl"><span dir="ltr">a</span> b...</div>
+<div dir="rtl"><span dir="ltr">&#x5d0;</span> &#x5d1;...</div>
+</div>
+<div class="ref">
+<div dir="ltr">&#x202d;&#x5d0; &#x5d1;...&#x202c;</div>
+<div dir="ltr">&#x202d;a b...&#x202c;</div>
+<div dir="rtl">&#x202d;...b a&#x202c;</div>
+<div dir="rtl">&#x202d;...&#x5d1; &#x5d0;&#x202c;</div>
+</div>
+</body></html> \ No newline at end of file
diff --git a/testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-005b.html b/testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-005b.html
new file mode 100644
index 0000000000..d61e258f21
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-005b.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="utf-8">
+<title>The dir attribute: isolated from following text, auto</title>
+<link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'>
+<link rel="help" href='http://www.w3.org/TR/html5/dom.html#requirements-relating-to-the-bidirectional-algorithm'>
+<link rel='match' href='reference/dir-isolation-005-ref.html'>
+<meta name='assert' content='Element content with a dir attribute is treated as a neutral character and directionally isolated from following text.'>
+<style type="text/css">
+.test, .ref { font-size: 150%; border: 1px solid orange; margin: 10px; margin-right: 200px; padding: 5px; clear: both; }
+input { margin: 5px; }
+</style>
+</head>
+<body>
+<p class="instructions" dir="ltr">Test passes if the two boxes are identical.</p>
+<!--Notes:
+Key to entities used below:
+&#x5d0; ... &#x5d5; - The first six Hebrew letters (strongly RTL).
+&#x202d; - The LRO (left-to-right-override) formatting character.
+&#x202c; - The PDF (pop directional formatting) formatting character; closes LRO.
+The punctuation is moved around in the source to make it easier to do visual comparisons when the test is run.
+-->
+<div class="test">
+<div dir="ltr"><span dir="auto">&#x5d0;</span> &#x5d1;...</div>
+<div dir="ltr"><span dir="auto">a</span> b...</div>
+<div dir="rtl"><span dir="auto">a</span> b...</div>
+<div dir="rtl"><span dir="auto">&#x5d0;</span> &#x5d1;...</div>
+</div>
+<div class="ref">
+<div dir="ltr">&#x202d;&#x5d0; &#x5d1;...&#x202c;</div>
+<div dir="ltr">&#x202d;a b...&#x202c;</div>
+<div dir="rtl">&#x202d;...b a&#x202c;</div>
+<div dir="rtl">&#x202d;...&#x5d1; &#x5d0;&#x202c;</div>
+</div>
+</body></html> \ No newline at end of file
diff --git a/testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-005c.html b/testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-005c.html
new file mode 100644
index 0000000000..d544275b2f
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-005c.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="utf-8">
+<title>The dir attribute: isolated from following text, same direction</title>
+<link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'>
+<link rel="help" href='http://www.w3.org/TR/html5/dom.html#requirements-relating-to-the-bidirectional-algorithm'>
+<link rel='match' href='reference/dir-isolation-005-ref.html'>
+<meta name='assert' content='Element content with a dir attribute is treated as a neutral character and directionally isolated from following text.'>
+<style type="text/css">
+.test, .ref { font-size: 150%; border: 1px solid orange; margin: 10px; margin-right: 200px; padding: 5px; clear: both; }
+input { margin: 5px; }
+</style>
+</head>
+<body>
+<p class="instructions" dir="ltr">Test passes if the two boxes are identical.</p>
+<!--Notes:
+Key to entities used below:
+&#x5d0; ... &#x5d5; - The first six Hebrew letters (strongly RTL).
+&#x202d; - The LRO (left-to-right-override) formatting character.
+&#x202c; - The PDF (pop directional formatting) formatting character; closes LRO.
+The punctuation is moved around in the source to make it easier to do visual comparisons when the test is run.
+-->
+<div class="test">
+<div dir="ltr"><span dir="ltr">&#x5d0;</span> &#x5d1;...</div>
+<div dir="ltr"><span dir="ltr">a</span> b...</div>
+<div dir="rtl"><span dir="rtl">a</span> b...</div>
+<div dir="rtl"><span dir="rtl">&#x5d0;</span> &#x5d1;...</div>
+</div>
+<div class="ref">
+<div dir="ltr">&#x202d;&#x5d0; &#x5d1;...&#x202c;</div>
+<div dir="ltr">&#x202d;a b...&#x202c;</div>
+<div dir="rtl">&#x202d;...b a&#x202c;</div>
+<div dir="rtl">&#x202d;...&#x5d1; &#x5d0;&#x202c;</div>
+</div>
+</body></html> \ No newline at end of file
diff --git a/testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-006a.html b/testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-006a.html
new file mode 100644
index 0000000000..430df00d9f
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-006a.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="utf-8">
+<title>The dir attribute: isolated from following text with intervening neutrals, opposite direction</title>
+<link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'>
+<link rel="help" href='http://www.w3.org/TR/html5/dom.html#requirements-relating-to-the-bidirectional-algorithm'>
+<link rel='match' href='reference/dir-isolation-006-ref.html'>
+<meta name='assert' content='Element content with a dir attribute is treated as a neutral character and directionally isolated from following text despite intervening neutrals.'>
+<style type="text/css">
+.test, .ref { font-size: 150%; border: 1px solid orange; margin: 10px; margin-right: 200px; padding: 5px; clear: both; }
+input { margin: 5px; }
+</style>
+</head>
+<body>
+<p class="instructions" dir="ltr">Test passes if the two boxes are identical.</p>
+<!--Notes:
+Key to entities used below:
+&#x5d0; ... &#x5d5; - The first six Hebrew letters (strongly RTL).
+&#x202d; - The LRO (left-to-right-override) formatting character.
+&#x202c; - The PDF (pop directional formatting) formatting character; closes LRO.
+The punctuation is moved around in the source to make it easier to do visual comparisons when the test is run.
+-->
+<div class="test">
+<div dir="ltr"><span dir="rtl">&gt; &#x5d0; &gt;</span> &gt; &#x5d1; &gt;...</div>
+<div dir="rtl"><span dir="ltr">&gt; a &gt;</span> &gt; b &gt;...</div>
+</div>
+<div class="ref">
+<div dir="ltr">&#x202d;&lt; &#x5d0; &lt; &gt; &#x5d1; &gt;...&#x202c;</div>
+<div dir="rtl">&#x202d;...&lt; b &lt; &gt; a &gt;&#x202c;</div>
+</div>
+</body></html> \ No newline at end of file
diff --git a/testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-006b.html b/testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-006b.html
new file mode 100644
index 0000000000..a6da487152
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-006b.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="utf-8">
+<title>The dir attribute: isolated from following text with intervening neutrals, auto</title>
+<link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'>
+<link rel="help" href='http://www.w3.org/TR/html5/dom.html#requirements-relating-to-the-bidirectional-algorithm'>
+<link rel='match' href='reference/dir-isolation-006-ref.html'>
+<meta name='assert' content='Element content with a dir attribute is treated as a neutral character and directionally isolated from following text despite intervening neutrals.'>
+<style type="text/css">
+.test, .ref { font-size: 150%; border: 1px solid orange; margin: 10px; margin-right: 200px; padding: 5px; clear: both; }
+input { margin: 5px; }
+</style>
+</head>
+<body>
+<p class="instructions" dir="ltr">Test passes if the two boxes are identical.</p>
+<!--Notes:
+Key to entities used below:
+&#x5d0; ... &#x5d5; - The first six Hebrew letters (strongly RTL).
+&#x202d; - The LRO (left-to-right-override) formatting character.
+&#x202c; - The PDF (pop directional formatting) formatting character; closes LRO.
+The punctuation is moved around in the source to make it easier to do visual comparisons when the test is run.
+-->
+<div class="test">
+<div dir="ltr"><span dir="auto">&gt; &#x5d0; &gt;</span> &gt; &#x5d1; &gt;...</div>
+<div dir="rtl"><span dir="auto">&gt; a &gt;</span> &gt; b &gt;...</div>
+</div>
+<div class="ref">
+<div dir="ltr">&#x202d;&lt; &#x5d0; &lt; &gt; &#x5d1; &gt;...&#x202c;</div>
+<div dir="rtl">&#x202d;...&lt; b &lt; &gt; a &gt;&#x202c;</div>
+</div>
+</body></html> \ No newline at end of file
diff --git a/testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-006c.html b/testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-006c.html
new file mode 100644
index 0000000000..3407d37f38
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-006c.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="utf-8">
+<title>The dir attribute: isolated from following text with intervening neutrals, same direction</title>
+<link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'>
+<link rel="help" href='http://www.w3.org/TR/html5/dom.html#requirements-relating-to-the-bidirectional-algorithm'>
+<link rel='match' href='reference/dir-isolation-006c-ref.html'>
+<meta name='assert' content='Element content with a dir attribute is treated as a neutral character and directionally isolated from following text despite intervening neutrals.'>
+<style type="text/css">
+.test, .ref { font-size: 150%; border: 1px solid orange; margin: 10px; margin-right: 200px; padding: 5px; clear: both; }
+input { margin: 5px; }
+</style>
+</head>
+<body>
+<p class="instructions" dir="ltr">Test passes if the two boxes are identical.</p>
+<!--Notes:
+Key to entities used below:
+&#x5d0; ... &#x5d5; - The first six Hebrew letters (strongly RTL).
+&#x202d; - The LRO (left-to-right-override) formatting character.
+&#x202c; - The PDF (pop directional formatting) formatting character; closes LRO.
+The punctuation is moved around in the source to make it easier to do visual comparisons when the test is run.
+-->
+<div class="test">
+<div dir="ltr"><span dir="ltr">&gt; &#x5d0; &gt;</span> &gt; &#x5d1; &gt;...</div>
+<div dir="rtl"><span dir="rtl">&gt; a &gt;</span> &gt; b &gt;...</div>
+</div>
+<div class="ref">
+<div dir="ltr">&#x202d;&gt; &#x5d0; &gt; &gt; &#x5d1; &gt;...&#x202c;</div>
+<div dir="rtl">&#x202d;...&lt; b &lt; &lt; a &lt;&#x202c;</div>
+</div>
+</body></html> \ No newline at end of file
diff --git a/testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-007a.html b/testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-007a.html
new file mode 100644
index 0000000000..e8b37b1b97
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-007a.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="utf-8">
+<title>The dir attribute: isolated from immediately following text, opposite direction</title>
+<link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'>
+<link rel="help" href='http://www.w3.org/TR/html5/dom.html#requirements-relating-to-the-bidirectional-algorithm'>
+<link rel='match' href='reference/dir-isolation-007-ref.html'>
+<meta name='assert' content='Element content with a dir attribute is treated as a neutral character and directionally isolated from following text even with no intervening white space.'>
+<style type="text/css">
+.test, .ref { font-size: 150%; border: 1px solid orange; margin: 10px; margin-right: 200px; padding: 5px; clear: both; }
+input { margin: 5px; }
+</style>
+</head>
+<body>
+<p class="instructions" dir="ltr">Test passes if the two boxes are identical.</p>
+<!--Notes:
+Key to entities used below:
+&#x5d0; ... &#x5d5; - The first six Hebrew letters (strongly RTL).
+&#x202d; - The LRO (left-to-right-override) formatting character.
+&#x202c; - The PDF (pop directional formatting) formatting character; closes LRO.
+The punctuation is moved around in the source to make it easier to do visual comparisons when the test is run.
+-->
+<div class="test">
+<div dir="ltr"><span dir="rtl">&#x5d0;</span>&#x5d1;...</div>
+<div dir="ltr"><span dir="rtl">a</span>b...</div>
+<div dir="rtl"><span dir="ltr">a</span>b...</div>
+<div dir="rtl"><span dir="ltr">&#x5d0;</span>&#x5d1;...</div>
+</div>
+<div class="ref">
+<div dir="ltr">&#x202d;&#x5d0;&#x5d1;...&#x202c;</div>
+<div dir="ltr">&#x202d;ab...&#x202c;</div>
+<div dir="rtl">&#x202d;...ba&#x202c;</div>
+<div dir="rtl">&#x202d;...&#x5d1;&#x5d0;&#x202c;</div>
+</div>
+</body></html> \ No newline at end of file
diff --git a/testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-007b.html b/testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-007b.html
new file mode 100644
index 0000000000..c54e63de7c
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-007b.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="utf-8">
+<title>The dir attribute: isolated from immediately following text, auto</title>
+<link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'>
+<link rel="help" href='http://www.w3.org/TR/html5/dom.html#requirements-relating-to-the-bidirectional-algorithm'>
+<link rel='match' href='reference/dir-isolation-007-ref.html'>
+<meta name='assert' content='Element content with a dir attribute is treated as a neutral character and directionally isolated from following text even with no intervening white space.'>
+<style type="text/css">
+.test, .ref { font-size: 150%; border: 1px solid orange; margin: 10px; margin-right: 200px; padding: 5px; clear: both; }
+input { margin: 5px; }
+</style>
+</head>
+<body>
+<p class="instructions" dir="ltr">Test passes if the two boxes are identical.</p>
+<!--Notes:
+Key to entities used below:
+&#x5d0; ... &#x5d5; - The first six Hebrew letters (strongly RTL).
+&#x202d; - The LRO (left-to-right-override) formatting character.
+&#x202c; - The PDF (pop directional formatting) formatting character; closes LRO.
+The punctuation is moved around in the source to make it easier to do visual comparisons when the test is run.
+-->
+<div class="test">
+<div dir="ltr"><span dir="auto">&#x5d0;</span>&#x5d1;...</div>
+<div dir="ltr"><span dir="auto">a</span>b...</div>
+<div dir="rtl"><span dir="auto">a</span>b...</div>
+<div dir="rtl"><span dir="auto">&#x5d0;</span>&#x5d1;...</div>
+</div>
+<div class="ref">
+<div dir="ltr">&#x202d;&#x5d0;&#x5d1;...&#x202c;</div>
+<div dir="ltr">&#x202d;ab...&#x202c;</div>
+<div dir="rtl">&#x202d;...ba&#x202c;</div>
+<div dir="rtl">&#x202d;...&#x5d1;&#x5d0;&#x202c;</div>
+</div>
+</body></html> \ No newline at end of file
diff --git a/testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-007c.html b/testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-007c.html
new file mode 100644
index 0000000000..b9c5219b8d
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-007c.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="utf-8">
+<title>The dir attribute: isolated from immediately following text, same direction</title>
+<link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'>
+<link rel="help" href='http://www.w3.org/TR/html5/dom.html#requirements-relating-to-the-bidirectional-algorithm'>
+<link rel='match' href='reference/dir-isolation-007-ref.html'>
+<meta name='assert' content='Element content with a dir attribute is treated as a neutral character and directionally isolated from following text even with no intervening white space.'>
+<style type="text/css">
+.test, .ref { font-size: 150%; border: 1px solid orange; margin: 10px; margin-right: 200px; padding: 5px; clear: both; }
+input { margin: 5px; }
+</style>
+</head>
+<body>
+<p class="instructions" dir="ltr">Test passes if the two boxes are identical.</p>
+<!--Notes:
+Key to entities used below:
+&#x5d0; ... &#x5d5; - The first six Hebrew letters (strongly RTL).
+&#x202d; - The LRO (left-to-right-override) formatting character.
+&#x202c; - The PDF (pop directional formatting) formatting character; closes LRO.
+The punctuation is moved around in the source to make it easier to do visual comparisons when the test is run.
+-->
+<div class="test">
+<div dir="ltr"><span dir="ltr">&#x5d0;</span>&#x5d1;...</div>
+<div dir="ltr"><span dir="ltr">a</span>b...</div>
+<div dir="rtl"><span dir="rtl">a</span>b...</div>
+<div dir="rtl"><span dir="rtl">&#x5d0;</span>&#x5d1;...</div>
+</div>
+<div class="ref">
+<div dir="ltr">&#x202d;&#x5d0;&#x5d1;...&#x202c;</div>
+<div dir="ltr">&#x202d;ab...&#x202c;</div>
+<div dir="rtl">&#x202d;...ba&#x202c;</div>
+<div dir="rtl">&#x202d;...&#x5d1;&#x5d0;&#x202c;</div>
+</div>
+</body></html> \ No newline at end of file
diff --git a/testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-008a.html b/testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-008a.html
new file mode 100644
index 0000000000..1455fd552b
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-008a.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="utf-8">
+<title>The dir attribute: isolated from preceding text, opposite direction</title>
+<link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'>
+<link rel="help" href='http://www.w3.org/TR/html5/dom.html#requirements-relating-to-the-bidirectional-algorithm'>
+<link rel='match' href='reference/dir-isolation-008-ref.html'>
+<meta name='assert' content='Element content with a dir attribute is treated as a neutral character and directionally isolated from preceding text.'>
+<style type="text/css">
+.test, .ref { font-size: 150%; border: 1px solid orange; margin: 10px; margin-right: 200px; padding: 5px; clear: both; }
+input { margin: 5px; }
+</style>
+</head>
+<body>
+<p class="instructions" dir="ltr">Test passes if the two boxes are identical.</p>
+<!--Notes:
+Key to entities used below:
+&#x5d0; ... &#x5d5; - The first six Hebrew letters (strongly RTL).
+&#x202d; - The LRO (left-to-right-override) formatting character.
+&#x202c; - The PDF (pop directional formatting) formatting character; closes LRO.
+The punctuation is moved around in the source to make it easier to do visual comparisons when the test is run.
+-->
+<div class="test">
+<div dir="ltr">&#x5d0; <span dir="rtl">&#x5d1;</span></div>
+<div dir="ltr">a <span dir="rtl">b</span></div>
+<div dir="rtl">&#x5d0; <span dir="ltr">&#x5d1;</span></div>
+<div dir="rtl">a <span dir="ltr">b</span></div>
+</div>
+<div class="ref">
+<div dir="ltr">&#x202d;&#x5d0; &#x5d1;&#x202c;</div>
+<div dir="ltr">&#x202d;a b&#x202c;</div>
+<div dir="rtl">&#x202d;&#x5d1; &#x5d0;&#x202c;</div>
+<div dir="rtl">&#x202d;b a&#x202c;</div>
+</div>
+</body></html> \ No newline at end of file
diff --git a/testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-008b.html b/testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-008b.html
new file mode 100644
index 0000000000..f12e6d67bf
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-008b.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="utf-8">
+<title>The dir attribute: isolated from preceding text, auto</title>
+<link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'>
+<link rel="help" href='http://www.w3.org/TR/html5/dom.html#requirements-relating-to-the-bidirectional-algorithm'>
+<link rel='match' href='reference/dir-isolation-008-ref.html'>
+<meta name='assert' content='Element content with a dir attribute is treated as a neutral character and directionally isolated from preceding text.'>
+<style type="text/css">
+.test, .ref { font-size: 150%; border: 1px solid orange; margin: 10px; margin-right: 200px; padding: 5px; clear: both; }
+input { margin: 5px; }
+</style>
+</head>
+<body>
+<p class="instructions" dir="ltr">Test passes if the two boxes are identical.</p>
+<!--Notes:
+Key to entities used below:
+&#x5d0; ... &#x5d5; - The first six Hebrew letters (strongly RTL).
+&#x202d; - The LRO (left-to-right-override) formatting character.
+&#x202c; - The PDF (pop directional formatting) formatting character; closes LRO.
+The punctuation is moved around in the source to make it easier to do visual comparisons when the test is run.
+-->
+<div class="test">
+<div dir="ltr">&#x5d0; <span dir="auto">&#x5d1;</span></div>
+<div dir="ltr">a <span dir="auto">b</span></div>
+<div dir="rtl">&#x5d0; <span dir="auto">&#x5d1;</span></div>
+<div dir="rtl">a <span dir="auto">b</span></div>
+</div>
+<div class="ref">
+<div dir="ltr">&#x202d;&#x5d0; &#x5d1;&#x202c;</div>
+<div dir="ltr">&#x202d;a b&#x202c;</div>
+<div dir="rtl">&#x202d;&#x5d1; &#x5d0;&#x202c;</div>
+<div dir="rtl">&#x202d;b a&#x202c;</div>
+</div>
+</body></html> \ No newline at end of file
diff --git a/testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-008c.html b/testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-008c.html
new file mode 100644
index 0000000000..b1754cf23e
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-008c.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="utf-8">
+<title>The dir attribute: isolated from preceding text, same direction</title>
+<link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'>
+<link rel="help" href='http://www.w3.org/TR/html5/dom.html#requirements-relating-to-the-bidirectional-algorithm'>
+<link rel='match' href='reference/dir-isolation-008-ref.html'>
+<meta name='assert' content='Element content with a dir attribute is treated as a neutral character and directionally isolated from preceding text.'>
+<style type="text/css">
+.test, .ref { font-size: 150%; border: 1px solid orange; margin: 10px; margin-right: 200px; padding: 5px; clear: both; }
+input { margin: 5px; }
+</style>
+</head>
+<body>
+<p class="instructions" dir="ltr">Test passes if the two boxes are identical.</p>
+<!--Notes:
+Key to entities used below:
+&#x5d0; ... &#x5d5; - The first six Hebrew letters (strongly RTL).
+&#x202d; - The LRO (left-to-right-override) formatting character.
+&#x202c; - The PDF (pop directional formatting) formatting character; closes LRO.
+The punctuation is moved around in the source to make it easier to do visual comparisons when the test is run.
+-->
+<div class="test">
+<div dir="ltr">&#x5d0; <span dir="ltr">&#x5d1;</span></div>
+<div dir="ltr">a <span dir="ltr">b</span></div>
+<div dir="rtl">&#x5d0; <span dir="rtl">&#x5d1;</span></div>
+<div dir="rtl">a <span dir="rtl">b</span></div>
+</div>
+<div class="ref">
+<div dir="ltr">&#x202d;&#x5d0; &#x5d1;&#x202c;</div>
+<div dir="ltr">&#x202d;a b&#x202c;</div>
+<div dir="rtl">&#x202d;&#x5d1; &#x5d0;&#x202c;</div>
+<div dir="rtl">&#x202d;b a&#x202c;</div>
+</div>
+</body></html> \ No newline at end of file
diff --git a/testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-009a.html b/testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-009a.html
new file mode 100644
index 0000000000..63a9706bae
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-009a.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html lang="en" >
+<head>
+<meta charset="utf-8"/>
+<title>The dir attribute: isolated from surrounding text, opposite direction</title>
+<link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'>
+<link rel="help" href='http://www.w3.org/TR/html5/dom.html#requirements-relating-to-the-bidirectional-algorithm'>
+<link rel='match' href='reference/dir-isolation-009-ref.html'>
+<meta name='assert' content="Element content with a dir attribute is treated as a neutral character and directionally isolated from surrounding text.">
+<style type='text/css'>
+.test, .ref { font-size: 150%; border: 1px solid orange; margin: 10px; margin-right: 200px; padding: 5px; clear: both; }
+input { margin: 5px; }
+</style>
+</head>
+<body>
+<p class="instructions" dir="ltr">Test passes if the two boxes are identical.</p>
+<!-- Key to entities used below:
+&#x5d0; ... &#x5d5; - The first six Hebrew letters (strongly RTL).
+&#x202d; - The LRO (left-to-right-override) formatting character.
+&#x202c; - The PDF (pop directional formatting) formatting character; closes LRO.
+If the BDI in the test's first DIV were a SPAN, its b would prevent the &#x5d0; and the &#x5d1;
+from forming a single RTL run and thus keep the &gt;s between from being mirrored into &lt;s.
+-->
+<div class="test">
+<div dir="ltr">&#x5d0; &gt; <span dir="rtl">&gt; b &gt;</span> &gt; &#x5d2;...</div>
+<div dir="rtl">a &gt; <span dir="ltr">&gt; &#x5d1; &gt;</span> &gt; c...</div>
+</div>
+<div class="ref">
+<div dir="ltr">&#x202d;&#x5d2; &lt; &lt; b &lt; &lt; &#x5d0;...&#x202c;</div>
+<div dir="rtl">&#x202d;...a &gt; &gt; &#x5d1; &gt; &gt; c&#x202c;</div>
+</div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-009b.html b/testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-009b.html
new file mode 100644
index 0000000000..57098fa75a
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-009b.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html lang="en" >
+<head>
+<meta charset="utf-8"/>
+<title>The dir attribute: isolated from surrounding text, auto</title>
+<link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'>
+<link rel="help" href='http://www.w3.org/TR/html5/dom.html#requirements-relating-to-the-bidirectional-algorithm'>
+<link rel='match' href='reference/dir-isolation-009b-ref.html'>
+<meta name='assert' content="Element content with a dir attribute is treated as a neutral character and directionally isolated from surrounding text.">
+<style type='text/css'>
+.test, .ref { font-size: 150%; border: 1px solid orange; margin: 10px; margin-right: 200px; padding: 5px; clear: both; }
+input { margin: 5px; }
+</style>
+</head>
+<body>
+<p class="instructions" dir="ltr">Test passes if the two boxes are identical.</p>
+<!-- Key to entities used below:
+&#x5d0; ... &#x5d5; - The first six Hebrew letters (strongly RTL).
+&#x202d; - The LRO (left-to-right-override) formatting character.
+&#x202c; - The PDF (pop directional formatting) formatting character; closes LRO.
+If the BDI in the test's first DIV were a SPAN, its b would prevent the &#x5d0; and the &#x5d1;
+from forming a single RTL run and thus keep the &gt;s between from being mirrored into &lt;s.
+-->
+<div class="test">
+<div dir="ltr">&#x5d0; &gt; <span dir="auto">&gt; b &gt;</span> &gt; &#x5d2;...</div>
+<div dir="rtl">a &gt; <span dir="auto">&gt; &#x5d1; &gt;</span> &gt; c...</div>
+</div>
+<div class="ref">
+<div dir="ltr">&#x202d;&#x5d2; &lt; &gt; b &gt; &lt; &#x5d0;...&#x202c;</div>
+<div dir="rtl">&#x202d;...a &gt; &lt; &#x5d1; &lt; &gt; c&#x202c;</div>
+</div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-009c.html b/testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-009c.html
new file mode 100644
index 0000000000..4aac3184ee
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/dir-isolation-009c.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html lang="en" >
+<head>
+<meta charset="utf-8"/>
+<title>The dir attribute: isolated from surrounding text, same direction</title>
+<link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'>
+<link rel="help" href='http://www.w3.org/TR/html5/dom.html#requirements-relating-to-the-bidirectional-algorithm'>
+<link rel='match' href='reference/dir-isolation-009b-ref.html'>
+<meta name='assert' content="Element content with a dir attribute is treated as a neutral character and directionally isolated from surrounding text.">
+<style type='text/css'>
+.test, .ref { font-size: 150%; border: 1px solid orange; margin: 10px; margin-right: 200px; padding: 5px; clear: both; }
+input { margin: 5px; }
+</style>
+</head>
+<body>
+<p class="instructions" dir="ltr">Test passes if the two boxes are identical.</p>
+<!-- Key to entities used below:
+&#x5d0; ... &#x5d5; - The first six Hebrew letters (strongly RTL).
+&#x202d; - The LRO (left-to-right-override) formatting character.
+&#x202c; - The PDF (pop directional formatting) formatting character; closes LRO.
+If the BDI in the test's first DIV were a SPAN, its b would prevent the &#x5d0; and the &#x5d1;
+from forming a single RTL run and thus keep the &gt;s between from being mirrored into &lt;s.
+-->
+<div class="test">
+<div dir="ltr">&#x5d0; &gt; <span dir="ltr">&gt; b &gt;</span> &gt; &#x5d2;...</div>
+<div dir="rtl">a &gt; <span dir="rtl">&gt; &#x5d1; &gt;</span> &gt; c...</div>
+</div>
+<div class="ref">
+<div dir="ltr">&#x202d;&#x5d2; &lt; &gt; b &gt; &lt; &#x5d0;...&#x202c;</div>
+<div dir="rtl">&#x202d;...a &gt; &lt; &#x5d1; &lt; &gt; c&#x202c;</div>
+</div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/reference/dir-isolation-001-ref.html b/testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/reference/dir-isolation-001-ref.html
new file mode 100644
index 0000000000..b5882eb7a3
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/reference/dir-isolation-001-ref.html
@@ -0,0 +1,16 @@
+<!doctype html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>The dir attribute: isolated from following number, opposite direction</title>
+<style type="text/css">
+.test, .ref { font-size: 150%; border: 1px solid orange; margin: 10px; margin-right: 200px; padding: 5px; clear: both; }
+input { margin: 5px; }
+</style>
+</head>
+<body>
+<p class="instructions" dir="ltr">Test passes if the two boxes are identical.</p>
+<div class="ref"><div dir="ltr">&#8237;&#1488; 3&#8236;</div><div dir="ltr">&#8237;a 3&#8236;</div><div dir="rtl">&#8237;3 &#1488;&#8236;</div><div dir="rtl">&#8237;3 a&#8236;</div></div>
+<div class="ref"><div dir="ltr">&#8237;&#1488; 3&#8236;</div><div dir="ltr">&#8237;a 3&#8236;</div><div dir="rtl">&#8237;3 &#1488;&#8236;</div><div dir="rtl">&#8237;3 a&#8236;</div></div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/reference/dir-isolation-002a-ref.html b/testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/reference/dir-isolation-002a-ref.html
new file mode 100644
index 0000000000..f28559b5a1
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/reference/dir-isolation-002a-ref.html
@@ -0,0 +1,16 @@
+<!doctype html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>The dir attribute: isolated from following number with intervening neutrals, opposite direction</title>
+<style type="text/css">
+.test, .ref { font-size: 150%; border: 1px solid orange; margin: 10px; margin-right: 200px; padding: 5px; clear: both; }
+input { margin: 5px; }
+</style>
+</head>
+<body>
+<p class="instructions" dir="ltr">Test passes if the two boxes are identical.</p>
+<div class="ref"><div dir="ltr">&#8237;&lt; &#1488; &lt; &gt; 3 &gt;&#8236;</div><div dir="ltr">&#8237;&lt; a &lt; &gt; 3 &gt;&#8236;</div><div dir="rtl">&#8237;&lt; 3 &lt; &gt; &#1488; &gt;&#8236;</div><div dir="rtl">&#8237;&lt; 3 &lt; &gt; a &gt;&#8236;</div></div>
+<div class="ref"><div dir="ltr">&#8237;&lt; &#1488; &lt; &gt; 3 &gt;&#8236;</div><div dir="ltr">&#8237;&lt; a &lt; &gt; 3 &gt;&#8236;</div><div dir="rtl">&#8237;&lt; 3 &lt; &gt; &#1488; &gt;&#8236;</div><div dir="rtl">&#8237;&lt; 3 &lt; &gt; a &gt;&#8236;</div></div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/reference/dir-isolation-002b-ref.html b/testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/reference/dir-isolation-002b-ref.html
new file mode 100644
index 0000000000..d4eda2189d
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/reference/dir-isolation-002b-ref.html
@@ -0,0 +1,16 @@
+<!doctype html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>The dir attribute: isolated from following number with intervening neutrals, auto</title>
+<style type="text/css">
+.test, .ref { font-size: 150%; border: 1px solid orange; margin: 10px; margin-right: 200px; padding: 5px; clear: both; }
+input { margin: 5px; }
+</style>
+</head>
+<body>
+<p class="instructions" dir="ltr">Test passes if the two boxes are identical.</p>
+<div class="ref"><div dir="ltr">&#8237;&lt; &#1488; &lt; &gt; 3 &gt;&#8236;</div><div dir="ltr">&#8237;&gt; a &gt; &gt; 3 &gt;&#8236;</div><div dir="rtl">&#8237;&lt; 3 &lt; &lt; &#1488; &lt;&#8236;</div><div dir="rtl">&#8237;&lt; 3 &lt; &gt; a &gt;&#8236;</div></div>
+<div class="ref"><div dir="ltr">&#8237;&lt; &#1488; &lt; &gt; 3 &gt;&#8236;</div><div dir="ltr">&#8237;&gt; a &gt; &gt; 3 &gt;&#8236;</div><div dir="rtl">&#8237;&lt; 3 &lt; &lt; &#1488; &lt;&#8236;</div><div dir="rtl">&#8237;&lt; 3 &lt; &gt; a &gt;&#8236;</div></div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/reference/dir-isolation-002c-ref.html b/testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/reference/dir-isolation-002c-ref.html
new file mode 100644
index 0000000000..6c21d0147d
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/reference/dir-isolation-002c-ref.html
@@ -0,0 +1,16 @@
+<!doctype html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>The dir attribute: isolated from following number with intervening neutrals, same direction</title>
+<style type="text/css">
+.test, .ref { font-size: 150%; border: 1px solid orange; margin: 10px; margin-right: 200px; padding: 5px; clear: both; }
+input { margin: 5px; }
+</style>
+</head>
+<body>
+<p class="instructions" dir="ltr">Test passes if the two boxes are identical.</p>
+<div class="ref"><div dir="ltr">&#8237;&gt; &#1488; &gt; &gt; 3 &gt;&#8236;</div><div dir="ltr">&#8237;&gt; a &gt; &gt; 3 &gt;&#8236;</div><div dir="rtl">&#8237;&lt; 3 &lt; &lt; &#1488; &lt;&#8236;</div><div dir="rtl">&#8237;&lt; 3 &lt; &lt; a &lt;&#8236;</div></div>
+<div class="ref"><div dir="ltr">&#8237;&gt; &#1488; &gt; &gt; 3 &gt;&#8236;</div><div dir="ltr">&#8237;&gt; a &gt; &gt; 3 &gt;&#8236;</div><div dir="rtl">&#8237;&lt; 3 &lt; &lt; &#1488; &lt;&#8236;</div><div dir="rtl">&#8237;&lt; 3 &lt; &lt; a &lt;&#8236;</div></div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/reference/dir-isolation-003-ref.html b/testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/reference/dir-isolation-003-ref.html
new file mode 100644
index 0000000000..4c29838ee4
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/reference/dir-isolation-003-ref.html
@@ -0,0 +1,16 @@
+<!doctype html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>The dir attribute: isolated from immediately following number, opposite direction</title>
+<style type="text/css">
+.test, .ref { font-size: 150%; border: 1px solid orange; margin: 10px; margin-right: 200px; padding: 5px; clear: both; }
+input { margin: 5px; }
+</style>
+</head>
+<body>
+<p class="instructions" dir="ltr">Test passes if the two boxes are identical.</p>
+<div class="ref"><div dir="ltr">&#8237;&#1488;3&#8236;</div><div dir="ltr">&#8237;a3&#8236;</div><div dir="rtl">&#8237;3&#1488;&#8236;</div><div dir="rtl">&#8237;3a&#8236;</div></div>
+<div class="ref"><div dir="ltr">&#8237;&#1488;3&#8236;</div><div dir="ltr">&#8237;a3&#8236;</div><div dir="rtl">&#8237;3&#1488;&#8236;</div><div dir="rtl">&#8237;3a&#8236;</div></div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/reference/dir-isolation-004-ref.html b/testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/reference/dir-isolation-004-ref.html
new file mode 100644
index 0000000000..cb83dde584
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/reference/dir-isolation-004-ref.html
@@ -0,0 +1,16 @@
+<!doctype html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>The dir attribute: numbers isolated from preceding text, opposite direction</title>
+<style type="text/css">
+.test, .ref { font-size: 150%; border: 1px solid orange; margin: 10px; margin-right: 200px; padding: 5px; clear: both; }
+input { margin: 5px; }
+</style>
+</head>
+<body>
+<p class="instructions" dir="ltr">Test passes if the two boxes are identical.</p>
+<div class="ref"><div dir="ltr">&#8237;&#1488; 3&#8236;</div><div dir="ltr">&#8237;a 3&#8236;</div><div dir="rtl">&#8237;3 &#1488;&#8236;</div><div dir="rtl">&#8237;3 a&#8236;</div></div>
+<div class="ref"><div dir="ltr">&#8237;&#1488; 3&#8236;</div><div dir="ltr">&#8237;a 3&#8236;</div><div dir="rtl">&#8237;3 &#1488;&#8236;</div><div dir="rtl">&#8237;3 a&#8236;</div></div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/reference/dir-isolation-005-ref.html b/testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/reference/dir-isolation-005-ref.html
new file mode 100644
index 0000000000..4a6c301aa1
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/reference/dir-isolation-005-ref.html
@@ -0,0 +1,16 @@
+<!doctype html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>The dir attribute: isolated from following text, opposite direction</title>
+<style type="text/css">
+.test, .ref { font-size: 150%; border: 1px solid orange; margin: 10px; margin-right: 200px; padding: 5px; clear: both; }
+input { margin: 5px; }
+</style>
+</head>
+<body>
+<p class="instructions" dir="ltr">Test passes if the two boxes are identical.</p>
+<div class="ref"><div dir="ltr">&#8237;&#1488; &#1489;...&#8236;</div><div dir="ltr">&#8237;a b...&#8236;</div><div dir="rtl">&#8237;...b a&#8236;</div><div dir="rtl">&#8237;...&#1489; &#1488;&#8236;</div></div>
+<div class="ref"><div dir="ltr">&#8237;&#1488; &#1489;...&#8236;</div><div dir="ltr">&#8237;a b...&#8236;</div><div dir="rtl">&#8237;...b a&#8236;</div><div dir="rtl">&#8237;...&#1489; &#1488;&#8236;</div></div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/reference/dir-isolation-006-ref.html b/testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/reference/dir-isolation-006-ref.html
new file mode 100644
index 0000000000..0f6b7bbbd0
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/reference/dir-isolation-006-ref.html
@@ -0,0 +1,16 @@
+<!doctype html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>The dir attribute: isolated from following text with intervening neutrals, opposite direction</title>
+<style type="text/css">
+.test, .ref { font-size: 150%; border: 1px solid orange; margin: 10px; margin-right: 200px; padding: 5px; clear: both; }
+input { margin: 5px; }
+</style>
+</head>
+<body>
+<p class="instructions" dir="ltr">Test passes if the two boxes are identical.</p>
+<div class="ref"><div dir="ltr">&#8237;&lt; &#1488; &lt; &gt; &#1489; &gt;...&#8236;</div><div dir="rtl">&#8237;...&lt; b &lt; &gt; a &gt;&#8236;</div></div>
+<div class="ref"><div dir="ltr">&#8237;&lt; &#1488; &lt; &gt; &#1489; &gt;...&#8236;</div><div dir="rtl">&#8237;...&lt; b &lt; &gt; a &gt;&#8236;</div></div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/reference/dir-isolation-006c-ref.html b/testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/reference/dir-isolation-006c-ref.html
new file mode 100644
index 0000000000..0347c0910c
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/reference/dir-isolation-006c-ref.html
@@ -0,0 +1,16 @@
+<!doctype html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>The dir attribute: isolated from following text with intervening neutrals, same direction</title>
+<style type="text/css">
+.test, .ref { font-size: 150%; border: 1px solid orange; margin: 10px; margin-right: 200px; padding: 5px; clear: both; }
+input { margin: 5px; }
+</style>
+</head>
+<body>
+<p class="instructions" dir="ltr">Test passes if the two boxes are identical.</p>
+<div class="ref"><div dir="ltr">&#8237;&gt; &#1488; &gt; &gt; &#1489; &gt;...&#8236;</div><div dir="rtl">&#8237;...&lt; b &lt; &lt; a &lt;&#8236;</div></div>
+<div class="ref"><div dir="ltr">&#8237;&gt; &#1488; &gt; &gt; &#1489; &gt;...&#8236;</div><div dir="rtl">&#8237;...&lt; b &lt; &lt; a &lt;&#8236;</div></div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/reference/dir-isolation-007-ref.html b/testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/reference/dir-isolation-007-ref.html
new file mode 100644
index 0000000000..665153d649
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/reference/dir-isolation-007-ref.html
@@ -0,0 +1,16 @@
+<!doctype html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>The dir attribute: isolated from immediately following text, opposite direction</title>
+<style type="text/css">
+.test, .ref { font-size: 150%; border: 1px solid orange; margin: 10px; margin-right: 200px; padding: 5px; clear: both; }
+input { margin: 5px; }
+</style>
+</head>
+<body>
+<p class="instructions" dir="ltr">Test passes if the two boxes are identical.</p>
+<div class="ref"><div dir="ltr">&#8237;&#1488;&#1489;...&#8236;</div><div dir="ltr">&#8237;ab...&#8236;</div><div dir="rtl">&#8237;...ba&#8236;</div><div dir="rtl">&#8237;...&#1489;&#1488;&#8236;</div></div>
+<div class="ref"><div dir="ltr">&#8237;&#1488;&#1489;...&#8236;</div><div dir="ltr">&#8237;ab...&#8236;</div><div dir="rtl">&#8237;...ba&#8236;</div><div dir="rtl">&#8237;...&#1489;&#1488;&#8236;</div></div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/reference/dir-isolation-008-ref.html b/testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/reference/dir-isolation-008-ref.html
new file mode 100644
index 0000000000..8eb90f8b79
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/reference/dir-isolation-008-ref.html
@@ -0,0 +1,16 @@
+<!doctype html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>The dir attribute: isolated from preceding text, opposite direction</title>
+<style type="text/css">
+.test, .ref { font-size: 150%; border: 1px solid orange; margin: 10px; margin-right: 200px; padding: 5px; clear: both; }
+input { margin: 5px; }
+</style>
+</head>
+<body>
+<p class="instructions" dir="ltr">Test passes if the two boxes are identical.</p>
+<div class="ref"><div dir="ltr">&#8237;&#1488; &#1489;&#8236;</div><div dir="ltr">&#8237;a b&#8236;</div><div dir="rtl">&#8237;&#1489; &#1488;&#8236;</div><div dir="rtl">&#8237;b a&#8236;</div></div>
+<div class="ref"><div dir="ltr">&#8237;&#1488; &#1489;&#8236;</div><div dir="ltr">&#8237;a b&#8236;</div><div dir="rtl">&#8237;&#1489; &#1488;&#8236;</div><div dir="rtl">&#8237;b a&#8236;</div></div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/reference/dir-isolation-009-ref.html b/testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/reference/dir-isolation-009-ref.html
new file mode 100644
index 0000000000..1d2f57c6cf
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/reference/dir-isolation-009-ref.html
@@ -0,0 +1,16 @@
+<!doctype html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>The dir attribute: isolated from surrounding text, opposite direction</title>
+<style type="text/css">
+.test, .ref { font-size: 150%; border: 1px solid orange; margin: 10px; margin-right: 200px; padding: 5px; clear: both; }
+input { margin: 5px; }
+</style>
+</head>
+<body>
+<p class="instructions" dir="ltr">Test passes if the two boxes are identical.</p>
+<div class="ref"><div dir="ltr">&#8237;&#1490; &lt; &lt; b &lt; &lt; &#1488;...&#8236;</div><div dir="rtl">&#8237;...a &gt; &gt; &#1489; &gt; &gt; c&#8236;</div></div>
+<div class="ref"><div dir="ltr">&#8237;&#1490; &lt; &lt; b &lt; &lt; &#1488;...&#8236;</div><div dir="rtl">&#8237;...a &gt; &gt; &#1489; &gt; &gt; c&#8236;</div></div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/reference/dir-isolation-009b-ref.html b/testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/reference/dir-isolation-009b-ref.html
new file mode 100644
index 0000000000..30ee14c6c0
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/requirements-relating-to-bidirectional-algorithm-formatting-characters/reference/dir-isolation-009b-ref.html
@@ -0,0 +1,16 @@
+<!doctype html>
+<html>
+<head>
+<meta charset="utf-8"/>
+<title>The dir attribute: isolated from surrounding text, auto</title>
+<style type="text/css">
+.test, .ref { font-size: 150%; border: 1px solid orange; margin: 10px; margin-right: 200px; padding: 5px; clear: both; }
+input { margin: 5px; }
+</style>
+</head>
+<body>
+<p class="instructions" dir="ltr">Test passes if the two boxes are identical.</p>
+<div class="ref"><div dir="ltr">&#8237;&#1490; &lt; &gt; b &gt; &lt; &#1488;...&#8236;</div><div dir="rtl">&#8237;...a &gt; &lt; &#1489; &lt; &gt; c&#8236;</div></div>
+<div class="ref"><div dir="ltr">&#8237;&#1490; &lt; &gt; b &gt; &lt; &#1488;...&#8236;</div><div dir="rtl">&#8237;...a &gt; &lt; &#1489; &lt; &gt; c&#8236;</div></div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/dom/elements/the-innertext-and-outertext-properties/dynamic-getter.html b/testing/web-platform/tests/html/dom/elements/the-innertext-and-outertext-properties/dynamic-getter.html
new file mode 100644
index 0000000000..e34fcf5ac1
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/the-innertext-and-outertext-properties/dynamic-getter.html
@@ -0,0 +1,88 @@
+<!DOCTYPE html>
+<title>innerText/outerText getter test with dynamic style changes</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="container"></div>
+<script>
+let container = document.querySelector('#container');
+
+function testText(html, expectedPlain, msg, mutate) {
+ test(function() {
+ container.innerHTML = html;
+
+ // Cause a flush of style and layout
+ document.body.offsetTop;
+
+ mutate();
+
+ var e = document.getElementById('target');
+ if (!e) {
+ e = container.firstChild;
+ }
+ assert_equals(e.innerText, expectedPlain, "innerText");
+ assert_equals(e.outerText, expectedPlain, "outerText");
+ container.textContext = '';
+ }, msg + ' (' + format_value(html) + ')');
+}
+
+function setStyle(id, attr, value) {
+ let el = document.getElementById(id);
+ if (el) {
+ el.style[attr] = value;
+ }
+}
+
+testText("<div id='target'><div id='child'>abc", "ABC",
+ "text-transform applied to child element", function() {
+ setStyle("child", "text-transform", "uppercase");
+ });
+testText("<div id='parent'><div id='target'>abc", "ABC",
+ "text-transform applied to parent element", function() {
+ setStyle("parent", "text-transform", "uppercase");
+ });
+
+testText("<div id='target'>abc<div id='child'>def", "abc",
+ "display: none applied to child element", function() {
+ setStyle("child", "display", "none");
+ });
+testText("<div id='parent'>invisible<div id='target'>abc", "abc",
+ "display: none applied to parent element", function() {
+ setStyle("parent", "display", "none");
+ });
+
+testText("<div id='target'>abc", "abc\ndef",
+ "insert node into sub-tree", function() {
+ let el = document.getElementById("target");
+ if (el) {
+ let c = document.createTextNode("def");
+ let d = document.createElement("div");
+ d.appendChild(c);
+ el.appendChild(d);
+ }
+ });
+
+testText("<div id='target'>abc<div id='remove'>def", "abc",
+ "remove node from sub-tree", function() {
+ let el = document.getElementById("target");
+ let victim = document.getElementById("remove");
+ if (el && victim) {
+ el.removeChild(victim);
+ }
+ });
+
+testText("<div id='target'>", "abcdef",
+ "insert whole sub-tree", function() {
+ var el = document.getElementById("target");
+ if (el) {
+ var def = document.createTextNode("def");
+ var s = document.createElement("span");
+ s.appendChild(def);
+
+ var abc = document.createTextNode("abc");
+ var d = document.createElement("div");
+ d.appendChild(abc);
+ d.appendChild(s);
+ el.appendChild(d);
+ }
+ });
+</script>
diff --git a/testing/web-platform/tests/html/dom/elements/the-innertext-and-outertext-properties/getter-first-letter-marker-multicol.html b/testing/web-platform/tests/html/dom/elements/the-innertext-and-outertext-properties/getter-first-letter-marker-multicol.html
new file mode 100644
index 0000000000..3b579dca1c
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/the-innertext-and-outertext-properties/getter-first-letter-marker-multicol.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<title>Test innerText/outerText for a combination of a list item with ::first-letter in multicol</title>
+<link rel="help" href="https://html.spec.whatwg.org/multipage/dom.html#dom-innertext">
+<link rel="help" href="https://crbug.com/1174985">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<style>
+ #item { display: list-item; }
+ #item::first-letter { background: lime; }
+ .col { column-count: 1; }
+</style>
+<div id="item" class="col"><div class="col">PASS</div></div>
+<script>
+ test(() => {
+ assert_equals(item.innerText, "PASS", "innerText");
+ assert_equals(item.outerText, "PASS", "outerText");
+ }, "");
+</script>
diff --git a/testing/web-platform/tests/html/dom/elements/the-innertext-and-outertext-properties/getter-tests.js b/testing/web-platform/tests/html/dom/elements/the-innertext-and-outertext-properties/getter-tests.js
new file mode 100644
index 0000000000..fd32e8d69a
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/the-innertext-and-outertext-properties/getter-tests.js
@@ -0,0 +1,401 @@
+testText("<div>abc", "abc", "Simplest possible test");
+
+/**** white-space:normal ****/
+
+testText("<div> abc", "abc", "Leading whitespace removed");
+testText("<div>abc ", "abc", "Trailing whitespace removed");
+testText("<div>abc def", "abc def", "Internal whitespace compressed");
+testText("<div>abc\ndef", "abc def", "\\n converted to space");
+testText("<div>abc\rdef", "abc def", "\\r converted to space");
+testText("<div>abc\tdef", "abc def", "\\t converted to space");
+testText("<div>abc <br>def", "abc\ndef", "Trailing whitespace before hard line break removed");
+testText("<div>abc<br> def", "abc\ndef", "Leading whitespace after hard line break removed");
+
+/**** <pre> ****/
+
+testText("<pre> abc", " abc", "Leading whitespace preserved");
+testText("<pre>abc ", "abc ", "Trailing whitespace preserved");
+testText("<pre>abc def", "abc def", "Internal whitespace preserved");
+testText("<pre>abc\ndef", "abc\ndef", "\\n preserved");
+testText("<pre>abc\rdef", "abc\ndef", "\\r converted to newline");
+testText("<pre>abc\tdef", "abc\tdef", "\\t preserved");
+testText("<div><pre>abc</pre><pre>def</pre>", "abc\ndef", "Two <pre> siblings");
+
+/**** <div style="white-space:pre"> ****/
+
+testText("<div style='white-space:pre'> abc", " abc", "Leading whitespace preserved");
+testText("<div style='white-space:pre'>abc ", "abc ", "Trailing whitespace preserved");
+testText("<div style='white-space:pre'>abc def", "abc def", "Internal whitespace preserved");
+testText("<div style='white-space:pre'>abc\ndef", "abc\ndef", "\\n preserved");
+testText("<div style='white-space:pre'>abc\rdef", "abc\ndef", "\\r converted to newline");
+testText("<div style='white-space:pre'>abc\tdef", "abc\tdef", "\\t preserved");
+
+/**** <span style="white-space:pre"> ****/
+
+testText("<span style='white-space:pre'> abc", " abc", "Leading whitespace preserved");
+testText("<span style='white-space:pre'>abc ", "abc ", "Trailing whitespace preserved");
+testText("<span style='white-space:pre'>abc def", "abc def", "Internal whitespace preserved");
+testText("<span style='white-space:pre'>abc\ndef", "abc\ndef", "\\n preserved");
+testText("<span style='white-space:pre'>abc\rdef", "abc\ndef", "\\r converted to newline");
+testText("<span style='white-space:pre'>abc\tdef", "abc\tdef", "\\t preserved");
+
+/**** <div style="white-space:pre-line"> ****/
+
+testText("<div style='white-space:pre-line'> abc", "abc", "Leading whitespace removed");
+testText("<div style='white-space:pre-line'>abc ", "abc", "Trailing whitespace removed");
+testText("<div style='white-space:pre-line'>abc def", "abc def", "Internal whitespace collapsed");
+testText("<div style='white-space:pre-line'>abc\ndef", "abc\ndef", "\\n preserved");
+testText("<div style='white-space:pre-line'>abc\rdef", "abc\ndef", "\\r converted to newline");
+testText("<div style='white-space:pre-line'>abc\tdef", "abc def", "\\t converted to space");
+
+/**** Collapsing whitespace across element boundaries ****/
+
+testText("<div><span>abc </span> def", "abc def", "Whitespace collapses across element boundaries");
+testText("<div><span>abc </span><span></span> def", "abc def", "Whitespace collapses across element boundaries");
+testText("<div><span>abc </span><span style='white-space:pre'></span> def", "abc def", "Whitespace collapses across element boundaries");
+testText("<div>abc <input> def", "abc def", "Whitespace around <input> should not be collapsed");
+testText("<div>abc <span style='display:inline-block'></span> def", "abc def", "Whitespace around inline-block should not be collapsed");
+testText("<div>abc <span style='display:inline-block'> def </span> ghi", "abc def ghi", "Trailing space at end of inline-block should be collapsed");
+testText("<div><input> <div>abc</div>", "abc", "Whitespace between <input> and block should be collapsed");
+testText("<div><span style='inline-block'></span> <div>abc</div>", "abc", "Whitespace between inline-block and block should be collapsed");
+testText("<div>abc <img> def", "abc def", "Whitespace around <img> should not be collapsed");
+testText("<div>abc <img width=1 height=1> def", "abc def", "Whitespace around <img> should not be collapsed");
+testText("<div><img> abc", " abc", "Leading whitesapce should not be collapsed");
+testText("<div>abc <img>", "abc ", "Trailing whitesapce should not be collapsed");
+testText("<div>abc <b></b> def", "abc def", "Whitespace around empty span should be collapsed");
+testText("<div>abc <b><i></i></b> def", "abc def", "Whitespace around empty spans should be collapsed");
+testText("<div><canvas></canvas> abc", " abc", "<canvas> should not collapse following space");
+testText("<div>abc <img style='display:block'> def", "abc\ndef", "Replaced element <img> with display:block should be treated as block-level");
+testText("<div>abc <canvas style='display:block'></canvas> def", "abc\ndef", "Replaced element <canvas> with display:block should be treated as block-level");
+
+/**** Soft line breaks ****/
+
+testText("<div style='width:0'>abc def", "abc def", "Soft line breaks ignored");
+testText("<div style='width:0'>abc-def", "abc-def", "Soft line break at hyphen ignored");
+testText("<div style='width:0'><span>abc</span> <span>def</span>", "abc def", "Whitespace text node preserved");
+
+/**** Soft line breaks when word-break:break-word is in effect ****/
+/* (based on Testcase #2 at https://bugzilla.mozilla.org/show_bug.cgi?id=1241631) */
+
+testText("<div style='width:1px; word-break:break-word'>Hello Kitty</div>", "Hello Kitty", "Soft breaks ignored in presence of word-break:break-word");
+testText("<div style='width:1px; word-break:break-word'><x>Hello</x> <x>Kitty</x></div>", "Hello Kitty", "Element boundaries ignored for soft break handling (1)");
+testText("<div style='width:1px; word-break:break-word'><x>Hello</x> <x> Kitty</x></div>", "Hello Kitty", "Whitespace collapses across element boundaries at soft break (1)");
+testText("<div style='width:1px; word-break:break-word'><x>Hello</x><x> Kitty</x></div>", "Hello Kitty", "Element boundaries ignored for soft break handling (2)");
+testText("<div style='width:1px; word-break:break-word'><x>Hello </x> <x>Kitty</x></div>", "Hello Kitty", "Whitespace collapses across element boundaries at soft break (2)");
+testText("<div style='width:1px; word-break:break-word'><x>Hello </x><x>Kitty</x></div>", "Hello Kitty", "Element boundaries ignored for soft break handling (3)");
+testText("<div style='width:1px; word-break:break-word'><x>Hello </x><x> Kitty</x></div>", "Hello Kitty", "Whitespace collapses across element boundaries at soft break (3)");
+testText("<div style='width:1px; word-break:break-word'><x>Hello </x> <x> Kitty</x></div>", "Hello Kitty", "Whitespace collapses across element boundaries at soft break (4)");
+testText("<div style='width:1px; word-break:break-word'><x>Hello</x> Kitty</div>", "Hello Kitty", "Element boundaries ignored for soft break handling (4)");
+testText("<div style='width:1px; word-break:break-word'><x>Hello </x>Kitty</div>", "Hello Kitty", "Element boundaries ignored for soft break handling (5)");
+testText("<div style='width:1px; word-break:break-word; text-transform:uppercase'>Hello Kitty</div>", "HELLO KITTY", "Soft breaks ignored, text-transform applied");
+testText("<div style='width:1px; word-break:break-word'>Hello<br> Kitty</div>", "Hello\nKitty", "<br> returned as newline, following space collapsed");
+testText("<div style='width:1px; word-break:break-word'>Hello <br>Kitty</div>", "Hello\nKitty", "<br> returned as newline, preceding space collapsed");
+testText("<div style='width:1px; word-break:break-word'><x>Hello </x> <br> <x> Kitty</x></div>", "Hello\nKitty", "<br> returned as newline, adjacent spaces collapsed across element boundaries");
+
+/**** first-line/first-letter ****/
+
+testText("<div class='first-line-uppercase' style='width:0'>abc def", "ABC def", "::first-line styles applied");
+testText("<div class='first-letter-uppercase' style='width:0'>abc def", "Abc def", "::first-letter styles applied");
+testText("<div class='first-letter-float' style='width:0'>abc def", "abc def", "::first-letter float ignored");
+
+/**** &nbsp; ****/
+
+testText("<div>&nbsp;", "\xA0", "&nbsp; preserved");
+
+/**** display:none ****/
+
+testText("<div style='display:none'>abc", "abc", "display:none container");
+testText("<div style='display:none'>abc def", "abc def", "No whitespace compression in display:none container");
+testText("<div style='display:none'> abc def ", " abc def ", "No removal of leading/trailing whitespace in display:none container");
+testText("<div>123<span style='display:none'>abc", "123", "display:none child not rendered");
+testText("<div style='display:none'><span id='target'>abc", "abc", "display:none container with non-display-none target child");
+testTextInSVG("<div id='target'>abc", "abc", "non-display-none child of svg");
+testTextInSVG("<div style='display:none' id='target'>abc", "abc", "display:none child of svg");
+testTextInSVG("<div style='display:none'><div id='target'>abc", "abc", "child of display:none child of svg");
+
+/**** display:contents ****/
+
+if (CSS.supports("display", "contents")) {
+ testText("<div style='display:contents'>abc", "abc", "display:contents container");
+ testText("<div><div style='display:contents'>abc", "abc", "display:contents container");
+ testText("<div>123<span style='display:contents'>abc", "123abc", "display:contents rendered");
+ testText("<div style='display:contents'> ", "", "display:contents not processed via textContent");
+ testText("<div><div style='display:contents'> ", "", "display:contents not processed via textContent");
+}
+
+/**** visibility:hidden ****/
+
+testText("<div style='visibility:hidden'>abc", "", "visibility:hidden container");
+testText("<div>123<span style='visibility:hidden'>abc", "123", "visibility:hidden child not rendered");
+testText("<div style='visibility:hidden'>123<span style='visibility:visible'>abc", "abc", "visibility:visible child rendered");
+
+/**** visibility:collapse ****/
+
+testText("<table><tbody style='visibility:collapse'><tr><td>abc", "", "visibility:collapse row-group");
+testText("<table><tr style='visibility:collapse'><td>abc", "", "visibility:collapse row");
+testText("<table><tr><td style='visibility:collapse'>abc", "", "visibility:collapse cell");
+testText("<table><tbody style='visibility:collapse'><tr><td style='visibility:visible'>abc", "abc",
+ "visibility:collapse row-group with visible cell");
+testText("<table><tr style='visibility:collapse'><td style='visibility:visible'>abc", "abc",
+ "visibility:collapse row with visible cell");
+testText("<div style='display:flex'><span style='visibility:collapse'>1</span><span>2</span></div>",
+ "2", "visibility:collapse honored on flex item");
+testText("<div style='display:grid'><span style='visibility:collapse'>1</span><span>2</span></div>",
+ "2", "visibility:collapse honored on grid item");
+
+/**** opacity:0 ****/
+
+testText("<div style='opacity:0'>abc", "abc", "opacity:0 container");
+testText("<div style='opacity:0'>abc def", "abc def", "Whitespace compression in opacity:0 container");
+testText("<div style='opacity:0'> abc def ", "abc def", "Remove leading/trailing whitespace in opacity:0 container");
+testText("<div>123<span style='opacity:0'>abc", "123abc", "opacity:0 child rendered");
+
+/**** generated content ****/
+
+testText("<div class='before'>", "", "Generated content not included");
+testText("<div><div class='before'>", "", "Generated content on child not included");
+
+/**** innerText on replaced elements ****/
+
+testText("<button>abc", "abc", "<button> contents preserved");
+testText("<fieldset>abc", "abc", "<fieldset> contents preserved");
+testText("<fieldset><legend>abc", "abc", "<fieldset> <legend> contents preserved");
+testText("<input type='text' value='abc'>", "", "<input> contents ignored");
+testText("<textarea>abc", "", "<textarea> contents ignored");
+testText("<iframe>abc", "", "<iframe> contents ignored");
+testText("<iframe><div id='target'>abc", "", "<iframe> contents ignored");
+testText("<iframe src='data:text/html,abc'>", "","<iframe> subdocument ignored");
+testText("<audio style='display:block'>abc", "", "<audio> contents ignored");
+testText("<audio style='display:block'><source id='target' class='poke' style='display:block'>", "abc", "<audio> contents ok for element not being rendered");
+testText("<audio style='display:block'><source id='target' class='poke' style='display:none'>", "abc", "<audio> contents ok for element not being rendered");
+testText("<video>abc", "", "<video> contents ignored");
+testText("<video style='display:block'><source id='target' class='poke' style='display:block'>", "abc", "<video> contents ok for element not being rendered");
+testText("<video style='display:block'><source id='target' class='poke' style='display:none'>", "abc", "<video> contents ok for element not being rendered");
+testText("<canvas>abc", "", "<canvas> contents ignored");
+testText("<canvas><div id='target'>abc", "abc", "<canvas><div id='target'> contents ok for element not being rendered");
+testText("<img alt='abc'>", "", "<img> alt text ignored");
+testText("<img src='about:blank' class='poke'>", "", "<img> contents ignored");
+testText("<div><svg><text>abc</text></svg></div>", "abc", "<svg> text contents preserved");
+testText("<div><svg><defs><text>abc</text></defs></svg></div>", "", "<svg><defs> text contents ignored");
+testText("<div><svg><stop>abc</stop></svg></div>", "", "<svg> non-rendered text ignored");
+testText("<svg><foreignObject><span id='target'>abc</span></foreignObject></svg>", "abc", "<foreignObject> contents preserved");
+
+/**** <select>, <optgroup> & <option> ****/
+
+testText("<select size='1'><option>abc</option><option>def", "abc\ndef", "<select size='1'> contents of options preserved");
+testText("<select size='2'><option>abc</option><option>def", "abc\ndef", "<select size='2'> contents of options preserved");
+testText("<select size='1'><option id='target'>abc</option><option>def", "abc", "<select size='1'> contents of target option preserved");
+testText("<select size='2'><option id='target'>abc</option><option>def", "abc", "<select size='2'> contents of target option preserved");
+testText("<div>a<select></select>bc", "abc", "empty <select>");
+testText("<div>a<select><optgroup></select>bc", "a\nbc", "empty <optgroup> in <select>");
+testText("<div>a<select><option></select>bc", "a\nbc", "empty <option> in <select>");
+testText("<select class='poke'></select>", "", "<select> containing text node child");
+testText("<select><optgroup class='poke-optgroup'></select>", "", "<optgroup> containing <optgroup>");
+testText("<select><optgroup><option>abc</select>", "abc", "<optgroup> containing <option>");
+testText("<select><option class='poke-div'>123</select>", "123\nabc", "<div> in <option>");
+testText("<div>a<optgroup></optgroup>bc", "a\nbc", "empty <optgroup> in <div>");
+testText("<div>a<optgroup>123</optgroup>bc", "a\nbc", "<optgroup> in <div>");
+testText("<div>a<option></option>bc", "a\nbc", "empty <option> in <div>");
+testText("<div>a<option>123</option>bc", "a\n123\nbc", "<option> in <div>");
+
+/**** innerText on replaced element children ****/
+
+testText("<div><button>abc", "abc", "<button> contents preserved");
+testText("<div><fieldset>abc", "abc", "<fieldset> contents preserved");
+testText("<div><fieldset><legend>abc", "abc", "<fieldset> <legend> contents preserved");
+testText("<div><input type='text' value='abc'>", "", "<input> contents ignored");
+testText("<div><textarea>abc", "", "<textarea> contents ignored");
+testText("<div><select size='1'><option>abc</option><option>def", "abc\ndef", "<select size='1'> contents of options preserved");
+testText("<div><select size='2'><option>abc</option><option>def", "abc\ndef", "<select size='2'> contents of options preserved");
+testText("<div><iframe>abc", "", "<iframe> contents ignored");
+testText("<div><iframe src='data:text/html,abc'>", ""," <iframe> subdocument ignored");
+testText("<div><audio>abc", "", "<audio> contents ignored");
+testText("<div><video>abc", "", "<video> contents ignored");
+testText("<div><canvas>abc", "", "<canvas> contents ignored");
+testText("<div><img alt='abc'>", "", "<img> alt text ignored");
+
+/**** Lines around blocks ****/
+
+testText("<div>123<div>abc</div>def", "123\nabc\ndef", "Newline at block boundary");
+testText("<div>123<span style='display:block'>abc</span>def", "123\nabc\ndef", "Newline at display:block boundary");
+testText("<div>abc<div></div>def", "abc\ndef", "Empty block induces single line break");
+testText("<div>abc<div></div><div></div>def", "abc\ndef", "Consecutive empty blocks ignored");
+testText("<div><p>abc", "abc", "No blank lines around <p> alone");
+testText("<div><p>abc</p> ", "abc", "No blank lines around <p> followed by only collapsible whitespace");
+testText("<div> <p>abc</p>", "abc", "No blank lines around <p> preceded by only collapsible whitespace");
+testText("<div><p>abc<p>def", "abc\n\ndef", "Blank line between consecutive <p>s");
+testText("<div><p>abc</p> <p>def", "abc\n\ndef", "Blank line between consecutive <p>s separated only by collapsible whitespace");
+testText("<div><p>abc</p><div></div><p>def", "abc\n\ndef", "Blank line between consecutive <p>s separated only by empty block");
+testText("<div><p>abc</p><div>123</div><p>def", "abc\n\n123\n\ndef", "Blank lines between <p>s separated by non-empty block");
+testText("<div>abc<div><p>123</p></div>def", "abc\n\n123\n\ndef", "Blank lines around a <p> in its own block");
+testText("<div>abc<p>def", "abc\n\ndef", "Blank line before <p>");
+testText("<div><p>abc</p>def", "abc\n\ndef", "Blank line after <p>");
+testText("<div><p>abc<p></p><p></p><p>def", "abc\n\ndef", "One blank line between <p>s, ignoring empty <p>s");
+testText("<div style='visibility:hidden'><p><span style='visibility:visible'>abc</span></p>\n<div style='visibility:visible'>def</div>",
+ "abc\ndef", "Invisible <p> doesn't induce extra line breaks");
+testText("<div>abc<div style='margin:2em'>def", "abc\ndef", "No blank lines around <div> with margin");
+testText("<div>123<span style='display:inline-block'>abc</span>def", "123abcdef", "No newlines at display:inline-block boundary");
+testText("<div>123<span style='display:inline-block'> abc </span>def", "123abcdef", "Leading/trailing space removal at display:inline-block boundary");
+testText("<div>123<p style='margin:0px'>abc</p>def", "123\n\nabc\n\ndef", "Blank lines around <p> even without margin");
+testText("<div>123<h1>abc</h1>def", "123\nabc\ndef", "No blank lines around <h1>");
+testText("<div>123<h2>abc</h2>def", "123\nabc\ndef", "No blank lines around <h2>");
+testText("<div>123<h3>abc</h3>def", "123\nabc\ndef", "No blank lines around <h3>");
+testText("<div>123<h4>abc</h4>def", "123\nabc\ndef", "No blank lines around <h4>");
+testText("<div>123<h5>abc</h5>def", "123\nabc\ndef", "No blank lines around <h5>");
+testText("<div>123<h6>abc</h6>def", "123\nabc\ndef", "No blank lines around <h6>");
+
+/**** Spans ****/
+
+testText("<div>123<span>abc</span>def", "123abcdef", "<span> boundaries are irrelevant");
+testText("<div>123 <span>abc</span> def", "123 abc def", "<span> boundaries are irrelevant");
+testText("<div style='width:0'>123 <span>abc</span> def", "123 abc def", "<span> boundaries are irrelevant");
+testText("<div>123<em>abc</em>def", "123abcdef", "<em> gets no special treatment");
+testText("<div>123<b>abc</b>def", "123abcdef", "<b> gets no special treatment");
+testText("<div>123<i>abc</i>def", "123abcdef", "<i> gets no special treatment");
+testText("<div>123<strong>abc</strong>def", "123abcdef", "<strong> gets no special treatment");
+testText("<div>123<tt>abc</tt>def", "123abcdef", "<tt> gets no special treatment");
+testText("<div>123<code>abc</code>def", "123abcdef", "<code> gets no special treatment");
+
+/**** Soft hyphen ****/
+
+testText("<div>abc&shy;def", "abc\xADdef", "soft hyphen preserved");
+testText("<div style='width:0'>abc&shy;def", "abc\xADdef", "soft hyphen preserved");
+
+/**** Tables ****/
+
+testText("<div><table style='white-space:pre'> <td>abc</td> </table>", "abc", "Ignoring non-rendered table whitespace");
+testText("<div><table><tr><td>abc<td>def</table>", "abc\tdef", "Tab-separated table cells");
+testText("<div><table><tr><td>abc<td><td>def</table>", "abc\t\tdef", "Tab-separated table cells including empty cells");
+testText("<div><table><tr><td>abc<td><td></table>", "abc\t\t", "Tab-separated table cells including trailing empty cells");
+testText("<div><table><tr><td>abc<tr><td>def</table>", "abc\ndef", "Newline-separated table rows");
+testText("<div>abc<table><td>def</table>ghi", "abc\ndef\nghi", "Newlines around table");
+testText("<div><table style='border-collapse:collapse'><tr><td>abc<td>def</table>", "abc\tdef",
+ "Tab-separated table cells in a border-collapse table");
+testText("<div><table><tfoot>x</tfoot><tbody>y</tbody></table>", "xy", "tfoot not reordered");
+testText("<table><tfoot><tr><td>footer</tfoot><thead><tr><td style='visibility:collapse'>thead</thead><tbody><tr><td>tbody</tbody></table>",
+ "footer\n\ntbody", "");
+testText("<table><tr><td id=target>abc</td><td>def</td>", "abc", "No tab on table-cell itself");
+testText("<table><tr id=target><td>abc</td><td>def</td></tr><tr id=target><td>ghi</td><td>jkl</td></tr>", "abc\tdef", "No newline on table-row itself");
+
+/**** Table captions ****/
+
+testText("<div><table><tr><td>abc<caption>def</caption></table>", "abc\ndef", "Newline between cells and caption");
+
+/**** display:table ****/
+
+testText("<div><div class='table'><span class='cell'>abc</span>\n<span class='cell'>def</span></div>",
+ "abc\tdef", "Tab-separated table cells");
+testText("<div><div class='table'><span class='row'><span class='cell'>abc</span></span>\n<span class='row'><span class='cell'>def</span></span></div>",
+ "abc\ndef", "Newline-separated table rows");
+testText("<div>abc<div class='table'><span class='cell'>def</span></div>ghi", "abc\ndef\nghi", "Newlines around table");
+
+/**** display:inline-table ****/
+
+testText("<div><div class='itable'><span class='cell'>abc</span>\n<span class='cell'>def</span></div>", "abc\tdef", "Tab-separated table cells");
+testText("<div><div class='itable'><span class='row'><span class='cell'>abc</span></span>\n<span class='row'><span class='cell'>def</span></span></div>",
+ "abc\ndef", "Newline-separated table rows");
+testText("<div>abc<div class='itable'><span class='cell'>def</span></div>ghi", "abcdefghi", "No newlines around inline-table");
+testText("<div>abc<div class='itable'><span class='row'><span class='cell'>def</span></span>\n<span class='row'><span class='cell'>123</span></span></div>ghi",
+ "abcdef\n123ghi", "Single newline in two-row inline-table");
+
+/**** display:table-row/table-cell/table-caption ****/
+testText("<div style='display:table-row'>", "", "display:table-row on the element itself");
+testText("<div style='display:table-cell'>", "", "display:table-cell on the element itself");
+testText("<div style='display:table-caption'>", "", "display:table-caption on the element itself");
+
+/**** Lists ****/
+
+testText("<div><ol><li>abc", "abc", "<ol> list items get no special treatment");
+testText("<div><ul><li>abc", "abc", "<ul> list items get no special treatment");
+
+/**** Misc elements ****/
+
+testText("<div><script style='display:block'>abc", "abc", "display:block <script> is rendered");
+testText("<div><style style='display:block'>abc", "abc", "display:block <style> is rendered");
+testText("<div><noscript style='display:block'>abc", "", "display:block <noscript> is not rendered (it's not parsed!)");
+testText("<div><template style='display:block'>abc", "",
+ "display:block <template> contents are not rendered (the contents are in a different document)");
+testText("<div>abc<br>def", "abc\ndef", "<br> induces line break");
+testText("<div>abc<br>", "abc\n", "<br> induces line break even at end of block");
+testText("<div><br class='poke'>", "\n", "<br> content ignored");
+testText("<div>abc<hr>def", "abc\ndef", "<hr> induces line break");
+testText("<div>abc<hr><hr>def", "abc\ndef", "<hr><hr> induces just one line break");
+testText("<div>abc<hr><hr><hr>def", "abc\ndef", "<hr><hr><hr> induces just one line break");
+testText("<div><hr class='poke'>", "abc", "<hr> content rendered");
+testText("<div>abc<!--comment-->def", "abcdef", "comment ignored");
+testText("<br>", "", "<br>");
+testText("<p>", "", "empty <p>");
+testText("<div>", "", "empty <div>");
+
+/**** text-transform ****/
+
+testText("<div><div style='text-transform:uppercase'>abc", "ABC", "text-transform is applied");
+testText("<div><div style='text-transform:uppercase'>Ma\xDF", "MASS", "text-transform handles es-zet");
+testText("<div><div lang='tr' style='text-transform:uppercase'>i \u0131", "\u0130 I", "text-transform handles Turkish casing");
+
+/**** block-in-inline ****/
+
+testText("<div>abc<span>123<div>456</div>789</span>def", "abc123\n456\n789def", "block-in-inline doesn't add unnecessary newlines");
+
+/**** floats ****/
+
+testText("<div>abc<div style='float:left'>123</div>def", "abc\n123\ndef", "floats induce a block boundary");
+testText("<div>abc<span style='float:left'>123</span>def", "abc\n123\ndef", "floats induce a block boundary");
+testText("<div style='float:left'>123", "123", "float on the element itself");
+
+/**** position ****/
+
+testText("<div>abc<div style='position:absolute'>123</div>def", "abc\n123\ndef", "position:absolute induces a block boundary");
+testText("<div>abc<span style='position:absolute'>123</span>def", "abc\n123\ndef", "position:absolute induces a block boundary");
+testText("<div style='position:absolute'>123", "123", "position:absolute on the element itself");
+testText("<div>abc<div style='position:relative'>123</div>def", "abc\n123\ndef", "position:relative has no effect");
+testText("<div>abc<span style='position:relative'>123</span>def", "abc123def", "position:relative has no effect");
+
+/**** text-overflow:ellipsis ****/
+
+testText("<div style='overflow:hidden'>abc", "abc", "overflow:hidden ignored");
+// XXX Chrome skips content with width:0 or height:0 and overflow:hidden;
+// should we spec that?
+testText("<div style='width:0; overflow:hidden'>abc", "abc", "overflow:hidden ignored even with zero width");
+testText("<div style='height:0; overflow:hidden'>abc", "abc", "overflow:hidden ignored even with zero height");
+testText("<div style='width:0; overflow:hidden; text-overflow:ellipsis'>abc", "abc", "text-overflow:ellipsis ignored");
+
+/**** Support on non-HTML elements ****/
+
+testText("<svg>abc", undefined, "innerText not supported on SVG elements");
+testText("<math>abc", undefined, "innerText not supported on MathML elements");
+
+/**** Ruby ****/
+
+testText("<div><ruby>abc<rt>def</rt></ruby>", "abcdef", "<rt> and no <rp>");
+testText("<div><ruby>abc<rp>(</rp><rt>def</rt><rp>)</rp></ruby>", "abcdef", "<rp>");
+testText("<div><rp>abc</rp>", "", "Lone <rp>");
+testText("<div><rp style='visibility:hidden'>abc</rp>", "", "visibility:hidden <rp>");
+testText("<div><rp style='display:block'>abc</rp>def", "abc\ndef", "display:block <rp>");
+testText("<div><rp style='display:block'> abc </rp>def", "abc\ndef", "display:block <rp> with whitespace");
+testText("<div><select class='poke-rp'></select>", "", "<rp> in a <select>");
+
+/**** Shadow DOM ****/
+
+if ("attachShadow" in document.body) {
+ testText("<div class='shadow'>", "", "Shadow DOM contents ignored");
+ testText("<div><div class='shadow'>", "", "Shadow DOM contents ignored");
+}
+
+/**** Flexbox ****/
+
+if (CSS.supports('display', 'flex')) {
+ testText("<div style='display:flex'><div style='order:1'>1</div><div>2</div></div>",
+ "1\n2", "CSS 'order' property ignored");
+ testText("<div style='display:flex'><span>1</span><span>2</span></div>",
+ "1\n2", "Flex items blockified");
+}
+
+/**** Grid ****/
+
+if (CSS.supports('display', 'grid')) {
+ testText("<div style='display:grid'><div style='order:1'>1</div><div>2</div></div>",
+ "1\n2", "CSS 'order' property ignored");
+ testText("<div style='display:grid'><span>1</span><span>2</span></div>",
+ "1\n2", "Grid items blockified");
+}
diff --git a/testing/web-platform/tests/html/dom/elements/the-innertext-and-outertext-properties/getter.html b/testing/web-platform/tests/html/dom/elements/the-innertext-and-outertext-properties/getter.html
new file mode 100644
index 0000000000..ffb3d34fe9
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/the-innertext-and-outertext-properties/getter.html
@@ -0,0 +1,64 @@
+<!DOCTYPE html>
+<title>innerText/outerText getter test</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<style>
+.before::before { content:'abc'; }
+.table { display:table; }
+.itable { display:inline-table; }
+.row { display:table-row; }
+.cell { display:table-cell; }
+.first-line-uppercase::first-line { text-transform:uppercase; }
+.first-letter-uppercase::first-letter { text-transform:uppercase; }
+.first-letter-float::first-letter { float:left; }
+</style>
+<div id="container"></div>
+<svg id="svgContainer"></svg>
+<script>
+let container = document.querySelector('#container');
+let svgContainer = document.querySelector('#svgContainer');
+function testText(html, expectedPlain, msg) {
+ textTextInContainer(container, html, expectedPlain, msg);
+}
+function testTextInSVG(html, expectedPlain, msg) {
+ textTextInContainer(svgContainer, html, expectedPlain, msg);
+}
+function textTextInContainer(cont, html, expectedPlain, msg) {
+ test(function() {
+ container.innerHTML = html;
+ if (cont != container) {
+ while (container.firstChild) {
+ cont.appendChild(container.firstChild);
+ }
+ }
+ var e = document.getElementById('target');
+ if (!e) {
+ e = cont.firstChild;
+ }
+ var pokes = document.getElementsByClassName('poke');
+ for (var i = 0; i < pokes.length; ++i) {
+ pokes[i].textContent = 'abc';
+ }
+ ['rp', 'optgroup', 'div'].forEach(function(tag) {
+ pokes = document.getElementsByClassName('poke-' + tag);
+ for (var i = 0; i < pokes.length; ++i) {
+ var el = document.createElement(tag);
+ el.textContent = "abc";
+ pokes[i].appendChild(el);
+ }
+ });
+ var shadows = document.getElementsByClassName('shadow');
+ for (var i = 0; i < shadows.length; ++i) {
+ var s = shadows[i].attachShadow({ mode: "open" });
+ s.textContent = 'abc';
+ }
+ while (e && e.nodeType != Node.ELEMENT_NODE) {
+ e = e.nextSibling;
+ }
+ assert_equals(e.innerText, expectedPlain, "innerText");
+ assert_equals(e.outerText, expectedPlain, "outerText");
+ cont.textContent = '';
+ }, msg + ' (' + format_value(html) + ')');
+}
+</script>
+<script src="getter-tests.js"></script>
diff --git a/testing/web-platform/tests/html/dom/elements/the-innertext-and-outertext-properties/innertext-domnoderemoved-crash.html b/testing/web-platform/tests/html/dom/elements/the-innertext-and-outertext-properties/innertext-domnoderemoved-crash.html
new file mode 100644
index 0000000000..94043caf69
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/the-innertext-and-outertext-properties/innertext-domnoderemoved-crash.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<link rel=author href="mailto:jarhar@chromium.org">
+<link rel=help href="https://bugs.chromium.org/p/chromium/issues/detail?id=1411135">
+
+<div id=parentelement><div id=childelement>hello world</div></div>
+
+<script>
+ let removed = false;
+ childelement.addEventListener('DOMNodeRemoved', () => {
+ if (!removed) {
+ removed = true;
+ childelement.remove();
+ }
+ });
+ parentelement.innerText = 'hello world';
+</script>
diff --git a/testing/web-platform/tests/html/dom/elements/the-innertext-and-outertext-properties/innertext-setter-tests.js b/testing/web-platform/tests/html/dom/elements/the-innertext-and-outertext-properties/innertext-setter-tests.js
new file mode 100644
index 0000000000..99ae5ec185
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/the-innertext-and-outertext-properties/innertext-setter-tests.js
@@ -0,0 +1,42 @@
+testText("<div>", "abc", "abc", "Simplest possible test");
+testHTML("<div>", "abc\ndef", "abc<br>def", "Newlines convert to <br> in non-white-space:pre elements");
+testHTML("<pre>", "abc\ndef", "abc<br>def", "Newlines convert to <br> in <pre> element");
+testHTML("<textarea>", "abc\ndef", "abc<br>def", "Newlines convert to <br> in <textarea> element");
+testHTML("<div style='white-space:pre'>", "abc\ndef", "abc<br>def", "Newlines convert to <br> in white-space:pre element");
+testHTML("<div>", "abc\rdef", "abc<br>def", "CRs convert to <br> in non-white-space:pre elements");
+testHTML("<pre>", "abc\rdef", "abc<br>def", "CRs convert to <br> in <pre> element");
+testHTML("<div>", "abc\r\ndef", "abc<br>def", "Newline/CR pair converts to <br> in non-white-space:pre element");
+testHTML("<div>", "abc\n\ndef", "abc<br><br>def", "Newline/newline pair converts to two <br>s in non-white-space:pre element");
+testHTML("<div>", "abc\r\rdef", "abc<br><br>def", "CR/CR pair converts to two <br>s in non-white-space:pre element");
+testHTML("<div style='white-space:pre'>", "abc\rdef", "abc<br>def", "CRs convert to <br> in white-space:pre element");
+testText("<div>", "abc<def", "abc<def", "< preserved");
+testText("<div>", "abc>def", "abc>def", "> preserved");
+testText("<div>", "abc&", "abc&", "& preserved");
+testText("<div>", "abc\"def", "abc\"def", "\" preserved");
+testText("<div>", "abc\'def", "abc\'def", "\' preserved");
+testHTML("<svg>", "abc", "", "innerText not supported on SVG elements");
+testHTML("<math>", "abc", "", "innerText not supported on MathML elements");
+testText("<div>", "abc\0def", "abc\0def", "Null characters preserved");
+testText("<div>", "abc\tdef", "abc\tdef", "Tabs preserved");
+testText("<div>", " abc", " abc", "Leading whitespace preserved");
+testText("<div>", "abc ", "abc ", "Trailing whitespace preserved");
+testText("<div>", "abc def", "abc def", "Whitespace not compressed");
+testText("<div>abc\n\n", "abc", "abc", "Existing text deleted");
+testText("<div><br>", "abc", "abc", "Existing <br> deleted");
+testHTML("<div>", "", "", "Assigning the empty string");
+testHTML("<div>", null, "", "Assigning null");
+testHTML("<div>", undefined, "undefined", "Assigning undefined");
+testHTML("<div>", "\rabc", "<br>abc", "Start with CR");
+testHTML("<div>", "\nabc", "<br>abc", "Start with LF");
+testHTML("<div>", "\r\nabc", "<br>abc", "Start with CRLF");
+testHTML("<div>", "abc\r", "abc<br>", "End with CR");
+testHTML("<div>", "abc\n", "abc<br>", "End with LF");
+testHTML("<div>", "abc\r\n", "abc<br>", "End with CRLF");
+
+// Setting innerText on these should not throw
+["area", "base", "basefont", "bgsound", "br", "col", "embed", "frame", "hr",
+"image", "img", "input", "keygen", "link", "menuitem", "meta", "param",
+"source", "track", "wbr", "colgroup", "frameset", "head", "html", "table",
+"tbody", "tfoot", "thead", "tr"].forEach(function(tag) {
+ testText(document.createElement(tag), "abc", "abc", "innerText on <" + tag + "> element");
+});
diff --git a/testing/web-platform/tests/html/dom/elements/the-innertext-and-outertext-properties/innertext-setter.html b/testing/web-platform/tests/html/dom/elements/the-innertext-and-outertext-properties/innertext-setter.html
new file mode 100644
index 0000000000..a835a164ed
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/the-innertext-and-outertext-properties/innertext-setter.html
@@ -0,0 +1,88 @@
+<!DOCTYPE html>
+<title>innerText setter test</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="container"></div>
+<script>
+// As of March 2017, WebKit and Blink have inconsistent results depending on
+// rendered or not. setupTest() tests a rendered case, and setupTestDetached()
+// tests a not-rendered case.
+
+function setupTest(context, plain) {
+ var container = document.getElementById("container");
+ // context is either a string or an element node
+ if (typeof context === "string") {
+ container.innerHTML = context;
+ } else {
+ container.innerHTML = "";
+ container.appendChild(context);
+ }
+ var e = container.firstChild;
+ while (e && e.nodeType != Node.ELEMENT_NODE) {
+ e = e.nextSibling;
+ }
+ e.offsetWidth;
+ var oldChild = e.firstChild;
+ e.innerText = plain;
+ return [e, oldChild];
+}
+
+function setupTestDetached(context, plain) {
+ var detachedContainer = document.createElement("div");
+ // context is either a string or an element node
+ if (typeof context === "string") {
+ detachedContainer.innerHTML = context;
+ } else {
+ detachedContainer.innerHTML = "";
+ detachedContainer.appendChild(context);
+ }
+ var e = detachedContainer.firstChild;
+ while (e && e.nodeType != Node.ELEMENT_NODE) {
+ e = e.nextSibling;
+ }
+ var oldChild = e.firstChild;
+ e.innerText = plain;
+ return [e, oldChild];
+}
+
+function assertNewSingleTextNode(newChild, expectedText, oldChild) {
+ assert_not_equals(newChild, null, "Should have a child");
+ assert_equals(newChild.nodeType, Node.TEXT_NODE, "Child should be a text node");
+ assert_equals(newChild.nextSibling, null, "Should have only one child");
+ assert_equals(newChild.data, expectedText);
+ assert_not_equals(newChild, oldChild, "Child should be a *new* text node");
+}
+
+function assertNoEmptyTextChild(parent) {
+ for (var child = parent.firstChild; child; child = child.nextSibling) {
+ if (child.nodeType === Node.TEXT_NODE) {
+ assert_not_equals(child.data, "", "Should not have empty text nodes");
+ }
+ }
+}
+
+function testText(context, plain, expectedText, msg) {
+ test(function(){
+ var arr = setupTest(context, plain);
+ assertNewSingleTextNode(arr[0].firstChild, expectedText, arr[1]);
+ }, msg);
+ test(function() {
+ var arr = setupTestDetached(context, plain);
+ assertNewSingleTextNode(arr[0].firstChild, expectedText, arr[1]);
+ }, msg + ", detached");
+}
+
+function testHTML(context, plain, expectedHTML, msg) {
+ test(function(){
+ var e = setupTest(context, plain)[0];
+ assert_equals(e.innerHTML, expectedHTML);
+ assertNoEmptyTextChild(e);
+ }, msg);
+ test(function() {
+ var e = setupTestDetached(context, plain)[0];
+ assert_equals(e.innerHTML, expectedHTML);
+ assertNoEmptyTextChild(e);
+ }, msg + ", detached");
+}
+</script>
+<script src="innertext-setter-tests.js"></script>
diff --git a/testing/web-platform/tests/html/dom/elements/the-innertext-and-outertext-properties/multiple-text-nodes.window.js b/testing/web-platform/tests/html/dom/elements/the-innertext-and-outertext-properties/multiple-text-nodes.window.js
new file mode 100644
index 0000000000..07c55e9669
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/the-innertext-and-outertext-properties/multiple-text-nodes.window.js
@@ -0,0 +1,16 @@
+async_test(t => {
+ const div = document.body.appendChild(document.createElement("div"));
+ t.add_cleanup(() => div.remove());
+ const t1 = div.appendChild(new Text(""));
+ div.appendChild(new Text(""));
+ const t2 = div.appendChild(new Text(""));
+ const t3 = div.appendChild(new Text(""));
+ t.step_timeout(() => {
+ t1.data = "X";
+ t2.data = " ";
+ t3.data = "Y";
+ assert_equals(div.innerText, "X Y", "innerText");
+ assert_equals(div.outerText, "X Y", "outerText");
+ t.done();
+ }, 100);
+}, "Ensure multiple text nodes get rendered properly");
diff --git a/testing/web-platform/tests/html/dom/elements/the-innertext-and-outertext-properties/outertext-setter.html b/testing/web-platform/tests/html/dom/elements/the-innertext-and-outertext-properties/outertext-setter.html
new file mode 100644
index 0000000000..953bedc9a8
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/the-innertext-and-outertext-properties/outertext-setter.html
@@ -0,0 +1,180 @@
+<!DOCTYPE html>
+<title>outerText setter test</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<ul>
+ <li>A <span id="testReplacePrevious">B</span></li>
+ <li><span id="testReplaceFollowing">A</span> B</li>
+ <li>A <span id="testReplaceBoth">B</span> C</li>
+ <li><span id="testRemove">Testing</span> removing node using outerText.</li>
+ <li><span id="testNewlines">Replace this child with lots of newlines</span></li>
+</ul>
+
+<div id="container"></div>
+
+<script>
+"use strict";
+
+test(() => {
+ const node = document.getElementById("testReplacePrevious");
+ const parent = node.parentNode;
+
+ node.outerText = "Replaced";
+
+ assert_equals(parent.innerHTML, "A Replaced");
+ assert_equals(parent.childNodes.length, 1, "It got merged with the previous text node");
+}, "Replacing a node and merging with the previous text node");
+
+test(() => {
+ const node = document.getElementById("testReplaceFollowing");
+ const parent = node.parentNode;
+
+ node.outerText = "Replaced";
+
+ assert_equals(parent.innerHTML, "Replaced B");
+ assert_equals(parent.childNodes.length, 1, "It got merged with the following text node");
+}, "Replacing a node and merging with the following text node");
+
+test(() => {
+ const node = document.getElementById("testReplaceBoth");
+ const parent = node.parentNode;
+
+ node.outerText = "Replaced";
+
+ assert_equals(parent.innerHTML, "A Replaced C");
+ assert_equals(parent.childNodes.length, 1, "It got merged with the previous and following text node");
+}, "Replacing a node and merging with the previous and following text node");
+
+test(t => {
+ const container = document.getElementById("container");
+ t.add_cleanup(() => { container.textContent = ""; });
+
+ container.append("A", "B", document.createElement("span"), "D", "E");
+ assert_equals(container.childNodes.length, 5, "Precondition check: five separate nodes");
+
+ const node = container.childNodes[2];
+ node.outerText = "Replaced";
+
+ assert_equals(container.innerHTML, "ABReplacedDE");
+ assert_equals(container.childNodes.length, 3, "It got merged with the previous and following text node");
+ assert_equals(container.childNodes[0].data, "A");
+ assert_equals(container.childNodes[1].data, "BReplacedD");
+ assert_equals(container.childNodes[2].data, "E");
+}, "Only merges with the previous and following text nodes, does not completely normalize");
+
+test(t => {
+ const container = document.getElementById("container");
+ t.add_cleanup(() => { container.textContent = ""; });
+
+ container.append(document.createElement("span"));
+ const node = container.childNodes[0];
+ node.outerText = "";
+
+ assert_equals(container.childNodes.length, 1, "Creates text node for the empty string");
+ assert_equals(container.childNodes[0].data, "");
+}, "Empty string");
+
+test(t => {
+ const container = document.getElementById("container");
+ t.add_cleanup(() => { container.textContent = ""; });
+
+ container.append("1", "2", document.createElement("span"), "3", "4");
+ const node = container.childNodes[2];
+ node.outerText = "";
+
+ assert_equals(container.childNodes.length, 3, "It got merged with the previous and following text node");
+ assert_equals(container.childNodes[0].data, "1");
+ assert_equals(container.childNodes[1].data, "23");
+ assert_equals(container.childNodes[2].data, "4");
+}, "Empty string with surrounding text nodes");
+
+test(t => {
+ const node = document.getElementById("testNewlines");
+ const parent = node.parentNode;
+
+ node.outerText = "\n\r\n\r";
+
+ assert_equals(parent.innerHTML, "<br><br><br>");
+ assert_equals(parent.childNodes.length, 3);
+ assert_equals(parent.childNodes[0].localName, "br", "node 1");
+ assert_equals(parent.childNodes[1].localName, "br", "node 2");
+ assert_equals(parent.childNodes[2].localName, "br", "node 3");
+}, "Setting outerText to a bunch of newlines creates a bunch of <br>s with no text nodes");
+
+test(() => {
+ const node = document.getElementById("testRemove");
+ const parent = node.parentNode;
+
+ node.outerText = "";
+
+ assert_equals(parent.innerHTML, " removing node using outerText.");
+}, "Removing a node");
+
+test(() => {
+ const node = document.createElement("span");
+
+ assert_throws_dom("NoModificationAllowedError", () => { node.outerText = ""; });
+}, "Detached node");
+
+testText("<div>", "abc", "abc", "Simplest possible test");
+testHTML("<div>", "abc\ndef", "abc<br>def", "Newlines convert to <br> in non-white-space:pre elements");
+testHTML("<pre>", "abc\ndef", "abc<br>def", "Newlines convert to <br> in <pre> element");
+testHTML("<textarea>", "abc\ndef", "abc<br>def", "Newlines convert to <br> in <textarea> element");
+testHTML("<div style='white-space:pre'>", "abc\ndef", "abc<br>def", "Newlines convert to <br> in white-space:pre element");
+testHTML("<div>", "abc\rdef", "abc<br>def", "CRs convert to <br> in non-white-space:pre elements");
+testHTML("<pre>", "abc\rdef", "abc<br>def", "CRs convert to <br> in <pre> element");
+testHTML("<div>", "abc\r\ndef", "abc<br>def", "Newline/CR pair converts to <br> in non-white-space:pre element");
+testHTML("<div>", "abc\n\ndef", "abc<br><br>def", "Newline/newline pair converts to two <br>s in non-white-space:pre element");
+testHTML("<div>", "abc\r\rdef", "abc<br><br>def", "CR/CR pair converts to two <br>s in non-white-space:pre element");
+testHTML("<div style='white-space:pre'>", "abc\rdef", "abc<br>def", "CRs convert to <br> in white-space:pre element");
+testText("<div>", "abc<def", "abc<def", "< preserved");
+testText("<div>", "abc>def", "abc>def", "> preserved");
+testText("<div>", "abc&", "abc&", "& preserved");
+testText("<div>", "abc\"def", "abc\"def", "\" preserved");
+testText("<div>", "abc\'def", "abc\'def", "\' preserved");
+testHTML("<svg>", "abc", "<svg></svg>", "outerText not supported on SVG elements");
+testHTML("<math>", "abc", "<math></math>", "outerText not supported on MathML elements");
+testText("<div>", "abc\0def", "abc\0def", "Null characters preserved");
+testText("<div>", "abc\tdef", "abc\tdef", "Tabs preserved");
+testText("<div>", " abc", " abc", "Leading whitespace preserved");
+testText("<div>", "abc ", "abc ", "Trailing whitespace preserved");
+testText("<div>", "abc def", "abc def", "Whitespace not compressed");
+testText("<div>abc\n\n", "abc", "abc", "Existing text deleted");
+testText("<div><br>", "abc", "abc", "Existing <br> deleted");
+testHTML("<div>", "", "", "Assigning the empty string");
+testHTML("<div>", null, "", "Assigning null");
+testHTML("<div>", undefined, "undefined", "Assigning undefined");
+testHTML("<div>", "\rabc", "<br>abc", "Start with CR");
+testHTML("<div>", "\nabc", "<br>abc", "Start with LF");
+testHTML("<div>", "\r\nabc", "<br>abc", "Start with CRLF");
+testHTML("<div>", "abc\r", "abc<br>", "End with CR");
+testHTML("<div>", "abc\n", "abc<br>", "End with LF");
+testHTML("<div>", "abc\r\n", "abc<br>", "End with CRLF");
+
+function testText(startingHTML, outerText, expected, description) {
+ test(t => {
+ const container = document.getElementById("container");
+ t.add_cleanup(() => { container.textContent = ""; });
+
+ container.innerHTML = startingHTML;
+ const elementToReplace = container.firstElementChild;
+
+ elementToReplace.outerText = outerText;
+ assert_equals(container.textContent, expected);
+ }, description);
+}
+
+function testHTML(startingHTML, outerText, expected, description) {
+ test(t => {
+ const container = document.getElementById("container");
+ t.add_cleanup(() => { container.textContent = ""; });
+
+ container.innerHTML = startingHTML;
+ const elementToReplace = container.firstElementChild;
+
+ elementToReplace.outerText = outerText;
+ assert_equals(container.innerHTML, expected);
+ }, description);
+}
+</script>
diff --git a/testing/web-platform/tests/html/dom/elements/wai-aria/README.md b/testing/web-platform/tests/html/dom/elements/wai-aria/README.md
new file mode 100644
index 0000000000..bea30702d1
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/elements/wai-aria/README.md
@@ -0,0 +1 @@
+The test suite for WAI-ARIA is available at: <https://www.w3.org/WAI/PF/testharness/>.
diff --git a/testing/web-platform/tests/html/dom/historical.html b/testing/web-platform/tests/html/dom/historical.html
new file mode 100644
index 0000000000..396e57a391
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/historical.html
@@ -0,0 +1,55 @@
+<!doctype html>
+<title>Historical HTML APIs</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<div id=log></div>
+<attachment></attachment>
+<applet name=war align=left></applet>
+<layer></layer>
+<nolayer></nolayer>
+<script>
+test(() => {
+ assert_array_equals(document.applets, []);
+}, "document.applets is always empty");
+
+[
+ "attachment",
+ "applet",
+ "layer",
+ "nolayer"
+].forEach(name => {
+ test(() => {
+ const ap = document.getElementsByTagName(name)[0];
+ assert_true(ap instanceof window.HTMLUnknownElement);
+ }, `<${name}> is HTMLUnknownElement`);
+});
+
+test(() => {
+ assert_equals(self.HTMLAppletElement, undefined);
+}, "HTMLAppletElement is no more")
+
+test(() => {
+ assert_equals(document.all.war, undefined);
+}, "document.all cannot find applet")
+
+test(() => {
+ assert_equals(document.war, undefined);
+}, "document cannot find applet")
+
+test(() => {
+ assert_equals(self.war, undefined);
+}, "window cannot find applet")
+
+test(() => {
+ assert_equals(self.getComputedStyle(document.getElementsByTagName("applet")[0], "").cssFloat, "none");
+}, "applet is not styled")
+
+// removed in https://github.com/whatwg/html/commit/e383ae23776362cafb2fb4bbba70c8c9080d4b0f
+test(() => {
+ assert_false("HTMLTableDataCellElement" in window);
+}, "HTMLTableDataCellElement interface is removed")
+
+test(() => {
+ assert_false("HTMLTableHeaderCellElement" in window);
+}, "HTMLTableHeaderCellElement interface is removed")
+</script>
diff --git a/testing/web-platform/tests/html/dom/idlharness-shadowrealm.window.js b/testing/web-platform/tests/html/dom/idlharness-shadowrealm.window.js
new file mode 100644
index 0000000000..ef71b74e50
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/idlharness-shadowrealm.window.js
@@ -0,0 +1,2 @@
+// META: script=/resources/idlharness-shadowrealm.js
+idl_test_shadowrealm(["html"], ["wai-aria", "SVG", "cssom", "touch-events", "uievents", "dom", "xhr", "FileAPI", "mediacapture-streams", "performance-timeline"]);
diff --git a/testing/web-platform/tests/html/dom/idlharness.https.html b/testing/web-platform/tests/html/dom/idlharness.https.html
new file mode 100644
index 0000000000..7d693d3c0a
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/idlharness.https.html
@@ -0,0 +1,241 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>HTML IDL tests</title>
+<meta name=timeout content=long>
+<meta name="variant" content="?include=(Document|Window)">
+<meta name="variant" content="?include=HTML.*">
+<meta name="variant" content="?exclude=(Document|Window|HTML.*)">
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script src=/common/subset-tests-by-key.js></script>
+<script src=/common/get-host-info.sub.js></script>
+<script src=/resources/WebIDLParser.js></script>
+<script src=/resources/idlharness.js></script>
+
+<h1>HTML IDL tests</h1>
+<div id=log></div>
+
+<script>
+"use strict";
+var errorVideo; // used to get a MediaError object
+var iframe; // used to get a Document object (can't use `document` because some test clears the page)
+setup(function() {
+ errorVideo = document.createElement('video');
+ errorVideo.src = 'data:,';
+ errorVideo.preload = 'auto';
+ iframe = document.createElement('iframe');
+ iframe.hidden = true;
+ document.body.appendChild(iframe);
+});
+
+function createInput(type) {
+ var input = document.createElement('input');
+ input.type = type;
+ return input;
+}
+
+const waitForLoad = new Promise(resolve => { addEventListener('load', resolve); })
+
+idl_test(
+ ['html'],
+ ['wai-aria', 'SVG', 'cssom', 'touch-events', 'uievents', 'dom', 'xhr', 'FileAPI', 'mediacapture-streams', 'performance-timeline'],
+ async idlArray => {
+ self.documentWithHandlers = new Document();
+ const handler = function(e) {};
+ for (const callback of idlArray.members['GlobalEventHandlers'].members) {
+ if (callback.idlType && callback.idlType.idlType === 'EventHandler') {
+ documentWithHandlers[callback.name] = handler;
+ }
+ }
+ idlArray.add_untested_idls('typedef Window WindowProxy;');
+
+ idlArray.add_objects({
+ NodeList: ['document.getElementsByName("name")'],
+ HTMLAllCollection: ['document.all'],
+ HTMLFormControlsCollection: ['document.createElement("form").elements'],
+ RadioNodeList: [],
+ HTMLOptionsCollection: ['document.createElement("select").options'],
+ DOMStringMap: ['document.head.dataset'],
+ Transferable: [],
+ Document: ['iframe.contentDocument', 'new Document()', 'documentWithHandlers'],
+ XMLDocument: ['document.implementation.createDocument(null, "", null)'],
+ HTMLElement: [
+ 'document.createElement("noscript")',
+ 'Object.assign(document.createElement("noscript"),{popover:"auto"})',
+ ], // more tests in html/semantics/interfaces.js
+ HTMLUnknownElement: ['document.createElement("bgsound")'], // more tests in html/semantics/interfaces.js
+ HTMLHtmlElement: ['document.createElement("html")'],
+ HTMLHeadElement: ['document.createElement("head")'],
+ HTMLTitleElement: ['document.createElement("title")'],
+ HTMLBaseElement: ['document.createElement("base")'],
+ HTMLLinkElement: ['document.createElement("link")'],
+ HTMLMetaElement: ['document.createElement("meta")'],
+ HTMLStyleElement: ['document.createElement("style")'],
+ HTMLScriptElement: ['document.createElement("script")'],
+ HTMLBodyElement: ['document.createElement("body")'],
+ HTMLHeadingElement: ['document.createElement("h1")'],
+ HTMLParagraphElement: ['document.createElement("p")'],
+ HTMLHRElement: ['document.createElement("hr")'],
+ HTMLPreElement: [
+ 'document.createElement("pre")',
+ 'document.createElement("listing")',
+ 'document.createElement("xmp")',
+ ],
+ HTMLQuoteElement: [
+ 'document.createElement("blockquote")',
+ 'document.createElement("q")',
+ ],
+ HTMLOlistElement: ['document.createElement("ol")'],
+ HTMLUlistElement: ['document.createElement("ul")'],
+ HTMLLIElement: ['document.createElement("li")'],
+ HTMLDlistElement: ['document.createElement("dl")'],
+ HTMLDivElement: ['document.createElement("div")'],
+ HTMLAnchorElement: ['document.createElement("a")'],
+ HTMLDataElement: ['document.createElement("data")'],
+ HTMLTimeElement: ['document.createElement("time")'],
+ HTMLSpanElement: ['document.createElement("span")'],
+ HTMLBRElement: ['document.createElement("br")'],
+ HTMLModElement: [
+ 'document.createElement("ins")',
+ 'document.createElement("del")',
+ ],
+ HTMLPictureElement: ['document.createElement("picture")'],
+ HTMLImageElement: ['document.createElement("img")', 'new Image()'],
+ HTMLIFrameElement: ['document.createElement("iframe")'],
+ HTMLEmbedElement: ['document.createElement("embed")'],
+ HTMLObjectElement: ['document.createElement("object")'],
+ HTMLParamElement: ['document.createElement("param")'],
+ HTMLVideoElement: ['document.createElement("video")'],
+ HTMLAudioElement: ['document.createElement("audio")', 'new Audio()'],
+ HTMLSourceElement: ['document.createElement("source")'],
+ HTMLTrackElement: ['document.createElement("track")'],
+ HTMLMediaElement: [],
+ MediaError: ['errorVideo.error'],
+ AudioTrackList: [],
+ AudioTrack: [],
+ VideoTrackList: [],
+ VideoTrack: [],
+ TextTrackList: ['document.createElement("video").textTracks'],
+ TextTrack: ['document.createElement("track").track'],
+ TextTrackCueList: ['document.createElement("video").addTextTrack("subtitles").cues'],
+ TextTrackCue: [],
+ DataCue: [],
+ TimeRanges: ['document.createElement("video").buffered'],
+ TrackEvent: ['new TrackEvent("addtrack", {track:document.createElement("track").track})'],
+ HTMLTemplateElement: ['document.createElement("template")'],
+ HTMLSlotElement: ['document.createElement("slot")'],
+ HTMLCanvasElement: ['document.createElement("canvas")'],
+ CanvasRenderingContext2D: ['document.createElement("canvas").getContext("2d")'],
+ CanvasGradient: [],
+ CanvasPattern: [],
+ ToggleEvent: ['new ToggleEvent("beforetoggle")'],
+ TextMetrics: [],
+ ImageData: ['new ImageData(10, 10)'],
+ HTMLMapElement: ['document.createElement("map")'],
+ HTMLAreaElement: ['document.createElement("area")'],
+ HTMLTableElement: ['document.createElement("table")'],
+ HTMLTableCaptionElement: ['document.createElement("caption")'],
+ HTMLTableColElement: [
+ 'document.createElement("colgroup")',
+ 'document.createElement("col")',
+ ],
+ HTMLTableSectionElement: [
+ 'document.createElement("tbody")',
+ 'document.createElement("thead")',
+ 'document.createElement("tfoot")',
+ ],
+ HTMLTableRowElement: ['document.createElement("tr")'],
+ HTMLTableCellElement: [
+ 'document.createElement("td")',
+ 'document.createElement("th")',
+ ],
+ HTMLFormElement: ['document.createElement("form")'],
+ HTMLFieldsetElement: ['document.createElement("fieldset")'],
+ HTMLLegendElement: ['document.createElement("legend")'],
+ HTMLLabelElement: ['document.createElement("label")'],
+ HTMLInputElement: [
+ 'document.createElement("input")',
+ 'createInput("text")',
+ 'createInput("hidden")',
+ 'createInput("search")',
+ 'createInput("tel")',
+ 'createInput("url")',
+ 'createInput("email")',
+ 'createInput("password")',
+ 'createInput("date")',
+ 'createInput("month")',
+ 'createInput("week")',
+ 'createInput("time")',
+ 'createInput("datetime-local")',
+ 'createInput("number")',
+ 'createInput("range")',
+ 'createInput("color")',
+ 'createInput("checkbox")',
+ 'createInput("radio")',
+ 'createInput("file")',
+ 'createInput("submit")',
+ 'createInput("image")',
+ 'createInput("reset")',
+ 'createInput("button")'
+ ],
+ HTMLButtonElement: ['document.createElement("button")'],
+ HTMLSelectElement: ['document.createElement("select")'],
+ HTMLDataListElement: ['document.createElement("datalist")'],
+ HTMLOptGroupElement: ['document.createElement("optgroup")'],
+ HTMLOptionElement: ['document.createElement("option")', 'new Option()'],
+ HTMLTextAreaElement: ['document.createElement("textarea")'],
+ HTMLOutputElement: ['document.createElement("output")'],
+ HTMLProgressElement: ['document.createElement("progress")'],
+ HTMLMeterElement: ['document.createElement("meter")'],
+ ValidityState: ['document.createElement("input").validity'],
+ FormDataEvent: ['new FormDataEvent("formdata", { formData: new FormData() })'],
+ HTMLDetailsElement: ['document.createElement("details")'],
+ HTMLMenuElement: ['document.createElement("menu")'],
+ Window: ['window'],
+ BarProp: [],
+ History: ['window.history'],
+ Location: ['window.location'],
+ PopStateEvent: ['new PopStateEvent("popstate", { data: {} })'],
+ HashChangeEvent: [],
+ PageTransitionEvent: [],
+ BeforeUnloadEvent: [],
+ WindowModal: [],
+ DOMParser: ['new DOMParser()'],
+ Navigator: ['window.navigator'],
+ External: ['window.external'],
+ DataTransfer: [],
+ DataTransferItemList: [],
+ DataTransferItem: [],
+ DragEvent: [],
+ NavigatorUserMediaError: [],
+ MediaStream: [],
+ MediaStreamTrack: [],
+ MediaStreamRecorder: [],
+ PeerConnection: [],
+ MediaStreamEvent: [],
+ ErrorEvent: [],
+ EventSource: ['new EventSource("http://invalid")'],
+ AbstractWorker: [],
+ Worker: [],
+ SharedWorker: [],
+ MessageEvent: ['new MessageEvent("message", { data: 5 })'],
+ MessageChannel: [],
+ MessagePort: [],
+ HTMLMarqueeElement: ['document.createElement("marquee")'],
+ HTMLFrameSetElement: ['document.createElement("frameset")'],
+ HTMLFrameElement: ['document.createElement("frame")'],
+ HTMLDirectoryElement: ['document.createElement("dir")'],
+ HTMLFontElement: ['document.createElement("font")'],
+ DOMStringList: ['location.ancestorOrigins'],
+ Storage: [
+ 'localStorage',
+ 'sessionStorage',
+ ],
+ StorageEvent: ['new StorageEvent("storage")']
+ });
+ idlArray.prevent_multiple_testing('HTMLElement');
+ await waitForLoad;
+ }
+);
+
+</script>
diff --git a/testing/web-platform/tests/html/dom/idlharness.worker.js b/testing/web-platform/tests/html/dom/idlharness.worker.js
new file mode 100644
index 0000000000..88942ddfea
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/idlharness.worker.js
@@ -0,0 +1,22 @@
+"use strict";
+
+importScripts("/resources/testharness.js");
+importScripts("/resources/WebIDLParser.js", "/resources/idlharness.js");
+
+idl_test(
+ ["html"],
+ ["wai-aria", "dom", "cssom", "touch-events", "uievents", "performance-timeline"],
+ idlArray => {
+ idlArray.add_untested_idls('typedef Window WindowProxy;');
+ idlArray.add_objects({
+ WorkerLocation: ['self.location'],
+ WorkerNavigator: ['self.navigator'],
+ EventSource: ['new EventSource("http://invalid")'],
+ Worker: [],
+ MessageEvent: ['new MessageEvent("message", { data: 5 })'],
+ DedicatedWorkerGlobalScope: ['self'],
+ });
+ }
+);
+
+done();
diff --git a/testing/web-platform/tests/html/dom/new-harness.js b/testing/web-platform/tests/html/dom/new-harness.js
new file mode 100644
index 0000000000..49f8e40ad7
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/new-harness.js
@@ -0,0 +1,11 @@
+// We override only the things we need to -- the rest we'll just inherit from
+// original-harness.js. Polymorphism, kind of.
+ReflectionHarness.conformanceTesting = true;
+
+ReflectionHarness.test = function(fun, description) {
+ test(fun, this.getTypeDescription() + ": " + description);
+}
+
+ReflectionHarness.assertEquals = assert_equals;
+
+ReflectionHarness.assertThrows = assert_throws_dom;
diff --git a/testing/web-platform/tests/html/dom/original-harness.js b/testing/web-platform/tests/html/dom/original-harness.js
new file mode 100644
index 0000000000..89a8067033
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/original-harness.js
@@ -0,0 +1,339 @@
+var ReflectionHarness = {};
+
+// @private
+ReflectionHarness.passed = document.getElementById("passed");
+ReflectionHarness.failed = document.getElementById("failed");
+
+/**
+ * In conformance testing mode, all tests will be run. Otherwise, we'll skip
+ * tests for attributes that have an entirely incorrect type.
+ */
+ReflectionHarness.conformanceTesting = false;
+
+/**
+ * Returns a string representing val. Basically just adds quotes for strings,
+ * and passes through other recognized types literally.
+ *
+ * @public
+ */
+ReflectionHarness.stringRep = function(val) {
+ if (val === null) {
+ // typeof is object, so the switch isn't useful
+ return "null";
+ }
+ // In JavaScript, -0 === 0 and String(-0) == "0", so we have to
+ // special-case.
+ if (val === -0 && 1/val === -Infinity) {
+ return "-0";
+ }
+ switch (typeof val) {
+ case "string":
+ for (var i = 0; i < 32; i++) {
+ var replace = "\\";
+ switch (i) {
+ case 0: replace += "0"; break;
+ case 1: replace += "x01"; break;
+ case 2: replace += "x02"; break;
+ case 3: replace += "x03"; break;
+ case 4: replace += "x04"; break;
+ case 5: replace += "x05"; break;
+ case 6: replace += "x06"; break;
+ case 7: replace += "x07"; break;
+ case 8: replace += "b"; break;
+ case 9: replace += "t"; break;
+ case 10: replace += "n"; break;
+ case 11: replace += "v"; break;
+ case 12: replace += "f"; break;
+ case 13: replace += "r"; break;
+ case 14: replace += "x0e"; break;
+ case 15: replace += "x0f"; break;
+ case 16: replace += "x10"; break;
+ case 17: replace += "x11"; break;
+ case 18: replace += "x12"; break;
+ case 19: replace += "x13"; break;
+ case 20: replace += "x14"; break;
+ case 21: replace += "x15"; break;
+ case 22: replace += "x16"; break;
+ case 23: replace += "x17"; break;
+ case 24: replace += "x18"; break;
+ case 25: replace += "x19"; break;
+ case 26: replace += "x1a"; break;
+ case 27: replace += "x1b"; break;
+ case 28: replace += "x1c"; break;
+ case 29: replace += "x1d"; break;
+ case 30: replace += "x1e"; break;
+ case 31: replace += "x1f"; break;
+ }
+ val = val.replace(String.fromCharCode(i), replace);
+ }
+ return '"' + val.replace('"', '\\"') + '"';
+ case "boolean":
+ case "undefined":
+ case "number":
+ return val + "";
+ default:
+ return typeof val + ' "' + val + '"';
+ }
+}
+
+/**
+ * An object representing info about the current test, used for printing out
+ * nice messages and so forth.
+ */
+ReflectionHarness.currentTestInfo = {};
+
+/**
+ * .test() sets this, and it's used by .assertEquals()/.assertThrows().
+ * Calling .test() recursively is an error.
+ */
+ReflectionHarness.currentTestDescription = null;
+
+/**
+ * Run a group of one or more assertions. If any exceptions are thrown, catch
+ * them and report a failure.
+ */
+ReflectionHarness.test = function(fn, description) {
+ if (this.currentTestDescription) {
+ throw "TEST BUG: test() may not be called recursively!";
+ }
+ this.currentTestDescription = description;
+ try {
+ fn();
+ // Not throwing is a success
+ this.success();
+ } catch(err) {
+ this.failure("Exception thrown during tests with " + description);
+ }
+ this.currentTestDescription = null;
+}
+
+/**
+ * If question === answer, output a success, else report a failure with the
+ * given description. Currently success and failure both increment counters,
+ * and failures output a message to a <ul>. Which <ul> is decided by the type
+ * parameter -- different attribute types are separated for readability.
+ *
+ * @public
+ */
+ReflectionHarness.assertEquals = function(expected, actual, description) {
+ // Special-case -0 yay!
+ if (expected === 0 && actual === 0 && 1/expected === 1/actual) {
+ this.increment(this.passed);
+ } else if (expected === actual) {
+ this.increment(this.passed);
+ } else {
+ this.increment(this.failed);
+ this.reportFailure(this.currentTestDescription +
+ (description ? " followed by " + description : "") +
+ ' (expected ' + this.stringRep(actual) + ', got ' +
+ this.stringRep(expected) + ')');
+ }
+}
+
+/**
+ * If calling fn causes a DOMException of the type given by the string
+ * exceptionName (e.g., "IndexSizeError"), output a success. Otherwise, report
+ * a failure.
+ *
+ * @public
+ */
+ReflectionHarness.assertThrows = function(exceptionName, fn) {
+ try {
+ fn();
+ } catch (e) {
+ if (e instanceof DOMException && (e.code == DOMException[exceptionName] ||
+ e.name == exceptionName)) {
+ this.increment(this.passed);
+ return true;
+ }
+ }
+ this.increment(this.failed);
+ this.reportFailure(this.currentTestDescription + " must throw " +
+ exceptionName);
+ return false;
+}
+
+/**
+ * Get a description of the current type, e.g., "a.href".
+ */
+ReflectionHarness.getTypeDescription = function() {
+ var domNode = this.currentTestInfo.domObj.tagName.toLowerCase();
+ var idlNode = this.currentTestInfo.idlObj.nodeName.toLowerCase();
+ var domName = this.currentTestInfo.domName;
+ var idlName = this.currentTestInfo.idlName;
+ var comment = this.currentTestInfo.data.comment;
+ var typeDesc = idlNode + "." + idlName;
+ if (!comment && (domNode != idlNode || domName != idlName)) {
+ comment = "<" + domNode + " " + domName + ">";
+ }
+ if (comment) {
+ typeDesc += " (" + comment + ")";
+ }
+ return typeDesc;
+}
+
+/**
+ * Report a failure with the given description, adding context from the
+ * currentTestInfo member.
+ *
+ * @private
+ */
+ReflectionHarness.reportFailure = function(description) {
+ var typeDesc = this.getTypeDescription();
+ var idlName = this.currentTestInfo.idlName;
+ var comment = this.currentTestInfo.data.comment;
+ typeDesc = typeDesc.replace("&", "&amp;").replace("<", "&lt;");
+ description = description.replace("&", "&amp;").replace("<", "&lt;");
+
+ var type = this.currentTestInfo.data.type;
+
+ // Special case for undefined attributes, which we don't want getting in
+ // the way of everything else.
+ if (description.search('^typeof IDL attribute \\(expected ".*", got "undefined"\\)$') != -1) {
+ type = "undefined";
+ }
+
+ var done = false;
+ var ul = document.getElementById("errors-" + type.replace(" ", "-"));
+ if (ul === null) {
+ ul = document.createElement("ul");
+ ul.id = "errors-" + type.replace(" ", "-");
+ var div = document.getElementById("errors");
+ p = document.createElement("p");
+ if (type == "undefined") {
+ div.parentNode.insertBefore(ul, div.nextSibling);
+ p.innerHTML = "These IDL attributes were of undefined type, presumably representing unimplemented features (cordoned off into a separate section for tidiness):";
+ } else {
+ div.appendChild(ul);
+ p.innerHTML = "Errors for type " + type + ":";
+ }
+ ul.parentNode.insertBefore(p, ul);
+ } else if (type != "undefined") {
+ var existingErrors = ul.getElementsByClassName("desc");
+ for (var i = 0; i < existingErrors.length; i++) {
+ if (existingErrors[i].innerHTML == description) {
+ var typeSpan = existingErrors[i].parentNode.getElementsByClassName("type")[0];
+ // Check if we have lots of the same error for the same
+ // attribute. If so, we want to collapse them -- the exact
+ // elements that exhibit the error aren't going to be important
+ // to report in this case, and it can take a lot of space if
+ // there's an error in a global attribute like dir or id.
+ var types = typeSpan.innerHTML.split(", ");
+ var count = 0;
+ for (var i = 0; i < types.length; i++) {
+ if (types[i].search("^\\([0-9]* elements\\)\\." + idlName + "$") != -1) {
+ types[i] = "(" + (1 + parseInt(/[0-9]+/.exec(types[i])[0])) + " elements)." + idlName;
+ typeSpan.innerHTML = types.join(", ");
+ return;
+ } else if (types[i].search("\\." + idlName + "$") != -1) {
+ count++;
+ }
+ }
+ if (comment || count < 10) {
+ // Just add the extra error to the end, not many duplicates
+ // (or we have a comment)
+ typeSpan.innerHTML += ", " + typeDesc;
+ } else {
+ var filteredTypes = types.filter(function(type) { return type.search("\\." + idlName + "$") == -1; });
+ if (filteredTypes.length) {
+ typeSpan.innerHTML = filteredTypes.join(", ") + ", ";
+ } else {
+ typeSpan.innerHTML = "";
+ }
+ typeSpan.innerHTML += "(" + (types.length - filteredTypes.length) + " elements)." + idlName;
+ }
+ return;
+ }
+ }
+ }
+
+ if (type == "undefined") {
+ ul.innerHTML += "<li>" + typeDesc;
+ } else {
+ ul.innerHTML += "<li><span class=\"type\">" + typeDesc + "</span>: <span class=\"desc\">" + description + "</span>";
+ }
+}
+
+/**
+ * Shorthand function for when we have a failure outside of
+ * assertEquals()/assertThrows(). Generally used when the failure is an
+ * exception thrown unexpectedly or such, something not equality-based.
+ *
+ * @public
+ */
+ReflectionHarness.failure = function(message) {
+ this.increment(this.failed);
+ this.reportFailure(message);
+}
+
+/**
+ * Shorthand function for when we have a success outside of
+ * assertEquals()/assertThrows().
+ *
+ * @public
+ */
+ReflectionHarness.success = function() {
+ this.increment(this.passed);
+}
+
+/**
+ * Increment the count in either "passed" or "failed". el should always be one
+ * of those two variables. The implementation of this function amuses me.
+ *
+ * @private
+ */
+ReflectionHarness.increment = function(el) {
+ el.innerHTML = parseInt(el.innerHTML) + 1;
+ var percent = document.getElementById("percent");
+ var passed = document.getElementById("passed");
+ var failed = document.getElementById("failed");
+ percent.innerHTML = (parseInt(passed.innerHTML)/(parseInt(passed.innerHTML) + parseInt(failed.innerHTML))*100).toPrecision(3);
+}
+
+/**
+ * Hide all displayed errors matching a given regex, so it's easier to filter
+ * out repetitive failures. TODO: Fix this so it works right with the new
+ * "lump many errors in one <li>" thing.
+ *
+ * @private (kind of, only called in the original reflection.html)
+ */
+ReflectionHarness.maskErrors = function(regex) {
+ var uls = document.getElementsByTagName("ul");
+ for (var i = 0; i < uls.length; i++) {
+ var lis = uls[i].children;
+ for (var j = 0; j < lis.length; j++) {
+ if (regex !== "" && lis[j].innerHTML.match(regex)) {
+ lis[j].style.display = "none";
+ } else {
+ lis[j].style.display = "list-item";
+ }
+ }
+ }
+}
+
+// Now for some stuff that has nothing to do with ReflectionHarness and
+// everything to do with initialization needed for reflection.js, which seems
+// pointless to put in an extra file.
+
+var elements = {};
+
+var extraTests = [];
+
+/**
+ * Used for combining a number of small arrays of element data into one big
+ * one.
+ */
+function mergeElements(src) {
+ for (var key in src) {
+ if (!src.hasOwnProperty(key)) {
+ // This is inherited from a prototype or something.
+ continue;
+ }
+
+ if (key in elements) {
+ elements[key] = elements[key].concat(src[key]);
+ } else {
+ elements[key] = src[key];
+ }
+ }
+}
diff --git a/testing/web-platform/tests/html/dom/reflection-embedded.html b/testing/web-platform/tests/html/dom/reflection-embedded.html
new file mode 100644
index 0000000000..0a362f817a
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/reflection-embedded.html
@@ -0,0 +1,17 @@
+<!doctype html>
+<title>HTML5 reflection tests: embedded elements</title>
+<meta name=timeout content=long>
+<p>Implementers looking to fix bugs might want to use the <a
+href=reflection-original.html>original version</a> of this suite's test
+framework, which conveniently aggregates similar errors and only reports
+failures. This file is (part of) the authoritative conformance test suite, and
+is suitable for incorporation into automated test suites.
+
+<div id=log></div>
+
+<script src="/resources/testharness.js"></script>
+<script src=/resources/testharnessreport.js></script>
+<script src=original-harness.js></script>
+<script src=new-harness.js></script>
+<script src=elements-embedded.js></script>
+<script src=reflection.js></script>
diff --git a/testing/web-platform/tests/html/dom/reflection-forms-weekmonth.html b/testing/web-platform/tests/html/dom/reflection-forms-weekmonth.html
new file mode 100644
index 0000000000..ad72da27c7
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/reflection-forms-weekmonth.html
@@ -0,0 +1,17 @@
+<!doctype html>
+<title>HTML5 reflection tests: week and month input types</title>
+<meta name=timeout content=long>
+<p>Implementers looking to fix bugs might want to use the <a
+href=reflection-original.html>original version</a> of this suite's test
+framework, which conveniently aggregates similar errors and only reports
+failures. This file is (part of) the authoritative conformance test suite, and
+is suitable for incorporation into automated test suites.
+
+<div id=log></div>
+
+<script src="/resources/testharness.js"></script>
+<script src=/resources/testharnessreport.js></script>
+<script src=original-harness.js></script>
+<script src=new-harness.js></script>
+<script src=elements-forms-weekmonth.js></script>
+<script src=reflection.js></script>
diff --git a/testing/web-platform/tests/html/dom/reflection-forms.html b/testing/web-platform/tests/html/dom/reflection-forms.html
new file mode 100644
index 0000000000..2fe251a6f4
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/reflection-forms.html
@@ -0,0 +1,17 @@
+<!doctype html>
+<title>HTML5 reflection tests: form elements</title>
+<meta name=timeout content=long>
+<p>Implementers looking to fix bugs might want to use the <a
+href=reflection-original.html>original version</a> of this suite's test
+framework, which conveniently aggregates similar errors and only reports
+failures. This file is (part of) the authoritative conformance test suite, and
+is suitable for incorporation into automated test suites.
+
+<div id=log></div>
+
+<script src="/resources/testharness.js"></script>
+<script src=/resources/testharnessreport.js></script>
+<script src=original-harness.js></script>
+<script src=new-harness.js></script>
+<script src=elements-forms.js></script>
+<script src=reflection.js></script>
diff --git a/testing/web-platform/tests/html/dom/reflection-grouping.html b/testing/web-platform/tests/html/dom/reflection-grouping.html
new file mode 100644
index 0000000000..e59f5f569c
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/reflection-grouping.html
@@ -0,0 +1,17 @@
+<!doctype html>
+<title>HTML5 reflection tests: grouping elements</title>
+<meta name=timeout content=long>
+<p>Implementers looking to fix bugs might want to use the <a
+href=reflection-original.html>original version</a> of this suite's test
+framework, which conveniently aggregates similar errors and only reports
+failures. This file is (part of) the authoritative conformance test suite, and
+is suitable for incorporation into automated test suites.
+
+<div id=log></div>
+
+<script src="/resources/testharness.js"></script>
+<script src=/resources/testharnessreport.js></script>
+<script src=original-harness.js></script>
+<script src=new-harness.js></script>
+<script src=elements-grouping.js></script>
+<script src=reflection.js></script>
diff --git a/testing/web-platform/tests/html/dom/reflection-metadata.html b/testing/web-platform/tests/html/dom/reflection-metadata.html
new file mode 100644
index 0000000000..f21b6863ec
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/reflection-metadata.html
@@ -0,0 +1,17 @@
+<!doctype html>
+<title>HTML5 reflection tests: metadata elements</title>
+<meta name=timeout content=long>
+<p>Implementers looking to fix bugs might want to use the <a
+href=reflection-original.html>original version</a> of this suite's test
+framework, which conveniently aggregates similar errors and only reports
+failures. This file is (part of) the authoritative conformance test suite, and
+is suitable for incorporation into automated test suites.
+
+<div id=log></div>
+
+<script src="/resources/testharness.js"></script>
+<script src=/resources/testharnessreport.js></script>
+<script src=original-harness.js></script>
+<script src=new-harness.js></script>
+<script src=elements-metadata.js></script>
+<script src=reflection.js></script>
diff --git a/testing/web-platform/tests/html/dom/reflection-misc.html b/testing/web-platform/tests/html/dom/reflection-misc.html
new file mode 100644
index 0000000000..915f6fad47
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/reflection-misc.html
@@ -0,0 +1,17 @@
+<!doctype html>
+<title>HTML5 reflection tests: miscellaneous elements</title>
+<meta name=timeout content=long>
+<p>Implementers looking to fix bugs might want to use the <a
+href=reflection-original.html>original version</a> of this suite's test
+framework, which conveniently aggregates similar errors and only reports
+failures. This file is (part of) the authoritative conformance test suite, and
+is suitable for incorporation into automated test suites.
+
+<div id=log></div>
+
+<script src="/resources/testharness.js"></script>
+<script src=/resources/testharnessreport.js></script>
+<script src=original-harness.js></script>
+<script src=new-harness.js></script>
+<script src=elements-misc.js></script>
+<script src=reflection.js></script>
diff --git a/testing/web-platform/tests/html/dom/reflection-obsolete.html b/testing/web-platform/tests/html/dom/reflection-obsolete.html
new file mode 100644
index 0000000000..0aa439813e
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/reflection-obsolete.html
@@ -0,0 +1,17 @@
+<!doctype html>
+<title>HTML5 reflection tests: obsolete elements</title>
+<meta name=timeout content=long>
+<p>Implementers looking to fix bugs might want to use the <a
+href=reflection-original.html>original version</a> of this suite's test
+framework, which conveniently aggregates similar errors and only reports
+failures. This file is (part of) the authoritative conformance test suite, and
+is suitable for incorporation into automated test suites.
+
+<div id=log></div>
+
+<script src="/resources/testharness.js"></script>
+<script src=/resources/testharnessreport.js></script>
+<script src=original-harness.js></script>
+<script src=new-harness.js></script>
+<script src=elements-obsolete.js></script>
+<script src=reflection.js></script>
diff --git a/testing/web-platform/tests/html/dom/reflection-original.html b/testing/web-platform/tests/html/dom/reflection-original.html
new file mode 100644
index 0000000000..0f7b43e375
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/reflection-original.html
@@ -0,0 +1,40 @@
+<!doctype html>
+<title>HTML5 reflection tests</title>
+<meta name=timeout content=long>
+<p>This is <em>not</em> the authoritative conformance test suite for
+reflection. The authoritative tests can be found here, split up into sections:
+
+<ul>
+ <li><a href=reflection-metadata.html>Metadata elements</a>
+ <li><a href=reflection-sections.html>Section elements</a>
+ <li><a href=reflection-grouping.html>Grouping elements</a>
+ <li><a href=reflection-text.html>Text elements</a>
+ <li><a href=reflection-embedded.html>Embedded elements</a>
+ <li><a href=reflection-tabular.html>Tabular elements</a>
+ <li><a href=reflection-forms.html>Form elements</a>
+ <li><a href=reflection-misc.html>Miscellaneous elements</a>
+ <li><a href=reflection-obsolete.html>Obsolete elements</a>
+</ul>
+
+<p>This test suite is provided for implementers' convenience in debugging
+failures. It groups similar failures in a fashion that should help fix them.
+It is not intended to be suitable for incorporation into automated testing
+frameworks.
+
+<p>Filter out errors matching a regex (operates on HTML not text, you have to manually escape entities): <input oninput="maskErrors(this.value)">
+
+<p>Passed: <span id=passed>0</span> (<span id=percent></span>%). Failed: <span id=failed>0</span>. Time to complete: <span id=time>0</span> s.
+
+<div id=errors></div>
+
+<script src=original-harness.js></script>
+<script src=elements-metadata.js></script>
+<script src=elements-sections.js></script>
+<script src=elements-grouping.js></script>
+<script src=elements-text.js></script>
+<script src=elements-embedded.js></script>
+<script src=elements-tabular.js></script>
+<script src=elements-forms.js></script>
+<script src=elements-misc.js></script>
+<script src=elements-obsolete.js></script>
+<script src=reflection.js></script>
diff --git a/testing/web-platform/tests/html/dom/reflection-sections.html b/testing/web-platform/tests/html/dom/reflection-sections.html
new file mode 100644
index 0000000000..2235665414
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/reflection-sections.html
@@ -0,0 +1,17 @@
+<!doctype html>
+<title>HTML5 reflection tests: section elements</title>
+<meta name=timeout content=long>
+<p>Implementers looking to fix bugs might want to use the <a
+href=reflection-original.html>original version</a> of this suite's test
+framework, which conveniently aggregates similar errors and only reports
+failures. This file is (part of) the authoritative conformance test suite, and
+is suitable for incorporation into automated test suites.
+
+<div id=log></div>
+
+<script src="/resources/testharness.js"></script>
+<script src=/resources/testharnessreport.js></script>
+<script src=original-harness.js></script>
+<script src=new-harness.js></script>
+<script src=elements-sections.js></script>
+<script src=reflection.js></script>
diff --git a/testing/web-platform/tests/html/dom/reflection-tabular.html b/testing/web-platform/tests/html/dom/reflection-tabular.html
new file mode 100644
index 0000000000..f790da253a
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/reflection-tabular.html
@@ -0,0 +1,17 @@
+<!doctype html>
+<title>HTML5 reflection tests: tabular elements</title>
+<meta name=timeout content=long>
+<p>Implementers looking to fix bugs might want to use the <a
+href=reflection-original.html>original version</a> of this suite's test
+framework, which conveniently aggregates similar errors and only reports
+failures. This file is (part of) the authoritative conformance test suite, and
+is suitable for incorporation into automated test suites.
+
+<div id=log></div>
+
+<script src="/resources/testharness.js"></script>
+<script src=/resources/testharnessreport.js></script>
+<script src=original-harness.js></script>
+<script src=new-harness.js></script>
+<script src=elements-tabular.js></script>
+<script src=reflection.js></script>
diff --git a/testing/web-platform/tests/html/dom/reflection-text.html b/testing/web-platform/tests/html/dom/reflection-text.html
new file mode 100644
index 0000000000..a2dc6f6154
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/reflection-text.html
@@ -0,0 +1,17 @@
+<!doctype html>
+<title>HTML5 reflection tests: text elements</title>
+<meta name=timeout content=long>
+<p>Implementers looking to fix bugs might want to use the <a
+href=reflection-original.html>original version</a> of this suite's test
+framework, which conveniently aggregates similar errors and only reports
+failures. This file is (part of) the authoritative conformance test suite, and
+is suitable for incorporation into automated test suites.
+
+<div id=log></div>
+
+<script src="/resources/testharness.js"></script>
+<script src=/resources/testharnessreport.js></script>
+<script src=original-harness.js></script>
+<script src=new-harness.js></script>
+<script src=elements-text.js></script>
+<script src=reflection.js></script>
diff --git a/testing/web-platform/tests/html/dom/reflection.js b/testing/web-platform/tests/html/dom/reflection.js
new file mode 100644
index 0000000000..b2c3b30aae
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/reflection.js
@@ -0,0 +1,1065 @@
+ReflectionTests = {};
+
+ReflectionTests.start = new Date().getTime();
+
+/**
+ * Resolve the given URL to an absolute URL, relative to the current document's
+ * address. There's no API that I know of that exposes this directly, so we
+ * actually just create an <a> element, set its href, and stitch together the
+ * various properties. Seems to work. We don't try to reimplement the
+ * algorithm here, because we're not concerned with its correctness -- we're
+ * only testing HTML reflection, not Web Addresses.
+ *
+ * Return the input if the URL couldn't be resolved, per the spec for
+ * reflected URL attributes.
+ *
+ * It seems like IE9 doesn't implement URL decomposition attributes correctly
+ * for <a>, which causes all these tests to fail. Ideally I'd do this in some
+ * other way, but the failure does stem from an incorrect implementation of
+ * HTML, so I'll leave it alone for now.
+ *
+ * TODO: This relies on reflection to test reflection, so it could mask bugs.
+ * Either get a JS implementation of the "resolve a URL" algorithm, or just
+ * specify expected values manually here. It shouldn't be too hard to write
+ * special cases for all the values we test.
+ */
+ReflectionTests.resolveUrl = function(url) {
+ url = String(url);
+ var el = document.createElement("a");
+ el.href = url;
+ var ret = el.protocol + "//" + el.host + el.pathname + el.search + el.hash;
+ if (ret == "//") {
+ return url;
+ } else {
+ return ret;
+ }
+};
+
+/**
+ * The "rules for parsing non-negative integers" from the HTML spec. They're
+ * mostly used for reflection, so here seems like as good a place to test them
+ * as any. Returns false on error.
+ */
+ReflectionTests.parseNonneg = function(input) {
+ var value = this.parseInt(input);
+ if (value === false || value < 0) {
+ return false;
+ }
+ return value;
+};
+
+/**
+ * The "rules for parsing integers" from the HTML spec. Returns false on
+ * error.
+ */
+ReflectionTests.parseInt = function(input) {
+ var position = 0;
+ var sign = 1;
+ // Skip whitespace
+ while (input.length > position && /^[ \t\n\f\r]$/.test(input[position])) {
+ position++;
+ }
+ if (position >= input.length) {
+ return false;
+ }
+ if (input[position] == "-") {
+ sign = -1;
+ position++;
+ } else if (input[position] == "+") {
+ position++;
+ }
+ if (position >= input.length) {
+ return false;
+ }
+ if (!/^[0-9]$/.test(input[position])) {
+ return false;
+ }
+ var value = 0;
+ while (input.length > position && /^[0-9]$/.test(input[position])) {
+ value *= 10;
+ // Don't use parseInt even for single-digit strings . . .
+ value += input.charCodeAt(position) - "0".charCodeAt(0);
+ position++;
+ }
+ if (value === 0) {
+ return 0;
+ }
+ return sign * value;
+};
+
+/**
+ * The "rules for parsing floating-point number values" from the HTML spec.
+ * Returns false on error.
+ */
+ReflectionTests.parseFloat = function(input) {
+ var position = 0;
+ var value = 1;
+ var divisor = 1;
+ var exponent = 1;
+ // Skip whitespace
+ while (input.length > position && /^[ \t\n\f\r]$/.test(input[position])) {
+ position++;
+ }
+ if (position >= input.length) {
+ return false;
+ }
+ if (input[position] == "-") {
+ value = -1;
+ divisor = -1;
+ position++;
+ } else if (input[position] == "+") {
+ position++;
+ }
+ if (position >= input.length) {
+ return false;
+ }
+ if (input[position] == "." && position+1 < input.length && /^[0-9]$/.test(input[position+1])) {
+ value = 0;
+ // Use "else" branches rather than "jump to label fraction"
+ } else if (!/^[0-9]$/.test(input[position])) {
+ return false;
+ } else {
+ var val = 0;
+ while (input.length > position && /^[0-9]$/.test(input[position])) {
+ val *= 10;
+ // Don't use parseInt even for single-digit strings . . .
+ val += input.charCodeAt(position) - "0".charCodeAt(0);
+ position++;
+ }
+ value *= val;
+ }
+ // Use nested "if" tests rather than "jump to label conversion" or "skip"
+ // Fraction:
+ if (input.length > position && input[position] == ".") {
+ position++;
+ while (input.length > position && /^[0-9]$/.test(input[position])) {
+ divisor *= 10;
+ // Don't use parseInt even for single-digit strings . . .
+ value += (input.charCodeAt(position) - "0".charCodeAt(0)) / divisor;
+ position++;
+ }
+ }
+ if (input.length > position && (input[position] == "e" || input[position] == "E")) {
+ position++;
+ if (input.length > position) {
+ if (input[position] == "-") {
+ exponent = -1;
+ position++;
+ } else if (input[position] == "+") {
+ position++;
+ }
+ if (input.length > position && /^[0-9]$/.test(input[position])) {
+ var exp = 0;
+ do {
+ exp *= 10;
+ // Don't use parseInt even for single-digit strings . . .
+ exp += input.charCodeAt(position) - "0".charCodeAt(0);
+ position++;
+ } while (input.length > position && /^[0-9]$/.test(input[position]));
+ exponent *= exp;
+ value *= Math.pow(10, exponent);
+ }
+ }
+ }
+ // Conversion:
+ if (!Number.isFinite(value)) {
+ return false;
+ }
+ if (value === 0) {
+ return 0;
+ }
+ return value;
+}
+
+// Used in initializing typeMap
+var binaryString = "\x00\x01\x02\x03\x04\x05\x06\x07 "
+ + "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f "
+ + "\x10\x11\x12\x13\x14\x15\x16\x17 "
+ + "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f ";
+var maxInt = 2147483647;
+var minInt = -2147483648;
+var maxUnsigned = 4294967295;
+
+/**
+ * Array containing the tests and other information for each type of reflected
+ * attribute. Meaning of keys:
+ *
+ * "jsType": What typeof idlObj[idlName] is supposed to be.
+ * "defaultVal": The default value to be returned if the attribute is not
+ * present and no default is specifically set for this attribute.
+ * "domTests": What values to test with setAttribute().
+ * "domExpected": What values to expect with IDL get after setAttribute().
+ * Defaults to the same as domTests.
+ * "idlTests": What values to test with IDL set. Defaults to domTests.
+ * "idlDomExpected": What to expect from getAttribute() after IDL set.
+ * Defaults to idlTests.
+ * "idlIdlExpected": What to expect from IDL get after IDL set. Defaults to
+ * idlDomExpected.
+ *
+ * Note that all tests/expected values are only baselines, and can be expanded
+ * with additional tests hardcoded into the function for particular types if
+ * necessary. For example, a special codepath is used for enums, and for
+ * IDL setters which throw an exception. null means "defaultVal" is the
+ * expected value. Expected DOM values are cast to strings by adding "".
+ *
+ * TODO: Test strings that aren't valid UTF-16. Desired behavior is not clear
+ * here at the time of writing, see
+ * http://www.w3.org/Bugs/Public/show_bug.cgi?id=12100
+ *
+ * TODO: Test deleting an IDL attribute, and maybe doing other fun stuff to it.
+ *
+ * TODO: Test IDL sets of integer types to out-of-range or other weird values.
+ * WebIDL says to wrap, but I'm not sure offhand if that's what we want.
+ *
+ * TODO: tokenlist, settable tokenlist, limited
+ */
+
+
+ReflectionTests.typeMap = {
+ /**
+ * "If a reflecting IDL attribute is a DOMString but doesn't fall into any
+ * of the above categories, then the getting and setting must be done in a
+ * transparent, case-preserving manner."
+ *
+ * The data object passed to reflects() can contain an optional key
+ * treatNullAsEmptyString, whose value is ignored. If it does contain the
+ * key, null will be cast to "" instead of "null", per WebIDL
+ * [TreatNullAs=EmptyString].
+ */
+ "string": {
+ "jsType": "string",
+ "defaultVal": "",
+ "domTests": ["", " " + binaryString + " foo ", undefined, 7, 1.5, "5%", "+100", ".5", true,
+ false, {"test": 6}, NaN, +Infinity, -Infinity, "\0", null,
+ {"toString":function(){return "test-toString";}},
+ {"valueOf":function(){return "test-valueOf";}, toString:null}
+ ]
+ },
+ /**
+ * "If a reflecting IDL attribute is a USVString attribute whose content
+ * attribute is defined to contain a URL, then on getting, if the content
+ * attribute is absent, the IDL attribute must return the empty string.
+ * Otherwise, the IDL attribute must parse the value of the content
+ * attribute relative to the element's node document and if that is
+ * successful, return the resulting URL string. If parsing fails, then the
+ * value of the content attribute must be returned instead, converted to a
+ * USVString. On setting, the content attribute must be set to the specified
+ * new value."
+ *
+ * Also HTMLHyperLinkElementUtils href, used by a.href and area.href
+ */
+ "url": {
+ "jsType": "string",
+ "defaultVal": "",
+ "domTests": ["", " foo ", "http://site.example/",
+ "//site.example/path???@#l", binaryString, undefined, 7, 1.5, "5%", "+100", ".5", true,
+ false, {"test": 6}, NaN, +Infinity, -Infinity, "\0", null,
+ {"toString":function(){return "test-toString";}},
+ {"valueOf":function(){return "test-valueOf";}, toString:null}],
+ "domExpected": ReflectionTests.resolveUrl,
+ "idlIdlExpected": ReflectionTests.resolveUrl
+ },
+ /**
+ * "If a reflecting IDL attribute is a DOMString whose content attribute is
+ * an enumerated attribute, and the IDL attribute is limited to only known
+ * values, then, on getting, the IDL attribute must return the conforming
+ * value associated with the state the attribute is in (in its canonical
+ * case), or the empty string if the attribute is in a state that has no
+ * associated keyword value; and on setting, if the new value is an ASCII
+ * case-insensitive match for one of the keywords given for that attribute,
+ * then the content attribute must be set to the conforming value
+ * associated with the state that the attribute would be in if set to the
+ * given new value, otherwise, if the new value is the empty string, then
+ * the content attribute must be removed, otherwise, the content attribute
+ * must be set to the given new value."
+ *
+ * "Some attributes are defined as taking one of a finite set of keywords.
+ * Such attributes are called enumerated attributes. The keywords are each
+ * defined to map to a particular state (several keywords might map to the
+ * same state, in which case some of the keywords are synonyms of each
+ * other; additionally, some of the keywords can be said to be
+ * non-conforming, and are only in the specification for historical
+ * reasons). In addition, two default states can be given. The first is the
+ * invalid value default, the second is the missing value default.
+ *
+ * . . .
+ *
+ * When the attribute is specified, if its value is an ASCII
+ * case-insensitive match for one of the given keywords then that keyword's
+ * state is the state that the attribute represents. If the attribute value
+ * matches none of the given keywords, but the attribute has an invalid
+ * value default, then the attribute represents that state. Otherwise, if
+ * the attribute value matches none of the keywords but there is a missing
+ * value default state defined, then that is the state represented by the
+ * attribute. Otherwise, there is no default, and invalid values must be
+ * ignored.
+ *
+ * When the attribute is not specified, if there is a missing value default
+ * state defined, then that is the state represented by the (missing)
+ * attribute. Otherwise, the absence of the attribute means that there is
+ * no state represented."
+ *
+ * This is only used for enums that are limited to known values, not other
+ * enums (those are treated as generic strings by the spec). The data
+ * object passed to reflects() can contain these keys:
+ *
+ * "defaultVal": missing value default (defaults to "")
+ * "invalidVal": invalid value default (defaults to defaultVal)
+ * "keywords": array of keywords as given by the spec (required)
+ * "nonCanon": dictionary mapping non-canonical values to their
+ * canonical equivalents (defaults to {})
+ * "isNullable": Indicates if attribute is nullable (defaults to false)
+ *
+ * Tests are mostly hardcoded into reflects(), since they depend on the
+ * keywords. All expected values are computed in reflects() using a helper
+ * function.
+ */
+ "enum": {
+ "jsType": "string",
+ "defaultVal": "",
+ "domTests": ["", " " + binaryString + " foo ", undefined, 7, 1.5, "5%", "+100", ".5", true,
+ false, {"test": 6}, NaN, +Infinity, -Infinity, "\0", null,
+ {"toString":function(){return "test-toString";}},
+ {"valueOf":function(){return "test-valueOf";}, toString:null}]
+ },
+ /**
+ * "If a reflecting IDL attribute is a boolean attribute, then on getting
+ * the IDL attribute must return true if the content attribute is set, and
+ * false if it is absent. On setting, the content attribute must be removed
+ * if the IDL attribute is set to false, and must be set to the empty
+ * string if the IDL attribute is set to true. (This corresponds to the
+ * rules for boolean content attributes.)"
+ */
+ "boolean": {
+ "jsType": "boolean",
+ "defaultVal": false,
+ "domTests": ["", " foo ", undefined, null, 7, 1.5, "5%", "+100", ".5", true, false,
+ {"test": 6}, NaN, +Infinity, -Infinity, "\0",
+ {"toString":function(){return "test-toString";}},
+ {"valueOf":function(){return "test-valueOf";}, toString:null}],
+ "domExpected": function(val) {
+ return true;
+ }
+ },
+ /**
+ * "If a reflecting IDL attribute is a signed integer type (long) then, on
+ * getting, the content attribute must be parsed according to the rules for
+ * parsing signed integers, and if that is successful, and the value is in
+ * the range of the IDL attribute's type, the resulting value must be
+ * returned. If, on the other hand, it fails or returns an out of range
+ * value, or if the attribute is absent, then the default value must be
+ * returned instead, or 0 if there is no default value. On setting, the
+ * given value must be converted to the shortest possible string
+ * representing the number as a valid integer and then that string must be
+ * used as the new content attribute value."
+ */
+ "long": {
+ "jsType": "number",
+ "defaultVal": 0,
+ "domTests": [-36, -1, 0, 1, maxInt, minInt, maxInt + 1, minInt - 1,
+ maxUnsigned, maxUnsigned + 1, "", "-", "+", "-1", "-0", "0", "1",
+ " " + binaryString + " foo ",
+ // Test various different whitespace. Only 20, 9, A, C,
+ // and D are whitespace.
+ "\u00097", "\u000B7", "\u000C7", "\u00207", "\u00A07", "\uFEFF7",
+ "\u000A7", "\u000D7", "\u20287", "\u20297", "\u16807", "\u180E7",
+ "\u20007", "\u20017", "\u20027", "\u20037", "\u20047", "\u20057",
+ "\u20067", "\u20077", "\u20087", "\u20097", "\u200A7", "\u202F7", "\u30007",
+ "\t\u000B7", "\n\u000B7","\f\u000B7", "\r\u000B7", "\x20\u000B7", "7\u000B",
+ undefined, 1.5, "5%", "+100", ".5", true, false, {"test": 6}, NaN, +Infinity,
+ -Infinity, "\0",
+ {toString:function() {return 2;}, valueOf: null},
+ {valueOf:function() {return 3;}, toString: null}],
+ "domExpected": function(val) {
+ var parsed = ReflectionTests.parseInt(String(val));
+ if (parsed === false || parsed > maxInt || parsed < minInt) {
+ return null;
+ }
+ return parsed;
+ },
+ "idlTests": [-36, -1, 0, 1, 2147483647, -2147483648],
+ "idlDomExpected": [-36, -1, 0, 1, 2147483647, -2147483648]
+ },
+ /**
+ * "If a reflecting IDL attribute is a signed integer type (long) that is
+ * limited to only non-negative numbers then, on getting, the content
+ * attribute must be parsed according to the rules for parsing non-negative
+ * integers, and if that is successful, and the value is in the range of
+ * the IDL attribute's type, the resulting value must be returned. If, on
+ * the other hand, it fails or returns an out of range value, or if the
+ * attribute is absent, the default value must be returned instead, or −1
+ * if there is no default value. On setting, if the value is negative, the
+ * user agent must fire an INDEX_SIZE_ERR exception. Otherwise, the given
+ * value must be converted to the shortest possible string representing the
+ * number as a valid non-negative integer and then that string must be used
+ * as the new content attribute value."
+ */
+ "limited long": {
+ "jsType": "number",
+ "defaultVal": -1,
+ "domTests": [minInt - 1, minInt, -36, -1, -0, 0, 1, maxInt, maxInt + 1,
+ maxUnsigned, maxUnsigned + 1, "", "-", "+", "-1", "-0", "0", "1",
+ " " + binaryString + " foo ",
+ "\u00097", "\u000B7", "\u000C7", "\u00207", "\u00A07", "\uFEFF7",
+ "\u000A7", "\u000D7", "\u20287", "\u20297", "\u16807", "\u180E7",
+ "\u20007", "\u20017", "\u20027", "\u20037", "\u20047", "\u20057",
+ "\u20067", "\u20077", "\u20087", "\u20097", "\u200A7", "\u202F7", "\u30007",
+ "\t\u000B7", "\n\u000B7","\f\u000B7", "\r\u000B7", "\x20\u000B7", "7\u000B",
+ undefined, 1.5, "5%", "+100", ".5", true, false, {"test": 6}, NaN, +Infinity,
+ -Infinity, "\0",
+ {toString:function() {return 2;}, valueOf: null},
+ {valueOf:function() {return 3;}, toString: null}],
+ "domExpected": function(val) {
+ var parsed = ReflectionTests.parseNonneg(String(val));
+ if (parsed === false || parsed > maxInt || parsed < minInt) {
+ return null;
+ }
+ return parsed;
+ },
+ "idlTests": [minInt, -36, -1, 0, 1, maxInt],
+ "idlDomExpected": [null/*exception*/, null/*exception*/, null/*exception*/, 0, 1, maxInt]
+ },
+ /**
+ * "If a reflecting IDL attribute is an unsigned integer type (unsigned
+ * long) then, on getting, the content attribute must be parsed according
+ * to the rules for parsing non-negative integers, and if that is
+ * successful, and the value is in the range 0 to 2147483647 inclusive, the
+ * resulting value must be returned. If, on the other hand, it fails or
+ * returns an out of range value, or if the attribute is absent, the
+ * default value must be returned instead, or 0 if there is no default
+ * value. On setting, the given value must be converted to the shortest
+ * possible string representing the number as a valid non-negative integer
+ * and then that string must be used as the new content attribute value."
+ */
+ "unsigned long": {
+ "jsType": "number",
+ "defaultVal": 0,
+ "domTests": [minInt - 1, minInt, -36, -1, 0, 1, 257, maxInt,
+ maxInt + 1, maxUnsigned, maxUnsigned + 1, "", "-", "+", "-1", "-0", "0", "1",
+ "\u00097", "\u000B7", "\u000C7", "\u00207", "\u00A07", "\uFEFF7",
+ "\u000A7", "\u000D7", "\u20287", "\u20297", "\u16807", "\u180E7",
+ "\u20007", "\u20017", "\u20027", "\u20037", "\u20047", "\u20057",
+ "\u20067", "\u20077", "\u20087", "\u20097", "\u200A7", "\u202F7", "\u30007",
+ "\t\u000B7", "\n\u000B7","\f\u000B7", "\r\u000B7", "\x20\u000B7", "7\u000B",
+ " " + binaryString + " foo ", undefined, 1.5, "5%", "+100", ".5", true, false,
+ {"test": 6}, NaN, +Infinity, -Infinity, "\0",
+ {toString:function() {return 2;}, valueOf: null},
+ {valueOf:function() {return 3;}, toString: null}],
+ "domExpected": function(val) {
+ var parsed = ReflectionTests.parseNonneg(String(val));
+ // Note maxInt, not maxUnsigned.
+ if (parsed === false || parsed < 0 || parsed > maxInt) {
+ return null;
+ }
+ return parsed;
+ },
+ "idlTests": [0, 1, 257, maxInt, "-0", maxInt + 1, maxUnsigned],
+ "idlIdlExpected": [0, 1, 257, maxInt, 0, null, null],
+ "idlDomExpected": [0, 1, 257, maxInt, 0, null, null],
+ },
+ /**
+ * "If a reflecting IDL attribute is an unsigned integer type (unsigned
+ * long) that is limited to only non-negative numbers greater than zero,
+ * then the behavior is similar to the previous case, but zero is not
+ * allowed. On getting, the content attribute must first be parsed
+ * according to the rules for parsing non-negative integers, and if that is
+ * successful, and the value is in the range 1 to 2147483647 inclusive, the
+ * resulting value must be returned. If, on the other hand, it fails or
+ * returns an out of range value, or if the attribute is absent, the
+ * default value must be returned instead, or 1 if there is no default
+ * value. On setting, if the value is zero, the user agent must fire an
+ * INDEX_SIZE_ERR exception. Otherwise, the given value must be converted
+ * to the shortest possible string representing the number as a valid
+ * non-negative integer and then that string must be used as the new
+ * content attribute value."
+ */
+ "limited unsigned long": {
+ "jsType": "number",
+ "defaultVal": 1,
+ "domTests": [minInt - 1, minInt, -36, -1, 0, 1, maxInt,
+ maxInt + 1, maxUnsigned, maxUnsigned + 1, "", "-", "+", "-1", "-0", "0", "1",
+ "\u00097", "\u000B7", "\u000C7", "\u00207", "\u00A07", "\uFEFF7",
+ "\u000A7", "\u000D7", "\u20287", "\u20297", "\u16807", "\u180E7",
+ "\u20007", "\u20017", "\u20027", "\u20037", "\u20047", "\u20057",
+ "\u20067", "\u20077", "\u20087", "\u20097", "\u200A7", "\u202F7", "\u30007",
+ "\t\u000B7", "\n\u000B7","\f\u000B7", "\r\u000B7", "\x20\u000B7", "7\u000B",
+ " " + binaryString + " foo ", undefined, 1.5, "5%", "+100", ".5", true, false,
+ {"test": 6}, NaN, +Infinity, -Infinity, "\0",
+ {toString:function() {return 2;}, valueOf: null},
+ {valueOf:function() {return 3;}, toString: null}],
+ "domExpected": function(val) {
+ var parsed = ReflectionTests.parseNonneg(String(val));
+ // Note maxInt, not maxUnsigned.
+ if (parsed === false || parsed < 1 || parsed > maxInt) {
+ return null;
+ }
+ return parsed;
+ },
+ "idlTests": [0, 1, maxInt, maxInt + 1, maxUnsigned],
+ "idlDomExpected": [null/*exception*/, 1, maxInt, null, null]
+ },
+ /**
+ * "If a reflecting IDL attribute has an unsigned integer type (unsigned
+ * long) that is limited to only non-negative numbers greater than zero
+ * with fallback, then the behaviour is similar to the previous case, but
+ * disallowed values are converted to the default value. On getting, the
+ * content attribute must first be parsed according to the rules for
+ * parsing non-negative integers, and if that is successful, and the value
+ * is in the range 1 to 2147483647 inclusive, the resulting value must be
+ * returned. If, on the other hand, it fails or returns an out of range
+ * value, or if the attribute is absent, the default value must be returned
+ * instead. On setting, first, if the new value is in the range 1 to
+ * 2147483647, then let n be the new value, otherwise let n be the default
+ * value; then, n must be converted to the shortest possible string
+ * representing the number as a valid non-negative integer and that string
+ * must be used as the new content attribute value."
+ */
+ "limited unsigned long with fallback": {
+ "jsType": "number",
+ "domTests": [minInt - 1, minInt, -36, -1, 0, 1, maxInt,
+ maxInt + 1, maxUnsigned, maxUnsigned + 1, "", "-", "+", "-1", "-0", "0", "1",
+ "\u00097", "\u000B7", "\u000C7", "\u00207", "\u00A07", "\uFEFF7",
+ "\u000A7", "\u000D7", "\u20287", "\u20297", "\u16807", "\u180E7",
+ "\u20007", "\u20017", "\u20027", "\u20037", "\u20047", "\u20057",
+ "\u20067", "\u20077", "\u20087", "\u20097", "\u200A7", "\u202F7", "\u30007",
+ "\t\u000B7", "\n\u000B7","\f\u000B7", "\r\u000B7", "\x20\u000B7", "7\u000B",
+ " " + binaryString + " foo ", undefined, 1.5, "5%", "+100", ".5", true, false,
+ {"test": 6}, NaN, +Infinity, -Infinity, "\0",
+ {toString:function() {return 2;}, valueOf: null},
+ {valueOf:function() {return 3;}, toString: null}],
+ "domExpected": function(val) {
+ var parsed = ReflectionTests.parseNonneg(String(val));
+ // Note maxInt, not maxUnsigned.
+ if (parsed === false || parsed < 1 || parsed > maxInt) {
+ return null;
+ }
+ return parsed;
+ },
+ "idlTests": [0, 1, maxInt, maxInt + 1, maxUnsigned],
+ "idlDomExpected": [null, 1, maxInt, null, null]
+ },
+ /**
+ * "If a reflecting IDL attribute has an unsigned integer type (unsigned
+ * long) that is clamped to the range [min, max], then on getting, the
+ * content attribute must first be parsed according to the rules for
+ * parsing non-negative integers, and if that is successful, and the value
+ * is between min and max inclusive, the resulting value must be returned.
+ * If it fails, the default value must be returned. If it succeeds but the
+ * value is less than min, min must be returned. If it succeeds but the
+ * value is greater than max, max must be returned. On setting, it behaves
+ * the same as a regular reflected unsigned integer."
+ *
+ * The data object passed to reflects must contain the keys defaultVal,
+ * min, and max. As with enum, domExpected is generated later once we have
+ * access to the min and max.
+ */
+ "clamped unsigned long": {
+ "jsType": "number",
+ "domTests": [minInt - 1, minInt, -36, -1, 0, 1, maxInt,
+ maxInt + 1, maxUnsigned, maxUnsigned + 1, "", "-", "+", "-1", "-0", "0", "1",
+ "\u00097", "\u000B7", "\u000C7", "\u00207", "\u00A07", "\uFEFF7",
+ "\u000A7", "\u000D7", "\u20287", "\u20297", "\u16807", "\u180E7",
+ "\u20007", "\u20017", "\u20027", "\u20037", "\u20047", "\u20057",
+ "\u20067", "\u20077", "\u20087", "\u20097", "\u200A7", "\u202F7", "\u30007",
+ "\t\u000B7", "\n\u000B7","\f\u000B7", "\r\u000B7", "\x20\u000B7", "7\u000B",
+ " " + binaryString + " foo ", undefined, 1.5, "5%", "+100", ".5", true, false,
+ {"test": 6}, NaN, +Infinity, -Infinity, "\0",
+ {toString:function() {return 2;}, valueOf: null},
+ {valueOf:function() {return 3;}, toString: null}],
+ "idlTests": [0, 1, 257, maxInt, "-0", maxInt + 1, maxUnsigned],
+ "idlDomExpected": [0, 1, 257, maxInt, 0, null, null],
+ },
+ /**
+ * "If a reflecting IDL attribute is a floating point number type (double),
+ * then, on getting, the content attribute must be parsed according to the
+ * rules for parsing floating point number values, and if that is
+ * successful, the resulting value must be returned. If, on the other hand,
+ * it fails, or if the attribute is absent, the default value must be
+ * returned instead, or 0.0 if there is no default value. On setting, the
+ * given value must be converted to the best representation of the number
+ * as a floating point number and then that string must be used as the new
+ * content attribute value."
+ *
+ * TODO: Check this:
+ *
+ * "Except where otherwise specified, if an IDL attribute that is a
+ * floating point number type (double) is assigned an Infinity or
+ * Not-a-Number (NaN) value, a NOT_SUPPORTED_ERR exception must be raised."
+ */
+ "double": {
+ "jsType": "number",
+ "defaultVal": 0.0,
+ "domTests": [minInt - 1, minInt, -36, -1, 0, 1, maxInt,
+ maxInt + 1, maxUnsigned, maxUnsigned + 1, "", "-", "+",
+ "\u00097", "\u000B7", "\u000C7", "\u00207", "\u00A07", "\uFEFF7",
+ "\u000A7", "\u000D7", "\u20287", "\u20297", "\u16807", "\u180E7",
+ "\u20007", "\u20017", "\u20027", "\u20037", "\u20047", "\u20057",
+ "\u20067", "\u20077", "\u20087", "\u20097", "\u200A7", "\u202F7", "\u30007",
+ "\t\u000B7", "\n\u000B7","\f\u000B7", "\r\u000B7", "\x20\u000B7", "7\u000B",
+ " " + binaryString + " foo ", undefined, 1.5, "5%", "+100", ".5", true, false,
+ "1.", "1e2", "1e+2", "1e-2", "1E2", "1E+2", "1E-2", "1.e2", "1.0e2",
+ "1. 1", "1 .1", "1. e2", "1 .e2", "1 e2", "1e 2", "1e -2", "1e- 2",
+ "1.8e308", "-1.8e308",
+ {"test": 6}, NaN, +Infinity, -Infinity, "\0",
+ {toString:function() {return 2;}, valueOf: null},
+ {valueOf:function() {return 3;}, toString: null}],
+ "domExpected": function (val) {
+ var parsed = ReflectionTests.parseFloat(String(val));
+ if (parsed === false) {
+ return null;
+ }
+ return parsed;
+ },
+ "idlTests": [ -10000000000, -1, -0, 0, 1, 10000000000,
+ 1e-10, 1e-4, 1.5, 1e25 ],
+ "idlIdlExpected": function (val) {
+ // This is a bit heavy-weight but hopefully will give values
+ // that compare "better" (without introducing some tolerance)
+ // when the test cases are expanded with more values.
+ return ReflectionTests.parseFloat(String(val));
+ }
+ },
+ /**
+ * Reflected IDL attribute of type double, limited to only positive values,
+ * are similar to the previous case with the following exceptions:
+ *
+ * - on getting, if the parsed value is not greater than 0, then return
+ * the default value
+ * - on setting, if the value is not greater than 0, then return (leaving)
+ * the attribute to its previous value.
+ */
+ "limited double": {
+ "jsType": "number",
+ "defaultVal": 0.0,
+ "domTests": [minInt - 1, minInt, -36, -1, 0, 1, maxInt,
+ maxInt + 1, maxUnsigned, maxUnsigned + 1, "", "-", "+",
+ "\u00097", "\u000B7", "\u000C7", "\u00207", "\u00A07", "\uFEFF7",
+ "\u000A7", "\u000D7", "\u20287", "\u20297", "\u16807", "\u180E7",
+ "\u20007", "\u20017", "\u20027", "\u20037", "\u20047", "\u20057",
+ "\u20067", "\u20077", "\u20087", "\u20097", "\u200A7", "\u202F7", "\u30007",
+ "\t\u000B7", "\n\u000B7","\f\u000B7", "\r\u000B7", "\x20\u000B7", "7\u000B",
+ " " + binaryString + " foo ", undefined, 1.5, "5%", "+100", ".5", true, false,
+ "1.", "1e2", "1e+2", "1e-2", "1E2", "1E+2", "1E-2", "1.e2", "1.0e2",
+ "1. 1", "1 .1", "1. e2", "1 .e2", "1 e2", "1e 2", "1e -2", "1e- 2",
+ "1.8e308", "-1.8e308",
+ {"test": 6}, NaN, +Infinity, -Infinity, "\0",
+ {toString:function() {return 2;}, valueOf: null},
+ {valueOf:function() {return 3;}, toString: null}],
+ "domExpected": function (val) {
+ var parsed = ReflectionTests.parseFloat(String(val));
+ if (parsed === false || parsed <= 0) {
+ return null;
+ }
+ return parsed;
+ },
+ "idlTests": [ -10000000000, -1, -0, 0, 1, 10000000000,
+ 1e-10, 1e-4, 1.5, 1e25 ],
+ "idlIdlExpected": function (val) {
+ // Non-positive values are special-cased below, as they
+ // should be ignored, leaving the current value unchanged
+
+ // This is a bit heavy-weight but hopefully will give values
+ // that compare "better" (without introducing some tolerance)
+ // when the test cases are expanded with more values.
+ return ReflectionTests.parseFloat(String(val));
+ }
+ }
+};
+
+for (var type in ReflectionTests.typeMap) {
+ var props = ReflectionTests.typeMap[type];
+ var cast = window[props.jsType[0].toUpperCase() + props.jsType.slice(1)];
+ if (props.domExpected === undefined) {
+ props.domExpected = props.domTests.map(cast);
+ } else if (typeof props.domExpected == "function") {
+ props.domExpected = props.domTests.map(props.domExpected);
+ }
+ if (props.idlTests === undefined) {
+ props.idlTests = props.domTests;
+ }
+ if (props.idlDomExpected === undefined) {
+ props.idlDomExpected = props.idlTests.map(cast);
+ } else if (typeof props.idlDomExpected == "function") {
+ props.idlDomExpected = props.idlTests.map(props.idlDomExpected);
+ }
+ if (props.idlIdlExpected === undefined) {
+ props.idlIdlExpected = props.idlDomExpected;
+ } else if (typeof props.idlIdlExpected == "function") {
+ props.idlIdlExpected = props.idlTests.map(props.idlIdlExpected);
+ }
+}
+
+/**
+ * Tests that the JavaScript attribute named idlName on the object idlObj
+ * reflects the DOM attribute named domName on domObj. The data argument is an
+ * object that must contain at least one key, "type", which contains the
+ * expected type of the IDL attribute ("string", "enum", etc.). The "comment"
+ * key will add a parenthesized comment in the type info if there's a test
+ * failure, to indicate that there's something special about the element you're
+ * testing (like it has an attribute set to some value). Other keys in the
+ * data object are type-specific, e.g., "defaultVal" for numeric types. If the
+ * data object is a string, it's converted to {"type": data}. If idlObj is a
+ * string, we set idlObj = domObj = document.createElement(idlObj).
+ */
+ReflectionTests.reflects = function(data, idlName, idlObj, domName, domObj) {
+ // Do some setup first so that getTypeDescription() works in testWrapper()
+ if (typeof data == "string") {
+ data = {type: data};
+ }
+ if (domName === undefined) {
+ domName = idlName;
+ }
+ if (typeof idlObj == "string") {
+ idlObj = document.createElement(idlObj);
+ }
+ if (domObj === undefined) {
+ domObj = idlObj;
+ }
+
+ // Note: probably a hack? This kind of assumes that the variables here
+ // won't change over the course of the tests, which is wrong, but it's
+ // probably safe enough. Just don't read stuff that will change.
+ ReflectionHarness.currentTestInfo = {data: data, idlName: idlName, idlObj: idlObj, domName: domName, domObj: domObj};
+
+ // If we don't recognize the type, testing is impossible.
+ if (this.typeMap[data.type] === undefined) {
+ if (unimplemented.indexOf(data.type) == -1) {
+ unimplemented.push(data.type);
+ }
+ return;
+ }
+
+ var typeInfo = this.typeMap[data.type];
+
+ if (typeof data.isNullable == "undefined") {
+ data.isNullable = false;
+ }
+
+ // Test that typeof idlObj[idlName] is correct. If not, further tests are
+ // probably pointless, so bail out if we're not running conformance tests.
+ var expectedType = data.isNullable && data.defaultVal === null ? "object"
+ : typeInfo.jsType;
+ ReflectionHarness.test(function() {
+ ReflectionHarness.assertEquals(typeof idlObj[idlName], expectedType);
+ }, "typeof IDL attribute");
+
+ if (!ReflectionHarness.conformanceTesting &&
+ typeof idlObj[idlName] !== expectedType) {
+ return;
+ }
+
+ // Test default
+ var defaultVal = data.defaultVal;
+ if (defaultVal === undefined) {
+ defaultVal = typeInfo.defaultVal;
+ }
+ if ((domObj.localName === "form" && domName === "action") ||
+ (["button", "input"].includes(domObj.localName) &&
+ domName === "formAction")) {
+ // Hard-coded special case
+ defaultVal = domObj.ownerDocument.URL;
+ }
+ if (!data.customGetter && (defaultVal !== null || data.isNullable)) {
+ ReflectionHarness.test(function() {
+ ReflectionHarness.assertEquals(idlObj[idlName], defaultVal);
+ }, "IDL get with DOM attribute unset");
+ }
+
+ var domTests = typeInfo.domTests.slice(0);
+ var domExpected = typeInfo.domExpected.map(function(val) { return val === null ? defaultVal : val; });
+ var idlTests = typeInfo.idlTests.slice(0);
+ var idlDomExpected = typeInfo.idlDomExpected.map(function(val) { return val === null ? defaultVal : val; });
+ var idlIdlExpected = typeInfo.idlIdlExpected.map(function(val) { return val === null ? defaultVal : val; });
+ switch (data.type) {
+ // Extra tests and other special-casing
+ case "boolean":
+ domTests.push(domName);
+ domExpected.push(true);
+ break;
+
+ case "enum":
+ // Whee, enum is complicated.
+ if (typeof data.invalidVal == "undefined") {
+ data.invalidVal = defaultVal;
+ }
+ if (typeof data.nonCanon == "undefined") {
+ data.nonCanon = {};
+ }
+ for (var i = 0; i < data.keywords.length; i++) {
+ if (data.keywords[i] != "") {
+ domTests.push(data.keywords[i], "x" + data.keywords[i], data.keywords[i] + "\0");
+ idlTests.push(data.keywords[i], "x" + data.keywords[i], data.keywords[i] + "\0");
+ }
+
+ if (data.keywords[i].length > 1) {
+ var sliced = data.keywords[i].slice(1);
+ // If slicing a value yields another valid value, then skip it since it results in duplicate tests.
+ if (data.keywords.indexOf(sliced) == -1) {
+ domTests.push(sliced);
+ idlTests.push(sliced);
+ }
+ }
+
+ if (data.keywords[i] != data.keywords[i].toLowerCase()) {
+ domTests.push(data.keywords[i].toLowerCase());
+ idlTests.push(data.keywords[i].toLowerCase());
+ }
+ if (data.keywords[i] != data.keywords[i].toUpperCase()) {
+ domTests.push(data.keywords[i].toUpperCase());
+ idlTests.push(data.keywords[i].toUpperCase());
+ }
+ if (data.keywords[i].indexOf("k") != -1) {
+ domTests.push(data.keywords[i].replace(/k/g, "\u212A"));
+ idlTests.push(data.keywords[i].replace(/k/g, "\u212A"));
+ }
+ if (data.keywords[i].indexOf("s") != -1) {
+ domTests.push(data.keywords[i].replace(/s/g, "\u017F"));
+ idlTests.push(data.keywords[i].replace(/s/g, "\u017F"));
+ }
+ }
+
+ // Per spec, the expected DOM values are the same as the value we set
+ // it to.
+ if (!data.isNullable) {
+ idlDomExpected = idlTests.slice(0);
+ } else {
+ idlDomExpected = [];
+ for (var i = 0; i < idlTests.length; i++) {
+ idlDomExpected.push((idlTests[i] === null || idlTests[i] === undefined) ? null : idlTests[i]);
+ }
+ }
+
+ // Now we have the fun of calculating what the expected IDL values are.
+ domExpected = [];
+ idlIdlExpected = [];
+ for (var i = 0; i < domTests.length; i++) {
+ domExpected.push(this.enumExpected(data.keywords, data.nonCanon, data.invalidVal, domTests[i]));
+ }
+ for (var i = 0; i < idlTests.length; i++) {
+ if (data.isNullable && (idlTests[i] === null || idlTests[i] === undefined)) {
+ idlIdlExpected.push(null);
+ } else {
+ idlIdlExpected.push(this.enumExpected(data.keywords, data.nonCanon, data.invalidVal, idlTests[i]));
+ }
+ }
+ break;
+
+ case "string":
+ if ("treatNullAsEmptyString" in data) {
+ for (var i = 0; i < idlTests.length; i++) {
+ if (idlTests[i] === null) {
+ idlDomExpected[i] = idlIdlExpected[i] = "";
+ }
+ }
+ }
+ break;
+
+ case "clamped unsigned long":
+ [data.min - 1, data.min, data.max, data.max + 1].forEach(function(val) {
+ if (domTests.indexOf(val) == -1) {
+ domTests.push(val);
+ }
+ if (idlTests.indexOf(val) == -1 && 0 <= val && val <= maxUnsigned) {
+ idlTests.push(val);
+ if (typeof val != "number") {
+ val = ReflectionTests.parseNonneg(val);
+ }
+ idlDomExpected.push(val > maxInt ? null : val);
+ }
+ });
+
+ // Rewrite expected values
+ domExpected = domTests.map(function(val) {
+ var parsed = ReflectionTests.parseNonneg(String(val));
+ if (parsed === false) {
+ return defaultVal;
+ }
+ if (parsed < data.min) {
+ return data.min;
+ }
+ if (parsed > data.max) {
+ return data.max;
+ }
+ return parsed;
+ });
+ idlIdlExpected = idlTests.map(function(val) {
+ if (typeof val != "number") {
+ val = ReflectionTests.parseNonneg(val);
+ }
+ if (val < 0 || val > maxUnsigned) {
+ throw "Test bug: val should be an unsigned long";
+ }
+ if (val > maxInt) {
+ return defaultVal;
+ }
+ if (val < data.min) {
+ return data.min;
+ }
+ if (val > data.max) {
+ return data.max;
+ }
+ return val;
+ });
+ break;
+ }
+ if (domObj.tagName.toLowerCase() == "canvas" && (domName == "width" || domName == "height")) {
+ // Opera tries to allocate a canvas with the given width and height, so
+ // it OOMs when given excessive sizes. This is permissible under the
+ // hardware-limitations clause, so cut out those checks. TODO: Must be
+ // a way to make this more succinct.
+ domTests = domTests.filter(function(element, index, array) { return domExpected[index] < 1000; });
+ domExpected = domExpected.filter(function(element, index, array) { return element < 1000; });
+ idlTests = idlTests.filter(function(element, index, array) { return idlIdlExpected[index] < 1000; });
+ idlDomExpected = idlDomExpected.filter(function(element, index, array) { return idlIdlExpected[index] < 1000; });
+ idlIdlExpected = idlIdlExpected.filter(function(element, index, array) { return idlIdlExpected[index] < 1000; });
+ }
+ if ((domObj.localName === "form" && domName === "action") ||
+ (["button", "input"].includes(domObj.localName) &&
+ domName === "formAction")) {
+ // Hard-coded special case
+ for (var i = 0; i < domTests.length; i++) {
+ if (domTests[i] === "") {
+ domExpected[i] = domObj.ownerDocument.URL;
+ }
+ }
+ for (var i = 0; i < idlTests.length; i++) {
+ if (idlTests[i] === "") {
+ idlIdlExpected[i] = domObj.ownerDocument.URL;
+ }
+ }
+ }
+ if (data.customGetter) {
+ // These are reflected only on setting, not getting
+ domTests = [];
+ domExpected = [];
+ idlIdlExpected = idlIdlExpected.map(() => null);
+ }
+
+ for (var i = 0; i < domTests.length; i++) {
+ if (domExpected[i] === null && !data.isNullable) {
+ // If you follow all the complicated logic here, you'll find that
+ // this will only happen if there's no expected value at all (like
+ // for tabIndex, where the default is too complicated). So skip
+ // the test.
+ continue;
+ }
+ ReflectionHarness.test(function() {
+ domObj.setAttribute(domName, domTests[i]);
+ ReflectionHarness.assertEquals(domObj.getAttribute(domName),
+ String(domTests[i]), "getAttribute()");
+ ReflectionHarness.assertEquals(idlObj[idlName], domExpected[i],
+ "IDL get");
+ }, "setAttribute() to " + ReflectionHarness.stringRep(domTests[i]));
+ }
+
+ for (var i = 0; i < idlTests.length; i++) {
+ ReflectionHarness.test(function() {
+ if ((data.type == "limited long" && idlTests[i] < 0) ||
+ (data.type == "limited unsigned long" && idlTests[i] == 0)) {
+ ReflectionHarness.assertThrows("IndexSizeError", function() {
+ idlObj[idlName] = idlTests[i];
+ });
+ } else if (data.type == "limited double" && idlTests[i] <= 0) {
+ domObj.setAttribute(domName, "previous value");
+ var previousIdl = idlObj[idlName]; // should be the default value
+ idlObj[idlName] = idlTests[i];
+ ReflectionHarness.assertEquals(domObj.getAttribute(domName),
+ "previous value", "getAttribute()");
+ ReflectionHarness.assertEquals(idlObj[idlName], previousIdl, "IDL get");
+ } else {
+ idlObj[idlName] = idlTests[i];
+ if (data.type == "boolean") {
+ // Special case yay
+ ReflectionHarness.assertEquals(domObj.hasAttribute(domName),
+ Boolean(idlTests[i]), "hasAttribute()");
+ } else if (idlDomExpected[i] !== null || data.isNullable) {
+ var expected = idlDomExpected[i] + "";
+ if (data.isNullable && idlDomExpected[i] === null) {
+ expected = null;
+ }
+ ReflectionHarness.assertEquals(domObj.getAttribute(domName), expected,
+ "getAttribute()");
+ }
+ if (idlIdlExpected[i] !== null || data.isNullable) {
+ ReflectionHarness.assertEquals(idlObj[idlName], idlIdlExpected[i], "IDL get");
+ }
+ }
+ }, "IDL set to " + ReflectionHarness.stringRep(idlTests[i]));
+ }
+};
+
+function toASCIILowerCase(str) {
+ return str.replace(/[A-Z]/g, function(m) { return m.toLowerCase(); });
+}
+
+/**
+ * If we have an enumerated attribute limited to the array of values in
+ * keywords, with nonCanon being a map of non-canonical values to their
+ * canonical equivalents, and invalidVal being the invalid value default (or ""
+ * for none), then what would we expect from an IDL get if the content
+ * attribute is equal to contentVal?
+ */
+ReflectionTests.enumExpected = function(keywords, nonCanon, invalidVal, contentVal) {
+ var ret = invalidVal;
+ for (var i = 0; i < keywords.length; i++) {
+ if (toASCIILowerCase(String(contentVal)) === toASCIILowerCase(keywords[i])) {
+ ret = keywords[i];
+ break;
+ }
+ }
+ if (typeof nonCanon[ret] != "undefined") {
+ return nonCanon[ret];
+ }
+ return ret;
+};
+
+/**
+ * Now we have the data structures that tell us which elements have which
+ * attributes.
+ *
+ * The elements object (which must have been defined in earlier files) is a map
+ * from element name to an object whose keys are IDL attribute names and whose
+ * values are types. A type is of the same format as
+ * ReflectionTests.reflects() accepts, except that there's an extra optional
+ * domAttrName key that gets passed as the fourth argument to reflects() if
+ * it's provided. (TODO: drop the fourth and fifth reflects() arguments and
+ * make it take them from the dictionary instead?)
+ */
+
+// Now we actually run all the tests.
+var unimplemented = [];
+for (var element in elements) {
+ ReflectionTests.reflects("string", "title", element);
+ ReflectionTests.reflects("string", "lang", element);
+ ReflectionTests.reflects({type: "enum", keywords: ["ltr", "rtl", "auto"]}, "dir", element);
+ ReflectionTests.reflects("string", "className", element, "class");
+ ReflectionTests.reflects("tokenlist", "classList", element, "class");
+ ReflectionTests.reflects("boolean", "autofocus", element);
+ ReflectionTests.reflects("boolean", "hidden", element);
+ ReflectionTests.reflects("string", "accessKey", element);
+ // Don't try to test the defaultVal -- it should be either 0 or -1, but the
+ // rules are complicated, and a lot of them are SHOULDs.
+ ReflectionTests.reflects({type: "long", defaultVal: null}, "tabIndex", element);
+ // TODO: classList, contextMenu, itemProp, itemRef
+
+ for (var idlAttrName in elements[element]) {
+ var type = elements[element][idlAttrName];
+ ReflectionTests.reflects(type, idlAttrName, element,
+ typeof type == "object" && "domAttrName" in type ? type.domAttrName : idlAttrName);
+ }
+}
+
+for (var i = 0; i < extraTests.length; i++) {
+ extraTests[i]();
+}
+
+var time = document.getElementById("time");
+if (time) {
+ time.innerHTML = (new Date().getTime() - ReflectionTests.start)/1000;
+}
+
+if (unimplemented.length) {
+ var p = document.createElement("p");
+ p.textContent = "(Note: missing tests for types " + unimplemented.join(", ") + ".)";
+ document.body.appendChild(p);
+}
diff --git a/testing/web-platform/tests/html/dom/render-blocking/blocking-idl-attr.html b/testing/web-platform/tests/html/dom/render-blocking/blocking-idl-attr.html
new file mode 100644
index 0000000000..c33b411eb4
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/render-blocking/blocking-idl-attr.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<title>Tests the 'blocking' IDL attribute on link, script and style elements</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+// Tests that the 'blocking' attribute follows the IDL:
+// [SameObject, PutForwards=value] readonly attribute DOMTokenList blocking;
+
+test(() => {
+ const link = document.createElement('link');
+ assert_true(link.blocking.supports('render'));
+ assert_false(link.blocking.supports('asdf'));
+}, "Supported tokens of the 'blocking' IDL attribute of the link element");
+
+test(() => {
+ const link = document.createElement('link');
+ link.blocking = 'asdf';
+ assert_equals(link.blocking.value, 'asdf');
+}, "Setting the 'blocking' IDL attribute of the link element");
+
+test(() => {
+ const script = document.createElement('script');
+ assert_true(script.blocking.supports('render'));
+ assert_false(script.blocking.supports('asdf'));
+}, "Supported tokens of the 'blocking' IDL attribute of the script element");
+
+test(() => {
+ const script = document.createElement('script');
+ script.blocking = 'asdf';
+ assert_equals(script.blocking.value, 'asdf');
+}, "Setting the 'blocking' IDL attribute of the script element");
+
+test(() => {
+ const style = document.createElement('style');
+ assert_true(style.blocking.supports('render'));
+ assert_false(style.blocking.supports('asdf'));
+}, "Supported tokens of the 'blocking' IDL attribute of the style element");
+
+test(() => {
+ const style = document.createElement('style');
+ style.blocking = 'asdf';
+ assert_equals(style.blocking.value, 'asdf');
+}, "Setting the 'blocking' IDL attribute of the style element");
+</script>
diff --git a/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-001.tentative.html b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-001.tentative.html
new file mode 100644
index 0000000000..36567f9d54
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-001.tentative.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<head>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="support/utils.js"></script>
+<title>`link rel=expect` defers frames until href element is parsed</title>
+
+<link rel=expect href="#last" blocking="render">
+<script>
+async_test((t) => {
+ requestAnimationFrame(() => {
+ t.step(() => assert_true(!!document.getElementById("last")));
+ t.done();
+ });
+}, "blocking defers frames until full parsing");
+</script>
+</head>
+<body>
+ <div id="first"></div>
+ <script>
+ generateParserDelay();
+ </script>
+ <div id="second"></div>
+ <script>
+ generateParserDelay();
+ </script>
+ <div id="last"></div>
+</body>
diff --git a/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-002.tentative.html b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-002.tentative.html
new file mode 100644
index 0000000000..3c907597f7
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-002.tentative.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<head>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="support/utils.js"></script>
+<title>Frames starts after href element is parsed before the end</title>
+
+<link rel=expect href="#third" blocking="render">
+<script>
+async_test((t) => {
+ requestAnimationFrame(() => {
+ t.step(() => assert_true(!!document.getElementById("third")));
+ t.step(() => assert_false(!!document.getElementById("last")));
+ t.done();
+ });
+}, "blocking defers until needed element is parsed");
+</script>
+</head>
+<body>
+ <div id="first"></div>
+ <script>
+ generateParserDelay();
+ </script>
+ <div id="second"></div>
+ <script>
+ generateParserDelay();
+ </script>
+ <div id="third"></div>
+ <script>
+ generateParserDelay();
+ </script>
+ <div id="fourth"></div>
+ <script>
+ generateParserDelay();
+ </script>
+ <div id="last"></div>
+</body>
diff --git a/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-003.tentative.html b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-003.tentative.html
new file mode 100644
index 0000000000..2858798a35
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-003.tentative.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<head>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="support/utils.js"></script>
+<title>Adding link in the head has an effect</title>
+
+<script>
+let link = document.createElement("link");
+link.rel = "expect";
+link.href = "#last";
+link.blocking = "render";
+document.head.appendChild(link)
+
+async_test((t) => {
+ requestAnimationFrame(() => {
+ t.step(() => assert_true(!!document.getElementById("last")));
+ t.done();
+ });
+}, "adding link in the head defers frames");
+</script>
+</head>
+<body>
+ <div id="first"></div>
+ <script>
+ generateParserDelay();
+ </script>
+ <div id="second"></div>
+ <script>
+ generateParserDelay();
+ </script>
+ <div id="last"></div>
+</body>
diff --git a/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-004.tentative.html b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-004.tentative.html
new file mode 100644
index 0000000000..f45f558720
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-004.tentative.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<head>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="support/utils.js"></script>
+<title>Removing link in the head has an effect</title>
+
+<link id=link rel=expect href="#last" blocking="render">
+<script>
+link.remove();
+
+async_test((t) => {
+ requestAnimationFrame(() => {
+ t.step(() => assert_false(!!document.getElementById("last")));
+ t.done();
+ });
+}, "removing link in the head makes it no longer blocking");
+</script>
+</head>
+<body>
+ <div id="first"></div>
+ <script>
+ generateParserDelay();
+ </script>
+ <div id="second"></div>
+ <script>
+ generateParserDelay();
+ </script>
+ <div id="last"></div>
+</body>
diff --git a/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-005.tentative.html b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-005.tentative.html
new file mode 100644
index 0000000000..098a3c5767
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-005.tentative.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<head>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="support/utils.js"></script>
+<title>Removing blocking attr in the head has an effect</title>
+
+<link id=link rel=expect href="#last" blocking="render">
+<script>
+link.blocking = ""
+
+async_test((t) => {
+ requestAnimationFrame(() => {
+ t.step(() => assert_false(!!document.getElementById("last")));
+ t.done();
+ });
+}, "removing 'blocking' makes it no longer blocking");
+</script>
+</head>
+<body>
+ <div id="first"></div>
+ <script>
+ generateParserDelay();
+ </script>
+ <div id="second"></div>
+ <script>
+ generateParserDelay();
+ </script>
+ <div id="last"></div>
+</body>
diff --git a/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-006.tentative.html b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-006.tentative.html
new file mode 100644
index 0000000000..223e42109e
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-006.tentative.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<head>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="support/utils.js"></script>
+<title>Adding blocking attr in the head has an effect</title>
+
+<link id=link rel=expect href="#last">
+<script>
+link.blocking = "render"
+
+async_test((t) => {
+ requestAnimationFrame(() => {
+ t.step(() => assert_true(!!document.getElementById("last")));
+ t.done();
+ });
+}, "adding 'blocking=render' in the head makes it blocking");
+</script>
+</head>
+<body>
+ <div id="first"></div>
+ <script>
+ generateParserDelay();
+ </script>
+ <div id="second"></div>
+ <script>
+ generateParserDelay();
+ </script>
+ <div id="last"></div>
+</body>
diff --git a/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-007.tentative.html b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-007.tentative.html
new file mode 100644
index 0000000000..9aa0aeea79
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-007.tentative.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<head>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="support/utils.js"></script>
+<title>Media attribute that doesn't match makes the link not apply</title>
+
+<link rel=expect href="#last" blocking="render" media="(max-width: 10px)">
+<script>
+async_test((t) => {
+ requestAnimationFrame(() => {
+ t.step(() => assert_false(!!document.getElementById("last")));
+ t.done();
+ });
+}, "link with non-matching media has no effect");
+</script>
+</head>
+<body>
+ <div id="first"></div>
+ <script>
+ generateParserDelay();
+ </script>
+ <div id="second"></div>
+ <script>
+ generateParserDelay();
+ </script>
+ <div id="last"></div>
+</body>
diff --git a/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-008.tentative.html b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-008.tentative.html
new file mode 100644
index 0000000000..e671dda19c
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-008.tentative.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<head>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="support/utils.js"></script>
+<title>Media attribute changes in the head to apply</title>
+
+<link id=link rel=expect href="#last" blocking="render" media="(max-width: 10px)">
+<script>
+link.media = "(min-width: 10px)";
+
+async_test((t) => {
+ requestAnimationFrame(() => {
+ t.step(() => assert_true(!!document.getElementById("last")));
+ t.done();
+ });
+}, "changing media to matching causes link to have an effect");
+</script>
+</head>
+<body>
+ <div id="first"></div>
+ <script>
+ generateParserDelay();
+ </script>
+ <div id="second"></div>
+ <script>
+ generateParserDelay();
+ </script>
+ <div id="last"></div>
+</body>
diff --git a/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-009.tentative.html b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-009.tentative.html
new file mode 100644
index 0000000000..8498816ea5
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-009.tentative.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<head>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="support/utils.js"></script>
+<title>Media attribute changes in the head to not apply</title>
+
+<link id=link rel=expect href="#last" blocking="render" media="(min-width: 10px)">
+<script>
+link.media = "(max-width: 10px)";
+
+async_test((t) => {
+ requestAnimationFrame(() => {
+ t.step(() => assert_false(!!document.getElementById("last")));
+ t.done();
+ });
+}, "changing media to non-matching makes it non blocking");
+</script>
+</head>
+<body>
+ <div id="first"></div>
+ <script>
+ generateParserDelay();
+ </script>
+ <div id="second"></div>
+ <script>
+ generateParserDelay();
+ </script>
+ <div id="last"></div>
+</body>
diff --git a/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-010.tentative.html b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-010.tentative.html
new file mode 100644
index 0000000000..ef6f709012
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-010.tentative.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<head>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="support/utils.js"></script>
+<title>Rel attribute changes in the head to not apply</title>
+
+<link id=link rel=expect href="#last" blocking="render">
+<script>
+link.rel = "stylesheet";
+
+async_test((t) => {
+ requestAnimationFrame(() => {
+ t.step(() => assert_false(!!document.getElementById("last")));
+ t.done();
+ });
+}, "changing rel to non-expect makes it non blocking");
+</script>
+</head>
+<body>
+ <div id="first"></div>
+ <script>
+ generateParserDelay();
+ </script>
+ <div id="second"></div>
+ <script>
+ generateParserDelay();
+ </script>
+ <div id="last"></div>
+</body>
diff --git a/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-011.tentative.html b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-011.tentative.html
new file mode 100644
index 0000000000..dee82d8c59
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-011.tentative.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<head>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="support/utils.js"></script>
+<title>Rel attribute changes in the head to apply</title>
+
+<link id=link rel=stylesheet href="#last" blocking="render">
+<script>
+link.rel = "expect";
+
+async_test((t) => {
+ requestAnimationFrame(() => {
+ t.step(() => assert_true(!!document.getElementById("last")));
+ t.done();
+ });
+}, "changing rel to expect in the head causes it to be blocking");
+</script>
+</head>
+<body>
+ <div id="first"></div>
+ <script>
+ generateParserDelay();
+ </script>
+ <div id="second"></div>
+ <script>
+ generateParserDelay();
+ </script>
+ <div id="last"></div>
+</body>
diff --git a/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-012.tentative.html b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-012.tentative.html
new file mode 100644
index 0000000000..4110e54c5f
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-012.tentative.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<head>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="support/utils.js"></script>
+<title>Href attribute changes in the head to apply</title>
+
+<link id=link rel=expect href="" blocking="render">
+<script>
+link.href = "#last";
+
+async_test((t) => {
+ requestAnimationFrame(() => {
+ t.step(() => assert_true(!!document.getElementById("last")));
+ t.done();
+ });
+}, "adding href in the head makes it blocking");
+</script>
+</head>
+<body>
+ <div id="first"></div>
+ <script>
+ generateParserDelay();
+ </script>
+ <div id="second"></div>
+ <script>
+ generateParserDelay();
+ </script>
+ <div id="last"></div>
+</body>
diff --git a/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-013.tentative.html b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-013.tentative.html
new file mode 100644
index 0000000000..ecd97be86a
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-013.tentative.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<head>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="support/utils.js"></script>
+<title>Href attribute changes in the head to not apply</title>
+
+<link id=link rel=expect href="#last" blocking="render">
+<script>
+link.href = "";
+
+async_test((t) => {
+ requestAnimationFrame(() => {
+ t.step(() => assert_false(!!document.getElementById("last")));
+ t.done();
+ });
+}, "removing href makes it no longer blocking");
+</script>
+</head>
+<body>
+ <div id="first"></div>
+ <script>
+ generateParserDelay();
+ </script>
+ <div id="second"></div>
+ <script>
+ generateParserDelay();
+ </script>
+ <div id="last"></div>
+</body>
diff --git a/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-014.tentative.html b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-014.tentative.html
new file mode 100644
index 0000000000..ea8948de42
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-014.tentative.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<head>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="support/utils.js"></script>
+<title>Blocking link added in the body has no effect</title>
+
+<script>
+async_test((t) => {
+ requestAnimationFrame(() => {
+ t.step(() => assert_false(!!document.getElementById("last")));
+ t.done();
+ });
+}, "link in the body has no effect");
+</script>
+</head>
+<body>
+<link rel=expect href="#last" blocking="render">
+<script>
+let link = document.createElement("link");
+link.rel = "rel";
+link.href = "#last";
+link.blocking = "render";
+document.head.appendChild(link);
+</script>
+
+ <div id="first"></div>
+ <script>
+ generateParserDelay();
+ </script>
+ <div id="second"></div>
+ <script>
+ generateParserDelay();
+ </script>
+ <div id="last"></div>
+</body>
diff --git a/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-015.tentative.html b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-015.tentative.html
new file mode 100644
index 0000000000..a775ee4174
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-015.tentative.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<head>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="support/utils.js"></script>
+<title>Blocking link removed in the body has an effect</title>
+
+<link id=link rel=expect href="#last" blocking="render">
+<script>
+async_test((t) => {
+ requestAnimationFrame(() => {
+ t.step(() => assert_false(!!document.getElementById("last")));
+ t.done();
+ });
+}, "removing link the body makes it non blocking");
+</script>
+</head>
+<body>
+<script>
+link.remove();
+</script>
+
+ <div id="first"></div>
+ <script>
+ generateParserDelay();
+ </script>
+ <div id="second"></div>
+ <script>
+ generateParserDelay();
+ </script>
+ <div id="last"></div>
+</body>
diff --git a/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-016.tentative.html b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-016.tentative.html
new file mode 100644
index 0000000000..8968c5dacd
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-016.tentative.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<head>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="support/utils.js"></script>
+<title>Removing blocking attr in the body has an effect</title>
+
+<link id=link rel=expect href="#last" blocking="render">
+<script>
+async_test((t) => {
+ requestAnimationFrame(() => {
+ t.step(() => assert_false(!!document.getElementById("last")));
+ t.done();
+ });
+}, "removing 'blocking' in the body makes it non blocking");
+</script>
+</head>
+<body>
+<script>
+link.blocking = "";
+</script>
+
+ <div id="first"></div>
+ <script>
+ generateParserDelay();
+ </script>
+ <div id="second"></div>
+ <script>
+ generateParserDelay();
+ </script>
+ <div id="last"></div>
+</body>
diff --git a/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-017.tentative.html b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-017.tentative.html
new file mode 100644
index 0000000000..2d3b574721
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-017.tentative.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<head>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="support/utils.js"></script>
+<title>Adding blocking attr in the body has no effect</title>
+
+<link id=link rel=expect href="#last">
+<script>
+async_test((t) => {
+ requestAnimationFrame(() => {
+ t.step(() => assert_false(!!document.getElementById("last")));
+ t.done();
+ });
+}, "adding 'blocking=render' in the body has no effect");
+</script>
+</head>
+<body>
+<script>
+link.blocking = "render"
+</script>
+ <div id="first"></div>
+ <script>
+ generateParserDelay();
+ </script>
+ <div id="second"></div>
+ <script>
+ generateParserDelay();
+ </script>
+ <div id="last"></div>
+</body>
diff --git a/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-018.tentative.html b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-018.tentative.html
new file mode 100644
index 0000000000..76e6394b5b
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-018.tentative.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<head>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="support/utils.js"></script>
+<title>Media attribute changes in the body to apply, but has no effect</title>
+
+<link id=link rel=expect href="#last" blocking="render" media="(max-width: 10px)">
+<script>
+async_test((t) => {
+ requestAnimationFrame(() => {
+ t.step(() => assert_false(!!document.getElementById("last")));
+ t.done();
+ });
+}, "changing media to matching in the body has no effect");
+</script>
+</head>
+<body>
+<script>
+link.media = "(min-width: 10px)";
+</script>
+
+ <div id="first"></div>
+ <script>
+ generateParserDelay();
+ </script>
+ <div id="second"></div>
+ <script>
+ generateParserDelay();
+ </script>
+ <div id="last"></div>
+</body>
diff --git a/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-019.tentative.html b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-019.tentative.html
new file mode 100644
index 0000000000..80a7019edc
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-019.tentative.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<head>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="support/utils.js"></script>
+<title>Media attribute changes in the body to not apply</title>
+
+<link id=link rel=expect href="#last" blocking="render" media="(min-width: 10px)">
+<script>
+async_test((t) => {
+ requestAnimationFrame(() => {
+ t.step(() => assert_false(!!document.getElementById("last")));
+ t.done();
+ });
+}, "changing media to non-matching in the body makes it non blocking");
+</script>
+</head>
+<body>
+<script>
+link.media = "(max-width: 10px)";
+</script>
+
+ <div id="first"></div>
+ <script>
+ generateParserDelay();
+ </script>
+ <div id="second"></div>
+ <script>
+ generateParserDelay();
+ </script>
+ <div id="last"></div>
+</body>
diff --git a/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-020.tentative.html b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-020.tentative.html
new file mode 100644
index 0000000000..10019c943f
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-020.tentative.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<head>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="support/utils.js"></script>
+<title>Rel attribute changes in the body to not apply</title>
+
+<link id=link rel=expect href="#last" blocking="render">
+<script>
+async_test((t) => {
+ requestAnimationFrame(() => {
+ t.step(() => assert_false(!!document.getElementById("last")));
+ t.done();
+ });
+}, "changing rel to non-expect in the body makes it non blocking");
+</script>
+</head>
+<body>
+<script>
+link.rel = "stylesheet";
+</script>
+ <div id="first"></div>
+ <script>
+ generateParserDelay();
+ </script>
+ <div id="second"></div>
+ <script>
+ generateParserDelay();
+ </script>
+ <div id="last"></div>
+</body>
diff --git a/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-021.tentative.html b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-021.tentative.html
new file mode 100644
index 0000000000..1ca2114689
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-021.tentative.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<head>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="support/utils.js"></script>
+<title>Rel attribute changes in the body to apply, but has no effect</title>
+
+<link id=link rel=stylesheet href="#last" blocking="render">
+<script>
+async_test((t) => {
+ requestAnimationFrame(() => {
+ t.step(() => assert_false(!!document.getElementById("last")));
+ t.done();
+ });
+}, "changing rel to expect in the body has no effect");
+</script>
+</head>
+<body>
+<script>
+link.rel = "expect";
+</script>
+ <div id="first"></div>
+ <script>
+ generateParserDelay();
+ </script>
+ <div id="second"></div>
+ <script>
+ generateParserDelay();
+ </script>
+ <div id="third"></div>
+ <script>
+ generateParserDelay();
+ </script>
+ <div id="last"></div>
+</body>
diff --git a/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-022.tentative.html b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-022.tentative.html
new file mode 100644
index 0000000000..5dfbcac30a
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-022.tentative.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<head>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="support/utils.js"></script>
+<title>Href attribute changes in the body to apply, but has no effect</title>
+
+<link id=link rel=expect href="" blocking="render">
+<script>
+async_test((t) => {
+ requestAnimationFrame(() => {
+ t.step(() => assert_false(!!document.getElementById("last")));
+ t.done();
+ });
+}, "adding href in the body has no effect");
+</script>
+</head>
+<body>
+<script>
+link.href = "#last";
+</script>
+
+ <div id="first"></div>
+ <script>
+ generateParserDelay();
+ </script>
+ <div id="second"></div>
+ <script>
+ generateParserDelay();
+ </script>
+ <div id="last"></div>
+</body>
diff --git a/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-023.tentative.html b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-023.tentative.html
new file mode 100644
index 0000000000..8fe8b6a8c8
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-023.tentative.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<head>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="support/utils.js"></script>
+<title>Href attribute changes in the body to not apply</title>
+
+<link id=link rel=expect href="#last" blocking="render">
+<script>
+async_test((t) => {
+ requestAnimationFrame(() => {
+ t.step(() => assert_false(!!document.getElementById("last")));
+ t.done();
+ });
+}, "removing href in the body makes it non blocking");
+</script>
+</head>
+<body>
+<script>
+link.href = "";
+</script>
+ <div id="first"></div>
+ <script>
+ generateParserDelay();
+ </script>
+ <div id="second"></div>
+ <script>
+ generateParserDelay();
+ </script>
+ <div id="last"></div>
+</body>
diff --git a/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-024.tentative.html b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-024.tentative.html
new file mode 100644
index 0000000000..19e4020fb7
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-024.tentative.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<head>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="support/utils.js"></script>
+<title>Unknown href causes the whole document to be blocked</title>
+
+<link rel=expect href="#unknown" blocking="render">
+<script>
+async_test((t) => {
+ requestAnimationFrame(() => {
+ t.step(() => assert_true(!!document.getElementById("last")));
+ t.done();
+ });
+}, "unknown href causes the whole document to be blocked");
+</script>
+</head>
+<body>
+ <div id="first"></div>
+ <script>
+ generateParserDelay();
+ </script>
+ <div id="second"></div>
+ <script>
+ generateParserDelay();
+ </script>
+ <div id="third"></div>
+ <script>
+ generateParserDelay();
+ </script>
+ <div id="fourth"></div>
+ <script>
+ generateParserDelay();
+ </script>
+ <div id="last"></div>
+</body>
diff --git a/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-025.tentative.html b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-025.tentative.html
new file mode 100644
index 0000000000..689ae69f45
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-025.tentative.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<head>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="support/utils.js"></script>
+<title>Adding an id to parsed element satisfies render block</title>
+
+<link rel=expect href="#first" blocking="render">
+<script>
+async_test((t) => {
+ requestAnimationFrame(() => {
+ t.step(() => assert_true(!!document.getElementById("first")));
+ t.step(() => assert_false(!!document.getElementById("last")));
+ t.done();
+ });
+}, "adding an id in the body satisfies render block");
+</script>
+</head>
+<body>
+ <div id="willbefirst"></div>
+ <script>
+ willbefirst.id = "first";
+ generateParserDelay();
+ </script>
+ <div id="second"></div>
+ <script>
+ generateParserDelay();
+ </script>
+ <div id="third"></div>
+ <script>
+ generateParserDelay();
+ </script>
+ <div id="fourth"></div>
+ <script>
+ generateParserDelay();
+ </script>
+ <div id="last"></div>
+</body>
diff --git a/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-026.tentative.html b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-026.tentative.html
new file mode 100644
index 0000000000..6abfc43b8b
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-026.tentative.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<head>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="support/utils.js"></script>
+<title>Removing id keeps render block satisfied</title>
+
+<link rel=expect href="#first" blocking="render">
+<script>
+async_test((t) => {
+ requestAnimationFrame(() => {
+ t.step(() => assert_true(!!document.getElementById("wasfirst")));
+ t.step(() => assert_false(!!document.getElementById("last")));
+ t.done();
+ });
+}, "removing id after it was renderer keeps render block satisfied");
+</script>
+</head>
+<body>
+ <div id="first"></div>
+ <script>
+ first.id = "wasfirst";
+ generateParserDelay();
+ </script>
+ <div id="second"></div>
+ <script>
+ generateParserDelay();
+ </script>
+ <div id="third"></div>
+ <script>
+ generateParserDelay();
+ </script>
+ <div id="fourth"></div>
+ <script>
+ generateParserDelay();
+ </script>
+ <div id="last"></div>
+</body>
diff --git a/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-027.tentative.html b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-027.tentative.html
new file mode 100644
index 0000000000..56f88e0fc2
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-027.tentative.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<head>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="support/utils.js"></script>
+<title>Unknown href causes the whole document to be blocked</title>
+
+<link id=link rel=expect href="#unknown" blocking="render">
+<script>
+link.href = "#stillunknown";
+
+async_test((t) => {
+ requestAnimationFrame(() => {
+ t.step(() => assert_true(!!document.getElementById("last")));
+ t.done();
+ });
+}, "unknown href causes the whole document to be blocked (with href changes!)");
+</script>
+</head>
+<body>
+ <div id="notfirst"></div>
+ <script>
+ generateParserDelay();
+ </script>
+ <div id="second"></div>
+ <script>
+ generateParserDelay();
+ </script>
+ <div id="third"></div>
+ <script>
+ generateParserDelay();
+ </script>
+ <div id="fourth"></div>
+ <script>
+ generateParserDelay();
+ </script>
+ <div id="last"></div>
+</body>
diff --git a/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-028.tentative.html b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-028.tentative.html
new file mode 100644
index 0000000000..a64d542c4a
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/render-blocking/element-render-blocking-028.tentative.html
@@ -0,0 +1,48 @@
+<!DOCTYPE html>
+<head>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="support/utils.js"></script>
+<title>Multiple links and all but one removed</title>
+
+<link rel=expect href="#third" blocking="render">
+<link id=one rel=expect href="#third" blocking="render">
+<link id=two rel=expect href="#third" blocking="render">
+<link id=three rel=expect href="#third" blocking="render">
+<link id=four rel=expect href="#third" blocking="render">
+<script>
+async_test((t) => {
+ requestAnimationFrame(() => {
+ t.step(() => assert_true(!!document.getElementById("third")));
+ t.step(() => assert_false(!!document.getElementById("last")));
+ t.done();
+ });
+}, "removing some links but not all keeps at least the matching link blocking");
+
+one.remove();
+two.remove();
+</script>
+</head>
+<body>
+<script>
+three.remove();
+four.remove();
+</script>
+ <div id="first"></div>
+ <script>
+ generateParserDelay();
+ </script>
+ <div id="second"></div>
+ <script>
+ generateParserDelay();
+ </script>
+ <div id="third"></div>
+ <script>
+ generateParserDelay();
+ </script>
+ <div id="fourth"></div>
+ <script>
+ generateParserDelay();
+ </script>
+ <div id="last"></div>
+</body>
diff --git a/testing/web-platform/tests/html/dom/render-blocking/non-render-blocking-scripts.optional.html b/testing/web-platform/tests/html/dom/render-blocking/non-render-blocking-scripts.optional.html
new file mode 100644
index 0000000000..a4c32ea037
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/render-blocking/non-render-blocking-scripts.optional.html
@@ -0,0 +1,61 @@
+<!DOCTYPE html>
+<title>Tests when script is not implicitly potentially render-blocking</title>
+<link rel="help" href="https://github.com/whatwg/html/pull/7894">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="support/test-render-blocking.js"></script>
+
+<!--
+ The test is marked "optional" because even when the document is not
+ render-blocked, the user agent is still free to take other factors, which are
+ not limited by the spec, into consideration and therefore decide not to
+ render. However, it is still more desirable if rendering starts
+ immediately/soon.
+-->
+
+<script class="test" data="parser-inserted async script" async
+ src="support/dummy-1.js?pipe=trickle(d1)&async"></script>
+<script class="test" data="parser-inserted defer script" defer
+ src="support/dummy-1.js?pipe=trickle(d1)&defer"></script>
+<script class="test" data="parser-inserted module script" type="module"
+ src="support/dummy-1.mjs?pipe=trickle(d1)"></script>
+<script class="test" data="parser-inserted async module script" type="module"
+ async src="support/dummy-1.mjs?pipe=trickle(d1)&async"></script>
+
+<script>
+function addTestScriptElement(title, attributes) {
+ let element = document.createElement('script');
+ element.className = 'test';
+ element.setAttribute('data', title);
+ Object.assign(element, attributes);
+ document.head.appendChild(element);
+}
+
+addTestScriptElement('script-inserted script', {src: 'support/dummy-1.js?pipe=trickle(d1)&dynamic'});
+addTestScriptElement('script-inserted sync script', {async: false, src: 'support/dummy-1.js?pipe=trickle(d1)&dynamicSync'});
+addTestScriptElement('script-inserted module script', {type: 'module', src: 'support/dummy-1.mjs?pipe=trickle(d1)&dynamic'});
+</script>
+
+<div id="dummy">Some text</div>
+
+<script>
+const testElements = [...document.querySelectorAll('.test')];
+const loadObservers = testElements.map(element => new LoadObserver(element));
+
+promise_setup(async () => {
+ // Test cases are run after rendering is unblocked.
+ await new Promise(resolve => requestAnimationFrame(resolve));
+});
+
+for (let index = 0; index < testElements.length; ++index) {
+ promise_test(
+ async () => assert_false(loadObservers[index].finished),
+ testElements[index].getAttribute('data') + ' is not implicitly render-blocking');
+}
+
+for (let index = 0; index < testElements.length; ++index) {
+ promise_test(
+ () => loadObservers[index].load,
+ testElements[index].getAttribute('data') + ' should eventually be loaded and evaluated');
+}
+</script>
diff --git a/testing/web-platform/tests/html/dom/render-blocking/parser-blocking-script.html b/testing/web-platform/tests/html/dom/render-blocking/parser-blocking-script.html
new file mode 100644
index 0000000000..8d391144b2
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/render-blocking/parser-blocking-script.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<title>Parser-blocking script elements are implicitly render-blocking</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="support/test-render-blocking.js"></script>
+
+<script>
+// Add some renderable content before parser inserts body
+document.documentElement.appendChild(document.createTextNode('text'));
+
+// Test must be setup before the parser-blocking script
+test_render_blocking(
+ () => assert_equals(window.dummy, 1),
+ 'Parser-blocking script is evaluated');
+</script>
+
+<script src="support/dummy-1.js?pipe=trickle(d1)"></script>
+
+<div>Some more text</div>
diff --git a/testing/web-platform/tests/html/dom/render-blocking/parser-inserted-async-inline-module-with-import.html b/testing/web-platform/tests/html/dom/render-blocking/parser-inserted-async-inline-module-with-import.html
new file mode 100644
index 0000000000..50a2add277
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/render-blocking/parser-inserted-async-inline-module-with-import.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<head>
+<title>Parser-inserted async inline module script elements with "blocking=render" are render-blocking</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+ window.did_execute_script = false;
+</script>
+<script type="module" blocking="render" async>
+ import "/loading/resources/dummy.js?pipe=trickle(d1)";
+ window.did_execute_script = true;
+</script>
+</head>
+<div id="dummy">some text</div>
+
+<script>
+ promise_test(async t => {
+ await new Promise(resolve => requestAnimationFrame(() => resolve()));
+ assert_true(window.did_execute_script, "Parser-inserted async render-blocking inline module script should execute before rAF callback");
+ });
+</script>
diff --git a/testing/web-platform/tests/html/dom/render-blocking/parser-inserted-async-script.html b/testing/web-platform/tests/html/dom/render-blocking/parser-inserted-async-script.html
new file mode 100644
index 0000000000..4b2216dfcb
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/render-blocking/parser-inserted-async-script.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<title>Parser-inserted async script elements with "blocking=render" are render-blocking</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="support/test-render-blocking.js"></script>
+
+<script id="async-script" async blocking="render"
+ src="support/dummy-1.js?pipe=trickle(d1)">
+</script>
+
+<div>Some text</div>
+
+<script>
+const asyncScript = document.getElementById('async-script');
+test_render_blocking(
+ asyncScript,
+ () => assert_equals(window.dummy, 1),
+ 'Parser-inserted render-blocking async script is evaluated');
+</script>
diff --git a/testing/web-platform/tests/html/dom/render-blocking/parser-inserted-defer-script.html b/testing/web-platform/tests/html/dom/render-blocking/parser-inserted-defer-script.html
new file mode 100644
index 0000000000..1ae8caf2ec
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/render-blocking/parser-inserted-defer-script.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<title>Parser-inserted defer script elements with "blocking=render" are render-blocking</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="support/test-render-blocking.js"></script>
+
+<script id="defer-script" defer blocking="render"
+ src="support/dummy-1.js?pipe=trickle(d1)">
+</script>
+
+<div>Some text</div>
+
+<script>
+const deferScript = document.getElementById('defer-script');
+test_render_blocking(
+ deferScript,
+ () => assert_equals(window.dummy, 1),
+ 'Parser-inserted render-blocking defer script is evaluated');
+</script>
diff --git a/testing/web-platform/tests/html/dom/render-blocking/parser-inserted-inline-module-with-import.html b/testing/web-platform/tests/html/dom/render-blocking/parser-inserted-inline-module-with-import.html
new file mode 100644
index 0000000000..af2ac46aaf
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/render-blocking/parser-inserted-inline-module-with-import.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<head>
+<title>Parser-inserted module script elements with "blocking=render" are render-blocking</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+ window.did_execute_script = false;
+</script>
+<script type="module" blocking="render">
+ import "/loading/resources/dummy.js?pipe=trickle(d1)";
+ window.did_execute_script = true;
+</script>
+</head>
+<div id="dummy">some text</div>
+
+<script>
+ promise_test(async t => {
+ await new Promise(resolve => requestAnimationFrame(() => resolve()));
+ assert_true(window.did_execute_script, "Parser-inserted render-blocking inline module script should execute before rAF callback");
+ });
+</script>
diff --git a/testing/web-platform/tests/html/dom/render-blocking/parser-inserted-module-script.html b/testing/web-platform/tests/html/dom/render-blocking/parser-inserted-module-script.html
new file mode 100644
index 0000000000..2bca88e73c
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/render-blocking/parser-inserted-module-script.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<title>Parser-inserted module script elements with "blocking=render" are render-blocking</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="support/test-render-blocking.js"></script>
+
+<script id="module-script" type="module" blocking="render"
+ src="support/dummy-1.mjs?pipe=trickle(d1)">
+</script>
+
+<div id="dummy">some text</div>
+
+<script>
+const moduleScript = document.getElementById('module-script');
+test_render_blocking(
+ moduleScript,
+ () => assert_equals(document.getElementById('dummy').textContent, '1'),
+ 'Parser-inserted render-blocking module script is evaluated');
+</script>
diff --git a/testing/web-platform/tests/html/dom/render-blocking/parser-inserted-style-element.html b/testing/web-platform/tests/html/dom/render-blocking/parser-inserted-style-element.html
new file mode 100644
index 0000000000..9a358aa493
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/render-blocking/parser-inserted-style-element.html
@@ -0,0 +1,20 @@
+<!doctype html>
+<title>Parser-inserted style elements are implicitly render-blocking</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="support/test-render-blocking.js"></script>
+<script>
+// Test case must be set up before the stylesheet, because the stylesheet is
+// script-blocking, which means we can't set it up while the stylesheet is
+// loading.
+test_render_blocking(() => {
+ let color = getComputedStyle(document.querySelector('.target')).color;
+ assert_equals(color, 'rgb(255, 0, 0)');
+}, 'Render-blocking stylesheet is applied');
+</script>
+<style>
+@import url('support/target-red.css?pipe=trickle(d1)');
+</style>
+<div class="target">
+ This should be red
+</div>
diff --git a/testing/web-platform/tests/html/dom/render-blocking/parser-inserted-stylesheet-link.html b/testing/web-platform/tests/html/dom/render-blocking/parser-inserted-stylesheet-link.html
new file mode 100644
index 0000000000..0a771448fd
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/render-blocking/parser-inserted-stylesheet-link.html
@@ -0,0 +1,18 @@
+<!doctype html>
+<title>Parser-inserted stylesheet links are implicitly render-blocking</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="support/test-render-blocking.js"></script>
+<script>
+// Test case must be set up before the stylesheet, because the stylesheet is
+// script-blocking, which means we can't set it up while the stylesheet is
+// loading.
+test_render_blocking(() => {
+ let color = getComputedStyle(document.querySelector('.target')).color;
+ assert_equals(color, 'rgb(255, 0, 0)');
+}, 'Render-blocking stylesheet is applied');
+</script>
+<link rel="stylesheet" href="support/target-red.css?pipe=trickle(d1)">
+<div class="target">
+ This should be red
+</div>
diff --git a/testing/web-platform/tests/html/dom/render-blocking/remove-attr-script-keeps-blocking.html b/testing/web-platform/tests/html/dom/render-blocking/remove-attr-script-keeps-blocking.html
new file mode 100644
index 0000000000..451d2f3695
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/render-blocking/remove-attr-script-keeps-blocking.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<title>Synchronous script element still blocks rendering after removing `blocking=render`</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="support/test-render-blocking.js"></script>
+
+<script>
+// Test script must be added before the synchronous script because the
+// synchronous script is parser-blocking.
+
+promise_setup(async () => {
+ let script = await nodeInserted(document.head, node => node.id === 'script');
+ script.blocking = '';
+
+ // Also inserts some contents for non-compliant UA to render
+ document.body = document.createElement('body');
+ document.body.appendChild(document.createTextNode('Some text'));
+});
+
+test_render_blocking(
+ () => assert_equals(window.dummy, 1),
+ 'Render-blocking script is loaded and evaluated');
+</script>
+
+<script id="script" blocking="render" src="support/dummy-1.js?pipe=trickle(d1)"></script>
diff --git a/testing/web-platform/tests/html/dom/render-blocking/remove-attr-style-keeps-blocking.html b/testing/web-platform/tests/html/dom/render-blocking/remove-attr-style-keeps-blocking.html
new file mode 100644
index 0000000000..31d4b56838
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/render-blocking/remove-attr-style-keeps-blocking.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<title>Parser-inserted style element still blocks rendering after removing `blocking=render`</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="support/test-render-blocking.js"></script>
+
+<script>
+// Test script must be added before the style element because the style
+// element is script-blocking.
+
+promise_setup(async () => {
+ let sheet = await nodeInserted(document.head, node => node.id === 'sheet');
+ sheet.blocking = '';
+});
+
+test_render_blocking(
+ () => {
+ let color = getComputedStyle(document.querySelector('.target')).color;
+ assert_equals(color, 'rgb(255, 0, 0)');
+ },
+ 'Render-blocking stylesheet is applied');
+</script>
+
+<style id="sheet" blocking="render">
+@import url("support/target-red.css?pipe=trickle(d1)");
+</style>
+
+<div class="target">Some text</div>
diff --git a/testing/web-platform/tests/html/dom/render-blocking/remove-attr-stylesheet-link-keeps-blocking.html b/testing/web-platform/tests/html/dom/render-blocking/remove-attr-stylesheet-link-keeps-blocking.html
new file mode 100644
index 0000000000..1248b90b23
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/render-blocking/remove-attr-stylesheet-link-keeps-blocking.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<title>Parser-inserted stylesheet link still blocks rendering after removing `blocking=render`</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="support/test-render-blocking.js"></script>
+
+<script>
+// Test script must be added before the stylesheet link because the stylesheet
+// link is script-blocking.
+
+promise_setup(async () => {
+ let sheet = await nodeInserted(document.head, node => node.id === 'sheet');
+ sheet.blocking = '';
+});
+
+test_render_blocking(
+ () => {
+ let color = getComputedStyle(document.querySelector('.target')).color;
+ assert_equals(color, 'rgb(255, 0, 0)');
+ },
+ 'Render-blocking stylesheet is applied');
+</script>
+
+<link id="sheet" rel="stylesheet" blocking="render"
+ href="support/target-red.css?pipe=trickle(d1)">
+
+<div class="target">Some text</div>
diff --git a/testing/web-platform/tests/html/dom/render-blocking/remove-attr-unblocks-rendering.optional.html b/testing/web-platform/tests/html/dom/render-blocking/remove-attr-unblocks-rendering.optional.html
new file mode 100644
index 0000000000..c73e3c6452
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/render-blocking/remove-attr-unblocks-rendering.optional.html
@@ -0,0 +1,86 @@
+<!DOCTYPE html>
+<title>Removing `blocking=render` should unblock rendering</title>
+<link rel="help" href="https://html.spec.whatwg.org/C/#blocking-attribute">
+<link rel="help" href="https://html.spec.whatwg.org/C/#rendering-opportunity">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="support/test-render-blocking.js"></script>
+
+<!--
+ The test is marked "optional" because even when the document is no longer
+ render-blocked, the user agent is still free to take other factors, which are
+ not limited by the spec, into consideration and therefore decide not to
+ render. However, it is still more desirable if rendering starts
+ immediately/soon.
+-->
+
+<script class="test" data="parser-inserted async script" async blocking="render"
+ src="support/dummy-1.js?pipe=trickle(d1)&async"></script>
+<script class="test" data="parser-inserted defer script" defer blocking="render"
+ src="support/dummy-1.js?pipe=trickle(d1)&defer"></script>
+<script class="test" data="parser-inserted module script" type="module"
+ blocking="render" src="support/dummy-1.mjs?pipe=trickle(d1)"></script>
+<script class="test" data="parser-inserted async module script" type="module"
+ async blocking="render" src="support/dummy-1.mjs?pipe=trickle(d1)&async"></script>
+
+<!--
+ No test for parser-inserted stylesheets and synchronous scripts because they
+ are render-blocking by default, so removing `blocking=render` does not unblock
+ rendering.
+-->
+
+<script>
+function addRenderBlockingElement(tag, title, attributes, optional_text) {
+ let element = document.createElement(tag);
+ element.className = 'test';
+ element.setAttribute('data', title);
+ element.blocking = 'render';
+ Object.assign(element, attributes);
+ if (optional_text)
+ element.textContent = optional_text;
+ document.head.appendChild(element);
+}
+
+addRenderBlockingElement(
+ 'link', 'script-inserted stylesheet link',
+ {rel: 'stylesheet', blocking: 'render', href: 'support/target-red.css?pipe=trickle(d1)&dynamic'});
+
+addRenderBlockingElement(
+ 'script', 'script-inserted script',
+ {src: 'support/dummy-1.js?pipe=trickle(d1)&dynamic'});
+addRenderBlockingElement(
+ 'script', 'script-inserted module script',
+ {type: 'module', src: 'support/dummy-1.mjs?pipe=trickle(d1)&dynamic'});
+
+addRenderBlockingElement(
+ 'style', 'script-inserted inline style', {},
+ '@import url("support/target-red.css?pipe=trickle(d1)&imported&dynamic")');
+</script>
+
+<div id="dummy">Some text</div>
+
+<script>
+const testElements = [...document.querySelectorAll('.test')];
+const loadObservers = testElements.map(element => new LoadObserver(element));
+
+promise_setup(async () => {
+ for (let element of testElements)
+ element.blocking = '';
+
+ // Test cases are run after rendering is unblocked.
+ await new Promise(resolve => requestAnimationFrame(resolve));
+});
+
+for (let index = 0; index < testElements.length; ++index) {
+ promise_test(
+ async () => assert_false(loadObservers[index].finished),
+ 'Render-blocking on ' + testElements[index].getAttribute('data') + ' is cancellable');
+}
+
+for (let index = 0; index < testElements.length; ++index) {
+ promise_test(
+ () => loadObservers[index].load,
+ 'Loading of ' + testElements[index].getAttribute('data') + ' should eventually succeed');
+}
+</script>
+
diff --git a/testing/web-platform/tests/html/dom/render-blocking/remove-element-unblocks-rendering.optional.html b/testing/web-platform/tests/html/dom/render-blocking/remove-element-unblocks-rendering.optional.html
new file mode 100644
index 0000000000..ad49c48c2e
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/render-blocking/remove-element-unblocks-rendering.optional.html
@@ -0,0 +1,83 @@
+<!DOCTYPE html>
+<title>Removing render-blocking element should unblock rendering</title>
+<link rel="help" href="https://html.spec.whatwg.org/C/#blocking-attribute">
+<link rel="help" href="https://html.spec.whatwg.org/C/#rendering-opportunity">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="support/test-render-blocking.js"></script>
+
+<!--
+ The test is marked "optional" because even when the document is no longer
+ render-blocked, the user agent is still free to take other factors, which are
+ not limited by the spec, into consideration and therefore decide not to
+ render. However, it is still more desirable if rendering starts
+ immediately/soon.
+-->
+
+<script class="test" data="parser-inserted async script" async blocking="render"
+ src="support/dummy-1.js?pipe=trickle(d1)&async"></script>
+<script class="test" data="parser-inserted defer script" defer blocking="render"
+ src="support/dummy-1.js?pipe=trickle(d1)&defer"></script>
+<script class="test" data="parser-inserted module script" type="module"
+ blocking="render" src="support/dummy-1.mjs?pipe=trickle(d1)"></script>
+<script class="test" data="parser-inserted async module script" type="module"
+ async blocking="render" src="support/dummy-1.mjs?pipe=trickle(d1)&async"></script>
+
+<!--
+ No test for parser-inserted stylesheets and synchronous scripts because
+ they are script-blocking or even parser-blocking, and they do not have new
+ behaviors to test about.
+-->
+
+<script>
+function addRenderBlockingElement(tag, title, attributes, optional_text) {
+ let element = document.createElement(tag);
+ element.className = 'test';
+ element.setAttribute('data', title);
+ element.blocking = 'render';
+ Object.assign(element, attributes);
+ if (optional_text)
+ element.textContent = optional_text;
+ document.head.appendChild(element);
+}
+
+addRenderBlockingElement(
+ 'link', 'script-inserted stylesheet link',
+ {rel: 'stylesheet', blocking: 'render', href: 'support/target-red.css?pipe=trickle(d1)&dynamic'});
+
+addRenderBlockingElement(
+ 'script', 'script-inserted script',
+ {src: 'support/dummy-1.js?pipe=trickle(d1)&dynamic'});
+addRenderBlockingElement(
+ 'script', 'script-inserted module script',
+ {type: 'module', src: 'support/dummy-1.mjs?pipe=trickle(d1)&dynamic'});
+
+addRenderBlockingElement(
+ 'style', 'script-inserted inline style', {},
+ '@import url("support/target-red.css?pipe=trickle(d1)&imported&dynamic")');
+</script>
+
+<div id="dummy">Some text</div>
+
+<script>
+const testElements = [...document.querySelectorAll('.test')];
+const loadObservers = testElements.map(element => new LoadObserver(element));
+
+promise_setup(async () => {
+ for (let element of testElements)
+ element.remove();
+
+ // Test cases are run after rendering is unblocked.
+ await new Promise(resolve => requestAnimationFrame(resolve));
+});
+
+for (let index = 0; index < testElements.length; ++index) {
+ promise_test(
+ async () => assert_false(loadObservers[index].finished),
+ 'Render-blocking on ' + testElements[index].getAttribute('data') + ' is cancellable');
+
+ // The loading can either continue or cancel. This test does not assert it.
+ loadObservers[index].load.catch(() => {});
+}
+</script>
+
diff --git a/testing/web-platform/tests/html/dom/render-blocking/remove-pending-async-render-blocking-script.html b/testing/web-platform/tests/html/dom/render-blocking/remove-pending-async-render-blocking-script.html
new file mode 100644
index 0000000000..5f6e8b34d1
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/render-blocking/remove-pending-async-render-blocking-script.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<title>Removed render-blocking script should not indefinitely block rendering</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script id="target" async blocking="render"
+ src="support/dummy-1.js?pipe=trickle(d1)"></script>
+<script>
+promise_test(async () => {
+ const target = document.getElementById('target');
+ const newDoc = document.implementation.createHTMLDocument('new document');
+ newDoc.documentElement.appendChild(target);
+
+ await new Promise(resolve => requestAnimationFrame(resolve));
+
+ // reqeustAnimationFrame() should be eventually run, but the script removed
+ // while pending should not be run.
+ assert_equals(window.dummy, undefined);
+});
+</script>
diff --git a/testing/web-platform/tests/html/dom/render-blocking/script-inserted-inline-module-with-import.html b/testing/web-platform/tests/html/dom/render-blocking/script-inserted-inline-module-with-import.html
new file mode 100644
index 0000000000..576c0b321a
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/render-blocking/script-inserted-inline-module-with-import.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<head>
+<title>Script-inserted module script elements with "blocking=render" are render-blocking</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+ window.did_execute_script = false;
+ const script = document.createElement("script");
+ script.type = "module";
+ script.blocking = "render";
+ script.textContent = `
+ import "/loading/resources/dummy.js?pipe=trickle(d1)";
+ window.did_execute_script = true;
+ `;
+ document.head.append(script);
+</script>
+</head>
+<div id="dummy">some text</div>
+
+<script>
+ promise_test(async t => {
+ await new Promise(resolve => requestAnimationFrame(() => resolve()));
+ assert_true(window.did_execute_script, "Script-inserted render-blocking inline module script should execute before rAF callback");
+ });
+</script>
diff --git a/testing/web-platform/tests/html/dom/render-blocking/script-inserted-module-script.html b/testing/web-platform/tests/html/dom/render-blocking/script-inserted-module-script.html
new file mode 100644
index 0000000000..73f0d3cdf4
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/render-blocking/script-inserted-module-script.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<title>Script-inserted module script elements with "blocking=render" are render-blocking</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="support/test-render-blocking.js"></script>
+
+<script>
+const moduleScript = document.createElement('script');
+moduleScript.type = 'module';
+moduleScript.blocking = 'render';
+moduleScript.src = 'support/dummy-1.mjs?pipe=trickle(d1)';
+document.head.appendChild(moduleScript);
+</script>
+
+<div id="dummy">some text</div>
+
+<script>
+test_render_blocking(
+ moduleScript,
+ () => assert_equals(document.getElementById('dummy').textContent, '1'),
+ 'Script-inserted render-blocking module script is evaluated');
+</script>
diff --git a/testing/web-platform/tests/html/dom/render-blocking/script-inserted-script.html b/testing/web-platform/tests/html/dom/render-blocking/script-inserted-script.html
new file mode 100644
index 0000000000..faf346b4dd
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/render-blocking/script-inserted-script.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<title>Script-inserted script elements with "blocking=render" are render-blocking</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="support/test-render-blocking.js"></script>
+
+<script>
+const script = document.createElement('script');
+script.src = 'support/dummy-1.js?pipe=trickle(d1)';
+script.blocking = 'render';
+document.head.appendChild(script);
+</script>
+
+<div>Some text</div>
+
+<script>
+test_render_blocking(
+ script,
+ () => assert_equals(window.dummy, 1),
+ 'Script-inserted render-blocking script is evaluated');
+</script>
diff --git a/testing/web-platform/tests/html/dom/render-blocking/script-inserted-style-element.html b/testing/web-platform/tests/html/dom/render-blocking/script-inserted-style-element.html
new file mode 100644
index 0000000000..683706af50
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/render-blocking/script-inserted-style-element.html
@@ -0,0 +1,26 @@
+<!doctype html>
+<title>Script-inserted style elements with "blocking=render" are render-blocking</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="support/test-render-blocking.js"></script>
+
+<script>
+const style = document.createElement('style');
+style.blocking = 'render';
+style.textContent = "@import url('support/target-red.css?pipe=trickle(d1)');";
+document.head.appendChild(style);
+</script>
+
+<div class="target">
+ This should be red
+</div>
+
+<script>
+test_render_blocking(
+ style,
+ () => {
+ let color = getComputedStyle(document.querySelector('.target')).color;
+ assert_equals(color, 'rgb(255, 0, 0)');
+ },
+ 'Render-blocking stylesheet is applied');
+</script>
diff --git a/testing/web-platform/tests/html/dom/render-blocking/script-inserted-stylesheet-link.html b/testing/web-platform/tests/html/dom/render-blocking/script-inserted-stylesheet-link.html
new file mode 100644
index 0000000000..46755387d7
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/render-blocking/script-inserted-stylesheet-link.html
@@ -0,0 +1,27 @@
+<!doctype html>
+<title>Script-inserted stylesheet links with "blocking=render" are render-blocking</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="support/test-render-blocking.js"></script>
+
+<script>
+const stylesheet = document.createElement('link');
+stylesheet.rel = 'stylesheet';
+stylesheet.href = 'support/target-red.css?pipe=trickle(d1)';
+stylesheet.blocking = 'render';
+document.head.appendChild(stylesheet);
+</script>
+
+<div class="target">
+ This should be red
+</div>
+
+<script>
+test_render_blocking(
+ stylesheet,
+ () => {
+ let color = getComputedStyle(document.querySelector('.target')).color;
+ assert_equals(color, 'rgb(255, 0, 0)');
+ },
+ 'Render-blocking stylesheet is applied');
+</script>
diff --git a/testing/web-platform/tests/html/dom/render-blocking/support/dummy-1.js b/testing/web-platform/tests/html/dom/render-blocking/support/dummy-1.js
new file mode 100644
index 0000000000..597772cf64
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/render-blocking/support/dummy-1.js
@@ -0,0 +1 @@
+window.dummy = 1;
diff --git a/testing/web-platform/tests/html/dom/render-blocking/support/dummy-1.mjs b/testing/web-platform/tests/html/dom/render-blocking/support/dummy-1.mjs
new file mode 100644
index 0000000000..9b85a21033
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/render-blocking/support/dummy-1.mjs
@@ -0,0 +1 @@
+document.getElementById('dummy').textContent = 1;
diff --git a/testing/web-platform/tests/html/dom/render-blocking/support/target-red.css b/testing/web-platform/tests/html/dom/render-blocking/support/target-red.css
new file mode 100644
index 0000000000..a387acd4ec
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/render-blocking/support/target-red.css
@@ -0,0 +1,3 @@
+.target {
+ color: red;
+}
diff --git a/testing/web-platform/tests/html/dom/render-blocking/support/test-render-blocking.js b/testing/web-platform/tests/html/dom/render-blocking/support/test-render-blocking.js
new file mode 100644
index 0000000000..71d0d68096
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/render-blocking/support/test-render-blocking.js
@@ -0,0 +1,118 @@
+// Observes the `load` event of an EventTarget, or the finishing of a resource
+// given its url. Requires `/preload/resources/preload_helper.js` for the latter
+// usage.
+class LoadObserver {
+ constructor(target) {
+ this.finishTime = null;
+ this.load = new Promise((resolve, reject) => {
+ if (target.addEventListener) {
+ target.addEventListener('load', ev => {
+ this.finishTime = ev.timeStamp;
+ resolve(ev);
+ });
+ target.addEventListener('error', reject);
+ } else if (typeof target === 'string') {
+ const observer = new PerformanceObserver(() => {
+ if (numberOfResourceTimingEntries(target)) {
+ this.finishTime = performance.now();
+ resolve();
+ }
+ });
+ observer.observe({type: 'resource', buffered: true});
+ } else {
+ reject('Unsupported target for LoadObserver');
+ }
+ });
+ }
+
+ get finished() {
+ return this.finishTime !== null;
+ }
+}
+
+// Observes the insertion of a script/parser-blocking element into DOM via
+// MutationObserver, so that we can access the element before it's loaded.
+function nodeInserted(parentNode, predicate) {
+ return new Promise(resolve => {
+ function callback(mutationList) {
+ for (let mutation of mutationList) {
+ for (let node of mutation.addedNodes) {
+ if (predicate(node))
+ resolve(node);
+ }
+ }
+ }
+ new MutationObserver(callback).observe(parentNode, {childList: true});
+ });
+}
+
+function createAutofocusTarget() {
+ const autofocusTarget = document.createElement('textarea');
+ autofocusTarget.setAttribute('autofocus', '');
+ // We may not have a body element at this point if we are testing a
+ // script-blocking stylesheet. Hence, the new element is added to
+ // documentElement.
+ document.documentElement.appendChild(autofocusTarget);
+ return autofocusTarget;
+}
+
+function createScrollTarget() {
+ const scrollTarget = document.createElement('div');
+ scrollTarget.style.overflow = 'scroll';
+ scrollTarget.style.height = '100px';
+ const scrollContent = document.createElement('div');
+ scrollContent.style.height = '200px';
+ scrollTarget.appendChild(scrollContent);
+ document.documentElement.appendChild(scrollTarget);
+ return scrollTarget;
+}
+
+function createAnimationTarget() {
+ const style = document.createElement('style');
+ style.textContent = `
+ @keyframes anim {
+ from { height: 100px; }
+ to { height: 200px; }
+ }
+ `;
+ const animationTarget = document.createElement('div');
+ animationTarget.style.backgroundColor = 'green';
+ animationTarget.style.height = '50px';
+ animationTarget.style.animation = 'anim 100ms';
+ document.documentElement.appendChild(style);
+ document.documentElement.appendChild(animationTarget);
+ return animationTarget;
+}
+
+// Error margin for comparing timestamps of paint and load events, in case they
+// are reported by different threads.
+const epsilon = 50;
+
+function test_render_blocking(optionalElementOrUrl, finalTest, finalTestTitle) {
+ // Ideally, we should observe the 'load' event on the specific render-blocking
+ // elements. However, this is not possible for script-blocking stylesheets, so
+ // we have to observe the 'load' event on 'window' instead.
+ if (!(optionalElementOrUrl instanceof HTMLElement) &&
+ typeof optionalElementOrUrl !== 'string') {
+ finalTestTitle = finalTest;
+ finalTest = optionalElementOrUrl;
+ optionalElementOrUrl = undefined;
+ }
+ const loadObserver = new LoadObserver(optionalElementOrUrl || window);
+
+ promise_test(async test => {
+ assert_implements(window.PerformancePaintTiming);
+
+ await test.step_wait(() => performance.getEntriesByType('paint').length);
+
+ assert_true(loadObserver.finished);
+ for (let entry of performance.getEntriesByType('paint')) {
+ assert_greater_than(entry.startTime, loadObserver.finishTime - epsilon,
+ `${entry.name} should occur after loading render-blocking resources`);
+ }
+ }, 'Rendering is blocked before render-blocking resources are loaded');
+
+ promise_test(test => {
+ return loadObserver.load.then(() => finalTest(test));
+ }, finalTestTitle);
+}
diff --git a/testing/web-platform/tests/html/dom/render-blocking/support/utils.js b/testing/web-platform/tests/html/dom/render-blocking/support/utils.js
new file mode 100644
index 0000000000..8a9a537e96
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/render-blocking/support/utils.js
@@ -0,0 +1,5 @@
+function generateParserDelay(seconds = 1) {
+ document.write(`
+ <script src="/loading/resources/dummy.js?pipe=trickle(d${seconds})"></script>
+ `);
+}
diff --git a/testing/web-platform/tests/html/dom/resources/self-origin-subframe.html b/testing/web-platform/tests/html/dom/resources/self-origin-subframe.html
new file mode 100644
index 0000000000..8759362bdf
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/resources/self-origin-subframe.html
@@ -0,0 +1,22 @@
+<script>
+ window.onmessage = function(e){
+ if (e.data == "getOrigin") {
+ parent.postMessage(self.origin, "*");
+ } else if (e.data == "setDomainAndGetOrigin") {
+ var oldDomain = document.domain;
+ try {
+ document.domain = document.domain.replace(/^[^.]*./, "");
+ } catch (e) {
+ parent.postMessage("THREW WHEN SETTING DOMAIN: " + e, "*");
+ return;
+ }
+ if (oldDomain === document.domain) {
+ parent.postMessage("FAILED TO SET DOMAIN", "*");
+ } else {
+ parent.postMessage(self.origin, "*");
+ }
+ } else {
+ parent.postMessage("UNEXPECTED MESSAGE", "*");
+ }
+ }
+</script>
diff --git a/testing/web-platform/tests/html/dom/self-origin.any.js b/testing/web-platform/tests/html/dom/self-origin.any.js
new file mode 100644
index 0000000000..c103a32144
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/self-origin.any.js
@@ -0,0 +1,5 @@
+"use strict";
+
+test(function() {
+ assert_equals(self.origin, "http://" + location.host);
+}, "self.origin should be correct");
diff --git a/testing/web-platform/tests/html/dom/self-origin.sub.html b/testing/web-platform/tests/html/dom/self-origin.sub.html
new file mode 100644
index 0000000000..aba2b3016a
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/self-origin.sub.html
@@ -0,0 +1,93 @@
+<!DOCTYPE HTML>
+<meta charset=utf-8>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<iframe></iframe>
+<iframe id="blob-test"></iframe> <!-- will get blob: URI -->
+<iframe src="javascript:'javascript'"></iframe>
+<iframe srcdoc="srcdoc"></iframe>
+<!-- Use the non-default HTTP port so we can make sure it gets included in
+ self.origin -->
+<iframe src="http://{{domains[www1]}}:{{ports[http][1]}}{{location[path]}}/../resources/self-origin-subframe.html"></iframe>
+<!-- Using the Unicode version on purpose, we expect to get back the Punycode
+ version in self.origin -->
+<iframe src="http://élève.{{domains[]}}:{{ports[http][1]}}{{location[path]}}/../resources/self-origin-subframe.html"></iframe>
+<iframe src="resources/self-origin-subframe.html" sandbox="allow-scripts"></iframe>
+<script type="application/javascript">
+test(function() {
+ var blob = new Blob(['blob']);
+ var url = URL.createObjectURL(blob);
+ document.getElementById("blob-test").src = url;
+}, "Assigning blob url");
+
+/* Each message test is a four things: window to send message to, message to
+ send, expected response, async test to use. */
+var messageTests = [
+ [ frames[4], "getOrigin", "http://{{domains[www1]}}:{{ports[http][1]}}",
+ async_test("Should have the right origin for cross-origin subframe") ],
+ [ frames[4], "setDomainAndGetOrigin", "http://{{domains[www1]}}:{{ports[http][1]}}",
+ async_test("Should have the right origin for cross-origin subframe after setting document.domain") ],
+ [ frames[5], "getOrigin", "http://xn--lve-6lad.{{domains[]}}:{{ports[http][1]}}",
+ async_test("Should have the right origin for IDN subframe") ],
+ [ frames[5], "setDomainAndGetOrigin", "http://xn--lve-6lad.{{domains[]}}:{{ports[http][1]}}",
+ async_test("Should have the right origin for IDN subframe after setting document.domain") ],
+ [ frames[6], "getOrigin", "null",
+ async_test("Should have the right origin for sandboxed iframe") ],
+];
+
+var curTest = 0;
+function nextMessageTest() {
+ if (curTest == messageTests.length) {
+ return;
+ }
+
+ var testData = messageTests[curTest];
+ testData[0].postMessage(testData[1], "*");
+}
+
+window.onmessage = function(e) {
+ var testData = messageTests[curTest++];
+ testData[3].step(function() {
+ assert_equals(e.data, testData[2])
+ });
+ testData[3].done();
+ nextMessageTest();
+}
+
+addEventListener("load", nextMessageTest);
+
+test(function() {
+ assert_equals(self.origin, "http://{{location[host]}}");
+}, "We should have the right origin for our page");
+
+var t1 = async_test("about:blank subframe origins");
+addEventListener("load", t1.step_func_done(function() {
+ assert_equals(frames[0].location.origin, "null",
+ "Should have the right location origin for about:blank iframe");
+ assert_equals(frames[0].origin, "http://{{location[host]}}",
+ "Should have the right origin for about:blank iframe");
+}));
+
+var t2 = async_test("blob: subframe origins");
+addEventListener("load", t2.step_func_done(function() {
+ assert_equals(frames[1].location.origin, "http://{{location[host]}}",
+ "Should have the right location origin for blob: iframe");
+ assert_equals(frames[1].origin, "http://{{location[host]}}",
+ "Should have the right origin for blob: iframe");
+}));
+
+var t3 = async_test("javascript: subframe origins");
+addEventListener("load", t3.step_func_done(function() {
+ assert_equals(frames[2].origin, "http://{{location[host]}}",
+ "Should have the right origin for javascript: iframe");
+}));
+
+var t4 = async_test("srcdoc subframe origins");
+addEventListener("load", t4.step_func_done(function() {
+ assert_equals(frames[3].location.origin, "null",
+ "Should have the right location origin for srcdoc iframe");
+ assert_equals(frames[3].origin, "http://{{location[host]}}",
+ "Should have the right origin for srcdoc iframe");
+}));
+</script>
diff --git a/testing/web-platform/tests/html/dom/usvstring-reflection.https.html b/testing/web-platform/tests/html/dom/usvstring-reflection.https.html
new file mode 100644
index 0000000000..775cb49281
--- /dev/null
+++ b/testing/web-platform/tests/html/dom/usvstring-reflection.https.html
@@ -0,0 +1,139 @@
+<!doctype html>
+<title>USVString test relate to url</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script src="../../webrtc/RTCPeerConnection-helper.js"></script>
+<div id=log></div>
+<script>
+// Unpaired surrogate codepoints present in USVString are replaced
+// with U+FFFD. %EF%BF%BD is UTF-8 encoding of U+FFFD.
+'use strict';
+test(() => {
+ location.hash = '\uD999';
+ assert_equals(location.hash, '#%EF%BF%BD');
+}, "location.hash : unpaired surrogate codepoint should be replaced with U+FFFD");
+
+test(() => {
+ var w = window.open("about:blank#\uD800");
+ assert_equals(w.location.href, 'about:blank#%EF%BF%BD');
+ w.location.href = 'about:blank#\uD999';
+ assert_equals(w.location.href, 'about:blank#%EF%BF%BD');
+}, "location.href : unpaired surrogate codepoint should be replaced with U+FFFD");
+
+test(() => {
+ var w = window.open("about:blank#\uD800");
+ assert_equals(w.location.hash, '#%EF%BF%BD');
+}, "window.open : unpaired surrogate codepoint should be replaced with U+FFFD");
+
+test(() => {
+ var w = document.open("about:blank#\uD800", "", "");
+ assert_equals(w.location.hash, '#%EF%BF%BD');
+}, "document.open : unpaired surrogate codepoint should be replaced with U+FFFD");
+
+test(() => {
+ var element = document.createElement("a");
+ element.ping = '\uD989';
+ assert_equals(element.ping, '\uFFFD');
+}, "anchor : unpaired surrogate codepoint should be replaced with U+FFFD")
+
+test(() => {
+ var element = document.createElement("area");
+ element.ping = '\uDA99';
+ assert_equals(element.ping, '\uFFFD');
+}, "area : unpaired surrogate codepoint should be replaced with U+FFFD")
+
+test(() => {
+ var element = document.createElement("base");
+ element.href = '\uD989';
+ assert_equals(element.href.endsWith('%EF%BF%BD'), true);
+}, "base : unpaired surrogate codepoint should be replaced with U+FFFD")
+
+test(() => {
+ var src = new EventSource('\uD899');
+ assert_equals(src.url.endsWith('%EF%BF%BD'), true);
+}, "EventSource : unpaired surrogate codepoint should be replaced with U+FFFD")
+
+test(() => {
+ var element = document.createElement("frame");
+ element.src = '\uDCA9';
+ element.longDesc = '\uDCA8';
+ assert_equals(element.src.endsWith('%EF%BF%BD'), true);
+ assert_equals(element.longDesc.endsWith('%EF%BF%BD'), true);
+}, "frame : unpaired surrogate codepoint should be replaced with U+FFFD")
+
+test(() => {
+ var element = document.createElement("iframe");
+ element.src = '\uDC89';
+ element.longDesc = '\uDC88';
+ assert_equals(element.src.endsWith('%EF%BF%BD'), true);
+ assert_equals(element.longDesc.endsWith('%EF%BF%BD'), true);
+}, "iframe : unpaired surrogate codepoint should be replaced with U+FFFD")
+
+test(() => {
+ var element = document.createElement("link");
+ element.href = '\uDB89';
+ assert_equals(element.href.endsWith('%EF%BF%BD'), true);
+}, "link : unpaired surrogate codepoint should be replaced with U+FFFD")
+
+test(() => {
+ var element = document.createElement("source");
+ element.src = '\uDDDD';
+ element.srcset = '\uD800';
+ assert_equals(element.src.endsWith('%EF%BF%BD'), true);
+ assert_equals(element.srcset, '\uFFFD');
+}, "source : unpaired surrogate codepoint should be replaced with U+FFFD")
+
+test(() => {
+ const event = new StorageEvent('storage', {
+ url: window.location.href + '\uD999',
+ });
+ assert_equals(event.url, window.location.href + "\uFFFD");
+}, "storage event : unpaired surrogate codepoint should be replaced with U+FFFD")
+
+test(() => {
+ var wsocket = new EventSource('ws://www.example.com/socketserve\uD899/');
+ assert_true(wsocket.url.endsWith('ws://www.example.com/socketserve%EF%BF%BD/'));
+}, "websocket url : unpaired surrogate codepoint should be replaced with U+FFFD")
+
+test(() => {
+ try {
+ navigator.sendBeacon("resources/\uD800blank.txt");
+ assert_true(true);
+ } catch (e) {
+ assert_true(false);
+ }
+}, "sendBeacon URL: unpaired surrogate codepoint should not make any exceptions.")
+
+test(() => {
+ // This shouldn't throw an exception.
+ window.navigator.registerProtocolHandler('web+myprotocol', "custom-scheme\uD800/url=%s", "title");
+}, "RegisterProtocolHandler URL: unpaired surrogate codepoint should not make any exceptions.")
+
+test(() => {
+ // This shouldn't throw an exception.
+ window.navigator.unregisterProtocolHandler('web+myprotocol', "custom-scheme\uD800/url=%s");
+}, "UnregisterProtocolHandler URL: unpaired surrogate codepoint should not make any exceptions.")
+
+test(() => {
+ var w = window.open("about:blank#\uD800");
+ assert_equals(w.document.URL, 'about:blank#%EF%BF%BD');
+ assert_equals(w.document.documentURI, 'about:blank#%EF%BF%BD');
+}, "Document URLs: unpaired surrogate codepoint should be replaced with U+FFFD")
+
+promise_test(t => {
+ const sendString = 'hello\uD999';
+ const receiveString = 'hello\uFFFD';
+
+ return createDataChannelPair(t)
+ .then(([channel1, channel2]) => {
+ channel1.send(sendString);
+ return awaitMessage(channel2)
+ }).then(message => {
+ assert_equals(typeof message, 'string',
+ 'Expect message to be a string');
+
+ assert_equals(message, receiveString);
+ });
+}, "RTCDataChannel.send: unpaired surrogate codepoint should be replaced with U+FFFD.")
+
+</script>