summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/html/rendering
diff options
context:
space:
mode:
Diffstat (limited to 'testing/web-platform/tests/html/rendering')
-rw-r--r--testing/web-platform/tests/html/rendering/bidi-rendering/slot-direction.window.js72
-rw-r--r--testing/web-platform/tests/html/rendering/bidi-rendering/slot-no-isolate-001-ref.html8
-rw-r--r--testing/web-platform/tests/html/rendering/bidi-rendering/slot-no-isolate-001.html22
-rw-r--r--testing/web-platform/tests/html/rendering/bidi-rendering/unicode-bidi-ua-rules.html25
-rw-r--r--testing/web-platform/tests/html/rendering/bindings/the-button-element/button-type-menu-historical-ref.html7
-rw-r--r--testing/web-platform/tests/html/rendering/bindings/the-button-element/button-type-menu-historical.html8
-rw-r--r--testing/web-platform/tests/html/rendering/bindings/the-input-element-as-a-text-entry-widget/unrecognized-type-should-fallback-as-text-type-ref.html9
-rw-r--r--testing/web-platform/tests/html/rendering/bindings/the-input-element-as-a-text-entry-widget/unrecognized-type-should-fallback-as-text-type.html10
-rw-r--r--testing/web-platform/tests/html/rendering/bindings/the-select-element-0/option-label-ref.html19
-rw-r--r--testing/web-platform/tests/html/rendering/bindings/the-select-element-0/option-label.html66
-rw-r--r--testing/web-platform/tests/html/rendering/bindings/the-textarea-element-0/cols-default.html5
-rw-r--r--testing/web-platform/tests/html/rendering/bindings/the-textarea-element-0/cols-zero.html5
-rw-r--r--testing/web-platform/tests/html/rendering/bindings/the-textarea-element-0/rows-default.html5
-rw-r--r--testing/web-platform/tests/html/rendering/bindings/the-textarea-element-0/rows-zero.html5
-rw-r--r--testing/web-platform/tests/html/rendering/bindings/the-textarea-element-0/textarea-ref.html4
-rw-r--r--testing/web-platform/tests/html/rendering/dimension-attributes.html233
-rw-r--r--testing/web-platform/tests/html/rendering/interactive-media/links-forms-and-navigation/original-id.json1
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/flow-content-0/dialog-display.html13
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/flow-content-0/dialog.html115
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/flow-content-0/div-align-ref.html76
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/flow-content-0/div-align.html71
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/flow-content-0/figure-ref.html11
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/flow-content-0/figure.html9
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/flow-content-0/form-margin-quirk.html20
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/flow-content-0/search-styles-iso-8859-8.html54
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/flow-content-0/search-styles.html49
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/flow-content-0/slot-element-focusable.tentative.html51
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/flow-content-0/slot-element-tabbable.tentative.html58
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/flow-content-0/support/dialog-framed.html13
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/form-controls/datetime-dynamic-type-change-ref.html2
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/form-controls/datetime-dynamic-type-change.html9
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/form-controls/input-line-height-computed.html32
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/form-controls/input-line-height-ref.html12
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/form-controls/input-line-height.html13
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/form-controls/input-placeholder-line-height-ref.html2
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/form-controls/input-placeholder-line-height.html10
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/form-controls/placeholder-opacity-default.tentative.html25
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/form-controls/resets.html118
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/form-controls/select-fixedpos-crash.html22
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/form-controls/select-sizing-001-ref.html59
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/form-controls/select-sizing-001.html77
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/form-controls/text-transform-ref.html39
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/form-controls/text-transform.html40
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/form-controls/toggle-display-ref.html47
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/form-controls/toggle-display.html64
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/hidden-elements.html52
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/lists/TODO-lists.html17
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/lists/dir-type-ref.html9
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/lists/dir-type.html13
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/lists/li-text-align.html18
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/lists/li-type-supported-ref.html45
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/lists/li-type-supported-xhtml.xhtml40
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/lists/li-type-supported.html35
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/lists/li-type-unsupported-lower-alpha.html14
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/lists/li-type-unsupported-lower-roman.html14
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/lists/li-type-unsupported-ref.html13
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/lists/li-type-unsupported-upper-alpha.html14
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/lists/li-type-unsupported-upper-roman.html14
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/lists/lists-presentational-hints-ascii-case-insensitive.html34
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/lists/lists-styles.html228
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/lists/ol-display-contents-ref.html8
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/lists/ol-start-display-contents.html8
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/lists/ol-start-reversed-display-contents.html8
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/lists/ol-type-supported-ref.html25
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/lists/ol-type-supported-xhtml.xhtml14
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/lists/ol-type-supported.html9
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/lists/ol-type-unsupported-circle.html6
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/lists/ol-type-unsupported-disc.html6
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/lists/ol-type-unsupported-invalid.html6
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/lists/ol-type-unsupported-lower-alpha.html6
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/lists/ol-type-unsupported-lower-roman.html6
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/lists/ol-type-unsupported-none.html6
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/lists/ol-type-unsupported-ref.html5
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/lists/ol-type-unsupported-round.html6
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/lists/ol-type-unsupported-square.html6
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/lists/ol-type-unsupported-upper-alpha.html6
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/lists/ol-type-unsupported-upper-roman.html6
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/lists/ul-type-supported-ref.html21
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/lists/ul-type-supported-xhtml.xhtml13
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/lists/ul-type-supported.html8
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/lists/ul-type-unsupported-decimal.html7
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/lists/ul-type-unsupported-invalid.html7
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/lists/ul-type-unsupported-lower-alpha.html7
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/lists/ul-type-unsupported-lower-roman.html7
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/lists/ul-type-unsupported-ref.html6
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/lists/ul-type-unsupported-upper-alpha.html7
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/lists/ul-type-unsupported-upper-roman.html7
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/margin-collapsing-quirks/compare-computed-style.js7
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/margin-collapsing-quirks/multicol-quirks-mode.html7
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/margin-collapsing-quirks/multicol-standards-mode.html8
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/phrasing-content-0/br-wbr-content/content-property.tentative.html18
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/phrasing-content-0/font-element-text-decoration-color/001-a.html33
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/phrasing-content-0/font-element-text-decoration-color/001-q.html32
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/phrasing-content-0/font-element-text-decoration-color/001-ref.html20
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/phrasing-content-0/font-element-text-decoration-color/001-s.html33
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/phrasing-content-0/font-element-text-decoration-color/001-x.xhtml22
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/phrasing-content-0/font-element-text-decoration-color/font-face.html22
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/phrasing-content-0/font-element-text-decoration-color/font-size.html103
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/sections-and-headings/headings-styles.html152
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/tables/colgroup_valign-ref.xhtmlbin0 -> 588 bytes
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/tables/colgroup_valign_bottom.xhtmlbin0 -> 814 bytes
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/tables/colgroup_valign_top.xhtmlbin0 -> 802 bytes
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/tables/form-in-tables-xhtml.xhtml23
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/tables/form-in-tables.html35
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/tables/hidden-attr.html42
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/tables/resources/aqua-yellow-32x32.pngbin0 -> 156 bytes
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/tables/resources/blue-16x20-green-16x20.pngbin0 -> 132 bytes
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/tables/resources/fuchsia-32x32.pngbin0 -> 110 bytes
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/tables/resources/red-32x32.pngbin0 -> 110 bytes
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/tables/resources/yellow-32x32.pngbin0 -> 110 bytes
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-attribute.html194
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-background-print-ref.html42
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-background-print.html46
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-border-1-ref.html46
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-border-1.html37
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-border-2-notref.html40
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-border-2-ref.html30
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-border-2.html31
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-border-3-ref.html91
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-border-3q.html95
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-border-3s.html95
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-border-presentational-hints-ascii-case-insensitive-ref.html41
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-border-presentational-hints-ascii-case-insensitive.html45
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-bordercolor-001-ref.html26
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-bordercolor-001.html29
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-cell-nowrap-with-fixed-width-ref.html2
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-cell-nowrap-with-fixed-width.html15
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-cell-width-ref.html37
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-cell-width-s.html55
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-cell-width.html54
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-column-width-ref.html2
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-column-width.html10
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-direction-ref.html37
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-direction.html38
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-layout-notref.html9
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-layout-ref.html9
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-layout.html12
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-row-direction-ref.html45
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-row-direction.html46
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-row-group-direction-ref.html45
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-row-group-direction.html54
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-row-group-height-ref.html30
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-row-group-height.html31
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-row-height-ref.html4
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-row-height.html9
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-row-pagination-001-print-ref.html29
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-row-pagination-001-print.html33
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-row-pagination-002-print-ref.html14
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-row-pagination-002-print.html26
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-ua-stylesheet.html44
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-valign-baseline-ascii-case-insensitive.html22
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-vspace-hspace-s.html16
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-vspace-hspace.html16
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-width-150percent-ref.html12
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-width-150percent.html12
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-width-ref.html13
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-width-s.html31
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-width.html30
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/tables/tr-transform-and-will-change-ref.html9
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/tables/tr-transform-and-will-change.html14
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/tables/transformed-tbody-tr-collapsed-border-ref.html18
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/tables/transformed-tbody-tr-collapsed-border.html23
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/META.yml4
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/absolute-fixed-in-legend-ref.html12
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/absolute-fixed-in-legend.html52
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/crashtests/fieldset-middleclick.html37
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/empty-scrollable-ref.html3
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/empty-scrollable.html5
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-baseline-ref.html14
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-baseline.html16
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-block-formatting-context.html29
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-block-size.html42
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-border-gap-negative-margin.html11
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-border-gap-position-relative-ref.html7
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-border-gap-position-relative.html10
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-border-radius-hittest.html14
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-border-radius-with-alpha-ref.html12
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-border-radius-with-alpha.html26
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-calculating-min-max-content.html34
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-containing-block-ref.html10
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-containing-block.html35
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-content-before-legend.html41
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-content-percentage-size.html16
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-content-rtl-ref.html24
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-content-rtl.html26
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-crash.html9
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-default-style.html57
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-display.html37
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-div-display-contents.html12
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-dynamic-baseline-ref.html7
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-dynamic-baseline.html13
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-dynamic-oof-container-crash.html46
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-dynamic-pseudo-ref.html12
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-dynamic-pseudo.html27
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-flexbox.html95
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-foo-ref.html6
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-generated-content.html30
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-grid.html85
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-list-item-ref.html9
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-list-item.html10
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-max-block-size-ref.html34
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-max-block-size.html36
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-multicol.html29
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-overflow-cssomview.html30
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-overflow-hidden-ref.html4
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-overflow-hidden.html11
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-overflow-ref.html64
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-overflow.html82
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-painting-order-ref.html10
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-painting-order.html17
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-percentage-block-size.html64
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-percentage-padding.html31
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-resize-ref.html13
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-resize.html15
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-shadow-dom.html28
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-transform-translatez-ref.html10
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-transform-translatez.html16
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-vertical-ref.html25
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-vertical.html27
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/flex-legend-float-abspos.html97
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/grid-template-propagation-ref.html3
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/grid-template-propagation.html20
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/insert-legend-in-multicol-fieldset-crash.html12
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-align-justify-self.html34
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-align-text-align.html27
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-align.html50
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-auto-margins-ref.html37
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-auto-margins.html32
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-block-formatting-context.html81
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-block-margins-2-ref.html142
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-block-margins-2.html139
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-block-margins-ref.html13
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-block-margins.html16
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-block-position-centering.html58
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-display-none-rendering-ref.html7
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-display-none-rendering.html11
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-display-none.html16
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-display-rendering-ref.html34
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-display-rendering.html119
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-display.html40
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-dynamic-update.html19
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-float-abspos.html88
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-float-ref.html7
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-float.html12
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-grid-flex-multicol.html31
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-hover.html22
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-in-slot-ref.html4
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-in-slot.html16
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-inline-position-with-fieldset-padding.html42
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-list-item-numbering-ref.html16
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-list-item-numbering.html17
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-list-item-ref.html7
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-list-item.html11
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-margin-inline.html50
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-painting-order-ref.html5
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-painting-order.html13
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-position-relative-2-ref.html16
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-position-relative-2.html21
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-position-relative-ref.html10
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-position-relative.html11
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-sans-fieldset-display.html68
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-sticky-crash.html16
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-tall-ref.html20
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-tall.html20
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend.html62
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/min-inline-size.html39
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/multicol-legend-becomes-floated-crash.html11
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/no-red-ref.html3
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/resources/fieldset-vertical.css18
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/second-legend-becomes-rendered-legend-crash.html20
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/sticky-content-crash.html22
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/sticky-content-ref.html34
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/sticky-content.html35
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-frameset-and-frame-elements/different-writing-modes.html12
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-frameset-and-frame-elements/exceed-then-not-exceed.html32
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-frameset-and-frame-elements/frameset-visibility-hidden.html7
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-frameset-and-frame-elements/large-cols-abssize.html9
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-frameset-and-frame-elements/large-cols-percentage.html9
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-frameset-and-frame-elements/large-cols-relsize.html22
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-frameset-and-frame-elements/large-rows-abssize.html9
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-frameset-and-frame-elements/large-rows-percentage.html9
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-frameset-and-frame-elements/large-rows-relsize.html22
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-frameset-and-frame-elements/multicol-table-crash.html12
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-frameset-and-frame-elements/reference/different-writing-modes-ref.html6
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-frameset-and-frame-elements/reference/empty-ref.html1
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-frameset-and-frame-elements/reference/green-ref.html5
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-frameset-and-frame-elements/resources/green.html5
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-frameset-and-frame-elements/resources/red.html5
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-hr-element-0/align-ref.html31
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-hr-element-0/align.html24
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-hr-element-0/color-ref.html22
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-hr-element-0/color.html7
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-hr-element-0/hr.html55
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-hr-element-0/setting-overflow-visible.html64
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-hr-element-0/width-ref.html19
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-hr-element-0/width.html15
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/body-margin-1-ref.html2
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/body-margin-1a.html5
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/body-margin-1b.html5
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/body-margin-1c.html5
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/body-margin-1d.html5
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/body-margin-1e.html5
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/body-margin-1f.html5
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/body-margin-1g.html5
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/body-margin-1h.html5
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/body-margin-1i.html5
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/body-margin-1j.html5
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/body-margin-1k.html5
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/body-margin-1l.html5
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/body-margin-2-ref.html2
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/body-margin-2a.html5
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/body-margin-2b.html5
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/body-margin-2c.html5
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/body-margin-2d.html5
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/body-margin-2e.html5
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/body-margin-2f.html5
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/body-margin-2g.html5
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/body-margin-2h.html5
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/body-margin-2i.html5
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/body-margin-2j.html5
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/body-margin-2k.html5
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/body-margin-2l.html5
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/body_link.xhtml16
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/body_text_00ffff-ref.html14
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/body_text_00ffff.xhtml12
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/crashtests/body-huge-attr-value-crash.html9
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/iframe-body-margin-attributes.html32
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/iframe-marginwidth-marginheight.html12
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/iframe-scrolling-attribute-ref.html16
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/iframe-scrolling-attribute-values-ref.html29
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/iframe-scrolling-attribute-values.html30
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/iframe-scrolling-attribute.html24
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/support/big-page.html2
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/support/body-marginwidth-marginheight.html2
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/support/body-topmargin-leftmargin.html2
-rw-r--r--testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/test-body.xhtml8
-rw-r--r--testing/web-platform/tests/html/rendering/pixel-length-attributes.html173
-rw-r--r--testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/align.html59
-rw-r--r--testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/canvas-aspect-ratio.html52
-rw-r--r--testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/content-aspect-ratio.html25
-rw-r--r--testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/embedded-and-images-presentational-hints-ascii-case-insensitive.html46
-rw-r--r--testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/img-alt-crash-001.html15
-rw-r--r--testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/img-aspect-ratio-lazy.html36
-rw-r--r--testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/img-aspect-ratio.html120
-rw-r--r--testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/img-dim-ref.html11
-rw-r--r--testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/img-dim.html12
-rw-r--r--testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/img-empty-alt-replaced.html23
-rw-r--r--testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/img-no-alt-replaced.html30
-rw-r--r--testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/img-replaced-box-while-loading.html29
-rw-r--r--testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/img-title-only-w-sizing.html25
-rw-r--r--testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/img_border-ref.xhtml9
-rw-r--r--testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/img_border_percent.xhtml10
-rw-r--r--testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/input-align-right-1.html3
-rw-r--r--testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/input-align-right-2.html3
-rw-r--r--testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/input-align-right-ref.html2
-rw-r--r--testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/input-image-content-crash.html15
-rw-r--r--testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/input-image-inline-alt-ref.html18
-rw-r--r--testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/input-image-inline-alt.html23
-rw-r--r--testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/input-type-change-from-image-1-ref.html2
-rw-r--r--testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/input-type-change-from-image-1.html10
-rw-r--r--testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/number-placeholder-right-aligned-ref.html8
-rw-r--r--testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/number-placeholder-right-aligned.html16
-rw-r--r--testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/object_border-ref.xhtml8
-rw-r--r--testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/object_border_perc.xhtml9
-rw-r--r--testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/object_border_pixel.xhtml9
-rw-r--r--testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/picture-aspect-ratio.html242
-rw-r--r--testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/resources/aspect-ratio.js14
-rw-r--r--testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/video-aspect-ratio.html72
-rw-r--r--testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/video-intrinsic-width-height.html41
-rw-r--r--testing/web-platform/tests/html/rendering/replaced-elements/embedded-content-rendering-rules/audio-controls-001.html7
-rw-r--r--testing/web-platform/tests/html/rendering/replaced-elements/embedded-content-rendering-rules/audio-controls-002.html12
-rw-r--r--testing/web-platform/tests/html/rendering/replaced-elements/embedded-content-rendering-rules/audio-without-controls.html11
-rw-r--r--testing/web-platform/tests/html/rendering/replaced-elements/embedded-content-rendering-rules/canvas-fallback-ref.html4
-rw-r--r--testing/web-platform/tests/html/rendering/replaced-elements/embedded-content-rendering-rules/canvas-fallback.html26
-rw-r--r--testing/web-platform/tests/html/rendering/replaced-elements/embedded-content-rendering-rules/canvas-update-with-border-object-fit-ref.html4
-rw-r--r--testing/web-platform/tests/html/rendering/replaced-elements/embedded-content-rendering-rules/canvas-update-with-border-object-fit.html31
-rw-r--r--testing/web-platform/tests/html/rendering/replaced-elements/embedded-content-rendering-rules/canvas_scale.html23
-rw-r--r--testing/web-platform/tests/html/rendering/replaced-elements/embedded-content-rendering-rules/canvas_scale_ref.html14
-rw-r--r--testing/web-platform/tests/html/rendering/replaced-elements/embedded-content-rendering-rules/canvas_without_context_a.html15
-rw-r--r--testing/web-platform/tests/html/rendering/replaced-elements/embedded-content-rendering-rules/canvas_without_context_ref.html14
-rw-r--r--testing/web-platform/tests/html/rendering/replaced-elements/embedded-content/audio-controls-intrinsic-size.html25
-rw-r--r--testing/web-platform/tests/html/rendering/replaced-elements/embedded-content/change-src-while-not-displayed-ref.html2
-rw-r--r--testing/web-platform/tests/html/rendering/replaced-elements/embedded-content/change-src-while-not-displayed.html21
-rw-r--r--testing/web-platform/tests/html/rendering/replaced-elements/embedded-content/cross-domain-iframe-in-multicol.sub-ref.html3
-rw-r--r--testing/web-platform/tests/html/rendering/replaced-elements/embedded-content/cross-domain-iframe-in-multicol.sub.html21
-rw-r--r--testing/web-platform/tests/html/rendering/replaced-elements/embedded-content/cross-domain-iframe.sub-ref.html3
-rw-r--r--testing/web-platform/tests/html/rendering/replaced-elements/embedded-content/cross-domain-iframe.sub.html17
-rw-r--r--testing/web-platform/tests/html/rendering/replaced-elements/embedded-content/object-fallback-text-decoration-ref.html3
-rw-r--r--testing/web-platform/tests/html/rendering/replaced-elements/embedded-content/object-fallback-text-decoration.html9
-rw-r--r--testing/web-platform/tests/html/rendering/replaced-elements/embedded-content/resources/tall.html6
-rw-r--r--testing/web-platform/tests/html/rendering/replaced-elements/embedded-content/tall-cross-domain-iframe-in-scrolled.sub-ref.html9
-rw-r--r--testing/web-platform/tests/html/rendering/replaced-elements/embedded-content/tall-cross-domain-iframe-in-scrolled.sub.html20
-rw-r--r--testing/web-platform/tests/html/rendering/replaced-elements/embedded-content/video-controls-vertical-writing-mode-ref.html4
-rw-r--r--testing/web-platform/tests/html/rendering/replaced-elements/embedded-content/video-controls-vertical-writing-mode.html8
-rw-r--r--testing/web-platform/tests/html/rendering/replaced-elements/images/blocked-by-csp-ref.html5
-rw-r--r--testing/web-platform/tests/html/rendering/replaced-elements/images/blocked-by-csp.html8
-rw-r--r--testing/web-platform/tests/html/rendering/replaced-elements/images/img-sizes-auto.html53
-rw-r--r--testing/web-platform/tests/html/rendering/replaced-elements/images/input-image-content-ref.html7
-rw-r--r--testing/web-platform/tests/html/rendering/replaced-elements/images/input-image-content.html14
-rw-r--r--testing/web-platform/tests/html/rendering/replaced-elements/images/revoked-blob-print-ref.html3
-rw-r--r--testing/web-platform/tests/html/rendering/replaced-elements/images/revoked-blob-print.html24
-rw-r--r--testing/web-platform/tests/html/rendering/replaced-elements/images/space-ref.html13
-rw-r--r--testing/web-platform/tests/html/rendering/replaced-elements/images/space.html14
-rw-r--r--testing/web-platform/tests/html/rendering/replaced-elements/resources/svg-sizing.js418
-rw-r--r--testing/web-platform/tests/html/rendering/replaced-elements/svg-embedded-sizing/svg-embedded-sizing.js96
-rw-r--r--testing/web-platform/tests/html/rendering/replaced-elements/svg-embedded-sizing/svg-in-iframe-auto.html33
-rw-r--r--testing/web-platform/tests/html/rendering/replaced-elements/svg-embedded-sizing/svg-in-iframe-fixed.html33
-rw-r--r--testing/web-platform/tests/html/rendering/replaced-elements/svg-embedded-sizing/svg-in-iframe-percentage.html33
-rw-r--r--testing/web-platform/tests/html/rendering/replaced-elements/svg-embedded-sizing/svg-in-img-auto.html33
-rw-r--r--testing/web-platform/tests/html/rendering/replaced-elements/svg-embedded-sizing/svg-in-img-fixed.html33
-rw-r--r--testing/web-platform/tests/html/rendering/replaced-elements/svg-embedded-sizing/svg-in-img-percentage.html33
-rw-r--r--testing/web-platform/tests/html/rendering/replaced-elements/svg-embedded-sizing/svg-in-object-auto.html33
-rw-r--r--testing/web-platform/tests/html/rendering/replaced-elements/svg-embedded-sizing/svg-in-object-fixed.html33
-rw-r--r--testing/web-platform/tests/html/rendering/replaced-elements/svg-embedded-sizing/svg-in-object-percentage.html33
-rw-r--r--testing/web-platform/tests/html/rendering/replaced-elements/svg-inline-sizing/svg-inline.html29
-rw-r--r--testing/web-platform/tests/html/rendering/replaced-elements/svg-inline-sizing/svg-inline.js79
-rw-r--r--testing/web-platform/tests/html/rendering/replaced-elements/the-option-element/option-with-br-ref.html21
-rw-r--r--testing/web-platform/tests/html/rendering/replaced-elements/the-option-element/option-with-br.html32
-rw-r--r--testing/web-platform/tests/html/rendering/replaced-elements/the-option-element/select-multiple-covered-by-abspos-ref.html11
-rw-r--r--testing/web-platform/tests/html/rendering/replaced-elements/the-option-element/select-multiple-covered-by-abspos.html19
-rw-r--r--testing/web-platform/tests/html/rendering/replaced-elements/the-select-element/select-1-block-size-001-ref-2.html24
-rw-r--r--testing/web-platform/tests/html/rendering/replaced-elements/the-select-element/select-1-block-size-001-ref.html24
-rw-r--r--testing/web-platform/tests/html/rendering/replaced-elements/the-select-element/select-1-block-size-001.html24
-rw-r--r--testing/web-platform/tests/html/rendering/replaced-elements/the-select-element/select-1-block-size-ref.html33
-rw-r--r--testing/web-platform/tests/html/rendering/replaced-elements/the-select-element/select-1-block-size.html38
-rw-r--r--testing/web-platform/tests/html/rendering/replaced-elements/the-select-element/select-1-line-height-ref.html23
-rw-r--r--testing/web-platform/tests/html/rendering/replaced-elements/the-select-element/select-1-line-height.html36
-rw-r--r--testing/web-platform/tests/html/rendering/replaced-elements/the-select-element/select-empty-ref.html35
-rw-r--r--testing/web-platform/tests/html/rendering/replaced-elements/the-select-element/select-empty.html33
-rw-r--r--testing/web-platform/tests/html/rendering/replaced-elements/the-select-element/select-intrinsic-option-font-size-ref.html8
-rw-r--r--testing/web-platform/tests/html/rendering/replaced-elements/the-select-element/select-intrinsic-option-font-size.html9
-rw-r--r--testing/web-platform/tests/html/rendering/replaced-elements/the-select-element/select-intrinsic-text-transform-ref.html5
-rw-r--r--testing/web-platform/tests/html/rendering/replaced-elements/the-select-element/select-intrinsic-text-transform.html8
-rw-r--r--testing/web-platform/tests/html/rendering/replaced-elements/the-select-element/select-multiple-re-add-option-via-document-fragment-ref.html4
-rw-r--r--testing/web-platform/tests/html/rendering/replaced-elements/the-select-element/select-multiple-re-add-option-via-document-fragment.html12
-rw-r--r--testing/web-platform/tests/html/rendering/replaced-elements/the-textarea-element/textarea-padding-bend-overlaps-content-001-ref.html32
-rw-r--r--testing/web-platform/tests/html/rendering/replaced-elements/the-textarea-element/textarea-padding-bend-overlaps-content-001.tentative.html43
-rw-r--r--testing/web-platform/tests/html/rendering/replaced-elements/the-textarea-element/textarea-padding-bstart-moves-content-001-ref.html34
-rw-r--r--testing/web-platform/tests/html/rendering/replaced-elements/the-textarea-element/textarea-padding-bstart-moves-content-001.tentative.html46
-rw-r--r--testing/web-platform/tests/html/rendering/replaced-elements/the-textarea-element/textarea-padding-iend-overlaps-content-001-ref.html32
-rw-r--r--testing/web-platform/tests/html/rendering/replaced-elements/the-textarea-element/textarea-padding-iend-overlaps-content-001.tentative.html37
-rw-r--r--testing/web-platform/tests/html/rendering/replaced-elements/the-textarea-element/textarea-padding-istart-moves-content-001-ref.html34
-rw-r--r--testing/web-platform/tests/html/rendering/replaced-elements/the-textarea-element/textarea-padding-istart-moves-content-001.tentative.html46
-rw-r--r--testing/web-platform/tests/html/rendering/replaced-elements/tools/gen-svgsizing-tests.py55
-rw-r--r--testing/web-platform/tests/html/rendering/support/test-ua-stylesheet.js74
-rw-r--r--testing/web-platform/tests/html/rendering/the-css-user-agent-style-sheet-and-presentational-hints/body-bgcolor-attribute-change-ref.html4
-rw-r--r--testing/web-platform/tests/html/rendering/the-css-user-agent-style-sheet-and-presentational-hints/body-bgcolor-attribute-change.html10
-rw-r--r--testing/web-platform/tests/html/rendering/the-css-user-agent-style-sheet-and-presentational-hints/mouse-cursor-imagemap.html19
-rw-r--r--testing/web-platform/tests/html/rendering/the-css-user-agent-style-sheet-and-presentational-hints/no-help-cursor-on-links-wrapped-in-svg.historical.html52
-rw-r--r--testing/web-platform/tests/html/rendering/the-css-user-agent-style-sheet-and-presentational-hints/no-help-cursor-on-links.historical.html50
-rw-r--r--testing/web-platform/tests/html/rendering/the-details-element/auto-expand-details-text-fragment.html30
-rw-r--r--testing/web-platform/tests/html/rendering/the-details-element/details-after.html12
-rw-r--r--testing/web-platform/tests/html/rendering/the-details-element/details-autofocus-crash.html25
-rw-r--r--testing/web-platform/tests/html/rendering/the-details-element/details-before.html12
-rw-r--r--testing/web-platform/tests/html/rendering/the-details-element/details-blockification.html35
-rw-r--r--testing/web-platform/tests/html/rendering/the-details-element/details-display-property-is-ignored-ref.html21
-rw-r--r--testing/web-platform/tests/html/rendering/the-details-element/details-display-property-is-ignored.html26
-rw-r--r--testing/web-platform/tests/html/rendering/the-details-element/details-display-type-001-ref.html46
-rw-r--r--testing/web-platform/tests/html/rendering/the-details-element/details-display-type-001-ref2.html37
-rw-r--r--testing/web-platform/tests/html/rendering/the-details-element/details-display-type-001.tentative.html51
-rw-r--r--testing/web-platform/tests/html/rendering/the-details-element/details-display-type-002-ref.html10
-rw-r--r--testing/web-platform/tests/html/rendering/the-details-element/details-display-type-002.tentative.html17
-rw-r--r--testing/web-platform/tests/html/rendering/the-details-element/details-page-break-after-1-print.html20
-rw-r--r--testing/web-platform/tests/html/rendering/the-details-element/details-page-break-after-2-print.html20
-rw-r--r--testing/web-platform/tests/html/rendering/the-details-element/details-page-break-before-1-print.html20
-rw-r--r--testing/web-platform/tests/html/rendering/the-details-element/details-page-break-before-2-print.html20
-rw-r--r--testing/web-platform/tests/html/rendering/the-details-element/details-pseudo-elements-001-ref.html13
-rw-r--r--testing/web-platform/tests/html/rendering/the-details-element/details-pseudo-elements-001.tentative.html19
-rw-r--r--testing/web-platform/tests/html/rendering/the-details-element/details-pseudo-elements-002-ref.html14
-rw-r--r--testing/web-platform/tests/html/rendering/the-details-element/details-pseudo-elements-002.tentative.html21
-rw-r--r--testing/web-platform/tests/html/rendering/the-details-element/details-revert-ref.html19
-rw-r--r--testing/web-platform/tests/html/rendering/the-details-element/details-revert.html18
-rw-r--r--testing/web-platform/tests/html/rendering/the-details-element/details-two-pages-print-ref.html12
-rw-r--r--testing/web-platform/tests/html/rendering/the-details-element/empty-crash.html7
-rw-r--r--testing/web-platform/tests/html/rendering/the-details-element/resources/auto-expand-details-text-fragment.html27
-rw-r--r--testing/web-platform/tests/html/rendering/the-details-element/single-summary.html6
-rw-r--r--testing/web-platform/tests/html/rendering/the-details-element/summary-display-flex-ref.html105
-rw-r--r--testing/web-platform/tests/html/rendering/the-details-element/summary-display-flex.html112
-rw-r--r--testing/web-platform/tests/html/rendering/the-details-element/summary-display-grid-ref.html72
-rw-r--r--testing/web-platform/tests/html/rendering/the-details-element/summary-display-grid.html77
-rw-r--r--testing/web-platform/tests/html/rendering/the-details-element/summary-display-inline-flex-ref.html105
-rw-r--r--testing/web-platform/tests/html/rendering/the-details-element/summary-display-inline-flex.html112
-rw-r--r--testing/web-platform/tests/html/rendering/the-details-element/summary-display-inline-grid-ref.html72
-rw-r--r--testing/web-platform/tests/html/rendering/the-details-element/summary-display-inline-grid.html77
-rw-r--r--testing/web-platform/tests/html/rendering/the-details-element/summary-display-list-item-001-ref.html28
-rw-r--r--testing/web-platform/tests/html/rendering/the-details-element/summary-display-list-item-001.html34
-rw-r--r--testing/web-platform/tests/html/rendering/the-details-element/summary-display-list-item-002-ref.html13
-rw-r--r--testing/web-platform/tests/html/rendering/the-details-element/summary-display-list-item-002.html23
-rw-r--r--testing/web-platform/tests/html/rendering/the-details-element/summary-in-ol-ref.html20
-rw-r--r--testing/web-platform/tests/html/rendering/the-details-element/summary-in-ol.html22
-rw-r--r--testing/web-platform/tests/html/rendering/the-details-element/summary-text-decoration-ref.html11
-rw-r--r--testing/web-platform/tests/html/rendering/the-details-element/summary-text-decoration.html11
-rw-r--r--testing/web-platform/tests/html/rendering/the-details-element/two-summaries-removal-crash.html17
-rw-r--r--testing/web-platform/tests/html/rendering/unmapped-attributes.html95
-rw-r--r--testing/web-platform/tests/html/rendering/widgets/appearance/appearance-animation-001.html23
-rw-r--r--testing/web-platform/tests/html/rendering/widgets/appearance/appearance-animation-002-ref.html3
-rw-r--r--testing/web-platform/tests/html/rendering/widgets/appearance/appearance-animation-002.html20
-rw-r--r--testing/web-platform/tests/html/rendering/widgets/appearance/appearance-transition-001-ref.html7
-rw-r--r--testing/web-platform/tests/html/rendering/widgets/appearance/appearance-transition-001.html21
-rw-r--r--testing/web-platform/tests/html/rendering/widgets/appearance/appearance-transition-002-ref.html6
-rw-r--r--testing/web-platform/tests/html/rendering/widgets/appearance/appearance-transition-002.html19
-rw-r--r--testing/web-platform/tests/html/rendering/widgets/appearance/appearance-transition-003.html19
-rw-r--r--testing/web-platform/tests/html/rendering/widgets/appearance/default-styles.html96
-rw-r--r--testing/web-platform/tests/html/rendering/widgets/baseline-alignment-and-overflow.tentative.html237
-rw-r--r--testing/web-platform/tests/html/rendering/widgets/button-layout/anonymous-button-content-box-ref.html31
-rw-r--r--testing/web-platform/tests/html/rendering/widgets/button-layout/anonymous-button-content-box.html31
-rw-r--r--testing/web-platform/tests/html/rendering/widgets/button-layout/computed-style.html52
-rw-r--r--testing/web-platform/tests/html/rendering/widgets/button-layout/display-other.html52
-rw-r--r--testing/web-platform/tests/html/rendering/widgets/button-layout/flex.html61
-rw-r--r--testing/web-platform/tests/html/rendering/widgets/button-layout/grid.html30
-rw-r--r--testing/web-platform/tests/html/rendering/widgets/button-layout/inline-level-ref.html10
-rw-r--r--testing/web-platform/tests/html/rendering/widgets/button-layout/inline-level.html25
-rw-r--r--testing/web-platform/tests/html/rendering/widgets/button-layout/input-type-button-clip-ref.html9
-rw-r--r--testing/web-platform/tests/html/rendering/widgets/button-layout/input-type-button-clip.html15
-rw-r--r--testing/web-platform/tests/html/rendering/widgets/button-layout/input-type-button-newline-2-mismatch.html2
-rw-r--r--testing/web-platform/tests/html/rendering/widgets/button-layout/input-type-button-newline-2.html6
-rw-r--r--testing/web-platform/tests/html/rendering/widgets/button-layout/input-type-button-newline-mismatch.html2
-rw-r--r--testing/web-platform/tests/html/rendering/widgets/button-layout/input-type-button-newline.html6
-rw-r--r--testing/web-platform/tests/html/rendering/widgets/button-layout/propagate-text-decoration-ref.html9
-rw-r--r--testing/web-platform/tests/html/rendering/widgets/button-layout/propagate-text-decoration.html13
-rw-r--r--testing/web-platform/tests/html/rendering/widgets/button-layout/shrink-wrap.html42
-rw-r--r--testing/web-platform/tests/html/rendering/widgets/field-sizing-input-number.html149
-rw-r--r--testing/web-platform/tests/html/rendering/widgets/field-sizing-input-text.html154
-rw-r--r--testing/web-platform/tests/html/rendering/widgets/field-sizing-select.html87
-rw-r--r--testing/web-platform/tests/html/rendering/widgets/field-sizing-textarea.html141
-rw-r--r--testing/web-platform/tests/html/rendering/widgets/input-checkbox-disabled-checked-notref.html2
-rw-r--r--testing/web-platform/tests/html/rendering/widgets/input-checkbox-disabled-checked.html5
-rw-r--r--testing/web-platform/tests/html/rendering/widgets/input-checkbox-no-centering.html19
-rw-r--r--testing/web-platform/tests/html/rendering/widgets/input-checkbox-switch-indeterminate-ref.html2
-rw-r--r--testing/web-platform/tests/html/rendering/widgets/input-checkbox-switch-indeterminate.tentative.html7
-rw-r--r--testing/web-platform/tests/html/rendering/widgets/input-checkbox-switch-notref.html4
-rw-r--r--testing/web-platform/tests/html/rendering/widgets/input-checkbox-switch-ref.html4
-rw-r--r--testing/web-platform/tests/html/rendering/widgets/input-checkbox-switch-rtl-notref.html1
-rw-r--r--testing/web-platform/tests/html/rendering/widgets/input-checkbox-switch-rtl.tentative.html3
-rw-r--r--testing/web-platform/tests/html/rendering/widgets/input-checkbox-switch.tentative.html14
-rw-r--r--testing/web-platform/tests/html/rendering/widgets/input-checkbox-switch.tentative.window.js34
-rw-r--r--testing/web-platform/tests/html/rendering/widgets/input-date-baseline-min-height-ref.html6
-rw-r--r--testing/web-platform/tests/html/rendering/widgets/input-date-baseline-min-height.html10
-rw-r--r--testing/web-platform/tests/html/rendering/widgets/input-date-baseline-print.html25
-rw-r--r--testing/web-platform/tests/html/rendering/widgets/input-date-baseline-ref.html16
-rw-r--r--testing/web-platform/tests/html/rendering/widgets/input-date-baseline.html25
-rw-r--r--testing/web-platform/tests/html/rendering/widgets/input-date-content-size-ref.html9
-rw-r--r--testing/web-platform/tests/html/rendering/widgets/input-date-content-size.html11
-rw-r--r--testing/web-platform/tests/html/rendering/widgets/input-date-no-resize-on-hover.html35
-rw-r--r--testing/web-platform/tests/html/rendering/widgets/input-no-centering-ref.html2
-rw-r--r--testing/web-platform/tests/html/rendering/widgets/input-radio-disabled-checked-notref.html2
-rw-r--r--testing/web-platform/tests/html/rendering/widgets/input-radio-disabled-checked.html5
-rw-r--r--testing/web-platform/tests/html/rendering/widgets/input-radio-no-centering.html19
-rw-r--r--testing/web-platform/tests/html/rendering/widgets/input-text-size.html45
-rw-r--r--testing/web-platform/tests/html/rendering/widgets/input-time-content-size-ref.html9
-rw-r--r--testing/web-platform/tests/html/rendering/widgets/input-time-content-size.html11
-rw-r--r--testing/web-platform/tests/html/rendering/widgets/select-wrap-no-spill.optional.html23
-rw-r--r--testing/web-platform/tests/html/rendering/widgets/textarea-cols-rows.html64
-rw-r--r--testing/web-platform/tests/html/rendering/widgets/the-select-element/option-add-label-quirks.html20
-rw-r--r--testing/web-platform/tests/html/rendering/widgets/the-select-element/option-add-label.html21
-rw-r--r--testing/web-platform/tests/html/rendering/widgets/the-select-element/option-checked-styling-ref.html21
-rw-r--r--testing/web-platform/tests/html/rendering/widgets/the-select-element/option-checked-styling.html21
-rw-r--r--testing/web-platform/tests/html/rendering/widgets/the-select-element/option-empty-label-to-empty-string.html21
-rw-r--r--testing/web-platform/tests/html/rendering/widgets/the-select-element/option-empty-label.html14
-rw-r--r--testing/web-platform/tests/html/rendering/widgets/the-select-element/option-label-and-text.html14
-rw-r--r--testing/web-platform/tests/html/rendering/widgets/the-select-element/option-label-ref.html12
-rw-r--r--testing/web-platform/tests/html/rendering/widgets/the-select-element/option-only-label.html14
-rw-r--r--testing/web-platform/tests/html/rendering/widgets/the-select-element/option-rm-label.html21
-rw-r--r--testing/web-platform/tests/html/rendering/widgets/the-select-element/select-as-listbox-default-styles.tentative.html113
-rw-r--r--testing/web-platform/tests/html/rendering/widgets/the-select-element/select-invalidation-ref.html15
-rw-r--r--testing/web-platform/tests/html/rendering/widgets/the-select-element/select-invalidation.html31
-rw-r--r--testing/web-platform/tests/html/rendering/widgets/the-select-element/select-size-001.html11
-rw-r--r--testing/web-platform/tests/html/rendering/widgets/the-select-element/select-size-002.html11
-rw-r--r--testing/web-platform/tests/html/rendering/widgets/the-select-element/select-size-ref.html7
569 files changed, 15972 insertions, 0 deletions
diff --git a/testing/web-platform/tests/html/rendering/bidi-rendering/slot-direction.window.js b/testing/web-platform/tests/html/rendering/bidi-rendering/slot-direction.window.js
new file mode 100644
index 0000000000..673f6c0b0f
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/bidi-rendering/slot-direction.window.js
@@ -0,0 +1,72 @@
+// https://html.spec.whatwg.org/multipage/rendering.html#bidi-rendering
+// https://github.com/whatwg/html/pull/9796
+// https://github.com/whatwg/html/pull/9880
+
+for (let t of [
+ {
+ description: "<slot> inherits direction from parent",
+ shadow_tree: `
+ <div dir=ltr data-expected="ltr">
+ <slot data-expected="ltr"></slot>
+ </div>
+ `,
+ host_dir: "rtl",
+ },
+ {
+ description: "<slot> inherits CSS direction from parent",
+ shadow_tree: `
+ <div style="direction: ltr" data-expected="ltr">
+ <slot data-expected="ltr"></slot>
+ </div>
+ `,
+ host_dir: "rtl",
+ },
+ {
+ description: "<slot dir=ltr>",
+ shadow_tree: `
+ <slot dir="ltr" data-expected="ltr"></slot>
+ `,
+ host_dir: "rtl",
+ },
+ {
+ description: "<slot dir=rtl>",
+ shadow_tree: `
+ <slot dir="rtl" data-expected="rtl"></slot>
+ `,
+ host_dir: "ltr",
+ },
+ {
+ description: "<slot dir=auto> resolving to LTR",
+ shadow_tree: `
+ <slot dir="ltr" data-expected="ltr"></slot>
+ `,
+ host_dir: "rtl",
+ host_contents: "A",
+ },
+ {
+ description: "<slot dir=auto> resolving to RTL",
+ shadow_tree: `
+ <slot dir="rtl" data-expected="rtl"></slot>
+ `,
+ host_dir: "ltr",
+ host_contents: "\u0627",
+ },
+]) {
+ test(() => {
+ let host = document.createElement("div");
+ document.body.appendChild(host);
+ host.dir = t.host_dir;
+ if ("host_contents" in t) {
+ host.innerHTML = t.host_contents;
+ }
+
+ let root = host.attachShadow({mode: "open"});
+ root.innerHTML = t.shadow_tree;
+
+ for (let e of Array.from(root.querySelectorAll("[data-expected]"))) {
+ assert_equals(getComputedStyle(e).direction, e.getAttribute("data-expected"), `direction of ${e.nodeName}`);
+ }
+
+ host.remove();
+ }, `<slot> element sets CSS direction property: ${t.description}`);
+}
diff --git a/testing/web-platform/tests/html/rendering/bidi-rendering/slot-no-isolate-001-ref.html b/testing/web-platform/tests/html/rendering/bidi-rendering/slot-no-isolate-001-ref.html
new file mode 100644
index 0000000000..6675f0a166
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/bidi-rendering/slot-no-isolate-001-ref.html
@@ -0,0 +1,8 @@
+<!DOCTYPE html>
+<title>HTML Rendering: slot element has unicode-bidi: isolate</title>
+<link rel="author" title="L. David Baron" href="https://dbaron.org/">
+<link rel="author" title="Google" href="http://www.google.com/">
+
+<div style="unicode-bidi: bidi-override; direction: ltr;">&#x5D1;-&#x5D0;</div>
+
+<div>normal</div>
diff --git a/testing/web-platform/tests/html/rendering/bidi-rendering/slot-no-isolate-001.html b/testing/web-platform/tests/html/rendering/bidi-rendering/slot-no-isolate-001.html
new file mode 100644
index 0000000000..bb2e927c08
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/bidi-rendering/slot-no-isolate-001.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<title>HTML Rendering: slot element has unicode-bidi: isolate</title>
+<link rel="author" title="L. David Baron" href="https://dbaron.org/">
+<link rel="author" title="Google" href="http://www.google.com/">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/rendering.html#bidi-rendering">
+<link rel="help" href="https://github.com/whatwg/html/pull/9880">
+<link rel="match" href="slot-no-isolate-001-ref.html">
+
+<div>&#x5D0;-<span id="e">&#x5D1;</span></div>
+
+<div id="v"></div>
+
+<script>
+
+let e = document.getElementById("e");
+let root = e.attachShadow({mode: "open"});
+// use display:inline to override default display:contents
+root.innerHTML = "<slot style='display:inline'>\u05D2</slot>";
+let val = getComputedStyle(root.querySelector("slot")).unicodeBidi;
+document.getElementById("v").innerText = val;
+
+</script>
diff --git a/testing/web-platform/tests/html/rendering/bidi-rendering/unicode-bidi-ua-rules.html b/testing/web-platform/tests/html/rendering/bidi-rendering/unicode-bidi-ua-rules.html
new file mode 100644
index 0000000000..78bfb80e6f
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/bidi-rendering/unicode-bidi-ua-rules.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<title>unicode-bidi UA stylesheet rules</title>
+<link rel="author" href="masonf@chromium.org">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/rendering.html#bidi-rendering">
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+
+<body>
+<script>
+ const elements = ['address', 'blockquote', 'center', 'div', 'figure',
+ 'figcaption', 'footer', 'form', 'header', 'hr', 'legend', 'listing',
+ 'main', 'p', 'plaintext', 'pre', 'summary', 'xmp', 'article', 'aside',
+ 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'hgroup', 'nav', 'section', 'search',
+ 'table', 'caption', 'colgroup', 'col', 'thead', 'tbody', 'tfoot', 'tr',
+ 'td', 'th', 'dir', 'dd', 'dl', 'dt', 'menu', 'ol', 'ul', 'li', 'bdi',
+ 'output'];
+ for(let tagname of elements) {
+ test((t) => {
+ const element = document.createElement(tagname);
+ t.add_cleanup(() => element.remove());
+ document.body.appendChild(element);
+ assert_equals(window.getComputedStyle(element, "").unicodeBidi,'isolate');
+ },`UA stylesheet rule for unicode-bidi, for <${tagname}>`);
+ }
+</script>
diff --git a/testing/web-platform/tests/html/rendering/bindings/the-button-element/button-type-menu-historical-ref.html b/testing/web-platform/tests/html/rendering/bindings/the-button-element/button-type-menu-historical-ref.html
new file mode 100644
index 0000000000..6d728e8136
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/bindings/the-button-element/button-type-menu-historical-ref.html
@@ -0,0 +1,7 @@
+<!DOCTYPE HTML>
+<title>Test that button with type="menu" renders the same as button with type="submit"</title>
+<meta charset="utf-8">
+<link rel="author" title="Domenic Denicola" href="mailto:d@domenic.me">
+<link rel="help" href="https://github.com/whatwg/html/pull/2342">
+
+<button type="submit">button</button>
diff --git a/testing/web-platform/tests/html/rendering/bindings/the-button-element/button-type-menu-historical.html b/testing/web-platform/tests/html/rendering/bindings/the-button-element/button-type-menu-historical.html
new file mode 100644
index 0000000000..b355afeed1
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/bindings/the-button-element/button-type-menu-historical.html
@@ -0,0 +1,8 @@
+<!DOCTYPE HTML>
+<title>Test that button with type="menu" renders the same as button with type="submit"</title>
+<meta charset="utf-8">
+<link rel="author" title="Domenic Denicola" href="mailto:d@domenic.me">
+<link rel="help" href="https://github.com/whatwg/html/pull/2342">
+<link rel="match" href="button-type-menu-historical-ref.html">
+
+<button type="menu">button</button>
diff --git a/testing/web-platform/tests/html/rendering/bindings/the-input-element-as-a-text-entry-widget/unrecognized-type-should-fallback-as-text-type-ref.html b/testing/web-platform/tests/html/rendering/bindings/the-input-element-as-a-text-entry-widget/unrecognized-type-should-fallback-as-text-type-ref.html
new file mode 100644
index 0000000000..879ca9233f
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/bindings/the-input-element-as-a-text-entry-widget/unrecognized-type-should-fallback-as-text-type-ref.html
@@ -0,0 +1,9 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>Unrecognized type should fallback as text type</title>
+<body>
+ <input type="text">
+ <input type="text">
+ <input type="text" disabled>
+ <input type="text" disabled>
+</body>
diff --git a/testing/web-platform/tests/html/rendering/bindings/the-input-element-as-a-text-entry-widget/unrecognized-type-should-fallback-as-text-type.html b/testing/web-platform/tests/html/rendering/bindings/the-input-element-as-a-text-entry-widget/unrecognized-type-should-fallback-as-text-type.html
new file mode 100644
index 0000000000..a5c7a60841
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/bindings/the-input-element-as-a-text-entry-widget/unrecognized-type-should-fallback-as-text-type.html
@@ -0,0 +1,10 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>Unrecognized type should fallback as text type</title>
+<link rel="match" href="unrecognized-type-should-fallback-as-text-type-ref.html">
+<body>
+ <input>
+ <input type="unknown">
+ <input disabled>
+ <input type="unknown" disabled>
+</body>
diff --git a/testing/web-platform/tests/html/rendering/bindings/the-select-element-0/option-label-ref.html b/testing/web-platform/tests/html/rendering/bindings/the-select-element-0/option-label-ref.html
new file mode 100644
index 0000000000..e3f73cb3ed
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/bindings/the-select-element-0/option-label-ref.html
@@ -0,0 +1,19 @@
+<!doctype html>
+<title>Option labels</title>
+<select size=12>
+ <option><!-- No children, no label-->
+ <option><!-- No children, empty label-->
+ <option>label<!-- No children, label-->
+ <option><!-- No children, namespaced label-->
+
+ <option>child<!-- Single child, no label-->
+ <option>child<!-- Single child, empty label-->
+ <option>label<!-- Single child, label-->
+ <option>child<!-- Single child, namespaced label-->
+
+ <option>child node<!-- Two children, no label-->
+ <option>child node<!-- Two children, empty label-->
+ <option>label<!-- Two children, label-->
+ <option>child node<!-- Two children, namespaced label-->
+</select>
+
diff --git a/testing/web-platform/tests/html/rendering/bindings/the-select-element-0/option-label.html b/testing/web-platform/tests/html/rendering/bindings/the-select-element-0/option-label.html
new file mode 100644
index 0000000000..f98595ed01
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/bindings/the-select-element-0/option-label.html
@@ -0,0 +1,66 @@
+<!doctype html>
+<title>Option labels</title>
+<link rel="match" href="option-label-ref.html">
+<select size=12></select>
+<script>
+var select = document.getElementsByTagName("select")[0], option;
+
+option = document.createElement("option");
+select.appendChild(option);
+
+option = document.createElement("option");
+option.setAttribute("label", "")
+select.appendChild(option);
+
+option = document.createElement("option");
+option.setAttribute("label", "label")
+select.appendChild(option);
+
+option = document.createElement("option");
+option.setAttributeNS("http://www.example.com/", "label", "label")
+select.appendChild(option);
+
+option = document.createElement("option");
+option.appendChild(document.createTextNode(" child "));
+select.appendChild(option);
+
+option = document.createElement("option");
+option.appendChild(document.createTextNode(" child "));
+option.setAttribute("label", "")
+select.appendChild(option);
+
+option = document.createElement("option");
+option.appendChild(document.createTextNode(" child "));
+option.setAttribute("label", "label")
+select.appendChild(option);
+
+option = document.createElement("option");
+option.appendChild(document.createTextNode(" child "));
+option.setAttributeNS("http://www.example.com/", "label", "label")
+select.appendChild(option);
+
+
+option = document.createElement("option");
+option.appendChild(document.createTextNode(" child "));
+option.appendChild(document.createTextNode(" node "));
+select.appendChild(option);
+
+option = document.createElement("option");
+option.appendChild(document.createTextNode(" child "));
+option.appendChild(document.createTextNode(" node "));
+option.setAttribute("label", "")
+select.appendChild(option);
+
+
+option = document.createElement("option");
+option.appendChild(document.createTextNode(" child "));
+option.appendChild(document.createTextNode(" node "));
+option.setAttribute("label", "label")
+select.appendChild(option);
+
+option = document.createElement("option");
+option.appendChild(document.createTextNode(" child "));
+option.appendChild(document.createTextNode(" node "));
+option.setAttributeNS("http://www.example.com/", "label", "label")
+select.appendChild(option);
+</script>
diff --git a/testing/web-platform/tests/html/rendering/bindings/the-textarea-element-0/cols-default.html b/testing/web-platform/tests/html/rendering/bindings/the-textarea-element-0/cols-default.html
new file mode 100644
index 0000000000..067d658dd4
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/bindings/the-textarea-element-0/cols-default.html
@@ -0,0 +1,5 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Textarea cols</title>
+<link rel=match href=textarea-ref.html>
+<textarea cols=20></textarea>
diff --git a/testing/web-platform/tests/html/rendering/bindings/the-textarea-element-0/cols-zero.html b/testing/web-platform/tests/html/rendering/bindings/the-textarea-element-0/cols-zero.html
new file mode 100644
index 0000000000..8ecac6bf5a
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/bindings/the-textarea-element-0/cols-zero.html
@@ -0,0 +1,5 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Textarea cols</title>
+<link rel=match href=textarea-ref.html>
+<textarea cols=0></textarea>
diff --git a/testing/web-platform/tests/html/rendering/bindings/the-textarea-element-0/rows-default.html b/testing/web-platform/tests/html/rendering/bindings/the-textarea-element-0/rows-default.html
new file mode 100644
index 0000000000..5bb9f61eee
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/bindings/the-textarea-element-0/rows-default.html
@@ -0,0 +1,5 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Textarea rows</title>
+<link rel=match href=textarea-ref.html>
+<textarea rows=2></textarea>
diff --git a/testing/web-platform/tests/html/rendering/bindings/the-textarea-element-0/rows-zero.html b/testing/web-platform/tests/html/rendering/bindings/the-textarea-element-0/rows-zero.html
new file mode 100644
index 0000000000..79c8d0ff53
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/bindings/the-textarea-element-0/rows-zero.html
@@ -0,0 +1,5 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Textarea rows</title>
+<link rel=match href=textarea-ref.html>
+<textarea rows=0></textarea>
diff --git a/testing/web-platform/tests/html/rendering/bindings/the-textarea-element-0/textarea-ref.html b/testing/web-platform/tests/html/rendering/bindings/the-textarea-element-0/textarea-ref.html
new file mode 100644
index 0000000000..f2982808f6
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/bindings/the-textarea-element-0/textarea-ref.html
@@ -0,0 +1,4 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Default textarea</title>
+<textarea></textarea>
diff --git a/testing/web-platform/tests/html/rendering/dimension-attributes.html b/testing/web-platform/tests/html/rendering/dimension-attributes.html
new file mode 100644
index 0000000000..1d94205e0b
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/dimension-attributes.html
@@ -0,0 +1,233 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Test handling of attributes that map to dimension properties</title>
+<meta name="timeout" content="long">
+<link rel="help"
+ href="https://html.spec.whatwg.org/multipage/rendering.html#maps-to-the-dimension-property">
+<link rel="help"
+ href="https://html.spec.whatwg.org/multipage/rendering.html#maps-to-the-dimension-property-(ignoring-zero)">
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<body>
+<!-- We need a place to put our elements so they're bound to a document and
+ have computed style, but we don't want percentages resolved to lengths,
+ so need to make sure they have no CSS boxes -->
+<div id="container" style="display: none"></div>
+<script>
+ /*
+ * This test tests
+ *
+ * https://html.spec.whatwg.org/multipage/rendering.html#maps-to-the-dimension-property
+ * and
+ * https://html.spec.whatwg.org/multipage/rendering.html#maps-to-the-dimension-property-(ignoring-zero)
+ * for various elements and various values.
+ */
+
+ /*
+ * Array of input/output pairs. The input is the string to use as the
+ * attribute value. The output is the string expected as the computed style
+ * for the relevant CSS property.
+ */
+const valid_values = [
+ // Valid values
+ [ "200", "200px" ],
+ [ "1007", "1007px" ],
+ [ " 00523 ", "523px" ],
+ [ "200.25", "200.25px" ],
+ [ "200.7", "200.7px" ],
+ [ "200.", "200px" ],
+ [ "200in", "200px" ],
+ [ "200.25in", "200.25px" ],
+ [ "200 %", "200px" ],
+ [ "200 abc", "200px" ],
+ [ "200%", "200%" ],
+ [ "200%abc", "200%" ],
+ [ "200.25%", "200.25%" ],
+ [ "200.%", "200%" ],
+ [ "20.25e2", "20.25px" ],
+ [ "20.25E2", "20.25px" ],
+];
+
+ /*
+ * Values that are only valid for the not-ignoring-zero case.
+ */
+const zero_values = [
+ [ "0", "0px" ],
+ [ "0%", "0%" ],
+ [ "0px", "0px" ],
+];
+
+ /*
+ * Array of invalid values. These should lead to the default value of the
+ * relevant CSS property.
+ */
+const invalid_values = [
+ "-0",
+ "-0%",
+ "-200",
+ "-200px",
+ " -200",
+ "+-200",
+ "-+200",
+ "-200%",
+ "+200",
+ " +200in ",
+ " +200.25in ",
+ "+200%",
+ " +200.25% ",
+ " +200.25%abc",
+ "+0",
+ "+0%",
+ ".",
+ ".%",
+ ".x",
+ ".5",
+ ".5%"
+];
+
+const valid_values_with_0 =
+ valid_values.concat(zero_values);
+const invalid_values_with_0 =
+ invalid_values.concat(zero_values.map((v) => v[0]));
+
+function newElem(name) {
+ return () => document.createElement(name);
+}
+
+function newImageInput() {
+ return () => {
+ var elem = newElem("input")();
+ elem.type = "image";
+ return elem;
+ }
+}
+
+function newImgSource() {
+ return () => {
+ var elem = newElem("source")();
+ elem.setAttribute("srcset", "/images/green-100x50.png");
+ return elem;
+ }
+}
+
+/*
+ * Array of tests. Each test consists of the following information:
+ *
+ * 1) An element creation function.
+ * 2) The name of the attribute to set
+ * 3) The name of the CSS property to get.
+ * 4) A boolean indicating whether 0 is a valid value for the dimension
+ * attribute.
+ */
+const tests = [
+ [ newElem("hr"), "width", "width", true ],
+ [ newElem("iframe"), "width", "width", true ],
+ [ newElem("iframe"), "height", "height", true ],
+ [ newImageInput(), "width", "width", true ],
+ [ newImageInput(), "height", "height", true ],
+ [ newElem("marquee"), "width", "width", true ],
+ [ newElem("marquee"), "height", "height", true ],
+ [ newElem("video"), "width", "width", true ],
+ [ newElem("video"), "height", "height", true ],
+ [ newElem("object"), "width", "width", true ],
+ [ newElem("object"), "height", "height", true ],
+ [ newElem("embed"), "width", "width", true ],
+ [ newElem("embed"), "height", "height", true ],
+ [ newElem("img"), "width", "width", true ],
+ [ newElem("img"), "height", "height", true ],
+ [ newElem("td"), "width", "width", false ],
+ [ newElem("td"), "height", "height", false ],
+ [ newElem("table"), "width", "width", false ],
+ [ newElem("table"), "height", "height", true ],
+ [ newElem("tr"), "height", "height", true ],
+ [ newElem("col"), "width", "width", true ],
+ [ newElem("embed"), "hspace", "marginLeft", true ],
+ [ newElem("embed"), "hspace", "marginRight", true ],
+ [ newElem("embed"), "vspace", "marginTop", true ],
+ [ newElem("embed"), "vspace", "marginBottom", true ],
+ [ newElem("img"), "hspace", "marginLeft", true ],
+ [ newElem("img"), "hspace", "marginRight", true ],
+ [ newElem("img"), "vspace", "marginTop", true ],
+ [ newElem("img"), "vspace", "marginBottom", true ],
+ [ newElem("object"), "hspace", "marginLeft", true ],
+ [ newElem("object"), "hspace", "marginRight", true ],
+ [ newElem("object"), "vspace", "marginTop", true ],
+ [ newElem("object"), "vspace", "marginBottom", true ],
+ [ newImageInput(), "hspace", "marginLeft", true ],
+ [ newImageInput(), "hspace", "marginRight", true ],
+ [ newImageInput(), "vspace", "marginTop", true ],
+ [ newImageInput(), "vspace", "marginBottom", true ],
+ [ newElem("marquee"), "hspace", "marginLeft", true ],
+ [ newElem("marquee"), "hspace", "marginRight", true ],
+ [ newElem("marquee"), "vspace", "marginTop", true ],
+ [ newElem("marquee"), "vspace", "marginBottom", true ],
+ // <source width> is mapped to <img> width if both are in <picture>.
+ [ newImgSource(), "width", "width", true, newElem("img"), newElem("picture") ],
+ // <source height> is mapped to <img> height if both are in <picture>.
+ [ newImgSource(), "height", "height", true, newElem("img"), newElem("picture") ],
+];
+
+function style(element) {
+ return element.ownerDocument.defaultView.getComputedStyle(element);
+}
+
+const container = document.getElementById("container");
+
+for (let [ctor, attr, prop, zero_allowed, mappedElemCtor, containerCtor] of tests) {
+ let valid, invalid;
+ if (zero_allowed) {
+ valid = valid_values_with_0;
+ invalid = invalid_values;
+ } else {
+ valid = valid_values;
+ invalid = invalid_values_with_0;
+ }
+
+ let elemContainer = null;
+ if (!!containerCtor) {
+ elemContainer = containerCtor();
+ container.appendChild(elemContainer);
+ } else {
+ elemContainer = container;
+ }
+
+ let runTest = (value, expected) => {
+ let elem = ctor();
+ let mappedElem = !!mappedElemCtor ? mappedElemCtor() : elem;
+ test(function() {
+ this.add_cleanup(() => {
+ elem.remove();
+ if (!!mappedElemCtor) {
+ mappedElem.remove();
+ }
+ });
+ elem.setAttribute(attr, value);
+ assert_equals(elem.getAttribute(attr), value);
+ elemContainer.appendChild(elem);
+ if (!!mappedElemCtor) {
+ elemContainer.appendChild(mappedElem);
+ }
+ assert_equals(style(mappedElem)[prop], expected);
+ }, `<${elem.localName} ${attr}="${value}"> mapping to ` +
+ `<${mappedElem.localName}> ${prop} property`);
+ }
+
+ for (let [value, result] of valid) {
+ runTest(value, result);
+ }
+
+ let default_elem = !!mappedElemCtor ? mappedElemCtor() : ctor();
+ elemContainer.appendChild(default_elem);
+ let defaultVal = style(default_elem)[prop];
+ default_elem.remove();
+ for (let value of invalid) {
+ runTest(value, defaultVal);
+ }
+
+ if (!!containerCtor) {
+ elemContainer.remove();
+ }
+}
+
+</script>
+</body>
diff --git a/testing/web-platform/tests/html/rendering/interactive-media/links-forms-and-navigation/original-id.json b/testing/web-platform/tests/html/rendering/interactive-media/links-forms-and-navigation/original-id.json
new file mode 100644
index 0000000000..07a108785e
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/interactive-media/links-forms-and-navigation/original-id.json
@@ -0,0 +1 @@
+{"original_id":"links,-forms,-and-navigation"} \ No newline at end of file
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/flow-content-0/dialog-display.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/flow-content-0/dialog-display.html
new file mode 100644
index 0000000000..48b0e33d94
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/flow-content-0/dialog-display.html
@@ -0,0 +1,13 @@
+<!doctype html>
+<title>dialog: display</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<style>
+ dialog { position: static }
+</style>
+<dialog open id=dialog></dialog>
+<script>
+test(function() {
+ assert_equals(getComputedStyle(document.getElementById('dialog')).display, 'block');
+});
+</script>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/flow-content-0/dialog.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/flow-content-0/dialog.html
new file mode 100644
index 0000000000..3588e03670
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/flow-content-0/dialog.html
@@ -0,0 +1,115 @@
+<!doctype html>
+<title>The dialog element</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<style>
+ #ref-element {
+ padding-top: 1em;
+ background-color: white;
+ color: black;
+ border: solid;
+ }
+</style>
+<!--
+HTML used to have a style rule with `@media screen and (max-width: 540px)`.
+That was removed in https://github.com/whatwg/html/pull/2459
+-->
+<div><iframe style="width: 540px" src="support/dialog-framed.html"></iframe></div>
+<div><iframe style="width: 538px" src="support/dialog-framed.html"></iframe></div>
+<div id=ref-element></div>
+<script>
+setup(() => {
+ const refStyle = getComputedStyle(document.getElementById('ref-element'));
+ window.ref1em = refStyle.paddingTop;
+ window.refWhite = refStyle.backgroundColor;
+ window.refBlack = refStyle.color;
+ window.refMediumBorder = refStyle.borderTopWidth;
+ window.iframeHeight = 150;
+ const bodyTopMargin = 8;
+ window.dialogSize = parseFloat(ref1em) * 2 + parseFloat(refMediumBorder) * 2;
+ window.normalBottomDistance = iframeHeight - bodyTopMargin - dialogSize;
+}, {explicit_done: true});
+
+onload = () => {
+ for (let iframe of document.querySelectorAll('iframe')) {
+ const win = iframe.contentWindow;
+ const styleAttr = iframe.getAttribute('style');
+ const iframeWidth = parseInt(styleAttr.split(' ')[1]);
+ const horizontalDistance = iframeWidth / 2 - dialogSize / 2;
+ const verticalDistance = iframeHeight / 2 - dialogSize / 2;
+ test(() => {
+ const style = win.getComputedStyle(win.dialogClosed);
+ assert_equals(style.position, 'absolute', 'position');
+ assert_equals(style.display, 'none', 'display');
+ assert_equals(style.overflow, 'visible', 'overflow');
+ assert_equals(style.top, 'auto', 'top');
+ assert_equals(style.right, '0px', 'right');
+ assert_equals(style.bottom, 'auto', 'bottom');
+ assert_equals(style.left, '0px', 'left');
+ assert_equals(style.width, 'fit-content', 'width');
+ assert_equals(style.height, 'fit-content', 'height');
+ assert_equals(style.maxWidth, 'none', 'max-width');
+ assert_equals(style.maxHeight, 'none', 'max-height');
+ assert_equals(style.marginTop, 'auto', 'marginTop');
+ assert_equals(style.marginRight, 'auto', 'marginRight');
+ assert_equals(style.marginBottom, 'auto', 'marginBottom');
+ assert_equals(style.marginLeft, 'auto', 'marginLeft');
+ assertCommon(style);
+ }, `Closed dialog in ${styleAttr} iframe`);
+
+ test(() => {
+ const style = win.getComputedStyle(win.dialogOpen);
+ assert_equals(style.position, 'absolute', 'position');
+ assert_equals(style.display, 'block', 'display');
+ assert_equals(style.overflow, 'visible', 'overflow');
+ assert_equals(style.top, '8px', 'top');
+ assert_equals(style.right, '0px', 'right');
+ assert_equals(style.bottom, normalBottomDistance + 'px', 'bottom');
+ assert_equals(style.left, '0px', 'left');
+ assert_equals(style.width, '0px', 'width');
+ assert_equals(style.height, '0px', 'height');
+ assert_equals(style.maxWidth, 'none', 'max-width');
+ assert_equals(style.maxHeight, 'none', 'max-height');
+ assert_equals(style.marginTop, '0px', 'marginTop');
+ assert_equals(style.marginRight, horizontalDistance + 'px', 'marginRight');
+ assert_equals(style.marginBottom, '0px', 'marginBottom');
+ assert_equals(style.marginLeft, horizontalDistance + 'px', 'marginLeft');
+ assertCommon(style);
+ }, `Open dialog in ${styleAttr} iframe`);
+
+ test(() => {
+ const style = win.getComputedStyle(win.dialogModal);
+ assert_equals(style.position, 'fixed', 'position');
+ assert_equals(style.display, 'block', 'display');
+ assert_equals(style.overflow, 'auto', 'overflow');
+ assert_equals(style.top, '0px', 'top');
+ assert_equals(style.right, '0px', 'right');
+ assert_equals(style.bottom, '0px', 'bottom');
+ assert_equals(style.left, '0px', 'left');
+ assert_equals(style.width, '0px', 'width');
+ assert_equals(style.height, '0px', 'height');
+ assert_equals(style.maxWidth, 'calc(100% - 38px)', 'max-width');
+ assert_equals(style.maxHeight, 'calc(100% - 38px)', 'max-height');
+ assert_equals(style.marginTop, verticalDistance + 'px', 'marginTop');
+ assert_equals(style.marginRight, horizontalDistance + 'px', 'marginRight');
+ assert_equals(style.marginBottom, verticalDistance + 'px', 'marginBottom');
+ assert_equals(style.marginLeft, horizontalDistance + 'px', 'marginLeft');
+ assertCommon(style);
+ }, `Modal dialog in ${styleAttr} iframe`);
+ }
+ done();
+};
+
+function assertCommon(style) {
+ assert_equals(style.borderTopStyle, 'solid', 'borderTopStyle');
+ assert_equals(style.borderRightStyle, 'solid', 'borderRightStyle');
+ assert_equals(style.borderBottomStyle, 'solid', 'borderBottomStyle');
+ assert_equals(style.borderLeftStyle, 'solid', 'borderLeftStyle');
+ assert_equals(style.paddingTop, ref1em, 'paddingTop');
+ assert_equals(style.paddingRight, ref1em, 'paddingRight');
+ assert_equals(style.paddingBottom, ref1em, 'paddingBottom');
+ assert_equals(style.paddingLeft, ref1em, 'paddingLeft');
+ assert_equals(style.backgroundColor, refWhite, 'backgroundColor');
+ assert_equals(style.color, refBlack, 'color');
+}
+</script>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/flow-content-0/div-align-ref.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/flow-content-0/div-align-ref.html
new file mode 100644
index 0000000000..da8e4d0dc1
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/flow-content-0/div-align-ref.html
@@ -0,0 +1,76 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset=utf-8>
+<style>
+.test { width: 50px; background-color: yellow; }
+.center { text-align: center; }
+.center .test { margin: 0 auto; }
+.left { text-align: left; }
+.left .test { margin-right: auto; }
+.right { text-align: right; }
+.right .test { margin-left: auto; }
+.rtl { direction: rtl; }
+.ltr { direction: ltr; }
+.left .margin { margin-left: 1em; }
+.right .margin { margin-right: 1em; }
+</style>
+</head>
+<body>
+<!-- Centered tests -->
+<div class=center>
+<div class=test>t א</div>
+<div class="test rtl">t א</div>
+<div class="test margin">t א</div>
+</div>
+
+<div class=center>
+<div class="test left">t א</div>
+<div class="test right">t א</div>
+</div>
+
+<div class=left>
+<div class=center>
+<div class=test>t א</div>
+</div>
+</div>
+
+<!-- Left-aligned tests -->
+<div class=left>
+<div class=test>t א</div>
+<div class="test rtl">t א</div>
+<div class="test margin">t א</div>
+</div>
+
+<div class="left rtl">
+<div class=test>t א</div>
+<div class="test ltr">t א</div>
+<div class="test margin">t א</div>
+</div>
+
+<div class=left>
+<div class="test center">t א</div>
+<div class="test right">t א</div>
+</div>
+
+<!-- Right-aligned tests -->
+<div class=right>
+<div class=test>t א</div>
+<div class="test rtl">t א</div>
+<div class="test margin">t א</div>
+</div>
+
+<div class="right rtl">
+<div class=test>t א</div>
+<div class="test ltr">t א</div>
+<div class="test margin">t א</div>
+</div>
+
+<div class=right>
+<div class="test left">t א</div>
+<div class="test center">t א</div>
+</div>
+
+</body>
+</html>
+
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/flow-content-0/div-align.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/flow-content-0/div-align.html
new file mode 100644
index 0000000000..b96fbaeda1
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/flow-content-0/div-align.html
@@ -0,0 +1,71 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset=utf-8>
+<link rel="match" href="div-align-ref.html">
+<style>
+.test { width: 50px; background-color: yellow; }
+.rtl { direction: rtl; }
+.ltr { direction: ltr; }
+[align=left] .margin { margin-left: 1em }
+[align=right] .margin { margin-right: 1em }
+</style>
+</head>
+<body>
+<!-- Centered tests -->
+<div align=center>
+<div class=test>t א</div>
+<div class="test rtl">t א</div>
+<div class="test margin">t א</div>
+</div>
+
+<div align=center>
+<div class=test align=left>t א</div>
+<div class=test align=right>t א</div>
+</div>
+
+<div align=left>
+<div align=center>
+<div class=test>t א</div>
+</div>
+</div>
+
+<!-- Left-aligned tests -->
+<div align=left>
+<div class=test>t א</div>
+<div class="test rtl">t א</div>
+<div class="test margin">t א</div>
+</div>
+
+<div align=left class=rtl>
+<div class=test>t א</div>
+<div class="test ltr">t א</div>
+<div class="test margin">t א</div>
+</div>
+
+<div align=left>
+<div class=test align=center>t א</div>
+<div class=test align=right>t א</div>
+</div>
+
+<!-- Right-aligned tests -->
+<div align=right>
+<div class=test>t א</div>
+<div class="test rtl">t א</div>
+<div class="test margin">t א</div>
+</div>
+
+<div align=right class=rtl>
+<div class=test>t א</div>
+<div class="test ltr">t א</div>
+<div class="test margin">t א</div>
+</div>
+
+<div align=right>
+<div class=test align=left>t א</div>
+<div class=test align=center>t א</div>
+</div>
+
+</body>
+</html>
+
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/flow-content-0/figure-ref.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/flow-content-0/figure-ref.html
new file mode 100644
index 0000000000..a87141be11
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/flow-content-0/figure-ref.html
@@ -0,0 +1,11 @@
+<!doctype html>
+<title>The figure element</title>
+<link rel=author title=Ms2ger href=ms2ger@gmail.com>
+<link rel=help href=https://html.spec.whatwg.org/multipage/#the-figure-element>
+<style>
+body > div { margin: 1em 40px; }
+</style>
+<div>
+<div>Caption</div>
+Figure
+</div>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/flow-content-0/figure.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/flow-content-0/figure.html
new file mode 100644
index 0000000000..943f38c3e0
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/flow-content-0/figure.html
@@ -0,0 +1,9 @@
+<!doctype html>
+<title>The figure element</title>
+<link rel="match" href="figure-ref.html">
+<link rel=author title=Ms2ger href=ms2ger@gmail.com>
+<link rel=help href=https://html.spec.whatwg.org/multipage/#the-figure-element>
+<figure>
+<figcaption>Caption</figcaption>
+Figure
+</figure>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/flow-content-0/form-margin-quirk.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/flow-content-0/form-margin-quirk.html
new file mode 100644
index 0000000000..7f6618bb78
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/flow-content-0/form-margin-quirk.html
@@ -0,0 +1,20 @@
+<!-- quirks -->
+<title>form margin quirk</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<style>
+form { writing-mode: vertical-lr; }
+#ref { margin: 0 1em 0 0; }
+</style>
+<form id=form></form>
+<div id=ref></div>
+<script>
+test(() => {
+ const formStyle = getComputedStyle(document.getElementById('form'));
+ const refStyle = getComputedStyle(document.getElementById('ref'));
+ assert_equals(formStyle.marginTop, refStyle.marginTop, 'marginTop');
+ assert_equals(formStyle.marginRight, refStyle.marginRight, 'marginRight');
+ assert_equals(formStyle.marginBottom, refStyle.marginBottom, 'marginBottom');
+ assert_equals(formStyle.marginLeft, refStyle.marginLeft, 'marginLeft');
+});
+</script>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/flow-content-0/search-styles-iso-8859-8.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/flow-content-0/search-styles-iso-8859-8.html
new file mode 100644
index 0000000000..343e97f504
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/flow-content-0/search-styles-iso-8859-8.html
@@ -0,0 +1,54 @@
+<!doctype html>
+<meta charset="ISO-8859-8">
+<title>default styles for the search element, ISO-8859-8</title>
+<meta name="viewport" content="width=device-width">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/rendering/support/test-ua-stylesheet.js"></script>
+<style>
+/* Specify this bogus namespace, so the rules in this stylesheet only apply to the `fakeClone`d elements in #refs, not the HTML elements in #tests. */
+@namespace url(urn:not-html);
+
+address, blockquote, center, dialog, div, figure, figcaption, footer, form,
+header, hr, legend, listing, main, p, plaintext, pre, search, xmp {
+ display: block;
+}
+
+address, blockquote, center, div, figure, figcaption, footer, form, header, hr,
+legend, listing, main, p, plaintext, pre, summary, xmp, article, aside, h1, h2,
+h3, h4, h5, h6, hgroup, nav, section, search, table, caption, colgroup, col,
+thead, tbody, tfoot, tr, td, th, dir, dd, dl, dt, menu, ol, ul, li, bdi, output,
+[dir=ltr i], [dir=rtl i], [dir=auto i], * /* only apply to the bogus namespace */ {
+ unicode-bidi: isolate;
+}
+
+</style>
+
+<div id="log"></div>
+
+<div id="tests">
+ <search></search>
+</div>
+
+<div id="refs"></div>
+
+<script>
+ test(() => {
+ assert_equals(document.characterSet, "ISO-8859-8")
+ }, "Verify document.characterSet is ISO-8859-8");
+
+ const props = [
+ 'display',
+ 'margin-top',
+ 'margin-right',
+ 'margin-bottom',
+ 'margin-left',
+ 'padding-top',
+ 'padding-right',
+ 'padding-bottom',
+ 'padding-left',
+ 'unicode-bidi',
+ ];
+ runUAStyleTests(props);
+
+</script>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/flow-content-0/search-styles.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/flow-content-0/search-styles.html
new file mode 100644
index 0000000000..8c8badd170
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/flow-content-0/search-styles.html
@@ -0,0 +1,49 @@
+<!doctype html>
+<title>default styles for the search element</title>
+<meta name="viewport" content="width=device-width">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/rendering/support/test-ua-stylesheet.js"></script>
+<style>
+/* Specify this bogus namespace, so the rules in this stylesheet only apply to the `fakeClone`d elements in #refs, not the HTML elements in #tests. */
+@namespace url(urn:not-html);
+
+address, blockquote, center, dialog, div, figure, figcaption, footer, form,
+header, hr, legend, listing, main, p, plaintext, pre, search, xmp {
+ display: block;
+}
+
+address, blockquote, center, div, figure, figcaption, footer, form, header, hr,
+legend, listing, main, p, plaintext, pre, summary, xmp, article, aside, h1, h2,
+h3, h4, h5, h6, hgroup, nav, section, search, table, caption, colgroup, col,
+thead, tbody, tfoot, tr, td, th, dir, dd, dl, dt, menu, ol, ul, li, bdi, output,
+[dir=ltr i], [dir=rtl i], [dir=auto i] {
+ unicode-bidi: isolate;
+}
+
+</style>
+
+<div id="log"></div>
+
+<div id="tests">
+ <search></search>
+</div>
+
+<div id="refs"></div>
+
+<script>
+ const props = [
+ 'display',
+ 'margin-top',
+ 'margin-right',
+ 'margin-bottom',
+ 'margin-left',
+ 'padding-top',
+ 'padding-right',
+ 'padding-bottom',
+ 'padding-left',
+ 'unicode-bidi',
+ ];
+ runUAStyleTests(props);
+
+</script>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/flow-content-0/slot-element-focusable.tentative.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/flow-content-0/slot-element-focusable.tentative.html
new file mode 100644
index 0000000000..b6d2449e89
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/flow-content-0/slot-element-focusable.tentative.html
@@ -0,0 +1,51 @@
+<!DOCTYPE html>
+<title>CSS Test (Display): <slot> elements should be focusable</title>
+<link rel="author" title="L. David Baron" href="https://dbaron.org/">
+<link rel="author" title="Google" href="http://www.google.com/">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/rendering.html#flow-content-3">
+<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/2632">
+<link rel="help" href="https://github.com/whatwg/html/issues/1837">
+<link rel="help" href="https://github.com/whatwg/html/pull/9425">
+<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1366037">
+<!--
+
+ This requirement is not particularly clear from current specs,
+ so this test is tentative. See issues above.
+
+-->
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<body>
+
+<script>
+
+ function do_test(slot_style, description) {
+ test(
+ function() {
+ let host = document.createElement("div");
+ document.body.appendChild(host);
+ var root = host.attachShadow({mode:"open"});
+ root.innerHTML = `
+ <style>
+ slot { --test-value: slot-not-focused; }
+ slot:focus { --test-value: slot-is-focused; }
+ </style>
+ <slot tabindex="1" style="${slot_style}"></slot>
+ `;
+ let slot = root.querySelector("slot");
+ let cs = getComputedStyle(slot);
+ assert_not_equals(root.activeElement, slot, "precondition");
+ assert_equals(cs.getPropertyValue("--test-value"), "slot-not-focused", "precondition (style)");
+ slot.focus();
+ assert_equals(root.activeElement, slot, "slot is now focused");
+ assert_equals(cs.getPropertyValue("--test-value"), "slot-is-focused", "slot is now focused (style)");
+ document.body.removeChild(host);
+ }, `slot element with ${description} should be focusable`);
+ }
+
+ do_test("display: block", "display: block");
+ do_test("", "default style");
+
+</script>
+
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/flow-content-0/slot-element-tabbable.tentative.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/flow-content-0/slot-element-tabbable.tentative.html
new file mode 100644
index 0000000000..22c2324d02
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/flow-content-0/slot-element-tabbable.tentative.html
@@ -0,0 +1,58 @@
+<!DOCTYPE html>
+<title>CSS Test (Display): <slot> elements should be tabbable</title>
+<link rel="author" title="L. David Baron" href="https://dbaron.org/">
+<link rel="author" title="Google" href="http://www.google.com/">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/rendering.html#flow-content-3">
+<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/2632">
+<link rel="help" href="https://github.com/whatwg/html/issues/1837">
+<link rel="help" href="https://github.com/whatwg/html/pull/9425">
+<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1366037">
+<!--
+
+ This requirement is not particularly clear from current specs,
+ so this test is tentative. See issues above.
+
+-->
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/testdriver.js"></script>
+<script src="/resources/testdriver-vendor.js"></script>
+
+<body>
+
+<div id="before" tabindex="1" style="height: 10px"></div>
+
+<script>
+
+ function do_test(slot_style, description) {
+ promise_test(
+ async () => {
+ let before = document.getElementById("before");
+ before.focus();
+ let host = document.createElement("div");
+ document.body.appendChild(host);
+ var root = host.attachShadow({mode:"open"});
+ root.innerHTML = `
+ <style>
+ slot { --test-value: slot-not-focused; }
+ slot:focus { --test-value: slot-is-focused; }
+ </style>
+ <slot tabindex="1" style="${slot_style}"></slot>
+ `;
+ let slot = root.querySelector("slot");
+ let cs = getComputedStyle(slot);
+ assert_equals(document.activeElement, before, "precondition");
+ assert_not_equals(root.activeElement, slot, "precondition");
+ assert_equals(cs.getPropertyValue("--test-value"), "slot-not-focused", "precondition (style)");
+ await test_driver.send_keys(before, "\uE004");
+ assert_equals(root.activeElement, slot, "slot is now focused");
+ assert_equals(cs.getPropertyValue("--test-value"), "slot-is-focused", "slot is now focused (style)");
+ document.body.removeChild(host);
+ }, `slot element with ${description} should be focusable`);
+ }
+
+ do_test("display: block", "display: block");
+ do_test("", "default style");
+
+</script>
+
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/flow-content-0/support/dialog-framed.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/flow-content-0/support/dialog-framed.html
new file mode 100644
index 0000000000..f9c414c246
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/flow-content-0/support/dialog-framed.html
@@ -0,0 +1,13 @@
+<!doctype html>
+<style>
+ html { color: red }
+</style>
+<dialog id=dialog-closed></dialog>
+<dialog id=dialog-open open></dialog>
+<dialog id=dialog-modal></dialog>
+<script>
+window.dialogClosed = document.getElementById('dialog-closed');
+window.dialogOpen = document.getElementById('dialog-open');
+window.dialogModal = document.getElementById('dialog-modal');
+dialogModal.showModal();
+</script>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/form-controls/datetime-dynamic-type-change-ref.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/form-controls/datetime-dynamic-type-change-ref.html
new file mode 100644
index 0000000000..478b8db485
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/form-controls/datetime-dynamic-type-change-ref.html
@@ -0,0 +1,2 @@
+<!doctype html>
+<input type="datetime-local">
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/form-controls/datetime-dynamic-type-change.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/form-controls/datetime-dynamic-type-change.html
new file mode 100644
index 0000000000..f8590ee561
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/form-controls/datetime-dynamic-type-change.html
@@ -0,0 +1,9 @@
+<!doctype html>
+<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1797139">
+<link rel="match" href="datetime-dynamic-type-change-ref.html">
+<input type="date">
+<script>
+ onload = function() {
+ document.querySelector("input").type = "datetime-local";
+ }
+</script>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/form-controls/input-line-height-computed.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/form-controls/input-line-height-computed.html
new file mode 100644
index 0000000000..1bee40359a
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/form-controls/input-line-height-computed.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>used value and computed value of 'line-height' on input elements as text entry widgets</title>
+<link rel="help" href="https://html.spec.whatwg.org/multipage/rendering.html#the-input-element-as-a-text-entry-widget">
+<link rel="help" href="https://drafts.csswg.org/cssom/#resolved-values">
+<link rel="help" href="https://drafts.css-houdini.org/css-typed-om/#computed-stylepropertymapreadonly-objects">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<style>
+ input { line-height: 1px; }
+</style>
+<p><input type=text value=text>
+<p><input type=tel value=tel>
+<p><input type=search value=search>
+<p><input type=url value=url>
+<p><input type=email value=email>
+<p><input type=password value=password></p>
+<script>
+const inputs = document.querySelectorAll('input');
+for (const input of inputs) {
+ test(() => {
+ const usedLineHeight = getComputedStyle(input).lineHeight;
+ assert_not_equals(usedLineHeight, '1px', 'usedLineHeight');
+ assert_not_equals(usedLineHeight, 'normal', 'usedLineHeight');
+ }, `getComputedStyle(<input type=${input.type}>).lineHeight should return a used value that is no smaller than 'normal' (but should not literally be 'normal')`);
+ test(() => {
+ const computedLineHeight = input.computedStyleMap().get('line-height');
+ assert_equals(computedLineHeight.value, 1, 'computedLineHeight.value');
+ assert_equals(computedLineHeight.unit, 'px', 'computedLineHeight.unit');
+ }, `<input type=${input.type}>.computedStyleMap().get('line-height') should not be affected by the used value clamping`);
+}
+</script>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/form-controls/input-line-height-ref.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/form-controls/input-line-height-ref.html
new file mode 100644
index 0000000000..abf50b8728
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/form-controls/input-line-height-ref.html
@@ -0,0 +1,12 @@
+<!doctype html>
+<title>Reference for 'line-height' smaller than 'normal' on input elements as text entry widgets</title>
+<style>
+ input { font-size: 60px; width: 240px; }
+ .appearance-none { appearance: none; }
+</style>
+<p><input type=text value=text> <input type=text value=text class=appearance-none>
+<p><input type=tel value=tel> <input type=tel value=tel class=appearance-none>
+<p><input type=search value=search> <input type=search value=search class=appearance-none>
+<p><input type=url value=url> <input type=url value=url class=appearance-none>
+<p><input type=email value=email> <input type=email value=email class=appearance-none>
+<p><input type=password value=password> <input type=password value=password class=appearance-none>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/form-controls/input-line-height.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/form-controls/input-line-height.html
new file mode 100644
index 0000000000..bfcd3665be
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/form-controls/input-line-height.html
@@ -0,0 +1,13 @@
+<!doctype html>
+<title>'line-height' smaller than 'normal' on input elements as text entry widgets</title>
+<link rel="match" href="input-line-height-ref.html">
+<style>
+ input { font-size: 60px; line-height: 40px; width: 240px; }
+ .appearance-none { appearance: none; }
+</style>
+<p><input type=text value=text> <input type=text value=text class=appearance-none>
+<p><input type=tel value=tel> <input type=tel value=tel class=appearance-none>
+<p><input type=search value=search> <input type=search value=search class=appearance-none>
+<p><input type=url value=url> <input type=url value=url class=appearance-none>
+<p><input type=email value=email> <input type=email value=email class=appearance-none>
+<p><input type=password value=password> <input type=password value=password class=appearance-none>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/form-controls/input-placeholder-line-height-ref.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/form-controls/input-placeholder-line-height-ref.html
new file mode 100644
index 0000000000..856146dec4
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/form-controls/input-placeholder-line-height-ref.html
@@ -0,0 +1,2 @@
+<!doctype html>
+<input placeholder=Foo>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/form-controls/input-placeholder-line-height.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/form-controls/input-placeholder-line-height.html
new file mode 100644
index 0000000000..7af4e65b09
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/form-controls/input-placeholder-line-height.html
@@ -0,0 +1,10 @@
+<!doctype html>
+<title>line-height has no effect on placeholder</title>
+<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1714631">
+<link rel="match" href="input-placeholder-line-height-ref.html">
+<style>
+ input::placeholder {
+ line-height: 0;
+ }
+</style>
+<input placeholder=Foo>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/form-controls/placeholder-opacity-default.tentative.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/form-controls/placeholder-opacity-default.tentative.html
new file mode 100644
index 0000000000..39ad44cfc0
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/form-controls/placeholder-opacity-default.tentative.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>Placeholder Test: opacity default value</title>
+ <link rel="author" title="Karl Dubost" href="mailto:kdubost@mozilla.com"
+ />
+ <link rel="help" href="https://drafts.csswg.org/css-pseudo-4/#placeholder-pseudo"
+ />
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+ <body>
+ <input
+ id="opacity"
+ placeholder="::placeholder should have default opacity: 1"
+ />
+ <script>
+ test(function () {
+ var target = document.getElementById("opacity");
+ assert_equals(getComputedStyle(target, '::placeholder').opacity, "1");
+ }, "Default opacity value is '1'");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/form-controls/resets.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/form-controls/resets.html
new file mode 100644
index 0000000000..db21188ee3
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/form-controls/resets.html
@@ -0,0 +1,118 @@
+<!doctype html>
+<title>default style resets</title>
+<meta name="viewport" content="width=device-width">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/rendering/support/test-ua-stylesheet.js"></script>
+<style>
+/* Have some non-initial values on the parent so we can tell the difference whether the UA stylesheet uses 'initial' keyword. */
+#tests, #refs {
+ letter-spacing: 5px;
+ word-spacing: 5px;
+ line-height: 5px;
+ text-transform: uppercase;
+ text-indent: 5px;
+ text-shadow: 0 0 5px transparent;
+ text-align: right;
+}
+</style>
+<style>
+/* Specify this bogus namespace, so the rules in this stylesheet only apply to the `fakeClone`d elements in #refs, not the HTML elements in #tests. */
+@namespace url(urn:not-html);
+
+input, select, button, textarea {
+ letter-spacing: initial;
+ word-spacing: initial;
+ line-height: initial;
+ text-transform: initial;
+ text-indent: initial;
+ text-shadow: initial;
+}
+input, select, textarea {
+ text-align: initial;
+}
+input[type=reset i], input[type=button i], input[type=submit i], button {
+ text-align: center;
+}
+input[type=radio i], input[type=checkbox i], input[type=reset i], input[type=button i],
+input[type=submit i], input[type=color i], input[type=search i], select, button {
+ box-sizing: border-box;
+}
+input, button {
+ display: inline-block;
+}
+input:not([type=image i], [type=range i], [type=checkbox i], [type=radio i]) {
+ overflow: clip;
+ overflow-clip-margin: 0;
+}
+/* in spec prose: */ select, textarea, meter, progress {
+ display: inline-block;
+}
+input[type=hidden i] { display: none !important; }
+marquee {
+ text-align: initial;
+}
+table { display: table; box-sizing: border-box; }
+caption { display: table-caption; }
+colgroup, colgroup[hidden] { display: table-column-group; }
+col, col[hidden] { display: table-column; }
+thead, thead[hidden] { display: table-header-group; }
+tbody, tbody[hidden] { display: table-row-group; }
+tfoot, tfoot[hidden] { display: table-footer-group; }
+tr, tr[hidden] { display: table-row; }
+td, th { display: table-cell; }
+table {
+ text-indent: initial;
+}
+</style>
+
+<div id="tests">
+ <input type="hidden">
+ <input type="text">
+ <input type="search">
+ <input type="tel">
+ <input type="url">
+ <input type="email">
+ <input type="password">
+ <input type="date">
+ <input type="month">
+ <input type="week">
+ <input type="time">
+ <input type="datetime-local">
+ <input type="number">
+ <input type="range">
+ <input type="color">
+ <input type="checkbox">
+ <input type="radio">
+ <input type="file">
+ <input type="submit">
+ <input type="image">
+ <input type="reset">
+ <input type="button">
+ <select><optgroup><option></select>
+ <select multiple></select>
+ <optgroup></optgroup>
+ <option></option>
+ <button></button>
+ <textarea></textarea>
+ <table><tbody><tr><td></table>
+ <marquee></marquee>
+</div>
+
+<div id="refs"></div>
+
+<script>
+ const props = ['letter-spacing',
+ 'word-spacing',
+ 'line-height',
+ 'text-transform',
+ 'text-indent',
+ 'text-shadow',
+ 'text-align',
+ 'display',
+ 'overflow',
+ 'overflow-clip-margin',
+ 'box-sizing'];
+ runUAStyleTests(props);
+
+</script>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/form-controls/select-fixedpos-crash.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/form-controls/select-fixedpos-crash.html
new file mode 100644
index 0000000000..47046f6c25
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/form-controls/select-fixedpos-crash.html
@@ -0,0 +1,22 @@
+<!doctype html>
+<meta charset=utf-8>
+<link rel=author href="mailto:emilio@crisal.io" title="Emilio Cobos Álvarez">
+<link rel=author href="https://mozilla.org" title="Mozilla">
+<link rel=help href="https://bugzilla.mozilla.org/show_bug.cgi?id=1741776">
+<style>
+#a {
+ rotate: 1deg 1 0 44;
+ filter: drop-shadow(81px 6px 0px red);
+}
+</style>
+<script>
+window.onload = function() {
+ document.getElementById("b").appendChild(document.getElementById("c"));
+}
+</script>
+<select id="a" multiple="multiple">
+ <option id="b">x</option>
+</select>
+<div id="c" style="position: fixed; top: 0; left: 0;">
+ x
+</div>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/form-controls/select-sizing-001-ref.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/form-controls/select-sizing-001-ref.html
new file mode 100644
index 0000000000..c59a6e1d98
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/form-controls/select-sizing-001-ref.html
@@ -0,0 +1,59 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>Reference for sizing of select elements, with wide vs. empty option selected</title>
+ <link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com">
+ <style>
+ select {
+ color: transparent;
+ margin: 1px;
+ }
+ div.customBorder > select {
+ /* This class is to let us test select elements *without* native theming
+ (for browsers that have both native and non-native controls): */
+ border: 3px solid black;
+ }
+ </style>
+</head>
+<body>
+ <div>
+ <select>
+ <option>some wide option</option>
+ </select>
+ <br>
+ <select>
+ <option>some wide option</option>
+ </select>
+ <br>
+ <select>
+ <option>some wide option</option>
+ </select>
+ <br>
+ <select>
+ <option>some wide option</option>
+ </select>
+ </div>
+
+ <!-- This is the same as above, but now with a custom border on the
+ select elements: -->
+ <div class="customBorder">
+ <select>
+ <option>some wide option</option>
+ </select>
+ <br>
+ <select>
+ <option>some wide option</option>
+ </select>
+ <br>
+ <select>
+ <option>some wide option</option>
+ </select>
+ <br>
+ <select>
+ <option>some wide option</option>
+ </select>
+ </div>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/form-controls/select-sizing-001.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/form-controls/select-sizing-001.html
new file mode 100644
index 0000000000..e8db3eae1d
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/form-controls/select-sizing-001.html
@@ -0,0 +1,77 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>Test for sizing of select elements, with wide vs. empty option selected</title>
+ <link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com">
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/rendering.html#list-box">
+ <link rel="match" href="select-sizing-001-ref.html">
+ <style>
+ select {
+ color: transparent;
+ margin: 1px;
+ }
+ div.customBorder > select {
+ /* This class is to let us test select elements *without* native theming
+ (for browsers that have both native and non-native controls): */
+ border: 3px solid black;
+ }
+ </style>
+</head>
+<body>
+ <div>
+ <!-- Wide thing is 2nd, and not selected: -->
+ <select>
+ <option></option>
+ <option>some wide option</option>
+ </select>
+ <br>
+ <!-- Wide thing is 2nd, and selected: -->
+ <select>
+ <option></option>
+ <option selected>some wide option</option>
+ </select>
+ <br>
+ <!-- Wide thing is 1st, and selected (implicitly): -->
+ <select>
+ <option>some wide option</option>
+ <option></option>
+ </select>
+ <br>
+ <!-- Wide thing is 1st, and not selected: -->
+ <select>
+ <option>some wide option</option>
+ <option selected></option>
+ </select>
+ </div>
+
+ <!-- This is the same as above, but now with a custom border on the
+ select elements: -->
+ <div class="customBorder">
+ <!-- Wide thing is 2nd, and not selected: -->
+ <select>
+ <option></option>
+ <option>some wide option</option>
+ </select>
+ <br>
+ <!-- Wide thing is 2nd, and selected: -->
+ <select>
+ <option></option>
+ <option selected>some wide option</option>
+ </select>
+ <br>
+ <!-- Wide thing is 1st, and selected (implicitly): -->
+ <select>
+ <option>some wide option</option>
+ <option></option>
+ </select>
+ <br>
+ <!-- Wide thing is 1st, and not selected: -->
+ <select>
+ <option>some wide option</option>
+ <option selected></option>
+ </select>
+ </div>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/form-controls/text-transform-ref.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/form-controls/text-transform-ref.html
new file mode 100644
index 0000000000..5dc26a78db
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/form-controls/text-transform-ref.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+</head>
+<body>
+ <span>THIS TEXT SHOULD BE UPPER-CASE.</span><br />
+
+ <input type="text" value="this text should be lower-case."><br />
+
+ <select>
+ <option>this text should be lower-case.</option>
+ </select><br />
+ <select multiple>
+ <option>this text should be lower-case.</option>
+ </select><br />
+ <select multiple>
+ <optgroup label="this text should be lower-case.">
+ <option>this text should be lower-case.</option>
+ </optgroup>
+ </select><br />
+
+ <select>
+ <option>THIS TEXT SHOULD BE UPPER-CASE.</option>
+ </select><br />
+ <select multiple>
+ <option>THIS TEXT SHOULD BE UPPER-CASE.</option>
+ </select><br />
+ <select multiple>
+ <optgroup label="THIS TEXT SHOULD BE UPPER-CASE.">
+ <option>THIS TEXT SHOULD BE UPPER-CASE.</option>
+ </optgroup>
+ </select><br />
+
+ <button>this text should be lower-case.</button><br />
+
+ <textarea>this text should be lower-case.</textarea><br />
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/form-controls/text-transform.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/form-controls/text-transform.html
new file mode 100644
index 0000000000..f57f092982
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/form-controls/text-transform.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <link rel="match" href="text-transform-ref.html">
+</head>
+<body style="text-transform: uppercase;">
+ <span>this text should be upper-case.</span><br />
+
+ <input type="text" value="this text should be lower-case."><br />
+
+ <select>
+ <option>this text should be lower-case.</option>
+ </select><br />
+ <select multiple>
+ <option>this text should be lower-case.</option>
+ </select><br />
+ <select multiple>
+ <optgroup label="this text should be lower-case.">
+ <option>this text should be lower-case.</option>
+ </optgroup>
+ </select><br />
+
+ <select style="text-transform: uppercase;">
+ <option>this text should be upper-case.</option>
+ </select><br />
+ <select multiple style="text-transform: uppercase;">
+ <option>this text should be upper-case.</option>
+ </select><br />
+ <select multiple style="text-transform: uppercase;">
+ <optgroup label="this text should be upper-case.">
+ <option>this text should be upper-case.</option>
+ </optgroup>
+ </select><br />
+
+ <button>this text should be lower-case.</button><br />
+
+ <textarea>this text should be lower-case.</textarea><br />
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/form-controls/toggle-display-ref.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/form-controls/toggle-display-ref.html
new file mode 100644
index 0000000000..8093efe5e8
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/form-controls/toggle-display-ref.html
@@ -0,0 +1,47 @@
+<!doctype html>
+<html>
+<title>Reference: toggle 'display' test</title>
+
+<div id="tests">
+ <input type="hidden">
+ <input type="text">
+ <input type="text" value="a">
+ <input type="search">
+ <input type="search" value="a">
+ <input type="tel">
+ <input type="tel" value="123456789">
+ <input type="url">
+ <input type="url" value="http://a">
+ <input type="email">
+ <input type="email" value="a">
+ <input type="password">
+ <input type="password" value="a">
+ <input type="date">
+ <input type="month">
+ <input type="week">
+ <input type="time">
+ <input type="datetime-local">
+ <input type="number">
+ <input type="range">
+ <input type="color">
+ <input type="checkbox">
+ <input type="radio">
+ <input type="file">
+ <input type="submit">
+ <input type="image">
+ <input type="reset">
+ <input type="button">
+ <input type="button" value="a">
+ <select><optgroup><option></select>
+ <select><optgroup><option>a</select>
+ <select multiple></select>
+ <select multiple><optgroup>a</optgroup><option>b</option></select>
+ <optgroup></optgroup>
+ <option></option>
+ <button></button>
+ <button>a</button>
+ <textarea></textarea>
+ <textarea>a</textarea>
+</div>
+
+</html>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/form-controls/toggle-display.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/form-controls/toggle-display.html
new file mode 100644
index 0000000000..127679b2ad
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/form-controls/toggle-display.html
@@ -0,0 +1,64 @@
+<!doctype html>
+<html class="reftest-wait">
+<title>toggle 'display' test</title>
+<meta charset="utf-8">
+<link rel="match" href="toggle-display-ref.html">
+
+<div id="tests">
+ <input type="hidden">
+ <input type="text">
+ <input type="text" value="a">
+ <input type="search">
+ <input type="search" value="a">
+ <input type="tel">
+ <input type="tel" value="123456789">
+ <input type="url">
+ <input type="url" value="http://a">
+ <input type="email">
+ <input type="email" value="a">
+ <input type="password">
+ <input type="password" value="a">
+ <input type="date">
+ <input type="month">
+ <input type="week">
+ <input type="time">
+ <input type="datetime-local">
+ <input type="number">
+ <input type="range">
+ <input type="color">
+ <input type="checkbox">
+ <input type="radio">
+ <input type="file">
+ <input type="submit">
+ <input type="image">
+ <input type="reset">
+ <input type="button">
+ <input type="button" value="a">
+ <select><optgroup><option></select>
+ <select><optgroup><option>a</select>
+ <select multiple></select>
+ <select multiple><optgroup>a</optgroup><option>b</option></select>
+ <optgroup></optgroup>
+ <option></option>
+ <button></button>
+ <button>a</button>
+ <textarea></textarea>
+ <textarea>a</textarea>
+</div>
+
+<script>
+window.onload = () => {
+ requestAnimationFrame(() => {
+ requestAnimationFrame(() => {
+ let tests = document.querySelector('#tests');
+ tests.style.display = 'none';
+ requestAnimationFrame(() => {
+ tests.style.display = '';
+ document.documentElement.classList.remove("reftest-wait");
+ });
+ });
+ });
+}
+</script>
+
+</html>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/hidden-elements.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/hidden-elements.html
new file mode 100644
index 0000000000..e1bcf508e5
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/hidden-elements.html
@@ -0,0 +1,52 @@
+<!doctype html>
+<link rel=help href="https://html.spec.whatwg.org/#hidden-elements">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div hidden></div>
+<embed hidden>
+<embed hidden=until-found>
+<script>
+const kNotHiddenElementLocalNames = [
+ "source", "track",
+];
+
+const kHiddenElementLocalNames = [
+ "area", "base", "basefont", "datalist", "head", "link", "meta", "noembed",
+ "noframes", "param", "rp", "script", "style", "template", "title",
+];
+
+for (let name of kNotHiddenElementLocalNames) {
+ test(function() {
+ let element = document.createElement(name);
+ document.body.appendChild(element);
+ assert_equals(getComputedStyle(element).display, "inline");
+ }, `${name} should not be hidden`);
+}
+
+for (let name of kHiddenElementLocalNames) {
+ test(function() {
+ let element = document.createElement(name);
+ document.body.appendChild(element);
+ assert_equals(getComputedStyle(element).display, "none");
+ }, `${name} should be hidden`);
+}
+
+test(function() {
+ assert_equals(getComputedStyle(document.querySelector("div[hidden]")).display, "none");
+}, `div[hidden] element should be hidden`);
+
+test(function() {
+ const el = document.querySelector("embed[hidden='']");
+ assert_equals(getComputedStyle(el).display, "inline");
+ assert_equals(getComputedStyle(el).width, "0px");
+ assert_equals(getComputedStyle(el).height, "0px");
+}, `embed[hidden=''] element should be inline 0x0`);
+
+test(function() {
+ const el = document.querySelector("embed[hidden='until-found']");
+ assert_equals(getComputedStyle(el).display, "inline");
+ assert_equals(getComputedStyle(el).width, "0px");
+ assert_equals(getComputedStyle(el).height, "0px");
+ assert_equals(getComputedStyle(el).contentVisibility, "visible");
+}, `embed[hidden='until-found'] element should be inline 0x0`);
+</script>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/TODO-lists.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/TODO-lists.html
new file mode 100644
index 0000000000..6d79efc384
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/TODO-lists.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<ol><div><li>A</div></ol>
+<ol><div><li>A</div> <li>B</ol>
+<ol><div><li>A</div><div><li>B</div></ol>
+<ol reversed><div><li>A</div> <li>B</ol>
+<ol><div style=display:list-item>A</div><li>B</ol>
+<ol reversed><div style=display:list-item>A</div><li>B</ol>
+<ol reversed>
+ <div><li>Two</li></div>
+ <li>One</li>
+ <li>Zero</li>
+</ol>
+<ol reversed>
+ <li>Three</li>
+ <li style="display: none"></li>
+ <li>Two</li>
+</ol>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/dir-type-ref.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/dir-type-ref.html
new file mode 100644
index 0000000000..710b39ceca
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/dir-type-ref.html
@@ -0,0 +1,9 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>Test reference</title>
+<dir>
+ <li>A
+</dir>
+<dir>
+ <li>B
+</dir>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/dir-type.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/dir-type.html
new file mode 100644
index 0000000000..d1f0ae3fe3
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/dir-type.html
@@ -0,0 +1,13 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>&lt;dir&gt; doesn't map the type and start attributes to CSS</title>
+<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1831863">
+<link rel="author" href="mailto:emilio@crisal.io" title="Emilio Cobos Álvarez">
+<link rel="author" href="https://mozilla.com" title="Mozilla">
+<link rel="match" href="dir-type-ref.html">
+<dir type="square">
+ <li>A
+</dir>
+<dir type="decimal" start="5">
+ <li>B
+</dir>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/li-text-align.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/li-text-align.html
new file mode 100644
index 0000000000..0fc01f275c
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/li-text-align.html
@@ -0,0 +1,18 @@
+<!doctype html>
+<title>text-align: match-parent on li</title>
+<meta name="viewport" content="width=device-width">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<ul dir=rtl><li dir=ltr></li></ul>
+<ul dir=ltr><li dir=rtl></li></ul>
+<script>
+ test(() => {
+ const li = document.querySelector('li[dir=ltr]');
+ assert_equals(getComputedStyle(li).textAlign, 'right');
+ }, '<ul dir=rtl><li dir=ltr>');
+
+ test(() => {
+ const li = document.querySelector('li[dir=rtl]');
+ assert_equals(getComputedStyle(li).textAlign, 'left');
+ }, '<ul dir=ltr><li dir=rtl>');
+</script>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/li-type-supported-ref.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/li-type-supported-ref.html
new file mode 100644
index 0000000000..0de7ff329c
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/li-type-supported-ref.html
@@ -0,0 +1,45 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>li@type: supported types</title>
+<style>
+ .decimal { list-style-type: decimal; }
+ .lower-alpha { list-style-type: lower-alpha; }
+ .upper-alpha { list-style-type: upper-alpha; }
+ .lower-roman { list-style-type: lower-roman; }
+ .upper-roman { list-style-type: upper-roman; }
+ .disc { list-style-type: disc; }
+ .circle { list-style-type: circle; }
+ .square { list-style-type: square; }
+ .none { list-style-type: none; }
+</style>
+<li class="decimal">first item</li>
+<li class="lower-alpha">second item</li>
+<li class="upper-alpha">third item</li>
+<li class="lower-roman">fourth item</li>
+<li class="upper-roman">fifth item</li>
+<li class="disc">sixth item</li>
+<li class="circle">seventh item</li>
+<li class="square">eighth item</li>
+<li class="none">ninth item</li>
+<ol>
+ <li class="decimal">first ordered item</li>
+ <li class="lower-alpha">second ordered item</li>
+ <li class="upper-alpha">third ordered item</li>
+ <li class="lower-roman">fourth ordered item</li>
+ <li class="upper-roman">fifth ordered item</li>
+ <li class="disc">sixth ordered item</li>
+ <li class="circle">seventh ordered item</li>
+ <li class="square">eighth ordered item</li>
+ <li class="none">ninth ordered item</li>
+</ol>
+<ul>
+ <li class="decimal">first unordered item</li>
+ <li class="lower-alpha">second unordered item</li>
+ <li class="upper-alpha">third unordered item</li>
+ <li class="lower-roman">fourth unordered item</li>
+ <li class="upper-roman">fifth unordered item</li>
+ <li class="disc">sixth unordered item</li>
+ <li class="circle">seventh unordered item</li>
+ <li class="square">eighth unordered item</li>
+ <li class="none">ninth unordered item</li>
+</ul>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/li-type-supported-xhtml.xhtml b/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/li-type-supported-xhtml.xhtml
new file mode 100644
index 0000000000..7a7640e03f
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/li-type-supported-xhtml.xhtml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title>li@type: supported types</title>
+<link rel="match" href="li-type-supported-ref.html"/>
+</head>
+<body>
+<li type="1">first item</li>
+<li type="a">second item</li>
+<li type="A">third item</li>
+<li type="i">fourth item</li>
+<li type="I">fifth item</li>
+<li type="disc">sixth item</li>
+<li type="circle">seventh item</li>
+<li type="square">eighth item</li>
+<li type="none">ninth item</li>
+<ol>
+ <li type="1">first ordered item</li>
+ <li type="a">second ordered item</li>
+ <li type="A">third ordered item</li>
+ <li type="i">fourth ordered item</li>
+ <li type="I">fifth ordered item</li>
+ <li type="disc">sixth ordered item</li>
+ <li type="circle">seventh ordered item</li>
+ <li type="square">eighth ordered item</li>
+ <li type="none">ninth ordered item</li>
+</ol>
+<ul>
+ <li type="1">first unordered item</li>
+ <li type="a">second unordered item</li>
+ <li type="A">third unordered item</li>
+ <li type="i">fourth unordered item</li>
+ <li type="I">fifth unordered item</li>
+ <li type="disc">sixth unordered item</li>
+ <li type="circle">seventh unordered item</li>
+ <li type="square">eighth unordered item</li>
+ <li type="none">ninth unordered item</li>
+</ul>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/li-type-supported.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/li-type-supported.html
new file mode 100644
index 0000000000..ddd9024c11
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/li-type-supported.html
@@ -0,0 +1,35 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>li@type: supported types</title>
+<link rel=match href=li-type-supported-ref.html>
+<li type=1>first item</li>
+<li type=a>second item</li>
+<li type=A>third item</li>
+<li type=i>fourth item</li>
+<li type=I>fifth item</li>
+<li type=disc>sixth item</li>
+<li type=circle>seventh item</li>
+<li type=square>eighth item</li>
+<li type=none>ninth item</li>
+<ol>
+ <li type=1>first ordered item</li>
+ <li type=a>second ordered item</li>
+ <li type=A>third ordered item</li>
+ <li type=i>fourth ordered item</li>
+ <li type=I>fifth ordered item</li>
+ <li type=disc>sixth ordered item</li>
+ <li type=circle>seventh ordered item</li>
+ <li type=square>eighth ordered item</li>
+ <li type=none>ninth ordered item</li>
+</ol>
+<ul>
+ <li type=1>first unordered item</li>
+ <li type=a>second unordered item</li>
+ <li type=A>third unordered item</li>
+ <li type=i>fourth unordered item</li>
+ <li type=I>fifth unordered item</li>
+ <li type=disc>sixth unordered item</li>
+ <li type=circle>seventh unordered item</li>
+ <li type=square>eighth unordered item</li>
+ <li type=none>ninth unordered item</li>
+</ul>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/li-type-unsupported-lower-alpha.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/li-type-unsupported-lower-alpha.html
new file mode 100644
index 0000000000..81babe7888
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/li-type-unsupported-lower-alpha.html
@@ -0,0 +1,14 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>li@type: unsupported type: lower-alpha</title>
+<link rel=match href=li-type-unsupported-ref.html>
+<li type=lower-alpha>first item</li>
+<li type=LOWER-ALPHA>second item</li>
+<ol>
+ <li type=lower-alpha>first ordered item</li>
+ <li type=LOWER-ALPHA>second ordered item</li>
+</ol>
+<ul>
+ <li type=lower-alpha>first unordered item</li>
+ <li type=LOWER-ALPHA>second unordered item</li>
+</ul>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/li-type-unsupported-lower-roman.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/li-type-unsupported-lower-roman.html
new file mode 100644
index 0000000000..e01cfdb72d
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/li-type-unsupported-lower-roman.html
@@ -0,0 +1,14 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>li@type: unsupported type: lower-roman</title>
+<link rel=match href=li-type-unsupported-ref.html>
+<li type=lower-roman>first item</li>
+<li type=LOWER-ROMAN>second item</li>
+<ol>
+ <li type=lower-roman>first ordered item</li>
+ <li type=LOWER-ROMAN>second ordered item</li>
+</ol>
+<ul>
+ <li type=lower-roman>first unordered item</li>
+ <li type=LOWER-ROMAN>second unordered item</li>
+</ul>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/li-type-unsupported-ref.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/li-type-unsupported-ref.html
new file mode 100644
index 0000000000..4fbc5aca97
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/li-type-unsupported-ref.html
@@ -0,0 +1,13 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>li@type: unsupported types</title>
+<li>first item</li>
+<li>second item</li>
+<ol>
+ <li>first ordered item</li>
+ <li>second ordered item</li>
+</ol>
+<ul>
+ <li>first unordered item</li>
+ <li>second unordered item</li>
+</ul>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/li-type-unsupported-upper-alpha.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/li-type-unsupported-upper-alpha.html
new file mode 100644
index 0000000000..2efb65dbda
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/li-type-unsupported-upper-alpha.html
@@ -0,0 +1,14 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>li@type: unsupported type: upper-alpha</title>
+<link rel=match href=li-type-unsupported-ref.html>
+<li type=upper-alpha>first item</li>
+<li type=UPPER-ALPHA>second item</li>
+<ol>
+ <li type=upper-alpha>first ordered item</li>
+ <li type=UPPER-ALPHA>second ordered item</li>
+</ol>
+<ul>
+ <li type=upper-alpha>first unordered item</li>
+ <li type=UPPER-ALPHA>second unordered item</li>
+</ul>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/li-type-unsupported-upper-roman.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/li-type-unsupported-upper-roman.html
new file mode 100644
index 0000000000..bd8dafc9c2
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/li-type-unsupported-upper-roman.html
@@ -0,0 +1,14 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>li@type: unsupported type: upper-roman</title>
+<link rel=match href=li-type-unsupported-ref.html>
+<li type=upper-roman>first item</li>
+<li type=UPPER-ROMAN>second item</li>
+<ol>
+ <li type=upper-roman>first ordered item</li>
+ <li type=UPPER-ROMAN>second ordered item</li>
+</ol>
+<ul>
+ <li type=upper-roman>first unordered item</li>
+ <li type=UPPER-ROMAN>second unordered item</li>
+</ul>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/lists-presentational-hints-ascii-case-insensitive.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/lists-presentational-hints-ascii-case-insensitive.html
new file mode 100644
index 0000000000..396055f73b
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/lists-presentational-hints-ascii-case-insensitive.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<link rel="help" href="https://html.spec.whatwg.org/#lists:presentational-hints">
+<link rel="help" href="https://drafts.csswg.org/selectors-4/#attribute-case">
+<meta name="assert" content="ul@type + li@type values are ASCII case-insensitive">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<ul type="circle"><li type="disc"></ul>
+<ul type="circle"><li type="DiSc"></ul>
+<ul type="circle"><li type="diſc"></ul>
+<ul type="circle"><li type="square"></ul>
+<ul type="circle"><li type="SqUaRe"></ul>
+<ul type="circle"><li type="ſquare"></ul>
+<script>
+const li = document.querySelectorAll("li");
+
+test(() => {
+ assert_equals(getComputedStyle(li[0]).getPropertyValue("list-style-type"),
+ "disc", "lowercase valid");
+ assert_equals(getComputedStyle(li[1]).getPropertyValue("list-style-type"),
+ "disc", "mixed case valid");
+ assert_equals(getComputedStyle(li[2]).getPropertyValue("list-style-type"),
+ "circle", "non-ASCII invalid");
+}, "keyword disc");
+
+test(() => {
+ assert_equals(getComputedStyle(li[3]).getPropertyValue("list-style-type"),
+ "square", "lowercase valid");
+ assert_equals(getComputedStyle(li[4]).getPropertyValue("list-style-type"),
+ "square", "mixed case valid");
+ assert_equals(getComputedStyle(li[5]).getPropertyValue("list-style-type"),
+ "circle", "non-ASCII invalid");
+}, "keyword square");
+</script>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/lists-styles.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/lists-styles.html
new file mode 100644
index 0000000000..a5f011cecc
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/lists-styles.html
@@ -0,0 +1,228 @@
+<!doctype html>
+<title>default styles and preshints for ol, ul, menu, li, dir, dl, dt, dd</title>
+<meta name="viewport" content="width=device-width">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/rendering/support/test-ua-stylesheet.js"></script>
+<style>
+/* Specify this bogus namespace, so the rules in this stylesheet only apply to the `fakeClone`d elements in #refs, not the HTML elements in #tests. */
+@namespace url(urn:not-html);
+
+dir, dd, dl, dt, menu, ol, ul { display: block; }
+li { display: list-item; text-align: match-parent; }
+
+dir, dl, menu, ol, ul { margin-block-start: 1em; margin-block-end: 1em; }
+
+:is(dir, dl, menu, ol, ul) :is(dir, dl, menu, ol, ul) {
+ margin-block-start: 0; margin-block-end: 0;
+}
+
+dd { margin-inline-start: 40px; }
+dir, menu, ol, ul { padding-inline-start: 40px; }
+
+ol, ul, menu { counter-reset: list-item; }
+ol { list-style-type: decimal; }
+
+dir, menu, ul {
+ list-style-type: disc;
+}
+:is(dir, menu, ol, ul) :is(dir, menu, ul) {
+ list-style-type: circle;
+}
+:is(dir, menu, ol, ul) :is(dir, menu, ol, ul) :is(dir, menu, ul) {
+ list-style-type: square;
+}
+
+/* preshints */
+ol[type="1"], li[type="1"] { list-style-type: decimal; }
+/* use classes due to lack of support for "s" annotation */
+ol[class=type-a], li[class=type-a] { list-style-type: lower-alpha; }
+ol[class=type-A], li[class=type-A] { list-style-type: upper-alpha; }
+ol[class=type-i], li[class=type-i] { list-style-type: lower-roman; }
+ol[class=type-I], li[class=type-I] { list-style-type: upper-roman; }
+ul[type=none i], li[type=none i] { list-style-type: none; }
+ul[type=disc i], li[type=disc i] { list-style-type: disc; }
+ul[type=circle i], li[type=circle i] { list-style-type: circle; }
+ul[type=square i], li[type=square i] { list-style-type: square; }
+
+li[value="10"], li[value="10xyz"], li[value="10e10"] { counter-set: list-item 10; }
+ol[start="10"], ol[start="10xyz"], ol[start="10e10"] { counter-reset: list-item 9; }
+ol[reversed] { counter-reset: reversed(list-item); }
+ol[reversed][start="20"], ol[reversed][start="20xyz"], ol[reversed][start="20e10"] { counter-reset: reversed(list-item) 21; }
+
+/* dir="" */
+[dir=ltr] { direction: ltr; }
+[dir=rtl] { direction: rtl; }
+</style>
+
+<div id="log"></div>
+
+<div id="tests">
+ <li></li>
+ <dir>
+ <li></li>
+ </dir>
+ <dt></dt>
+ <dd></dd>
+ <dl>
+ <dt></dt>
+ <dd></dd>
+ </dl>
+ <menu>
+ <li></li>
+ </menu>
+ <ol>
+ <li></li>
+ </ol>
+ <ul>
+ <li></li>
+ </ul>
+ <dir data-skip><dir></dir></dir>
+ <dir data-skip><menu></menu></dir>
+ <dir data-skip><ul></ul></dir>
+ <menu data-skip><dir></dir></menu>
+ <menu data-skip><menu></menu></menu>
+ <menu data-skip><ul></ul></menu>
+ <ol data-skip><dir></dir></ol>
+ <ol data-skip><menu></menu></ol>
+ <ol data-skip><ul></ul></ol>
+ <ul data-skip><dir></dir></ul>
+ <ul data-skip><menu></menu></ul>
+ <ul data-skip><ul></ul></ul>
+
+ <dir data-skip><dir data-skip><dir></dir></dir></dir>
+ <dir data-skip><dir data-skip><menu></menu></dir></dir>
+ <dir data-skip><dir data-skip><ul></ul></dir></dir>
+ <dir data-skip><menu data-skip><dir></dir></menu></dir>
+ <dir data-skip><menu data-skip><menu></menu></menu></dir>
+ <dir data-skip><menu data-skip><ul></ul></menu></dir>
+ <dir data-skip><ol data-skip><dir></dir></ol></dir>
+ <dir data-skip><ol data-skip><menu></menu></ol></dir>
+ <dir data-skip><ol data-skip><ul></ul></ol></dir>
+ <dir data-skip><ul data-skip><dir></dir></ul></dir>
+ <dir data-skip><ul data-skip><menu></menu></ul></dir>
+ <dir data-skip><ul data-skip><ul></ul></ul></dir>
+
+ <menu data-skip><dir data-skip><dir></dir></dir></menu>
+ <menu data-skip><dir data-skip><menu></menu></dir></menu>
+ <menu data-skip><dir data-skip><ul></ul></dir></menu>
+ <menu data-skip><menu data-skip><dir></dir></menu></menu>
+ <menu data-skip><menu data-skip><menu></menu></menu></menu>
+ <menu data-skip><menu data-skip><ul></ul></menu></menu>
+ <menu data-skip><ol data-skip><dir></dir></ol></menu>
+ <menu data-skip><ol data-skip><menu></menu></ol></menu>
+ <menu data-skip><ol data-skip><ul></ul></ol></menu>
+ <menu data-skip><ul data-skip><dir></dir></ul></menu>
+ <menu data-skip><ul data-skip><menu></menu></ul></menu>
+ <menu data-skip><ul data-skip><ul></ul></ul></menu>
+
+ <ol data-skip><dir data-skip><dir></dir></dir></ol>
+ <ol data-skip><dir data-skip><menu></menu></dir></ol>
+ <ol data-skip><dir data-skip><ul></ul></dir></ol>
+ <ol data-skip><menu data-skip><dir></dir></menu></ol>
+ <ol data-skip><menu data-skip><menu></menu></menu></ol>
+ <ol data-skip><menu data-skip><ul></ul></menu></ol>
+ <ol data-skip><ol data-skip><dir></dir></ol></ol>
+ <ol data-skip><ol data-skip><menu></menu></ol></ol>
+ <ol data-skip><ol data-skip><ul></ul></ol></ol>
+ <ol data-skip><ul data-skip><dir></dir></ul></ol>
+ <ol data-skip><ul data-skip><menu></menu></ul></ol>
+ <ol data-skip><ul data-skip><ul></ul></ul></ol>
+
+ <ul data-skip><dir data-skip><dir></dir></dir></ul>
+ <ul data-skip><dir data-skip><menu></menu></dir></ul>
+ <ul data-skip><dir data-skip><ul></ul></dir></ul>
+ <ul data-skip><menu data-skip><dir></dir></menu></ul>
+ <ul data-skip><menu data-skip><menu></menu></menu></ul>
+ <ul data-skip><menu data-skip><ul></ul></menu></ul>
+ <ul data-skip><ol data-skip><dir></dir></ol></ul>
+ <ul data-skip><ol data-skip><menu></menu></ol></ul>
+ <ul data-skip><ol data-skip><ul></ul></ol></ul>
+ <ul data-skip><ul data-skip><dir></dir></ul></ul>
+ <ul data-skip><ul data-skip><menu></menu></ul></ul>
+ <ul data-skip><ul data-skip><ul></ul></ul></ul>
+
+ <ol type="1"></ol>
+ <ul type="1"></ul>
+ <li type="1"></li>
+ <ol type="a" class="type-a"></ol>
+ <ul type="a" class="type-a"></ul>
+ <li type="a" class="type-a"></li>
+ <ol type="A" class="type-A"></ol>
+ <ul type="A" class="type-A"></ul>
+ <li type="A" class="type-A"></li>
+ <ol type="i" class="type-i"></ol>
+ <ul type="i" class="type-i"></ul>
+ <li type="i" class="type-i"></li>
+ <ol type="I" class="type-I"></ol>
+ <ul type="I" class="type-I"></ul>
+ <li type="I" class="type-I"></li>
+ <ol type="none"></ol>
+ <ul type="none"></ul>
+ <li type="none"></li>
+ <ol type="NONE"></ol>
+ <ul type="NONE"></ul>
+ <li type="NONE"></li>
+ <ol type="disc"></ol>
+ <ul type="disc"></ul>
+ <li type="disc"></li>
+ <ol type="DISC"></ol>
+ <ul type="DISC"></ul>
+ <li type="DISC"></li>
+ <ol type="circle"></ol>
+ <ul type="circle"></ul>
+ <li type="circle"></li>
+ <ol type="CIRCLE"></ol>
+ <ul type="CIRCLE"></ul>
+ <li type="CIRCLE"></li>
+ <ol type="square"></ol>
+ <ul type="square"></ul>
+ <li type="square"></li>
+ <ol type="SQUARE"></ol>
+ <ul type="SQUARE"></ul>
+ <li type="SQUARE"></li>
+
+ <ol>
+ <li value="10"></li>
+ <li value="10xyz"></li>
+ <li value="10e10"></li>
+ <li value="xyz"></li>
+ </ol>
+
+ <ol start="10"><li></li></ol>
+ <ol start="10xyz"><li></li></ol>
+ <ol start="10e10"><li></li></ol>
+ <ol start="xyz"><li></li></ol>
+ <ol reversed><li></li></ol>
+ <ol reversed start="20"><li></li></ol>
+ <ol reversed start="20xyz"><li></li></ol>
+ <ol reversed start="20e10"><li></li></ol>
+ <ol reversed start="xyz"><li></li></ol>
+
+ <ul data-skip dir="rtl"><li dir="ltr"></li></ul>
+ <ul data-skip dir="ltr"><li dir="rtl"></li></ul>
+
+</div>
+
+<div id="refs"></div>
+
+<script>
+ const props = [
+ 'display',
+ 'margin-top',
+ 'margin-right',
+ 'margin-bottom',
+ 'margin-left',
+ 'padding-top',
+ 'padding-right',
+ 'padding-bottom',
+ 'padding-left',
+ 'list-style-type',
+ 'counter-set',
+ 'counter-reset',
+ 'counter-increment',
+ 'text-align',
+ ];
+ runUAStyleTests(props);
+
+</script>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/ol-display-contents-ref.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/ol-display-contents-ref.html
new file mode 100644
index 0000000000..f9fce33313
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/ol-display-contents-ref.html
@@ -0,0 +1,8 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Reference for: display: contents; on &lt;ol ...></title>
+<style>
+ li { margin-left: 40px; list-style-type: decimal; }
+</style>
+<li value="1">The list item marker on this line should be "1."</li>
+<li value="2">The list item marker on this line should be "2."</li>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/ol-start-display-contents.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/ol-start-display-contents.html
new file mode 100644
index 0000000000..226570e935
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/ol-start-display-contents.html
@@ -0,0 +1,8 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>display: contents; on &lt;ol start></title>
+<meta rel=match href=ol-display-contents-ref.html>
+<ol start=5 style="display: contents">
+ <li style="margin-left: 40px">The list item marker on this line should be "1."</li>
+ <li style="margin-left: 40px">The list item marker on this line should be "2."</li>
+</ol>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/ol-start-reversed-display-contents.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/ol-start-reversed-display-contents.html
new file mode 100644
index 0000000000..dd6fff0fd8
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/ol-start-reversed-display-contents.html
@@ -0,0 +1,8 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>display: contents; on &lt;ol start reversed></title>
+<meta rel=match href=ol-display-contents-ref.html>
+<ol start=5 reversed style="display: contents">
+ <li style="margin-left: 40px">The list item marker on this line should be "1."</li>
+ <li style="margin-left: 40px">The list item marker on this line should be "2."</li>
+</ol>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/ol-type-supported-ref.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/ol-type-supported-ref.html
new file mode 100644
index 0000000000..fb61db3261
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/ol-type-supported-ref.html
@@ -0,0 +1,25 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>ol@type: supported types</title>
+<style>
+.decimal {
+ list-style-type: decimal;
+}
+.lower-alpha {
+ list-style-type: lower-alpha;
+}
+.upper-alpha {
+ list-style-type: upper-alpha;
+}
+.lower-roman {
+ list-style-type: lower-roman;
+}
+.upper-roman {
+ list-style-type: upper-roman;
+}
+</style>
+<ol class=decimal><li>1<li>2</ol>
+<ol class=lower-alpha><li>a<li>b</ol>
+<ol class=upper-alpha><li>A<li>B</ol>
+<ol class=lower-roman><li>i<li>ii</ol>
+<ol class=upper-roman><li>I<li>II</ol>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/ol-type-supported-xhtml.xhtml b/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/ol-type-supported-xhtml.xhtml
new file mode 100644
index 0000000000..d7b949dab1
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/ol-type-supported-xhtml.xhtml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title>ol@type: supported types</title>
+<link rel="match" href="ol-type-supported-ref.html"/>
+</head>
+<body>
+<ol type="1"><li>1</li><li>2</li></ol>
+<ol type="a"><li>a</li><li>b</li></ol>
+<ol type="A"><li>A</li><li>B</li></ol>
+<ol type="i"><li>i</li><li>ii</li></ol>
+<ol type="I"><li>I</li><li>II</li></ol>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/ol-type-supported.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/ol-type-supported.html
new file mode 100644
index 0000000000..86ed3be383
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/ol-type-supported.html
@@ -0,0 +1,9 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>ol@type: supported types</title>
+<link rel=match href=ol-type-supported-ref.html>
+<ol type=1><li>1<li>2</ol>
+<ol type=a><li>a<li>b</ol>
+<ol type=A><li>A<li>B</ol>
+<ol type=i><li>i<li>ii</ol>
+<ol type=I><li>I<li>II</ol>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/ol-type-unsupported-circle.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/ol-type-unsupported-circle.html
new file mode 100644
index 0000000000..f3c52e43bd
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/ol-type-unsupported-circle.html
@@ -0,0 +1,6 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>ol@type: unsupported type: circle</title>
+<link rel=match href=ol-type-unsupported-ref.html>
+<ol type=circle><li>1<li>2</ol>
+<ol type=CIRCLE><li>1<li>2</ol>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/ol-type-unsupported-disc.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/ol-type-unsupported-disc.html
new file mode 100644
index 0000000000..a0f41f3b1c
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/ol-type-unsupported-disc.html
@@ -0,0 +1,6 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>ol@type: unsupported type: disc</title>
+<link rel=match href=ol-type-unsupported-ref.html>
+<ol type=disc><li>1<li>2</ol>
+<ol type=DISC><li>1<li>2</ol>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/ol-type-unsupported-invalid.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/ol-type-unsupported-invalid.html
new file mode 100644
index 0000000000..6c1198ef50
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/ol-type-unsupported-invalid.html
@@ -0,0 +1,6 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>ol@type: unsupported type: invalid</title>
+<link rel=match href=ol-type-unsupported-ref.html>
+<ol type=disk><li>1<li>2</ol>
+<ol type=DISK><li>1<li>2</ol>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/ol-type-unsupported-lower-alpha.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/ol-type-unsupported-lower-alpha.html
new file mode 100644
index 0000000000..2fd656100f
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/ol-type-unsupported-lower-alpha.html
@@ -0,0 +1,6 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>ol@type: unsupported type: lower-alpha</title>
+<link rel=match href=ol-type-unsupported-ref.html>
+<ol type=lower-alpha><li>1<li>2</ol>
+<ol type=LOWER-ALPHA><li>1<li>2</ol>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/ol-type-unsupported-lower-roman.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/ol-type-unsupported-lower-roman.html
new file mode 100644
index 0000000000..49f5b2888e
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/ol-type-unsupported-lower-roman.html
@@ -0,0 +1,6 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>ol@type: unsupported type: lower-roman</title>
+<link rel=match href=ol-type-unsupported-ref.html>
+<ol type=lower-roman><li>1<li>2</ol>
+<ol type=LOWER-ROMAN><li>1<li>2</ol>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/ol-type-unsupported-none.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/ol-type-unsupported-none.html
new file mode 100644
index 0000000000..bf800e1b11
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/ol-type-unsupported-none.html
@@ -0,0 +1,6 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>ol@type: unsupported type: none</title>
+<link rel=match href=ol-type-unsupported-ref.html>
+<ol type=none><li>1<li>2</ol>
+<ol type=NONE><li>1<li>2</ol>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/ol-type-unsupported-ref.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/ol-type-unsupported-ref.html
new file mode 100644
index 0000000000..530f8ef6c7
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/ol-type-unsupported-ref.html
@@ -0,0 +1,5 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>ol@type: unsupported types</title>
+<ol><li>1<li>2</ol>
+<ol><li>1<li>2</ol>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/ol-type-unsupported-round.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/ol-type-unsupported-round.html
new file mode 100644
index 0000000000..10a573687b
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/ol-type-unsupported-round.html
@@ -0,0 +1,6 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>ol@type: unsupported type: round</title>
+<link rel=match href=ol-type-unsupported-ref.html>
+<ol type=round><li>1<li>2</ol>
+<ol type=ROUND><li>1<li>2</ol>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/ol-type-unsupported-square.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/ol-type-unsupported-square.html
new file mode 100644
index 0000000000..b3e8937fb3
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/ol-type-unsupported-square.html
@@ -0,0 +1,6 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>ol@type: unsupported type: square</title>
+<link rel=match href=ol-type-unsupported-ref.html>
+<ol type=square><li>1<li>2</ol>
+<ol type=SQUARE><li>1<li>2</ol>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/ol-type-unsupported-upper-alpha.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/ol-type-unsupported-upper-alpha.html
new file mode 100644
index 0000000000..6a1ff97dbf
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/ol-type-unsupported-upper-alpha.html
@@ -0,0 +1,6 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>ol@type: unsupported type: upper-latin</title>
+<link rel=match href=ol-type-unsupported-ref.html>
+<ol type=upper-alpha><li>1<li>2</ol>
+<ol type=UPPER-ALPHA><li>1<li>2</ol>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/ol-type-unsupported-upper-roman.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/ol-type-unsupported-upper-roman.html
new file mode 100644
index 0000000000..04cf451c67
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/ol-type-unsupported-upper-roman.html
@@ -0,0 +1,6 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>ol@type: unsupported type: upper-roman</title>
+<link rel=match href=ol-type-unsupported-ref.html>
+<ol type=upper-roman><li>1<li>2</ol>
+<ol type=UPPER-ROMAN><li>1<li>2</ol>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/ul-type-supported-ref.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/ul-type-supported-ref.html
new file mode 100644
index 0000000000..59a0400cc8
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/ul-type-supported-ref.html
@@ -0,0 +1,21 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>ul@type: supported types</title>
+<style>
+.disc {
+ list-style-type: disc;
+}
+.circle {
+ list-style-type: circle;
+}
+.square {
+ list-style-type: square;
+}
+.none {
+ list-style-type: none;
+}
+</style>
+<ul class="disc"><li>first disc</li><li>second disc</li></ul>
+<ul class="circle"><li>first circle</li><li>second circle</li></ul>
+<ul class="square"><li>first square</li><li>second square</li></ul>
+<ul class="none"><li>first none</li><li>second none</li></ul>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/ul-type-supported-xhtml.xhtml b/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/ul-type-supported-xhtml.xhtml
new file mode 100644
index 0000000000..a2e5e0bbf6
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/ul-type-supported-xhtml.xhtml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title>ul@type: supported types</title>
+<link rel="match" href="ul-type-supported-ref.html"/>
+</head>
+<body>
+<ul type="disc"><li>first disc</li><li>second disc</li></ul>
+<ul type="circle"><li>first circle</li><li>second circle</li></ul>
+<ul type="square"><li>first square</li><li>second square</li></ul>
+<ul type="none"><li>first none</li><li>second none</li></ul>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/ul-type-supported.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/ul-type-supported.html
new file mode 100644
index 0000000000..c2449d7acd
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/ul-type-supported.html
@@ -0,0 +1,8 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>ul@type: supported types</title>
+<link rel=match href=ul-type-supported-ref.html>
+<ul type=disc><li>first disc</li><li>second disc</li></ul>
+<ul type=circle><li>first circle</li><li>second circle</li></ul>
+<ul type=square><li>first square</li><li>second square</li></ul>
+<ul type=none><li>first none</li><li>second none</li></ul>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/ul-type-unsupported-decimal.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/ul-type-unsupported-decimal.html
new file mode 100644
index 0000000000..0fb0e14abb
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/ul-type-unsupported-decimal.html
@@ -0,0 +1,7 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>ul@type: unsupported type: decimal</title>
+<link rel=match href=ul-type-unsupported-ref.html>
+<ul type=decimal><li>first item</li><li>second item</li></ul>
+<ul type=DECIMAL><li>first item</li><li>second item</li></ul>
+<ul type=1><li>first item</li><li>second item</li></ul>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/ul-type-unsupported-invalid.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/ul-type-unsupported-invalid.html
new file mode 100644
index 0000000000..c6ee14eac8
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/ul-type-unsupported-invalid.html
@@ -0,0 +1,7 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>ul@type: unsupported type: invalid</title>
+<link rel=match href=ul-type-unsupported-ref.html>
+<ul type=disk><li>first item</li><li>second item</li></ul>
+<ul type=DISK><li>first item</li><li>second item</li></ul>
+<ul type=x><li>first item</li><li>second item</li></ul>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/ul-type-unsupported-lower-alpha.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/ul-type-unsupported-lower-alpha.html
new file mode 100644
index 0000000000..f31cc247ca
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/ul-type-unsupported-lower-alpha.html
@@ -0,0 +1,7 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>ul@type: unsupported type: lower-alpha</title>
+<link rel=match href=ul-type-unsupported-ref.html>
+<ul type=lower-alpha><li>first item</li><li>second item</li></ul>
+<ul type=LOWER-ALPHA><li>first item</li><li>second item</li></ul>
+<ul type=a><li>first item</li><li>second item</li></ul>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/ul-type-unsupported-lower-roman.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/ul-type-unsupported-lower-roman.html
new file mode 100644
index 0000000000..bd86861c9d
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/ul-type-unsupported-lower-roman.html
@@ -0,0 +1,7 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>ul@type: unsupported type: lower-roman</title>
+<link rel=match href=ul-type-unsupported-ref.html>
+<ul type=lower-roman><li>first item</li><li>second item</li></ul>
+<ul type=LOWER-ROMAN><li>first item</li><li>second item</li></ul>
+<ul type=i><li>first item</li><li>second item</li></ul>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/ul-type-unsupported-ref.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/ul-type-unsupported-ref.html
new file mode 100644
index 0000000000..c53fe947f2
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/ul-type-unsupported-ref.html
@@ -0,0 +1,6 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>ul@type: unsupported types</title>
+<ul><li>first item</li><li>second item</li></ul>
+<ul><li>first item</li><li>second item</li></ul>
+<ul><li>first item</li><li>second item</li></ul>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/ul-type-unsupported-upper-alpha.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/ul-type-unsupported-upper-alpha.html
new file mode 100644
index 0000000000..3f880f1dcd
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/ul-type-unsupported-upper-alpha.html
@@ -0,0 +1,7 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>ul@type: unsupported type: upper-alpha</title>
+<link rel=match href=ul-type-unsupported-ref.html>
+<ul type=upper-alpha><li>first item</li><li>second item</li></ul>
+<ul type=UPPER-ALPHA><li>first item</li><li>second item</li></ul>
+<ul type=A><li>first item</li><li>second item</li></ul>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/ul-type-unsupported-upper-roman.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/ul-type-unsupported-upper-roman.html
new file mode 100644
index 0000000000..d7f1295d63
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/lists/ul-type-unsupported-upper-roman.html
@@ -0,0 +1,7 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>ul@type: unsupported type: upper-roman</title>
+<link rel=match href=ul-type-unsupported-ref.html>
+<ul type=upper-roman><li>first item</li><li>second item</li></ul>
+<ul type=UPPER-ROMAN><li>first item</li><li>second item</li></ul>
+<ul type=I><li>first item</li><li>second item</li></ul>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/margin-collapsing-quirks/compare-computed-style.js b/testing/web-platform/tests/html/rendering/non-replaced-elements/margin-collapsing-quirks/compare-computed-style.js
new file mode 100644
index 0000000000..496bae3a10
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/margin-collapsing-quirks/compare-computed-style.js
@@ -0,0 +1,7 @@
+test(function() {
+ var testStyle = getComputedStyle(document.getElementById('test'));
+ var refStyle = getComputedStyle(document.getElementById('ref'));
+ for (var prop in testStyle) {
+ assert_equals(testStyle[prop], refStyle[prop], prop);
+ }
+});
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/margin-collapsing-quirks/multicol-quirks-mode.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/margin-collapsing-quirks/multicol-quirks-mode.html
new file mode 100644
index 0000000000..905d7bc7cb
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/margin-collapsing-quirks/multicol-quirks-mode.html
@@ -0,0 +1,7 @@
+<title>multicol default styles (quirks mode)</title>
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#multicol">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<multicol id=test></multicol>
+<asdfasdf id=ref></asdfasdf>
+<script src="compare-computed-style.js"></script>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/margin-collapsing-quirks/multicol-standards-mode.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/margin-collapsing-quirks/multicol-standards-mode.html
new file mode 100644
index 0000000000..999cf42c76
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/margin-collapsing-quirks/multicol-standards-mode.html
@@ -0,0 +1,8 @@
+<!DOCTYPE html>
+<title>multicol default styles (standards mode)</title>
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#multicol">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<multicol id=test></multicol>
+<asdfasdf id=ref></asdfasdf>
+<script src="compare-computed-style.js"></script>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/phrasing-content-0/br-wbr-content/content-property.tentative.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/phrasing-content-0/br-wbr-content/content-property.tentative.html
new file mode 100644
index 0000000000..d814c0a076
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/phrasing-content-0/br-wbr-content/content-property.tentative.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<link rel=stylesheet href=/fonts/ahem.css>
+<link rel=match href=/css/reference/pass_if_square_96px_black.html>
+<link rel=help href=https://github.com/whatwg/html/issues/2291>
+<link rel=help href=https://drafts.csswg.org/css-content/#content-property>
+<style>
+.test, .ref {
+ font: 16px/1 Ahem;
+ margin: 0;
+}
+.test br {
+ /* This should have no affect. Per css-content, <string> when applied to elements. */
+ content: "";
+}
+</style>
+<p>Test passes if there is a square below.</p>
+<p class=test>xxxxxx<br>xxxxxx<br>xxxxxx</p>
+<p class=ref>xxxxxx<br>xxxxxx<br>xxxxxx</p>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/phrasing-content-0/font-element-text-decoration-color/001-a.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/phrasing-content-0/font-element-text-decoration-color/001-a.html
new file mode 100644
index 0000000000..2ac6f44649
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/phrasing-content-0/font-element-text-decoration-color/001-a.html
@@ -0,0 +1,33 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<link rel=match href=001-ref.html>
+<title>The font element text decoration color quirk, 001, almost standards mode</title>
+<style>[id] > * { color:fuchsia }</style>
+<div>Quirks should not apply:</div>
+<div><u>foo <font style="color:fuchsia">style</font> bar</u></div>
+<div><u>foo <font color="fuchsia">color</font> bar</u></div>
+<div><u>foo <font color="fuchsia" style="color:fuchsia">color and style</font> bar</u></div>
+<div><u>foo <font color="x" style="color:fuchsia">color=x and style</font> bar</u></div>
+<div><u>foo <font color="transparent" style="color:fuchsia">color=transparent and style</font> bar</u></div>
+<div><u>foo <font color="" style="color:fuchsia">color="" and style</font> bar</u></div>
+<div><u>foo <font style="display:block; color:fuchsia">block</font> bar</u></div>
+<div><s>foo <font color="fuchsia">line-through</font> bar</s></div>
+<div><u style="text-decoration:overline">foo <font color="fuchsia">overline</font> bar</u></div>
+<div><u>foo <span style="color:fuchsia">span</span> bar</u></div>
+<div><u id="no-namespace">FAIL (script didn't run)</u></div>
+<script>
+var a = document.getElementById('no-namespace');
+a.textContent = 'foo ';
+var elm = document.createElementNS('', 'font');
+elm.textContent = 'no-namespace font element';
+a.appendChild(elm);
+a.appendChild(document.createTextNode(' bar'));
+</script>
+<div><u id="uppercase">FAIL (script didn't run)</u></div>
+<script>
+var a = document.getElementById('uppercase');
+a.textContent = 'foo ';
+var elm = document.createElementNS('http://www.w3.org/1999/xhtml', 'FONT');
+elm.textContent = 'uppercase FONT element';
+a.appendChild(elm);
+a.appendChild(document.createTextNode(' bar'));
+</script>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/phrasing-content-0/font-element-text-decoration-color/001-q.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/phrasing-content-0/font-element-text-decoration-color/001-q.html
new file mode 100644
index 0000000000..846cb6e8af
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/phrasing-content-0/font-element-text-decoration-color/001-q.html
@@ -0,0 +1,32 @@
+<link rel=match href=001-ref.html>
+<title>The font element text decoration color quirk, 001, quirks mode</title>
+<style>[id] > * { color:fuchsia }</style>
+<div>Quirks should not apply:</div>
+<div><u>foo <font style="color:fuchsia">style</font> bar</u></div>
+<div><u>foo <font color="fuchsia">color</font> bar</u></div>
+<div><u>foo <font color="fuchsia" style="color:fuchsia">color and style</font> bar</u></div>
+<div><u>foo <font color="x" style="color:fuchsia">color=x and style</font> bar</u></div>
+<div><u>foo <font color="transparent" style="color:fuchsia">color=transparent and style</font> bar</u></div>
+<div><u>foo <font color="" style="color:fuchsia">color="" and style</font> bar</u></div>
+<div><u>foo <font style="display:block; color:fuchsia">block</font> bar</u></div>
+<div><s>foo <font color="fuchsia">line-through</font> bar</s></div>
+<div><u style="text-decoration:overline">foo <font color="fuchsia">overline</font> bar</u></div>
+<div><u>foo <span style="color:fuchsia">span</span> bar</u></div>
+<div><u id="no-namespace">FAIL (script didn't run)</u></div>
+<script>
+var a = document.getElementById('no-namespace');
+a.textContent = 'foo ';
+var elm = document.createElementNS('', 'font');
+elm.textContent = 'no-namespace font element';
+a.appendChild(elm);
+a.appendChild(document.createTextNode(' bar'));
+</script>
+<div><u id="uppercase">FAIL (script didn't run)</u></div>
+<script>
+var a = document.getElementById('uppercase');
+a.textContent = 'foo ';
+var elm = document.createElementNS('http://www.w3.org/1999/xhtml', 'FONT');
+elm.textContent = 'uppercase FONT element';
+a.appendChild(elm);
+a.appendChild(document.createTextNode(' bar'));
+</script>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/phrasing-content-0/font-element-text-decoration-color/001-ref.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/phrasing-content-0/font-element-text-decoration-color/001-ref.html
new file mode 100644
index 0000000000..fb632e693d
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/phrasing-content-0/font-element-text-decoration-color/001-ref.html
@@ -0,0 +1,20 @@
+<title>Reference for The font element text decoration color quirk, 001</title>
+<style>
+span, div > div { color:fuchsia }
+.under { text-decoration:underline }
+.over { text-decoration:overline }
+.strike { text-decoration:line-through }
+</style>
+<div>Quirks should not apply:</div>
+<div class="under">foo <span>style</span> bar</div>
+<div class="under">foo <span>color</span> bar</div>
+<div class="under">foo <span>color and style</span> bar</div>
+<div class="under">foo <span>color=x and style</span> bar</div>
+<div class="under">foo <span>color=transparent and style</span> bar</div>
+<div class="under">foo <span>color="" and style</span> bar</div>
+<div class="under">foo<div>block</div>bar</div>
+<div class="strike">foo <span>line-through</span> bar</div>
+<div class="over">foo <span>overline</span> bar</div>
+<div class="under">foo <span>span</span> bar</div>
+<div class="under">foo <span>no-namespace font element</span> bar</div>
+<div class="under">foo <span>uppercase FONT element</span> bar</div>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/phrasing-content-0/font-element-text-decoration-color/001-s.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/phrasing-content-0/font-element-text-decoration-color/001-s.html
new file mode 100644
index 0000000000..d781fab289
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/phrasing-content-0/font-element-text-decoration-color/001-s.html
@@ -0,0 +1,33 @@
+<!doctype html>
+<link rel=match href=001-ref.html>
+<title>The font element text decoration color quirk, 001, standards mode</title>
+<style>[id] > * { color:fuchsia }</style>
+<div>Quirks should not apply:</div>
+<div><u>foo <font style="color:fuchsia">style</font> bar</u></div>
+<div><u>foo <font color="fuchsia">color</font> bar</u></div>
+<div><u>foo <font color="fuchsia" style="color:fuchsia">color and style</font> bar</u></div>
+<div><u>foo <font color="x" style="color:fuchsia">color=x and style</font> bar</u></div>
+<div><u>foo <font color="transparent" style="color:fuchsia">color=transparent and style</font> bar</u></div>
+<div><u>foo <font color="" style="color:fuchsia">color="" and style</font> bar</u></div>
+<div><u>foo <font style="display:block; color:fuchsia">block</font> bar</u></div>
+<div><s>foo <font color="fuchsia">line-through</font> bar</s></div>
+<div><u style="text-decoration:overline">foo <font color="fuchsia">overline</font> bar</u></div>
+<div><u>foo <span style="color:fuchsia">span</span> bar</u></div>
+<div><u id="no-namespace">FAIL (script didn't run)</u></div>
+<script>
+var a = document.getElementById('no-namespace');
+a.textContent = 'foo ';
+var elm = document.createElementNS('', 'font');
+elm.textContent = 'no-namespace font element';
+a.appendChild(elm);
+a.appendChild(document.createTextNode(' bar'));
+</script>
+<div><u id="uppercase">FAIL (script didn't run)</u></div>
+<script>
+var a = document.getElementById('uppercase');
+a.textContent = 'foo ';
+var elm = document.createElementNS('http://www.w3.org/1999/xhtml', 'FONT');
+elm.textContent = 'uppercase FONT element';
+a.appendChild(elm);
+a.appendChild(document.createTextNode(' bar'));
+</script>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/phrasing-content-0/font-element-text-decoration-color/001-x.xhtml b/testing/web-platform/tests/html/rendering/non-replaced-elements/phrasing-content-0/font-element-text-decoration-color/001-x.xhtml
new file mode 100644
index 0000000000..623b346eea
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/phrasing-content-0/font-element-text-decoration-color/001-x.xhtml
@@ -0,0 +1,22 @@
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<link rel="match" href="001-ref.html"/>
+<title>The font element text decoration color quirk, 001, XHTML</title>
+<style>[id] > * { color:fuchsia }</style>
+</head>
+<body>
+<div>Quirks should not apply:</div>
+<div><u>foo <font style="color:fuchsia">style</font> bar</u></div>
+<div><u>foo <font color="fuchsia">color</font> bar</u></div>
+<div><u>foo <font color="fuchsia" style="color:fuchsia">color and style</font> bar</u></div>
+<div><u>foo <font color="x" style="color:fuchsia">color=x and style</font> bar</u></div>
+<div><u>foo <font color="transparent" style="color:fuchsia">color=transparent and style</font> bar</u></div>
+<div><u>foo <font color="" style="color:fuchsia">color="" and style</font> bar</u></div>
+<div><u>foo <font style="display:block; color:fuchsia">block</font> bar</u></div>
+<div><s>foo <font color="fuchsia">line-through</font> bar</s></div>
+<div><u style="text-decoration:overline">foo <font color="fuchsia">overline</font> bar</u></div>
+<div><u>foo <span style="color:fuchsia">span</span> bar</u></div>
+<div><u id="no-namespace">foo <font xmlns="">no-namespace font element</font> bar</u></div>
+<div><u id="uppercase">foo <FONT>uppercase FONT element</FONT> bar</u></div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/phrasing-content-0/font-element-text-decoration-color/font-face.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/phrasing-content-0/font-element-text-decoration-color/font-face.html
new file mode 100644
index 0000000000..a37da3c45f
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/phrasing-content-0/font-element-text-decoration-color/font-face.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>font face</title>
+<link rel="help" href="https://html.spec.whatwg.org/#the-font-element-text-decoration-color-quirk">
+<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>
+
+const types = ["serif", "sans-serif", "cursive", "fantasy", "monospace"];
+for (let type of types) {
+ test(() => {
+ let elem = document.createElement("font");
+ elem.setAttribute("face", type);
+ document.body.appendChild(elem);
+ let exp_type = window.getComputedStyle(elem, null).getPropertyValue("font-family");
+ assert_equals(exp_type, type);
+ }, `font face attribute ${type} is correct`);
+}
+
+</script>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/phrasing-content-0/font-element-text-decoration-color/font-size.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/phrasing-content-0/font-element-text-decoration-color/font-size.html
new file mode 100644
index 0000000000..8e8b9f28eb
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/phrasing-content-0/font-element-text-decoration-color/font-size.html
@@ -0,0 +1,103 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>font size</title>
+<link rel="help" href="https://html.spec.whatwg.org/#the-font-element-text-decoration-color-quirk">
+<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>
+
+const modes = ["", "+", "-"];
+const values = ["0", "1", "2", "3", "4", "5", "6", "7", "8"];
+const rels = [
+ ["1", "x-small"],
+ ["2", "small"],
+ ["3", "medium"],
+ ["4", "large"],
+ ["5", "x-large"],
+ ["6", "xx-large"],
+ ["7", "xxx-large"]
+];
+let results = getCSSFontSize(rels);
+
+function cal(n) {
+ //If value is greater than 7, let it be 7
+ //If value is less than 1, let it be 1
+ return n > 7 ? 7 : (n < 1 ? 1 : n);
+}
+
+function getRealInput(mode, value) {
+ switch(mode) {
+ case "+":
+ //If mode is relative-plus, then increment value by 3
+ return cal(3 + parseInt(value));
+ case "-":
+ // If mode is relative-minus, then let value be the result of subtracting value from 3
+ return cal(3 - parseInt(value));
+ default:
+ return cal(parseInt(value));
+ }
+}
+
+function getCSSFontSize(rels) {
+ let results = {};
+ for (let [key, value] of rels) {
+ if (key == "7") {
+ //The 'xxx-large' value is a non-CSS value used here to indicate a font size 50% larger than 'xx-large'.
+ let size = parseInt(results["6"]) * 1.5;
+ results[key] = size.toString();
+ return results;
+ }
+ let elem = document.createElement("span");
+ document.body.appendChild(elem);
+ elem.setAttribute("style", `font-size: ${value}`);
+ let exp_size = window.getComputedStyle(elem, null).getPropertyValue("font-size");
+ results[key] = exp_size.slice(0, -2);
+ }
+ return results;
+}
+
+for (let mode of modes) {
+ for (let value of values) {
+ test(() => {
+ let size = getRealInput(mode, value);
+ let elem = document.createElement("font");
+ elem.setAttribute("size", `${mode}${value}`);
+ document.body.appendChild(elem);
+ let exp_size = window.getComputedStyle(elem, null).getPropertyValue("font-size");
+ assert_equals(exp_size.slice(0, -2), results[size]);
+ }, `font size attribute ${mode}${value} is correct`);
+ }
+}
+
+test(() => {
+ let span_elem = document.createElement("span");
+ document.body.appendChild(span_elem);
+ span_elem.setAttribute("style", "font-size: medium");
+ let span_size = window.getComputedStyle(span_elem, null).getPropertyValue("font-size");
+
+ let font_elem = document.createElement("font");
+ document.body.appendChild(font_elem);
+ let font_size = window.getComputedStyle(font_elem, null).getPropertyValue("font-size");
+ assert_equals(font_size, span_size);
+
+ font_elem.setAttribute("size", "");
+ font_size = window.getComputedStyle(font_elem, null).getPropertyValue("font-size");
+ assert_equals(font_size, span_size);
+
+ font_elem.setAttribute("size", " ");
+ font_size = window.getComputedStyle(font_elem, null).getPropertyValue("font-size");
+ assert_equals(font_size, span_size);
+
+ font_elem.setAttribute("size", " 3");
+ font_size = window.getComputedStyle(font_elem, null).getPropertyValue("font-size");
+ assert_equals(font_size, span_size);
+
+ font_elem.setAttribute("size", "3");
+ font_size = window.getComputedStyle(font_elem, null).getPropertyValue("font-size");
+ assert_equals(font_size, span_size);
+}, "font size default value is 3");
+
+</script>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/sections-and-headings/headings-styles.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/sections-and-headings/headings-styles.html
new file mode 100644
index 0000000000..63e6a83e88
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/sections-and-headings/headings-styles.html
@@ -0,0 +1,152 @@
+<!doctype html>
+<title>default styles for h1..h6, hgroup, article, aside, nav, section</title>
+<meta name="viewport" content="width=device-width">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/rendering/support/test-ua-stylesheet.js"></script>
+<style>
+/* Specify this bogus namespace, so the rules in this stylesheet only apply to the `fakeClone`d elements in #refs, not the HTML elements in #tests. */
+@namespace url(urn:not-html);
+
+article, aside, h1, h2, h3, h4, h5, h6, hgroup, nav, section {
+ display: block;
+}
+
+h1 { margin-block-start: 0.67em; margin-block-end: 0.67em; font-size: 2.00em; font-weight: bold; }
+h2 { margin-block-start: 0.83em; margin-block-end: 0.83em; font-size: 1.50em; font-weight: bold; }
+h3 { margin-block-start: 1.00em; margin-block-end: 1.00em; font-size: 1.17em; font-weight: bold; }
+h4 { margin-block-start: 1.33em; margin-block-end: 1.33em; font-size: 1.00em; font-weight: bold; }
+h5 { margin-block-start: 1.67em; margin-block-end: 1.67em; font-size: 0.83em; font-weight: bold; }
+h6 { margin-block-start: 2.33em; margin-block-end: 2.33em; font-size: 0.67em; font-weight: bold; }
+
+:is(article, aside, nav, section) h1 { margin-block-start: 0.83em; margin-block-end: 0.83em; font-size: 1.50em; }
+:is(article, aside, nav, section) :is(article, aside, nav, section) h1 { margin-block-start: 1.00em; margin-block-end: 1.00em; font-size: 1.17em; }
+:is(article, aside, nav, section) :is(article, aside, nav, section) :is(article, aside, nav, section) h1 { margin-block-start: 1.33em; margin-block-end: 1.33em; font-size: 1.00em; }
+:is(article, aside, nav, section) :is(article, aside, nav, section) :is(article, aside, nav, section) :is(article, aside, nav, section) h1 { margin-block-start: 1.67em; margin-block-end: 1.67em; font-size: 0.83em; }
+:is(article, aside, nav, section) :is(article, aside, nav, section) :is(article, aside, nav, section) :is(article, aside, nav, section) :is(article, aside, nav, section) h1 { margin-block-start: 2.33em; margin-block-end: 2.33em; font-size: 0.67em; }
+
+</style>
+
+<div id="log"></div>
+
+<div id="tests">
+ <h1></h1>
+ <h2></h2>
+ <h3></h3>
+ <h4></h4>
+ <h5></h5>
+ <h6></h6>
+ <hgroup></hgroup>
+ <article></article>
+ <aside></aside>
+ <nav></nav>
+ <section></section>
+ <article data-skip>
+ <h1></h1>
+ <article data-skip>
+ <h1></h1>
+ <article data-skip>
+ <h1></h1>
+ <article data-skip>
+ <h1></h1>
+ <article data-skip>
+ <h1></h1>
+ <hgroup data-skip>
+ <h1></h1>
+ <h2></h2>
+ <h3></h3>
+ <h4></h4>
+ <h5></h5>
+ </hgroup>
+ </article>
+ </article>
+ </article>
+ </article>
+ </article>
+ <aside data-skip>
+ <h1></h1>
+ <aside data-skip>
+ <h1></h1>
+ <aside data-skip>
+ <h1></h1>
+ <aside data-skip>
+ <h1></h1>
+ <aside data-skip>
+ <h1></h1>
+ <hgroup data-skip>
+ <h1></h1>
+ <h2></h2>
+ <h3></h3>
+ <h4></h4>
+ <h5></h5>
+ </hgroup>
+ </aside>
+ </aside>
+ </aside>
+ </aside>
+ </aside>
+ <nav data-skip>
+ <h1></h1>
+ <nav data-skip>
+ <h1></h1>
+ <nav data-skip>
+ <h1></h1>
+ <nav data-skip>
+ <h1></h1>
+ <nav data-skip>
+ <h1></h1>
+ <hgroup data-skip>
+ <h1></h1>
+ <h2></h2>
+ <h3></h3>
+ <h4></h4>
+ <h5></h5>
+ </hgroup>
+ </nav>
+ </nav>
+ </nav>
+ </nav>
+ </nav>
+ <section data-skip>
+ <h1></h1>
+ <section data-skip>
+ <h1></h1>
+ <section data-skip>
+ <h1></h1>
+ <section data-skip>
+ <h1></h1>
+ <section data-skip>
+ <h1></h1>
+ <hgroup data-skip>
+ <h1></h1>
+ <h2></h2>
+ <h3></h3>
+ <h4></h4>
+ <h5></h5>
+ </hgroup>
+ </section>
+ </section>
+ </section>
+ </section>
+ </section>
+</div>
+
+<div id="refs"></div>
+
+<script>
+ const props = [
+ 'display',
+ 'margin-top',
+ 'margin-right',
+ 'margin-bottom',
+ 'margin-left',
+ 'padding-top',
+ 'padding-right',
+ 'padding-bottom',
+ 'padding-left',
+ 'font-size',
+ 'font-weight',
+ ];
+ runUAStyleTests(props);
+
+</script>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/colgroup_valign-ref.xhtml b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/colgroup_valign-ref.xhtml
new file mode 100644
index 0000000000..7d21ce1180
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/colgroup_valign-ref.xhtml
Binary files differ
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/colgroup_valign_bottom.xhtml b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/colgroup_valign_bottom.xhtml
new file mode 100644
index 0000000000..8610f37938
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/colgroup_valign_bottom.xhtml
Binary files differ
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/colgroup_valign_top.xhtml b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/colgroup_valign_top.xhtml
new file mode 100644
index 0000000000..3f02219973
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/colgroup_valign_top.xhtml
Binary files differ
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/form-in-tables-xhtml.xhtml b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/form-in-tables-xhtml.xhtml
new file mode 100644
index 0000000000..6af44139a0
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/form-in-tables-xhtml.xhtml
@@ -0,0 +1,23 @@
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <title>UA style for form in table elements - XHTML</title>
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/rendering.html#tables-2" />
+ <link rel="author" title="Rune Lillesveen" href="mailto:futhark@chromium.org" />
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+ <body>
+ <table><form></form></table>
+ <table><thead><form></form></thead></table>
+ <table><tbody><form></form></tbody></table>
+ <table><tfoot><form></form></tfoot></table>
+ <table><tr><form></form></tr></table>
+ <script>
+ for (const form of document.querySelectorAll("form")) {
+ test(function() {
+ assert_equals(getComputedStyle(form).display, "block");
+ }, `Computed display of form inside ${form.parentNode.nodeName} in xhtml should be 'block'`);
+ }
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/form-in-tables.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/form-in-tables.html
new file mode 100644
index 0000000000..611c8305b9
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/form-in-tables.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<title>UA style for form in table elements</title>
+<link rel="help" href="https://html.spec.whatwg.org/multipage/rendering.html#tables-2">
+<link rel="author" title="Rune Lillesveen" href="mailto:futhark@chromium.org">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<style>
+ .block { display: block !important }
+</style>
+<div id="display">
+ <table><form></form></table>
+ <table><thead><form></form></thead></table>
+ <table><tbody><form></form></tbody></table>
+ <table><tfoot><form></form></tfoot></table>
+ <table><tr><form></form></tr></table>
+</div>
+<div id="important">
+ <table><form class="block"></form></table>
+ <table><thead><form class="block"></form></thead></table>
+ <table><tbody><form class="block"></form></tbody></table>
+ <table><tfoot><form class="block"></form></tfoot></table>
+ <table><tr><form class="block"></form></tr></table>
+</div>
+<script>
+ for (const form of display.querySelectorAll("form")) {
+ test(function() {
+ assert_equals(getComputedStyle(form).display, "none");
+ }, `Computed display of form inside ${form.parentNode.nodeName} should be 'none'`);
+ }
+ for (const form of important.querySelectorAll("form")) {
+ test(function() {
+ assert_equals(getComputedStyle(form).display, "none");
+ }, `Computed display of form inside ${form.parentNode.nodeName} should be 'none' (!important UA style))`);
+ }
+</script>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/hidden-attr.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/hidden-attr.html
new file mode 100644
index 0000000000..f06c3dc9b4
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/hidden-attr.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<title>UA style for hidden attribute on table elements</title>
+<link rel="help" href="https://html.spec.whatwg.org/multipage/rendering.html#tables-2">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<table hidden></table>
+<table><caption hidden></caption></table>
+<table><colgroup hidden></table>
+<table><col hidden></table>
+<table><thead hidden></table>
+<table><tbody hidden></table>
+<table><tfoot hidden></table>
+<table><tr hidden></table>
+<table><tr><td hidden></table>
+<table><tr><th hidden></table>
+<script>
+const expectedDisplay = {
+ 'table': 'none',
+ 'caption': 'none',
+ 'colgroup': 'table-column-group',
+ 'col': 'table-column',
+ 'thead': 'table-header-group',
+ 'tbody': 'table-row-group',
+ 'tfoot': 'table-footer-group',
+ 'tr': 'table-row',
+ 'td': 'none',
+ 'th': 'none',
+};
+for (const el of document.querySelectorAll("[hidden]")) {
+ test(function() {
+ const style = getComputedStyle(el);
+ assert_equals(style.display, expectedDisplay[el.localName]);
+ if (el instanceof HTMLTableElement ||
+ el instanceof HTMLTableCaptionElement ||
+ el instanceof HTMLTableCellElement) {
+ assert_equals(style.visibility, 'visible');
+ } else {
+ assert_equals(style.visibility, 'collapse');
+ }
+ }, `Computed display and visibility of ${el.localName}`);
+}
+</script>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/resources/aqua-yellow-32x32.png b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/resources/aqua-yellow-32x32.png
new file mode 100644
index 0000000000..42f8a2100b
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/resources/aqua-yellow-32x32.png
Binary files differ
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/resources/blue-16x20-green-16x20.png b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/resources/blue-16x20-green-16x20.png
new file mode 100644
index 0000000000..9bf59ebdf1
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/resources/blue-16x20-green-16x20.png
Binary files differ
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/resources/fuchsia-32x32.png b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/resources/fuchsia-32x32.png
new file mode 100644
index 0000000000..7902bc31e0
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/resources/fuchsia-32x32.png
Binary files differ
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/resources/red-32x32.png b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/resources/red-32x32.png
new file mode 100644
index 0000000000..191e13ea11
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/resources/red-32x32.png
Binary files differ
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/resources/yellow-32x32.png b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/resources/yellow-32x32.png
new file mode 100644
index 0000000000..a45f8111b4
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/resources/yellow-32x32.png
Binary files differ
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-attribute.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-attribute.html
new file mode 100644
index 0000000000..54acff0350
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-attribute.html
@@ -0,0 +1,194 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Table attribute test</title>
+<link rel="help" href="https://html.spec.whatwg.org/multipage/rendering.html#tables-2">
+<link rel="author" title="Intel" href="http://www.intel.com">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<style>
+ .div_tbl table {
+ width: 400px;
+ height: 300px;
+ border-spacing: 0px;
+ }
+ .div_tbl td {
+ padding: 0px;
+ }
+ .div_tbl th {
+ padding: 0px;
+ }
+ .div_200 {
+ height: 200px;
+ }
+</style>
+
+<div id="div">
+ <table id="table">
+ <thead id="thead">
+ <tr>
+ <th id="th">Month</th>
+ <th>Savings</th>
+ </tr>
+ </thead>
+ <tbody id="tbody">
+ <tr id="tr">
+ <td>January</td>
+ <td>$60</td>
+ </tr>
+ <tr>
+ <td id="td">February</td>
+ <td>$80</td>
+ </tr>
+ </tbody>
+ <tfoot id="tfoot">
+ <tr>
+ <td>Sum</td>
+ <td>$140</td>
+ </tr>
+ </tfoot>
+ </table>
+</div>
+
+<script>
+
+const ids = ["table", "thead", "tbody", "tfoot", "tr", "td", "th"];
+const alignIds = ["thead", "tbody", "tfoot", "tr", "td", "th"];
+const heightIds = ["tr", "td", "th"];
+const div = document.getElementById("div");
+const table = document.getElementById("table");
+const aligns = [
+ ["center", "center"],
+ ["middle", "center"],
+ ["left", "left"],
+ ["right", "right"],
+ ["justify", "justify"]
+];
+
+function commonTest(id, attr, value, cssProp, expected) {
+ test(t => {
+ let elem = document.getElementById(id);
+ t.add_cleanup(() => {
+ elem.removeAttribute(attr);
+ });
+ elem.setAttribute(attr, value);
+ let css = window.getComputedStyle(elem, null).getPropertyValue(cssProp);
+ assert_equals(css, expected);
+ }, `${id} ${attr} attribute is correct`);
+}
+
+function commonAlignTest(id, attr, value, cssProp, expected) {
+ test(t => {
+ let elem = document.getElementById(id);
+ t.add_cleanup(() => {
+ elem.removeAttribute(attr);
+ });
+ elem.setAttribute(attr, value);
+ let css = window.getComputedStyle(elem, null).getPropertyValue(cssProp);
+ assert_equals(css, expected);
+ }, `table ${id} align attribute ${value} is correct`);
+}
+
+function commonHeightTest(id, attr, value, cssProp, expected, type="", divClass) {
+ test(t => {
+ let elem = document.getElementById(id);
+ t.add_cleanup(() => {
+ elem.removeAttribute(attr);
+ div.classList.remove(divClass);
+ });
+ elem.setAttribute(attr, value);
+ div.classList.add(divClass);
+ let css = window.getComputedStyle(elem, null).getPropertyValue(cssProp);
+ assert_equals(css, expected);
+ }, `${id} ${attr} attribute ${type} is correct`);
+}
+
+// table#bordercolor
+commonTest("table", "bordercolor", "red", "border-color", "rgb(255, 0, 0)");
+// table#cellspacing
+commonTest("table", "cellspacing", "10", "border-spacing", "10px 10px", "10");
+
+// {table, thead, body, tfoot, tr, td, th}#background
+// {table, thead, body, tfoot, tr, td, th}#bgcolor
+const url = new URL('/images/threecolors.png', window.location.href).href;
+for (let id of ids) {
+ commonTest(id, "background", "/images/threecolors.png", "background-image", `url(\"${url}\")`);
+
+ commonTest(id, "bgcolor", "red", "background-color", "rgb(255, 0, 0)");
+}
+
+// {thead, body, tfoot, tr, td, th}#align#{center, middle, left, right, justify}
+for (let id of alignIds) {
+ for (let [value, expected] of aligns) {
+ commonAlignTest(id, "align", value, "text-align", expected);
+ }
+}
+
+// {tr, td, th}#height#pixel
+for (let id of heightIds) {
+ commonHeightTest(id, "height", "60", "height", "60px", "pixel", "div_tbl");
+}
+
+// {tr, td, th}#height#percentage
+let tbl = document.createElement("table");
+tbl.innerHTML = '<tr id="table_tr"><th id="table_th"></th></tr><tr><td id="table_td"></td></tr>';
+div.appendChild(tbl);
+const heightPercIds = ["table_tr", "table_td", "table_th"];
+for (let id of heightPercIds) {
+ commonHeightTest(id, "height", "20%", "height", "60px", "percentage", "div_tbl");
+}
+div.removeChild(tbl);
+
+// table#height#{pixel, percentage}
+commonHeightTest("table", "height", "180", "height", "180px", "pixel", "div_200");
+commonHeightTest("table", "height", "90%", "height", "180px", "90%", "div_200");
+commonHeightTest("table", "height", "110%", "height", "220px", "110%", "div_200");
+
+// table#cellpadding
+test(t => {
+ t.add_cleanup(() => {
+ table.removeAttribute("cellpadding");
+ });
+ table.setAttribute("cellpadding", "10");
+
+ let th = document.getElementById("th");
+ let th_css = window.getComputedStyle(th, null).getPropertyValue("padding");
+ assert_equals(th_css, "10px");
+
+ let td = document.getElementById("td");
+ let td_css = window.getComputedStyle(td, null).getPropertyValue("padding");
+ assert_equals(td_css, "10px");
+}, "table cellpadding attribute is correct");
+
+// th default text-align property is center
+test(t => {
+ let elem = document.getElementById("th");
+ let css = window.getComputedStyle(elem, null).getPropertyValue("text-align");
+ assert_equals(css, "center");
+}, "th default align attribute is center");
+
+// col#width#{pixel, percentage}
+test(t => {
+ let colgroup = document.createElement("colgroup");
+ let col1 = document.createElement("col");
+ let col2 = document.createElement("col");
+ t.add_cleanup(() => {
+ table.removeChild(colgroup);
+ div.classList.remove("div_tbl");
+ });
+ colgroup.appendChild(col1);
+ colgroup.appendChild(col2);
+ table.insertBefore(colgroup, table.firstChild);
+ div.classList.add("div_tbl");
+
+ col1.setAttribute("width", "100");
+ let td = document.getElementById("td");
+ let css = window.getComputedStyle(td, null).getPropertyValue("width");
+ assert_equals(css, "100px");
+
+ col1.setAttribute("width", "50%");
+ css = window.getComputedStyle(td, null).getPropertyValue("width");
+ assert_equals(css, "200px");
+}, "table col width attribute is correct");
+
+</script>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-background-print-ref.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-background-print-ref.html
new file mode 100644
index 0000000000..3aa0abd320
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-background-print-ref.html
@@ -0,0 +1,42 @@
+<!DOCTYPE HTML>
+<html>
+<body>
+<table style="background-image: url('resources/aqua-yellow-32x32.png')">
+ <thead style="background-image: url('resources/blue-16x20-green-16x20.png')">
+ <tr>
+ <td>
+ Foo
+ </td>
+ <td style="background-image: url('resources/yellow-32x32.png')">
+ Bar
+ </td>
+ </tr>
+ </thead>
+ <tbody style="background-image: url('resources/red-32x32.png')">
+ <tr>
+ <th style="background-image: url('resources/fuchsia-32x32.png')">
+ Foo
+ </th>
+ <th>
+ Bar
+ </th>
+ </tr>
+ <tr style="background-image: url('resources/fuchsia-32x32.png')">
+ <td>
+ Foo
+ </td>
+ <td style="background-image: url('resources/yellow-32x32.png')">
+ Bar
+ </td>
+ </tr>
+ </tbody>
+ <tfoot style="background-image: url('resources/yellow-32x32.png')">
+ <tr>
+ <td>
+ Baz
+ </td>
+ </tr>
+ </tfoot>
+</table>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-background-print.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-background-print.html
new file mode 100644
index 0000000000..0cbaca6019
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-background-print.html
@@ -0,0 +1,46 @@
+<!DOCTYPE HTML>
+<html>
+<link rel="match" href="table-background-print-ref.html">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/rendering.html#tables-2">
+<link rel="help" href="https://drafts.csswg.org/css-break/">
+<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=816498">
+<body>
+<table background="resources/aqua-yellow-32x32.png">
+ <thead background="resources/blue-16x20-green-16x20.png">
+ <tr>
+ <td>
+ Foo
+ </td>
+ <td background="resources/yellow-32x32.png">
+ Bar
+ </td>
+ </tr>
+ </thead>
+ <tbody background="resources/red-32x32.png">
+ <tr>
+ <th background="resources/fuchsia-32x32.png">
+ Foo
+ </th>
+ <th>
+ Bar
+ </th>
+ </tr>
+ <tr background="resources/fuchsia-32x32.png">
+ <td>
+ Foo
+ </td>
+ <td background="resources/yellow-32x32.png">
+ Bar
+ </td>
+ </tr>
+ </tbody>
+ <tfoot background="resources/yellow-32x32.png">
+ <tr>
+ <td>
+ Baz
+ </td>
+ </tr>
+ </tfoot>
+</table>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-border-1-ref.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-border-1-ref.html
new file mode 100644
index 0000000000..ceac88e9a3
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-border-1-ref.html
@@ -0,0 +1,46 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Table borders</title>
+<style>
+table {
+ border-width: 1px;
+ border-style: outset;
+}
+td {
+ border-width: 1px;
+ border-style: inset;
+}
+</style>
+<table>
+<tr><td>Test
+</table>
+<table>
+<tr><td>Test
+</table>
+<table>
+<tr><td>Test
+</table>
+<table>
+<tr><td>Test
+</table>
+<table>
+<tr><td>Test
+</table>
+<table>
+<tr><td>Test
+</table>
+<table>
+<tr><td>Test
+</table>
+<table>
+<tr><td>Test
+</table>
+<table>
+<tr><td>Test
+</table>
+<table>
+<tr><td>Test
+</table>
+<table>
+<tr><td>Test
+</table>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-border-1.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-border-1.html
new file mode 100644
index 0000000000..3338813995
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-border-1.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<link rel="match" href="table-border-1-ref.html">
+<title>Table borders</title>
+<table border>
+<tr><td>Test
+</table>
+<table border="">
+<tr><td>Test
+</table>
+<table border=null>
+<tr><td>Test
+</table>
+<table border=undefined>
+<tr><td>Test
+</table>
+<table border=foo>
+<tr><td>Test
+</table>
+<table border=1>
+<tr><td>Test
+</table>
+<table border=1foo>
+<tr><td>Test
+</table>
+<table border=1%>
+<tr><td>Test
+</table>
+<table border=-1>
+<tr><td>Test
+</table>
+<table border=-1foo>
+<tr><td>Test
+</table>
+<table border=-1%>
+<tr><td>Test
+</table>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-border-2-notref.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-border-2-notref.html
new file mode 100644
index 0000000000..7558e5271a
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-border-2-notref.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Table borders</title>
+<style>
+table {
+ border-width: 1px;
+ border-style: outset;
+}
+td {
+ border-width: 1px;
+ border-style: inset;
+}
+</style>
+<table>
+<tr><td>Test
+</table>
+<table>
+<tr><td>Test
+</table>
+<table>
+<tr><td>Test
+</table>
+<table>
+<tr><td>Test
+</table>
+<table>
+<tr><td>Test
+</table>
+<table>
+<tr><td>Test
+</table>
+<table>
+<tr><td>Test
+</table>
+<table>
+<tr><td>Test
+</table>
+<table>
+<tr><td>Test
+</table>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-border-2-ref.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-border-2-ref.html
new file mode 100644
index 0000000000..36d1e45106
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-border-2-ref.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Table borders</title>
+<table>
+<tr><td>Test
+</table>
+<table>
+<tr><td>Test
+</table>
+<table>
+<tr><td>Test
+</table>
+<table>
+<tr><td>Test
+</table>
+<table>
+<tr><td>Test
+</table>
+<table>
+<tr><td>Test
+</table>
+<table>
+<tr><td>Test
+</table>
+<table>
+<tr><td>Test
+</table>
+<table>
+<tr><td>Test
+</table>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-border-2.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-border-2.html
new file mode 100644
index 0000000000..6f4f39b113
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-border-2.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<link rel="match" href="table-border-2-ref.html">
+<title>Table borders</title>
+<table border=0>
+<tr><td>Test
+</table>
+<table border=0foo>
+<tr><td>Test
+</table>
+<table border=0%>
+<tr><td>Test
+</table>
+<table border=+0>
+<tr><td>Test
+</table>
+<table border=+0foo>
+<tr><td>Test
+</table>
+<table border=+0%>
+<tr><td>Test
+</table>
+<table border=-0>
+<tr><td>Test
+</table>
+<table border=-0foo>
+<tr><td>Test
+</table>
+<table border=-0%>
+<tr><td>Test
+</table>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-border-3-ref.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-border-3-ref.html
new file mode 100644
index 0000000000..e465fd433c
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-border-3-ref.html
@@ -0,0 +1,91 @@
+<!DOCTYPE html>
+<head>
+ <title>Reference for default 'border-color' on table (with 'color' set)</title>
+ <meta charset="utf-8">
+ <link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com">
+ <style>
+ * {
+ border-color: teal;
+ /* This only affects the elements that we specify 'border-style' on: */
+ border-width: 6px;
+ }
+
+ table {
+ height: 30px;
+ width: 30px;
+ border-spacing: 0;
+
+ /* To test in "rows": */
+ float: left;
+ margin: 1px;
+ }
+ br {
+ clear: both;
+ }
+
+ .dotted {
+ border-style: dotted;
+ }
+ .dashed {
+ border-style: dashed;
+ }
+ .solid {
+ border-style: solid;
+ }
+ .double {
+ border-style: double;
+ }
+ .groove {
+ border-style: groove;
+ }
+ .ridge {
+ border-style: ridge;
+ }
+ .inset {
+ border-style: inset;
+ }
+ .outset {
+ border-style: outset;
+ }
+ </style>
+</head>
+
+<table class="dotted"><td></td></table>
+<table><th class="dotted"></th></table>
+<table><td class="dotted"></td></table>
+<br>
+
+<table class="dashed"><td></td></table>
+<table><th class="dashed"></th></table>
+<table><td class="dashed"></td></table>
+<br>
+
+<table class="solid"><td></td></table>
+<table><th class="solid"></th></table>
+<table><td class="solid"></td></table>
+<br>
+
+<table class="double"><td></td></table>
+<table><th class="double"></th></table>
+<table><td class="double"></td></table>
+<br>
+
+<table class="groove"><td></td></table>
+<table><th class="groove"></th></table>
+<table><td class="groove"></td></table>
+<br>
+
+<table class="ridge"><td></td></table>
+<table><th class="ridge"></th></table>
+<table><td class="ridge"></td></table>
+<br>
+
+<table class="inset"><td></td></table>
+<table><th class="inset"></th></table>
+<table><td class="inset"></td></table>
+<br>
+
+<table class="outset"><td></td></table>
+<table><th class="outset"></th></table>
+<table><td class="outset"></td></table>
+<br>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-border-3q.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-border-3q.html
new file mode 100644
index 0000000000..4b481194dc
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-border-3q.html
@@ -0,0 +1,95 @@
+<!-- Intentionally omitting doctype, to test quirks mode. -->
+<head>
+ <title>Testing default 'border-color' on table (with 'color' set), in quirks mode</title>
+ <meta charset="utf-8">
+ <link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com">
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/rendering.html#tables-2">
+ <link rel="match" href="table-border-3-ref.html">
+ <style>
+ * {
+ /* This sets the used value of 'currentColor', which is what should be
+ used for all border-coloring in this test: */
+ color: teal;
+ /* This only affects the elements that we specify 'border-style' on: */
+ border-width: 6px;
+ }
+
+ table {
+ height: 30px;
+ width: 30px;
+ border-spacing: 0;
+
+ /* To test in "rows": */
+ float: left;
+ margin: 1px;
+ }
+ br {
+ clear: both;
+ }
+
+ .dotted {
+ border-style: dotted;
+ }
+ .dashed {
+ border-style: dashed;
+ }
+ .solid {
+ border-style: solid;
+ }
+ .double {
+ border-style: double;
+ }
+ .groove {
+ border-style: groove;
+ }
+ .ridge {
+ border-style: ridge;
+ }
+ .inset {
+ border-style: inset;
+ }
+ .outset {
+ border-style: outset;
+ }
+ </style>
+</head>
+
+<table class="dotted"><td></td></table>
+<table><th class="dotted"></th></table>
+<table><td class="dotted"></td></table>
+<br>
+
+<table class="dashed"><td></td></table>
+<table><th class="dashed"></th></table>
+<table><td class="dashed"></td></table>
+<br>
+
+<table class="solid"><td></td></table>
+<table><th class="solid"></th></table>
+<table><td class="solid"></td></table>
+<br>
+
+<table class="double"><td></td></table>
+<table><th class="double"></th></table>
+<table><td class="double"></td></table>
+<br>
+
+<table class="groove"><td></td></table>
+<table><th class="groove"></th></table>
+<table><td class="groove"></td></table>
+<br>
+
+<table class="ridge"><td></td></table>
+<table><th class="ridge"></th></table>
+<table><td class="ridge"></td></table>
+<br>
+
+<table class="inset"><td></td></table>
+<table><th class="inset"></th></table>
+<table><td class="inset"></td></table>
+<br>
+
+<table class="outset"><td></td></table>
+<table><th class="outset"></th></table>
+<table><td class="outset"></td></table>
+<br>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-border-3s.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-border-3s.html
new file mode 100644
index 0000000000..c4c019c8eb
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-border-3s.html
@@ -0,0 +1,95 @@
+<!DOCTYPE html>
+<head>
+ <title>Testing default 'border-color' on table (with 'color' set), in standards mode</title>
+ <meta charset="utf-8">
+ <link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com">
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/rendering.html#tables-2">
+ <link rel="match" href="table-border-3-ref.html">
+ <style>
+ * {
+ /* This sets the used value of 'currentColor', which is what should be
+ used for all border-coloring in this test: */
+ color: teal;
+ /* This only affects the elements that we specify 'border-style' on: */
+ border-width: 6px;
+ }
+
+ table {
+ height: 30px;
+ width: 30px;
+ border-spacing: 0;
+
+ /* To test in "rows": */
+ float: left;
+ margin: 1px;
+ }
+ br {
+ clear: both;
+ }
+
+ .dotted {
+ border-style: dotted;
+ }
+ .dashed {
+ border-style: dashed;
+ }
+ .solid {
+ border-style: solid;
+ }
+ .double {
+ border-style: double;
+ }
+ .groove {
+ border-style: groove;
+ }
+ .ridge {
+ border-style: ridge;
+ }
+ .inset {
+ border-style: inset;
+ }
+ .outset {
+ border-style: outset;
+ }
+ </style>
+</head>
+
+<table class="dotted"><td></td></table>
+<table><th class="dotted"></th></table>
+<table><td class="dotted"></td></table>
+<br>
+
+<table class="dashed"><td></td></table>
+<table><th class="dashed"></th></table>
+<table><td class="dashed"></td></table>
+<br>
+
+<table class="solid"><td></td></table>
+<table><th class="solid"></th></table>
+<table><td class="solid"></td></table>
+<br>
+
+<table class="double"><td></td></table>
+<table><th class="double"></th></table>
+<table><td class="double"></td></table>
+<br>
+
+<table class="groove"><td></td></table>
+<table><th class="groove"></th></table>
+<table><td class="groove"></td></table>
+<br>
+
+<table class="ridge"><td></td></table>
+<table><th class="ridge"></th></table>
+<table><td class="ridge"></td></table>
+<br>
+
+<table class="inset"><td></td></table>
+<table><th class="inset"></th></table>
+<table><td class="inset"></td></table>
+<br>
+
+<table class="outset"><td></td></table>
+<table><th class="outset"></th></table>
+<table><td class="outset"></td></table>
+<br>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-border-presentational-hints-ascii-case-insensitive-ref.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-border-presentational-hints-ascii-case-insensitive-ref.html
new file mode 100644
index 0000000000..c8d6a20726
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-border-presentational-hints-ascii-case-insensitive-ref.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<link rel="stylesheet" type="text/css" href="/fonts/ahem.css">
+<style>
+table {
+ display: inline-table;
+ font-family: Ahem;
+}
+table, table * {
+ border-width: 3px;
+}
+</style>
+<p>For every three tables below, the first two should have borders between some cells, but not the third:
+<table rules="rows"><tr><td>X<tr><td>X<tr><td>X</table>
+<table rules="rows"><tr><td>X<tr><td>X<tr><td>X</table>
+<table><tr><td>X<tr><td>X<tr><td>X</table>
+<br><br>
+<table rules="cols"><tr><td>X<td>X<td>X</table>
+<table rules="cols"><tr><td>X<td>X<td>X</table>
+<table><tr><td>X<td>X<td>X</table>
+<br><br>
+<table rules="groups"><colgroup span="2"><colgroup><tr><td>X<td>X<td>X</table>
+<table rules="groups"><colgroup span="2"><colgroup><tr><td>X<td>X<td>X</table>
+<table><colgroup span="2"><colgroup><tr><td>X<td>X<td>X</table>
+<br><br>
+<p>For every three tables below, the first two should have borders on some edges, but not the third:
+<table frame="hsides"><tr><td>X</table>
+<table frame="hsides"><tr><td>X</table>
+<table><tr><td>X</table>
+<br><br>
+<table frame="lhs"><tr><td>X</table>
+<table frame="lhs"><tr><td>X</table>
+<table><tr><td>X</table>
+<br><br>
+<table frame="rhs"><tr><td>X</table>
+<table frame="rhs"><tr><td>X</table>
+<table><tr><td>X</table>
+<br><br>
+<table frame="vsides"><tr><td>X</table>
+<table frame="vsides"><tr><td>X</table>
+<table><tr><td>X</table>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-border-presentational-hints-ascii-case-insensitive.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-border-presentational-hints-ascii-case-insensitive.html
new file mode 100644
index 0000000000..45c9da925d
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-border-presentational-hints-ascii-case-insensitive.html
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<link rel="help" href="https://html.spec.whatwg.org/#tables-2:presentational-hints">
+<link rel="help" href="https://drafts.csswg.org/selectors-4/#attribute-case">
+<link rel="match" href="table-border-presentational-hints-ascii-case-insensitive-ref.html">
+<meta name="assert" content="@rules + @frame values are ASCII case-insensitive">
+<link rel="stylesheet" type="text/css" href="/fonts/ahem.css">
+<style>
+table {
+ display: inline-table;
+ font-family: Ahem;
+}
+table, table * {
+ border-width: 3px;
+}
+</style>
+<p>For every three tables below, the first two should have borders between some cells, but not the third:
+<table rules="rows"><tr><td>X<tr><td>X<tr><td>X</table>
+<table rules="RoWs"><tr><td>X<tr><td>X<tr><td>X</table>
+<table rules="rowſ"><tr><td>X<tr><td>X<tr><td>X</table>
+<br><br>
+<table rules="cols"><tr><td>X<td>X<td>X</table>
+<table rules="CoLs"><tr><td>X<td>X<td>X</table>
+<table rules="colſ"><tr><td>X<td>X<td>X</table>
+<br><br>
+<table rules="groups"><colgroup span="2"><colgroup><tr><td>X<td>X<td>X</table>
+<table rules="GrOuPs"><colgroup span="2"><colgroup><tr><td>X<td>X<td>X</table>
+<table rules="groupſ"><colgroup span="2"><colgroup><tr><td>X<td>X<td>X</table>
+<br><br>
+<p>For every three tables below, the first two should have borders on some edges, but not the third:
+<table frame="hsides"><tr><td>X</table>
+<table frame="HsIdEs"><tr><td>X</table>
+<table frame="hſideſ"><tr><td>X</table>
+<br><br>
+<table frame="lhs"><tr><td>X</table>
+<table frame="LhS"><tr><td>X</table>
+<table frame="lhſ"><tr><td>X</table>
+<br><br>
+<table frame="rhs"><tr><td>X</table>
+<table frame="RhS"><tr><td>X</table>
+<table frame="rhſ"><tr><td>X</table>
+<br><br>
+<table frame="vsides"><tr><td>X</table>
+<table frame="VsIdEs"><tr><td>X</table>
+<table frame="vſideſ"><tr><td>X</table>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-bordercolor-001-ref.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-bordercolor-001-ref.html
new file mode 100644
index 0000000000..1b128e6171
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-bordercolor-001-ref.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>Reference case for table bordercolor attribute behaving like border-color property</title>
+<link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com">
+<link rel="author" title="Mozilla" href="https://www.mozilla.org/">
+<style>
+ table { margin: 5px }
+</style>
+<table>
+ <td>I should not have a border.</td>
+</table>
+<table>
+ <td>I should not have a border.</td>
+</table>
+<table>
+ <td>I should not have a border.</td>
+</table>
+<table>
+ <td>I should not have a border.</td>
+</table>
+<table style="border-color: lime; border-style: solid">
+ <td>I should have a border.</td>
+</table>
+<table style="border-color: lime; border-style: solid">
+ <td>I should have a border.</td>
+</table>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-bordercolor-001.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-bordercolor-001.html
new file mode 100644
index 0000000000..014abe3567
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-bordercolor-001.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>Test for table bordercolor attribute behaving like border-color property</title>
+<link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com">
+<link rel="author" title="Mozilla" href="https://www.mozilla.org/">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/rendering.html#tables-2">
+<link rel="match" href="table-bordercolor-001-ref.html">
+<meta name="assert" content="bordercolor is treated as a presentation hint, equivalent to setting the border-color property">
+<style>
+ table { margin: 5px }
+</style>
+<table bordercolor="red">
+ <td>I should not have a border.</td>
+</table>
+<table style="border-color: red">
+ <td>I should not have a border.</td>
+</table>
+<table bordercolor="red" style="border-width: 10px">
+ <td>I should not have a border.</td>
+</table>
+<table style="border-color: red; border-width: 10px">
+ <td>I should not have a border.</td>
+</table>
+<table bordercolor="lime" style="border-style: solid">
+ <td>I should have a border.</td>
+</table>
+<table style="border-color: lime; border-style: solid">
+ <td>I should have a border.</td>
+</table>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-cell-nowrap-with-fixed-width-ref.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-cell-nowrap-with-fixed-width-ref.html
new file mode 100644
index 0000000000..5b2ea91fe5
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-cell-nowrap-with-fixed-width-ref.html
@@ -0,0 +1,2 @@
+<!DOCTYPE html>
+<div style="width: 100px; height: 100px; background: green;"></div>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-cell-nowrap-with-fixed-width.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-cell-nowrap-with-fixed-width.html
new file mode 100644
index 0000000000..65962ac273
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-cell-nowrap-with-fixed-width.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<link rel="help" href="https://html.spec.whatwg.org/#tables-2">
+<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=821915">
+<link rel="match" href="table-cell-nowrap-with-fixed-width-ref.html">
+<title>A td element with the nowrap attribute should unconditionally apply white-space:nowrap</title>
+<style>
+table { border-spacing: 0; }
+td { width: 10px; padding: 0; }
+div { display: inline-block; background: green; width: 50px; height: 100px; }
+</style>
+<table>
+ <td nowrap>
+ <div></div><div></div>
+ </td>
+</table>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-cell-width-ref.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-cell-width-ref.html
new file mode 100644
index 0000000000..b5ba0443f3
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-cell-width-ref.html
@@ -0,0 +1,37 @@
+<style>
+body {
+ margin: 0;
+}
+
+.row {
+ clear: both;
+}
+
+.row div {
+ float: left;
+}
+
+.red {
+ background-color: red;
+}
+</style>
+
+<div class="row">
+ <div class="red" style="width: 200px">a</div>
+ <div style="width: 200px">a</div>
+</div>
+
+<div class="row">
+ <div class="red" style="width: 200px">a</div>
+ <div style="width: 200px">a</div>
+</div>
+
+<div class="row">
+ <div class="red" style="width: 100px">a</div>
+ <div style="width: 300px">a</div>
+</div>
+
+<div class="row">
+ <div class="red" style="width: 100px">a</div>
+ <div style="width: 300px">a</div>
+</div>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-cell-width-s.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-cell-width-s.html
new file mode 100644
index 0000000000..0fe0e2c25a
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-cell-width-s.html
@@ -0,0 +1,55 @@
+<!doctype html>
+<link rel="match" href="table-cell-width-ref.html">
+<style>
+body {
+ margin: 0;
+}
+
+table {
+ width: 400px;
+ border-collapse: collapse;
+}
+
+th {
+ font-weight: normal;
+ text-align: left;
+}
+
+td, th {
+ padding: 0;
+}
+
+td:first-child, th:first-child {
+ background-color: red;
+}
+</style>
+
+<!-- width=0 should be treated as 'auto' -->
+<table>
+ <tr>
+ <th width=0>a</th>
+ <th>a</th>
+ </tr>
+</table>
+
+<table>
+ <tr>
+ <td width=0>a</td>
+ <td>a</td>
+ </tr>
+</table>
+
+<!-- test valid width attribute value-->
+<table>
+ <tr>
+ <th width=100>a</th>
+ <th>a</th>
+ </tr>
+</table>
+
+<table>
+ <tr>
+ <td width=100>a</td>
+ <td>a</td>
+ </tr>
+</table>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-cell-width.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-cell-width.html
new file mode 100644
index 0000000000..f66244ab10
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-cell-width.html
@@ -0,0 +1,54 @@
+<link rel="match" href="table-cell-width-ref.html">
+<style>
+body {
+ margin: 0;
+}
+
+table {
+ width: 400px;
+ border-collapse: collapse;
+}
+
+th {
+ font-weight: normal;
+ text-align: left;
+}
+
+td, th {
+ padding: 0;
+}
+
+td:first-child, th:first-child {
+ background-color: red;
+}
+</style>
+
+<!-- width=0 should be treated as 'auto' -->
+<table>
+ <tr>
+ <th width=0>a</th>
+ <th>a</th>
+ </tr>
+</table>
+
+<table>
+ <tr>
+ <td width=0>a</td>
+ <td>a</td>
+ </tr>
+</table>
+
+<!-- test valid width attribute value-->
+<table>
+ <tr>
+ <th width=100>a</th>
+ <th>a</th>
+ </tr>
+</table>
+
+<table>
+ <tr>
+ <td width=100>a</td>
+ <td>a</td>
+ </tr>
+</table>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-column-width-ref.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-column-width-ref.html
new file mode 100644
index 0000000000..1eb7c00d21
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-column-width-ref.html
@@ -0,0 +1,2 @@
+<!doctype html>
+<div style="border: 1px solid green; width: 0">Text</div>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-column-width.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-column-width.html
new file mode 100644
index 0000000000..6358e14a39
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-column-width.html
@@ -0,0 +1,10 @@
+<!doctype html>
+<link rel="match" href="table-column-width-ref.html">
+<table style="display: block">
+ <colgroup style="display: block">
+ <col style="border: 1px solid green; display: block" width="0"></col>
+ </colgroup>
+</table>
+<script>
+ document.querySelector("col").append("Text");
+</script>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-direction-ref.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-direction-ref.html
new file mode 100644
index 0000000000..2bbd6c0477
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-direction-ref.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<title>Table direction</title>
+
+<style>
+ table {
+ border-collapse: collapse;
+ }
+
+ td {
+ border: 2px solid black;
+ width: 20px;
+ height: 20px;
+ }
+
+ td.special {
+ border-left: 5px solid green;
+ border-right: 5px solid blue;
+ }
+</style>
+
+Normal table:
+<table>
+ <tr>
+ <td></td>
+ <td class="special"></td>
+ </tr>
+</table>
+
+<hr>
+
+RTL table:
+<table>
+ <tr>
+ <td class="special"></td>
+ <td></td>
+ </tr>
+</table>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-direction.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-direction.html
new file mode 100644
index 0000000000..a3de4136f1
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-direction.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<link rel="match" href="table-direction-ref.html">
+<title>Table direction</title>
+
+<style>
+ table {
+ border-collapse: collapse;
+ }
+
+ td {
+ border: 2px solid black;
+ width: 20px;
+ height: 20px;
+ }
+
+ td.special {
+ border-left: 5px solid green;
+ border-right: 5px solid blue;
+ }
+</style>
+
+Normal table:
+<table>
+ <tr>
+ <td></td>
+ <td class="special"></td>
+ </tr>
+</table>
+
+<hr>
+
+RTL table:
+<table style="direction: rtl">
+ <tr>
+ <td></td>
+ <td class="special"></td>
+ </tr>
+</table>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-layout-notref.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-layout-notref.html
new file mode 100644
index 0000000000..ef1378185a
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-layout-notref.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Table layout attribute</title>
+<table border width=100% style=table-layout:fixed>
+<tr><td>aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa<td>aaa
+</table>
+<table border width=100% style=table-layout:fixed>
+<tr><td>aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa<td>aaa
+</table>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-layout-ref.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-layout-ref.html
new file mode 100644
index 0000000000..d76a48c4ab
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-layout-ref.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Table layout attribute</title>
+<table border width=100%>
+<tr><td>aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa<td>aaa
+</table>
+<table border width=100%>
+<tr><td>aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa<td>aaa
+</table>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-layout.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-layout.html
new file mode 100644
index 0000000000..7dfacf2279
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-layout.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Table layout attribute</title>
+<link rel="match" href="table-layout-ref.html">
+<meta name="assert"
+ content="The layout attribute on table elements should have no effect.">
+<table border width=100% layout=fixed>
+<tr><td>aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa<td>aaa
+</table>
+<table border width=100% layout=auto>
+<tr><td>aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa<td>aaa
+</table>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-row-direction-ref.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-row-direction-ref.html
new file mode 100644
index 0000000000..dab31636d9
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-row-direction-ref.html
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<title>Table row direction</title>
+
+<style>
+ table {
+ border-collapse: collapse;
+ }
+
+ td {
+ border: 2px solid black;
+ width: 20px;
+ height: 20px;
+ }
+
+ td.special {
+ border-left: 5px solid green;
+ border-right: 5px solid blue;
+ }
+</style>
+
+Normal table with LTR and RTL rows:
+<table>
+ <tr>
+ <td></td>
+ <td class="special"></td>
+ </tr>
+ <tr>
+ <td></td>
+ <td class="special"></td>
+ </tr>
+</table>
+
+<hr>
+
+RTL table with LTR and RTL rows:
+<table>
+ <tr>
+ <td class="special"></td>
+ <td></td>
+ </tr>
+ <tr>
+ <td class="special"></td>
+ <td></td>
+ </tr>
+</table>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-row-direction.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-row-direction.html
new file mode 100644
index 0000000000..64ed5a667a
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-row-direction.html
@@ -0,0 +1,46 @@
+<!DOCTYPE html>
+<link rel="match" href="table-row-direction-ref.html">
+<title>Table row direction</title>
+
+<style>
+ table {
+ border-collapse: collapse;
+ }
+
+ td {
+ border: 2px solid black;
+ width: 20px;
+ height: 20px;
+ }
+
+ td.special {
+ border-left: 5px solid green;
+ border-right: 5px solid blue;
+ }
+</style>
+
+Normal table with LTR and RTL rows:
+<table>
+ <tr style="direction: ltr">
+ <td></td>
+ <td class="special"></td>
+ </tr>
+ <tr style="direction: rtl">
+ <td></td>
+ <td class="special"></td>
+ </tr>
+</table>
+
+<hr>
+
+RTL table with LTR and RTL rows:
+<table style="direction: rtl">
+ <tr style="direction: ltr">
+ <td></td>
+ <td class="special"></td>
+ </tr>
+ <tr style="direction: rtl">
+ <td></td>
+ <td class="special"></td>
+ </tr>
+</table>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-row-group-direction-ref.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-row-group-direction-ref.html
new file mode 100644
index 0000000000..0f3e03f9ba
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-row-group-direction-ref.html
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<title>Table row-group direction</title>
+
+<style>
+ table {
+ border-collapse: collapse;
+ }
+
+ td {
+ border: 2px solid black;
+ width: 20px;
+ height: 20px;
+ }
+
+ td.special {
+ border-left: 5px solid green;
+ border-right: 5px solid blue;
+ }
+</style>
+
+Normal table with LTR and RTL row groups:
+<table>
+ <tr>
+ <td></td>
+ <td class="special"></td>
+ </tr>
+ <tr>
+ <td></td>
+ <td class="special"></td>
+ </tr>
+</table>
+
+<hr>
+
+RTL table with LTR and RTL row groups:
+<table>
+ <tr>
+ <td class="special"></td>
+ <td></td>
+ </tr>
+ <tr>
+ <td class="special"></td>
+ <td></td>
+ </tr>
+</table>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-row-group-direction.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-row-group-direction.html
new file mode 100644
index 0000000000..385672f127
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-row-group-direction.html
@@ -0,0 +1,54 @@
+<!DOCTYPE html>
+<link rel="match" href="table-row-group-direction-ref.html">
+<title>Table row-group direction</title>
+
+<style>
+ table {
+ border-collapse: collapse;
+ }
+
+ td {
+ border: 2px solid black;
+ width: 20px;
+ height: 20px;
+ }
+
+ td.special {
+ border-left: 5px solid green;
+ border-right: 5px solid blue;
+ }
+</style>
+
+Normal table with LTR and RTL row groups:
+<table>
+ <tbody style="direction: ltr">
+ <tr>
+ <td></td>
+ <td class="special"></td>
+ </tr>
+ </tbody>
+ <tbody style="direction: rtl">
+ <tr>
+ <td></td>
+ <td class="special"></td>
+ </tr>
+ </tbody>
+</table>
+
+<hr>
+
+RTL table with LTR and RTL row groups:
+<table style="direction: rtl">
+ <tbody style="direction: ltr">
+ <tr>
+ <td></td>
+ <td class="special"></td>
+ </tr>
+ </tbody>
+ <tbody style="direction: rtl">
+ <tr>
+ <td></td>
+ <td class="special"></td>
+ </tr>
+ </tbody>
+</table>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-row-group-height-ref.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-row-group-height-ref.html
new file mode 100644
index 0000000000..e5279080f0
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-row-group-height-ref.html
@@ -0,0 +1,30 @@
+<!doctype html>
+<table style="border: 1px solid red">
+ <thead style="display: block; height: 100px">
+ <tr>
+ <td>
+ thead text
+ </td>
+ </tr>
+ </tr>
+</table>
+
+<table style="border: 1px solid red">
+ <tbody style="display: block; height: 100px">
+ <tr>
+ <td>
+ tbody text
+ </td>
+ </tr>
+ </tr>
+</table>
+
+<table style="border: 1px solid red">
+ <tfoot style="display: block; height: 100px">
+ <tr>
+ <td>
+ tfoot text
+ </td>
+ </tr>
+ </tr>
+</table>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-row-group-height.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-row-group-height.html
new file mode 100644
index 0000000000..b58311dd72
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-row-group-height.html
@@ -0,0 +1,31 @@
+<!doctype html>
+<link rel="match" href="table-row-group-height-ref.html">
+<table style="border: 1px solid red">
+ <thead style="display: block" height="100">
+ <tr>
+ <td>
+ thead text
+ </td>
+ </tr>
+ </tr>
+</table>
+
+<table style="border: 1px solid red">
+ <tbody style="display: block" height="100">
+ <tr>
+ <td>
+ tbody text
+ </td>
+ </tr>
+ </tr>
+</table>
+
+<table style="border: 1px solid red">
+ <tfoot style="display: block" height="100">
+ <tr>
+ <td>
+ tfoot text
+ </td>
+ </tr>
+ </tr>
+</table>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-row-height-ref.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-row-height-ref.html
new file mode 100644
index 0000000000..63f882c689
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-row-height-ref.html
@@ -0,0 +1,4 @@
+<!doctype html>
+<div style="border: 1px solid green; height: 0; border-spacing: 2px">
+ <div style="display: table-cell; padding: 1px">Hey</div>
+</div>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-row-height.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-row-height.html
new file mode 100644
index 0000000000..8ecc0dd454
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-row-height.html
@@ -0,0 +1,9 @@
+<!doctype html>
+<link rel="match" href="table-row-height-ref.html">
+<table style="display: block">
+ <tbody style="display: block">
+ <tr style="display: block; border: 1px solid green" height="0">
+ <td>Hey</td>
+ </tr>
+ </tbody>
+</table>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-row-pagination-001-print-ref.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-row-pagination-001-print-ref.html
new file mode 100644
index 0000000000..2aa94109ad
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-row-pagination-001-print-ref.html
@@ -0,0 +1,29 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Testing row split</title>
+<style type="text/css">
+@page { size:5in 3in; margin:0.5in; }
+html,body {
+ color:black;
+ background-color:white;
+ font-size:16px;
+ padding:0;
+ margin:0;
+ height:100%;
+}
+div { height:160%; }
+p { height: 50%; margin:0; }
+</style>
+</head>
+<body>
+
+<div>
+<p></p>
+<p>1</p>
+</div>
+
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-row-pagination-001-print.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-row-pagination-001-print.html
new file mode 100644
index 0000000000..3a14558a8b
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-row-pagination-001-print.html
@@ -0,0 +1,33 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+<link rel="match" href="table-row-pagination-001-print-ref.html">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/rendering.html#tables-2">
+<link rel="help" href="https://drafts.csswg.org/css-break/">
+<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=685012">
+<meta charset="utf-8">
+<title>Testing row split</title>
+<style type="text/css">
+@page { size:5in 3in; margin:0.5in; }
+html,body {
+ color:black;
+ background-color:white;
+ font-size:16px;
+ padding:0;
+ margin:0;
+ height:100%;
+}
+table { height:160%; width:100%; }
+td { height:50%; width:100%; }
+</style>
+</head>
+<body>
+
+<table border="0" cellspacing="0" cellpadding="0">
+<tr><td></td></tr>
+<tr><td valign="top">1</td></tr>
+</table>
+
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-row-pagination-002-print-ref.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-row-pagination-002-print-ref.html
new file mode 100644
index 0000000000..91400fcc1e
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-row-pagination-002-print-ref.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<style>
+@page { size:5in 3in; margin:0.5in; }
+</style>
+</head>
+<body>
+ <div style="height:3in">Tall div. (Scroll to end.)</div>
+ <div>IS THIS TEXT VISIBLE IN PRINT PREVIEW?</div>
+ <div>[clear:left]</div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-row-pagination-002-print.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-row-pagination-002-print.html
new file mode 100644
index 0000000000..bc1c42088f
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-row-pagination-002-print.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<link rel="match" href="table-row-pagination-002-print-ref.html">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/rendering.html#tables-2">
+<link rel="help" href="https://drafts.csswg.org/css-break/">
+<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=963441">
+<style>
+@page { size:5in 3in; margin:0.5in; }
+</style>
+</head>
+<body>
+ <div style="float: left">
+ <table cellpadding=0 cellspacing=0>
+ <tr>
+ <td>
+ <div style="height:3in">Tall div. (Scroll to end.)</div>
+ <div>IS THIS TEXT VISIBLE IN PRINT PREVIEW?</div>
+ </td>
+ </tr>
+ </table>
+ </div>
+ <div style="clear: left">[clear:left]</div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-ua-stylesheet.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-ua-stylesheet.html
new file mode 100644
index 0000000000..dc3e45f5a4
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-ua-stylesheet.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>Test for table element's UA-stylesheet-provided styles</title>
+<link rel="help" href="https://html.spec.whatwg.org/multipage/rendering.html#the-css-user-agent-style-sheet-and-presentational-hints">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/rendering.html#tables-2">
+<link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<div id="refElem"></div>
+<!-- Note: this test puts the table inside of an element with a non-default
+ 'text-indent' and 'border-collapse' values, so that we can verify that
+ the table does indeed use the initial value for these properties, rather
+ than simply inheriting. -->
+<div style="text-indent: 100px; border-collapse: collapse">
+ <table id="tableElem"></table>
+</div>
+
+<script>
+/* These styles come from the default `table` styling here:
+ * https://html.spec.whatwg.org/multipage/rendering.html#tables-2
+ * We can't check for these values directly, because they may be
+ * serialized slightly differently when read from the computed style.
+ * So, for each property here, we apply it to a "reference" div and then
+ * read back the computed value, and we validate that a table element
+ * has that same computed value by default. */
+const defaultTablePropVals = {
+ 'display': 'table',
+ 'box-sizing': 'border-box',
+ 'border-spacing': '2px',
+ 'border-collapse': 'separate',
+ 'text-indent': 'initial',
+};
+
+for (var propName in defaultTablePropVals) {
+ test(function() {
+ refElem.style[propName] = defaultTablePropVals[propName];
+ let expectedComputedVal = getComputedStyle(refElem, "")[propName];
+
+ let actualComputedVal = getComputedStyle(tableElem, "")[propName];
+ assert_equals(actualComputedVal, expectedComputedVal);
+ }, `Computed '${propName}' on table should match html spec`);
+}
+</script>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-valign-baseline-ascii-case-insensitive.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-valign-baseline-ascii-case-insensitive.html
new file mode 100644
index 0000000000..f64bb9aa08
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-valign-baseline-ascii-case-insensitive.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<link rel="help" href="https://html.spec.whatwg.org/#tables-2:presentational-hints">
+<link rel="help" href="https://drafts.csswg.org/selectors-4/#attribute-case">
+<meta name="assert" content="@valign values on table-related elements are ASCII case-insensitive">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<table><tr><td valign="baseline">X</table>
+<table><tr><td valign="BaSeLiNe">X</table>
+<table><tr><td valign="baſeline">X</table>
+<script>
+const td = document.querySelectorAll("td");
+
+test(() => {
+ assert_equals(getComputedStyle(td[0]).getPropertyValue("vertical-align"),
+ "baseline", "lowercase valid");
+ assert_equals(getComputedStyle(td[1]).getPropertyValue("vertical-align"),
+ "baseline", "mixed case valid");
+ assert_equals(getComputedStyle(td[2]).getPropertyValue("vertical-align"),
+ "middle", "non-ASCII invalid");
+}, "keyword baseline");
+</script>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-vspace-hspace-s.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-vspace-hspace-s.html
new file mode 100644
index 0000000000..9f462b5768
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-vspace-hspace-s.html
@@ -0,0 +1,16 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>table vspace hspace (standards mode)</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<div>x</div>
+<table vspace=25 hspace=25><tr><td>x</table>
+<div>x</div>
+<script>
+test(function() {
+ var style = getComputedStyle(document.querySelector('table'));
+ ['marginTop', 'marginRight', 'marginBottom', 'marginLeft'].forEach(function(m) {
+ assert_equals(style[m], '0px', m);
+ });
+});
+</script>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-vspace-hspace.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-vspace-hspace.html
new file mode 100644
index 0000000000..c081775b87
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-vspace-hspace.html
@@ -0,0 +1,16 @@
+<!-- quirks -->
+<meta charset=utf-8>
+<title>table vspace hspace (quirks mode)</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<div>x</div> <!-- prevent margin collapsing quirks -->
+<table vspace=25 hspace=25><tr><td>x</table>
+<div>x</div> <!-- prevent margin collapsing quirks -->
+<script>
+test(function() {
+ var style = getComputedStyle(document.querySelector('table'));
+ ['marginTop', 'marginRight', 'marginBottom', 'marginLeft'].forEach(function(m) {
+ assert_equals(style[m], '0px', m);
+ });
+});
+</script>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-width-150percent-ref.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-width-150percent-ref.html
new file mode 100644
index 0000000000..820c360e39
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-width-150percent-ref.html
@@ -0,0 +1,12 @@
+<!doctype html>
+<title>Test for capping percentages</title>
+<style>
+div { width:300px; background:yellow; height:50px; }
+table { width:150%; }
+td { background:blue; }
+</style>
+<div>
+ <table cellspacing="0" cellpadding="0" border="0">
+ <tr><td>parent div float=left</td></tr>
+ </table>
+</div>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-width-150percent.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-width-150percent.html
new file mode 100644
index 0000000000..9a5e108505
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-width-150percent.html
@@ -0,0 +1,12 @@
+<!doctype html>
+<title>Test for capping percentages</title>
+<link rel="match" href="table-width-150percent-ref.html">
+<style>
+div { width:300px; background:yellow; height:50px; }
+td { background:blue; }
+</style>
+<div>
+ <table width="150%" cellspacing="0" cellpadding="0" border="0">
+ <tr><td>parent div float=left</td></tr>
+ </table>
+</div>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-width-ref.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-width-ref.html
new file mode 100644
index 0000000000..2b0f9e445c
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-width-ref.html
@@ -0,0 +1,13 @@
+<style>
+p {
+ padding: 0;
+ margin: 0;
+}
+</style>
+
+<p>a b</p>
+
+<hr>
+
+<p>a</p>
+<p>b</p>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-width-s.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-width-s.html
new file mode 100644
index 0000000000..5b987e7919
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-width-s.html
@@ -0,0 +1,31 @@
+<!doctype html>
+<link rel="match" href="table-width-ref.html">
+
+<style>
+table {
+ border-collapse: collapse;
+}
+
+td {
+ padding: 0;
+}
+</style>
+
+<!-- width=0 should be treated as 'auto' -->
+<table width=0>
+ <tr>
+ <td>
+ a b
+ </td>
+ </tr>
+</table>
+
+<hr>
+
+<table width=1>
+ <tr>
+ <td>
+ a b
+ </td>
+ </tr>
+</table>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-width.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-width.html
new file mode 100644
index 0000000000..59c5ca70d4
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/table-width.html
@@ -0,0 +1,30 @@
+<link rel="match" href="table-width-ref.html">
+
+<style>
+table {
+ border-collapse: collapse;
+}
+
+td {
+ padding: 0;
+}
+</style>
+
+<!-- width=0 should be treated as 'auto' -->
+<table width=0>
+ <tr>
+ <td>
+ a b
+ </td>
+ </tr>
+</table>
+
+<hr>
+
+<table width=1>
+ <tr>
+ <td>
+ a b
+ </td>
+ </tr>
+</table>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/tr-transform-and-will-change-ref.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/tr-transform-and-will-change-ref.html
new file mode 100644
index 0000000000..2cbcd6a347
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/tr-transform-and-will-change-ref.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<style>
+td { width: 100px; height: 100px; background: green; }
+</style>
+<table>
+ <tr><td></td></tr>
+ <tr><td></td></tr>
+</table>
+There should be 2 green boxes above.
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/tr-transform-and-will-change.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/tr-transform-and-will-change.html
new file mode 100644
index 0000000000..0f37d635a5
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/tr-transform-and-will-change.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<link rel="match" href="tr-transform-and-will-change-ref.html">
+<style>
+tbody { background: green; }
+td { width: 100px; height: 100px; }
+tr { transform: translateX(5px); will-change: transform; }
+</style>
+<table>
+ <tbody>
+ <tr><td></td></tr>
+ <tr><td></td></tr>
+ </tbody>
+</table>
+There should be 2 green boxes above.
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/transformed-tbody-tr-collapsed-border-ref.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/transformed-tbody-tr-collapsed-border-ref.html
new file mode 100644
index 0000000000..2f313f3395
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/transformed-tbody-tr-collapsed-border-ref.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<style>
+table {
+ border-collapse: collapse;
+}
+td {
+ border: 5px solid black;
+ width: 100px;
+ height: 100px;
+}
+</style>
+Passes if there is a grid containing 2x2 squares.
+<table>
+ <tbody>
+ <tr><td></td><td></td></tr>
+ <tr><td></td><td></td></tr>
+ </tbody>
+</table>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/transformed-tbody-tr-collapsed-border.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/transformed-tbody-tr-collapsed-border.html
new file mode 100644
index 0000000000..5f131e6658
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/tables/transformed-tbody-tr-collapsed-border.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<title>Test for transformed tbody and tr with collapsed borders</title>
+<link rel="match" href="transformed-tbody-tr-collapsed-border-ref.html">
+<style>
+table {
+ border-collapse: collapse;
+}
+tbody, tr {
+ transform: translateY(0);
+}
+td {
+ border: 5px solid black;
+ width: 100px;
+ height: 100px;
+}
+</style>
+Passes if there is a grid containing 2x2 squares.
+<table>
+ <tbody>
+ <tr><td></td><td></td></tr>
+ <tr><td></td><td></td></tr>
+ </tbody>
+</table>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/META.yml b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/META.yml
new file mode 100644
index 0000000000..f5b533c377
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/META.yml
@@ -0,0 +1,4 @@
+suggested_reviewers:
+ - emilio
+ - mstensho
+ - zcorpan
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/absolute-fixed-in-legend-ref.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/absolute-fixed-in-legend-ref.html
new file mode 100644
index 0000000000..f82faee114
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/absolute-fixed-in-legend-ref.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<style>
+div {
+ display: block;
+ font-size: 32px;
+ background: lime;
+ width: 10em;
+}
+</style>
+
+<div>legend</div>
+<div>legend</div>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/absolute-fixed-in-legend.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/absolute-fixed-in-legend.html
new file mode 100644
index 0000000000..56d296977c
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/absolute-fixed-in-legend.html
@@ -0,0 +1,52 @@
+<!DOCTYPE html>
+<title>Absolute/fixed-positioned boxes in LEGEND should be painted on the fieldset content</title>
+<link rel=match href=absolute-fixed-in-legend-ref.html>
+<style>
+.absolute-container {
+ position: relative;
+ border: none;
+ padding: 0;
+ margin: 0;
+}
+
+.absolute-container .legend-content {
+ display: block;
+ font-size: 32px;
+ position: absolute;
+ left: 0px;
+ background: lime;
+ width: 10em;
+}
+
+.fixed-container {
+ contain: paint;
+ border: none;
+ padding: 0;
+ margin: 0;
+}
+
+.fixed-container .legend-content {
+ display: block;
+ font-size: 32px;
+ position: fixed;
+ left: 0px;
+ background: lime;
+ width: 10em;
+}
+
+.fieldset-content {
+ background: red;
+ font-size: 32px;
+ width: 10em;
+}
+</style>
+
+<fieldset class="absolute-container">
+ <legend><span class="legend-content">legend</span></legend>
+ <div class="fieldset-content">content</div>
+</fieldset>
+
+<fieldset class="fixed-container">
+ <legend><span class="legend-content">legend</span></legend>
+ <div class="fieldset-content">content</div>
+</fieldset>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/crashtests/fieldset-middleclick.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/crashtests/fieldset-middleclick.html
new file mode 100644
index 0000000000..39acf9eca1
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/crashtests/fieldset-middleclick.html
@@ -0,0 +1,37 @@
+<!DOCTYPE HTML>
+<html class="test-wait">
+<head>
+<script src="/resources/testdriver.js"></script>
+<script src="/resources/testdriver-actions.js"></script>
+<script src="/resources/testdriver-vendor.js"></script>
+<style>
+#f {
+ overflow-y: scroll;
+ width: 100px;
+ height: 100px;
+}
+</style>
+</head>
+<body>
+<fieldset id="f">
+ <p>test</p>
+ <p>test</p>
+ <p>test</p>
+ <p>test</p>
+ <p>test</p>
+ <p>test</p>
+</fieldset>
+<script>
+onload = async () => {
+ const actions = new test_driver.Actions();
+ const button = {button: actions.ButtonType.MIDDLE};
+ await actions.
+ pointerMove(50, 50).
+ pointerDown(button).
+ pointerUp(button).
+ send();
+ document.documentElement.className = "";
+};
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/empty-scrollable-ref.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/empty-scrollable-ref.html
new file mode 100644
index 0000000000..7fa15da174
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/empty-scrollable-ref.html
@@ -0,0 +1,3 @@
+<!DOCTYPE html>
+<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org">
+<div style="all:initial; display:block; overflow:scroll; width:100px; height:100px; background:blue;"></div>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/empty-scrollable.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/empty-scrollable.html
new file mode 100644
index 0000000000..c968ed3f13
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/empty-scrollable.html
@@ -0,0 +1,5 @@
+<!DOCTYPE html>
+<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/rendering.html#the-fieldset-and-legend-elements">
+<link rel="match" href="empty-scrollable-ref.html">
+<fieldset style="all:initial; display:block; overflow:scroll; width:100px; height:100px; background:blue;"></fieldset>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-baseline-ref.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-baseline-ref.html
new file mode 100644
index 0000000000..ff583435a6
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-baseline-ref.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<style>
+span {
+ border: solid 2px;
+ padding: 10px;
+ margin: 5px;
+}
+</style>
+<div>
+ text <span style="display: inline-block;">line1<br>line2</span>
+</div>
+<div>
+ text <span style="display: inline-flex;">line1<br>line2</span>
+</div>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-baseline.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-baseline.html
new file mode 100644
index 0000000000..23f5ad76f3
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-baseline.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1305890">
+<link rel="match" href="fieldset-baseline-ref.html">
+<style>
+fieldset {
+ border: solid 2px;
+ padding: 10px;
+ margin: 5px;
+}
+</style>
+<div>
+ text <fieldset style="display: inline-block;">line1<br>line2</fieldset>
+</div>
+<div>
+ text <fieldset style="display: inline-flex;">line1<br>line2</fieldset>
+</div>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-block-formatting-context.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-block-formatting-context.html
new file mode 100644
index 0000000000..c38944ae79
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-block-formatting-context.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<title>The fieldset element: block formatting context</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<style>
+* {
+ margin: 0;
+ padding: 0;
+}
+fieldset { border: none; }
+.float {
+ float: left;
+ width: 50px;
+ height: 50px;
+ background-color: orange;
+}
+</style>
+
+<div class=float></div>
+<fieldset><div class=float></div></fieldset>
+
+<script>
+test(() => {
+ const fieldset = document.querySelector('fieldset');
+ assert_equals(fieldset.offsetTop, 0, 'fieldset.offsetTop');
+ assert_equals(fieldset.offsetLeft, 50, 'fieldset.offsetLeft');
+ assert_equals(fieldset.clientHeight, 50, 'fieldset.clientHeight');
+});
+</script>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-block-size.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-block-size.html
new file mode 100644
index 0000000000..e1247637db
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-block-size.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<link rel="help" href="https://html.spec.whatwg.org/C/#the-fieldset-and-legend-elements">
+<!-- A test for the following paragraph:
+For the purpose of calculating the used 'block-size', if the computed
+'block-size' is not 'auto', the space allocated for the rendered legend's
+margin box that spills out past the border, if any, is expected to be
+subtracted from the 'block-size'. If the content box's block-size would be
+negative, then let the content box's block-size be zero instead.
+-->
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<style>
+fieldset {
+ margin: 0;
+ padding: 0;
+ border: 2px solid black;
+}
+legend {
+ height: 102px;
+ background-color: yellow;
+}
+.content {
+ background-color: lime;
+}
+</style>
+<fieldset style="block-size: 200px;">
+<legend>Legend</legend>
+<div class="content" style="height:100%"></div>
+</fieldset>
+
+<fieldset style="block-size: 40px;">
+<legend>Legend</legend>
+<div class="content" style="height:100%"></div>
+</fieldset>
+
+<script>
+test(() => {
+ let cs = document.querySelectorAll('.content');
+ assert_equals(cs[0].offsetHeight, Math.max(202 - 102, 0));
+ assert_equals(cs[1].offsetHeight, Math.max(42 - 102, 0));
+}, 'Test content\'s block-size');
+</script>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-border-gap-negative-margin.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-border-gap-negative-margin.html
new file mode 100644
index 0000000000..563a2aa68d
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-border-gap-negative-margin.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<title>fieldset border gap with negative margin</title>
+<link rel=match href=no-red-ref.html>
+<style>
+fieldset { border:none; border-left: 100px solid red; margin: 0; padding: 0; height:100px; }
+legend { padding: 0; margin-left: -100px; width: 100px; height: 100px; transform: rotate(45deg); }
+</style>
+<p>There should be no red.</p>
+<fieldset>
+ <legend></legend>
+</fieldset>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-border-gap-position-relative-ref.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-border-gap-position-relative-ref.html
new file mode 100644
index 0000000000..95e2347121
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-border-gap-position-relative-ref.html
@@ -0,0 +1,7 @@
+<!doctype html>
+<title>Reference for fieldset border gap</title>
+<style>
+div { position: relative; top: 25px; width: 100px; height: 50px; background: lime; }
+</style>
+<p>There should be no red.</p>
+<div></div>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-border-gap-position-relative.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-border-gap-position-relative.html
new file mode 100644
index 0000000000..1dbef479a9
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-border-gap-position-relative.html
@@ -0,0 +1,10 @@
+<!doctype html>
+<title>fieldset border gap</title>
+<link rel=match href=fieldset-border-gap-position-relative-ref.html>
+<style>
+fieldset, legend { margin: 0; padding: 0; }
+fieldset { border: none; border-top: 100px solid red; width: 100px; }
+legend { width: 100px; height: 50px; background: lime; }
+</style>
+<p>There should be no red.</p>
+<fieldset><legend></legend></fieldset>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-border-radius-hittest.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-border-radius-hittest.html
new file mode 100644
index 0000000000..9ab10159d8
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-border-radius-hittest.html
@@ -0,0 +1,14 @@
+<!doctype html>
+<title>fieldset, border-radius and hit testing</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<style>
+fieldset { width: 80px; height: 80px; border-radius: 100px; border: 10px solid; background: lime; }
+</style>
+<fieldset>
+</fieldset>
+<script>
+test(() => {
+ assert_equals(document.elementFromPoint(20, 20), document.body);
+});
+</script>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-border-radius-with-alpha-ref.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-border-radius-with-alpha-ref.html
new file mode 100644
index 0000000000..5cfe13c40d
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-border-radius-with-alpha-ref.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<style>
+div {
+ background-color: green;
+ height: 110px;
+ position: absolute;
+ width: 150px;
+ top: 70px;
+}
+</style>
+<p>There should be no red.</p>
+<div></div>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-border-radius-with-alpha.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-border-radius-with-alpha.html
new file mode 100644
index 0000000000..7a942076fb
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-border-radius-with-alpha.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<title>Fieldset with a border-radius and non-opaque border-color</title>
+<link rel="match" href="fieldset-border-radius-with-alpha-ref.html">
+<style>
+fieldset {
+ background-color: green;
+ border: 3px solid rgba(255, 0, 0, 0.9);
+ border-radius: 4px;
+ height: 100px;
+ width: 100px;
+}
+legend {
+ height: 50px;
+ width: 50px;
+}
+div {
+ background-color: green;
+ height: 110px;
+ position: absolute;
+ width: 150px;
+ top: 70px;
+}
+</style>
+<p>There should be no red.</p>
+<fieldset><legend></legend></fieldset>
+<div></div>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-calculating-min-max-content.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-calculating-min-max-content.html
new file mode 100644
index 0000000000..4a9f261895
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-calculating-min-max-content.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<title>fieldset calculating min-/max-content</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<style>
+fieldset { margin: 0; padding: 0; }
+.min-content { width: 0; }
+legend { padding: 0; }
+fieldset, #ref-max-content, #ref-min-content { float: left; clear: left; border: 1px solid; }
+#log { clear: left; }
+</style>
+<fieldset class=max-content><legend>foo fooo</legend>x x</fieldset>
+<fieldset class=max-content><legend>x x</legend>foo fooo</fieldset>
+<div id=ref-max-content>foo fooo</div>
+
+<fieldset class=min-content><legend>foo fooo</legend>x x</fieldset>
+<fieldset class=min-content><legend>x x</legend>foo fooo</fieldset>
+<div id=ref-min-content>fooo</div>
+
+<script>
+test(() => {
+ const ref = document.querySelector('#ref-max-content');
+ for (const e of document.querySelectorAll('.max-content')) {
+ assert_equals(e.clientWidth, ref.clientWidth);
+ }
+}, 'max-content');
+
+test(() => {
+ const ref = document.querySelector('#ref-min-content');
+ for (const e of document.querySelectorAll('.min-content')) {
+ assert_equals(e.clientWidth, ref.clientWidth);
+ }
+}, 'min-content');
+</script>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-containing-block-ref.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-containing-block-ref.html
new file mode 100644
index 0000000000..282c0d4ef1
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-containing-block-ref.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<title>Reference for fieldset containing block</title>
+<style>
+p { margin: 0; height: 100px }
+.div1 { position: absolute; top: 108px; width: 100px; height: 100px; background: lime; }
+.div2 { position: absolute; top: 158px; width: 200px; height: 100px; background: lime; }
+</style>
+<p>There should be no red.</p>
+<div class="div1"></div>
+<div class="div2"></div>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-containing-block.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-containing-block.html
new file mode 100644
index 0000000000..cefb3584ea
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-containing-block.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<title>fieldset containing block</title>
+<link rel=match href=fieldset-containing-block-ref.html>
+<style>
+p { margin: 0; height: 100px }
+fieldset { position: relative; border: none; padding: 0; margin: 0; }
+legend { padding: 0; width: 100px; height: 50px; background: lime; }
+div { position: absolute; top: 0; width: 100px; height: 50px; background: lime; }
+.behind { height:100px; top: 108px; background: red; }
+
+.fixed-container {
+ filter: invert();
+ overflow: hidden;
+ width: 200px;
+ height: 200px;
+}
+.fixed {
+ position: fixed;
+ width: 400px;
+ height: 100px;
+ background: linear-gradient(to right, #ff00ff 50%, #00ffff 50%);
+}
+.has-fixed {
+ width: 0px;
+ height: 0px;
+}
+</style>
+<p>There should be no red.</p>
+<div class="behind"></div>
+<fieldset><legend></legend><div></div></fieldset>
+
+<fieldset class="fixed-container">
+<legend class="has-fixed"><div style="position:fixed; width:0; height0;"></div></legend>
+<div class="fixed"></div>
+</fieldset>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-content-before-legend.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-content-before-legend.html
new file mode 100644
index 0000000000..5bd1fbc161
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-content-before-legend.html
@@ -0,0 +1,41 @@
+<!doctype html>
+<title>fieldset content before legend</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<style>
+fieldset {
+ /* Paddings might have fractional values by default, and they can cause
+ rounding differences between the test element and the reference element. */
+ padding: 0;
+}
+</style>
+
+<fieldset id=test>
+ X
+ <legend>legend</legend>
+ Y
+</fieldset>
+<fieldset id=ref>
+ <legend>legend</legend>
+ X Y
+</fieldset>
+
+<fieldset id="test2">
+ P<span id="hidden" style="display:none;">AS</span><legend>legend</legend>S
+</fieldset>
+
+<script>
+ test(() => {
+ const testElm = document.getElementById('test');
+ const refElm = document.getElementById('ref');
+ assert_equals(testElm.clientHeight, refElm.clientHeight);
+ });
+
+ test(() => {
+ const testElm = document.getElementById('test2');
+ testElm.clientHeight;
+ const span = document.getElementById('hidden');
+ span.style.display = 'inline';
+ testElm.clientHeight;
+ }, 'Showing a node just before the rendered legend should not crash');
+</script>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-content-percentage-size.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-content-percentage-size.html
new file mode 100644
index 0000000000..6195d8bb05
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-content-percentage-size.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<link rel="help" href="https://crbug.com/1140595">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<div style="height:100px;">
+ <fieldset style="margin:0; padding:0; border:none;">
+ <div id="inner" style="height:59%;"></div>
+ </fieldset>
+</div>
+<script>
+test(() => {
+ let innerDiv = document.querySelector('#inner');
+ assert_equals(innerDiv.clientHeight, 0);
+}, 'A percentage height for an element in an auto-height fieldset should be ignored');
+</script>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-content-rtl-ref.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-content-rtl-ref.html
new file mode 100644
index 0000000000..b7c080bfac
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-content-rtl-ref.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<html dir="rtl">
+<head>
+<meta charset="utf-8">
+<style>
+.control {
+ background: blue;
+ width: 200px;
+ height: 1em;
+}
+.container {
+ border: 2px groove ThreeDFace;
+ margin: 0;
+ padding: 1em;
+}
+</style>
+</head>
+<body>
+<div class="container">
+ <label>Label</label>
+ <div class="control" id="ctrl-d"></div>
+</div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-content-rtl.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-content-rtl.html
new file mode 100644
index 0000000000..0f12c6f92a
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-content-rtl.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<html dir="rtl">
+<head>
+<meta charset="utf-8">
+<title>crbug.com/1130174; Non-auto-width block should be right-aligned in an RTL fieldset</title>
+<link rel="match" href="fieldset-content-rtl-ref.html">
+<style>
+.control {
+ background: blue;
+ width: 200px;
+ height: 1em;
+}
+fieldset {
+ border: 2px groove ThreeDFace;
+ margin: 0;
+ padding: 1em;
+}
+</style>
+</head>
+<body>
+<fieldset>
+ <label>Label</label>
+ <div class="control"></div>
+</fieldset>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-crash.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-crash.html
new file mode 100644
index 0000000000..111dcbe533
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-crash.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<link rel="help" href="https://crbug.com/1039241">
+<div style="width: min-content;">
+ <div style="writing-mode:vertical-lr;">
+ <fieldset>
+ <div style="width:10%;"></div>
+ </fieldset>
+ </div>
+</div>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-default-style.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-default-style.html
new file mode 100644
index 0000000000..9a711383e6
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-default-style.html
@@ -0,0 +1,57 @@
+<!doctype html>
+<title>fieldset default style</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<style>
+#ref {
+ display: block;
+ margin-left: 2px;
+ margin-right: 2px;
+ /* TODO replace above declarations with these when they are widely supported.
+ margin-inline-start: 2px;
+ margin-inline-end: 2px;
+ */
+ border: groove 2px;
+ padding: 0.35em 0.75em 0.625em 0.75em;
+ /* TODO replace above declarations with these when they are widely supported.
+ padding-block-start: 0.35em;
+ padding-inline-end: 0.75em;
+ padding-block-end: 0.625em;
+ padding-inline-start: 0.75em;
+ */
+ min-width: min-content;
+ /* TODO change the above to min-inline-size when it's widely supported. */
+}
+</style>
+<fieldset id=test></fieldset>
+<div id=ref></div>
+<script>
+ const testElm = document.querySelector('#test');
+ const refElm = document.querySelector('#ref');
+ const props = ['display',
+ 'margin-top',
+ 'margin-right',
+ 'margin-bottom',
+ 'margin-left',
+ 'border-top-style',
+ 'border-right-style',
+ 'border-bottom-style',
+ 'border-left-style',
+ 'border-top-width',
+ 'border-right-width',
+ 'border-bottom-width',
+ 'border-left-width',
+ 'padding-top',
+ 'padding-right',
+ 'padding-bottom',
+ 'padding-left',
+ 'min-width',
+ ];
+ const testStyle = getComputedStyle(testElm);
+ const refStyle = getComputedStyle(refElm);
+ props.forEach(prop => {
+ test(() => {
+ assert_equals(testStyle[prop], refStyle[prop]);
+ }, `${prop}`);
+ });
+</script>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-display.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-display.html
new file mode 100644
index 0000000000..a8a553c836
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-display.html
@@ -0,0 +1,37 @@
+<!doctype html>
+<title>fieldset and CSS display</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<style>
+ #inline-ref { display: inline-block; }
+</style>
+<fieldset id="block-ref">x</fieldset>
+<fieldset id="inline-ref">x</fieldset>
+<fieldset id="test">x</fieldset>
+<script>
+ const blockWidth = getComputedStyle(document.querySelector('#block-ref')).width;
+ const inlineWidth = getComputedStyle(document.querySelector('#inline-ref')).width;
+ const testElm = document.querySelector('#test');
+ // Please only add canonical values to these lists:
+ const blocks = ['block', 'table', 'table-row-group', 'table-header-group', 'table-footer-group', 'table-row', 'table-cell',
+ 'table-column-group', 'table-column', 'table-caption', 'list-item', 'flow-root', 'run-in', 'block ruby'];
+ const inlines = ['inline', 'inline-block', 'inline-table', 'ruby', 'ruby-base', 'ruby-text', 'ruby-base-container', 'ruby-text-container'];
+
+ function test_display(val, expectedWidth) {
+ test(() => {
+ testElm.style.removeProperty('display');
+ testElm.style.display = val;
+ const computed = getComputedStyle(testElm);
+ assert_equals(computed.display, val, `display: ${val} is not supported`);
+ assert_equals(computed.width, expectedWidth);
+ }, `fieldset with display: ${val}`);
+ }
+
+ for (const val of blocks) {
+ test_display(val, blockWidth);
+ }
+
+ for (const val of inlines) {
+ test_display(val, inlineWidth);
+ }
+</script>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-div-display-contents.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-div-display-contents.html
new file mode 100644
index 0000000000..5d17b91290
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-div-display-contents.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<title>fieldset and div with display: contents</title>
+<link rel=fieldset-foo-ref.html>
+<style>
+div { display: contents; }
+</style>
+<p>There should be a normal fieldset below with the legend "Foo".</p>
+<fieldset>
+ <div>
+ <legend>Foo</legend>
+ </div>
+</fieldset>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-dynamic-baseline-ref.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-dynamic-baseline-ref.html
new file mode 100644
index 0000000000..c34096f270
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-dynamic-baseline-ref.html
@@ -0,0 +1,7 @@
+<!DOCTYPE html>
+baseline
+<fieldset style="display: inline-block;">
+ <div style="position: relative;">
+ line1<br>line2
+ </div>
+</fieldset>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-dynamic-baseline.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-dynamic-baseline.html
new file mode 100644
index 0000000000..88aeed28c1
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-dynamic-baseline.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1307140">
+<link rel="match" href="fieldset-dynamic-baseline-ref.html">
+baseline
+<fieldset style="display: inline-block;">
+ <div style="position: relative;">
+ line1<br>line2<div id="target" style="position: absolute;"></div>
+ </div>
+</fieldset>
+<script>
+document.body.offsetTop;
+document.getElementById('target').style.top = '10px';
+</script>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-dynamic-oof-container-crash.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-dynamic-oof-container-crash.html
new file mode 100644
index 0000000000..a2b999fa00
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-dynamic-oof-container-crash.html
@@ -0,0 +1,46 @@
+<!DOCTYPE html>
+<html class="test-wait">
+<title>No crash after stop being an asbolute container.</title>
+<link rel="help" href="https://crbug.com/1395688">
+<style>
+.c2 {
+ transform: rotate3d(0, 1, 0, 45deg);
+ column-width: 100px;
+}
+.c19 {
+ overflow: auto;
+ padding-left: 65536px;
+ column-count: 3;
+}
+
+q {
+ position: absolute;
+ column-width: 1px;
+}
+
+body {
+ column-count: 3;
+}
+</style>
+<script>
+function animationFrame() {
+ return new Promise(resolve => requestAnimationFrame(resolve));
+}
+
+async function doTest() {
+ document.documentElement.appendChild(document.createElement('body'));
+ await animationFrame();
+ document.body.innerHTML = '<fieldset class=c2><q>q</q></fieldset>';
+ window.scrollBy(28, 71);
+ await animationFrame();
+ document.querySelector('fieldset').setAttribute('class', 'c19');
+ await animationFrame();
+ document.body.remove();
+ await animationFrame();
+ await animationFrame();
+ document.documentElement.classList.remove('test-wait');
+}
+
+doTest();
+</script>
+</html>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-dynamic-pseudo-ref.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-dynamic-pseudo-ref.html
new file mode 100644
index 0000000000..5bdf78db55
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-dynamic-pseudo-ref.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<html>
+<head>
+<style>
+*::after { content:"after text"; border:3px solid black;}
+*::before { content:"before text"; border:3px solid black; }
+</style>
+</head>
+<body>
+<fieldset><legend>Legend</legend></fielset>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-dynamic-pseudo.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-dynamic-pseudo.html
new file mode 100644
index 0000000000..c5fbf53000
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-dynamic-pseudo.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<!--
+Chrome had a crash bug in a case of dynamic addition of pseudo elements.
+crbug.com/1242229
+-->
+<html class="reftest-wait">
+<head>
+<link rel="match" href="fieldset-dynamic-pseudo-ref.html">
+<style>
+*::after { content:"after text"; border:3px solid black;}
+*::before { content:"before text"; border:3px solid black; }
+</style>
+</head>
+<body>
+<fieldset><legend>Legend</legend></fielset>
+<script>
+document.styleSheets[0].disabled = true;
+
+requestAnimationFrame(() => {
+ requestAnimationFrame(() => {
+ document.styleSheets[0].disabled = false;
+ document.documentElement.className = '';
+ });
+});
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-flexbox.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-flexbox.html
new file mode 100644
index 0000000000..9e1c9ed152
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-flexbox.html
@@ -0,0 +1,95 @@
+<!DOCTYPE html>
+<title>fieldset and CSS Flexbox</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<style>
+#test, #ref, #test-inline, #ref-inline {
+ display: flex;
+ justify-content: space-around;
+ margin: 0;
+ padding: 0;
+ border: none
+}
+#test-inline, #ref-inline { display: inline-flex }
+legend {
+ float: left; /* Makes it not the "rendered legend" */
+ padding: 0;
+}
+</style>
+<fieldset id=test>
+ <legend>1</legend>
+ <div>2</div>
+ <div>3</div>
+ <div>4</div>
+ <div>5</div>
+ <div>6</div>
+ <div>7</div>
+ <div>8</div>
+ <div>9</div>
+</fieldset>
+<hr>
+<div id=ref>
+ <legend>1</legend>
+ <div>2</div>
+ <div>3</div>
+ <div>4</div>
+ <div>5</div>
+ <div>6</div>
+ <div>7</div>
+ <div>8</div>
+ <div>9</div>
+</div>
+<hr>
+<fieldset id=test-inline>
+ <legend>1</legend>
+ <div>2</div>
+ <div>3</div>
+ <div>4</div>
+ <div>5</div>
+ <div>6</div>
+ <div>7</div>
+ <div>8</div>
+ <div>9</div>
+</fieldset>
+<div id=ref-inline>
+ <div>1</div>
+ <div>2</div>
+ <div>3</div>
+ <div>4</div>
+ <div>5</div>
+ <div>6</div>
+ <div>7</div>
+ <div>8</div>
+ <div>9</div>
+</div>
+<script>
+ test(() => {
+ const testElm = document.getElementById('test');
+ const refElm = document.getElementById('ref');
+ assert_equals(getComputedStyle(testElm).height,
+ getComputedStyle(refElm).height, 'height');
+ assert_equals(testElm.querySelector('legend').offsetTop,
+ testElm.querySelector('div').offsetTop, 'offsetTop')
+ }, "Flex");
+
+ test(() => {
+ const testElm = document.getElementById('test-inline');
+ const refElm = document.getElementById('ref-inline');
+ assert_equals(getComputedStyle(testElm).height,
+ getComputedStyle(refElm).height, 'height');
+ assert_equals(testElm.querySelector('legend').offsetTop,
+ testElm.querySelector('div').offsetTop, 'offsetTop')
+
+ }, "Inline flex");
+
+test(() => {
+ const testElm = document.getElementById('test');
+ testElm.style.flexDirection = 'row';
+ const item0 = testElm.querySelectorAll('div')[0];
+ const item1 = testElm.querySelectorAll('div')[1];
+ assert_equals(item0.offsetTop, item1.offsetTop);
+
+ testElm.style.flexDirection = 'column';
+ assert_true(item0.offsetTop < item1.offsetTop);
+}, "Dynamic change of flex-direction");
+</script>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-foo-ref.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-foo-ref.html
new file mode 100644
index 0000000000..cace814a8c
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-foo-ref.html
@@ -0,0 +1,6 @@
+<!DOCTYPE html>
+<title>Reference with a fieldset and legend "Foo"</title>
+<p>There should be a normal fieldset below with the legend "Foo".</p>
+<fieldset>
+ <legend>Foo</legend>
+</fieldset>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-generated-content.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-generated-content.html
new file mode 100644
index 0000000000..25a36bc42c
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-generated-content.html
@@ -0,0 +1,30 @@
+<!doctype html>
+<title>fieldset generated content</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<link rel="stylesheet" href="/fonts/ahem.css">
+<style>
+body {
+ /* Use Ahem to avoid fractional letter widths. */
+ font: 20px/1 Ahem;
+}
+
+fieldset {
+ display: inline-block;
+ /* Paddings might have fractional values by default, and they can cause
+ rounding differences between the test element and the reference element. */
+ padding: 0;
+}
+
+#test::before, #test::after { content:"X"; }
+</style>
+<fieldset id=test><legend>A</legend>Y</fieldset>
+<fieldset id=ref><legend>A</legend>XYX</fieldset>
+<script>
+test(() => {
+ const testElm = document.querySelector('#test');
+ const refElm = document.querySelector('#ref');
+ assert_equals(testElm.clientWidth, refElm.clientWidth, 'clientWidth');
+ assert_equals(testElm.clientHeight, refElm.clientHeight, 'clientHeight');
+});
+</script>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-grid.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-grid.html
new file mode 100644
index 0000000000..bbb71dfa70
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-grid.html
@@ -0,0 +1,85 @@
+<!DOCTYPE html>
+<title>fieldset and CSS Grid</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<style>
+#test, #ref, #test-inline, #ref-inline {
+ display: grid;
+ grid-template-columns: auto 50px auto;
+ grid-template-rows: auto 50px auto;
+ margin: 0;
+ padding: 0;
+ border: none
+}
+#test-inline, #ref-inline { display: inline-grid }
+legend {
+ float: left; /* Makes it not the "rendered legend" */
+ padding: 0;
+}
+</style>
+<fieldset id=test>
+ <legend>1</legend>
+ <div>2</div>
+ <div>3</div>
+ <div>4</div>
+ <div>5</div>
+ <div>6</div>
+ <div>7</div>
+ <div>8</div>
+ <div>9</div>
+</fieldset>
+<hr>
+<div id=ref>
+ <div>1</div>
+ <div>2</div>
+ <div>3</div>
+ <div>4</div>
+ <div>5</div>
+ <div>6</div>
+ <div>7</div>
+ <div>8</div>
+ <div>9</div>
+</div>
+<hr>
+<fieldset id=test-inline>
+ <legend>1</legend>
+ <div>2</div>
+ <div>3</div>
+ <div>4</div>
+ <div>5</div>
+ <div>6</div>
+ <div>7</div>
+ <div>8</div>
+ <div>9</div>
+</fieldset>
+<div id=ref-inline>
+ <div>1</div>
+ <div>2</div>
+ <div>3</div>
+ <div>4</div>
+ <div>5</div>
+ <div>6</div>
+ <div>7</div>
+ <div>8</div>
+ <div>9</div>
+</div>
+<script>
+ test(() => {
+ const testElm = document.getElementById('test');
+ const refElm = document.getElementById('ref');
+ assert_equals(getComputedStyle(testElm).height,
+ getComputedStyle(refElm).height, 'height');
+ assert_equals(testElm.querySelector('legend').offsetTop,
+ testElm.querySelector('div').offsetTop, 'offsetTop')
+ }, "Grid");
+
+ test(() => {
+ const testElm = document.getElementById('test-inline');
+ const refElm = document.getElementById('ref-inline');
+ assert_equals(getComputedStyle(testElm).height,
+ getComputedStyle(refElm).height, 'height');
+ assert_equals(testElm.querySelector('legend').offsetTop,
+ testElm.querySelector('div').offsetTop, 'offsetTop')
+
+ }, "Inline grid");
+</script>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-list-item-ref.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-list-item-ref.html
new file mode 100644
index 0000000000..05b8ca4770
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-list-item-ref.html
@@ -0,0 +1,9 @@
+<!doctype html>
+<title>Reference for fieldset and dipslay: list-item</title>
+<style>
+ fieldset { margin: 0 40px; }
+</style>
+<p>There should be no bullet points below.</p>
+<fieldset>
+ <legend>X</legend>
+</fieldset>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-list-item.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-list-item.html
new file mode 100644
index 0000000000..7726947bec
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-list-item.html
@@ -0,0 +1,10 @@
+<!doctype html>
+<title>fieldset and dipslay: list-item</title>
+<link rel=match href=fieldset-list-item-ref.html>
+<style>
+ fieldset { margin: 0 40px; display: list-item; }
+</style>
+<p>There should be no bullet points below.</p>
+<fieldset>
+ <legend>X</legend>
+</fieldset>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-max-block-size-ref.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-max-block-size-ref.html
new file mode 100644
index 0000000000..07c9da85b5
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-max-block-size-ref.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<style>
+.fieldset {
+ border: 2px solid gray;
+ margin: 1em;
+ padding: 0;
+ width: 20em;
+}
+
+.f1 {
+ overflow: auto;
+ max-height: 3em;
+}
+.f2 {
+ max-height: 0;
+}
+</style>
+
+<div class="fieldset f1">
+<div>foo</div>
+<div>foo</div>
+<div>foo</div>
+<div>foo</div>
+<div>foo</div>
+</div>
+
+<div class="fieldset f1">
+<div>foo</div>
+</div>
+
+<div class="fieldset f2">
+<div>foo</div>
+</div>
+
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-max-block-size.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-max-block-size.html
new file mode 100644
index 0000000000..170dedd606
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-max-block-size.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<link rel="help" href="http://crbug.com/1151858">
+<link rel="match" href="fieldset-max-block-size-ref.html">
+<style>
+fieldset {
+ border: 2px solid gray;
+ margin: 1em;
+ padding: 0;
+ width: 20em;
+}
+
+.f1 {
+ overflow: auto;
+ max-height: 3em;
+}
+.f2 {
+ max-height: 0;
+}
+</style>
+
+<fieldset class="f1">
+<div>foo</div>
+<div>foo</div>
+<div>foo</div>
+<div>foo</div>
+<div>foo</div>
+</fieldset>
+
+<fieldset class="f1">
+<div>foo</div>
+</fieldset>
+
+<fieldset class="f2">
+<div>foo</div>
+</fieldset>
+
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-multicol.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-multicol.html
new file mode 100644
index 0000000000..bdb2c2fd94
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-multicol.html
@@ -0,0 +1,29 @@
+<!doctype html>
+<title>fieldset multicol</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<style>
+ #test { margin: 0; padding: 0; border: none }
+ #test, #ref { columns: 5 }
+ p { margin: 0 }
+</style>
+<fieldset id=test>
+ <p>1
+ <p>2
+ <p>3
+ <p>4
+ <p>5
+</fieldset>
+<div id=ref>
+ <p>1
+ <p>2
+ <p>3
+ <p>4
+ <p>5
+</div>
+<script>
+ test(() => {
+ assert_equals(getComputedStyle(document.getElementById('test')).height,
+ getComputedStyle(document.getElementById('ref')).height);
+ });
+</script>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-overflow-cssomview.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-overflow-cssomview.html
new file mode 100644
index 0000000000..c47c7cdd5d
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-overflow-cssomview.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<style>
+fieldset {
+ height: 200px;
+ overflow: scroll;
+ padding: 0;
+}
+
+.content {
+ height: 400px;
+}
+</style>
+
+<fieldset>
+ <legend>Legend</legend>
+ <div class="content"></div>
+</fieldset>
+
+<script>
+test(() => {
+ const fieldset = document.querySelector('fieldset');
+ assert_equals(getComputedStyle(fieldset)['overflow-x'], 'scroll');
+ assert_equals(getComputedStyle(fieldset)['overflow-y'], 'scroll');
+ assert_equals(fieldset.scrollHeight, 400);
+ fieldset.scrollTop = 500;
+ assert_greater_than_equal(fieldset.scrollTop, 200);
+}, 'Test cssom-view API for FIELDSET');
+</script>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-overflow-hidden-ref.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-overflow-hidden-ref.html
new file mode 100644
index 0000000000..9fe632f7c2
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-overflow-hidden-ref.html
@@ -0,0 +1,4 @@
+<!DOCTYPE html>
+<title>Reference for fieldset and overflow</title>
+<p>It should say PASS below.</p>
+PASS
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-overflow-hidden.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-overflow-hidden.html
new file mode 100644
index 0000000000..cacbdbae00
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-overflow-hidden.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<title>fieldset and overflow</title>
+<link rel=match href=fieldset-overflow-hidden-ref.html>
+<style>
+fieldset { margin:0; padding: 0; overflow: hidden; border: none; border-top: 1em solid transparent; }
+legend { padding: 0; }
+</style>
+<p>It should say PASS below.</p>
+<fieldset>
+ <legend>PASS</legend>
+</fieldset>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-overflow-ref.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-overflow-ref.html
new file mode 100644
index 0000000000..42ecb22aef
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-overflow-ref.html
@@ -0,0 +1,64 @@
+<!DOCTYPE HTML>
+<title>Reference for fieldset overflow</title>
+<style>
+.fieldset, .legend {
+ border: 1em solid;
+ background: lime;
+}
+.fieldset {
+ height: 1em;
+ margin-top: 2em;
+}
+.legend {
+ height: 1em;
+ width: 5em;
+ line-height: 1;
+ margin-top: -4em;
+ margin-left: 1em;
+ margin-bottom: 1em;
+}
+
+.fieldset2 {
+ background: lime;
+ padding: 50px;
+ max-height: 50px;
+ overflow: scroll;
+}
+
+.fieldset3 {
+ width: 20em;
+ max-height: 250px;
+ padding: 7px;
+ margin: 0;
+ overflow: auto;
+ box-sizing: border-box;
+ border: 1em solid transparent;
+ border-top: 40px solid transparent;
+}
+</style>
+<p>There should be no red.</p>
+<div class=fieldset>
+</div>
+<div class=legend></div>
+
+<div class=fieldset2>
+ <div style="height:200px; background:blue"></div>
+</div>
+
+<div class="fieldset3">
+ <p>
+The quick brown fox jumps over the lazy dog.
+The quick brown fox jumps over the lazy dog.
+The quick brown fox jumps over the lazy dog.
+The quick brown fox jumps over the lazy dog.
+The quick brown fox jumps over the lazy dog.
+The quick brown fox jumps over the lazy dog.
+The quick brown fox jumps over the lazy dog.
+The quick brown fox jumps over the lazy dog.
+The quick brown fox jumps over the lazy dog.
+The quick brown fox jumps over the lazy dog.
+The quick brown fox jumps over the lazy dog.
+The quick brown fox jumps over the lazy dog.
+The quick brown fox jumps over the lazy dog.
+ </p>
+</div>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-overflow.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-overflow.html
new file mode 100644
index 0000000000..83813f9020
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-overflow.html
@@ -0,0 +1,82 @@
+<!DOCTYPE HTML>
+<title>fieldset overflow</title>
+<link rel=match href=fieldset-overflow-ref.html>
+<style>
+fieldset, legend {
+ border: 1em solid;
+ margin: 0;
+ padding: 0;
+ background: lime
+}
+#f1 {
+ overflow: auto;
+ height: 2em;
+}
+legend {
+ height: 1em;
+ width: 5em;
+}
+div {
+ background: red;
+ height: 2em;
+}
+
+#f2 {
+ border: none;
+ padding: 50px;
+ max-height: 50px;
+ overflow: scroll;
+}
+
+#f3 {
+ width: 20em;
+ max-height: 250px;
+ padding: 7px;
+ overflow: auto;
+ box-sizing: border-box;
+ border-color: transparent;
+ background: transparent;
+}
+
+#f3 legend {
+ height: 40px;
+ border: none;
+ color: transparent;
+ background: transparent;
+}
+</style>
+<p>There should be no red.</p>
+<fieldset id="f1">
+ <legend></legend>
+ <div></div>
+ <div id=last></div>
+</fieldset>
+
+<!-- crbug.com/1247733 -->
+<fieldset id="f2">
+ <div style="height:200px; background:blue"></div>
+</fieldset>
+<script>
+ document.getElementById('last').scrollIntoView();
+</script>
+
+<!-- crbug.com/1282408 -->
+<fieldset id="f3">
+ <legend>Legend</legend>
+ <p>
+The quick brown fox jumps over the lazy dog.
+The quick brown fox jumps over the lazy dog.
+The quick brown fox jumps over the lazy dog.
+The quick brown fox jumps over the lazy dog.
+The quick brown fox jumps over the lazy dog.
+The quick brown fox jumps over the lazy dog.
+The quick brown fox jumps over the lazy dog.
+The quick brown fox jumps over the lazy dog.
+The quick brown fox jumps over the lazy dog.
+The quick brown fox jumps over the lazy dog.
+The quick brown fox jumps over the lazy dog.
+The quick brown fox jumps over the lazy dog.
+The quick brown fox jumps over the lazy dog.
+ </p>
+</fieldset>
+
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-painting-order-ref.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-painting-order-ref.html
new file mode 100644
index 0000000000..13b262a804
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-painting-order-ref.html
@@ -0,0 +1,10 @@
+<!doctype html>
+<title>Reference for fieldset painting order</title>
+<style>
+div { width: 200px; height: 200px; }
+#a { background: green; }
+#b { background: lime; position: relative; top: -100px; left: 100px; }
+</style>
+<p>There should be no red.</p>
+<div id=a></div>
+<div id=b></div>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-painting-order.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-painting-order.html
new file mode 100644
index 0000000000..7bd2cedb1b
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-painting-order.html
@@ -0,0 +1,17 @@
+<!doctype html>
+<title>fieldset painting order</title>
+<link rel=match href=fieldset-painting-order-ref.html>
+<style>
+fieldset, legend { margin: 0; padding: 0; }
+fieldset {
+ border: 100px solid red;
+ width: 0;
+ min-width: 0;
+ height: 0;
+}
+legend { width: 200px; height: 200px; margin-left: -100px; background: green; }
+legend > span { float: right; margin-top: 100px; width: 100px; height: 100px; background: red; }
+fieldset > div { margin-top: -100px; background: lime; width: 200px; height: 200px; }
+</style>
+<p>There should be no red.</p>
+<fieldset><legend><span></span></legend><div></div></fieldset>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-percentage-block-size.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-percentage-block-size.html
new file mode 100644
index 0000000000..e98de892d3
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-percentage-block-size.html
@@ -0,0 +1,64 @@
+<!doctype html>
+<title>fieldset percentage block size</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<style>
+ fieldset { block-size: 100px; margin: 20px; padding: 0; border: 10px solid; }
+ .rendered-legend { block-size: 80%; background: lime; padding: 0; }
+ .second-legend { block-size: 100%; background: yellow; padding: 0; }
+ fieldset > div { block-size: 100%; background: fuchsia; }
+</style>
+<div style="writing-mode: horizontal-tb">
+ <fieldset>
+ <legend class="rendered-legend">rendered legend</legend>
+ <legend class="second-legend">second legend</legend>
+ <div>div</div>
+ </fieldset>
+</div>
+
+<div style="writing-mode: vertical-lr">
+ <fieldset>
+ <legend class="rendered-legend">rendered legend</legend>
+ <legend class="second-legend">second legend</legend>
+ <div>div</div>
+ </fieldset>
+</div>
+
+<div style="writing-mode: vertical-rl">
+ <fieldset>
+ <legend class="rendered-legend">rendered legend</legend>
+ <legend class="second-legend">second legend</legend>
+ <div>div</div>
+ </fieldset>
+</div>
+
+<table cellspacing="0" cellpadding="0" style="width:100px; height:60px;">
+ <tr>
+ <td>
+ <fieldset style="border:none; padding:0; height:100%; margin:0; margin-top:13px;">
+ <div><div id="elm"></div></div>
+ </fieldset>
+ </td>
+ </tr>
+</table>
+
+<script>
+ for (const div of document.querySelectorAll('div[style]')) {
+ for (const el of div.firstElementChild.children) {
+ test(() => {
+ const expected = el.textContent === 'rendered legend' ? '80px' : '30px';
+ // 30px because: 100px - (max(0, legend-block-size - border-block-start))
+ assert_equals(getComputedStyle(el).blockSize, expected);
+ }, `${el.textContent} (${div.getAttribute('style')})`);
+ }
+ }
+
+// crbug.com/1138204. Though the specification doesn't mention this behavior,
+// there must be no doubt about the expected behavior.
+test(() => {
+ const fieldset = document.querySelector('table fieldset');
+ const initialHeight = fieldset.offsetHeight;
+ document.querySelector('#elm').style.display = 'none';
+ assert_equals(fieldset.offsetHeight, initialHeight);
+}, 'Fieldset with a percentage height should not increase the height on every reflow.');
+</script>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-percentage-padding.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-percentage-padding.html
new file mode 100644
index 0000000000..61ad4ed4c9
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-percentage-padding.html
@@ -0,0 +1,31 @@
+<!doctype html>
+<title>fieldset percentage padding</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<style>
+ body { margin: 0; }
+ .outer { width: 500px; position: relative; }
+ fieldset { width: 100px; padding: 10%; margin: 0; border: none; }
+ .overflow { overflow: auto; }
+</style>
+<div class=outer>
+ <fieldset>
+ <div id=no-overflow>x</div>
+ </fieldset>
+</div>
+<div class=outer>
+ <fieldset class=overflow>
+ <div id=with-overflow>x</div>
+ </fieldset>
+</div>
+<script>
+const noOverflow = document.getElementById('no-overflow');
+const withOverflow = document.getElementById('with-overflow');
+for (const div of [noOverflow, withOverflow]) {
+ test(() => {
+ assert_equals(div.offsetLeft, 50, "offsetLeft");
+ assert_equals(div.clientWidth, 100, "clientWidth");
+ assert_equals(div.offsetTop, 50, "offsetTop");
+ }, div.id);
+}
+</script>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-resize-ref.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-resize-ref.html
new file mode 100644
index 0000000000..e77bb69d7f
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-resize-ref.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<title>CSS Test Reference</title>
+<style>
+ div {
+ border: 1px solid;
+ padding: 10px;
+ resize: both;
+ overflow: scroll;
+ width: 100px;
+ height: 100px;
+ }
+</style>
+<div></div>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-resize.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-resize.html
new file mode 100644
index 0000000000..6a34a7465c
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-resize.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<title>resize property on fieldset</title>
+<link rel="match" href="fieldset-resize-ref.html">
+<style>
+ fieldset {
+ margin: 0;
+ border: 1px solid;
+ padding: 10px;
+ resize: both;
+ overflow: scroll;
+ width: 100px;
+ height: 100px;
+ }
+</style>
+<fieldset></fieldset>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-shadow-dom.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-shadow-dom.html
new file mode 100644
index 0000000000..3b46eb03c6
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-shadow-dom.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<title>fieldset and shadow DOM</title>
+<link rel=fieldset-foo-ref.html>
+<p>There should be a normal fieldset below with the legend "Foo".</p>
+<template id="my-fieldset">
+ <fieldset><slot name="my-text"></slot></fieldset>
+</template>
+
+<my-fieldset>
+ <legend slot="my-text">Foo</legend>
+</my-fieldset>
+
+<script>
+customElements.define('my-fieldset',
+ class extends HTMLElement {
+ constructor() {
+ super();
+
+ const template = document.getElementById('my-fieldset');
+ const templateContent = template.content;
+
+ this.attachShadow({mode: 'open'}).appendChild(
+ templateContent.cloneNode(true)
+ );
+ }
+ }
+);
+</script>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-transform-translatez-ref.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-transform-translatez-ref.html
new file mode 100644
index 0000000000..8200e67194
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-transform-translatez-ref.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<title>Reference for Fieldset and transform: translateZ(0)</title>
+<style>
+fieldset { background: #eee; margin: 0 0 10px; }
+</style>
+<p>It should say PASS below without anything obscuring the text.</p>
+
+<fieldset>
+ <legend>PASS</legend>
+</fieldset>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-transform-translatez.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-transform-translatez.html
new file mode 100644
index 0000000000..df30468b00
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-transform-translatez.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<title>Fieldset and transform: translateZ(0)</title>
+<link rel=match href=fieldset-transform-translatez-ref.html>
+<style>
+#outer { transform: translateZ(0); }
+fieldset { background: #eee; overflow: hidden; margin: 0 0 10px; }
+#inner { position: relative; }
+</style>
+<p>It should say PASS below without anything obscuring the text.</p>
+<div id=outer>
+ <fieldset>
+ <legend>
+ <div id="inner">PASS</div>
+ </legend>
+ </fieldset>
+</div>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-vertical-ref.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-vertical-ref.html
new file mode 100644
index 0000000000..29c28ea5f8
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-vertical-ref.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<title>Reference for fieldset vertical</title>
+<link rel=stylesheet href=resources/fieldset-vertical.css>
+<p>vertical-lr
+<div style="writing-mode: vertical-lr">
+ <div class=fieldset><div class="legend top">foo bar</div>normal</div>
+ <div class="fieldset rtl"><div class="legend bottom">foo bar</div>dir=rtl</div>
+ <div class="fieldset rtl"><div class="legend top">foo bar</div>dir=rtl align=left</div>
+ <div class="fieldset rtl"><div class="legend center">foo bar</div>dir=rtl align=center</div>
+ <div class="fieldset rtl"><div class="legend bottom">foo bar</div>dir=rtl align=right</div>
+ <div class=fieldset><div class="legend top">foo bar</div>align=left</div>
+ <div class=fieldset><div class="legend center">foo bar</div>align=center</div>
+ <div class=fieldset><div class="legend bottom">foo bar</div>align=right</div>
+</div>
+<hr>
+<p>vertical-rl
+<div style="writing-mode: vertical-rl">
+ <div class=fieldset><div class="legend top">foo bar</div>normal</div>
+ <div class="fieldset rtl"><div class="legend bottom">foo bar</div>dir=rtl</div>
+ <div class="fieldset rtl"><div class="legend top">foo bar</div>dir=rtl align=left</div>
+ <div class="fieldset rtl"><div class="legend center">foo bar</div>dir=rtl align=center</div>
+ <div class="fieldset rtl"><div class="legend bottom">foo bar</div>dir=rtl align=right</div>
+ <div class=fieldset><div class="legend top">foo bar</div>align=left</div>
+ <div class=fieldset><div class="legend center">foo bar</div>align=center</div>
+ <div class=fieldset><div class="legend bottom">foo bar</div>align=right</div></div>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-vertical.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-vertical.html
new file mode 100644
index 0000000000..c11b466669
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/fieldset-vertical.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<title>fieldset vertical</title>
+<link rel=stylesheet href=resources/fieldset-vertical.css>
+<link rel=match href=fieldset-vertical-ref.html>
+<p>vertical-lr
+<div style="writing-mode: vertical-lr">
+ <fieldset><legend>foo bar</legend>normal</fieldset>
+ <fieldset dir=rtl><legend>foo bar</legend>dir=rtl</fieldset>
+ <fieldset dir=rtl><legend align=left>foo bar</legend>dir=rtl align=left</fieldset>
+ <fieldset dir=rtl><legend align=center>foo bar</legend>dir=rtl align=center</fieldset>
+ <fieldset dir=rtl><legend align=right>foo bar</legend>dir=rtl align=right</fieldset>
+ <fieldset><legend align=left>foo bar</legend>align=left</fieldset>
+ <fieldset><legend align=center>foo bar</legend>align=center</fieldset>
+ <fieldset><legend align=right>foo bar</legend>align=right</fieldset>
+</div>
+<hr>
+<p>vertical-rl
+<div style="writing-mode: vertical-rl">
+ <fieldset><legend>foo bar</legend>normal</fieldset>
+ <fieldset dir=rtl><legend>foo bar</legend>dir=rtl</fieldset>
+ <fieldset dir=rtl><legend align=left>foo bar</legend>dir=rtl align=left</fieldset>
+ <fieldset dir=rtl><legend align=center>foo bar</legend>dir=rtl align=center</fieldset>
+ <fieldset dir=rtl><legend align=right>foo bar</legend>dir=rtl align=right</fieldset>
+ <fieldset><legend align=left>foo bar</legend>align=left</fieldset>
+ <fieldset><legend align=center>foo bar</legend>align=center</fieldset>
+ <fieldset><legend align=right>foo bar</legend>align=right</fieldset>
+</div>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/flex-legend-float-abspos.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/flex-legend-float-abspos.html
new file mode 100644
index 0000000000..f6eead471c
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/flex-legend-float-abspos.html
@@ -0,0 +1,97 @@
+<!doctype html>
+<title>
+ legend and float and position: absolute/fixed when the display type of
+ the fieldset is flex.
+</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<style>
+ body { margin: 0; }
+ fieldset {
+ border: 10px solid;
+ display: flex;
+ margin: 0;
+ padding: 20px;
+ width: 300px;
+ }
+ legend { height: 10px; }
+ #legend1 { float: left; }
+ #legend2 { float: right; }
+ #legend3 { position: absolute; }
+ #legend4 { position: fixed; }
+</style>
+<fieldset id=fieldset>
+ <div>div</div>
+ <legend id=legend1>legend1</legend>
+ <legend id=legend2>legend2</legend>
+ <legend id=legend3>legend3</legend>
+ <legend id=legend4>legend4</legend>
+ <legend id=legend5>legend5</legend>
+</fieldset>
+<script>
+ const fieldset = document.getElementById('fieldset');
+ const legends = document.getElementsByTagName('legend');
+ const [legend1, legend2, legend3, legend4, legend5] = legends;
+ const expectedTop = 0;
+ const expectedLeft = 10 + 20;
+
+ function assert_rendered_legend(legend) {
+ assert_equals(legend.offsetTop, expectedTop, `${legend.id}.offsetTop`);
+ assert_equals(legend.offsetLeft, expectedLeft, `${legend.id}.offsetLeft`);
+ for (const other of legends) {
+ if (other === legend) {
+ continue;
+ }
+ if (other.offsetTop === expectedTop && other.offsetLeft === expectedLeft) {
+ assert_unreached(`${other.id} should not be the "rendered legend"`);
+ }
+ }
+ }
+
+ test(t => {
+ assert_rendered_legend(legend5);
+ }, 'no dynamic changes');
+
+ test(t => {
+ const legend = document.createElement('legend');
+ t.add_cleanup(() => {
+ legend.remove();
+ });
+ legend.id = 'script-inserted';
+ legend.textContent = 'script-inserted legend';
+ fieldset.insertBefore(legend, legend1);
+ assert_rendered_legend(legend);
+ legend.remove();
+ assert_rendered_legend(legend5);
+ }, 'inserting a new legend and removing it again');
+
+ test(t => {
+ t.add_cleanup(() => {
+ legend1.id = 'legend1';
+ legend2.id = 'legend2';
+ });
+ legend2.id = '';
+ assert_rendered_legend(legend2);
+ legend1.id = '';
+ assert_rendered_legend(legend1);
+ legend1.id = 'legend1';
+ assert_rendered_legend(legend2);
+ legend2.id = 'legend2';
+ assert_rendered_legend(legend5);
+ }, 'dynamic changes to float');
+
+ test(t => {
+ t.add_cleanup(() => {
+ legend3.id = 'legend3';
+ legend4.id = 'legend4';
+ });
+ legend4.id = '';
+ assert_rendered_legend(legend4);
+ legend3.id = '';
+ assert_rendered_legend(legend3);
+ legend3.id = 'legend3';
+ assert_rendered_legend(legend4);
+ legend4.id = 'legend4';
+ assert_rendered_legend(legend5);
+ }, 'dynamic changes to position');
+</script>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/grid-template-propagation-ref.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/grid-template-propagation-ref.html
new file mode 100644
index 0000000000..954bcab573
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/grid-template-propagation-ref.html
@@ -0,0 +1,3 @@
+<!DOCTYPE html>
+<p>There should be a green box below.</p>
+<div style="background: green; width: 100px; height: 100px;"></div>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/grid-template-propagation.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/grid-template-propagation.html
new file mode 100644
index 0000000000..aa51ebac62
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/grid-template-propagation.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<link rel="match" href="grid-template-propagation-ref.html">
+<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1222988">
+<link rel="help" href="https://html.spec.whatwg.org/C/#anonymous-fieldset-content-box">
+<style>
+fieldset {
+ display: grid;
+ grid-template: auto / 1fr;
+ grid-template-areas: "a";
+ width: 100px;
+ height: 100px;
+ margin: 0;
+ border: none;
+ padding: 0;
+}
+</style>
+<p>There should be a green box below.</p>
+<fieldset>
+ <div style="background: green; grid-area: a"></div>
+</fieldset>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/insert-legend-in-multicol-fieldset-crash.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/insert-legend-in-multicol-fieldset-crash.html
new file mode 100644
index 0000000000..aad552dbe2
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/insert-legend-in-multicol-fieldset-crash.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org">
+<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1211926">
+<fieldset id="fieldset">
+ <legend id="legend"></legend>
+ <div></div>
+</fieldset>
+<script>
+ document.body.offsetTop;
+ fieldset.style.columns = "2";
+ legend.style.position = "relative";
+</script>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-align-justify-self.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-align-justify-self.html
new file mode 100644
index 0000000000..29df29d177
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-align-justify-self.html
@@ -0,0 +1,34 @@
+<!doctype html>
+<title>legend align to justify-self</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<fieldset><legend>x</legend></fieldset>
+<fieldset><legend align=left>x</legend></fieldset>
+<fieldset><legend align=center>x</legend></fieldset>
+<fieldset><legend align=right>x</legend></fieldset>
+<fieldset><legend align=lEfT>x</legend></fieldset>
+<fieldset><legend align=cEnTeR>x</legend></fieldset>
+<fieldset><legend align=rIgHt>x</legend></fieldset>
+<!-- invalid values -->
+<fieldset><legend align=justify>x</legend></fieldset>
+<fieldset><legend align="left ">x</legend></fieldset>
+<!-- dir -->
+<fieldset><legend dir=ltr>x</legend></fieldset>
+<fieldset><legend dir=rtl>x</legend></fieldset>
+<fieldset dir=rtl><legend dir=ltr>x</legend></fieldset>
+<fieldset dir=rtl><legend dir=rtl>x</legend></fieldset>
+<script>
+for (const fieldset of document.querySelectorAll('fieldset')) {
+ test(() => {
+ const legend = fieldset.firstChild;
+ const align = legend.align.toLowerCase();
+ let expected = 'auto';
+ switch (align) {
+ case 'left': expected = 'left'; break;
+ case 'center': expected = 'center'; break;
+ case 'right': expected = 'right'; break;
+ }
+ assert_equals(getComputedStyle(legend).justifySelf, expected);
+ }, `${fieldset.outerHTML}`)
+}
+</script>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-align-text-align.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-align-text-align.html
new file mode 100644
index 0000000000..01483bf8ad
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-align-text-align.html
@@ -0,0 +1,27 @@
+<!doctype html>
+<title>legend align does not map to text-align</title>
+<!-- See discussion in https://bugzilla.mozilla.org/show_bug.cgi?id=1488228 -->
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<style>
+ legend { width: 13em }
+</style>
+<fieldset><legend>foo bar abcdefghijklmnopqrstuvwxyz</legend></fieldset>
+<fieldset><legend align=left>foo bar abcdefghijklmnopqrstuvwxyz</legend></fieldset>
+<fieldset><legend align=center>foo bar abcdefghijklmnopqrstuvwxyz</legend></fieldset>
+<fieldset><legend align=right>foo bar abcdefghijklmnopqrstuvwxyz</legend></fieldset>
+<fieldset><legend align=justify>foo bar abcdefghijklmnopqrstuvwxyz</legend></fieldset>
+<script>
+function test_align(selectorTest, expectedAlign) {
+ const testElm = document.querySelector(selectorTest);
+ test(() => {
+ assert_equals(getComputedStyle(testElm).textAlign, expectedAlign);
+ }, selectorTest);
+}
+
+test_align('legend', 'start');
+
+for (const val of ['left', 'center', 'right', 'justify']) {
+ test_align(`legend[align=${val}]`, 'start');
+}
+</script>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-align.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-align.html
new file mode 100644
index 0000000000..e774599819
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-align.html
@@ -0,0 +1,50 @@
+<!doctype html>
+<title>legend align</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<fieldset><legend align=left>x</legend></fieldset>
+<fieldset><legend align=center>x</legend></fieldset>
+<fieldset><legend align=right>x</legend></fieldset>
+<fieldset><legend align=justify>x</legend></fieldset>
+<div align=left>
+ <fieldset><legend>x</legend></fieldset>
+</div>
+<div align=center>
+ <fieldset><legend>x</legend></fieldset>
+</div>
+<div align=right>
+ <fieldset><legend>x</legend></fieldset>
+</div>
+<div align=justify>
+ <fieldset><legend>x</legend></fieldset>
+</div>
+<div style="text-align: center">
+ <fieldset><legend>x</legend></fieldset>
+</div>
+<div style="text-align: center" align=center>
+ <fieldset><legend>x</legend></fieldset>
+</div>
+<fieldset><legend style="margin: 0 auto">x</legend></fieldset>
+<fieldset><legend style="margin: 0 0 0 auto">x</legend></fieldset>
+<fieldset dir=rtl><legend>x</legend></fieldset>
+<fieldset dir=rtl><legend style="text-align: left">x</legend></fieldset>
+<script>
+function test_align(selectorTest, selectorRef) {
+ const testElm = document.querySelector(selectorTest);
+ const refElm = document.querySelector(selectorRef);
+ test(() => {
+ assert_equals(testElm.offsetLeft, refElm.offsetLeft, `expected ${selectorRef}`);
+ }, selectorTest);
+}
+
+for (const val of ['left', 'center', 'right', 'justify']) {
+ test_align(`div[align=${val}] legend`, `legend[align=left]`);
+}
+
+test_align(`div[style="text-align: center"] legend`, `legend[align=left]`);
+test_align(`div[style="text-align: center"][align=center] legend`, `legend[align=left]`);
+test_align(`legend[style="margin: 0 auto"]`, `legend[align=center]`);
+test_align(`legend[style="margin: 0 0 0 auto"]`, `legend[align=right]`);
+test_align(`fieldset[dir=rtl] legend`, `legend[align=right]`);
+test_align(`fieldset[dir=rtl] legend[style="text-align: left"]`, `legend[align=right]`);
+</script>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-auto-margins-ref.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-auto-margins-ref.html
new file mode 100644
index 0000000000..8b1258727f
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-auto-margins-ref.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>legend inline auto margins</title>
+<link rel="author" title="Mats Palmgren" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1488301">
+<style>
+body, html { padding:0; margin: 0; }
+div {
+ border: 1px solid black;
+ border-width: 10px 17px 7px 23px;
+ padding: 0;
+ margin: 0;
+ width: 448px;
+ height: 5px;
+ margin-top: 5px;
+ position: relative;
+}
+span {
+ position: absolute;
+ top: -15px;
+ width: 200px;
+ height: 20px;
+ padding: 0;
+ margin: 0;
+ background: grey;
+}
+center { width: 200px; height: 20px; background: red; }
+</style>
+</head>
+<body>
+ <div><span style="right:17px"></span></div>
+ <div><span style="left:31px"></span></div>
+ <div><span style="left:131px"></span></div>
+ <div><span style="right:32px"></span></div>
+ <div><span style="left:46px"></span></div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-auto-margins.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-auto-margins.html
new file mode 100644
index 0000000000..dd1964ba25
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-auto-margins.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>legend inline auto margins</title>
+<link rel="author" title="Mats Palmgren" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1488301">
+<link rel="match" href="legend-auto-margins-ref.html">
+<style>
+body, html { padding:0; margin: 0; }
+fieldset {
+ border: 1px solid black;
+ border-width: 10px 17px 7px 23px;
+ padding: 0 17px 0 31px;
+ margin: 0;
+ width: 400px;
+}
+legend {
+ width: 200px;
+ height: 20px;
+ padding: 0;
+ margin: 0;
+ background: grey;
+}
+</style>
+</head>
+<body>
+ <fieldset><legend style="margin-left:auto"></legend></fieldset>
+ <fieldset><legend style="margin-right:auto"></legend></fieldset>
+ <fieldset><legend style="margin:0 auto"></legend></fieldset>
+ <fieldset><legend style="margin:0 15px 0 auto"></legend></fieldset>
+ <fieldset><legend style="margin:0 auto 0 15px"></legend></fieldset>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-block-formatting-context.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-block-formatting-context.html
new file mode 100644
index 0000000000..4e95391797
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-block-formatting-context.html
@@ -0,0 +1,81 @@
+<!DOCTYPE html>
+<title>The legend element: block formatting context</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<style>
+/* Set margin and padding for fieldset to 0 to make things simpler */
+fieldset {
+ margin: 0;
+ padding: 0;
+}
+.wrapper {
+ height: 200px;
+ position: relative;
+}
+.float {
+ float: left;
+ width: 50px;
+ height: 50px;
+ background-color: orange;
+}
+</style>
+
+<div class=wrapper>
+ <div class=float></div>
+ <legend id=in-body><div class=float></div></legend>
+ <div class=float></div>
+</div>
+
+<div class=wrapper>
+ <fieldset>
+ <div class=float></div>
+ <legend id=rendered-legend><div class=float></div></legend>
+ <legend id=in-fieldset-second-child><div class=float></div></legend>
+ <div><legend id=in-fieldset-descendant><div class=float></div></legend></div>
+ </fieldset>
+</div>
+
+<script>
+const fieldsetBorderWidth = 2;
+const legendPadding = 2;
+
+test(() => {
+ const legend = document.getElementById('in-body');
+ assert_equals(legend.offsetLeft, 0, 'legend.offsetLeft');
+ assert_equals(legend.offsetTop, 0, 'legend.offsetTop');
+ assert_equals(legend.clientHeight, 0, 'legend.clientHeight');
+ const divAfter = legend.nextElementSibling;
+ assert_equals(divAfter.offsetLeft, 100, 'divAfter.offsetLeft');
+ assert_equals(divAfter.offsetTop, 0, 'divAfter.offsetTop');
+}, 'in-body');
+
+test(() => {
+ const legend = document.getElementById('rendered-legend');
+ assert_equals(legend.offsetLeft, fieldsetBorderWidth, 'legend.offsetLeft');
+ assert_equals(legend.offsetTop, 0, 'legend.offsetTop');
+ assert_equals(legend.clientHeight, 50, 'legend.clientHeight');
+ const divChild = legend.firstChild;
+ assert_equals(divChild.offsetLeft, fieldsetBorderWidth + legendPadding, 'divChild.offsetLeft');
+ assert_equals(divChild.offsetTop, 0, 'divChild.offsetTop');
+}, 'rendered-legend');
+
+test(() => {
+ const legend = document.getElementById('in-fieldset-second-child');
+ assert_equals(legend.offsetLeft, fieldsetBorderWidth, 'legend.offsetLeft');
+ assert_equals(legend.offsetTop, 50, 'legend.offsetTop');
+ assert_equals(legend.clientHeight, 0, 'legend.clientHeight');
+ const divChild = legend.firstChild;
+ assert_equals(divChild.offsetLeft, fieldsetBorderWidth + 50, 'divChild.offsetLeft');
+ assert_equals(divChild.offsetTop, 50, 'divChild.offsetTop');
+}, 'in-fieldset-second-child');
+
+test(() => {
+ const legend = document.getElementById('in-fieldset-descendant');
+ assert_equals(legend.offsetLeft, fieldsetBorderWidth, 'legend.offsetLeft');
+ assert_equals(legend.offsetTop, 50, 'legend.offsetTop');
+ assert_equals(legend.clientHeight, 0, 'legend.clientHeight');
+ const divChild = legend.firstChild;
+ assert_equals(divChild.offsetLeft, fieldsetBorderWidth + 50 + 50, 'divChild.offsetLeft');
+ assert_equals(divChild.offsetTop, 50, 'divChild.offsetTop');
+}, 'in-fieldset-descendant');
+</script>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-block-margins-2-ref.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-block-margins-2-ref.html
new file mode 100644
index 0000000000..1680cc8884
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-block-margins-2-ref.html
@@ -0,0 +1,142 @@
+<!DOCTYPE HTML>
+<!--
+ Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<html><head>
+ <meta charset="utf-8">
+ <title>Reference for legend block-axis margins</title>
+<style>
+.fieldset {
+ display: block;
+ position: relative;
+ width: 40px;
+ border: 2px solid blue;
+ padding: 4px;
+}
+.legend {
+ display: block;
+ position: absolute;
+ width: 10px;
+ height: 20px;
+ padding: 0;
+ margin: 0;
+ background: grey;
+}
+
+.t2 .fieldset { border-top-width: 12px; }
+.t3 .fieldset { border-top-width: 12px; }
+.t3 .legend { height: 12px; background:white; }
+.legend > x { display:block; position:relative; height:6px; background:grey; margin-top:3px; }
+
+div { border: 1px solid; margin: 0 2px 10px 0; }
+c { display:block; height:10px; background: lightgrey; }
+f { float: left; }
+</style>
+</head>
+<body>
+
+<f>
+<div>
+ <span class="fieldset" style="margin-top:9px"><span class="legend" style="top:-11px"></span><c style="margin-top:9px"></c></span>
+</div>
+
+<div>
+ <span class="fieldset" style="margin-top:19px"><span class="legend" style="top:-11px"></span><c style="margin-top:9px"></c></span>
+</div>
+
+<div>
+ <span class="fieldset"><span class="legend" style="top:-12px"></span><c style="margin-top:8px"></c></span>
+</div>
+
+<div>
+ <span class="fieldset"><span class="legend" style="top:-20px"></span><c></c></span>
+</div>
+
+<div>
+ <span class="fieldset"><span class="legend" style="top:-20px"></span><c></c></span>
+</div>
+
+<div>
+ <span class="fieldset" style="margin-top:9px"><span class="legend" style="top:-11px"></span><c style="margin-top:19px"></c></span>
+</div>
+
+<div>
+ <span class="fieldset" style="margin-top:9px"><span class="legend" style="top:-11px"></span><c style="margin-top:29px"></c></span>
+</div>
+
+<div>
+ <span class="fieldset"><span class="legend" style="top:-2px; z-index:1"></span><c style="position:relative; z-index:1"></c></span>
+</div>
+</f>
+
+<f class=t2>
+<div>
+ <span class="fieldset" style="margin-top:4px"><span class="legend" style="top:-16px"></span><c style="margin-top:4px"></c></span>
+</div>
+
+<div>
+ <span class="fieldset" style="margin-top:14px"><span class="legend" style="top:-16px"></span><c style="margin-top:4px"></c></span>
+</div>
+
+<div>
+ <span class="fieldset"><span class="legend" style="top:-20px"></span><c></c></span>
+</div>
+
+<div>
+ <span class="fieldset"><span class="legend" style="top:-20px"></span><c></c></span>
+</div>
+
+<div>
+ <span class="fieldset"><span class="legend" style="top:-20px"></span><c></c></span>
+</div>
+
+<div>
+ <span class="fieldset" style="margin-top:4px"><span class="legend" style="top:-16px"></span><c style="margin-top:14px"></c></span>
+</div>
+
+<div>
+ <span class="fieldset" style="margin-top:4px"><span class="legend" style="top:-16px"></span><c style="margin-top:24px"></c></span>
+</div>
+
+<div>
+ <span class="fieldset"><span class="legend" style="top:-12px; height:16px"></span><c></c></span>
+</div>
+</f>
+
+<f class=t3>
+<div>
+ <span class="fieldset"><span class="legend" style="margin-top: -16px"><x></x></span><c></c></span>
+</div>
+
+<div>
+ <span class="fieldset" style="margin-top: 4px"><span class="legend" style="margin-top: -16px"><x style="top:3px"></x></span><c></c></span>
+</div>
+
+<div>
+ <span class="fieldset"><span class="legend" style="margin-top: -16px"><x></x></span><c></c></span>
+</div>
+
+<div>
+ <span class="fieldset"><span class="legend" style="margin-top: -16px"><x></x></span><c></c></span>
+</div>
+
+<div>
+ <span class="fieldset"><span class="legend" style="margin-top: -16px"><x></x></span><c></c></span>
+</div>
+
+<div>
+ <span class="fieldset"><span class="legend" style="margin-top: -16px"><x style="top:-3px"></x></span><c style="margin-top:4px"></c></span>
+</div>
+
+<div>
+ <span class="fieldset"><span class="legend" style="margin-top: -16px"><x style="top:-3px"></x></span><c style="margin-top:14px"></c></span>
+</div>
+
+<div>
+ <span class="fieldset"><span class="legend" style="margin-top: -16px"><x></x></span><c></c></span>
+</div>
+</f>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-block-margins-2.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-block-margins-2.html
new file mode 100644
index 0000000000..9ca9e18adf
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-block-margins-2.html
@@ -0,0 +1,139 @@
+<!DOCTYPE HTML>
+<!--
+ Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<html><head>
+ <meta charset="utf-8">
+ <title>legend block-axis margins</title>
+ <link rel="match" href="legend-block-margins-2-ref.html">
+<style>
+fieldset {
+ width: 40px;
+ border: 2px solid blue;
+ padding: 4px;
+ margin: 0;
+}
+legend {
+ width: 10px;
+ height: 20px;
+ padding: 0;
+ background: grey;
+
+}
+
+.t2 fieldset { border-top-width: 12px; }
+.t3 fieldset { border-top-width: 12px; }
+.t3 legend { height: 6px; }
+
+div { border: 1px solid; margin: 0 2px 10px 0; }
+c { display:block; height:10px; background: lightgrey; }
+f { float: left; }
+</style>
+</head>
+<body>
+
+<f>
+<div>
+ <fieldset><legend></legend><c></c></fieldset>
+</div>
+
+<div>
+ <fieldset><legend style="margin-top: 10px"></legend><c></c></fieldset>
+</div>
+
+<div>
+ <fieldset><legend style="margin-top: -10px"></legend><c></c></fieldset>
+</div>
+
+<div>
+ <fieldset><legend style="margin-top: -20px"></legend><c></c></fieldset>
+</div>
+
+<div>
+ <fieldset><legend style="margin-top: -30px"></legend><c></c></fieldset>
+</div>
+
+<div>
+ <fieldset><legend style="margin-bottom: 10px"></legend><c></c></fieldset>
+</div>
+
+<div>
+ <fieldset><legend style="margin-bottom: 20px"></legend><c></c></fieldset>
+</div>
+
+<div>
+ <fieldset><legend style="margin-bottom: -20px"></legend><c></c></fieldset>
+</div>
+</f>
+
+<f class=t2>
+<div>
+ <fieldset><legend></legend><c></c></fieldset>
+</div>
+
+<div>
+ <fieldset><legend style="margin-top: 10px"></legend><c></c></fieldset>
+</div>
+
+<div>
+ <fieldset><legend style="margin-top: -10px"></legend><c></c></fieldset>
+</div>
+
+<div>
+ <fieldset><legend style="margin-top: -20px"></legend><c></c></fieldset>
+</div>
+
+<div>
+ <fieldset><legend style="margin-top: -30px"></legend><c></c></fieldset>
+</div>
+
+<div>
+ <fieldset><legend style="margin-bottom: 10px"></legend><c></c></fieldset>
+</div>
+
+<div>
+ <fieldset><legend style="margin-bottom: 20px"></legend><c></c></fieldset>
+</div>
+
+<div>
+ <fieldset><legend style="margin-bottom: -20px"></legend><c></c></fieldset>
+</div>
+</f>
+
+<f class=t3>
+<div>
+ <fieldset><legend></legend><c></c></fieldset>
+</div>
+
+<div>
+ <fieldset><legend style="margin-top: 10px"></legend><c></c></fieldset>
+</div>
+
+<div>
+ <fieldset><legend style="margin-top: -10px"></legend><c></c></fieldset>
+</div>
+
+<div>
+ <fieldset><legend style="margin-top: -20px"></legend><c></c></fieldset>
+</div>
+
+<div>
+ <fieldset><legend style="margin-top: -30px"></legend><c></c></fieldset>
+</div>
+
+<div>
+ <fieldset><legend style="margin-bottom: 10px"></legend><c></c></fieldset>
+</div>
+
+<div>
+ <fieldset><legend style="margin-bottom: 20px"></legend><c></c></fieldset>
+</div>
+
+<div>
+ <fieldset><legend style="margin-bottom: -20px"></legend><c></c></fieldset>
+</div>
+</f>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-block-margins-ref.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-block-margins-ref.html
new file mode 100644
index 0000000000..f2701d26f3
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-block-margins-ref.html
@@ -0,0 +1,13 @@
+<!doctype html>
+<title>Reference for legend block margins</title>
+<style>
+body { margin: 0; }
+.fieldset { margin: 2em 1em 1em 1em; border: 1em solid green; }
+.legend { position: absolute; margin-top: -1em; margin-left: 1em; background: white; height: 1em; }
+.inner { margin: 3em 1em 1em 1em; height: 1em; }
+</style>
+<p>There should be no red.</p>
+<div class=fieldset>
+ <div class=legend>X</div>
+ <div class=inner>Y</div>
+</div>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-block-margins.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-block-margins.html
new file mode 100644
index 0000000000..98cd16c7c1
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-block-margins.html
@@ -0,0 +1,16 @@
+<!doctype html>
+<title>legend block margins</title>
+<link rel=match href=legend-block-margins-ref.html>
+<style>
+ body { margin: 0; }
+ fieldset { margin: 1em; border: 1em solid green; padding: 0; background: white; }
+ legend { margin: 1em 1em 2em 1em; height: 1em; padding: 0; }
+ .inner { margin: 1em; height: 1em; }
+ .behind { position: absolute; left: 1em; right: 1em; margin-top: 1em; height: 7em; background: red; z-index: -1; }
+</style>
+<p>There should be no red.</p>
+<div class=behind></div>
+<fieldset>
+ <legend>X</legend>
+ <div class=inner>Y</div>
+</fieldset>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-block-position-centering.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-block-position-centering.html
new file mode 100644
index 0000000000..a4eda6e3ef
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-block-position-centering.html
@@ -0,0 +1,58 @@
+<!DOCTYPE html>
+<link rel="help" href="https://html.spec.whatwg.org/C/#the-fieldset-and-legend-elements">
+<!-- A test for the following paragraph:
+The element is expected to be positioned in the block-flow direction such that
+its border box is centered over the border on the block-start side of the
+fieldset element.
+-->
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<style>
+fieldset {
+ margin: 0;
+ padding: 0;
+ border: 100px solid black;
+}
+legend {
+ height: 0px;
+ border-color: yellow;
+ border-style: solid;
+}
+</style>
+<fieldset>
+<legend style="border-width:50px"></legend>
+<br>
+</fieldset>
+<br>
+
+<fieldset>
+<legend style="border-width:25px 50px"></legend>
+<br>
+</fieldset>
+<br>
+
+<fieldset>
+<legend style="border-width:10px 50px 40px 50px"></legend>
+<br>
+</fieldset>
+<br>
+
+<fieldset>
+<legend style="border-width:40px 50px 10px 50px"></legend>
+<br>
+</fieldset>
+
+<script>
+function legendBlockOffset(fieldset) {
+ let legend = fieldset.querySelector('legend');
+ return legend.getBoundingClientRect().y - fieldset.getBoundingClientRect().y;
+}
+
+test(() => {
+ let fieldsets = document.querySelectorAll('fieldset');
+ assert_equals(legendBlockOffset(fieldsets[0]), 0);
+ assert_equals(legendBlockOffset(fieldsets[1]), 25);
+ assert_equals(legendBlockOffset(fieldsets[2]), 25);
+ assert_equals(legendBlockOffset(fieldsets[3]), 25);
+}, 'Legend\'s border-box should be centere on the fieldset border');
+</script>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-display-none-rendering-ref.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-display-none-rendering-ref.html
new file mode 100644
index 0000000000..e6eff47e53
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-display-none-rendering-ref.html
@@ -0,0 +1,7 @@
+<!doctype html>
+<title>Reference for Rendering of display: none legend</title>
+<style>
+ div { border: 2em solid lime; width: 0; }
+</style>
+<p>There should be a green box below.</p>
+<div></div>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-display-none-rendering.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-display-none-rendering.html
new file mode 100644
index 0000000000..abf3c45df7
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-display-none-rendering.html
@@ -0,0 +1,11 @@
+<!doctype html>
+<title>Rendering of display: none legend</title>
+<link rel=match href=legend-display-none-rendering-ref.html>
+<style>
+ fieldset { border: 2em solid lime; width: 0; margin: 0; padding: 0; }
+ legend { display: none; background: red; }
+</style>
+<p>There should be a green box below.</p>
+<fieldset>
+ <legend>FAIL</legend>
+</fieldset>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-display-none.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-display-none.html
new file mode 100644
index 0000000000..689454ac49
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-display-none.html
@@ -0,0 +1,16 @@
+<!doctype html>
+<title>legend display: none</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<style>
+ legend { display: none; }
+</style>
+<fieldset>
+ <legend>Foo</legend>
+</fieldset>
+<script>
+ test(() => {
+ const display = getComputedStyle(document.querySelector('legend')).display;
+ assert_equals(display, 'none');
+ });
+</script>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-display-rendering-ref.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-display-rendering-ref.html
new file mode 100644
index 0000000000..189b195f61
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-display-rendering-ref.html
@@ -0,0 +1,34 @@
+<!doctype html>
+<title>Reference for rendered legend and CSS display rendering</title>
+<style>
+body { margin: 0; }
+div { width: 600px; box-sizing: border-box; background: #ddd; border: 1px solid; }
+.padding { padding-left: 5em; }
+.margin { margin-left: 5em; }
+.cell { display: inline-block; width: 50%; }
+.ruby { display: block; }
+</style>
+<div><span class=cell>table</span><span class=cell>table</span></div>
+<div class=padding>table-row-group</div>
+<div class=padding>table-header-group</div>
+<div class=padding>table-footer-group</div>
+<div class=padding>table-row</div>
+<div class=margin>table-cell</div>
+<div class=padding>table-column-group</div>
+<div class=padding>table-column</div>
+<div>table-caption</div>
+<div>flow</div>
+<div>flow-root</div>
+<div>run-in</div>
+<div>inline</div>
+<div>inline-block</div>
+<div><span class=cell>inline-table</span><span class=cell>inline-table</span></div>
+<div><span class=ruby>ruby</span><span class=ruby>ruby</span></div>
+<div>ruby-base</div>
+<div>ruby-text</div>
+<div>ruby-base-container</div>
+<div>ruby-text-container</div>
+<div><span class=cell>grid</span><span class=cell>grid</span></div>
+<div><span class=cell>inline-grid</span><span class=cell>inline-grid</span></div>
+<div><span class=cell>flex</span><span class=cell>flex</span></div>
+<div><span class=cell>inline-flex</span><span class=cell>inline-flex</span></div>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-display-rendering.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-display-rendering.html
new file mode 100644
index 0000000000..ba6610503a
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-display-rendering.html
@@ -0,0 +1,119 @@
+<!doctype html>
+<title>rendered legend and CSS display rendering</title>
+<link rel=match href=legend-display-rendering-ref.html>
+<style>
+body { margin: 0; }
+fieldset { margin: 0; padding: 0; border: none; }
+legend { width: 600px; box-sizing: border-box; padding: 0; background: #ddd; border: 1px solid; }
+[style="display: table"] span,
+[style="display: inline-table"] span { display: table-cell; }
+[style="display: table-row-group"],
+[style="display: table-header-group"],
+[style="display: table-footer-group"],
+[style="display: table-row"],
+[style="display: table-column-group"],
+[style="display: table-column"] { padding-left: 5em; /* would be ignored if not blockified */ }
+[style="display: table-cell"] { margin-left: 5em; /* would be ignored if not blockified */ }
+.rb { display: ruby-base; }
+.rt { display: ruby-text; }
+[style="display: grid"],
+[style="display: inline-grid"] { grid-template-columns: auto auto; }
+[style="display: flex"] span,
+[style="display: inline-flex"] span { display: block; flex-grow: 1 }
+</style>
+<fieldset>
+ <legend style="display: table"><span>table</span><span>table</span></legend>
+</fieldset>
+
+<fieldset>
+ <legend style="display: table-row-group">table-row-group</legend>
+</fieldset>
+
+<fieldset>
+ <legend style="display: table-header-group">table-header-group</legend>
+</fieldset>
+
+<fieldset>
+ <legend style="display: table-footer-group">table-footer-group</legend>
+</fieldset>
+
+<fieldset>
+ <legend style="display: table-row">table-row</legend>
+</fieldset>
+
+<fieldset>
+ <legend style="display: table-cell">table-cell</legend>
+</fieldset>
+
+<fieldset>
+ <legend style="display: table-column-group">table-column-group</legend>
+</fieldset>
+
+<fieldset>
+ <legend style="display: table-column">table-column</legend>
+</fieldset>
+
+<fieldset>
+ <legend style="display: table-caption">table-caption</legend>
+</fieldset>
+
+<fieldset>
+ <legend style="display: flow">flow</legend>
+</fieldset>
+
+<fieldset>
+ <legend style="display: flow-root">flow-root</legend>
+</fieldset>
+
+<fieldset>
+ <legend style="display: run-in">run-in</legend>
+</fieldset>
+
+<fieldset>
+ <legend style="display: inline">inline</legend>
+</fieldset>
+
+<fieldset>
+ <legend style="display: inline-block">inline-block</legend>
+</fieldset>
+
+<fieldset>
+ <legend style="display: inline-table"><span>inline-table</span><span>inline-table</span></legend>
+</fieldset>
+
+<fieldset>
+ <legend style="display: ruby"><span class=rb>ruby</span><span class=rt>ruby</span></legend>
+</fieldset>
+
+<fieldset>
+ <legend style="display: ruby-base">ruby-base</legend>
+</fieldset>
+
+<fieldset>
+ <legend style="display: ruby-text">ruby-text</legend>
+</fieldset>
+
+<fieldset>
+ <legend style="display: ruby-base-container">ruby-base-container</legend>
+</fieldset>
+
+<fieldset>
+ <legend style="display: ruby-text-container">ruby-text-container</legend>
+</fieldset>
+
+<fieldset>
+ <legend style="display: grid"><span>grid</span><span>grid</span></legend>
+</fieldset>
+
+<fieldset>
+ <legend style="display: inline-grid"><span>inline-grid</span><span>inline-grid</span></legend>
+</fieldset>
+
+<fieldset>
+ <legend style="display: flex"><span>flex</span><span>flex</span></legend>
+</fieldset>
+
+<fieldset>
+ <legend style="display: inline-flex"><span>inline-flex</span><span>inline-flex</span></legend>
+</fieldset>
+
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-display.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-display.html
new file mode 100644
index 0000000000..b6c57a67ba
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-display.html
@@ -0,0 +1,40 @@
+<!doctype html>
+<title>rendered legend and CSS display</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<style>
+legend { width:initial; }
+</style>
+<fieldset><legend id="ref">x</legend></fieldset>
+<fieldset><legend id="test">x</legend></fieldset>
+<script>
+ const refElm = document.querySelector('#ref');
+ const refStyle = getComputedStyle(refElm);
+ const testElm = document.querySelector('#test');
+ const values = ['block', 'table', 'table-row-group', 'table-header-group', 'table-footer-group', 'table-row', 'table-cell',
+ 'table-column-group', 'table-column', 'table-caption', 'list-item', 'flow', 'flow-root','run-in','inline',
+ 'inline-block', 'inline-table', 'block ruby', 'ruby', 'ruby-base', 'ruby-text', 'ruby-base-container', 'ruby-text-container',
+ 'grid', 'inline-grid', 'flex', 'inline-flex'];
+ const extraStyle = ['', 'overflow:hidden', 'columns:1', 'overflow:hidden;columns:1'];
+
+ for (const style of extraStyle) {
+ for (const val of values) {
+ test(() => {
+ testElm.style.removeProperty('display');
+ testElm.style = style;
+ testElm.style.display = val;
+ const computed = getComputedStyle(testElm);
+ // Note that computed value is different from the used value.
+ // E.g., if ruby is not supported, the following assertion will
+ // fail as the computed value of display will be block.
+ // If ruby is supported, computed.display will return "ruby",
+ // but the used value is supposed to be "block ruby".
+ // Also, 'flow' is serialized as 'block' for legacy reasons.
+ let expected = val == 'flow' ? 'block' : val;
+ assert_equals(computed.display, expected, `display: ${val} is not supported`);
+ assert_equals(computed.width, refStyle.width, 'width');
+ assert_equals(testElm.offsetLeft, refElm.offsetLeft, 'offsetLeft');
+ }, `rendered legend with display: ${val}` + (style == '' ? '' : "; " + style));
+ }
+ }
+</script>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-dynamic-update.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-dynamic-update.html
new file mode 100644
index 0000000000..5dc68244fe
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-dynamic-update.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<title>legend and dynamic update</title>
+<link rel=fieldset-foo-ref.html>
+<p>There should be a normal fieldset below with the legend "Foo".</p>
+<fieldset>
+ <legend>F</legend>
+</fieldset>
+<script>
+ const legend = document.querySelector('legend');
+ // force layout
+ legend.offsetTop;
+ requestAnimationFrame(() => {
+ legend.textContent += "oo";
+ requestAnimationFrame(() => {
+ document.documentElement.removeAttribute('class');
+ });
+ });
+</script>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-float-abspos.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-float-abspos.html
new file mode 100644
index 0000000000..7979e1d03e
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-float-abspos.html
@@ -0,0 +1,88 @@
+<!doctype html>
+<title>legend and float and position: absolute/fixed</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<style>
+ body { margin: 0; }
+ fieldset { margin: 0; padding: 20px; border: 10px solid; width: 300px; }
+ legend { height: 10px; }
+ #legend1 { float: left; }
+ #legend2 { float: right; }
+ #legend3 { position: absolute; }
+ #legend4 { position: fixed; }
+</style>
+<fieldset id=fieldset>
+ <div>div</div>
+ <legend id=legend1>legend1</legend>
+ <legend id=legend2>legend2</legend>
+ <legend id=legend3>legend3</legend>
+ <legend id=legend4>legend4</legend>
+ <legend id=legend5>legend5</legend>
+</fieldset>
+<script>
+ const fieldset = document.getElementById('fieldset');
+ const legends = document.getElementsByTagName('legend');
+ const [legend1, legend2, legend3, legend4, legend5] = legends;
+ const expectedTop = 0;
+ const expectedLeft = 10 + 20;
+
+ function assert_rendered_legend(legend) {
+ assert_equals(legend.offsetTop, expectedTop, `${legend.id}.offsetTop`);
+ assert_equals(legend.offsetLeft, expectedLeft, `${legend.id}.offsetLeft`);
+ for (const other of legends) {
+ if (other === legend) {
+ continue;
+ }
+ if (other.offsetTop === expectedTop && other.offsetLeft === expectedLeft) {
+ assert_unreached(`${other.id} should not be the "rendered legend"`);
+ }
+ }
+ }
+
+ test(t => {
+ assert_rendered_legend(legend5);
+ }, 'no dynamic changes');
+
+ test(t => {
+ const legend = document.createElement('legend');
+ t.add_cleanup(() => {
+ legend.remove();
+ });
+ legend.id = 'script-inserted';
+ legend.textContent = 'script-inserted legend';
+ fieldset.insertBefore(legend, legend1);
+ assert_rendered_legend(legend);
+ legend.remove();
+ assert_rendered_legend(legend5);
+ }, 'inserting a new legend and removing it again');
+
+ test(t => {
+ t.add_cleanup(() => {
+ legend1.id = 'legend1';
+ legend2.id = 'legend2';
+ });
+ legend2.id = '';
+ assert_rendered_legend(legend2);
+ legend1.id = '';
+ assert_rendered_legend(legend1);
+ legend1.id = 'legend1';
+ assert_rendered_legend(legend2);
+ legend2.id = 'legend2';
+ assert_rendered_legend(legend5);
+ }, 'dynamic changes to float');
+
+ test(t => {
+ t.add_cleanup(() => {
+ legend3.id = 'legend3';
+ legend4.id = 'legend4';
+ });
+ legend4.id = '';
+ assert_rendered_legend(legend4);
+ legend3.id = '';
+ assert_rendered_legend(legend3);
+ legend3.id = 'legend3';
+ assert_rendered_legend(legend4);
+ legend4.id = 'legend4';
+ assert_rendered_legend(legend5);
+ }, 'dynamic changes to position');
+</script>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-float-ref.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-float-ref.html
new file mode 100644
index 0000000000..c51bca231e
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-float-ref.html
@@ -0,0 +1,7 @@
+<!doctype html>
+<title>Reference for floated legend should not disappear</title>
+<style>
+ div { width: 100px; height: 100px; background: lime; }
+</style>
+<p>There should be no red.</p>
+<div></div>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-float.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-float.html
new file mode 100644
index 0000000000..f70e952ed0
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-float.html
@@ -0,0 +1,12 @@
+<!doctype html>
+<title>floated legend should not disappear</title>
+<link rel=match href=legend-float-ref.html>
+<style>
+ fieldset { margin: 0; padding: 0; border: none; width: 100px; height: 50px; background: red; }
+ legend { width: 100px; height: 50px; background: lime; padding: 0; }
+ .left { float: left; }
+ .right { float: right; }
+</style>
+<p>There should be no red.</p>
+<fieldset><legend class=left></legend></fieldset>
+<fieldset><legend class=right></legend></fieldset>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-grid-flex-multicol.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-grid-flex-multicol.html
new file mode 100644
index 0000000000..edd2600d4a
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-grid-flex-multicol.html
@@ -0,0 +1,31 @@
+<!doctype html>
+<title>legend and flexbox, grid & multicol</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<style>
+legend { width: 200px; background: silver }
+#flex { display: flex; }
+#inline-flex { display: inline-flex; }
+#grid { display: grid; }
+#inline-grid { display: inline-grid; }
+#grid, #inline-grid { grid-template-columns: auto auto }
+#multicol { columns: 2; }
+</style>
+<fieldset><legend id=ref>12</legend></fieldset>
+<fieldset><legend id=flex><div>1</div><div>2</div></legend></fieldset>
+<fieldset><legend id=inline-flex><div>1</div><div>2</div></legend></fieldset>
+<fieldset><legend id=grid><div>1</div><div>2</div></legend></fieldset>
+<fieldset><legend id=inline-grid><div>1</div><div>2</div></legend></fieldset>
+<fieldset><legend id=multicol><div>1</div><div>2</div></legend></fieldset>
+<script>
+ const ref = document.getElementById('ref');
+ for (const id of ["flex", "inline-flex", "grid", "inline-grid", "multicol"]) {
+ test(() => {
+ const elm = document.getElementById(id);
+ assert_equals(elm.offsetHeight, ref.offsetHeight, 'offsetHeight');
+ if (id !== "multicol") {
+ assert_equals(getComputedStyle(elm).display, id, 'display');
+ }
+ }, id);
+ }
+</script>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-hover.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-hover.html
new file mode 100644
index 0000000000..170e3cc874
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-hover.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/testdriver.js"></script>
+<script src="/resources/testdriver-vendor.js"></script>
+
+<style>
+legend:hover {
+ background: lime;
+}
+</style>
+<h1>Header</h1>
+<fieldset>
+ <legend>Legend</legend>
+</fieldset>
+<script>
+// https://crbug.com/1127743
+promise_test(async () => {
+ await test_driver.click(document.querySelector('legend'));
+ assert_not_equals(document.querySelector('legend:hover'), null);
+}, 'The rendered LEGEND should work well for :hover.');
+</script>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-in-slot-ref.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-in-slot-ref.html
new file mode 100644
index 0000000000..ee64e81762
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-in-slot-ref.html
@@ -0,0 +1,4 @@
+<!DOCTYPE html>
+<fieldset>
+ <legend>Is rendered legend</legend>
+</fieldset>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-in-slot.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-in-slot.html
new file mode 100644
index 0000000000..c4ab5a3ea0
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-in-slot.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<link rel="match" href="legend-in-slot-ref.html">
+
+<div id="host">
+ <legend id="legend">Was rendered legend</legend>
+ <legend>Is rendered legend</legend>
+</div>
+<script>
+let root = document.querySelector('#host').attachShadow({mode:"open"});
+root.innerHTML = `
+<fieldset>
+ <slot></slot>
+</fieldset>`;
+document.body.offsetTop;
+document.querySelector('#legend').remove();
+</script>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-inline-position-with-fieldset-padding.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-inline-position-with-fieldset-padding.html
new file mode 100644
index 0000000000..0b2624859e
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-inline-position-with-fieldset-padding.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<link rel="help" href="https://html.spec.whatwg.org/C/#the-fieldset-and-legend-elements">
+<!-- A test for the following paragraphs:
+The element's box is expected to be constrained in the inline direction by
+the inline content size of the fieldset as if it had used its computed
+inline padding.
+Example:
+For example, if the fieldset has a specified padding of 50px, then the
+rendered legend will be positioned 50px in from the fieldset's border. The
+padding will further apply to the anonymous fieldset content box instead
+of the fieldset element itself.
+-->
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<style>
+fieldset {
+ width: 400px;
+ margin: 0;
+ padding: 0 50px;
+ border: 2px solid black;
+}
+legend {
+ width: 100%;
+ padding: 0;
+ background-color: yellow;
+}
+.content {
+ background-color: lime;
+}
+</style>
+<fieldset>
+<legend>Legend</legend>
+</fieldset>
+
+<script>
+test(() => {
+ let fieldset = document.querySelector('fieldset');
+ let legend = document.querySelector('legend');
+ assert_equals(legend.offsetLeft - fieldset.offsetLeft, 52);
+ assert_equals(legend.offsetWidth, 400);
+}, 'Test legend\'s inline-size in a fieldset with inline paddings');
+</script>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-list-item-numbering-ref.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-list-item-numbering-ref.html
new file mode 100644
index 0000000000..f7b4754e09
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-list-item-numbering-ref.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>Reference for legend and display: list-item numbering</title>
+<link rel="author" title="Ting-Yu Lin" href="mailto:tlin@mozilla.com">
+<link rel="author" title="Mozilla" href="http://www.mozilla.org/">
+
+<style>
+ol { margin: 0; padding: 0; border: none; }
+ol > * { margin: 0 40px; padding: 0; }
+</style>
+
+<ol>
+ <li value="2">B</li>
+ <li value="1">A</li>
+ <li value="3">C</li>
+</ol>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-list-item-numbering.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-list-item-numbering.html
new file mode 100644
index 0000000000..d7d904b8c7
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-list-item-numbering.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>Legend and display: list-item numbering</title>
+<link rel="author" title="Ting-Yu Lin" href="mailto:tlin@mozilla.com">
+<link rel="author" title="Mozilla" href="http://www.mozilla.org/">
+<link rel=match href="legend-list-item-numbering-ref.html">
+
+<style>
+fieldset { margin: 0; padding: 0; border: none; list-style-type: decimal; }
+fieldset > * { margin: 0 40px; padding: 0; display: list-item; }
+</style>
+
+<fieldset>
+ <div>A</div>
+ <legend>B</legend>
+ <div>C</div>
+</fieldset>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-list-item-ref.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-list-item-ref.html
new file mode 100644
index 0000000000..ee76e93b64
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-list-item-ref.html
@@ -0,0 +1,7 @@
+<!doctype html>
+<title>Reference for legend and dipslay: list-item</title>
+<style>
+ div { margin: 0 40px; display: list-item; }
+</style>
+<p>There should be a bullet point below.</p>
+<div>X</div>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-list-item.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-list-item.html
new file mode 100644
index 0000000000..e967643572
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-list-item.html
@@ -0,0 +1,11 @@
+<!doctype html>
+<title>legend and dipslay: list-item</title>
+<link rel=match href=legend-list-item-ref.html>
+<style>
+ fieldset { margin: 0; padding: 0; border: none; }
+ legend { margin: 0 40px; padding: 0; display: list-item; }
+</style>
+<p>There should be a bullet point below.</p>
+<fieldset>
+ <legend>X</legend>
+</fieldset>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-margin-inline.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-margin-inline.html
new file mode 100644
index 0000000000..8daf78db99
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-margin-inline.html
@@ -0,0 +1,50 @@
+<!doctype html>
+<title>legend and margin (inline direction)</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<style>
+ fieldset { margin: 0 0 10px 0; padding: 20px; border: 10px solid; width: 500px; }
+ legend { height: 10px; width: 200px; padding: 0; }
+
+ #legend-center { margin-left: auto; margin-right: auto; }
+ #legend-right { margin-left: auto; }
+ #legend-10 { margin-left: 10px; }
+</style>
+<fieldset>
+ <legend id=legend-left>left</legend>
+</fieldset>
+<fieldset>
+ <legend id=legend-center>center</legend>
+</fieldset>
+<fieldset>
+ <legend id=legend-right>right</legend>
+</fieldset>
+<fieldset>
+ <legend id=legend-10>10px</legend>
+</fieldset>
+
+<script>
+ const legends = document.getElementsByTagName('legend');
+ const [legendLeft, legendCenter, legendRight, legend10] = legends;
+
+ const expectedLeft = 8 + 10 + 20;
+ const expectedCenter = expectedLeft + (500 / 2) - (200 / 2);
+ const expectedRight = expectedLeft + 500 - 200;
+ const expected10 = expectedLeft + 10;
+
+ test(() => {
+ assert_equals(legendLeft.offsetLeft, expectedLeft);
+ }, 'left');
+
+ test(() => {
+ assert_equals(legendCenter.offsetLeft, expectedCenter);
+ }, 'center');
+
+ test(() => {
+ assert_equals(legendRight.offsetLeft, expectedRight);
+ }, 'right');
+
+ test(() => {
+ assert_equals(legend10.offsetLeft, expected10);
+ }, '10px');
+</script>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-painting-order-ref.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-painting-order-ref.html
new file mode 100644
index 0000000000..94f4991f22
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-painting-order-ref.html
@@ -0,0 +1,5 @@
+<!doctype html>
+<title>Reference for fieldset painting order</title>
+
+<p>There should be a green square below, and no red.</p>
+<div style="width:100px; height:100px; background:green;"></div>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-painting-order.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-painting-order.html
new file mode 100644
index 0000000000..ac0bd43037
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-painting-order.html
@@ -0,0 +1,13 @@
+<!doctype html>
+<title>Legend painting order</title>
+<link rel=match href=legend-painting-order-ref.html>
+
+<p>There should be a green square below, and no red.</p>
+<div style="float:left; width:0px; height:0px;">
+ <div style="width:100px; height:100px; background:red;"></div>
+</div>
+<fieldset style="margin:0; border:none; padding:0;">
+ <legend style="padding:0;">
+ <div style="float:left; width:100px; height:100px; background:green;"></div>
+ </legend>
+</fieldset>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-position-relative-2-ref.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-position-relative-2-ref.html
new file mode 100644
index 0000000000..da2dd3e1c6
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-position-relative-2-ref.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<title>Reference for legend position: relative</title>
+<style>
+#fieldset2 {
+ background: lime;
+ border: 2px solid lime;
+ width: 200px;
+ padding: 0;
+ margin: 0;
+}
+#legend2 {
+ background: #00ffff;
+}
+</style>
+<p>"Legend" should be shown.</p>
+<fieldset id="fieldset2"><legend id="legend2">Legend</legend></fieldset>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-position-relative-2.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-position-relative-2.html
new file mode 100644
index 0000000000..3fbdbd5c20
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-position-relative-2.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<title>legend position: relative</title>
+<link ref=help href="http://crbug.com/1151295">
+<link rel=match href=legend-position-relative-2-ref.html>
+<style>
+#fieldset2 {
+ background: lime;
+ border: 2px solid lime;
+ width: 200px;
+ padding: 0;
+ margin: 0;
+ overflow: hidden;
+}
+#legend2 {
+ position: relative;
+ overflow: hidden;
+ background: #00ffff;
+}
+</style>
+<p>"Legend" should be shown.</p>
+<fieldset id="fieldset2"><legend id="legend2">Legend</legend></fieldset>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-position-relative-ref.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-position-relative-ref.html
new file mode 100644
index 0000000000..fd6c11a005
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-position-relative-ref.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<title>Reference for legend position: relative</title>
+<style>
+div { display: inline-block; background: lime; }
+.a { width: 100px; height: 200px; }
+.b { width: 100px; height: 100px; }
+.c { width: 200px; height: 200px; }
+</style>
+<p>There should be no red.</p>
+<div class=a></div><div class=b></div><div class=c></div>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-position-relative.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-position-relative.html
new file mode 100644
index 0000000000..9938361261
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-position-relative.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<title>legend position: relative</title>
+<link rel=match href=legend-position-relative-ref.html>
+<style>
+fieldset { border: 100px solid lime; width: 200px; padding: 0; margin: 0 }
+legend { position: relative; left: 100px; width: 100px; height: 100px; padding: 0 }
+.behind { position: absolute; left: 208px; width: 100px; height: 100px; background: red; z-index: -1 }
+</style>
+<p>There should be no red.</p>
+<div class=behind></div>
+<fieldset><legend></legend></fieldset>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-sans-fieldset-display.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-sans-fieldset-display.html
new file mode 100644
index 0000000000..5f27ca5c29
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-sans-fieldset-display.html
@@ -0,0 +1,68 @@
+<!doctype html>
+<title>legend sans fieldset and CSS display</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<style>
+ * { margin: 0; padding: 0; }
+ .table, table { display: table; width: 200px; border-collapse: collapse; }
+ .tbody { display: table-row-group; }
+ .tr { display: table-row; }
+ .td, td { display: table-cell; }
+ .col { display: table-column; }
+ .caption { display: table-caption; }
+ .li { display: list-item; }
+ .inline { display: inline; }
+ .inline-block { display: inline-block; }
+ .inline-table { display: inline-table; }
+ .ruby { display: ruby; }
+ .rt { display: ruby-text; }
+ rt { font-size: inherit; }
+</style>
+<legend class=table>
+ <legend class=caption>caption</legend>
+ <legend class=col></legend><legend class=col></legend>
+ <legend class=tbody>
+ <legend class=tr>
+ <legend class=td>td</legend><legend class=td>td</legend>
+ </legend>
+ </legend>
+</legend>
+<table>
+ <caption>caption</caption>
+ <col><col>
+ <tbody>
+ <tr>
+ <td>td<td>td
+</table>
+<ul>
+ <legend class=li>li</legend>
+ <li>li</li>
+</ul>
+<p>foo <legend class=inline>inline</legend> <span>inline</span>
+<p>foo <legend class=inline-block>inline-block</legend> <span class=inline-block>inline-block</span>
+<p><legend class=ruby>ruby<legend class=rt>rt</legend></legend> <ruby>ruby<rt>rt</ruby>
+<script>
+ function test_display(testSelector, refSelector) {
+ test(() => {
+ const testElm = document.querySelector(testSelector);
+ const refElm = document.querySelector(refSelector);
+ const testStyle = getComputedStyle(testElm);
+ const refStyle = getComputedStyle(refElm);
+ assert_equals(testStyle.display, refStyle.display, testSelector + ' display');
+ assert_equals(testStyle.width, refStyle.width, testSelector + ' width');
+ assert_equals(testStyle.height, refStyle.height, testSelector + ' height');
+ }, testSelector);
+ }
+
+ test_display('.table', 'table');
+ test_display('.caption', 'caption');
+ test_display('.col', 'col');
+ test_display('.tbody', 'tbody');
+ test_display('.tr', 'tr');
+ test_display('.td', 'td');
+ test_display('.li', 'li');
+ test_display('.inline', 'span');
+ test_display('.inline-block', 'span.inline-block');
+ test_display('.ruby', 'ruby');
+ test_display('.rt', 'rt');
+</script>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-sticky-crash.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-sticky-crash.html
new file mode 100644
index 0000000000..71debf7e44
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-sticky-crash.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<link rel="help" href="http://crbug.com/1197946">
+<style>
+legend {
+ position: sticky;
+ left: -1em;
+}
+fieldset {
+ position: sticky;
+ left: -1em;
+ overflow-y: auto;
+}
+</style>
+<fieldset>
+<legend>Legend</legend>
+</fieldset>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-tall-ref.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-tall-ref.html
new file mode 100644
index 0000000000..004ce42129
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-tall-ref.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<title>Reference for tall legend</title>
+<style>
+body, p { margin: 0; }
+.legend { position: absolute; height: 160px; margin-left: 20px; inline-size: fit-content; background: lime }
+.fieldset {
+ position: absolute;
+ z-index: -1;
+ margin-top: calc((/* half legend height */ 160px / 2) - (/* half top border */ 20px / 2));
+ background: green;
+ height: 40px;
+ left: 0;
+ right: 0;
+}
+.hello { margin-top: 160px; margin-left: 20px; }
+</style>
+<p>There should be no red.</p>
+<div class=legend>X</div>
+<div class=fieldset></div>
+<div class=hello>HELLO</div>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-tall.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-tall.html
new file mode 100644
index 0000000000..7b9495946e
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend-tall.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<title>tall legend</title>
+<link rel=match href=legend-tall-ref.html>
+<style>
+body, p { margin: 0; }
+fieldset { height: 30px; margin: 0; border: 20px solid green; padding: 0px; background: red; }
+legend { height: 160px; background: lime; padding: 0; }
+#behind {
+ position: absolute;
+ z-index: -1;
+ margin-top: calc((/* half legend height */ 160px / 2) - (/* half top border */ 20px / 2));
+ background: red;
+ height: 40px;
+ left: 0;
+ right: 0;
+}
+</style>
+<p>There should be no red.</p>
+<div id=behind></div>
+<fieldset><legend>X</legend>HELLO</fieldset>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend.html
new file mode 100644
index 0000000000..1cda91f32b
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/legend.html
@@ -0,0 +1,62 @@
+<!doctype html>
+<title>The legend element</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<style>
+#ref {
+ display: block;
+ unicode-bidi: isolate;
+ padding-left: 2px;
+ padding-right: 2px;
+ /* TODO: uncomment this when these properties are widely supported
+ padding-inline-start: 2px; padding-inline-end: 2px;
+ */
+}
+</style>
+
+<legend id=in-body></legend>
+<fieldset>
+ <legend id=rendered-legend></legend>
+ <legend id=in-fieldset-second-child></legend>
+ <div><legend id=in-fieldset-descendant></legend></div>
+</fieldset>
+<div id=ref></div>
+
+<script>
+setup(() => {
+ self.legends = [].slice.call(document.querySelectorAll('legend'));
+ self.refStyle = getComputedStyle(document.getElementById('ref'));
+ self.props = ['display',
+ 'unicodeBidi',
+ 'marginTop',
+ 'marginRight',
+ 'marginBottom',
+ 'marginLeft',
+ 'paddingTop',
+ 'paddingRight',
+ 'paddingBottom',
+ 'paddingLeft',
+ 'overflow',
+ // Extra tests
+ 'height',
+ 'box-sizing',
+ ];
+});
+legends.forEach(legend => {
+ const testStyle = getComputedStyle(legend);
+ props.forEach(prop => {
+ test(() => {
+ assert_equals(testStyle[prop], refStyle[prop]);
+ }, `${legend.id}: ${prop}`);
+ });
+
+ // Test width separately since it differs outside fieldset vs. in fieldset vs. rendered legend
+ test(() => {
+ if (legend.id === 'rendered-legend') {
+ assert_equals(testStyle.width, '0px');
+ } else {
+ assert_not_equals(testStyle.width, '0px');
+ }
+ }, `${legend.id}: width`);
+});
+</script>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/min-inline-size.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/min-inline-size.html
new file mode 100644
index 0000000000..92c3302970
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/min-inline-size.html
@@ -0,0 +1,39 @@
+<!doctype html>
+<title>fieldset min-inline-size</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<style>
+ fieldset { width: 0; height: 0 }
+ fieldset > div { width: 100px; height: 100px }
+ #vertical-lr { writing-mode: vertical-lr }
+ #vertical-rl { writing-mode: vertical-rl }
+ .override { min-inline-size: 5px }
+</style>
+<fieldset id=horizontal-tb><div></div></fieldset>
+<fieldset id=vertical-lr><div></div></fieldset>
+<fieldset id=vertical-rl><div></div></fieldset>
+<script>
+ for (const className of ['', 'override']) {
+ const expected = className === '' ? '100px' : '5px';
+ test(() => {
+ const fieldset = document.getElementById('horizontal-tb');
+ fieldset.className = className;
+ assert_equals(getComputedStyle(fieldset).width, expected, 'width');
+ assert_equals(getComputedStyle(fieldset).height, '0px', 'height');
+ }, `horizontal-tb ${className}`);
+
+ test(() => {
+ const fieldset = document.getElementById('vertical-lr');
+ fieldset.className = className;
+ assert_equals(getComputedStyle(fieldset).width, '0px', 'width');
+ assert_equals(getComputedStyle(fieldset).height, expected, 'height');
+ }, `vertical-lr ${className}`);
+
+ test(() => {
+ const fieldset = document.getElementById('vertical-rl');
+ fieldset.className = className;
+ assert_equals(getComputedStyle(fieldset).width, '0px', 'width');
+ assert_equals(getComputedStyle(fieldset).height, expected, 'height');
+ }, `vertical-rl ${className}`);
+ }
+</script>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/multicol-legend-becomes-floated-crash.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/multicol-legend-becomes-floated-crash.html
new file mode 100644
index 0000000000..0e7f87232a
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/multicol-legend-becomes-floated-crash.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org">
+<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1122722">
+<fieldset id="fieldset">
+ <legend id="legend"></legend>
+</fieldset>
+<script>
+ document.body.offsetTop;
+ fieldset.style.columns = "2";
+ legend.style.cssFloat = "left";
+</script>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/no-red-ref.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/no-red-ref.html
new file mode 100644
index 0000000000..32b7d46d6f
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/no-red-ref.html
@@ -0,0 +1,3 @@
+<!doctype html>
+<title>Reference there should be no red</title>
+<p>There should be no red.</p>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/resources/fieldset-vertical.css b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/resources/fieldset-vertical.css
new file mode 100644
index 0000000000..b358d925a7
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/resources/fieldset-vertical.css
@@ -0,0 +1,18 @@
+body > div { display: inline-block }
+fieldset, .fieldset { padding: 0; height:10em; width:2em; border:1em groove; margin: 0em; line-height:1 }
+legend, .legend { padding: 0; width: 1em }
+.legend {
+ background: white; /* overlap the border to emulate the border not being painted */
+ display: table; /* shrink-wrap */
+}
+
+[style="writing-mode: vertical-lr"] .legend {
+ margin-left: -1em;
+}
+[style="writing-mode: vertical-rl"] .legend {
+ margin-right: -1em;
+}
+.top { margin-bottom: auto }
+.center { margin-top: auto; margin-bottom: auto }
+.bottom { margin-top: auto }
+.rtl { direction: rtl }
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/second-legend-becomes-rendered-legend-crash.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/second-legend-becomes-rendered-legend-crash.html
new file mode 100644
index 0000000000..6e36b3bb5a
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/second-legend-becomes-rendered-legend-crash.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org">
+<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1119400">
+<fieldset>
+ <legend id="legend1"></legend>
+ <legend id="legend2"><div id="child" style="float:left;"></div></legend>
+</fieldset>
+<script>
+ requestAnimationFrame(()=> {
+ requestAnimationFrame(()=> {
+ legend1.style.display = "none";
+ document.body.offsetTop;
+
+ child.style.width = "22px";
+ document.body.offsetTop;
+
+ child.style.display = "none";
+ });
+ });
+</script>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/sticky-content-crash.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/sticky-content-crash.html
new file mode 100644
index 0000000000..a6e8fa7a82
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/sticky-content-crash.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<link rel="help" href="http://crbug.com/1146872">
+<body>
+<fieldset><span><span></span></span></fieldset>
+<div id="host"><span></span></div>
+<script>
+const host = document.querySelector('#host');
+const shadowRoot = host.attachShadow({mode: 'closed'});
+const fieldset = shadowRoot.appendChild(document.createElement('fieldset'));
+fieldset.setAttribute('style', 'overflow: scroll');
+fieldset.innerHTML = '<slot></slot>';
+</script>
+<style>
+*:not(fieldset, div) {
+ position: sticky;
+ bottom: 72pc;
+}
+fieldset {
+ overflow: visible scroll;
+}
+</style>
+</body>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/sticky-content-ref.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/sticky-content-ref.html
new file mode 100644
index 0000000000..95e3c05cd8
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/sticky-content-ref.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<body>
+<style>
+body {
+ margin: 0;
+}
+
+.fieldset div {
+ height:1000px;
+}
+
+span {
+ background: lime;
+ display: block;
+ height: 40px;
+ position: absolute;
+ top: 4px;
+ left: 0px;
+ width: 40px;
+}
+
+.fieldset {
+ border: none;
+ height: 400px;
+ margin: 0;
+ overflow: scroll;
+ padding: 0;
+}
+</style>
+<div class="fieldset"><div><span></span></div></div>
+<script>
+document.querySelector('.fieldset').scrollTop = 1000;
+</script>
+</body>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/sticky-content.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/sticky-content.html
new file mode 100644
index 0000000000..f60d9ec528
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-fieldset-and-legend-elements/sticky-content.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<link rel="help" href="http://crbug.com/1146925">
+<link rel="match" href="sticky-content-ref.html">
+<body>
+<style>
+body {
+ margin: 0;
+}
+
+fieldset div {
+ height:1000px;
+}
+
+span {
+ background: lime;
+ display: block;
+ height: 40px;
+ position: sticky;
+ top: 4px;
+ width: 40px;
+}
+
+fieldset {
+ border: none;
+ height: 400px;
+ margin: 0;
+ overflow: scroll;
+ padding: 0;
+}
+</style>
+<fieldset><div><span></span></div></fieldset>
+<script>
+document.querySelector('fieldset').scrollTop = 1000;
+</script>
+</body>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-frameset-and-frame-elements/different-writing-modes.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-frameset-and-frame-elements/different-writing-modes.html
new file mode 100644
index 0000000000..c697d4dbbf
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-frameset-and-frame-elements/different-writing-modes.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<link rel="match" href="reference/different-writing-modes-ref.html">
+<style>
+frame {
+ writing-mode: vertical-rl;
+}
+</style>
+<frameset cols="50%,*" rows="50%,*">
+ <frame src="resources/green.html"></frame>
+ <frame src="resources/green.html"></frame>
+ <frame></frame>
+</frameset>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-frameset-and-frame-elements/exceed-then-not-exceed.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-frameset-and-frame-elements/exceed-then-not-exceed.html
new file mode 100644
index 0000000000..85a5b98ae5
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-frameset-and-frame-elements/exceed-then-not-exceed.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+promise_test(async () => {
+ await new Promise(resolve => document.addEventListener('DOMContentLoaded', resolve, {once:true}));
+ await new Promise(resolve => requestAnimationFrame(resolve));
+ await new Promise(resolve => requestAnimationFrame(resolve));
+ // #fs1, #container, and #child were laid out.
+
+ // Move #child.
+ // It makes #container dirty, and it exceeds from #fs1's 1x1 grid.
+ document.querySelector('#fs1').insertBefore(
+ document.querySelector('#child'), document.querySelector('#container'));
+ await new Promise(resolve => requestAnimationFrame(resolve));
+ await new Promise(resolve => requestAnimationFrame(resolve));
+
+ // Removing #child makes #container visible again.
+ document.querySelector('#child').remove();
+ await new Promise(resolve => requestAnimationFrame(resolve));
+ await new Promise(resolve => requestAnimationFrame(resolve));
+}, 'No crash when a dirty FRAMESET exceeds from the grid then fits in it again');
+</script>
+</head>
+<frameset id="fs1">
+<frameset id="container">
+<frameset id="child"></frameset>
+</frameset>
+</frameset>
+</html>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-frameset-and-frame-elements/frameset-visibility-hidden.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-frameset-and-frame-elements/frameset-visibility-hidden.html
new file mode 100644
index 0000000000..b6c454b03f
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-frameset-and-frame-elements/frameset-visibility-hidden.html
@@ -0,0 +1,7 @@
+<!DOCTYPE html>
+<link rel="author" title="Xianzhu Wang" href="mailto:wangxianzhu@chromium.org">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/rendering.html#frames-and-framesets">
+<link rel="match" href="reference/empty-ref.html">
+<frameset cols="100%" style="visibility: hidden">
+ <frame src="resources/red.html">
+</frameset>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-frameset-and-frame-elements/large-cols-abssize.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-frameset-and-frame-elements/large-cols-abssize.html
new file mode 100644
index 0000000000..ba55da8686
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-frameset-and-frame-elements/large-cols-abssize.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/rendering.html#frames-and-framesets">
+<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1116832">
+<link rel="match" href="reference/green-ref.html">
+<frameset cols="4294967227%,*" frameborder="0">
+ <frame src="resources/green.html">
+ <frame src="resources/red.html">
+</frameset>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-frameset-and-frame-elements/large-cols-percentage.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-frameset-and-frame-elements/large-cols-percentage.html
new file mode 100644
index 0000000000..ba55da8686
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-frameset-and-frame-elements/large-cols-percentage.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/rendering.html#frames-and-framesets">
+<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1116832">
+<link rel="match" href="reference/green-ref.html">
+<frameset cols="4294967227%,*" frameborder="0">
+ <frame src="resources/green.html">
+ <frame src="resources/red.html">
+</frameset>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-frameset-and-frame-elements/large-cols-relsize.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-frameset-and-frame-elements/large-cols-relsize.html
new file mode 100644
index 0000000000..f056aa7e30
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-frameset-and-frame-elements/large-cols-relsize.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/rendering.html#frames-and-framesets">
+<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1116832">
+<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1353277">
+<script>
+window.onload = () => {
+ test(() => {
+ const frameSet = document.querySelector('frameset');
+ const frames = document.querySelectorAll('frame');
+ assert_less_than(frames[0].offsetWidth, frameSet.offsetWidth);
+ assert_greater_than(frames[0].offsetWidth, frames[1].offsetWidth);
+ assert_greater_than_equal(frames[1].offsetWidth, 0);
+ }, 'A large relative value should not produce weird sizes.');
+};
+</script>
+<frameset cols="4294967227*,*" frameborder="0">
+ <frame src="resources/green.html">
+ <frame src="resources/red.html">
+</frameset>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-frameset-and-frame-elements/large-rows-abssize.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-frameset-and-frame-elements/large-rows-abssize.html
new file mode 100644
index 0000000000..7cd86b9455
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-frameset-and-frame-elements/large-rows-abssize.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/rendering.html#frames-and-framesets">
+<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1116832">
+<link rel="match" href="reference/green-ref.html">
+<frameset rows="4294967227%,*" frameborder="0">
+ <frame src="resources/green.html">
+ <frame src="resources/red.html">
+</frameset>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-frameset-and-frame-elements/large-rows-percentage.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-frameset-and-frame-elements/large-rows-percentage.html
new file mode 100644
index 0000000000..7cd86b9455
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-frameset-and-frame-elements/large-rows-percentage.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/rendering.html#frames-and-framesets">
+<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1116832">
+<link rel="match" href="reference/green-ref.html">
+<frameset rows="4294967227%,*" frameborder="0">
+ <frame src="resources/green.html">
+ <frame src="resources/red.html">
+</frameset>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-frameset-and-frame-elements/large-rows-relsize.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-frameset-and-frame-elements/large-rows-relsize.html
new file mode 100644
index 0000000000..c33cd44adf
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-frameset-and-frame-elements/large-rows-relsize.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/rendering.html#frames-and-framesets">
+<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1116832">
+<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1353277">
+<script>
+window.onload = () => {
+ test(() => {
+ const frameSet = document.querySelector('frameset');
+ const frames = document.querySelectorAll('frame');
+ assert_less_than(frames[0].offsetHeight, frameSet.offsetHeight);
+ assert_greater_than(frames[0].offsetHeight, frames[1].offsetHeight);
+ assert_greater_than_equal(frames[1].offsetHeight, 0);
+ }, 'A large relative value should not produce weird sizes.');
+};
+</script>
+<frameset rows="4294967227*,*" frameborder="0">
+ <frame src="resources/green.html">
+ <frame src="resources/red.html">
+</frameset>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-frameset-and-frame-elements/multicol-table-crash.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-frameset-and-frame-elements/multicol-table-crash.html
new file mode 100644
index 0000000000..adfb76e15a
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-frameset-and-frame-elements/multicol-table-crash.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<link rel="help" href="http://crbug.com/1383361">
+<body style="columns:2">
+<div id="parent" style="display:table-caption"></div>
+<script>
+const caption = document.querySelector('#parent');
+const frameset = caption.appendChild(document.createElement('frameset'));
+frameset.setAttribute('rows', '100%');
+frameset.setAttribute('cols', '100%');
+frameset.innerHTML = '<frame srcdoc=""></frame><frame srcdoc=""></frame>';
+</script>
+</body>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-frameset-and-frame-elements/reference/different-writing-modes-ref.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-frameset-and-frame-elements/reference/different-writing-modes-ref.html
new file mode 100644
index 0000000000..9d5e5977f0
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-frameset-and-frame-elements/reference/different-writing-modes-ref.html
@@ -0,0 +1,6 @@
+<!DOCTYPE html>
+<frameset cols="50%,*" rows="50%,*">
+ <frame src="../resources/green.html"></frame>
+ <frame src="../resources/green.html"></frame>
+ <frame></frame>
+</frameset>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-frameset-and-frame-elements/reference/empty-ref.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-frameset-and-frame-elements/reference/empty-ref.html
new file mode 100644
index 0000000000..0e76edd65b
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-frameset-and-frame-elements/reference/empty-ref.html
@@ -0,0 +1 @@
+<!DOCTYPE html>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-frameset-and-frame-elements/reference/green-ref.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-frameset-and-frame-elements/reference/green-ref.html
new file mode 100644
index 0000000000..62208d72c9
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-frameset-and-frame-elements/reference/green-ref.html
@@ -0,0 +1,5 @@
+<!DOCTYPE html>
+<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org">
+<style>
+ body { background: green; }
+</style>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-frameset-and-frame-elements/resources/green.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-frameset-and-frame-elements/resources/green.html
new file mode 100644
index 0000000000..62208d72c9
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-frameset-and-frame-elements/resources/green.html
@@ -0,0 +1,5 @@
+<!DOCTYPE html>
+<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org">
+<style>
+ body { background: green; }
+</style>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-frameset-and-frame-elements/resources/red.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-frameset-and-frame-elements/resources/red.html
new file mode 100644
index 0000000000..b5e7f79617
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-frameset-and-frame-elements/resources/red.html
@@ -0,0 +1,5 @@
+<!DOCTYPE html>
+<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org">
+<style>
+ body { background: red; }
+</style>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-hr-element-0/align-ref.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-hr-element-0/align-ref.html
new file mode 100644
index 0000000000..9e4283e208
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-hr-element-0/align-ref.html
@@ -0,0 +1,31 @@
+
+<!doctype html>
+<meta charset=utf-8>
+<style>
+.hr {
+ color: gray;
+ border-style: inset;
+ border-width: 1px;
+ margin: 0.5em auto;
+ width: 100px;
+}
+
+.left {
+ margin-left: 0;
+}
+
+.right {
+ margin-right: 0;
+}
+</style>
+<div class='hr'></div>
+<div class='hr left'></div>
+<div class='hr'></div>
+<div class='hr right'></div>
+<div class='hr'></div>
+
+<div class='hr'></div>
+<div class='hr left'></div>
+<div class='hr'></div>
+<div class='hr right'></div>
+<div class='hr'></div>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-hr-element-0/align.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-hr-element-0/align.html
new file mode 100644
index 0000000000..1657f2458d
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-hr-element-0/align.html
@@ -0,0 +1,24 @@
+<!doctype html>
+<meta charset="utf-8">
+<link rel="match" href="align-ref.html">
+<style>
+hr {
+ width: 100px;
+}
+</style>
+
+<hr align=>
+<hr align=left>
+<hr align=center>
+<hr align=right>
+<hr align=foobar>
+
+<script>
+// Test the IDL attribute
+const values = ['', 'left', 'center', 'right', 'foobar'];
+values.forEach(value => {
+ const hr = document.createElement('hr');
+ hr.align = value;
+ document.body.appendChild(hr);
+});
+</script>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-hr-element-0/color-ref.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-hr-element-0/color-ref.html
new file mode 100644
index 0000000000..5cd35c83ad
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-hr-element-0/color-ref.html
@@ -0,0 +1,22 @@
+<!doctype html>
+<meta charset=utf-8>
+<style>
+.hr {
+ color: gray;
+ border-style: inset;
+ border-width: 1px;
+ margin: 0.5em auto;
+}
+
+.green {
+ color: green;
+}
+
+.no-inset {
+ border-style: solid;
+}
+</style>
+<div class='hr'></div>
+<div class='hr no-inset'></div>
+<div class='hr no-inset'></div>
+<div class='hr green no-inset'></div>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-hr-element-0/color.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-hr-element-0/color.html
new file mode 100644
index 0000000000..750f77e5fb
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-hr-element-0/color.html
@@ -0,0 +1,7 @@
+<!doctype html>
+<meta charset=utf-8>
+<link rel=match href="color-ref.html">
+<hr>
+<hr color="">
+<hr color=transparent>
+<hr color=green>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-hr-element-0/hr.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-hr-element-0/hr.html
new file mode 100644
index 0000000000..e852216494
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-hr-element-0/hr.html
@@ -0,0 +1,55 @@
+<!doctype html>
+<title>The hr element</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<style>
+#ref {
+ display: block;
+ unicode-bidi: isolate;
+ color: gray;
+ border-style: inset;
+ border-width: 1px;
+ margin: 0.5em auto;
+ /* TODO: uncomment this when these properties are widely supported
+ margin-block-start: 0.5em;
+ margin-inline-end: auto;
+ margin-block-end: 0.5em;
+ margin-inline-start: auto;
+ */
+ overflow: hidden;
+}
+</style>
+
+<hr id=test>
+<div id=ref></div>
+
+<script>
+setup(() => {
+ self.testStyle = getComputedStyle(document.getElementById('test'));
+ self.refStyle = getComputedStyle(document.getElementById('ref'));
+});
+['display',
+ 'unicodeBidi',
+ 'color',
+ 'borderTopStyle',
+ 'borderRightStyle',
+ 'borderBottomStyle',
+ 'borderLeftStyle',
+ 'borderTopWidth',
+ 'borderRightWidth',
+ 'borderBottomWidth',
+ 'borderLeftWidth',
+ 'marginTop',
+ 'marginRight',
+ 'marginBottom',
+ 'marginLeft',
+ 'overflow',
+ // Extra tests
+ 'height',
+ 'box-sizing',
+].forEach(prop => {
+ test(() => {
+ assert_equals(testStyle[prop], refStyle[prop]);
+ }, prop);
+});
+</script>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-hr-element-0/setting-overflow-visible.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-hr-element-0/setting-overflow-visible.html
new file mode 100644
index 0000000000..11e3d63e34
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-hr-element-0/setting-overflow-visible.html
@@ -0,0 +1,64 @@
+<!doctype html>
+<title>The hr element: setting 'overflow: visible'</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<style>
+/* Use 0 margin for hr instead of default 0.5em to make things simpler */
+hr {
+ margin-top: 0;
+ margin-bottom: 0;
+}
+.wrapper {
+ height: 150px;
+ position: relative;
+}
+#test-visible {
+ overflow: visible;
+}
+.float, hr::before {
+ content: "";
+ float: left;
+ width: 50px;
+ height: 50px;
+ background-color: orange;
+}
+.clear {
+ clear: left;
+}
+</style>
+
+<div class=wrapper>
+ <div class=float></div>
+ <hr id=test-control>
+ <div class=float></div>
+</div>
+
+<div class=wrapper>
+ <div class=float></div>
+ <hr id=test-visible>
+ <div class=float></div>
+</div>
+
+<script>
+
+test(() => {
+ const hr = document.getElementById('test-control');
+ assert_equals(hr.offsetLeft, 50, 'hr.offsetLeft');
+ assert_equals(hr.offsetTop, 0, 'hr.offsetTop');
+ assert_equals(hr.clientHeight, 50, 'hr.clientHeight');
+ const divAfter = hr.nextElementSibling;
+ assert_equals(divAfter.offsetLeft, 0, 'divAfter.offsetLeft');
+ assert_equals(divAfter.offsetTop, 50 + 1 + 1 /* hr border */, 'divAfter.offsetTop');
+}, 'control');
+
+test(() => {
+ const hr = document.getElementById('test-visible');
+ assert_equals(hr.offsetLeft, 0, 'hr.offsetLeft');
+ assert_equals(hr.offsetTop, 0, 'hr.offsetTop');
+ assert_equals(hr.clientHeight, 0, 'hr.clientHeight');
+ const divAfter = hr.nextElementSibling;
+ assert_equals(divAfter.offsetLeft, 50 + 50, 'divAfter.offsetLeft');
+ assert_equals(divAfter.offsetTop, 1 + 1 /* hr border */, 'divAfter.offsetTop');
+}, 'overflow: visible');
+
+</script>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-hr-element-0/width-ref.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-hr-element-0/width-ref.html
new file mode 100644
index 0000000000..71e7651c1a
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-hr-element-0/width-ref.html
@@ -0,0 +1,19 @@
+<style>
+.hr {
+ color: gray;
+ border-style: inset;
+ border-width: 1px;
+ margin: 0.5em auto;
+}
+</style>
+<div class=hr></div>
+<div class=hr style="width: 50%"></div>
+<div class=hr style="width: 100px"></div>
+<div class=hr style="width: 100px"></div>
+<div class=hr style="width: 100px"></div>
+<div class=hr style="width: 100.99px"></div>
+<div class=hr style="width: 0%"></div>
+<div class=hr style="width: 0%"></div>
+<div class=hr></div>
+<div class=hr></div>
+<div class=hr></div>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-hr-element-0/width.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-hr-element-0/width.html
new file mode 100644
index 0000000000..a436d2ae25
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-hr-element-0/width.html
@@ -0,0 +1,15 @@
+<!doctype html>
+<meta charset="utf-8">
+<title></title>
+<link rel="match" href="width-ref.html">
+<hr>
+<hr width='50%'>
+<hr width='100'>
+<hr width='100foo'>
+<hr width=' 100 '>
+<hr width='100.99'>
+<hr width='0'>
+<hr width='00'>
+<hr width='+0'>
+<hr width='+00'>
+<hr width='++0'>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/body-margin-1-ref.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/body-margin-1-ref.html
new file mode 100644
index 0000000000..3d9d45ec94
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/body-margin-1-ref.html
@@ -0,0 +1,2 @@
+<!doctype html>
+<iframe src="data:text/html,<!doctype html><body style='margin-left: 100px; margin-right: 100px;'>100px left/right margins, default top/bottom margins</body>"></iframe>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/body-margin-1a.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/body-margin-1a.html
new file mode 100644
index 0000000000..ba891d5021
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/body-margin-1a.html
@@ -0,0 +1,5 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Test that body's marginwidth attribute has the right effect in standards mode</title>
+<link rel=match href="body-margin-1-ref.html">
+<iframe src="data:text/html,<!doctype html><body marginwidth='100'>100px left/right margins, default top/bottom margins</body>"></iframe>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/body-margin-1b.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/body-margin-1b.html
new file mode 100644
index 0000000000..431f74be29
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/body-margin-1b.html
@@ -0,0 +1,5 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Test that body's marginwidth attribute has the right effect in quirks mode</title>
+<link rel=match href="body-margin-1-ref.html">
+<iframe src="data:text/html,<body marginwidth='100'>100px left/right margins, default top/bottom margins</body>"></iframe>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/body-margin-1c.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/body-margin-1c.html
new file mode 100644
index 0000000000..84eb4cfe82
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/body-margin-1c.html
@@ -0,0 +1,5 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Test that body's leftmargin/rightmargin attributes have the right effect in standards mode</title>
+<link rel=match href="body-margin-1-ref.html">
+<iframe src="data:text/html,<!doctype html><body leftmargin='100' rightmargin='100'>100px left/right margins, default top/bottom margins</body>"></iframe>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/body-margin-1d.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/body-margin-1d.html
new file mode 100644
index 0000000000..938d4c2c0b
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/body-margin-1d.html
@@ -0,0 +1,5 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Test that body's leftmargin/rightmargin attributes have the right effect in quirks mode</title>
+<link rel=match href="body-margin-1-ref.html">
+<iframe src="data:text/html,<body leftmargin='100' rightmargin='100'>100px left/right margins, default top/bottom margins</body>"></iframe>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/body-margin-1e.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/body-margin-1e.html
new file mode 100644
index 0000000000..8cc463fb15
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/body-margin-1e.html
@@ -0,0 +1,5 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Test that iframe's marginwidth attribute has the right effect in standards mode</title>
+<link rel=match href="body-margin-1-ref.html">
+<iframe marginwidth="100" src="data:text/html,<!doctype html><body>100px left/right margins, default top/bottom margins</body>"></iframe>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/body-margin-1f.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/body-margin-1f.html
new file mode 100644
index 0000000000..2f123b392c
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/body-margin-1f.html
@@ -0,0 +1,5 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Test that iframe's marginwidth attribute has the right effect in quirks mode</title>
+<link rel=match href="body-margin-1-ref.html">
+<iframe marginwidth="100" src="data:text/html,<body>100px left/right margins, default top/bottom margins</body>"></iframe>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/body-margin-1g.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/body-margin-1g.html
new file mode 100644
index 0000000000..052455390c
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/body-margin-1g.html
@@ -0,0 +1,5 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Test that body's style margin takes precedence over everything else in standards mode</title>
+<link rel=match href="body-margin-1-ref.html">
+<iframe marginwidth="20" src="data:text/html,<!doctype html><body marginwidth='30' leftmargin='40' rightmargin='50' style='margin-left: 100px; margin-right: 100px'>100px left/right margins, default top/bottom margins</body>"></iframe>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/body-margin-1h.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/body-margin-1h.html
new file mode 100644
index 0000000000..6778945494
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/body-margin-1h.html
@@ -0,0 +1,5 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Test that body's style margin takes precedence over everything else in quirks mode</title>
+<link rel=match href="body-margin-1-ref.html">
+<iframe marginwidth="20" src="data:text/html,<body marginwidth='30' leftmargin='40' rightmargin='50' style='margin-left: 100px; margin-right: 100px'>100px left/right margins, default top/bottom margins</body>"></iframe>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/body-margin-1i.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/body-margin-1i.html
new file mode 100644
index 0000000000..95e21e3626
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/body-margin-1i.html
@@ -0,0 +1,5 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Test that body's marginwidth attribute takes precedence over other body margin presentational attributes in standards mode</title>
+<link rel=match href="body-margin-1-ref.html">
+<iframe marginwidth="20" src="data:text/html,<!doctype html><body marginwidth='100' leftmargin='40' rightmargin='50'>100px left/right margins, default top/bottom margins</body>"></iframe>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/body-margin-1j.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/body-margin-1j.html
new file mode 100644
index 0000000000..4f945853d8
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/body-margin-1j.html
@@ -0,0 +1,5 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Test that body's marginwidth attribute takes precedence over other body margin presentational attributes in quirks mode</title>
+<link rel=match href="body-margin-1-ref.html">
+<iframe marginwidth="20" src="data:text/html,<body marginwidth='100' leftmargin='40' rightmargin='50'>100px left/right margins, default top/bottom margins</body>"></iframe>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/body-margin-1k.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/body-margin-1k.html
new file mode 100644
index 0000000000..c05cd24e2d
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/body-margin-1k.html
@@ -0,0 +1,5 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Test that body's leftmargin/rightmargin attributes take precedence over iframe marginwidth in standards mode</title>
+<link rel=match href="body-margin-1-ref.html">
+<iframe marginwidth="20" src="data:text/html,<!doctype html><body leftmargin='100' rightmargin='100'>100px left/right margins, default top/bottom margins</body>"></iframe>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/body-margin-1l.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/body-margin-1l.html
new file mode 100644
index 0000000000..f53d2c5a1d
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/body-margin-1l.html
@@ -0,0 +1,5 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Test that body's leftmargin/rightmargin attributes take precedence over iframe marginwidth in quirks mode</title>
+<link rel=match href="body-margin-1-ref.html">
+<iframe marginwidth="20" src="data:text/html,<body leftmargin='100' rightmargin='100'>100px left/right margins, default top/bottom margins</body>"></iframe>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/body-margin-2-ref.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/body-margin-2-ref.html
new file mode 100644
index 0000000000..1bda1a8928
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/body-margin-2-ref.html
@@ -0,0 +1,2 @@
+<!doctype html>
+<iframe src="data:text/html,<!doctype html><body style='margin-top: 100px; margin-bottom: 100px;'>100px top/bottom margins, default left/right margins</body>"></iframe>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/body-margin-2a.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/body-margin-2a.html
new file mode 100644
index 0000000000..9091ab2c78
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/body-margin-2a.html
@@ -0,0 +1,5 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Test that body's marginheight attribute has the right effect in standards mode</title>
+<link rel=match href="body-margin-2-ref.html">
+<iframe src="data:text/html,<!doctype html><body marginheight='100'>100px top/bottom margins, default left/right margins</body>"></iframe>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/body-margin-2b.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/body-margin-2b.html
new file mode 100644
index 0000000000..dd7d74b635
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/body-margin-2b.html
@@ -0,0 +1,5 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Test that body's marginheight attribute has the right effect in quirks mode</title>
+<link rel=match href="body-margin-2-ref.html">
+<iframe src="data:text/html,<body marginheight='100'>100px top/bottom margins, default left/right margins</body>"></iframe>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/body-margin-2c.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/body-margin-2c.html
new file mode 100644
index 0000000000..f72e4b6c71
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/body-margin-2c.html
@@ -0,0 +1,5 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Test that body's topmargin/bottommargin attributes have the right effect in standards mode</title>
+<link rel=match href="body-margin-2-ref.html">
+<iframe src="data:text/html,<!doctype html><body topmargin='100' bottommargin='100'>100px top/bottom margins, default left/right margins</body>"></iframe>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/body-margin-2d.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/body-margin-2d.html
new file mode 100644
index 0000000000..40799b2277
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/body-margin-2d.html
@@ -0,0 +1,5 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Test that body's topmargin/bottommargin attributes have the right effect in quirks mode</title>
+<link rel=match href="body-margin-2-ref.html">
+<iframe src="data:text/html,<body topmargin='100' bottommargin='100'>100px top/bottom margins, default left/right margins</body>"></iframe>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/body-margin-2e.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/body-margin-2e.html
new file mode 100644
index 0000000000..bab012bcf0
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/body-margin-2e.html
@@ -0,0 +1,5 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Test that iframe's marginheight attribute has the right effect in standards mode</title>
+<link rel=match href="body-margin-2-ref.html">
+<iframe marginheight="100" src="data:text/html,<!doctype html><body>100px top/bottom margins, default left/right margins</body>"></iframe>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/body-margin-2f.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/body-margin-2f.html
new file mode 100644
index 0000000000..103cde96d9
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/body-margin-2f.html
@@ -0,0 +1,5 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Test that iframe's marginheight attribute has the right effect in quirks mode</title>
+<link rel=match href="body-margin-2-ref.html">
+<iframe marginheight="100" src="data:text/html,<body>100px top/bottom margins, default left/right margins</body>"></iframe>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/body-margin-2g.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/body-margin-2g.html
new file mode 100644
index 0000000000..b87acacefe
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/body-margin-2g.html
@@ -0,0 +1,5 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Test that body's style margin takes precedence over everything else in standards mode</title>
+<link rel=match href="body-margin-2-ref.html">
+<iframe marginheight="20" src="data:text/html,<!doctype html><body marginheight='30' topmargin='40' bottommargin='50' style='margin-top: 100px; margin-bottom: 100px'>100px top/bottom margins, default left/right margins</body>"></iframe>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/body-margin-2h.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/body-margin-2h.html
new file mode 100644
index 0000000000..53f5267f71
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/body-margin-2h.html
@@ -0,0 +1,5 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Test that body's style margin takes precedence over everything else in quirks mode</title>
+<link rel=match href="body-margin-2-ref.html">
+<iframe marginheight="20" src="data:text/html,<body marginheight='30' topmargin='40' bottommargin='50' style='margin-top: 100px; margin-bottom: 100px'>100px top/bottom margins, default left/right margins</body>"></iframe>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/body-margin-2i.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/body-margin-2i.html
new file mode 100644
index 0000000000..642972ea33
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/body-margin-2i.html
@@ -0,0 +1,5 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Test that body's marginheight attribute takes precedence over other body margin presentational attributes in standards mode</title>
+<link rel=match href="body-margin-2-ref.html">
+<iframe marginheight="20" src="data:text/html,<!doctype html><body marginheight='100' topmargin='40' bottommargin='50'>100px top/bottom margins, default left/right margins</body>"></iframe>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/body-margin-2j.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/body-margin-2j.html
new file mode 100644
index 0000000000..f1b1689f1f
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/body-margin-2j.html
@@ -0,0 +1,5 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Test that body's marginheight attribute takes precedence over other body margin presentational attributes in quirks mode</title>
+<link rel=match href="body-margin-2-ref.html">
+<iframe marginheight="20" src="data:text/html,<body marginheight='100' topmargin='40' bottommargin='50'>100px top/bottom margins, default left/right margins</body>"></iframe>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/body-margin-2k.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/body-margin-2k.html
new file mode 100644
index 0000000000..d11febeb5d
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/body-margin-2k.html
@@ -0,0 +1,5 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Test that body's topmargin/bottommargin attributes take precedence over iframe marginheight in standards mode</title>
+<link rel=match href="body-margin-2-ref.html">
+<iframe marginheight="20" src="data:text/html,<!doctype html><body topmargin='100' bottommargin='100'>100px top/bottom margins, default left/right margins</body>"></iframe>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/body-margin-2l.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/body-margin-2l.html
new file mode 100644
index 0000000000..2f947b984f
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/body-margin-2l.html
@@ -0,0 +1,5 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Test that body's topmargin/bottommargin attributes take precedence over iframe marginheight in quirks mode</title>
+<link rel=match href="body-margin-2-ref.html">
+<iframe marginheight="20" src="data:text/html,<body topmargin='100' bottommargin='100'>100px top/bottom margins, default left/right margins</body>"></iframe>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/body_link.xhtml b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/body_link.xhtml
new file mode 100644
index 0000000000..b93435de8a
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/body_link.xhtml
@@ -0,0 +1,16 @@
+<html xmlns='http://www.w3.org/1999/xhtml'>
+<head>
+<title>body - LINK=yellow</title>
+</head>
+<body link="yellow">
+<p> Test for <b> link="yellow" </b> on body </p>
+
+This <a href="test-body.xhtml">LINK</a> should be displayed in <b>yellow</b><i> if it has not been clicked before </i><br/>
+<p>Once clicked, the link will take default color of visited link.<br /></p>
+<p>To run this test again in browsers, delete your browsing history and navigate to this page.<br /></p>
+
+<p>
+<i>Note - This test checks for User Agent requirement as per HTML5 spec NOT the author requirement</i>
+</p>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/body_text_00ffff-ref.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/body_text_00ffff-ref.html
new file mode 100644
index 0000000000..c907a119f8
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/body_text_00ffff-ref.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>[body - TEXT=00ffff] Reference file</title>
+<link rel="author" title="Intel" href="http://www.intel.com">
+<style>
+ body {
+ color: blue;
+ }
+</style>
+<body>
+ <p>This document should have text color 'Blue' using the RGB Hexadecimal color value of "0000ff". </p>
+ <p>This test passes if the color of text above matches the image below.</p>
+ <p><img src="/images/blue.png"/></p>
+</body>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/body_text_00ffff.xhtml b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/body_text_00ffff.xhtml
new file mode 100644
index 0000000000..42b8aa3b6b
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/body_text_00ffff.xhtml
@@ -0,0 +1,12 @@
+<html xmlns='http://www.w3.org/1999/xhtml'>
+<head>
+<title>body - TEXT=00ffff</title>
+<link rel="match" href="body_text_00ffff-ref.html"/>
+<meta name="assert" content="Test checks that User Agent requirement as per HTML5 spec NOT the author requirement."/>
+</head>
+<body text="0000ff">
+<p>This document should have text color 'Blue' using the RGB Hexadecimal color value of "0000ff". </p>
+<p>This test passes if the color of text above matches the image below.</p>
+<p><img src="/images/blue.png" /></p>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/crashtests/body-huge-attr-value-crash.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/crashtests/body-huge-attr-value-crash.html
new file mode 100644
index 0000000000..b7aea03bf3
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/crashtests/body-huge-attr-value-crash.html
@@ -0,0 +1,9 @@
+<html xmlns="http://www.w3.org/1999/xhtml" xlink="http://www.w3.org/1999/xlink">
+<meta charset="utf-8">
+<link rel="author" href="mailto:0xdevssh@gmail.com">
+<link rel="help" href="https://crbug.com/1238543">
+<meta name="assert" content="The renderer should not crash.">
+ <body topmargin="62099815446794541154677680790275022478020296315411546776807902750224780254115467768079027502247802349339973475906291022478020296313493399734759062916145353182409398397817693775043304346030250203150386848140862367251147544337900224780202963134933997347590629161453531824093983978176937750433043460302502031503868481408623672511475443379061453531824093983978176937750433043460302502031503868481408623672511475443379012223934551240400478945189095326288308770771506289350685029953926171692408537507190372257890049958209064274944598761777623561353561543911257846386780780067311874929239209275379981860757">
+
+ </body>
+</html> \ No newline at end of file
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/iframe-body-margin-attributes.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/iframe-body-margin-attributes.html
new file mode 100644
index 0000000000..e1f4fb5154
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/iframe-body-margin-attributes.html
@@ -0,0 +1,32 @@
+<!doctype html>
+<title>iframe and body margin attributes</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<body marginwidth=20 marginheight=20 topmargin=10 rightmargin=10 bottommargin=10 leftmargin=10>
+<iframe data-desc="iframe marginwidth vs child body leftmargin" src="support/body-topmargin-leftmargin.html" marginwidth=10 marginheight=10></iframe>
+<iframe data-desc="iframe marginwidth vs child body marginwidth" src="support/body-marginwidth-marginheight.html" marginwidth=10 marginheight=10></iframe>
+<script>
+setup({explicit_done: true});
+
+onload = () => {
+ test(() => {
+ const style = getComputedStyle(document.body);
+ assert_style_props(style);
+ }, 'body marginwidth vs body leftmargin');
+
+ [].forEach.call(document.querySelectorAll('iframe'), iframe => {
+ test(() => {
+ const win = iframe.contentWindow;
+ const style = win.getComputedStyle(win.document.body);
+ assert_style_props(style);
+ }, iframe.dataset.desc);
+ });
+ done();
+}
+
+function assert_style_props(style) {
+ for (let prop of ['marginTop', 'marginRight', 'marginBottom', 'marginLeft']) {
+ assert_equals(style[prop], '20px', prop);
+ }
+}
+</script>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/iframe-marginwidth-marginheight.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/iframe-marginwidth-marginheight.html
new file mode 100644
index 0000000000..b09cafbbe4
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/iframe-marginwidth-marginheight.html
@@ -0,0 +1,12 @@
+<!doctype html>
+<title>iframe marginwidth and marginheight</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<iframe src="/common/blank.html" marginwidth=0 marginheight=0></iframe>
+<script>
+setup({ single_test: true });
+onload = () => {
+ assert_equals(window[0].document.body.attributes.length, 0, "Number of attributes on the child document's body");
+ done();
+}
+</script>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/iframe-scrolling-attribute-ref.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/iframe-scrolling-attribute-ref.html
new file mode 100644
index 0000000000..424e039e3f
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/iframe-scrolling-attribute-ref.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<title>iframe: changing the scrolling attribute</title>
+<link rel="author" href="mailto:masonf@chromium.org">
+
+
+
+<style>
+ iframe {
+ width: 100px;
+ height: 100px;
+ }
+</style>
+
+<p>These two iframes should *both* render with scrollbars:</p>
+<iframe src="support/big-page.html" scrolling="unknown"></iframe>
+<iframe src="support/big-page.html" scrolling="unknown"></iframe>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/iframe-scrolling-attribute-values-ref.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/iframe-scrolling-attribute-values-ref.html
new file mode 100644
index 0000000000..2ead59af39
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/iframe-scrolling-attribute-values-ref.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<title>The scrolling attribute</title>
+<link rel="author" href="mailto:masonf@chromium.org">
+
+
+
+<style>
+ iframe {
+ width: 100px;
+ height: 100px;
+ }
+</style>
+
+<p>This page tests the behavior of the <tt>scrolling</tt> attribute on
+<tt>&lt;iframe&gt;</tt> elements which contain a page large enough to need to
+be scrolled.</p>
+
+<iframe src="support/big-page.html" scrolling="auto"></iframe>
+<iframe src="support/big-page.html" scrolling="auto"></iframe>
+<iframe src="support/big-page.html" scrolling="auto"></iframe>
+<iframe src="support/big-page.html" scrolling="auto"></iframe>
+<iframe src="support/big-page.html" scrolling="auto"></iframe>
+<iframe src="support/big-page.html" scrolling="no"></iframe>
+<iframe src="support/big-page.html" scrolling="no"></iframe>
+<iframe src="support/big-page.html" scrolling="no"></iframe>
+<iframe src="support/big-page.html" scrolling="no"></iframe>
+<iframe src="support/big-page.html" scrolling="auto"></iframe>
+<iframe src="support/big-page.html" scrolling="auto"></iframe>
+
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/iframe-scrolling-attribute-values.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/iframe-scrolling-attribute-values.html
new file mode 100644
index 0000000000..997745ba48
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/iframe-scrolling-attribute-values.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<title>The scrolling attribute</title>
+<link rel="author" href="mailto:masonf@chromium.org">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/rendering.html#the-page">
+<link rel="match" href="iframe-scrolling-attribute-values-ref.html">
+<meta name="fuzzy" content="maxDifference=0-1;totalPixels=0-4">
+
+<style>
+ iframe {
+ width: 100px;
+ height: 100px;
+ }
+</style>
+
+<p>This page tests the behavior of the <tt>scrolling</tt> attribute on
+<tt>&lt;iframe&gt;</tt> elements which contain a page large enough to need to
+be scrolled.</p>
+
+<iframe src="support/big-page.html"></iframe>
+<iframe src="support/big-page.html" scrolling></iframe>
+<iframe src="support/big-page.html" scrolling=""></iframe>
+<iframe src="support/big-page.html" scrolling="auto"></iframe>
+<iframe src="support/big-page.html" scrolling="yes"></iframe>
+<iframe src="support/big-page.html" scrolling="no"></iframe>
+<iframe src="support/big-page.html" scrolling="noscroll"></iframe>
+<iframe src="support/big-page.html" scrolling="off"></iframe>
+<iframe src="support/big-page.html" scrolling="NoScRoLl"></iframe>
+<iframe src="support/big-page.html" scrolling="bogus"></iframe>
+<iframe src="support/big-page.html" scrolling="1234"></iframe>
+
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/iframe-scrolling-attribute.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/iframe-scrolling-attribute.html
new file mode 100644
index 0000000000..d04e2dd56f
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/iframe-scrolling-attribute.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<title>iframe: changing the scrolling attribute</title>
+<link rel="author" href="mailto:masonf@chromium.org">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/rendering.html#the-page">
+<link rel="match" href="iframe-scrolling-attribute-ref.html">
+
+<style>
+ iframe {
+ width: 100px;
+ height: 100px;
+ }
+</style>
+
+<p>These two iframes should *both* render with scrollbars:</p>
+<iframe src="support/big-page.html" scrolling="unknown"></iframe>
+<iframe src="support/big-page.html" scrolling="unknown"></iframe>
+
+<script>
+ var iframe = document.getElementsByTagName("iframe")[1];
+ // Setting scrolling=no and then back to scrolling=unknown
+ // should result in a final value of auto.
+ iframe.setAttribute("scrolling", "no");
+ iframe.setAttribute("scrolling", "unknown");
+</script>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/support/big-page.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/support/big-page.html
new file mode 100644
index 0000000000..65f2a65bcf
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/support/big-page.html
@@ -0,0 +1,2 @@
+<p>Scroll me</p>
+<div style="width: 400px; height: 400px; background-color: blue"></div>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/support/body-marginwidth-marginheight.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/support/body-marginwidth-marginheight.html
new file mode 100644
index 0000000000..5d825e3455
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/support/body-marginwidth-marginheight.html
@@ -0,0 +1,2 @@
+<!doctype html>
+<body marginwidth=20 marginheight=20>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/support/body-topmargin-leftmargin.html b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/support/body-topmargin-leftmargin.html
new file mode 100644
index 0000000000..7ba5e53330
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/support/body-topmargin-leftmargin.html
@@ -0,0 +1,2 @@
+<!doctype html>
+<body topmargin=20 rightmargin=20 bottommargin=20 leftmargin=20>
diff --git a/testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/test-body.xhtml b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/test-body.xhtml
new file mode 100644
index 0000000000..cd733b17ba
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/non-replaced-elements/the-page/test-body.xhtml
@@ -0,0 +1,8 @@
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title> This is a test page</title>
+</head>
+<body>
+<p> To rerun this test, delete history and go <a href="body_link.xhtml">back </a> to previous test.</p>
+</body>
+</html> \ No newline at end of file
diff --git a/testing/web-platform/tests/html/rendering/pixel-length-attributes.html b/testing/web-platform/tests/html/rendering/pixel-length-attributes.html
new file mode 100644
index 0000000000..888e6d0a3f
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/pixel-length-attributes.html
@@ -0,0 +1,173 @@
+<!doctype html>
+<meta charset=utf-8>
+<!-- Creating iframes is slow in browsers -->
+<meta name=timeout content=long>
+<title>Test handling of attributes that map to pixel length properties</title>
+<link rel="help"
+ href="https://html.spec.whatwg.org/multipage/rendering.html#maps-to-the-pixel-length-property">
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<body>
+ <div id="container" style="display: none">
+ <img id="defaultImg">
+ <object id="defaultObject"></object>
+ <input type="image" id="defaultInput"></input>
+ </div>
+<script>
+ /*
+ * This test tests
+ * https://html.spec.whatwg.org/multipage/rendering.html#maps-to-the-pixel-length-property
+ * for various elements and various values.
+ */
+
+ /*
+ * Array of input/output pairs. The input is the string to use as the
+ * attribute value. The output is the string expected as the computed style
+ * for the relevant CSS property.
+ */
+const valid_values = [
+ [ "200", "200px" ],
+ [ "1007", "1007px" ],
+ [ " 00523 ", "523px" ],
+ [ "200.", "200px" ],
+ [ "200.25", "200px" ],
+ [ "200.7", "200px" ],
+ [ "0", "0px" ],
+ [ "-0", "0px" ],
+ [ "+0", "0px" ],
+ [ "+200", "200px" ],
+ [ "200in", "200px" ],
+ [ "200.25in", "200px" ],
+ [ " +200in ", "200px" ],
+ [ "200%", "200px" ],
+ [ "200.%", "200px" ],
+ [ "200.25%", "200px" ],
+];
+
+ /*
+ * Array of invalid values. These should lead to the default value of the
+ * relevant CSS property.
+ */
+const invalid_values = [
+ "-200",
+ "-200px",
+ " -200",
+ "+-200",
+ "-+200",
+];
+
+/*
+ * Array of tests. Each test consists of the following information:
+ *
+ * 1) A function to call to create the element to test. This returns a
+ * 3-element array: The element to set the attribute on, the element to
+ * compute style on, and a cleanup function to call when done.
+ * 2) The name of the attribute to set.
+ * 3) The name of the computed style property to get.
+ * 4) An element that can be used to determine the fallback style value for
+ * invalid values.
+ */
+const tests = [
+ [ createIframe, "marginwidth", "marginLeft", document.body ],
+ [ createIframe, "marginwidth", "marginRight", document.body ],
+ [ createIframe, "marginheight", "marginTop", document.body ],
+ [ createIframe, "marginheight", "marginBottom", document.body ],
+ [ createFrame, "marginwidth", "marginLeft", document.body ],
+ [ createFrame, "marginwidth", "marginRight", document.body ],
+ [ createFrame, "marginheight", "marginTop", document.body ],
+ [ createFrame, "marginheight", "marginBottom", document.body ],
+ [ createBody, "marginwidth", "marginLeft", document.body ],
+ [ createBody, "marginwidth", "marginRight", document.body ],
+ [ createBody, "leftmargin", "marginLeft", document.body ],
+ [ createBody, "rightmargin", "marginRight", document.body ],
+ [ createBody, "marginheight", "marginTop", document.body ],
+ [ createBody, "marginheight", "marginBottom", document.body ],
+ [ createBody, "topmargin", "marginTop", document.body ],
+ [ createBody, "bottommargin", "marginBottom", document.body ],
+ [ newElem("img"), "border", "borderTopWidth", defaultImg ],
+ [ newElem("img"), "border", "borderRightWidth", defaultImg ],
+ [ newElem("img"), "border", "borderBottomWidth", defaultImg ],
+ [ newElem("img"), "border", "borderLeftWidth", defaultImg ],
+ [ newElem("object"), "border", "borderTopWidth", defaultObject ],
+ [ newElem("object"), "border", "borderRightWidth", defaultObject ],
+ [ newElem("object"), "border", "borderBottomWidth", defaultObject ],
+ [ newElem("object"), "border", "borderLeftWidth", defaultObject ],
+ [ newImageInput, "border", "borderTopWidth", defaultInput ],
+ [ newImageInput, "border", "borderRightWidth", defaultInput ],
+ [ newImageInput, "border", "borderBottomWidth", defaultInput ],
+ [ newImageInput, "border", "borderLeftWidth", defaultInput ],
+];
+
+function newElem(name) {
+ return () => {
+ var elem = document.createElement(name);
+ document.getElementById("container").appendChild(elem);
+ return [ elem, elem, () => elem.remove() ];
+ }
+}
+
+function newImageInput() {
+ var elem = document.createElement("input");
+ elem.type = "image";
+ document.getElementById("container").appendChild(elem);
+ return [ elem, elem, () => elem.remove() ];
+}
+
+function createIframe() {
+ let ifr = document.createElement("iframe");
+ document.body.appendChild(ifr);
+ return [ ifr, ifr.contentDocument.body, () => ifr.remove() ];
+ }
+
+function createBody() {
+ let ifr = document.createElement("iframe");
+ document.body.appendChild(ifr);
+ return [ ifr.contentDocument.body, ifr.contentDocument.body, () => ifr.remove() ];
+}
+
+function createFrame() {
+ // We need to create a separate iframe to put our frameset into.
+ let ifr = document.createElement("iframe");
+ document.body.appendChild(ifr);
+ let doc = ifr.contentDocument;
+ let root = doc.documentElement;
+ while (root.firstChild) {
+ root.firstChild.remove();
+ }
+ let frameset = doc.createElement("frameset");
+ frameset.setAttribute("rows", "*");
+ frameset.setAttribute("cols", "*");
+ let frame = doc.createElement("frame");
+ frameset.appendChild(frame);
+ root.appendChild(frameset);
+ return [ frame, frame.contentDocument.body, () => ifr.remove() ];
+}
+
+function style(element) {
+ return element.ownerDocument.defaultView.getComputedStyle(element);
+}
+
+for (let [setup, attr, prop, default_elem] of tests) {
+ for (let [value, result] of valid_values) {
+ let [ attr_elem, prop_elem, cleanup ] = setup();
+ test(function() {
+ this.add_cleanup(cleanup);
+ attr_elem.setAttribute(attr, value);
+ assert_equals(attr_elem.getAttribute(attr), value);
+ assert_equals(style(prop_elem)[prop], result);
+ }, `<${attr_elem.localName} ${attr}="${value}"> mapping to ${prop}`);
+ }
+
+ let defaultVal = style(default_elem)[prop];
+ for (let value of invalid_values) {
+ let [ attr_elem, prop_elem, cleanup ] = setup();
+ test(function() {
+ this.add_cleanup(cleanup);
+ attr_elem.setAttribute(attr, value);
+ assert_equals(attr_elem.getAttribute(attr), value);
+ assert_equals(style(prop_elem)[prop], defaultVal);
+ }, `<${attr_elem.localName} ${attr}="${value}"> mapping to ${prop}`);
+ }
+}
+</script>
+</body>
diff --git a/testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/align.html b/testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/align.html
new file mode 100644
index 0000000000..b5f3ec1aa6
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/align.html
@@ -0,0 +1,59 @@
+<!doctype html>
+<title>align attribute mapping on replaced elements</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<img id="replaced" src="/images/green.png">
+<something id="non-replaced"></something>
+<script>
+const kMapping = {
+ "left": ["float", "left"],
+ "right": ["float", "right"],
+
+ "top": ["vertical-align", "top"],
+
+ // This one requires a magic value (`-moz-middle-with-baseline` on Gecko,
+ // `-webkit-baseline-middle` on WebKit-based browsers).
+ "middle": ["vertical-align", undefined],
+ // These are inconsistent across browsers. WebKit maps it to "middle", Gecko
+ // to the aforementioned value.
+ "center": ["vertical-align", undefined],
+
+ "baseline": ["vertical-align", "baseline"],
+ "bottom": ["vertical-align", "baseline"], // *shrug*
+
+ "texttop": ["vertical-align", "text-top"],
+ "absmiddle": ["vertical-align", "middle"],
+ "abscenter": ["vertical-align", "middle"],
+ "absbottom": ["vertical-align", "bottom"],
+};
+
+const kInitialValues = {
+ "vertical-align": "baseline",
+ "float": "none",
+};
+
+let replaced = document.getElementById("replaced");
+let nonReplaced = document.getElementById("non-replaced");
+let t = async_test("align attribute mapping");
+onload = t.step_func_done(function() {
+ for (const attributeValue in kMapping) {
+ for (const element of [replaced, nonReplaced]) {
+ test(function() {
+ element.setAttribute("align", attributeValue);
+ let [property, expected] = kMapping[attributeValue];
+ let actual = getComputedStyle(element).getPropertyValue(property);
+ if (element == nonReplaced) {
+ assert_equals(actual, kInitialValues[property], "align shouldn't map to non-replaced elements")
+ } else {
+ if (expected) {
+ assert_equals(actual, expected, `align=${attributeValue} should map to ${property}: ${expected}`);
+ } else {
+ assert_equals(property, "vertical-align");
+ assert_not_equals(actual, "baseline", `align=${attributeValue} should map a vertical-align value`);
+ }
+ }
+ }, `align=${attributeValue} on ${element == replaced ? "replaced" : "non-replaced"} elements`);
+ }
+ }
+});
+</script>
diff --git a/testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/canvas-aspect-ratio.html b/testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/canvas-aspect-ratio.html
new file mode 100644
index 0000000000..dbe4c7d9f3
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/canvas-aspect-ratio.html
@@ -0,0 +1,52 @@
+<!doctype html>
+<title>Canvas width and height attributes are used as the surface size, and also to infer aspect ratio</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/aspect-ratio.js"></script>
+<style>
+ canvas {
+ width: 100%;
+ max-width: 100px;
+ height: auto;
+ }
+</style>
+<body>
+<canvas id="contained" width="250" height="100" style="contain: size;"></canvas>
+<script>
+function assert_ratio(img, expected) {
+ let epsilon = 0.001;
+ assert_approx_equals(parseInt(getComputedStyle(img).width, 10) / parseInt(getComputedStyle(img).height, 10), expected, epsilon);
+}
+
+function test_computed_style(width, height, expected) {
+ test_computed_style_aspect_ratio("canvas", {width: width, height: height}, expected);
+}
+
+test(function() {
+ canvas = document.getElementById("contained");
+ assert_ratio(canvas, 2.5);
+}, "Canvas width and height attributes are used as the surface size with contain:size");
+
+// Create and append a new canvas and immediately check the ratio.
+test(function() {
+ var canvas = document.createElement("canvas");
+ canvas.setAttribute("width", "250");
+ canvas.setAttribute("height", "100");
+ document.body.appendChild(canvas);
+ // Canvases always use the aspect ratio from their surface size.
+ assert_ratio(canvas, 2.5);
+}, "Canvas width and height attributes are used as the surface size");
+
+test_computed_style("10", "20", "auto 10 / 20");
+test_computed_style("0", "1", "auto 0 / 1");
+test_computed_style("1", "0", "auto 1 / 0");
+test_computed_style("0", "0", "auto 0 / 0");
+test_computed_style("0.5", "1.5", "auto 0 / 1");
+test_computed_style("10%", "20", "auto 10 / 20");
+test_computed_style(null, null, "auto");
+test_computed_style("10", null, "auto");
+test_computed_style(null, "20", "auto");
+test_computed_style("xx", "20", "auto");
+test_computed_style("20", "xx", "auto");
+
+</script>
diff --git a/testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/content-aspect-ratio.html b/testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/content-aspect-ratio.html
new file mode 100644
index 0000000000..42be8ce7a8
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/content-aspect-ratio.html
@@ -0,0 +1,25 @@
+<!doctype html>
+<title>div with content style's width and height attributes are not used to infer aspect-ratio</title>
+<link rel="help" href="https://bugs.webkit.org/show_bug.cgi?id=201641#c22">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<style>
+ video {
+ width: 100%;
+ max-width: 100px;
+ height: auto;
+ }
+</style>
+<body>
+<script>
+// Create and append a div with content style and immediately check the height.
+let t = test(function() {
+ var div = document.createElement("div");
+ div.setAttribute("style", "content: url('/images/blue.png')");
+ div.setAttribute("width", "250");
+ div.setAttribute("height", "100");
+ document.body.appendChild(div);
+ assert_equals(getComputedStyle(div).height, "0px");
+}, "div with content style's width and height attributes are not used to infer aspect-ratio");
+
+</script>
diff --git a/testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/embedded-and-images-presentational-hints-ascii-case-insensitive.html b/testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/embedded-and-images-presentational-hints-ascii-case-insensitive.html
new file mode 100644
index 0000000000..8fafb0c7f0
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/embedded-and-images-presentational-hints-ascii-case-insensitive.html
@@ -0,0 +1,46 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<link rel="help" href="https://html.spec.whatwg.org/#attributes-for-embedded-content-and-images:presentational-hints">
+<link rel="help" href="https://drafts.csswg.org/selectors-4/#attribute-case">
+<meta name="assert" content="@align values on embedded content and images are ASCII case-insensitive">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<img src="fuchsia.png" align="absbottom">
+<img src="fuchsia.png" align="AbSbOtToM">
+<img src="fuchsia.png" align="abſbottom">
+<img src="fuchsia.png" align="abscenter">
+<img src="fuchsia.png" align="AbScEnTeR">
+<img src="fuchsia.png" align="abſcenter">
+<img src="fuchsia.png" align="absmiddle">
+<img src="fuchsia.png" align="AbSmIdDlE">
+<img src="fuchsia.png" align="abſmiddle">
+<script>
+const img = document.querySelectorAll("img");
+
+test(() => {
+ assert_equals(getComputedStyle(img[0]).getPropertyValue("vertical-align"),
+ "bottom", "lowercase valid");
+ assert_equals(getComputedStyle(img[1]).getPropertyValue("vertical-align"),
+ "bottom", "mixed case valid");
+ assert_equals(getComputedStyle(img[2]).getPropertyValue("vertical-align"),
+ "baseline", "non-ASCII invalid");
+}, "keyword absbottom");
+
+test(() => {
+ assert_equals(getComputedStyle(img[3]).getPropertyValue("vertical-align"),
+ "middle", "lowercase valid");
+ assert_equals(getComputedStyle(img[4]).getPropertyValue("vertical-align"),
+ "middle", "mixed case valid");
+ assert_equals(getComputedStyle(img[5]).getPropertyValue("vertical-align"),
+ "baseline", "non-ASCII invalid");
+}, "keyword abscenter");
+
+test(() => {
+ assert_equals(getComputedStyle(img[6]).getPropertyValue("vertical-align"),
+ "middle", "lowercase valid");
+ assert_equals(getComputedStyle(img[7]).getPropertyValue("vertical-align"),
+ "middle", "mixed case valid");
+ assert_equals(getComputedStyle(img[8]).getPropertyValue("vertical-align"),
+ "baseline", "non-ASCII invalid");
+}, "keyword absmiddle");
+</script>
diff --git a/testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/img-alt-crash-001.html b/testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/img-alt-crash-001.html
new file mode 100644
index 0000000000..b057967e7e
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/img-alt-crash-001.html
@@ -0,0 +1,15 @@
+<!doctype html>
+<title>Crash test: img alt rendering in combination with style attribute selector</title>
+<link rel="help" href="https://crbug.com/1057210">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<style>
+ img { display: block; width: 100px; }
+ [style] + * {}
+</style>
+<img id="img" alt="alternative text">
+<script>
+ test(() => {
+ assert_equals(getComputedStyle(img).width, "100px");
+ }, "Should not crash.");
+</script>
diff --git a/testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/img-aspect-ratio-lazy.html b/testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/img-aspect-ratio-lazy.html
new file mode 100644
index 0000000000..1833efb804
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/img-aspect-ratio-lazy.html
@@ -0,0 +1,36 @@
+<!doctype html>
+<title>Image width and height attributes are used to infer aspect-ratio for lazy-loaded images</title>
+<meta name="viewport" content="width=device-width">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<style>
+ img {
+ width: 100%;
+ max-width: 100px;
+ height: auto;
+ }
+</style>
+<div style="height: 600vh"></div>
+<img src="/images/green.png" loading="lazy" width=100 height=100>
+<script>
+let t = async_test("Image width and height attributes are used to infer aspect-ratio for lazy-loaded images");
+
+function assert_ratio(img, expected) {
+ let epsilon = 0.001;
+ assert_approx_equals(parseFloat(getComputedStyle(img).width, 10) / parseFloat(getComputedStyle(img).height, 10), expected, epsilon);
+}
+
+t.step(function() {
+ let img = document.querySelector("img");
+ // The initial aspect ratio is given by the width/height attributes:
+ // https://html.spec.whatwg.org/#map-to-the-aspect-ratio-property-(using-dimension-rules)
+ assert_ratio(img, 1.0);
+ img.addEventListener("load", t.step_func_done(function() {
+ // Now the element "represents an image":
+ // https://html.spec.whatwg.org/multipage/rendering.html#images-3
+ // 2.0 is the original aspect ratio of green.png
+ assert_ratio(img, 2.0);
+ }));
+ window.scrollTo(0, img.getBoundingClientRect().top);
+});
+</script>
diff --git a/testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/img-aspect-ratio.html b/testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/img-aspect-ratio.html
new file mode 100644
index 0000000000..4dee3cf7ad
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/img-aspect-ratio.html
@@ -0,0 +1,120 @@
+<!doctype html>
+<title>Image width and height attributes are used to infer aspect-ratio</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="resources/aspect-ratio.js"></script>
+<style>
+ img {
+ width: 100%;
+ max-width: 100px;
+ height: auto;
+ }
+</style>
+<img src="/images/green.png">
+<img src="/images/green.png" width=100 height=125>
+<img src="" width=100 height=125>
+<img src="error.png" width=100 height=125>
+<img src="error.png">
+<img src="error.png" alt="Alt text" width=100 height=500>
+<script>
+let guard = async_test("Image width and height attributes are used to infer aspect-ratio");
+let cookie = Math.random();
+function assert_ratio(img, expected, description) {
+ let epsilon = 0.001;
+ assert_approx_equals(parseFloat(getComputedStyle(img).width, 10) / parseFloat(getComputedStyle(img).height, 10),
+ expected, epsilon, description);
+}
+
+function test_computed_style(width, height, expected) {
+ test_computed_style_aspect_ratio("img", {width: width, height: height}, expected);
+ test_computed_style_aspect_ratio("input", {type: "image", width: width, height: height}, expected);
+ // input type=submit should not do this mapping.
+ test_computed_style_aspect_ratio("input", {type: "submit", width: width, height: height}, "auto");
+}
+
+// Create and append a new image and immediately check the ratio.
+// We append a random query to the URL(s) to avoid matching something in the 'list
+// of available images' (step 6 of the algorithm below) and thus have the actual
+// load run in a microtask.
+// https://html.spec.whatwg.org/multipage/images.html#updating-the-image-data
+test(function() {
+ // This img will be tested again after loaded. In order to locate it correctly, body should append it first.
+ var img = new Image();
+ img.width = 250;
+ img.height = 100;
+ img.src = "/images/blue.png?" + cookie;
+ document.body.appendChild(img);
+ assert_ratio(img, 2.5);
+}, "Create, append and test immediately: <img> with attributes width=250, height=100");
+
+test(function () {
+ img = new Image();
+ img.setAttribute("width", "0.8");
+ img.setAttribute("height", "0.2");
+ img.src = "/images/blue.png?" + (cookie + 1);
+ document.body.appendChild(img);
+ assert_ratio(img, 4);
+}, "Create, append and test immediately: <img> with attributes width=0.8, height=0.2");
+
+test(function () {
+ img = new Image();
+ img.setAttribute("width", "50%");
+ img.setAttribute("height", "25%");
+ img.src = "/images/blue.png?" + (cookie + 2);
+ document.body.appendChild(img);
+ // Percentages should be ignored.
+ assert_equals(getComputedStyle(img).height, "0px");
+}, "Create, append and test immediately: <img> with attributes width=50% height=25%");
+
+test(function () {
+ img = new Image();
+ img.setAttribute("width", "50pp");
+ img.setAttribute("height", "25xx");
+ img.src = "/images/blue.png?" + (cookie + 3);
+ document.body.appendChild(img);
+ assert_ratio(img, 2);
+}, "Create, append and test immediately: <img> with invalid trailing attributes width=50pp height=25xx");
+
+test_computed_style("10", "20", "auto 10 / 20");
+test_computed_style("0", "1", "auto 0 / 1");
+test_computed_style("1", "0", "auto 1 / 0");
+test_computed_style("0", "0", "auto 0 / 0");
+test_computed_style("0.5", "1.5", "auto 0.5 / 1.5");
+test_computed_style(null, null, "auto");
+test_computed_style("10", null, "auto");
+test_computed_style(null, "20", "auto");
+test_computed_style("xx", "20", "auto");
+test_computed_style("10%", "20", "auto");
+
+onload = function() {
+ let images = document.querySelectorAll("img");
+ // Tests for images finished loading.
+ test(function() {
+ assert_ratio(images[0], 2.0, "2.0 is the original aspect ratio of green.png");
+ }, "Loaded images test: <img> without width height attributes");
+
+ test(function() {
+ assert_ratio(images[1], 2.0, "Loaded image's aspect ratio, at least by default, overrides width / height ratio.");
+ }, "Loaded images test: <img> with width and height attributes, but conflicting to the original aspect ratio");
+
+ test(function () {
+ assert_ratio(images[2], 100 / 125, "aspect-ratio should override intrinsic size of images that don't have any src.");
+ }, "Loaded images test: <img> with width, height and empty src attributes");
+
+ test(function () {
+ assert_ratio(images[3], 100 / 125, "aspect-ratio should affect the size of error images.");
+ }, "Loaded images test: Error image with width and height attributes");
+
+ test(function () {
+ assert_not_equals(images[5].offsetHeight, 500, "Images with alt text should be inline and ignore the aspect ratio");
+ // Though aspect-ratio is ignored, its value does not change.
+ assert_equals(getComputedStyle(images[5]).aspectRatio, "auto 100 / 500");
+ }, "Loaded images test: Error image with width, height and alt attributes");
+
+ test(function () {
+ assert_ratio(images[6], 133 / 106, "The original aspect ratio of blue.png");
+ }, "Loaded images test: <img> with width and height attributes, but not equal to the original aspect ratio");
+
+ guard.done();
+};
+</script>
diff --git a/testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/img-dim-ref.html b/testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/img-dim-ref.html
new file mode 100644
index 0000000000..b1adb68307
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/img-dim-ref.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>img width/height - reference</title>
+<style>
+p { width: 50px; height: 50px; }
+</style>
+<p><img src=/images/green.png>
+<p><img src=/images/green.png style="width: 10px">
+<p><img src=/images/green.png style="height: 10px">
+<p><img src=/images/green.png style="width: 10%">
+<p><img src=/images/green.png style="height: 10%">
diff --git a/testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/img-dim.html b/testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/img-dim.html
new file mode 100644
index 0000000000..2d636c9417
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/img-dim.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>img width/height</title>
+<link rel=match href=img-dim-ref.html>
+<style>
+p { width: 50px; height: 50px; }
+</style>
+<p><img src=/images/green.png>
+<p><img src=/images/green.png width=10>
+<p><img src=/images/green.png height=10>
+<p><img src=/images/green.png width=10%>
+<p><img src=/images/green.png height=10%>
diff --git a/testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/img-empty-alt-replaced.html b/testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/img-empty-alt-replaced.html
new file mode 100644
index 0000000000..3cc06d6c85
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/img-empty-alt-replaced.html
@@ -0,0 +1,23 @@
+<!doctype html>
+<title>Images with an empty alt attribute have an intrinsic size of zero</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<style>
+ img {
+ width: 50px;
+ height: auto;
+ }
+</style>
+<img src="broken">
+<img src="broken" alt="non-empty">
+<img src="broken" alt="">
+<script>
+const t = async_test("Images with an empty alt attribute have an intrinsic size of zero");
+onload = t.step_func_done(function() {
+ for (const img of document.querySelectorAll("img")) {
+ const alt = img.getAttribute("alt");
+ const shouldTakeUpSpace = alt == null || alt.length > 0;
+ (shouldTakeUpSpace ? assert_not_equals : assert_equals)(img.offsetHeight, 0, img.outerHTML);
+ }
+});
+</script>
diff --git a/testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/img-no-alt-replaced.html b/testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/img-no-alt-replaced.html
new file mode 100644
index 0000000000..5f3503ae3b
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/img-no-alt-replaced.html
@@ -0,0 +1,30 @@
+<!doctype html>
+<title>Images without alt attribute or with an empty alt attribute render as replaced elements regardless of src</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<link rel="author" href="mailto:emilio@crisal.io" title="Emilio Cobos Álvarez">
+<link rel="author" href="mailto:yuzhehan@chromium.org" title="Yu Han">
+<link rel="author" href="https://mozilla.org" title="Mozilla">
+<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1196668">
+<link rel="help" href="https://crbug.com/753868">
+<link ref="help" href="https://html.spec.whatwg.org/multipage/rendering.html#images-3">
+<style>
+ img {
+ width: 100px;
+ height: 150px;
+ }
+</style>
+<img>
+<img src="broken">
+<img alt="">
+<img alt>
+<img src="broken" alt="">
+<script>
+const t = async_test("Images without alt attribute or with an empty alt attribute render as replaced elements regardless of src");
+onload = t.step_func_done(function() {
+ for (const img of document.querySelectorAll("img")) {
+ assert_equals(img.offsetWidth, 100, `width: ${img.outerHTML}`);
+ assert_equals(img.offsetHeight, 150, `height: ${img.outerHTML}`);
+ }
+});
+</script>
diff --git a/testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/img-replaced-box-while-loading.html b/testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/img-replaced-box-while-loading.html
new file mode 100644
index 0000000000..48bbd36db9
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/img-replaced-box-while-loading.html
@@ -0,0 +1,29 @@
+<!doctype html>
+<title>Images don't render as a non-replaced inline while loading, even when there's no concrete size specified</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<link rel="author" href="mailto:emilio@crisal.io" title="Emilio Cobos Álvarez">
+<link rel="author" href="https://mozilla.org" title="Mozilla">
+<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1472637">
+<style>
+ img {
+ min-width: 1000px;
+ }
+</style>
+<img alt="T">
+<script>
+// Do an async test off the onload handler to avoid waiting for the load even for too long unnecessarily.
+let t = async_test("Loading images should get a replaced box, even without specified size");
+onload = t.step_func(function() {
+ const image = document.querySelector("img");
+ // Use the trickle pipe to have 100 seconds until the image actually loads,
+ // that should be enough to run the test.
+ image.src = "../../../../../images/blue.png?pipe=trickle(d100)";
+ t.step_timeout(t.step_func_done(function() {
+ assert_equals(
+ image.offsetWidth,
+ 1000,
+ );
+ }), 0);
+});
+</script>
diff --git a/testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/img-title-only-w-sizing.html b/testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/img-title-only-w-sizing.html
new file mode 100644
index 0000000000..c290d9d6b1
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/img-title-only-w-sizing.html
@@ -0,0 +1,25 @@
+<!doctype html>
+<title>Images with only title should be treated as a replaced element</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<link rel="author" href="mailto:yuzhehan@chromium.org" title="Yu Han">
+<link rel="help" href="https://crbug.com/958250">
+<link ref="help" href="https://html.spec.whatwg.org/multipage/rendering.html#images-3">
+<style>
+ .title-only {
+ width: 100px;
+ height: 150px;
+ }
+</style>
+<img class="title-only" title="title">
+<img width="100" height="150px" title="title">
+<script>
+async_test(t => {
+ onload = t.step_func_done(function() {
+ for (const img of document.querySelectorAll("img")) {
+ assert_equals(img.offsetWidth, 100, `width: ${img.outerHTML}`);
+ assert_equals(img.offsetHeight, 150, `height: ${img.outerHTML}`);
+ }
+ });
+});
+</script>
diff --git a/testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/img_border-ref.xhtml b/testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/img_border-ref.xhtml
new file mode 100644
index 0000000000..0050c542cd
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/img_border-ref.xhtml
@@ -0,0 +1,9 @@
+<html xmlns='http://www.w3.org/1999/xhtml'>
+<head>
+<title>IMG - Border in CSS</title>
+</head>
+<body>
+<p><img src="../../../../../images/blue.png"/></p>
+<p><img src="../../../../../images/blue.png" style="border-width:50px; border-style:solid;"/></p>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/img_border_percent.xhtml b/testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/img_border_percent.xhtml
new file mode 100644
index 0000000000..da74fb32b9
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/img_border_percent.xhtml
@@ -0,0 +1,10 @@
+<html xmlns='http://www.w3.org/1999/xhtml'>
+<head>
+<title>IMG - Border= value in percent</title>
+<link rel="match" href="img_border-ref.xhtml"/>
+</head>
+<body>
+<p><img src="../../../../../images/blue.png" border="0%"/></p>
+<p><img src="../../../../../images/blue.png" border="50%"/></p>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/input-align-right-1.html b/testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/input-align-right-1.html
new file mode 100644
index 0000000000..6e32206d91
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/input-align-right-1.html
@@ -0,0 +1,3 @@
+<!DOCTYPE html>
+<link rel="match" href="input-align-right-ref.html">
+<input type="image" align="right">
diff --git a/testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/input-align-right-2.html b/testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/input-align-right-2.html
new file mode 100644
index 0000000000..d58848aa53
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/input-align-right-2.html
@@ -0,0 +1,3 @@
+<!DOCTYPE html>
+<link rel="match" href="input-align-right-ref.html">
+<input align="right" type="image">
diff --git a/testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/input-align-right-ref.html b/testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/input-align-right-ref.html
new file mode 100644
index 0000000000..55f06ef96b
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/input-align-right-ref.html
@@ -0,0 +1,2 @@
+<!DOCTYPE html>
+<input type="image" style="float: right">
diff --git a/testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/input-image-content-crash.html b/testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/input-image-content-crash.html
new file mode 100644
index 0000000000..84ef2ab153
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/input-image-content-crash.html
@@ -0,0 +1,15 @@
+<!doctype html>
+<title>Crash test: asynchronously applying image content to image input</title>
+<link rel="author" href="mailto:yuzhehan@chromium.org" title="Yu Han">
+<link rel="help" href="https://crbug.com/1096002">
+<style>
+ .content { content: url(data:text/plain,aaa); }
+</style>
+<input id="input" type="image" class=content>
+<script>
+ onload = ()=> {
+ document.body.offsetTop;
+ input.setAttribute('class', '');
+ document.body.offsetTop;
+ }
+</script>
diff --git a/testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/input-image-inline-alt-ref.html b/testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/input-image-inline-alt-ref.html
new file mode 100644
index 0000000000..b3fdc14ef1
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/input-image-inline-alt-ref.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<title>Input image type fallback content should respect display property.</title>
+<meta name="author" title="Yu Han" href="mailto:yuzhehan@chromium.org">
+<style>
+ div {
+ border:1px dashed blue;
+ line-height: 1em;
+ height: 100px;
+ width: 150px;
+ }
+ input {
+ font: 1em monospace;
+ line-height: 1em;
+ }
+</style>
+<div>
+ <input alt="This is a long ALT text which takes up few lines to display. And additional text to be inlined." type="image">
+</div>
diff --git a/testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/input-image-inline-alt.html b/testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/input-image-inline-alt.html
new file mode 100644
index 0000000000..e05ad84191
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/input-image-inline-alt.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<title>Input image type fallback content should respect display property.</title>
+<meta name="author" title="Yu Han" href="mailto:yuzhehan@chromium.org">
+<link rel="match" href="input-image-inline-alt-ref.html">
+<link ref="help" href="https://html.spec.whatwg.org/multipage/rendering.html#images-3:represents-5">
+<style>
+ div {
+ border:1px dashed blue;
+ font: 1em monospace;
+ line-height: 1em;
+ height: 100px;
+ width: 150px;
+ }
+ input {
+ display: inline;
+ font: 1em monospace;
+ line-height: 1em;
+ }
+</style>
+<div>
+ <input alt="This is a long ALT text which takes up few lines to display." type="image">
+ And additional text to be inlined.
+</div>
diff --git a/testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/input-type-change-from-image-1-ref.html b/testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/input-type-change-from-image-1-ref.html
new file mode 100644
index 0000000000..7768379e91
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/input-type-change-from-image-1-ref.html
@@ -0,0 +1,2 @@
+<!DOCTYPE html>
+<input align="right">
diff --git a/testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/input-type-change-from-image-1.html b/testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/input-type-change-from-image-1.html
new file mode 100644
index 0000000000..00747a5fbf
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/input-type-change-from-image-1.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<link rel=match href="input-type-change-from-image-1-ref.html">
+<input type="image" align="right">
+<script>
+ onload = function() {
+ var i = document.querySelector("input");
+ window.rect = i.getBoundingClientRect();
+ i.type = "text";
+ }
+</script>
diff --git a/testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/number-placeholder-right-aligned-ref.html b/testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/number-placeholder-right-aligned-ref.html
new file mode 100644
index 0000000000..61dff1e460
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/number-placeholder-right-aligned-ref.html
@@ -0,0 +1,8 @@
+<!doctype html>
+<style>
+input {
+ color: black;
+ text-align: right;
+}
+</style>
+<input type=number value=0>
diff --git a/testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/number-placeholder-right-aligned.html b/testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/number-placeholder-right-aligned.html
new file mode 100644
index 0000000000..c1c695ffca
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/number-placeholder-right-aligned.html
@@ -0,0 +1,16 @@
+<!doctype html>
+<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=1698043">
+<link rel="match" href="number-placeholder-right-aligned-ref.html">
+<style>
+input {
+ color: black;
+ text-align: right;
+}
+input::placeholder {
+ color: inherit;
+ opacity: 1;
+}
+</style>
+<input type=number placeholder=0>
diff --git a/testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/object_border-ref.xhtml b/testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/object_border-ref.xhtml
new file mode 100644
index 0000000000..6eaaa0ba14
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/object_border-ref.xhtml
@@ -0,0 +1,8 @@
+<html xmlns='http://www.w3.org/1999/xhtml'>
+<head>
+<title>OBJECT - border in CSS</title>
+</head>
+<body>
+<p><object data="../../../../images/blue.png" type="image/png" style="border-width:50px; border-style:solid;"></object></p>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/object_border_perc.xhtml b/testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/object_border_perc.xhtml
new file mode 100644
index 0000000000..3663e9ce61
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/object_border_perc.xhtml
@@ -0,0 +1,9 @@
+<html xmlns='http://www.w3.org/1999/xhtml'>
+<head>
+<title>OBJECT - border=value in %</title>
+<link rel="match" href="object_border-ref.xhtml"/>
+</head>
+<body>
+<p><object data="../../../../images/blue.png" type="image/png" border="50%"></object></p>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/object_border_pixel.xhtml b/testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/object_border_pixel.xhtml
new file mode 100644
index 0000000000..55f7f0a3bf
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/object_border_pixel.xhtml
@@ -0,0 +1,9 @@
+<html xmlns='http://www.w3.org/1999/xhtml'>
+<head>
+<title>OBJECT - border=pixel</title>
+<link rel="match" href="object_border-ref.xhtml"/>
+</head>
+<body>
+<p><object data="../../../../images/blue.png" type="image/png" border="50"></object></p>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/picture-aspect-ratio.html b/testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/picture-aspect-ratio.html
new file mode 100644
index 0000000000..939d7895c3
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/picture-aspect-ratio.html
@@ -0,0 +1,242 @@
+<!doctype html>
+<title>Image width and height attributes are used to infer aspect-ratio</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<style>
+ img:not([nowidth]) {
+ width: 100%;
+ max-width: 100px;
+ height: auto;
+ }
+</style>
+<picture>
+ <source srcset="/images/green-100x50.png"></source>
+ <img>
+</picture>
+
+<picture>
+ <source srcset="/images/green-100x50.png" width="100" height="100"></source>
+ <img>
+</picture>
+
+<picture>
+ <source srcset="/images/green-100x50.png" width="100" height="100"></source>
+ <img width="50" height="100">
+</picture>
+
+<picture>
+ <source srcset="/images/green-100x50.png" width="100" height="100" id="twosource-s1"></source>
+ <source srcset="/images/green-100x50.png" width="300" height="150"></source>
+ <img id="twosource-img">
+</picture>
+
+<div style="width: 100px;">
+ <picture>
+ <source srcset="/images/green-100x50.png" width="100%" height="50%" id="percent-src"></source>
+ <img style="contain:size;" id="percent-img" nowidth="true">
+ </picture>
+</div>
+
+<picture>
+ <source srcset="/images/green-100x50.png" width="100abc" height="50abc" id="trailing-src"></source>
+ <img style="contain:size;" id="trailing-img" nowidth="true">
+</picture>
+
+<script>
+let guard = async_test("source width and height attributes are used to infer aspect-ratio in <picture>");
+function assert_ratio(img, expected, description) {
+ let epsilon = 0.001;
+ assert_approx_equals(parseFloat(getComputedStyle(img).width, 10) / parseFloat(getComputedStyle(img).height, 10),
+ expected, epsilon, description);
+}
+
+function createPicture(width, height) {
+ var picture = document.createElement("picture");
+ var source = document.createElement("source");
+ if (width !== undefined)
+ source.setAttribute("width", width);
+ if (height !== undefined)
+ source.setAttribute("height", height);
+ source.setAttribute("srcset", "/images/green.png");
+ picture.appendChild(source);
+ var img = document.createElement("img");
+ picture.appendChild(img);
+ document.body.appendChild(picture);
+ return img;
+}
+
+function assert_cs(img, val) {
+ assert_equals(getComputedStyle(img).aspectRatio, val);
+}
+
+// Create and append a new image and immediately check the ratio.
+// This is not racy because the spec requires the user agent to queue a task:
+// https://html.spec.whatwg.org/multipage/images.html#updating-the-image-data
+test(function() {
+ var img = createPicture(100, 100);
+ assert_ratio(img, 1.0);
+ assert_cs(img, "auto 100 / 100");
+ img.style.display = "none";
+ img.setAttribute("nowidth", "true");
+ assert_equals(getComputedStyle(img).width, "100px");
+ assert_equals(getComputedStyle(img).height, "100px");
+ var source = img.previousSibling;
+ assert_equals(getComputedStyle(source).width, "auto");
+ assert_equals(getComputedStyle(source).height, "auto");
+}, "Computed style for width/height/aspect-ratio");
+
+test(function() {
+ img = createPicture(200, 100);
+ img.setAttribute("width", 250);
+ img.setAttribute("height", 50);
+ assert_ratio(img, 2.0);
+ assert_cs(img, "auto 200 / 100");
+ img.style.display = "none";
+ img.setAttribute("nowidth", "true");
+ assert_equals(getComputedStyle(img).width, "200px");
+ assert_equals(getComputedStyle(img).height, "100px");
+ source = img.previousSibling;
+ assert_equals(getComputedStyle(source).width, "auto");
+ assert_equals(getComputedStyle(source).height, "auto");
+}, "Source width/height should take precedence over img attributes.");
+
+test(function() {
+ img.parentNode.removeChild(img.previousSibling);
+ assert_cs(img, "auto 250 / 50");
+ img.src = "/images/green.png";
+ assert_ratio(img, 5.0);
+ img.style.display = "none";
+ img.setAttribute("nowidth", "true");
+ assert_equals(getComputedStyle(img).width, "250px");
+ assert_equals(getComputedStyle(img).height, "50px");
+}, "Make sure style gets invalidated correctly when the source gets removed.");
+
+test(function() {
+ img = createPicture(100, undefined);
+ img.setAttribute("width", 200);
+ img.setAttribute("height", 100);
+ assert_cs(img, "auto");
+ img.style.display = "none";
+ img.setAttribute("nowidth", "true");
+ assert_equals(getComputedStyle(img).width, "100px");
+ assert_equals(getComputedStyle(img).height, "auto");
+}, "If the <source> has only one of width/height, we don't get an aspect ratio, even if the <img> has both.");
+
+test(function() {
+ img = createPicture(undefined, undefined);
+ img.setAttribute("width", 200);
+ img.setAttribute("height", 100);
+ assert_cs(img, "auto 200 / 100");
+}, "If we don't have width/height on the source, we fall back to width/height on the <img>.");
+
+test(function() {
+ img = createPicture(100, undefined);
+ img.parentNode.style.display = "none";
+ img.setAttribute("width", "200");
+ img.setAttribute("height", "300");
+ img.setAttribute("nowidth", "true");
+ assert_cs(img, "auto");
+ assert_equals(getComputedStyle(img).width, "100px");
+ assert_equals(getComputedStyle(img).height, "auto");
+}, "If we only have one width attribute, we should get width mapped but no aspect ratio, even if <img> has attributes.");
+
+test(function() {
+ img = createPicture(undefined, 100);
+ img.parentNode.style.display = "none";
+ img.setAttribute("width", "200");
+ img.setAttribute("height", "300");
+ img.setAttribute("nowidth", "true");
+ assert_cs(img, "auto");
+ assert_equals(getComputedStyle(img).width, "auto");
+ assert_equals(getComputedStyle(img).height, "100px");
+}, "If we only have height attribute, we should get height mapped but no aspect ratio, even if <img> has attributes.");
+
+test(function() {
+ img = createPicture(100, 100);
+ assert_cs(img, "auto 100 / 100");
+ img.previousSibling.setAttribute("height", "300");
+ assert_cs(img, "auto 100 / 300");
+ img.previousSibling.setAttribute("width", "10");
+ assert_cs(img, "auto 10 / 300");
+ img.style.display = "none";
+ img.setAttribute("nowidth", "true");
+ assert_equals(getComputedStyle(img).width, "10px");
+ assert_equals(getComputedStyle(img).height, "300px");
+}, "Dynamically changing width/height should change computed style");
+
+test(function() {
+ img = document.getElementById("twosource-img");
+ assert_cs(img, "auto 100 / 100");
+ source = document.getElementById("twosource-s1");
+ source.setAttribute("type", "x-foo/x-bar");
+ // We should now match the second source
+ assert_cs(img, "auto 300 / 150");
+ img.style.display = "none";
+ img.setAttribute("nowidth", "true");
+ assert_equals(getComputedStyle(img).width, "300px");
+ assert_equals(getComputedStyle(img).height, "150px");
+}, "Changing which <source> matches should change computed style");
+
+test(function() {
+ img = document.getElementById("percent-img");
+ assert_equals(img.offsetWidth, 100);
+ assert_equals(img.offsetHeight, 0);
+ assert_cs(img, "auto");
+ source = document.getElementById("percent-src");
+ assert_equals(source.width, 100);
+ assert_equals(source.height, 50);
+ img.style.display = "none";
+ img.setAttribute("nowidth", "true");
+ assert_equals(getComputedStyle(img).width, "100%");
+ assert_equals(getComputedStyle(img).height, "50%");
+}, "Percentages on source should be ignored for aspect-ratio but used for width/height.");
+
+test(function() {
+ img = document.getElementById("trailing-img");
+ assert_equals(img.offsetWidth, 100);
+ assert_equals(img.offsetHeight, 50);
+ assert_cs(img, "auto 100 / 50");
+ source = document.getElementById("trailing-src");
+ assert_equals(source.width, 100);
+ assert_equals(source.height, 50);
+ img.style.display = "none";
+ img.setAttribute("nowidth", "true");
+ assert_equals(getComputedStyle(img).width, "100px");
+ assert_equals(getComputedStyle(img).height, "50px");
+}, "Trailing garbage should be ignored but not make the attribute invalid");
+
+onload = function() {
+ let images = document.querySelectorAll("img");
+ test(function() {
+ var img = images[0];
+ assert_ratio(img, 2.0, "2.0 is the original aspect ratio of green-100x50.png");
+ assert_cs(img, "auto");
+ img.style.display = "none";
+ img.setAttribute("nowidth", "true");
+ assert_equals(getComputedStyle(img).width, "auto");
+ assert_equals(getComputedStyle(img).height, "auto");
+ }, "Loaded picture test: Both <source> and <img> are without width and height attributes");
+
+ test(function () {
+ img = images[1];
+ assert_ratio(img, 2.0, "Loaded image's aspect ratio, at least by default, overrides width / height ratio.");
+ assert_cs(img, "auto 100 / 100");
+ img.style.display = "none";
+ img.setAttribute("nowidth", "true");
+ assert_equals(getComputedStyle(img).width, "100px");
+ assert_equals(getComputedStyle(img).height, "100px");
+ }, "Loaded picture test: <source> with width and height attributes, <img> without width and height attributes");
+
+ test(function () {
+ img = images[2];
+ assert_ratio(img, 2.0, "Loaded image's aspect ratio, at least by default, overrides width / height ratio (2).");
+ assert_cs(img, "auto 100 / 100");
+ img.style.display = "none";
+ img.setAttribute("nowidth", "true");
+ assert_equals(getComputedStyle(img).width, "100px");
+ assert_equals(getComputedStyle(img).height, "100px");
+ }, "Loaded picture test: Both <source> and <img> are with width and height attributes");
+
+ guard.done();
+};
+</script>
diff --git a/testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/resources/aspect-ratio.js b/testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/resources/aspect-ratio.js
new file mode 100644
index 0000000000..c6826f271a
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/resources/aspect-ratio.js
@@ -0,0 +1,14 @@
+function test_computed_style_aspect_ratio(tag, attributes, expected) {
+ test(function() {
+ var elem = document.createElement(tag);
+ for (name in attributes) {
+ let val = attributes[name];
+ if (val !== null)
+ elem.setAttribute(name, val);
+ }
+ document.body.appendChild(elem);
+ let aspectRatio = getComputedStyle(elem).aspectRatio;
+ assert_equals(aspectRatio, expected);
+ elem.remove();
+ }, `Computed style test: ${tag} with ${JSON.stringify(attributes)}`);
+}
diff --git a/testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/video-aspect-ratio.html b/testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/video-aspect-ratio.html
new file mode 100644
index 0000000000..119523d250
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/video-aspect-ratio.html
@@ -0,0 +1,72 @@
+<!doctype html>
+<title>Video width and height attributes are used to infer aspect-ratio</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/media.js"></script>
+<script src="resources/aspect-ratio.js"></script>
+<style>
+ video {
+ width: 100%;
+ max-width: 100px;
+ height: auto;
+ }
+</style>
+<body>
+<video width="250" height="100" id="contained" style="contain: size;"></video>
+<script>
+function assert_ratio(img, expected) {
+ let epsilon = 0.001;
+ assert_approx_equals(parseInt(getComputedStyle(img).width, 10) / parseInt(getComputedStyle(img).height, 10), expected, epsilon);
+}
+
+function test_computed_style(width, height, expected) {
+ test_computed_style_aspect_ratio("video", {width: width, height: height}, expected);
+}
+
+promise_test(async function() {
+ {
+ let video = document.getElementById("contained");
+ video.src = getVideoURI('/media/2x2-green');
+ assert_ratio(video, 2.5, "contain:size aspect ratio");
+ }
+
+ // Create and append a new video and immediately check the ratio.
+ // This is not racy because the spec requires the user agent to queue a task:
+ // https://html.spec.whatwg.org/multipage/media.html#concept-media-load-algorithm
+ {
+ let video = document.createElement("video");
+ video.setAttribute("width", "250");
+ video.setAttribute("height", "100");
+ video.src = getVideoURI('/media/2x2-green');
+ document.body.appendChild(video);
+ assert_ratio(video, 2.5, "aspect ratio for regular video before load");
+ await new Promise(r => video.addEventListener("loadeddata", r, { once: true }));
+ // When loaded this video is square.
+ assert_ratio(video, 1, "aspect ratio for regular video after load");
+ }
+
+ // Same but with auto width.
+ {
+ let video = document.createElement("video");
+ video.setAttribute("width", "250");
+ video.setAttribute("height", "100");
+ video.style.width = "auto";
+ video.src = getVideoURI('/media/2x2-green');
+ document.body.appendChild(video);
+ assert_ratio(video, 2.5, "aspect ratio for regular video with width: auto before load");
+ await new Promise(r => video.addEventListener("loadeddata", r, { once: true }));
+ assert_ratio(video, 1, "aspect ratio for regular video with width: auto after load");
+ }
+
+ test_computed_style("10", "20", "auto 10 / 20");
+ test_computed_style("0.5", "1.5", "auto 0.5 / 1.5");
+ test_computed_style("0", "1", "auto 0 / 1");
+ test_computed_style("1", "0", "auto 1 / 0");
+ test_computed_style("0", "0", "auto 0 / 0");
+ test_computed_style(null, null, "auto");
+ test_computed_style("10", null, "auto");
+ test_computed_style(null, "20", "auto");
+ test_computed_style("xx", "20", "auto");
+ test_computed_style("10%", "20", "auto");
+});
+</script>
diff --git a/testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/video-intrinsic-width-height.html b/testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/video-intrinsic-width-height.html
new file mode 100644
index 0000000000..74989be521
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/replaced-elements/attributes-for-embedded-content-and-images/video-intrinsic-width-height.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>video element intrinsic width/height</title>
+ <link rel="author" title="Sammy Gill" href="sammy.gill@apple.com" />
+ <link rel="help" href="https://github.com/w3c/csswg-drafts/issues/7524" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/rendering.html#replaced-elements" />
+ <link rel="help" href="https://drafts.csswg.org/css-sizing-4/#aspect-ratio" />
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+ <body>
+ <div id="log"></div>
+ <video title="no width/height attributes"
+ data-expected-width="300" data-expected-height="150"></video>
+ <video title="only width attribute"
+ data-expected-width="100" data-expected-height="50"
+ width="100"></video>
+ <video title="only height attribute"
+ data-expected-width="200" data-expected-height="100"
+ height="100"></video>
+ <video title="both width/height attributes"
+ data-expected-width="100" data-expected-height="100"
+ width="100" height="100"></video>
+ <!-- A width:height ratio other than 2:1 and overriding the specified style must be used to
+ verify that width/height does not influence intrinsic ratio -->
+ <video title="both width/height attributes and style"
+ data-expected-width="300" data-expected-height="300"
+ width="100" height="100" style="width: auto; height: auto"></video>
+ <script>
+ Array.prototype.forEach.call(document.querySelectorAll('video'), function(video)
+ {
+ test(function()
+ {
+ assert_equals(video.clientWidth, parseInt(video.dataset.expectedWidth), "width");
+ assert_equals(video.clientHeight, parseInt(video.dataset.expectedHeight), "height");
+ }, video.title);
+ });
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/rendering/replaced-elements/embedded-content-rendering-rules/audio-controls-001.html b/testing/web-platform/tests/html/rendering/replaced-elements/embedded-content-rendering-rules/audio-controls-001.html
new file mode 100644
index 0000000000..eeb4368aaa
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/replaced-elements/embedded-content-rendering-rules/audio-controls-001.html
@@ -0,0 +1,7 @@
+<!DOCTYPE html>
+<title>HTML audio with controls</title>
+<link rel="author" title="Mozilla" href="https://www.mozilla.org/">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/rendering.html#embedded-content-rendering-rules">
+<link rel="mismatch" href="/common/blank.html">
+
+<audio controls></audio>
diff --git a/testing/web-platform/tests/html/rendering/replaced-elements/embedded-content-rendering-rules/audio-controls-002.html b/testing/web-platform/tests/html/rendering/replaced-elements/embedded-content-rendering-rules/audio-controls-002.html
new file mode 100644
index 0000000000..678ba7281e
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/replaced-elements/embedded-content-rendering-rules/audio-controls-002.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<title>HTML audio with controls via Web APIs</title>
+<link rel="author" title="Mozilla" href="https://www.mozilla.org/">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/rendering.html#embedded-content-rendering-rules">
+<link rel="mismatch" href="/common/blank.html">
+
+<audio id="target"></audio>
+
+<script>
+ document.body.offsetTop;
+ document.getElementById("target").setAttribute("controls", "");
+</script>
diff --git a/testing/web-platform/tests/html/rendering/replaced-elements/embedded-content-rendering-rules/audio-without-controls.html b/testing/web-platform/tests/html/rendering/replaced-elements/embedded-content-rendering-rules/audio-without-controls.html
new file mode 100644
index 0000000000..8cc134d6d6
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/replaced-elements/embedded-content-rendering-rules/audio-without-controls.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<title>HTML audio without controls</title>
+<link rel="author" title="Mozilla" href="https://www.mozilla.org/">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/rendering.html#embedded-content-rendering-rules">
+<link rel="match" href="../../../../css/reference/ref-filled-green-100px-square.xht" />
+
+<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
+
+<div style="width: 100px; height: 100px; background: green;">
+ <audio style="display: block; width: 100px; height: 100px; background: red;"></audio>
+</div>
diff --git a/testing/web-platform/tests/html/rendering/replaced-elements/embedded-content-rendering-rules/canvas-fallback-ref.html b/testing/web-platform/tests/html/rendering/replaced-elements/embedded-content-rendering-rules/canvas-fallback-ref.html
new file mode 100644
index 0000000000..9077591f46
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/replaced-elements/embedded-content-rendering-rules/canvas-fallback-ref.html
@@ -0,0 +1,4 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Canvas fallback content</title>
+<p>The word "FAIL" should not be visible below this line.
diff --git a/testing/web-platform/tests/html/rendering/replaced-elements/embedded-content-rendering-rules/canvas-fallback.html b/testing/web-platform/tests/html/rendering/replaced-elements/embedded-content-rendering-rules/canvas-fallback.html
new file mode 100644
index 0000000000..01df0c547a
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/replaced-elements/embedded-content-rendering-rules/canvas-fallback.html
@@ -0,0 +1,26 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Canvas fallback content</title>
+<link rel=match href=canvas-fallback-ref.html>
+<style>
+canvas {
+ height: 2em; /* avoid causing scrollbar for 600x600 viewport */
+}
+
+#canvas2 {
+ display: inline;
+}
+
+#canvas3 {
+ display: block;
+}
+
+#canvas4 {
+ display: table;
+}
+</style>
+<p>The word "FAIL" should not be visible below this line.
+<p><canvas id=canvas1>FAIL</canvas>
+<p><canvas id=canvas2>FAIL</canvas>
+<p><canvas id=canvas3>FAIL</canvas>
+<p><canvas id=canvas4>FAIL</canvas>
diff --git a/testing/web-platform/tests/html/rendering/replaced-elements/embedded-content-rendering-rules/canvas-update-with-border-object-fit-ref.html b/testing/web-platform/tests/html/rendering/replaced-elements/embedded-content-rendering-rules/canvas-update-with-border-object-fit-ref.html
new file mode 100644
index 0000000000..3133ac86f3
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/replaced-elements/embedded-content-rendering-rules/canvas-update-with-border-object-fit-ref.html
@@ -0,0 +1,4 @@
+<!doctype html>
+<div style="width: 200px; height: 100px; background: black; border: 100px solid blue; padding-left: 100px">
+ <div style="width: 100px; height: 100px; background: green"></div>
+</div>
diff --git a/testing/web-platform/tests/html/rendering/replaced-elements/embedded-content-rendering-rules/canvas-update-with-border-object-fit.html b/testing/web-platform/tests/html/rendering/replaced-elements/embedded-content-rendering-rules/canvas-update-with-border-object-fit.html
new file mode 100644
index 0000000000..b20db66eb9
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/replaced-elements/embedded-content-rendering-rules/canvas-update-with-border-object-fit.html
@@ -0,0 +1,31 @@
+<!doctype html>
+<title>Verifies canvas with object-fit and border correctly updates</title>
+<link rel="match" href="canvas-update-with-border-object-fit-ref.html">
+<html class="reftest-wait">
+ <div style="width: 300px; height: 100px; background: black; border: 100px solid blue">
+ <canvas id="target" width="1000" height="1000"
+ style="object-fit: contain; object-position: center; width: 100%; height: 100%">
+ </canvas>
+ </div>
+</html>
+<script>
+var ctx = target.getContext("2d");
+ctx.fillStyle = "red";
+ctx.fillRect(0, 0, target.width, target.height);
+
+var x=0, y=0, step=500;
+ctx.fillStyle = "green";
+function drawRect() {
+ ctx.fillRect(x, y, step, step);
+ x += step;
+ if (x >= target.width) {
+ x = 0;
+ y += step;
+ }
+ if (y >= target.height)
+ document.documentElement.classList.remove("reftest-wait");
+ else
+ requestAnimationFrame(drawRect);
+}
+drawRect();
+</script>
diff --git a/testing/web-platform/tests/html/rendering/replaced-elements/embedded-content-rendering-rules/canvas_scale.html b/testing/web-platform/tests/html/rendering/replaced-elements/embedded-content-rendering-rules/canvas_scale.html
new file mode 100644
index 0000000000..cdc4647534
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/replaced-elements/embedded-content-rendering-rules/canvas_scale.html
@@ -0,0 +1,23 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>Verify that canvases are scaled up to their computed size</title>
+<link rel="match" href="canvas_scale_ref.html">
+<style>
+canvas {
+ width: 20px;
+ height: 20px;
+}
+div {
+ line-height: 0;
+}
+</style>
+<div><canvas width="16" height="16" data-color="#FF00FF"></canvas><canvas width="16" height="16" data-color="#00FF00"></canvas></div>
+<div><canvas width="16" height="16" data-color="#0000FF"></canvas><canvas width="16" height="16" data-color="#FF00FF"></canvas></div>
+<script>
+var canvases = document.getElementsByTagName('canvas');
+for (var i = 0; i < canvases.length; i++) {
+ var ctx = canvases[i].getContext('2d');
+ ctx.fillStyle = canvases[i].getAttribute('data-color');
+ ctx.fillRect(0, 0, 16, 16);
+}
+</script>
diff --git a/testing/web-platform/tests/html/rendering/replaced-elements/embedded-content-rendering-rules/canvas_scale_ref.html b/testing/web-platform/tests/html/rendering/replaced-elements/embedded-content-rendering-rules/canvas_scale_ref.html
new file mode 100644
index 0000000000..2d1756f856
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/replaced-elements/embedded-content-rendering-rules/canvas_scale_ref.html
@@ -0,0 +1,14 @@
+<!doctype html>
+<meta charset="utf-8">
+<style>
+span {
+ display: inline-block;
+ width: 20px;
+ height: 20px;
+}
+div {
+ line-height: 0;
+}
+</style>
+<div><span style="background-color: #FF00FF"></span><span style="background-color: #00FF00"></span></div>
+<div><span style="background-color: #0000FF"></span><span style="background-color: #FF00FF"></span></div>
diff --git a/testing/web-platform/tests/html/rendering/replaced-elements/embedded-content-rendering-rules/canvas_without_context_a.html b/testing/web-platform/tests/html/rendering/replaced-elements/embedded-content-rendering-rules/canvas_without_context_a.html
new file mode 100644
index 0000000000..b7398f8d59
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/replaced-elements/embedded-content-rendering-rules/canvas_without_context_a.html
@@ -0,0 +1,15 @@
+<!doctype html>
+<meta charset="utf-8">
+<link rel="match" href="canvas_without_context_ref.html">
+<style>
+ div {
+ background-color: green;
+ width: 20px;
+ height: 20px;
+ }
+</style>
+</head>
+<body>
+<div><canvas width="20" height="20"></canvas></div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/rendering/replaced-elements/embedded-content-rendering-rules/canvas_without_context_ref.html b/testing/web-platform/tests/html/rendering/replaced-elements/embedded-content-rendering-rules/canvas_without_context_ref.html
new file mode 100644
index 0000000000..ae0c9c8c8e
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/replaced-elements/embedded-content-rendering-rules/canvas_without_context_ref.html
@@ -0,0 +1,14 @@
+<html>
+<head>
+<style>
+ div {
+ background-color: green;
+ width: 20px;
+ height: 20px;
+ }
+</style>
+</head>
+<body>
+<div></div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/rendering/replaced-elements/embedded-content/audio-controls-intrinsic-size.html b/testing/web-platform/tests/html/rendering/replaced-elements/embedded-content/audio-controls-intrinsic-size.html
new file mode 100644
index 0000000000..6cbbcd02f5
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/replaced-elements/embedded-content/audio-controls-intrinsic-size.html
@@ -0,0 +1,25 @@
+<!doctype html>
+<title>Audio intrinsic size doesn't depend on its max size</title>
+<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1683979">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div style="display: inline-block">
+ <audio controls style="max-width: 99%" id="test"></audio>
+</div>
+<script>
+let audio = document.getElementById("test");
+
+function computeSize() {
+ return audio.getBoundingClientRect().width;
+}
+
+let size = computeSize();
+async_test(function(t) {
+ requestAnimationFrame(t.step_func(function() {
+ assert_equals(computeSize(), size, "Shouldn't have changed size");
+ requestAnimationFrame(t.step_func_done(function() {
+ assert_equals(computeSize(), size, "Shouldn't have changed size");
+ }));
+ }));
+});
+</script>
diff --git a/testing/web-platform/tests/html/rendering/replaced-elements/embedded-content/change-src-while-not-displayed-ref.html b/testing/web-platform/tests/html/rendering/replaced-elements/embedded-content/change-src-while-not-displayed-ref.html
new file mode 100644
index 0000000000..96500cf0bd
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/replaced-elements/embedded-content/change-src-while-not-displayed-ref.html
@@ -0,0 +1,2 @@
+<!DOCTYPE html>
+<embed style="display:block;" src="data:text/html,PASS">
diff --git a/testing/web-platform/tests/html/rendering/replaced-elements/embedded-content/change-src-while-not-displayed.html b/testing/web-platform/tests/html/rendering/replaced-elements/embedded-content/change-src-while-not-displayed.html
new file mode 100644
index 0000000000..521a816337
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/replaced-elements/embedded-content/change-src-while-not-displayed.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org">
+<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1240261">
+<link rel="match" href="change-src-while-not-displayed-ref.html">
+<embed id="embed" style="display:block;" src="data:text/html,FAIL">
+<script>
+ onload = function() {
+ document.body.offsetTop;
+ embed.style.display = "none";
+ document.body.offsetTop;
+ embed.src = "data:text/html,PASS";
+ document.body.offsetTop;
+ embed.style.display = "block";
+ requestAnimationFrame(()=> {
+ requestAnimationFrame(()=> {
+ document.documentElement.classList.remove('reftest-wait');
+ });
+ });
+ }
+</script>
diff --git a/testing/web-platform/tests/html/rendering/replaced-elements/embedded-content/cross-domain-iframe-in-multicol.sub-ref.html b/testing/web-platform/tests/html/rendering/replaced-elements/embedded-content/cross-domain-iframe-in-multicol.sub-ref.html
new file mode 100644
index 0000000000..2645ed459f
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/replaced-elements/embedded-content/cross-domain-iframe-in-multicol.sub-ref.html
@@ -0,0 +1,3 @@
+<!doctype html>
+<div style="height: 100px"></div>
+<iframe id=myframe src="/images/green.png"></iframe>
diff --git a/testing/web-platform/tests/html/rendering/replaced-elements/embedded-content/cross-domain-iframe-in-multicol.sub.html b/testing/web-platform/tests/html/rendering/replaced-elements/embedded-content/cross-domain-iframe-in-multicol.sub.html
new file mode 100644
index 0000000000..e39e2bc764
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/replaced-elements/embedded-content/cross-domain-iframe-in-multicol.sub.html
@@ -0,0 +1,21 @@
+<!doctype html>
+<html class="reftest-wait">
+<title>Rendering of cross-domain iframe element in multicol</title>
+<link rel="match" href="cross-domain-iframe-in-multicol.sub-ref.html">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/rendering.html#embedded-content-rendering-rules">
+<meta name="assert" content="Checks that cross-domain iframe in multicol is correctly rendered">
+<div style="columns: 2; height: 300px">
+ <div style="height: 100px"></div>
+ <iframe id=myframe src="http://{{domains[www1]}}:{{ports[http][0]}}/images/green.png"></iframe>
+ <div style="height: 100px"></div>
+</div>
+<script>
+ myframe.onload = () => {
+ requestAnimationFrame(() => {
+ requestAnimationFrame(() => {
+ document.documentElement.classList.remove('reftest-wait');
+ });
+ });
+ }
+</script>
+</html>
diff --git a/testing/web-platform/tests/html/rendering/replaced-elements/embedded-content/cross-domain-iframe.sub-ref.html b/testing/web-platform/tests/html/rendering/replaced-elements/embedded-content/cross-domain-iframe.sub-ref.html
new file mode 100644
index 0000000000..a3579eee74
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/replaced-elements/embedded-content/cross-domain-iframe.sub-ref.html
@@ -0,0 +1,3 @@
+<!doctype html>
+<title>Test reference</title>
+<iframe src="/images/green.png"></iframe>
diff --git a/testing/web-platform/tests/html/rendering/replaced-elements/embedded-content/cross-domain-iframe.sub.html b/testing/web-platform/tests/html/rendering/replaced-elements/embedded-content/cross-domain-iframe.sub.html
new file mode 100644
index 0000000000..8d9b8cd5b4
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/replaced-elements/embedded-content/cross-domain-iframe.sub.html
@@ -0,0 +1,17 @@
+<!doctype html>
+<html class="reftest-wait">
+<title>Rendering of iframe element with src attribute from another domain</title>
+<link rel="match" href="cross-domain-iframe.sub-ref.html">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/rendering.html#embedded-content-rendering-rules">
+<meta name="assert" content="Checks that iframe content is correctly rendered even if it is retrieved from a different domain.">
+<iframe id=myframe src="http://{{domains[www1]}}:{{ports[http][0]}}/images/green.png"></iframe>
+<script>
+ myframe.onload = () => {
+ requestAnimationFrame(() => {
+ requestAnimationFrame(() => {
+ document.documentElement.classList.remove('reftest-wait');
+ });
+ });
+ }
+</script>
+</html>
diff --git a/testing/web-platform/tests/html/rendering/replaced-elements/embedded-content/object-fallback-text-decoration-ref.html b/testing/web-platform/tests/html/rendering/replaced-elements/embedded-content/object-fallback-text-decoration-ref.html
new file mode 100644
index 0000000000..9481e80ac8
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/replaced-elements/embedded-content/object-fallback-text-decoration-ref.html
@@ -0,0 +1,3 @@
+<!doctype html>
+<title>Test reference</title>
+<span style="text-decoration:underline">This text should be underlined.</span>
diff --git a/testing/web-platform/tests/html/rendering/replaced-elements/embedded-content/object-fallback-text-decoration.html b/testing/web-platform/tests/html/rendering/replaced-elements/embedded-content/object-fallback-text-decoration.html
new file mode 100644
index 0000000000..89657ef8a2
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/replaced-elements/embedded-content/object-fallback-text-decoration.html
@@ -0,0 +1,9 @@
+<!doctype html>
+<title>Rendering of object element fallback with text-decoration</title>
+<link rel="match" href="object-fallback-text-decoration-ref.html">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/rendering.html#embedded-content-rendering-rules">
+<meta name="assert" content="Checks that text-decoration applies to rendered object fallback.">
+<style>
+ object { text-decoration: underline; }
+</style>
+<object>This text should be underlined.</object>
diff --git a/testing/web-platform/tests/html/rendering/replaced-elements/embedded-content/resources/tall.html b/testing/web-platform/tests/html/rendering/replaced-elements/embedded-content/resources/tall.html
new file mode 100644
index 0000000000..3de84d0b3f
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/replaced-elements/embedded-content/resources/tall.html
@@ -0,0 +1,6 @@
+<!DOCTYPE html>
+<body style="background: blue">
+ <div style="position: fixed; left: 0; top: 0; width: 100%; height: 100px; background: yellow"></div>
+ <div style="position: fixed; left: 0; bottom: 0; width: 100%; height: 100px; background: green"></div>
+ <div style="height: 2000px"></div>
+</body>
diff --git a/testing/web-platform/tests/html/rendering/replaced-elements/embedded-content/tall-cross-domain-iframe-in-scrolled.sub-ref.html b/testing/web-platform/tests/html/rendering/replaced-elements/embedded-content/tall-cross-domain-iframe-in-scrolled.sub-ref.html
new file mode 100644
index 0000000000..01c1e2f86f
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/replaced-elements/embedded-content/tall-cross-domain-iframe-in-scrolled.sub-ref.html
@@ -0,0 +1,9 @@
+<!doctype html>
+<html class="reftest-wait">
+<iframe id=myframe style="width: 300px; height: 1000px" src="resources/tall.html"></iframe>
+<div style="height: 2000px"></div>
+<script>
+ window.scrollTo(0, 700);
+ myframe.onload = () => document.documentElement.classList.remove('reftest-wait');
+</script>
+</html>
diff --git a/testing/web-platform/tests/html/rendering/replaced-elements/embedded-content/tall-cross-domain-iframe-in-scrolled.sub.html b/testing/web-platform/tests/html/rendering/replaced-elements/embedded-content/tall-cross-domain-iframe-in-scrolled.sub.html
new file mode 100644
index 0000000000..865be7c883
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/replaced-elements/embedded-content/tall-cross-domain-iframe-in-scrolled.sub.html
@@ -0,0 +1,20 @@
+<!doctype html>
+<html class="reftest-wait">
+<title>Rendering of tall cross-domain iframe element in a scrolled window</title>
+<link rel="match" href="tall-cross-domain-iframe-in-scrolled.sub-ref.html">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/rendering.html#embedded-content-rendering-rules">
+<meta name="assert" content="Checks that tall cross-domain iframe in a scrolled window is correctly rendered">
+<iframe id=myframe style="width: 300px; height: 1000px"
+ src="http://{{domains[www1]}}:{{ports[http][0]}}/html/rendering/replaced-elements/embedded-content/resources/tall.html"></iframe>
+<div style="height: 2000px"></div>
+<script>
+ window.scrollTo(0, 700);
+ myframe.onload = () => {
+ requestAnimationFrame(() => {
+ requestAnimationFrame(() => {
+ document.documentElement.classList.remove('reftest-wait');
+ });
+ });
+ }
+</script>
+</html>
diff --git a/testing/web-platform/tests/html/rendering/replaced-elements/embedded-content/video-controls-vertical-writing-mode-ref.html b/testing/web-platform/tests/html/rendering/replaced-elements/embedded-content/video-controls-vertical-writing-mode-ref.html
new file mode 100644
index 0000000000..e65bf6cbe8
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/replaced-elements/embedded-content/video-controls-vertical-writing-mode-ref.html
@@ -0,0 +1,4 @@
+<!DOCTYPE html>
+<div>
+ <video controls></video>
+</div>
diff --git a/testing/web-platform/tests/html/rendering/replaced-elements/embedded-content/video-controls-vertical-writing-mode.html b/testing/web-platform/tests/html/rendering/replaced-elements/embedded-content/video-controls-vertical-writing-mode.html
new file mode 100644
index 0000000000..acd2588112
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/replaced-elements/embedded-content/video-controls-vertical-writing-mode.html
@@ -0,0 +1,8 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Video controls rendering in vertical-lr</title>
+<link rel="help" href="https://html.spec.whatwg.org/multipage/rendering.html#embedded-content-rendering-rules" />
+<link rel="match" href="video-controls-vertical-writing-mode-ref.html" />
+<div style="writing-mode:vertical-lr">
+ <video controls></video>
+</div>
diff --git a/testing/web-platform/tests/html/rendering/replaced-elements/images/blocked-by-csp-ref.html b/testing/web-platform/tests/html/rendering/replaced-elements/images/blocked-by-csp-ref.html
new file mode 100644
index 0000000000..f37d8a3ec9
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/replaced-elements/images/blocked-by-csp-ref.html
@@ -0,0 +1,5 @@
+<!doctype html>
+<title>Test reference</title>
+<style>img { border: solid; }</style>
+It should say PASS below:<br>
+<img alt="PASS">
diff --git a/testing/web-platform/tests/html/rendering/replaced-elements/images/blocked-by-csp.html b/testing/web-platform/tests/html/rendering/replaced-elements/images/blocked-by-csp.html
new file mode 100644
index 0000000000..2416e5dfd0
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/replaced-elements/images/blocked-by-csp.html
@@ -0,0 +1,8 @@
+<!doctype html>
+<title>Images behave the same when blocked by CSP as when failing to load/broken</title>
+<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1664156">
+<link rel="match" href="blocked-by-csp-ref.html">
+<meta http-equiv=content-security-policy content="img-src 'none'">
+<style>img { border: solid; }</style>
+It should say PASS below:<br>
+<img src=image alt="PASS">
diff --git a/testing/web-platform/tests/html/rendering/replaced-elements/images/img-sizes-auto.html b/testing/web-platform/tests/html/rendering/replaced-elements/images/img-sizes-auto.html
new file mode 100644
index 0000000000..cbdf769596
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/replaced-elements/images/img-sizes-auto.html
@@ -0,0 +1,53 @@
+<!doctype html>
+<title>default styles for &lt;img sizes=auto></title>
+<meta name="viewport" content="width=device-width">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/rendering/support/test-ua-stylesheet.js"></script>
+<style>
+/* Specify this bogus namespace, so the rules in this stylesheet only apply to the `fakeClone`d elements in #refs, not the HTML elements in #tests. */
+@namespace url(urn:not-html);
+
+img:is([sizes="auto" i], [sizes^="auto," i]) {
+ contain: size !important;
+ contain-intrinsic-size: 300px 150px;
+}
+</style>
+
+<style>
+/* Test !important */
+img.test-important { contain: style; contain-intrinsic-size: 30px 15px; }
+</style>
+
+<div id="log"></div>
+
+<div id="tests">
+ <img sizes=auto>
+ <img sizes=auto width=10 height=20>
+ <img sizes=AuTo>
+ <img sizes=auto,xyz>
+ <img sizes=AuTo,xyz>
+
+ <!-- UA style should not apply: -->
+ <img>
+ <img sizes>
+ <img sizes=xyz,auto>
+ <picture data-skip>
+ <source data-skip sizes=auto>
+ <img>
+ </picture>
+
+ <!-- Test !important -->
+ <img sizes=auto class=test-important>
+</div>
+
+<div id="refs"></div>
+
+<script>
+ const props = [
+ 'contain',
+ 'contain-intrinsic-size'
+ ];
+ runUAStyleTests(props);
+
+</script>
diff --git a/testing/web-platform/tests/html/rendering/replaced-elements/images/input-image-content-ref.html b/testing/web-platform/tests/html/rendering/replaced-elements/images/input-image-content-ref.html
new file mode 100644
index 0000000000..37af13329e
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/replaced-elements/images/input-image-content-ref.html
@@ -0,0 +1,7 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>Input type=image with CSS content.</title>
+<link rel="author" href="mailto:masonf@chromium.org">
+
+You should see a red dot.<br>
+<input type="image" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==">
diff --git a/testing/web-platform/tests/html/rendering/replaced-elements/images/input-image-content.html b/testing/web-platform/tests/html/rendering/replaced-elements/images/input-image-content.html
new file mode 100644
index 0000000000..5376e8033f
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/replaced-elements/images/input-image-content.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>Input type=image with CSS content.</title>
+<link rel="author" href="mailto:masonf@chromium.org">
+<link rel="match" href="input-image-content-ref.html">
+
+You should see a red dot.<br>
+<style>
+ input {
+ content: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==);
+ }
+</style>
+
+<input type="image">
diff --git a/testing/web-platform/tests/html/rendering/replaced-elements/images/revoked-blob-print-ref.html b/testing/web-platform/tests/html/rendering/replaced-elements/images/revoked-blob-print-ref.html
new file mode 100644
index 0000000000..6b2f0bb606
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/replaced-elements/images/revoked-blob-print-ref.html
@@ -0,0 +1,3 @@
+<!doctype html>
+<title>Test reference</title>
+<img width=100 height=50 src="/images/black-rectangle.png">
diff --git a/testing/web-platform/tests/html/rendering/replaced-elements/images/revoked-blob-print.html b/testing/web-platform/tests/html/rendering/replaced-elements/images/revoked-blob-print.html
new file mode 100644
index 0000000000..fd5c2c5754
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/replaced-elements/images/revoked-blob-print.html
@@ -0,0 +1,24 @@
+<!doctype html>
+<html class="test-wait">
+<title>Printing an image with src="revoked-blob"</title>
+<link rel="author" href="mailto:emilio@crisal.io" title="Emilio Cobos Álvarez">
+<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1665343">
+<link rel="match" href="revoked-blob-print-ref.html">
+<img width=100 height=50>
+<script>
+ let canvas = document.createElement("canvas");
+ canvas.width = 100;
+ canvas.height = 50;
+ let ctx = canvas.getContext("2d");
+ ctx.fillRect(0, 0, 100, 50);
+ canvas.toBlob(function(blob) {
+ let img = document.querySelector("img");
+ let url = URL.createObjectURL(blob);
+ img.onload = function() {
+ URL.revokeObjectURL(url);
+ document.documentElement.className = "";
+ };
+ img.src = url;
+ });
+</script>
+</html>
diff --git a/testing/web-platform/tests/html/rendering/replaced-elements/images/space-ref.html b/testing/web-platform/tests/html/rendering/replaced-elements/images/space-ref.html
new file mode 100644
index 0000000000..0cf272e162
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/replaced-elements/images/space-ref.html
@@ -0,0 +1,13 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>img hspace/vspace - reference</title>
+<style>
+span { background: blue; }
+</style>
+<div style=width:400px;>
+<p><span><img src=/images/green.png></span>
+<p><span><img src=/images/green.png style="margin: 0 10px"></span>
+<p><span><img src=/images/green.png style="margin: 10px 0"></span>
+<p><span><img src=/images/green.png style="margin: 0 10%"></span>
+<p><span><img src=/images/green.png style="margin: 10% 0"></span>
+</div>
diff --git a/testing/web-platform/tests/html/rendering/replaced-elements/images/space.html b/testing/web-platform/tests/html/rendering/replaced-elements/images/space.html
new file mode 100644
index 0000000000..fee115dfce
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/replaced-elements/images/space.html
@@ -0,0 +1,14 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>img hspace/vspace</title>
+<link rel=match href=space-ref.html>
+<style>
+span { background: blue; }
+</style>
+<div style=width:400px;>
+<p><span><img src=/images/green.png></span>
+<p><span><img src=/images/green.png hspace=10></span>
+<p><span><img src=/images/green.png vspace=10></span>
+<p><span><img src=/images/green.png hspace=10%></span>
+<p><span><img src=/images/green.png vspace=10%></span>
+</div>
diff --git a/testing/web-platform/tests/html/rendering/replaced-elements/resources/svg-sizing.js b/testing/web-platform/tests/html/rendering/replaced-elements/resources/svg-sizing.js
new file mode 100644
index 0000000000..c212c6b283
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/replaced-elements/resources/svg-sizing.js
@@ -0,0 +1,418 @@
+// Simple implementation of SVG sizing
+
+setup({explicit_done: true});
+
+var SVGSizing = (function() {
+ function parseLength(l) {
+ var match = /^([-+]?[0-9]+|[-+]?[0-9]*\.[0-9]+)(px|%)?$/.exec(l);
+ if (!match)
+ return null;
+ return new Length(Number(match[1]), match[2] ? match[2] : "px");
+ }
+
+ function parseViewBox(input) {
+ if (!input)
+ return null;
+
+ var arr = input.split(' ');
+ return arr.map(function(a) { return parseInt(a); });
+ }
+
+ // Only px and % are used
+ function convertToPx(input, percentRef) {
+ if (input == null)
+ return null;
+ var length = parseLength(input);
+ if (length.amount == 0)
+ return 0;
+ if (!length.unit)
+ length.unit = "px";
+ if (length.unit == "%" && percentRef === undefined)
+ return null;
+ return length.amount * { px: 1,
+ "%": percentRef/100}[length.unit];
+ }
+
+ function Length(amount, unit) {
+ this.amount = amount;
+ this.unit = unit;
+ }
+
+ function describe(data) {
+ function dumpObject(obj) {
+ var r = "";
+ for (var property in obj) {
+ if (obj.hasOwnProperty(property)) {
+ var value = obj[property];
+ if (typeof value == 'string')
+ value = "'" + value + "'";
+ else if (value == null)
+ value = "null";
+ else if (typeof value == 'object')
+ {
+ if (value instanceof Array)
+ value = "[" + value + "]";
+ else
+ value = "{" + dumpObject(value) + "}";
+ }
+
+ if (value != "null")
+ r += property + ": " + value + ", ";
+ }
+ }
+ return r;
+ }
+ var result = dumpObject(data);
+ if (result == "")
+ return "(initial values)";
+ return result;
+ }
+
+ function mapPresentationalHintLength(testData, cssProperty, attr) {
+ if (attr) {
+ var l = parseLength(attr);
+ if (l)
+ testData.style[cssProperty] = l.amount + l.unit;
+ }
+ }
+
+ function computedWidthIsAuto(testData) {
+ return !testData.style["width"] || testData.style["width"] == 'auto';
+ }
+
+ function computedHeightIsAuto(testData) {
+ return !testData.style["height"] || testData.style["height"] == 'auto' ||
+ (parseLength(testData.style["height"]).unit == '%' &&
+ containerComputedHeightIsAuto(testData));
+ }
+
+ function containerComputedWidthIsAuto(testData) {
+ return !testData.config.containerWidthStyle ||
+ testData.config.containerWidthStyle == 'auto';
+ }
+
+ function containerComputedHeightIsAuto(testData) {
+ return !testData.config.containerHeightStyle ||
+ testData.config.containerHeightStyle == 'auto';
+ }
+
+ function intrinsicInformation(testData) {
+ if (testData.config.placeholder == 'iframe')
+ return {};
+
+ var w = convertToPx(testData.config.svgWidthAttr) || 0;
+ var h = convertToPx(testData.config.svgHeightAttr) || 0;
+ var r = 0;
+ if (w && h) {
+ r = w / h;
+ } else {
+ var vb = parseViewBox(testData.config.svgViewBoxAttr);
+ if (vb) {
+ r = vb[2] / vb[3];
+ }
+ if (r) {
+ if (!w && h)
+ w = h * r;
+ else if (!h && w)
+ h = w / r;
+ }
+ }
+ return { width: w, height: h, ratio: r };
+ };
+
+ function contentAttributeForPlaceholder(testData) {
+ if (testData.config.placeholder == 'object')
+ return "data";
+ else
+ return "src";
+ }
+
+ function TestData(config) {
+ this.config = config;
+ this.name = describe(config);
+ this.style = {};
+ if (config.placeholder) {
+ mapPresentationalHintLength(this, "width", config.placeholderWidthAttr);
+ mapPresentationalHintLength(this, "height", config.placeholderHeightAttr);
+ } else {
+ if (config.svgWidthStyle)
+ this.style["width"] = config.svgWidthStyle;
+ else
+ mapPresentationalHintLength(this, "width", config.svgWidthAttr);
+
+ if (config.svgHeightStyle)
+ this.style["height"] = config.svgHeightStyle;
+ else
+ mapPresentationalHintLength(this, "height", config.svgHeightAttr);
+ }
+ }
+
+ TestData.prototype.computeInlineReplacedSize = function(outerWidth, outerHeight) {
+ var intrinsic = intrinsicInformation(this);
+ var self = this;
+
+ // http://www.w3.org/TR/CSS2/visudet.html#inline-replaced-height
+ function calculateUsedHeight() {
+ if (computedHeightIsAuto(self)) {
+ if (computedWidthIsAuto(self) && intrinsic.height)
+ return intrinsic.height;
+ if (intrinsic.ratio)
+ return calculateUsedWidth() / intrinsic.ratio;
+ if (intrinsic.height)
+ return intrinsic.height;
+ return 150;
+ }
+
+ return convertToPx(self.style["height"],
+ convertToPx(self.config.containerHeightStyle,
+ outerHeight));
+ }
+
+ // http://www.w3.org/TR/CSS2/visudet.html#inline-replaced-width
+ function calculateUsedWidth() {
+ if (computedWidthIsAuto(self)) {
+ if (computedHeightIsAuto(self) && intrinsic.width)
+ return intrinsic.width;
+ if (!computedHeightIsAuto(self) && intrinsic.ratio)
+ return calculateUsedHeight() * intrinsic.ratio;
+ if (computedHeightIsAuto(self) && intrinsic.ratio) {
+ if (containerComputedWidthIsAuto(self)) {
+ // Note: While this is actually undefined in CSS
+ // 2.1, use the suggested value by examining the
+ // ancestor widths.
+ return outerWidth;
+ } else {
+ return convertToPx(self.config.containerWidthStyle,
+ outerWidth);
+ }
+ }
+ if (intrinsic.width)
+ return intrinsic.width;
+ return 300;
+ }
+
+ if (containerComputedWidthIsAuto(self))
+ return convertToPx(self.style["width"], outerWidth);
+ else
+ return convertToPx(self.style["width"],
+ convertToPx(self.config.containerWidthStyle,
+ outerWidth));
+ }
+ return { width: calculateUsedWidth(),
+ height: calculateUsedHeight() };
+ };
+
+ TestData.prototype.buildContainer = function (placeholder, options) {
+ options = options || {};
+
+ var container = document.createElement("div");
+
+ container.id = "container";
+ if (this.config.containerWidthStyle)
+ container.style.width = this.config.containerWidthStyle;
+
+ if (this.config.containerHeightStyle)
+ container.style.height = this.config.containerHeightStyle;
+
+ if (options.pretty)
+ container.appendChild(document.createTextNode("\n\t\t"));
+ container.appendChild(placeholder);
+ if (options.pretty)
+ container.appendChild(document.createTextNode("\n\t"));
+
+ return container;
+ };
+
+ TestData.prototype.buildSVGOrPlaceholder = function (options) {
+ options = options || {};
+ var self = this;
+
+ if (this.config.placeholder) {
+ var generateSVGURI = function(testData, encoder) {
+ var res = '<svg xmlns="http://www.w3.org/2000/svg"';
+ function addAttr(attr, prop) {
+ if (testData.config[prop])
+ res += ' ' + attr + '="' + testData.config[prop] + '"';
+ }
+ addAttr("width", "svgWidthAttr");
+ addAttr("height", "svgHeightAttr");
+ addAttr("viewBox", "svgViewBoxAttr");
+ res += '></svg>';
+ return 'data:image/svg+xml' + encoder(res);
+ };
+ var placeholder = document.createElement(this.config.placeholder);
+ if (options.pretty) {
+ placeholder.appendChild(document.createTextNode("\n\t\t\t"));
+ placeholder.appendChild(
+ document.createComment(
+ generateSVGURI(this, function(x) { return "," + x; })));
+ placeholder.appendChild(document.createTextNode("\n\t\t"));
+ }
+ placeholder.setAttribute("id", "test");
+ if (this.config.placeholderWidthAttr)
+ placeholder.setAttribute("width", this.config.placeholderWidthAttr);
+ if (this.config.placeholderHeightAttr)
+ placeholder.setAttribute("height", this.config.placeholderHeightAttr);
+ placeholder.setAttribute(contentAttributeForPlaceholder(this),
+ generateSVGURI(this, function(x) {
+ return ";base64," + btoa(x);
+ }));
+ return placeholder;
+ } else {
+ var svgElement = document.createElementNS("http://www.w3.org/2000/svg", "svg");
+ svgElement.setAttribute("id", "test");
+ if (self.config.svgWidthStyle)
+ svgElement.style.width = self.config.svgWidthStyle;
+ if (self.config.svgHeightStyle)
+ svgElement.style.height = self.config.svgHeightStyle;
+ if (self.config.svgWidthAttr)
+ svgElement.setAttribute("width", self.config.svgWidthAttr);
+ if (self.config.svgHeightAttr)
+ svgElement.setAttribute("height", self.config.svgHeightAttr);
+ if (self.config.svgViewBoxAttr)
+ svgElement.setAttribute("viewBox", self.config.svgViewBoxAttr);
+ return svgElement;
+ }
+ };
+
+ TestData.prototype.buildDemo = function (expectedRect, id) {
+ // Non-essential debugging tool
+ var self = this;
+
+ function buildDemoSerialization() {
+ var outerWidth = 800;
+ var outerHeight = 600;
+
+ var options = { pretty: true };
+ var container =
+ self.buildContainer(self.buildSVGOrPlaceholder(options), options);
+
+ var root = document.createElement("html");
+ var style = document.createElement("style");
+
+ style.textContent = "\n" +
+ "\tbody { margin: 0; font-family: sans-serif }\n" +
+ "\tiframe { border: none }\n" +
+ "\t#expected {\n" +
+ "\t\twidth: " + (expectedRect.width) + "px; height: "
+ + (expectedRect.height) + "px;\n" +
+ "\t\tborder: 10px solid lime; position: absolute;\n" +
+ "\t\tbackground-color: red }\n" +
+ "\t#testContainer { position: absolute;\n" +
+ "\t\ttop: 10px; left: 10px; width: " + outerWidth + "px;\n" +
+ "\t\theight: " + outerHeight + "px }\n" +
+ "\t#test { background-color: green }\n" +
+ "\t.result { position: absolute; top: 0; right: 0;\n" +
+ "\t\tbackground-color: hsla(0,0%, 0%, 0.85); border-radius: 0.5em;\n" +
+ "\t\tpadding: 0.5em; border: 0.25em solid black }\n" +
+ "\t.pass { color: lime }\n" +
+ "\t.fail { color: red }\n";
+
+ root.appendChild(document.createTextNode("\n"));
+ root.appendChild(style);
+ root.appendChild(document.createTextNode("\n"));
+
+ var script = document.createElement("script");
+ script.textContent = "\n" +
+ "onload = function() {\n" +
+ "\tvar svgRect =\n" +
+ "\t\tdocument.querySelector('#test').getBoundingClientRect();\n" +
+ "\tpassed = (svgRect.width == " + expectedRect.width + " && " +
+ "svgRect.height == " + expectedRect.height + ");\n" +
+ "\tdocument.body.insertAdjacentHTML('beforeEnd',\n" +
+ "\t\t'<span class=\"result '+ (passed ? 'pass' : 'fail') " +
+ "+ '\">' + (passed ? 'Pass' : 'Fail') + '</span>');\n" +
+ "};\n";
+
+ root.appendChild(script);
+ root.appendChild(document.createTextNode("\n"));
+
+ var expectedElement = document.createElement("div");
+ expectedElement.id = "expected";
+ root.appendChild(expectedElement);
+ root.appendChild(document.createTextNode("\n"));
+
+ var testContainer = document.createElement("div");
+ testContainer.id = "testContainer";
+ testContainer.appendChild(document.createTextNode("\n\t"));
+ testContainer.appendChild(container);
+ testContainer.appendChild(document.createTextNode("\n"));
+ root.appendChild(testContainer);
+ root.appendChild(document.createTextNode("\n"));
+
+ return "<!DOCTYPE html>\n" + root.outerHTML;
+ }
+
+ function pad(n, width, z) {
+ z = z || '0';
+ n = n + '';
+ return n.length >= width ? n : new Array(width - n.length + 1).join(z) + n;
+ }
+
+ function heightToDescription(height) {
+ if (!height || height == "auto")
+ return "auto";
+ if (parseLength(height).unit == '%')
+ return "percentage";
+ return "fixed";
+ }
+
+ var demoRoot = document.querySelector('#demo');
+ if (demoRoot) {
+ var demo = buildDemoSerialization();
+ var iframe = document.createElement('iframe');
+ iframe.style.width = (Math.max(900, expectedRect.width)) + "px";
+ iframe.style.height = (Math.max(400, expectedRect.height)) + "px";
+ iframe.src = "data:text/html;charset=utf-8," + encodeURIComponent(demo);
+ demoRoot.appendChild(iframe);
+ demoRoot.insertAdjacentHTML(
+ 'beforeEnd',
+ '<p><a href="data:application/octet-stream;charset=utf-8;base64,' +
+ btoa(demo) + '" download="svg-in-' + this.config.placeholder + "-" +
+ heightToDescription(this.config.placeholderHeightAttr) + "-" + pad(id, 3) +
+ '.html">Download</a></p>');
+ }
+ };
+
+ return {
+ TestData: TestData,
+ doCombinationTest: function(values, func, testSingleId) {
+ function computeConfig(id) {
+ id--;
+ var multiplier = 1;
+ var config = {};
+ for (var i=0; i<values.length; i++) {
+ // Compute offset into current array
+ var ii = (Math.floor(id / multiplier)) % values[i][1].length;
+ // Set corresponding value
+ config[values[i][0]] = values[i][1][ii];
+ // Compute new multiplier
+ multiplier *= values[i][1].length;
+ }
+ if (id >= multiplier)
+ return null;
+ return config;
+ }
+
+ function cont(id) {
+ var config = computeConfig(id);
+ if (config && (!testSingleId || testSingleId == id)) {
+ var next = function() {func(config, id, cont)};
+ // Make sure we don't blow the stack, without too much slowness
+ if (id % 20 === 0) {
+ step_timeout(next, 0);
+ } else {
+ next();
+ }
+ } else {
+ done();
+ }
+ };
+
+ if (testSingleId)
+ cont(testSingleId);
+ else
+ cont(1);
+ }
+ };
+})();
diff --git a/testing/web-platform/tests/html/rendering/replaced-elements/svg-embedded-sizing/svg-embedded-sizing.js b/testing/web-platform/tests/html/rendering/replaced-elements/svg-embedded-sizing/svg-embedded-sizing.js
new file mode 100644
index 0000000000..a502d2c747
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/replaced-elements/svg-embedded-sizing/svg-embedded-sizing.js
@@ -0,0 +1,96 @@
+// global async_test, assert_equals
+//
+// This test generates a couple of scenarios (each a
+// SVGSizing.TestData) for sizing inline <svg> and uses a simple
+// JavaScript sizing implementation for comparison.
+//
+// The tests loops through different combinations of:
+//
+// * width and height on <object>, <iframe> (input dependent)
+//
+// * width and height on <svg>
+//
+// * viewBox on <svg> (gives intrinsic ratio)
+//
+// * width and height on containing block of <object>
+//
+// All these contribute to the final size of the SVG in some way.
+//
+// The test focuses on the size of the CSS box generated by the SVG.
+// The SVG is always empty by itself so no actual SVG are tested.
+// Little focus is put on variations within an attribute that doesn't
+// affect the sizing behavior.
+//
+// To debug a specific test, append ?<test-id> to the URL. An <iframe>
+// is generated with equivalent test and the source code of the test
+// can be downloaded.
+
+var debugHint = function(id) { return "(append ?"+id+" to debug) "; };
+var testSingleId;
+if (window.location.search) {
+ testSingleId = parseInt(window.location.search.substring(1));
+ debugHint = function(id) { return ""; };
+}
+
+function testPlaceholderWithHeight(placeholder,
+ placeholderHeightAttr) {
+ var testContainer = document.querySelector('#testContainer');
+ var outerWidth = testContainer.getBoundingClientRect().width;
+ var outerHeight = testContainer.getBoundingClientRect().height;
+
+ SVGSizing.doCombinationTest(
+ [["placeholder", [ placeholder ]],
+ ["containerWidthStyle", [null, "400px"]],
+ ["containerHeightStyle", [null, "400px"]],
+ ["placeholderWidthAttr", [null, "100", "50%"]],
+ ["placeholderHeightAttr", [placeholderHeightAttr]],
+ ["svgViewBoxAttr", [ null, "0 0 100 200" ]],
+ ["svgWidthAttr", [ null, "200", "25%" ]],
+ ["svgHeightAttr", [ null, "200", "25%" ]]],
+ function (config, id, cont) {
+ var testData = new SVGSizing.TestData(config);
+ var t = async_test(testData.name);
+ var expectedRect =
+ testData.computeInlineReplacedSize(outerWidth, outerHeight);
+ var placeholder = testData.buildSVGOrPlaceholder();
+ var container =
+ testData.buildContainer(placeholder);
+
+ var checkSize = function() {
+ var placeholderRect =
+ placeholder.getBoundingClientRect();
+
+ try {
+ assert_equals(placeholderRect.width,
+ expectedRect.width,
+ debugHint(id) + "Wrong width");
+ assert_equals(placeholderRect.height,
+ expectedRect.height,
+ debugHint(id) + "Wrong height");
+ } finally {
+ testContainer.removeChild(container);
+ if (testSingleId)
+ document.body.removeChild(testContainer);
+ cont(id+1);
+ }
+ t.done();
+ };
+
+ if (!config.placeholder) {
+ testContainer.appendChild(container);
+ test(checkSize, testData.name);
+ } else {
+ t.step(function() {
+ placeholder.addEventListener('load', function() {
+ // step_timeout is a work-around to let engines
+ // finish layout of child browsing contexts even
+ // after the load event
+ step_timeout(t.step_func(checkSize), 0);
+ });
+ testContainer.appendChild(container);
+ });
+ }
+ if (testSingleId == id)
+ testData.buildDemo(expectedRect, id);
+ }, testSingleId);
+}
diff --git a/testing/web-platform/tests/html/rendering/replaced-elements/svg-embedded-sizing/svg-in-iframe-auto.html b/testing/web-platform/tests/html/rendering/replaced-elements/svg-embedded-sizing/svg-in-iframe-auto.html
new file mode 100644
index 0000000000..4c3fefe88f
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/replaced-elements/svg-embedded-sizing/svg-in-iframe-auto.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- This file is generated by gen-svgsizing-tests.py -->
+<html>
+ <head>
+ <title>SVG sizing: &lt;iframe></title>
+ <meta name=timeout content=long>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="../resources/svg-sizing.js"></script>
+ <style>
+ #testContainer {
+ position: absolute;
+ left: 0;
+ top: 0;
+ width: 800px;
+ height: 600px
+ }
+ iframe { border: 0 }
+ </style>
+ <link rel="help" href="http://www.w3.org/TR/CSS2/visudet.html#inline-replaced-width">
+ <link rel="help" href="http://www.w3.org/TR/CSS2/visudet.html#inline-replaced-height">
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#replaced-elements">
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#attr-dim-width">
+ <link rel="help" href="http://www.w3.org/TR/SVG/coords.html#ViewportSpace">
+ </head>
+ <body>
+ <div id="log"></div>
+ <div id="testContainer"></div>
+ <div id="demo"></div>
+ <script src="svg-embedded-sizing.js"></script>
+ <script>testPlaceholderWithHeight("iframe", null)</script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/rendering/replaced-elements/svg-embedded-sizing/svg-in-iframe-fixed.html b/testing/web-platform/tests/html/rendering/replaced-elements/svg-embedded-sizing/svg-in-iframe-fixed.html
new file mode 100644
index 0000000000..ae3328c6a8
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/replaced-elements/svg-embedded-sizing/svg-in-iframe-fixed.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- This file is generated by gen-svgsizing-tests.py -->
+<html>
+ <head>
+ <title>SVG sizing: &lt;iframe></title>
+ <meta name=timeout content=long>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="../resources/svg-sizing.js"></script>
+ <style>
+ #testContainer {
+ position: absolute;
+ left: 0;
+ top: 0;
+ width: 800px;
+ height: 600px
+ }
+ iframe { border: 0 }
+ </style>
+ <link rel="help" href="http://www.w3.org/TR/CSS2/visudet.html#inline-replaced-width">
+ <link rel="help" href="http://www.w3.org/TR/CSS2/visudet.html#inline-replaced-height">
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#replaced-elements">
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#attr-dim-width">
+ <link rel="help" href="http://www.w3.org/TR/SVG/coords.html#ViewportSpace">
+ </head>
+ <body>
+ <div id="log"></div>
+ <div id="testContainer"></div>
+ <div id="demo"></div>
+ <script src="svg-embedded-sizing.js"></script>
+ <script>testPlaceholderWithHeight("iframe", '100px')</script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/rendering/replaced-elements/svg-embedded-sizing/svg-in-iframe-percentage.html b/testing/web-platform/tests/html/rendering/replaced-elements/svg-embedded-sizing/svg-in-iframe-percentage.html
new file mode 100644
index 0000000000..da00c0680b
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/replaced-elements/svg-embedded-sizing/svg-in-iframe-percentage.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- This file is generated by gen-svgsizing-tests.py -->
+<html>
+ <head>
+ <title>SVG sizing: &lt;iframe></title>
+ <meta name=timeout content=long>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="../resources/svg-sizing.js"></script>
+ <style>
+ #testContainer {
+ position: absolute;
+ left: 0;
+ top: 0;
+ width: 800px;
+ height: 600px
+ }
+ iframe { border: 0 }
+ </style>
+ <link rel="help" href="http://www.w3.org/TR/CSS2/visudet.html#inline-replaced-width">
+ <link rel="help" href="http://www.w3.org/TR/CSS2/visudet.html#inline-replaced-height">
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#replaced-elements">
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#attr-dim-width">
+ <link rel="help" href="http://www.w3.org/TR/SVG/coords.html#ViewportSpace">
+ </head>
+ <body>
+ <div id="log"></div>
+ <div id="testContainer"></div>
+ <div id="demo"></div>
+ <script src="svg-embedded-sizing.js"></script>
+ <script>testPlaceholderWithHeight("iframe", '100%')</script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/rendering/replaced-elements/svg-embedded-sizing/svg-in-img-auto.html b/testing/web-platform/tests/html/rendering/replaced-elements/svg-embedded-sizing/svg-in-img-auto.html
new file mode 100644
index 0000000000..cef3530676
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/replaced-elements/svg-embedded-sizing/svg-in-img-auto.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- This file is generated by gen-svgsizing-tests.py -->
+<html>
+ <head>
+ <title>SVG sizing: &lt;img></title>
+ <meta name=timeout content=long>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="../resources/svg-sizing.js"></script>
+ <style>
+ #testContainer {
+ position: absolute;
+ left: 0;
+ top: 0;
+ width: 800px;
+ height: 600px
+ }
+ iframe { border: 0 }
+ </style>
+ <link rel="help" href="http://www.w3.org/TR/CSS2/visudet.html#inline-replaced-width">
+ <link rel="help" href="http://www.w3.org/TR/CSS2/visudet.html#inline-replaced-height">
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#replaced-elements">
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#attr-dim-width">
+ <link rel="help" href="http://www.w3.org/TR/SVG/coords.html#ViewportSpace">
+ </head>
+ <body>
+ <div id="log"></div>
+ <div id="testContainer"></div>
+ <div id="demo"></div>
+ <script src="svg-embedded-sizing.js"></script>
+ <script>testPlaceholderWithHeight("img", null)</script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/rendering/replaced-elements/svg-embedded-sizing/svg-in-img-fixed.html b/testing/web-platform/tests/html/rendering/replaced-elements/svg-embedded-sizing/svg-in-img-fixed.html
new file mode 100644
index 0000000000..e8ad0dc935
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/replaced-elements/svg-embedded-sizing/svg-in-img-fixed.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- This file is generated by gen-svgsizing-tests.py -->
+<html>
+ <head>
+ <title>SVG sizing: &lt;img></title>
+ <meta name=timeout content=long>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="../resources/svg-sizing.js"></script>
+ <style>
+ #testContainer {
+ position: absolute;
+ left: 0;
+ top: 0;
+ width: 800px;
+ height: 600px
+ }
+ iframe { border: 0 }
+ </style>
+ <link rel="help" href="http://www.w3.org/TR/CSS2/visudet.html#inline-replaced-width">
+ <link rel="help" href="http://www.w3.org/TR/CSS2/visudet.html#inline-replaced-height">
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#replaced-elements">
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#attr-dim-width">
+ <link rel="help" href="http://www.w3.org/TR/SVG/coords.html#ViewportSpace">
+ </head>
+ <body>
+ <div id="log"></div>
+ <div id="testContainer"></div>
+ <div id="demo"></div>
+ <script src="svg-embedded-sizing.js"></script>
+ <script>testPlaceholderWithHeight("img", '100px')</script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/rendering/replaced-elements/svg-embedded-sizing/svg-in-img-percentage.html b/testing/web-platform/tests/html/rendering/replaced-elements/svg-embedded-sizing/svg-in-img-percentage.html
new file mode 100644
index 0000000000..7bd5d90317
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/replaced-elements/svg-embedded-sizing/svg-in-img-percentage.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- This file is generated by gen-svgsizing-tests.py -->
+<html>
+ <head>
+ <title>SVG sizing: &lt;img></title>
+ <meta name=timeout content=long>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="../resources/svg-sizing.js"></script>
+ <style>
+ #testContainer {
+ position: absolute;
+ left: 0;
+ top: 0;
+ width: 800px;
+ height: 600px
+ }
+ iframe { border: 0 }
+ </style>
+ <link rel="help" href="http://www.w3.org/TR/CSS2/visudet.html#inline-replaced-width">
+ <link rel="help" href="http://www.w3.org/TR/CSS2/visudet.html#inline-replaced-height">
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#replaced-elements">
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#attr-dim-width">
+ <link rel="help" href="http://www.w3.org/TR/SVG/coords.html#ViewportSpace">
+ </head>
+ <body>
+ <div id="log"></div>
+ <div id="testContainer"></div>
+ <div id="demo"></div>
+ <script src="svg-embedded-sizing.js"></script>
+ <script>testPlaceholderWithHeight("img", '100%')</script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/rendering/replaced-elements/svg-embedded-sizing/svg-in-object-auto.html b/testing/web-platform/tests/html/rendering/replaced-elements/svg-embedded-sizing/svg-in-object-auto.html
new file mode 100644
index 0000000000..7d79d2a428
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/replaced-elements/svg-embedded-sizing/svg-in-object-auto.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- This file is generated by gen-svgsizing-tests.py -->
+<html>
+ <head>
+ <title>SVG sizing: &lt;object></title>
+ <meta name=timeout content=long>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="../resources/svg-sizing.js"></script>
+ <style>
+ #testContainer {
+ position: absolute;
+ left: 0;
+ top: 0;
+ width: 800px;
+ height: 600px
+ }
+ iframe { border: 0 }
+ </style>
+ <link rel="help" href="http://www.w3.org/TR/CSS2/visudet.html#inline-replaced-width">
+ <link rel="help" href="http://www.w3.org/TR/CSS2/visudet.html#inline-replaced-height">
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#replaced-elements">
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#attr-dim-width">
+ <link rel="help" href="http://www.w3.org/TR/SVG/coords.html#ViewportSpace">
+ </head>
+ <body>
+ <div id="log"></div>
+ <div id="testContainer"></div>
+ <div id="demo"></div>
+ <script src="svg-embedded-sizing.js"></script>
+ <script>testPlaceholderWithHeight("object", null)</script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/rendering/replaced-elements/svg-embedded-sizing/svg-in-object-fixed.html b/testing/web-platform/tests/html/rendering/replaced-elements/svg-embedded-sizing/svg-in-object-fixed.html
new file mode 100644
index 0000000000..75f7636258
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/replaced-elements/svg-embedded-sizing/svg-in-object-fixed.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- This file is generated by gen-svgsizing-tests.py -->
+<html>
+ <head>
+ <title>SVG sizing: &lt;object></title>
+ <meta name=timeout content=long>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="../resources/svg-sizing.js"></script>
+ <style>
+ #testContainer {
+ position: absolute;
+ left: 0;
+ top: 0;
+ width: 800px;
+ height: 600px
+ }
+ iframe { border: 0 }
+ </style>
+ <link rel="help" href="http://www.w3.org/TR/CSS2/visudet.html#inline-replaced-width">
+ <link rel="help" href="http://www.w3.org/TR/CSS2/visudet.html#inline-replaced-height">
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#replaced-elements">
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#attr-dim-width">
+ <link rel="help" href="http://www.w3.org/TR/SVG/coords.html#ViewportSpace">
+ </head>
+ <body>
+ <div id="log"></div>
+ <div id="testContainer"></div>
+ <div id="demo"></div>
+ <script src="svg-embedded-sizing.js"></script>
+ <script>testPlaceholderWithHeight("object", '100px')</script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/rendering/replaced-elements/svg-embedded-sizing/svg-in-object-percentage.html b/testing/web-platform/tests/html/rendering/replaced-elements/svg-embedded-sizing/svg-in-object-percentage.html
new file mode 100644
index 0000000000..8f82836e1b
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/replaced-elements/svg-embedded-sizing/svg-in-object-percentage.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- This file is generated by gen-svgsizing-tests.py -->
+<html>
+ <head>
+ <title>SVG sizing: &lt;object></title>
+ <meta name=timeout content=long>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="../resources/svg-sizing.js"></script>
+ <style>
+ #testContainer {
+ position: absolute;
+ left: 0;
+ top: 0;
+ width: 800px;
+ height: 600px
+ }
+ iframe { border: 0 }
+ </style>
+ <link rel="help" href="http://www.w3.org/TR/CSS2/visudet.html#inline-replaced-width">
+ <link rel="help" href="http://www.w3.org/TR/CSS2/visudet.html#inline-replaced-height">
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#replaced-elements">
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#attr-dim-width">
+ <link rel="help" href="http://www.w3.org/TR/SVG/coords.html#ViewportSpace">
+ </head>
+ <body>
+ <div id="log"></div>
+ <div id="testContainer"></div>
+ <div id="demo"></div>
+ <script src="svg-embedded-sizing.js"></script>
+ <script>testPlaceholderWithHeight("object", '100%')</script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/rendering/replaced-elements/svg-inline-sizing/svg-inline.html b/testing/web-platform/tests/html/rendering/replaced-elements/svg-inline-sizing/svg-inline.html
new file mode 100644
index 0000000000..2b3cf65366
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/replaced-elements/svg-inline-sizing/svg-inline.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>SVG sizing: inline</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="../resources/svg-sizing.js"></script>
+ <style>
+ #testContainer {
+ position: absolute;
+ left: 0;
+ top: 0;
+ width: 800px;
+ height: 600px;
+ }
+ </style>
+ <link rel="help" href="http://www.w3.org/TR/CSS2/visudet.html#inline-replaced-width">
+ <link rel="help" href="http://www.w3.org/TR/CSS2/visudet.html#inline-replaced-height">
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#replaced-elements">
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#attr-dim-width">
+ <link rel="help" href="http://www.w3.org/TR/SVG/coords.html#ViewportSpace">
+ </head>
+ <body>
+ <div id="log"></div>
+ <div id="testContainer"></div>
+ <div id="demo"></div>
+ <script src="svg-inline.js"></script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/rendering/replaced-elements/svg-inline-sizing/svg-inline.js b/testing/web-platform/tests/html/rendering/replaced-elements/svg-inline-sizing/svg-inline.js
new file mode 100644
index 0000000000..9b7fca0502
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/replaced-elements/svg-inline-sizing/svg-inline.js
@@ -0,0 +1,79 @@
+// global async_test, assert_equals
+//
+// This test generates a couple of scenarios (each a
+// SVGSizing.TestData) for sizing inline <svg> and uses a simple
+// JavaScript sizing implementation for comparison.
+//
+// The tests loops through different combinations of:
+//
+// * width and height attributes and style on <svg>
+//
+// * viewBox on <svg> (gives intrinsic ratio)
+//
+// * width and height on containing block of <svg>
+//
+// All these may contribute to the final size of the SVG. The test
+// focuses on the size of the CSS box generated by the SVG. Little
+// focus is put on variations within an attribute that doesn't affect
+// the final size.
+//
+// To debug a specific test append ?<test-id> to the URL. An <iframe>
+// is generated with equivalent test and the source of the test is
+// added to a <pre> element.
+
+var debugHint = function(id) { return "(append ?"+id+" to debug) "; };
+var testSingleId;
+if (window.location.search) {
+ testSingleId = window.location.search.substring(1);
+ debugHint = function(id) { return ""; };
+}
+
+var testContainer = document.querySelector('#testContainer');
+var testContainerWidth = testContainer.getBoundingClientRect().width;
+var testContainerHeight = testContainer.getBoundingClientRect().height;
+
+SVGSizing.doCombinationTest(
+ [["placeholder", [ null ]],
+ ["containerWidthStyle", [null, "400px"]],
+ ["containerHeightStyle", [null, "400px"]],
+ ["svgViewBoxAttr", [ null, "0 0 100 200" ]],
+ ["svgWidthStyle", [ null, "100px", "50%" ]],
+ ["svgHeightStyle", [ null, "100px", "50%" ]],
+ ["svgWidthAttr", [ null, "200", "25%" ]],
+ ["svgHeightAttr", [ null, "200", "25%" ]]],
+ function(config, id, cont) {
+ var testData = new SVGSizing.TestData(config);
+
+ var expectedRect =
+ testData.computeInlineReplacedSize(testContainerWidth,
+ testContainerHeight);
+ var svgElement = testData.buildSVGOrPlaceholder();
+ var container =
+ testData.buildContainer(svgElement);
+
+ var checkSize = function() {
+ var svgRect =
+ svgElement.getBoundingClientRect();
+
+ try {
+ assert_equals(svgRect.width,
+ expectedRect.width,
+ debugHint(id) + "Wrong width");
+ assert_equals(svgRect.height,
+ expectedRect.height,
+ debugHint(id) + "Wrong height");
+ } finally {
+ testContainer.removeChild(container);
+ if (testSingleId)
+ document.body.removeChild(testContainer);
+ cont(id+1);
+ }
+ };
+
+ testContainer.appendChild(container);
+ test(checkSize, testData.name);
+
+ if (testSingleId == id) {
+ testData.buildDemo(expectedRect, id);
+ }
+ }, testSingleId);
diff --git a/testing/web-platform/tests/html/rendering/replaced-elements/the-option-element/option-with-br-ref.html b/testing/web-platform/tests/html/rendering/replaced-elements/the-option-element/option-with-br-ref.html
new file mode 100644
index 0000000000..954840f389
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/replaced-elements/the-option-element/option-with-br-ref.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>option element with br child</title>
+<link rel="author" title="Domenic Denicola" href="mailto:d@domenic.me">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#concept-option-label">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-option-text">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#the-select-element-2">
+
+<p>This test passes if the option element displays three options:</p>
+
+<pre>a
+b
+ab</pre>
+
+<p>Importantly the third option must not be split across two lines.</p>
+
+<select multiple>
+ <option>a</option>
+ <option>b</option>
+ <option>ab</option>
+</select>
diff --git a/testing/web-platform/tests/html/rendering/replaced-elements/the-option-element/option-with-br.html b/testing/web-platform/tests/html/rendering/replaced-elements/the-option-element/option-with-br.html
new file mode 100644
index 0000000000..3b8d992cc2
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/replaced-elements/the-option-element/option-with-br.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>option element with br child</title>
+<link rel="author" title="Domenic Denicola" href="mailto:d@domenic.me">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#concept-option-label">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-option-text">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#the-select-element-2">
+
+<link rel="match" href="option-with-br-ref.html">
+
+<p>This test passes if the option element displays three options:</p>
+
+<pre>a
+b
+ab</pre>
+
+<p>Importantly the third option must not be split across two lines.</p>
+
+<select multiple>
+ <option>a</option>
+ <option>b</option>
+ <option id="manipulate-me"></option>
+</select>
+
+<script>
+"use strict";
+const option = document.querySelector("#manipulate-me");
+
+option.appendChild(document.createTextNode("a"));
+option.appendChild(document.createElement("br"));
+option.appendChild(document.createTextNode("b"));
+</script>
diff --git a/testing/web-platform/tests/html/rendering/replaced-elements/the-option-element/select-multiple-covered-by-abspos-ref.html b/testing/web-platform/tests/html/rendering/replaced-elements/the-option-element/select-multiple-covered-by-abspos-ref.html
new file mode 100644
index 0000000000..3cb496ea1b
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/replaced-elements/the-option-element/select-multiple-covered-by-abspos-ref.html
@@ -0,0 +1,11 @@
+<!doctype html>
+<title>Test reference</title>
+<style>
+.abspos {
+ position: absolute;
+ background-color: green;
+ height: 300px;
+ width: 300px;
+}
+</style>
+<div class="abspos"></div>
diff --git a/testing/web-platform/tests/html/rendering/replaced-elements/the-option-element/select-multiple-covered-by-abspos.html b/testing/web-platform/tests/html/rendering/replaced-elements/the-option-element/select-multiple-covered-by-abspos.html
new file mode 100644
index 0000000000..ed290250da
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/replaced-elements/the-option-element/select-multiple-covered-by-abspos.html
@@ -0,0 +1,19 @@
+<!doctype html>
+<meta charset="utf-8">
+<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1770532">
+<link rel="author" href="mailto:dholbert@mozilla.com" title="Daniel Holbert">
+<link rel="author" href="https://mozilla.org" title="Mozilla">
+<link rel="match" href="select-multiple-covered-by-abspos-ref.html">
+<title>Combobox selects are not stacking contexts by default</title>
+<style>
+.abspos {
+ position: absolute;
+ background-color: green;
+ height: 300px;
+ width: 300px;
+}
+</style>
+<div class="abspos"></div>
+<select multiple>
+ <option>This text shouldn't be visible.</option>
+</select>
diff --git a/testing/web-platform/tests/html/rendering/replaced-elements/the-select-element/select-1-block-size-001-ref-2.html b/testing/web-platform/tests/html/rendering/replaced-elements/the-select-element/select-1-block-size-001-ref-2.html
new file mode 100644
index 0000000000..385c2a75d4
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/replaced-elements/the-select-element/select-1-block-size-001-ref-2.html
@@ -0,0 +1,24 @@
+<!doctype html>
+<title>CSS Test Reference</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=1571764">
+<style>
+div {
+ -webkit-appearance: none;
+ appearance: none;
+
+ background: black;
+ color: black;
+
+ line-height: 100px;
+ width: 100px;
+
+ border: 0;
+ padding: 0;
+
+ display: inline-block;
+}
+</style>
+<div>A</div>
+<div>A</div>
diff --git a/testing/web-platform/tests/html/rendering/replaced-elements/the-select-element/select-1-block-size-001-ref.html b/testing/web-platform/tests/html/rendering/replaced-elements/the-select-element/select-1-block-size-001-ref.html
new file mode 100644
index 0000000000..3834281dd8
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/replaced-elements/the-select-element/select-1-block-size-001-ref.html
@@ -0,0 +1,24 @@
+<!doctype html>
+<title>CSS Test Reference</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=1571764">
+<link rel="match" href="select-1-block-size-001-ref-2.html">
+<style>
+button {
+ -webkit-appearance: none;
+ appearance: none;
+
+ background: black;
+ color: black;
+
+ line-height: 100px;
+ width: 100px;
+
+ border: 0;
+ border-radius: 0;
+ padding: 0;
+}
+</style>
+<button>A</button>
+<button>A</button>
diff --git a/testing/web-platform/tests/html/rendering/replaced-elements/the-select-element/select-1-block-size-001.html b/testing/web-platform/tests/html/rendering/replaced-elements/the-select-element/select-1-block-size-001.html
new file mode 100644
index 0000000000..5dc0fc15dc
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/replaced-elements/the-select-element/select-1-block-size-001.html
@@ -0,0 +1,24 @@
+<!doctype html>
+<title>Select block size when line-height is specified</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=1571764">
+<link rel="match" href="select-1-block-size-001-ref.html">
+<style>
+select {
+ -webkit-appearance: none;
+ appearance: none;
+
+ background: black;
+ color: black;
+
+ line-height: 100px;
+ width: 100px;
+
+ border: 0;
+ border-radius: 0;
+ padding: 0;
+}
+</style>
+<select></select>
+<select><option>A</option></select>
diff --git a/testing/web-platform/tests/html/rendering/replaced-elements/the-select-element/select-1-block-size-ref.html b/testing/web-platform/tests/html/rendering/replaced-elements/the-select-element/select-1-block-size-ref.html
new file mode 100644
index 0000000000..3e437494c0
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/replaced-elements/the-select-element/select-1-block-size-ref.html
@@ -0,0 +1,33 @@
+<!DOCTYPE HTML>
+<!--
+ Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<html><head>
+ <meta charset="utf-8">
+ <title>Reference: Combobox block-size test</title>
+ <link rel="author" title="Mats Palmgren" href="mailto:mats@mozilla.com">
+ <style>
+html,body {
+ color:black; background-color:white; font:16px/1 monospace; padding:0; margin:0;
+}
+
+select { -webkit-appearance: none; }
+
+.big { font-size: 48pt; min-height: 40pt; }
+.lh { line-height: 48pt; min-height: 40pt; }
+
+.mask { position:fixed; left:20px; right:0; top:0; bottom:0; background: black; }
+ </style>
+</head>
+<body>
+
+<!-- mask off differences on the right side -->
+<div class="mask"></div>
+
+<select><optgroup label="label"><option>option</option></select><br>
+<select class="big"><optgroup label="label"><option>option</option></select><br>
+<select class="lh"><optgroup label="label"><option>option</option></select><br>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/rendering/replaced-elements/the-select-element/select-1-block-size.html b/testing/web-platform/tests/html/rendering/replaced-elements/the-select-element/select-1-block-size.html
new file mode 100644
index 0000000000..4aecc596ce
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/replaced-elements/the-select-element/select-1-block-size.html
@@ -0,0 +1,38 @@
+<!DOCTYPE HTML>
+<!--
+ Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<html><head>
+ <meta charset="utf-8">
+ <title>Test: Combobox block-size test</title>
+ <link rel="author" title="Mats Palmgren" href="mailto:mats@mozilla.com">
+ <link rel="match" href="select-1-block-size-ref.html">
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/rendering.html#the-select-element-2">
+ <link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1499578">
+ <style>
+html,body {
+ color:black; background-color:white; font:16px/1 monospace; padding:0; margin:0;
+}
+
+select { -webkit-appearance: none; }
+
+optgroup { font-size: 32pt; }
+option { font-size: 24pt; }
+.big { font-size: 48pt; }
+.lh { line-height: 48pt; }
+
+.mask { position:fixed; left:20px; right:0; top:0; bottom:0; background: black; }
+ </style>
+</head>
+<body>
+
+<!-- mask off differences on the right side -->
+<div class="mask"></div>
+
+<select><optgroup label="label"><option>option</option></select><br>
+<select class="big"><optgroup label="label"><option>option</option></select><br>
+<select class="lh"><optgroup label="label"><option>option</option></select><br>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/rendering/replaced-elements/the-select-element/select-1-line-height-ref.html b/testing/web-platform/tests/html/rendering/replaced-elements/the-select-element/select-1-line-height-ref.html
new file mode 100644
index 0000000000..26e5f33282
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/replaced-elements/the-select-element/select-1-line-height-ref.html
@@ -0,0 +1,23 @@
+<!DOCTYPE HTML>
+<!--
+ Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<html><head>
+ <meta charset="utf-8">
+ <title>Reference: Combobox ignores CSS 'line-height'</title>
+ <link rel="author" title="Mats Palmgren" href="mailto:mats@mozilla.com">
+ <style type="text/css">
+html,body {
+ color:black; background-color:white; font:16px/1 monospace;
+}
+
+ </style>
+</head>
+<body>
+
+<select><option>aaaaaaaaaa<option>bbbbbbbbbb</select>
+
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/rendering/replaced-elements/the-select-element/select-1-line-height.html b/testing/web-platform/tests/html/rendering/replaced-elements/the-select-element/select-1-line-height.html
new file mode 100644
index 0000000000..605a988e25
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/replaced-elements/the-select-element/select-1-line-height.html
@@ -0,0 +1,36 @@
+<!DOCTYPE HTML>
+<!--
+ Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<html><head>
+ <meta charset="utf-8">
+ <title>Test: Combobox ignores CSS 'line-height'</title>
+ <link rel="author" title="Mats Palmgren" href="mailto:mats@mozilla.com">
+ <link rel="match" href="select-1-line-height-ref.html">
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/rendering.html#the-select-element-2">
+ <link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1501908">
+ <style type="text/css">
+html,body {
+ color:black; background-color:white; font:16px/1 monospace;
+}
+
+select { line-height:100px; }
+
+ </style>
+</head>
+<body>
+
+<select><option>aaaaaaaaaa<option>bbbbbbbbbb</select>
+
+<script>
+document.body.offsetHeight;
+var cv = window.getComputedStyle(document.querySelector('select')).lineHeight;
+if (cv != "normal" && parseInt(cv) > 50) {
+ document.body.appendChild(document.createTextNode(
+ "FAIL: got computed line-height '" + cv + "', " +
+ "expected 'normal' or a length <= 50px"));
+}</script>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/rendering/replaced-elements/the-select-element/select-empty-ref.html b/testing/web-platform/tests/html/rendering/replaced-elements/the-select-element/select-empty-ref.html
new file mode 100644
index 0000000000..31ba23a5cf
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/replaced-elements/the-select-element/select-empty-ref.html
@@ -0,0 +1,35 @@
+<!DOCTYPE HTML>
+<!--
+ Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<html><head>
+ <meta charset="utf-8">
+ <title>Reference: empty SELECT</title>
+ <link rel="author" title="Mats Palmgren" href="mailto:mats@mozilla.com">
+ <style>
+
+.none { display: none; }
+
+ </style>
+</head>
+<body>
+
+<table border="1" cellpadding="10">
+<tr>
+<td><select size="4"><option class="none"></select>
+<td><select size="4" style="-webkit-appearance: none"><option class="none">option</select>
+<td><select size="4" style="-webkit-appearance: none; border: 1px solid black"><option class="none">option</select>
+<td><select size="4" style="border: 1px solid black"><option class="none">option</select>
+</table>
+
+<table border="1" cellpadding="10">
+<tr>
+<td><select size="1"><option class="none"></select>
+<td><select size="1" style="-webkit-appearance: none"><option class="none"></select>
+<td><select size="1" style="-webkit-appearance: none; border: 1px solid black"><option class="none"></select>
+<td><select size="1" style="border: 1px solid black"><option class="none"></select>
+</table>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/rendering/replaced-elements/the-select-element/select-empty.html b/testing/web-platform/tests/html/rendering/replaced-elements/the-select-element/select-empty.html
new file mode 100644
index 0000000000..6568a6de34
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/replaced-elements/the-select-element/select-empty.html
@@ -0,0 +1,33 @@
+<!DOCTYPE HTML>
+<!--
+ Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<html><head>
+ <meta charset="utf-8">
+ <title>Test: empty SELECT</title>
+ <link rel="author" title="Mats Palmgren" href="mailto:mats@mozilla.com">
+ <link rel="match" href="select-empty-ref.html">
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/rendering.html#the-select-element-2">
+ <link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1499230">
+</head>
+<body>
+
+<table border="1" cellpadding="10">
+<tr>
+<td><select size="4"></select>
+<td><select size="4" style="-webkit-appearance: none"></select>
+<td><select size="4" style="-webkit-appearance: none; border: 1px solid black"></select>
+<td><select size="4" style="border: 1px solid black"></select>
+</table>
+
+<table border="1" cellpadding="10">
+<tr>
+<td><select size="1"></select>
+<td><select size="1" style="-webkit-appearance: none"></select>
+<td><select size="1" style="-webkit-appearance: none; border: 1px solid black"></select>
+<td><select size="1" style="border: 1px solid black"></select>
+</table>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/rendering/replaced-elements/the-select-element/select-intrinsic-option-font-size-ref.html b/testing/web-platform/tests/html/rendering/replaced-elements/the-select-element/select-intrinsic-option-font-size-ref.html
new file mode 100644
index 0000000000..8b1b422176
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/replaced-elements/the-select-element/select-intrinsic-option-font-size-ref.html
@@ -0,0 +1,8 @@
+<!doctype html>
+<title>CSS Test Reference</title>
+<select>
+ <option>ABC</option>
+</select>
+<select>
+ <option>ABC</option>
+</select>
diff --git a/testing/web-platform/tests/html/rendering/replaced-elements/the-select-element/select-intrinsic-option-font-size.html b/testing/web-platform/tests/html/rendering/replaced-elements/the-select-element/select-intrinsic-option-font-size.html
new file mode 100644
index 0000000000..7f36708973
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/replaced-elements/the-select-element/select-intrinsic-option-font-size.html
@@ -0,0 +1,9 @@
+<!doctype html>
+<title>Select should be as wide as needed to fit its options regardless of option styles</title>
+<link rel=match href=select-intrinsic-option-font-size-ref.html>
+<select>
+ <option style="font-size: 5px">ABC</option>
+</select>
+<select>
+ <option style="font-size: 50px">ABC</option>
+</select>
diff --git a/testing/web-platform/tests/html/rendering/replaced-elements/the-select-element/select-intrinsic-text-transform-ref.html b/testing/web-platform/tests/html/rendering/replaced-elements/the-select-element/select-intrinsic-text-transform-ref.html
new file mode 100644
index 0000000000..18e272ba10
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/replaced-elements/the-select-element/select-intrinsic-text-transform-ref.html
@@ -0,0 +1,5 @@
+<!doctype html>
+<title>CSS Test Reference</title>
+<select>
+ <option>ABCDEFGHIJK</option>
+</select>
diff --git a/testing/web-platform/tests/html/rendering/replaced-elements/the-select-element/select-intrinsic-text-transform.html b/testing/web-platform/tests/html/rendering/replaced-elements/the-select-element/select-intrinsic-text-transform.html
new file mode 100644
index 0000000000..1026e29977
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/replaced-elements/the-select-element/select-intrinsic-text-transform.html
@@ -0,0 +1,8 @@
+<!doctype html>
+<title>text-transform in option doesn't affect combobox rendering</title>
+<link rel=match href=select-intrinsic-text-transform-ref.html>
+<link rel=help href="https://bugs.chromium.org/p/chromium/issues/detail?id=1283930">
+<link rel=author href="mailto:emilio@crisal.io" title="Emilio Cobos Álvarez">
+<select>
+ <option style="text-transform: lowercase">ABCDEFGHIJK</option>
+</select>
diff --git a/testing/web-platform/tests/html/rendering/replaced-elements/the-select-element/select-multiple-re-add-option-via-document-fragment-ref.html b/testing/web-platform/tests/html/rendering/replaced-elements/the-select-element/select-multiple-re-add-option-via-document-fragment-ref.html
new file mode 100644
index 0000000000..cb66ddaaaf
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/replaced-elements/the-select-element/select-multiple-re-add-option-via-document-fragment-ref.html
@@ -0,0 +1,4 @@
+<!doctype html>
+<title>Reference: Move option from select[multiple] into DocumentFragment and back</title>
+<p>You should see the word PASS below.</p>
+<select multiple><option>PASS</option></select>
diff --git a/testing/web-platform/tests/html/rendering/replaced-elements/the-select-element/select-multiple-re-add-option-via-document-fragment.html b/testing/web-platform/tests/html/rendering/replaced-elements/the-select-element/select-multiple-re-add-option-via-document-fragment.html
new file mode 100644
index 0000000000..844f05639c
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/replaced-elements/the-select-element/select-multiple-re-add-option-via-document-fragment.html
@@ -0,0 +1,12 @@
+<!doctype html>
+<title>Test: Move option from select[multiple] into DocumentFragment and back</title>
+<link rel="help" href="https://html.spec.whatwg.org/multipage/rendering.html#the-select-element-2">
+<link rel="match" href="select-multiple-re-add-option-via-document-fragment-ref.html">
+<p>You should see the word PASS below.</p>
+<select multiple id="sel"><option id="opt">PASS</option></select>
+<script>
+ document.body.offsetTop;
+ let rm = opt;
+ document.createDocumentFragment().appendChild(rm);
+ sel.appendChild(rm);
+</script>
diff --git a/testing/web-platform/tests/html/rendering/replaced-elements/the-textarea-element/textarea-padding-bend-overlaps-content-001-ref.html b/testing/web-platform/tests/html/rendering/replaced-elements/the-textarea-element/textarea-padding-bend-overlaps-content-001-ref.html
new file mode 100644
index 0000000000..2f479dd72a
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/replaced-elements/the-textarea-element/textarea-padding-bend-overlaps-content-001-ref.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>Reference Case</title>
+
+<link rel="stylesheet" href="/fonts/ahem.css">
+<style>
+textarea {
+ font: 10px/1 Ahem;
+
+ block-size: 8em;
+ inline-size: 10em;
+
+ padding-block-end: 0;
+}
+.rtl { direction: rtl; }
+.vlr { writing-mode: vertical-lr; }
+.vrl { writing-mode: vertical-rl; }
+.slr { writing-mode: sideways-lr; }
+.srl { writing-mode: sideways-rl; }
+</style>
+<textarea>X</textarea>
+<textarea class="rtl">X</textarea>
+<br>
+<textarea class="vlr">X</textarea>
+<textarea class="vrl">X</textarea>
+<textarea class="slr">X</textarea>
+<textarea class="srl">X</textarea>
+<br>
+<textarea class="vlr rtl">X</textarea>
+<textarea class="vrl rtl">X</textarea>
+<textarea class="slr rtl">X</textarea>
+<textarea class="srl rtl">X</textarea>
diff --git a/testing/web-platform/tests/html/rendering/replaced-elements/the-textarea-element/textarea-padding-bend-overlaps-content-001.tentative.html b/testing/web-platform/tests/html/rendering/replaced-elements/the-textarea-element/textarea-padding-bend-overlaps-content-001.tentative.html
new file mode 100644
index 0000000000..d99ca1956f
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/replaced-elements/the-textarea-element/textarea-padding-bend-overlaps-content-001.tentative.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>Test: padding-block-end on a textarea creates space that content can render into</title>
+<link rel="help" href="https://html.spec.whatwg.org/multipage/rendering.html#the-textarea-element-2">
+<link rel="match" href="textarea-padding-bend-overlaps-content-001-ref.html">
+
+<link rel="stylesheet" href="/fonts/ahem.css">
+<style>
+textarea {
+ font: 10px/1 Ahem;
+
+ /* Zero out the content-box, leaving the padding area as the only
+ place where the contents might get rendered. */
+ block-size: 0;
+ inline-size: 10em;
+
+ padding-block-end: 8em;
+
+ /* The textarea's padding-block-end may create overflow in the block axis,
+ and hence generate a scrollbar in the testcase that's not present in the
+ reference case (and might be hard to properly mock up there). We avoid
+ this problem by suppressing scrollbars using "overflow:hidden": */
+ overflow: hidden;
+}
+.rtl { direction: rtl; }
+.vlr { writing-mode: vertical-lr; }
+.vrl { writing-mode: vertical-rl; }
+.slr { writing-mode: sideways-lr; }
+.srl { writing-mode: sideways-rl; }
+</style>
+
+<textarea>X</textarea>
+<textarea class="rtl">X</textarea>
+<br>
+<textarea class="vlr">X</textarea>
+<textarea class="vrl">X</textarea>
+<textarea class="slr">X</textarea>
+<textarea class="srl">X</textarea>
+<br>
+<textarea class="vlr rtl">X</textarea>
+<textarea class="vrl rtl">X</textarea>
+<textarea class="slr rtl">X</textarea>
+<textarea class="srl rtl">X</textarea>
diff --git a/testing/web-platform/tests/html/rendering/replaced-elements/the-textarea-element/textarea-padding-bstart-moves-content-001-ref.html b/testing/web-platform/tests/html/rendering/replaced-elements/the-textarea-element/textarea-padding-bstart-moves-content-001-ref.html
new file mode 100644
index 0000000000..5144f18660
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/replaced-elements/the-textarea-element/textarea-padding-bstart-moves-content-001-ref.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>Reference Case</title>
+
+<link rel="stylesheet" href="/fonts/ahem.css">
+<style>
+textarea {
+ font: 10px/1 Ahem;
+
+ block-size: 8em;
+ inline-size: 10em;
+
+ padding-block-start: 0;
+ padding-block-end: 0;
+}
+.rtl { direction: rtl; }
+.vlr { writing-mode: vertical-lr; }
+.vrl { writing-mode: vertical-rl; }
+.slr { writing-mode: sideways-lr; }
+.srl { writing-mode: sideways-rl; }
+</style>
+
+<textarea></textarea>
+<textarea class="rtl"></textarea>
+<br>
+<textarea class="vlr"></textarea>
+<textarea class="vrl"></textarea>
+<textarea class="slr"></textarea>
+<textarea class="srl"></textarea>
+<br>
+<textarea class="vlr rtl"></textarea>
+<textarea class="vrl rtl"></textarea>
+<textarea class="slr rtl"></textarea>
+<textarea class="srl rtl"></textarea>
diff --git a/testing/web-platform/tests/html/rendering/replaced-elements/the-textarea-element/textarea-padding-bstart-moves-content-001.tentative.html b/testing/web-platform/tests/html/rendering/replaced-elements/the-textarea-element/textarea-padding-bstart-moves-content-001.tentative.html
new file mode 100644
index 0000000000..f4643af132
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/replaced-elements/the-textarea-element/textarea-padding-bstart-moves-content-001.tentative.html
@@ -0,0 +1,46 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>Test: padding-block-start on a textarea moves the textarea content over, potentially out of the textarea's scrollport</title>
+<link rel="help" href="https://html.spec.whatwg.org/multipage/rendering.html#the-textarea-element-2">
+<link rel="match" href="textarea-padding-bstart-moves-content-001-ref.html">
+
+<link rel="stylesheet" href="/fonts/ahem.css">
+<style>
+textarea {
+ font: 10px/1 Ahem;
+
+ /* Zero out the content-box, leaving the padding area as the only
+ place where the contents might get rendered. */
+ block-size: 0;
+ inline-size: 10em;
+
+ padding-block-start: 8em;
+ padding-block-end: 0;
+
+ /* We expect the textarea's content to overflow in the block direction,
+ which makes the textarea blank, aside from any scrollbars that might get
+ created by this overflow. We use overflow:hidden here to suppress these
+ scrollbars, so that the reference case can just use a trivial empty
+ textarea (without needing to worry about mocking up scrollbars of
+ precisely the right size). */
+ overflow: hidden;
+}
+.rtl { direction: rtl; }
+.vlr { writing-mode: vertical-lr; }
+.vrl { writing-mode: vertical-rl; }
+.slr { writing-mode: sideways-lr; }
+.srl { writing-mode: sideways-rl; }
+</style>
+
+<textarea>X</textarea>
+<textarea class="rtl">X</textarea>
+<br>
+<textarea class="vlr">X</textarea>
+<textarea class="vrl">X</textarea>
+<textarea class="slr">X</textarea>
+<textarea class="srl">X</textarea>
+<br>
+<textarea class="vlr rtl">X</textarea>
+<textarea class="vrl rtl">X</textarea>
+<textarea class="slr rtl">X</textarea>
+<textarea class="srl rtl">X</textarea>
diff --git a/testing/web-platform/tests/html/rendering/replaced-elements/the-textarea-element/textarea-padding-iend-overlaps-content-001-ref.html b/testing/web-platform/tests/html/rendering/replaced-elements/the-textarea-element/textarea-padding-iend-overlaps-content-001-ref.html
new file mode 100644
index 0000000000..94473c0873
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/replaced-elements/the-textarea-element/textarea-padding-iend-overlaps-content-001-ref.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>Reference Case</title>
+
+<link rel="stylesheet" href="/fonts/ahem.css">
+<style>
+textarea {
+ font: 10px/1 Ahem;
+
+ inline-size: 8em;
+ block-size: 10em;
+
+ padding-inline-end: 0;
+}
+.rtl { direction: rtl; }
+.vlr { writing-mode: vertical-lr; }
+.vrl { writing-mode: vertical-rl; }
+.slr { writing-mode: sideways-lr; }
+.srl { writing-mode: sideways-rl; }
+</style>
+<textarea>X</textarea>
+<textarea class="rtl">X</textarea>
+<br>
+<textarea class="vlr">X</textarea>
+<textarea class="vrl">X</textarea>
+<textarea class="slr">X</textarea>
+<textarea class="srl">X</textarea>
+<br>
+<textarea class="vlr rtl">X</textarea>
+<textarea class="vrl rtl">X</textarea>
+<textarea class="slr rtl">X</textarea>
+<textarea class="srl rtl">X</textarea>
diff --git a/testing/web-platform/tests/html/rendering/replaced-elements/the-textarea-element/textarea-padding-iend-overlaps-content-001.tentative.html b/testing/web-platform/tests/html/rendering/replaced-elements/the-textarea-element/textarea-padding-iend-overlaps-content-001.tentative.html
new file mode 100644
index 0000000000..80cbbe3c1e
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/replaced-elements/the-textarea-element/textarea-padding-iend-overlaps-content-001.tentative.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>Test: padding-inline-end on a textarea creates space that content can render into</title>
+<link rel="help" href="https://html.spec.whatwg.org/multipage/rendering.html#the-textarea-element-2">
+<link rel="match" href="textarea-padding-iend-overlaps-content-001-ref.html">
+
+<link rel="stylesheet" href="/fonts/ahem.css">
+<style>
+textarea {
+ font: 10px/1 Ahem;
+
+ /* Zero out the content-box, leaving the padding area as the only
+ place where the contents might get rendered. */
+ inline-size: 0;
+ block-size: 10em;
+
+ padding-inline-end: 8em;
+}
+.rtl { direction: rtl; }
+.vlr { writing-mode: vertical-lr; }
+.vrl { writing-mode: vertical-rl; }
+.slr { writing-mode: sideways-lr; }
+.srl { writing-mode: sideways-rl; }
+</style>
+
+<textarea>X</textarea>
+<textarea class="rtl">X</textarea>
+<br>
+<textarea class="vlr">X</textarea>
+<textarea class="vrl">X</textarea>
+<textarea class="slr">X</textarea>
+<textarea class="srl">X</textarea>
+<br>
+<textarea class="vlr rtl">X</textarea>
+<textarea class="vrl rtl">X</textarea>
+<textarea class="slr rtl">X</textarea>
+<textarea class="srl rtl">X</textarea>
diff --git a/testing/web-platform/tests/html/rendering/replaced-elements/the-textarea-element/textarea-padding-istart-moves-content-001-ref.html b/testing/web-platform/tests/html/rendering/replaced-elements/the-textarea-element/textarea-padding-istart-moves-content-001-ref.html
new file mode 100644
index 0000000000..eb88858b87
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/replaced-elements/the-textarea-element/textarea-padding-istart-moves-content-001-ref.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>Reference Case</title>
+
+<link rel="stylesheet" href="/fonts/ahem.css">
+<style>
+textarea {
+ font: 10px/1 Ahem;
+
+ inline-size: 8em;
+ block-size: 10em;
+
+ padding-inline-start: 0;
+ padding-inline-end: 0;
+}
+.rtl { direction: rtl; }
+.vlr { writing-mode: vertical-lr; }
+.vrl { writing-mode: vertical-rl; }
+.slr { writing-mode: sideways-lr; }
+.srl { writing-mode: sideways-rl; }
+</style>
+
+<textarea></textarea>
+<textarea class="rtl"></textarea>
+<br>
+<textarea class="vlr"></textarea>
+<textarea class="vrl"></textarea>
+<textarea class="slr"></textarea>
+<textarea class="srl"></textarea>
+<br>
+<textarea class="vlr rtl"></textarea>
+<textarea class="vrl rtl"></textarea>
+<textarea class="slr rtl"></textarea>
+<textarea class="srl rtl"></textarea>
diff --git a/testing/web-platform/tests/html/rendering/replaced-elements/the-textarea-element/textarea-padding-istart-moves-content-001.tentative.html b/testing/web-platform/tests/html/rendering/replaced-elements/the-textarea-element/textarea-padding-istart-moves-content-001.tentative.html
new file mode 100644
index 0000000000..f5abf84c12
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/replaced-elements/the-textarea-element/textarea-padding-istart-moves-content-001.tentative.html
@@ -0,0 +1,46 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>Test: padding-inline-start on a textarea moves the textarea content over, potentially out of the textarea's scrollport</title>
+<link rel="help" href="https://html.spec.whatwg.org/multipage/rendering.html#the-textarea-element-2">
+<link rel="match" href="textarea-padding-istart-moves-content-001-ref.html">
+
+<link rel="stylesheet" href="/fonts/ahem.css">
+<style>
+textarea {
+ font: 10px/1 Ahem;
+
+ /* Zero out the content-box, leaving the padding area as the only
+ place where the contents might get rendered. */
+ inline-size: 0;
+ block-size: 10em;
+
+ padding-inline-start: 8em;
+ padding-inline-end: 0;
+
+ /* We expect the textarea's content to overflow in the inline direction,
+ which makes the textarea blank, aside from any scrollbars that might get
+ created by this overflow. We use overflow:hidden here to suppress these
+ scrollbars, so that the reference case can just use a trivial empty
+ textarea (without needing to worry about mocking up scrollbars of
+ precisely the right size). */
+ overflow: hidden;
+}
+.rtl { direction: rtl; }
+.vlr { writing-mode: vertical-lr; }
+.vrl { writing-mode: vertical-rl; }
+.slr { writing-mode: sideways-lr; }
+.srl { writing-mode: sideways-rl; }
+</style>
+
+<textarea>X</textarea>
+<textarea class="rtl">X</textarea>
+<br>
+<textarea class="vlr">X</textarea>
+<textarea class="vrl">X</textarea>
+<textarea class="slr">X</textarea>
+<textarea class="srl">X</textarea>
+<br>
+<textarea class="vlr rtl">X</textarea>
+<textarea class="vrl rtl">X</textarea>
+<textarea class="slr rtl">X</textarea>
+<textarea class="srl rtl">X</textarea>
diff --git a/testing/web-platform/tests/html/rendering/replaced-elements/tools/gen-svgsizing-tests.py b/testing/web-platform/tests/html/rendering/replaced-elements/tools/gen-svgsizing-tests.py
new file mode 100644
index 0000000000..5ba69f8ab5
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/replaced-elements/tools/gen-svgsizing-tests.py
@@ -0,0 +1,55 @@
+from string import Template
+import os
+import sys
+
+template = Template("""<!DOCTYPE html>
+<!-- This file is generated by $generator -->
+<html>
+ <head>
+ <title>SVG sizing: &lt;$placeholder></title>
+ <meta name=timeout content=long>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="../resources/svg-sizing.js"></script>
+ <style>
+ #testContainer {
+ position: absolute;
+ left: 0;
+ top: 0;
+ width: 800px;
+ height: 600px
+ }
+ iframe { border: 0 }
+ </style>
+ <link rel="help" href="http://www.w3.org/TR/CSS2/visudet.html#inline-replaced-width">
+ <link rel="help" href="http://www.w3.org/TR/CSS2/visudet.html#inline-replaced-height">
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#replaced-elements">
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#attr-dim-width">
+ <link rel="help" href="http://www.w3.org/TR/SVG/coords.html#ViewportSpace">
+ </head>
+ <body>
+ <div id="log"></div>
+ <div id="testContainer"></div>
+ <div id="demo"></div>
+ <script src="svg-embedded-sizing.js"></script>
+ <script>testPlaceholderWithHeight("$placeholder", $placeholderHeightAttr)</script>
+ </body>
+</html>
+""")
+
+placeholders = [ "object", "iframe", "img" ]
+placeholderHeightAttrs = [ "null", "'100px'", "'100%'" ]
+placeholderHeightAttrsDescriptions = [ "auto", "fixed", "percentage" ]
+
+try:
+ os.makedirs("../svg-embedded-sizing")
+except OSError:
+ pass
+
+for placeholder in placeholders:
+ for i, placeholderHeightAttr in enumerate(placeholderHeightAttrs):
+ testContent = template.substitute(placeholder=placeholder, placeholderHeightAttr=placeholderHeightAttr, generator=sys.argv[0])
+ filename = "../svg-embedded-sizing/svg-in-%s-%s.html" % (placeholder, placeholderHeightAttrsDescriptions[i])
+ f = open(filename, "w")
+ f.write(testContent)
+ f.close()
diff --git a/testing/web-platform/tests/html/rendering/support/test-ua-stylesheet.js b/testing/web-platform/tests/html/rendering/support/test-ua-stylesheet.js
new file mode 100644
index 0000000000..e23c9a6720
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/support/test-ua-stylesheet.js
@@ -0,0 +1,74 @@
+function runUAStyleTests(props) {
+ const refs = document.getElementById('refs');
+ for (const el of document.querySelectorAll('#tests > *')) {
+ const clone = fakeClone(el);
+ refs.append(clone);
+ }
+ const testsContainer = document.getElementById('tests');
+ const testEls = document.querySelectorAll('#tests *');
+ const refEls = document.querySelectorAll('#refs *');
+ for (let i = 0; i < testEls.length; ++i) {
+ const testEl = testEls[i];
+ if (testEl.hasAttribute('data-skip')) {
+ continue;
+ }
+ const refEl = refEls[i];
+ const testStyle = getComputedStyle(testEl);
+ const refStyle = getComputedStyle(refEl);
+ for (const prop of props) {
+ // Don't test display for some elements.
+ // TODO(zcorpan): https://github.com/whatwg/html/issues/4093
+ // TODO(zcorpan): https://github.com/whatwg/html/issues/5063
+ if (prop === 'display' &&
+ (testEl.localName === 'optgroup' ||
+ testEl.localName === 'option' ||
+ testEl.localName === 'marquee')
+ ) {
+ continue;
+ }
+ if (prop === 'overflow' && testEl.localName === 'select') {
+ // TODO: https://github.com/whatwg/html/issues/10031
+ continue;
+ }
+ test(() => {
+ assert_equals(testStyle.getPropertyValue(prop), refStyle.getPropertyValue(prop));
+ }, `${testNameContext(testEl)} - ${prop}`);
+ }
+ }
+
+ function fakeClone(el) {
+ const clone = document.createElementNS('urn:not-html', el.localName);
+ for (const att of el.attributes) {
+ clone.setAttributeNS(att.namespaceURI, att.name, att.value);
+ }
+ // deep clone
+ for (const child of el.children) {
+ clone.append(fakeClone(child));
+ }
+ return clone;
+ }
+
+ function testNameContext(el) {
+ const outerHTML = el.outerHTML;
+ const startTags = outerHTML.substring(0, outerHTML.indexOf('</')) || outerHTML;
+
+ let ancestors = [];
+ let current = el.parentNode;
+ while (current != testsContainer) {
+ ancestors.unshift(`<${current.localName}${contextAttrs(current.attributes)}>`);
+ current = current.parentNode;
+ }
+ return startTags + (ancestors.length ? ` (in ${ancestors.join('')})` : '');
+ }
+
+ function contextAttrs(attributes) {
+ let rv = "";
+ for (let i = 0; i < attributes.length; ++i) {
+ if (attributes[i].name === 'data-skip') {
+ continue;
+ }
+ rv += ` ${attributes[i].name}="${attributes[i].value}"`;
+ }
+ return rv;
+ }
+}
diff --git a/testing/web-platform/tests/html/rendering/the-css-user-agent-style-sheet-and-presentational-hints/body-bgcolor-attribute-change-ref.html b/testing/web-platform/tests/html/rendering/the-css-user-agent-style-sheet-and-presentational-hints/body-bgcolor-attribute-change-ref.html
new file mode 100644
index 0000000000..43f0c6dd20
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/the-css-user-agent-style-sheet-and-presentational-hints/body-bgcolor-attribute-change-ref.html
@@ -0,0 +1,4 @@
+<!doctype html>
+<body bgcolor="green">
+ Passes if the background is green.
+</body>
diff --git a/testing/web-platform/tests/html/rendering/the-css-user-agent-style-sheet-and-presentational-hints/body-bgcolor-attribute-change.html b/testing/web-platform/tests/html/rendering/the-css-user-agent-style-sheet-and-presentational-hints/body-bgcolor-attribute-change.html
new file mode 100644
index 0000000000..d0b2396a40
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/the-css-user-agent-style-sheet-and-presentational-hints/body-bgcolor-attribute-change.html
@@ -0,0 +1,10 @@
+<!doctype html>
+<link rel="help" href="https://html.spec.whatwg.org/multipage/obsolete.html#attr-body-bgcolor">
+<link rel="match" href="body-bgcolor-attribute-change-ref.html">
+<body bgcolor="yellow">
+ Passes if the background is green.
+</body>
+<script>
+ document.body.offsetTop;
+ document.body.setAttribute("bgcolor", "green");
+</script>
diff --git a/testing/web-platform/tests/html/rendering/the-css-user-agent-style-sheet-and-presentational-hints/mouse-cursor-imagemap.html b/testing/web-platform/tests/html/rendering/the-css-user-agent-style-sheet-and-presentational-hints/mouse-cursor-imagemap.html
new file mode 100644
index 0000000000..78f69a2895
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/the-css-user-agent-style-sheet-and-presentational-hints/mouse-cursor-imagemap.html
@@ -0,0 +1,19 @@
+<!doctype html>
+<img usemap="#map" src="data:image/gif;base64,R0lGODlhAQABAIAAAOTm7AAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==" width="1000" height="1000" style="border: 1px solid black;">
+<map name="map">
+ <area id="clickable-area" shape="rect" coords="0,0,500,500" href="#" role="img">
+ <area id="nonclickable-area" shape="rect" coords="500,500,1000,1000" role="img"><!-- No href attribute.-->
+</map>
+
+<p>An unclickable (non-link) area should not show the link cursor when hovered.</p>
+
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+test(function() {
+ let clickable = window.getComputedStyle(document.getElementById('clickable-area'));
+ let nonclickable = window.getComputedStyle(document.getElementById('nonclickable-area'));
+ assert_equals(clickable.getPropertyValue('cursor'), 'pointer');
+ assert_not_equals(nonclickable.getPropertyValue('cursor'), 'pointer');
+}, 'Only clickable areas should show the link cursor.');
+</script> \ No newline at end of file
diff --git a/testing/web-platform/tests/html/rendering/the-css-user-agent-style-sheet-and-presentational-hints/no-help-cursor-on-links-wrapped-in-svg.historical.html b/testing/web-platform/tests/html/rendering/the-css-user-agent-style-sheet-and-presentational-hints/no-help-cursor-on-links-wrapped-in-svg.historical.html
new file mode 100644
index 0000000000..da6ffe15bb
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/the-css-user-agent-style-sheet-and-presentational-hints/no-help-cursor-on-links-wrapped-in-svg.historical.html
@@ -0,0 +1,52 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>link with rel="help" cursor tests</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<link rel="help" href="https://html.spec.whatwg.org/#phrasing-content-3">
+<link rel="help" href="https://github.com/w3c/svgwg/issues/468">
+
+<div id="log"></div>
+
+<svg>
+<a href="/common/blank.html?unvisited" rel="help" id="unvisited">unvisited</a>
+<a href="/common/blank.html?willbevisited" rel="help" id="willbevisited">will be visited</a>
+</svg>
+
+<script>
+"use strict";
+
+
+test(() => {
+ const el = document.querySelector("#unvisited");
+ const style = window.getComputedStyle(el);
+
+ assert_equals(style.cursor, "pointer");
+},"Unvisited help links must have pointer cursor, not help cursor");
+
+
+// This test is kind of dubious. Browsers don't allow you to distinguish visited and unvisited links
+// from script, for privacy reasons. So we can't really be sure that loading the iframe would make
+// the link count as visited. Manually running this test turns the link purple in some browsers,
+// but leaves it blue in others. Even then it's not clear whether it turned purple before or after
+// the onload; this test assumes that once the iframe onload fires, it counts as visited, which
+// may not be justified even in the purple-turning browsers.
+//
+// Still, the test doesn't really hurt. At worst it's redundant with the above.
+//
+// If someone comes up with a better way of testing this (i.e. something that truly guarantees that
+// the link will count as "visited" for UA stylesheet purposes), then please submit a PR.
+async_test(t => {
+ const el = document.querySelector("#willbevisited");
+
+ const iframe = document.createElement("iframe");
+ iframe.src = el.href;
+ iframe.onload = t.step_func_done(() => {
+ const style = window.getComputedStyle(el);
+ assert_equals(style.cursor, "pointer");
+ });
+
+ document.body.appendChild(iframe);
+}, "Visited help links must have pointer cursor, not help cursor");
+</script>
diff --git a/testing/web-platform/tests/html/rendering/the-css-user-agent-style-sheet-and-presentational-hints/no-help-cursor-on-links.historical.html b/testing/web-platform/tests/html/rendering/the-css-user-agent-style-sheet-and-presentational-hints/no-help-cursor-on-links.historical.html
new file mode 100644
index 0000000000..82aa08d215
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/the-css-user-agent-style-sheet-and-presentational-hints/no-help-cursor-on-links.historical.html
@@ -0,0 +1,50 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>link with rel="help" cursor tests</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<link rel="help" href="https://html.spec.whatwg.org/#phrasing-content-3">
+<link rel="help" href="https://github.com/whatwg/html/pull/3902">
+
+<div id="log"></div>
+
+<a href="/common/blank.html?unvisited" rel="help" id="unvisited">unvisited</a>
+<a href="/common/blank.html?willbevisited" rel="help" id="willbevisited">will be visited</a>
+
+<script>
+"use strict";
+
+
+test(() => {
+ const el = document.querySelector("#unvisited");
+ const style = window.getComputedStyle(el);
+
+ assert_equals(style.cursor, "pointer");
+},"Unvisited help links must have pointer cursor, not help cursor");
+
+
+// This test is kind of dubious. Browsers don't allow you to distinguish visited and unvisited links
+// from script, for privacy reasons. So we can't really be sure that loading the iframe would make
+// the link count as visited. Manually running this test turns the link purple in some browsers,
+// but leaves it blue in others. Even then it's not clear whether it turned purple before or after
+// the onload; this test assumes that once the iframe onload fires, it counts as visited, which
+// may not be justified even in the purple-turning browsers.
+//
+// Still, the test doesn't really hurt. At worst it's redundant with the above.
+//
+// If someone comes up with a better way of testing this (i.e. something that truly guarantees that
+// the link will count as "visited" for UA stylesheet purposes), then please submit a PR.
+async_test(t => {
+ const el = document.querySelector("#willbevisited");
+
+ const iframe = document.createElement("iframe");
+ iframe.src = el.href;
+ iframe.onload = t.step_func_done(() => {
+ const style = window.getComputedStyle(el);
+ assert_equals(style.cursor, "pointer");
+ });
+
+ document.body.appendChild(iframe);
+}, "Visited help links must have pointer cursor, not help cursor");
+</script>
diff --git a/testing/web-platform/tests/html/rendering/the-details-element/auto-expand-details-text-fragment.html b/testing/web-platform/tests/html/rendering/the-details-element/auto-expand-details-text-fragment.html
new file mode 100644
index 0000000000..321d82c02d
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/the-details-element/auto-expand-details-text-fragment.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>beforematch fired on ScrollToTextFragment</title>
+<link rel="author" title="Joey Arhar" href="mailto:jarhar@chromium.org">
+<link rel="help" href="https://github.com/WICG/display-locking">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/testdriver.js"></script>
+<script src="/resources/testdriver-vendor.js"></script>
+
+<script src="/common/utils.js"></script>
+<script src="/scroll-to-text-fragment/stash.js"></script>
+
+<script>
+promise_test(t => new Promise((resolve, reject) => {
+ const key = token();
+ test_driver.bless('Open a scroll to text fragment URL', () => {
+ window.open(
+ `resources/auto-expand-details-text-fragment.html?key=${key}#:~:text=foo`,
+ '_blank',
+ 'noopener');
+ });
+ fetchResults(key, resolve, reject);
+}).then(results => {
+ assert_true(results.detailsHasOpenAttribute,
+ 'The matching closed details element should be open.');
+ assert_true(results.pageYOffsetAfterRaf > 0,
+ 'The page should be scrolled down to the match.');
+}), 'Verifies that the beforematch event is fired on the matching element of a ScrollToTextFragment navigation.');
+</script>
diff --git a/testing/web-platform/tests/html/rendering/the-details-element/details-after.html b/testing/web-platform/tests/html/rendering/the-details-element/details-after.html
new file mode 100644
index 0000000000..b4bf050466
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/the-details-element/details-after.html
@@ -0,0 +1,12 @@
+<!doctype html>
+<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
+<link rel="help" title="https://github.com/whatwg/html/pull/3686">
+<link rel="help" title="https://html.spec.whatwg.org/multipage/#the-details-element">
+<link rel="mismatch" href="single-summary.html">
+<title>CSS Test: details ::after pseudo-element</title>
+<style>
+ details::after { content: "::after" }
+</style>
+<details>
+ <summary>This is the main summary</summary>
+</details>
diff --git a/testing/web-platform/tests/html/rendering/the-details-element/details-autofocus-crash.html b/testing/web-platform/tests/html/rendering/the-details-element/details-autofocus-crash.html
new file mode 100644
index 0000000000..70a220feac
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/the-details-element/details-autofocus-crash.html
@@ -0,0 +1,25 @@
+<!doctype html>
+<meta charset="utf-8">
+<link rel="author" href="mailto:vmpstr@chromium.org">
+<link rel="help" href="https://crbug.com/1500582">
+<meta name="assert" content="The renderer should not crash.">
+<html>
+<head>
+<style>
+:not(g) { justify-content: right; line-clamp: none; glyph-orientation-vertical: 0deg; flood-color: rgb(22,11,39); mso-style-parent: style61; column-count: auto; nav-left: htmlvar00001 root; grid-row-end: 35 last; white-space-trim: discard-before discard-after discard-inner; row-gap: normal; cellspacing: 33; line-grid: match-parent; caret-shape: auto; outline: solid red 0px; -webkit-columns: 21; font-family: Courier; mso-displayed-thousand-separator: '\,'; animation-timeline: scroll( x ); shape-image-threshold: 0; stroke-origin: fill-box }
+
+.class1 { background-position-x: x-end 43; ruby-overhang: auto; -webkit-writing-mode: vertical-rl; flex-direction: initial; fill-size: 0px 92; voice-balance: center; -webkit-direction: rtl; inset-block-end: auto; -webkit-align-items: flex-start; text-decoration-style: dashed; order: inherit; border-top-style: dotted; border-bottom-style: dashed; box-shadow: <hwb()> 4 0 2px 0px; view-timeline-axis: block, block; border-inline-start-style: dotted; line-height-step: 1px; content-visibility: hidden; -webkit-flex-flow: ""; text-group-align: right }
+
+
+.class1, #htmlvar00003 { max-zoom: auto; cy: 39; margin-block-end: 96%; max-width: 1vmax; overscroll-behavior-y: auto; -webkit-mask-position: 24px 1px; overflow-y: scroll; -webkit-filter: drop-shadow(1px 1px 1px green); text-emphasis-color: rgb(156,115,92); box-reflect: right; mask-mode: alpha, luminance; voice-balance: left; wrap-flow: both; font-size: math; background-repeat: space space; -webkit-margin-top-collapse: collapse; border-block-style: groove solid; scrollbar-width: auto; padding: 0px 0px 0px 1px; -webkit-column-break-before: always }
+</style>
+<script>
+
+</script>
+</head>
+<body>
+
+<details id="htmlvar00003" class="class1" class="class7" open="true" class="class1" illuminance="0.3882950034014543" autofocus="autofocus" basefrequency="0.0833728589179481" optimum="0.10248315813775544" rel="noreferrer">
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/rendering/the-details-element/details-before.html b/testing/web-platform/tests/html/rendering/the-details-element/details-before.html
new file mode 100644
index 0000000000..3dd95e311a
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/the-details-element/details-before.html
@@ -0,0 +1,12 @@
+<!doctype html>
+<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
+<link rel="help" title="https://github.com/whatwg/html/pull/3686">
+<link rel="help" title="https://html.spec.whatwg.org/multipage/#the-details-element">
+<link rel="mismatch" href="single-summary.html">
+<title>CSS Test: details ::before pseudo-element</title>
+<style>
+ details::before { content: "::before" }
+</style>
+<details>
+ <summary>This is the main summary</summary>
+</details>
diff --git a/testing/web-platform/tests/html/rendering/the-details-element/details-blockification.html b/testing/web-platform/tests/html/rendering/the-details-element/details-blockification.html
new file mode 100644
index 0000000000..960074854d
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/the-details-element/details-blockification.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Test: details children blockification</title>
+<link rel="author" href="mailto:masonf@chromium.org">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/rendering.html#the-details-and-summary-elements">
+<meta name="assert" content="Ensure blockification of <details> children">
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+
+<div id="example1">
+ <details style="display: grid" open>
+ <summary style="display: inline">foo</summary>
+ <div style="display: inline">bar</span>
+ </details>
+</div>
+
+<div id="example2" style="display: grid">
+ <details style="display: contents" open>
+ <summary style="display: inline">foo</summary>
+ <div style="display: inline">bar</span>
+ </details>
+</div>
+
+<script>
+ function checkDetails(details) {
+ assert_equals(getComputedStyle(details.querySelector('summary')).display, "block");
+ assert_equals(getComputedStyle(details.querySelector('div')).display, "block");
+ }
+ test(() => {
+ checkDetails(document.querySelector('#example1'));
+ checkDetails(document.querySelector('#example2'));
+ assert_equals(getComputedStyle(document.querySelector('#example2>details')).display, "contents");
+ }, "Summary and content should have display:block computed value");
+
+</script>
diff --git a/testing/web-platform/tests/html/rendering/the-details-element/details-display-property-is-ignored-ref.html b/testing/web-platform/tests/html/rendering/the-details-element/details-display-property-is-ignored-ref.html
new file mode 100644
index 0000000000..6ebed6075d
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/the-details-element/details-display-property-is-ignored-ref.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<link rel="author" title="David Grogan" href="dgrogan@chromium.org">
+From <a href="https://html.spec.whatwg.org/multipage/rendering.html#the-details-and-summary-elements">html.spec.whatwg.org</a>:
+
+<blockquote>
+The details element is expected to render as a block box. The element's shadow
+tree is expected to take the element's first summary element child, if any, and
+place it in a first block box container, and then take the element's remaining
+descendants, if any, and place them in a second block box container.
+</blockquote>
+
+&lt;details display:flex> should be ignored. Otherwise details would render as
+something other than a block box.
+<hr>
+
+<details open>
+ <summary>This is the summary.</summary>
+ <div>thing 1</div>
+ thing 2
+</details>
diff --git a/testing/web-platform/tests/html/rendering/the-details-element/details-display-property-is-ignored.html b/testing/web-platform/tests/html/rendering/the-details-element/details-display-property-is-ignored.html
new file mode 100644
index 0000000000..445b4e483d
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/the-details-element/details-display-property-is-ignored.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<link rel="author" title="David Grogan" href="dgrogan@chromium.org">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/rendering.html#the-details-and-summary-elements">
+<link rel="match" href="details-display-property-is-ignored-ref.html">
+<link rel="bookmark" href="https://bugs.chromium.org/p/chromium/issues/detail?id=635282" />
+<meta name="assert" content="The display property is ignored on details elements and is instead always rendered as a block box." />
+
+From <a href="https://html.spec.whatwg.org/multipage/rendering.html#the-details-and-summary-elements">html.spec.whatwg.org</a>:
+
+<blockquote>
+The details element is expected to render as a block box. The element's shadow
+tree is expected to take the element's first summary element child, if any, and
+place it in a first block box container, and then take the element's remaining
+descendants, if any, and place them in a second block box container.
+</blockquote>
+
+&lt;details display:flex> should be ignored. Otherwise details would render as
+something other than a block box.
+<hr>
+
+<details open style="display:flex;">
+ <summary>This is the summary.</summary>
+ <div>thing 1</div>
+ thing 2
+</details>
diff --git a/testing/web-platform/tests/html/rendering/the-details-element/details-display-type-001-ref.html b/testing/web-platform/tests/html/rendering/the-details-element/details-display-type-001-ref.html
new file mode 100644
index 0000000000..925ee19f77
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/the-details-element/details-display-type-001-ref.html
@@ -0,0 +1,46 @@
+<!DOCTYPE HTML>
+<title>Details and summary and display property (subgrid)</title>
+<link rel="match" href="details-display-type-001-ref2.html">
+<style>
+
+.container {
+ display: grid;
+ grid: 30px 75px 45px / 80px 125px 90px;
+}
+
+.before {
+ background: aqua;
+ grid-area: 1 / 3;
+}
+
+.after {
+ background: yellow;
+ grid-area: 3 / 1;
+}
+
+.details {
+ display: grid;
+ grid-template: subgrid / subgrid;
+ grid-area: 2 / 2 / 4 / 4;
+}
+
+.summary {
+ background: fuchsia;
+ grid-area: 1 / 1;
+}
+
+.contents {
+ background: silver;
+ grid-area: 2 / 2;
+}
+
+</style>
+
+<div class="container">
+ <div class="before">before</div>
+ <div class="details">
+ <div class="summary">summary</div>
+ <div class="contents">contents</div>
+ </div>
+ <div class="after">after</div>
+</div>
diff --git a/testing/web-platform/tests/html/rendering/the-details-element/details-display-type-001-ref2.html b/testing/web-platform/tests/html/rendering/the-details-element/details-display-type-001-ref2.html
new file mode 100644
index 0000000000..4349df38d6
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/the-details-element/details-display-type-001-ref2.html
@@ -0,0 +1,37 @@
+<!DOCTYPE HTML>
+<title>Details and summary and display property (subgrid)</title>
+<style>
+
+.container {
+ display: grid;
+ grid: 30px 75px 45px / 80px 125px 90px;
+}
+
+.before {
+ background: aqua;
+ grid-area: 1 / 3;
+}
+
+.after {
+ background: yellow;
+ grid-area: 3 / 1;
+}
+
+.summary {
+ background: fuchsia;
+ grid-area: 2 / 2;
+}
+
+.contents {
+ background: silver;
+ grid-area: 3 / 3;
+}
+
+</style>
+
+<div class="container">
+ <div class="before">before</div>
+ <div class="summary">summary</div>
+ <div class="contents">contents</div>
+ <div class="after">after</div>
+</div>
diff --git a/testing/web-platform/tests/html/rendering/the-details-element/details-display-type-001.tentative.html b/testing/web-platform/tests/html/rendering/the-details-element/details-display-type-001.tentative.html
new file mode 100644
index 0000000000..8164135518
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/the-details-element/details-display-type-001.tentative.html
@@ -0,0 +1,51 @@
+<!DOCTYPE HTML>
+<title>Details and summary and display property (subgrid)</title>
+<link rel="match" href="details-display-type-001-ref.html">
+<link rel="help" href="https://github.com/dbaron/details-styling">
+<link rel="help" href="https://crbug.com/1469418">
+<style>
+
+.container {
+ display: grid;
+ grid: 30px 75px 45px / 80px 125px 90px;
+}
+
+.container::before {
+ display: block;
+ content: "before";
+ background: aqua;
+ grid-area: 1 / 3;
+}
+
+.container::after {
+ display: block;
+ content: "after";
+ background: yellow;
+ grid-area: 3 / 1;
+}
+
+details {
+ display: grid;
+ grid-template: subgrid / subgrid;
+ grid-area: 2 / 2 / 4 / 4;
+}
+
+summary {
+ display: block;
+ background: fuchsia;
+ grid-area: 1 / 1;
+}
+
+.contents {
+ background: silver;
+ grid-area: 2 / 2;
+}
+
+</style>
+
+<div class="container">
+ <details open>
+ <summary>summary</summary>
+ <div class="contents">contents</div>
+ </details>
+</div>
diff --git a/testing/web-platform/tests/html/rendering/the-details-element/details-display-type-002-ref.html b/testing/web-platform/tests/html/rendering/the-details-element/details-display-type-002-ref.html
new file mode 100644
index 0000000000..297634b521
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/the-details-element/details-display-type-002-ref.html
@@ -0,0 +1,10 @@
+<!doctype html>
+<style>
+ div {
+ margin-top: 3em;
+ }
+</style>
+<details open>
+ <summary>The summary.</summary>
+ <div>Some details.</div>
+</details>
diff --git a/testing/web-platform/tests/html/rendering/the-details-element/details-display-type-002.tentative.html b/testing/web-platform/tests/html/rendering/the-details-element/details-display-type-002.tentative.html
new file mode 100644
index 0000000000..716221f7c5
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/the-details-element/details-display-type-002.tentative.html
@@ -0,0 +1,17 @@
+<!DOCTYPE HTML>
+<meta charset="utf-8">
+<title>Details display property (flex)</title>
+<link rel="match" href="details-display-type-002-ref.html">
+<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1856374">
+<link rel="help" href="https://github.com/dbaron/details-styling">
+<style>
+ details {
+ display: flex;
+ flex-direction: column;
+ gap: 3em;
+ }
+</style>
+<details open>
+ <summary>The summary.</summary>
+ Some details.
+</details>
diff --git a/testing/web-platform/tests/html/rendering/the-details-element/details-page-break-after-1-print.html b/testing/web-platform/tests/html/rendering/the-details-element/details-page-break-after-1-print.html
new file mode 100644
index 0000000000..cb7fc466d0
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/the-details-element/details-page-break-after-1-print.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<!-- Any copyright is dedicated to the Public Domain.
+ - http://creativecommons.org/publicdomain/zero/1.0/ -->
+
+<html>
+ <link rel="match" href="details-two-pages-print-ref.html">
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/rendering.html#the-details-and-summary-elements">
+ <style>
+ summary {
+ /* Hide the triangle for comparing with div in reftest. */
+ list-style-type: none;
+ }
+ </style>
+ <body>
+ <details open>
+ <summary style="page-break-after: always;">Summary</summary>
+ <p>This is the details.</p>
+ </details>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/rendering/the-details-element/details-page-break-after-2-print.html b/testing/web-platform/tests/html/rendering/the-details-element/details-page-break-after-2-print.html
new file mode 100644
index 0000000000..2f3d12bbe3
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/the-details-element/details-page-break-after-2-print.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<!-- Any copyright is dedicated to the Public Domain.
+ - http://creativecommons.org/publicdomain/zero/1.0/ -->
+
+<html>
+ <link rel="match" href="details-two-pages-print-ref.html">
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/rendering.html#the-details-and-summary-elements">
+ <style>
+ summary {
+ /* Hide the triangle for comparing with div in reftest. */
+ list-style-type: none;
+ }
+ </style>
+ <body>
+ <details open>
+ <summary>Summary<div style="page-break-before: always;"></div></summary>
+ <p>This is the details.</p>
+ </details>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/rendering/the-details-element/details-page-break-before-1-print.html b/testing/web-platform/tests/html/rendering/the-details-element/details-page-break-before-1-print.html
new file mode 100644
index 0000000000..5abf4c39ae
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/the-details-element/details-page-break-before-1-print.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<!-- Any copyright is dedicated to the Public Domain.
+ - http://creativecommons.org/publicdomain/zero/1.0/ -->
+
+<html>
+ <link rel="match" href="details-two-pages-print-ref.html">
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/rendering.html#the-details-and-summary-elements">
+ <style>
+ summary {
+ /* Hide the triangle for comparing with div in reftest. */
+ list-style-type: none;
+ }
+ </style>
+ <body>
+ <details open>
+ <summary>Summary</summary>
+ <p style="page-break-before: always;">This is the details.</p>
+ </details>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/rendering/the-details-element/details-page-break-before-2-print.html b/testing/web-platform/tests/html/rendering/the-details-element/details-page-break-before-2-print.html
new file mode 100644
index 0000000000..2f3d12bbe3
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/the-details-element/details-page-break-before-2-print.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<!-- Any copyright is dedicated to the Public Domain.
+ - http://creativecommons.org/publicdomain/zero/1.0/ -->
+
+<html>
+ <link rel="match" href="details-two-pages-print-ref.html">
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/rendering.html#the-details-and-summary-elements">
+ <style>
+ summary {
+ /* Hide the triangle for comparing with div in reftest. */
+ list-style-type: none;
+ }
+ </style>
+ <body>
+ <details open>
+ <summary>Summary<div style="page-break-before: always;"></div></summary>
+ <p>This is the details.</p>
+ </details>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/rendering/the-details-element/details-pseudo-elements-001-ref.html b/testing/web-platform/tests/html/rendering/the-details-element/details-pseudo-elements-001-ref.html
new file mode 100644
index 0000000000..e00e6c52ff
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/the-details-element/details-pseudo-elements-001-ref.html
@@ -0,0 +1,13 @@
+<!DOCTYPE HTML>
+<title>Details pseudo-elements</title>
+<!-- This test is (at time of writing) _EXTREMELY_ tentative. -->
+<style>
+
+div { background: aqua }
+
+</style>
+
+<details open>
+ <summary>The summary</summary>
+ <div>The details!</div>
+</details>
diff --git a/testing/web-platform/tests/html/rendering/the-details-element/details-pseudo-elements-001.tentative.html b/testing/web-platform/tests/html/rendering/the-details-element/details-pseudo-elements-001.tentative.html
new file mode 100644
index 0000000000..1a9f7d6a02
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/the-details-element/details-pseudo-elements-001.tentative.html
@@ -0,0 +1,19 @@
+<!DOCTYPE HTML>
+<title>Details pseudo-elements</title>
+<!-- This test is (at time of writing) _EXTREMELY_ tentative. -->
+<link rel="match" href="details-pseudo-elements-001-ref.html">
+<link rel="help" href="https://github.com/dbaron/details-styling">
+<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1469418">
+<style>
+
+details::details-content {
+ background: aqua;
+ display: block; /* override display: contents for slot */
+}
+
+</style>
+
+<details open>
+ <summary>The summary</summary>
+ <div>The details!</div>
+</details>
diff --git a/testing/web-platform/tests/html/rendering/the-details-element/details-pseudo-elements-002-ref.html b/testing/web-platform/tests/html/rendering/the-details-element/details-pseudo-elements-002-ref.html
new file mode 100644
index 0000000000..baf242291b
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/the-details-element/details-pseudo-elements-002-ref.html
@@ -0,0 +1,14 @@
+<!DOCTYPE HTML>
+<title>Details pseudo-elements</title>
+<!-- This test is (at time of writing) _EXTREMELY_ tentative. -->
+<style>
+
+summary { list-style-type: disclosure-closed; }
+div { background: aqua }
+
+</style>
+
+<details open>
+ <summary>The summary</summary>
+ <div>The details!</div>
+</details>
diff --git a/testing/web-platform/tests/html/rendering/the-details-element/details-pseudo-elements-002.tentative.html b/testing/web-platform/tests/html/rendering/the-details-element/details-pseudo-elements-002.tentative.html
new file mode 100644
index 0000000000..e149395665
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/the-details-element/details-pseudo-elements-002.tentative.html
@@ -0,0 +1,21 @@
+<!DOCTYPE HTML>
+<title>Details pseudo-elements</title>
+<!-- This test is (at time of writing) _EXTREMELY_ tentative. -->
+<link rel="match" href="details-pseudo-elements-002-ref.html">
+<link rel="help" href="https://github.com/dbaron/details-styling">
+<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1469418">
+<meta name="assert" content="Checks that the content-visibility property on the pseudo-element overrides the style attribute inside the shadow dom.">
+<style>
+
+details::details-content {
+ background: aqua;
+ display: block; /* override display: contents for slot */
+ content-visibility: visible;
+}
+
+</style>
+
+<details>
+ <summary>The summary</summary>
+ <div>The details!</div>
+</details>
diff --git a/testing/web-platform/tests/html/rendering/the-details-element/details-revert-ref.html b/testing/web-platform/tests/html/rendering/the-details-element/details-revert-ref.html
new file mode 100644
index 0000000000..dc46b15901
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/the-details-element/details-revert-ref.html
@@ -0,0 +1,19 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>CSS Test Reference</title>
+<style>
+ summary {
+ display: list-item;
+ counter-increment: list-item 0;
+ list-style: disclosure-closed inside;
+ }
+ details[open] > summary {
+ list-style-type: disclosure-open;
+ }
+</style>
+<details>
+ <summary>Example</summary>
+</details>
+<details open>
+ <summary>Example</summary>
+</details>
diff --git a/testing/web-platform/tests/html/rendering/the-details-element/details-revert.html b/testing/web-platform/tests/html/rendering/the-details-element/details-revert.html
new file mode 100644
index 0000000000..760cc8281e
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/the-details-element/details-revert.html
@@ -0,0 +1,18 @@
+<!doctype html>
+<meta charset="utf-8">
+<link rel="help" href="https://html.spec.whatwg.org/#the-details-and-summary-elements">
+<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1804925">
+<link rel="match" href="details-revert-ref.html">
+<style>
+ summary {
+ display: revert;
+ counter-increment: revert;
+ list-style: revert;
+ }
+</style>
+<details>
+ <summary>Example</summary>
+</details>
+<details open>
+ <summary>Example</summary>
+</details>
diff --git a/testing/web-platform/tests/html/rendering/the-details-element/details-two-pages-print-ref.html b/testing/web-platform/tests/html/rendering/the-details-element/details-two-pages-print-ref.html
new file mode 100644
index 0000000000..309a138696
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/the-details-element/details-two-pages-print-ref.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<!-- Any copyright is dedicated to the Public Domain.
+ - http://creativecommons.org/publicdomain/zero/1.0/ -->
+
+<html>
+ <body>
+ <div>
+ <div style="page-break-after: always;">Summary</div>
+ <p>This is the details.</p>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/rendering/the-details-element/empty-crash.html b/testing/web-platform/tests/html/rendering/the-details-element/empty-crash.html
new file mode 100644
index 0000000000..d409eff4a8
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/the-details-element/empty-crash.html
@@ -0,0 +1,7 @@
+<!DOCTYPE html>
+<link rel="help" href="https://crbug.com/1068227">
+<style>
+body { display: flex; }
+details, summary { display: inherit; }
+</style>
+<details><summary>
diff --git a/testing/web-platform/tests/html/rendering/the-details-element/resources/auto-expand-details-text-fragment.html b/testing/web-platform/tests/html/rendering/the-details-element/resources/auto-expand-details-text-fragment.html
new file mode 100644
index 0000000000..b95459fe5c
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/the-details-element/resources/auto-expand-details-text-fragment.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<script src="/scroll-to-text-fragment/stash.js"></script>
+
+<!-- This test is navigated to with the fragment #:~:text=foo -->
+
+<body>
+ <div style="height: 4000px;">spacer</div>
+ <details>
+ <div>foo</div>
+ </details>
+ <script>
+ requestAnimationFrame(() => {
+ requestAnimationFrame(() => {
+ const results = {};
+ // This should be true. The details element should be opened by
+ // ScrollToTextFragment because it has matching text.
+ results.detailsHasOpenAttribute = document.querySelector('details').hasAttribute('open');
+ // This should be greater than zero. The page should be scrolled down
+ // to the matching target.
+ results.pageYOffsetAfterRaf = window.pageYOffset;
+
+ params = new URLSearchParams(window.location.search);
+ stashResultsThenClose(params.get('key'), results);
+ });
+ });
+ </script>
+</body>
diff --git a/testing/web-platform/tests/html/rendering/the-details-element/single-summary.html b/testing/web-platform/tests/html/rendering/the-details-element/single-summary.html
new file mode 100644
index 0000000000..1f09e7e75f
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/the-details-element/single-summary.html
@@ -0,0 +1,6 @@
+<!doctype html>
+<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
+<title>CSS Test Reference</title>
+<details>
+ <summary>This is the main summary</summary>
+</details>
diff --git a/testing/web-platform/tests/html/rendering/the-details-element/summary-display-flex-ref.html b/testing/web-platform/tests/html/rendering/the-details-element/summary-display-flex-ref.html
new file mode 100644
index 0000000000..083dba8795
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/the-details-element/summary-display-flex-ref.html
@@ -0,0 +1,105 @@
+<!DOCTYPE html>
+<link rel="author" title="Xing Xu" href="mailto:xing.xu@intel.com">
+<style>
+.flex-container {
+ background: #333;
+ border: 0px;
+ display: flex;
+ margin: 0px;
+ padding: 0px;
+}
+
+.flex-container.flex-direction-row {
+ flex-direction : row;
+}
+
+.flex-container.flex-direction-row-reverse {
+ flex-direction : row-reverse;
+}
+
+.flex-container.flex-direction-column {
+ flex-direction : column;
+}
+
+.flex-container.flex-direction-column-reverse {
+ flex-direction : column-reverse;
+}
+
+.flex-container.flex-direction-column-reverse {
+ flex-direction : column-reverse;
+}
+
+.flex-container.justify-content-center {
+ justify-content: center;
+}
+
+.flex-container.justify-content-space-around {
+ justify-content: space-around;
+}
+
+.flex-container.justify-content-space-between {
+ justify-content: space-between;
+}
+
+.flex-item {
+ width:50px;
+ height:50px;
+ margin:20px;
+ background: #eee;
+ line-height: 50px;
+ text-align: center;
+}
+</style>
+
+<summary>
+ <div>these fieldsshouldn't bestacked vertically</div>
+</summary>
+
+<h1>flex-direction: row</h1>
+<div class="flex-container flex-direction-row">
+ <div class="flex-item">1</div>
+ <div class="flex-item">2</div>
+ <div class="flex-item">3</div>
+</div>
+
+<h1>flex-direction: row-reverse</h1>
+<div class="flex-container flex-direction-row-reverse">
+ <div class="flex-item">1</div>
+ <div class="flex-item">2</div>
+ <div class="flex-item">3</div>
+</div>
+
+<h1>flex-direction: column</h1>
+<div class="flex-container flex-direction-column">
+ <div class="flex-item">1</div>
+ <div class="flex-item">2</div>
+ <div class="flex-item">3</div>
+</div>
+
+<h1>flex-direction: column-reverse</h1>
+<div class="flex-container flex-direction-column-reverse">
+ <div class="flex-item">1</div>
+ <div class="flex-item">2</div>
+ <div class="flex-item">3</div>
+</div>
+
+<h1>justify-content: center</h1>
+<div class="flex-container justify-content-center">
+ <div class="flex-item">1</div>
+ <div class="flex-item">2</div>
+ <div class="flex-item">3</div>
+</div>
+
+<h1>justify-content: space-around</h1>
+<div class="flex-container justify-content-space-around">
+ <div class="flex-item">1</div>
+ <div class="flex-item">2</div>
+ <div class="flex-item">3</div>
+</div>
+
+<h1>justify-content: space-between</h1>
+<div class="flex-container justify-content-space-between">
+ <div class="flex-item">1</div>
+ <div class="flex-item">2</div>
+ <div class="flex-item">3</div>
+</div>
diff --git a/testing/web-platform/tests/html/rendering/the-details-element/summary-display-flex.html b/testing/web-platform/tests/html/rendering/the-details-element/summary-display-flex.html
new file mode 100644
index 0000000000..c495516cf3
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/the-details-element/summary-display-flex.html
@@ -0,0 +1,112 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Test: summary with 'display: flex'</title>
+<link rel="author" title="Xing Xu" href="mailto:xing.xu@intel.com">
+<link rel="match" href="summary-display-flex-ref.html">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/rendering.html#the-details-and-summary-elements">
+<meta name="assert" content="Checks that styling a <summary> with 'display: flex' makes it a flex container.">
+<style>
+.flex-container {
+ background: #333;
+ border: 0px;
+ display: flex;
+ margin: 0px;
+ padding: 0px;
+}
+
+.flex-container.flex-direction-row {
+ flex-direction : row;
+}
+
+.flex-container.flex-direction-row-reverse {
+ flex-direction : row-reverse;
+}
+
+.flex-container.flex-direction-column {
+ flex-direction : column;
+}
+
+.flex-container.flex-direction-column-reverse {
+ flex-direction : column-reverse;
+}
+
+.flex-container.flex-direction-column-reverse {
+ flex-direction : column-reverse;
+}
+
+.flex-container.justify-content-center {
+ justify-content: center;
+}
+
+.flex-container.justify-content-space-around {
+ justify-content: space-around;
+}
+
+.flex-container.justify-content-space-between {
+ justify-content: space-between;
+}
+
+.flex-item {
+ width:50px;
+ height:50px;
+ margin:20px;
+ background: #eee;
+ line-height: 50px;
+ text-align: center;
+}
+</style>
+
+<summary style="display: flex;">
+ <div>these fields</div>
+ <div>shouldn't be</div>
+ <div>stacked vertically</div>
+</summary>
+
+<h1>flex-direction: row</h1>
+<summary class="flex-container flex-direction-row">
+ <div class="flex-item">1</div>
+ <div class="flex-item">2</div>
+ <div class="flex-item">3</div>
+</summary>
+
+<h1>flex-direction: row-reverse</h1>
+<summary class="flex-container flex-direction-row-reverse">
+ <div class="flex-item">1</div>
+ <div class="flex-item">2</div>
+ <div class="flex-item">3</div>
+</summary>
+
+<h1>flex-direction: column</h1>
+<summary class="flex-container flex-direction-column">
+ <div class="flex-item">1</div>
+ <div class="flex-item">2</div>
+ <div class="flex-item">3</div>
+</summary>
+
+<h1>flex-direction: column-reverse</h1>
+<summary class="flex-container flex-direction-column-reverse">
+ <div class="flex-item">1</div>
+ <div class="flex-item">2</div>
+ <div class="flex-item">3</div>
+</summary>
+
+<h1>justify-content: center</h1>
+<summary class="flex-container justify-content-center">
+ <div class="flex-item">1</div>
+ <div class="flex-item">2</div>
+ <div class="flex-item">3</div>
+</summary>
+
+<h1>justify-content: space-around</h1>
+<summary class="flex-container justify-content-space-around">
+ <div class="flex-item">1</div>
+ <div class="flex-item">2</div>
+ <div class="flex-item">3</div>
+</summary>
+
+<h1>justify-content: space-between</h1>
+<summary class="flex-container justify-content-space-between">
+ <div class="flex-item">1</div>
+ <div class="flex-item">2</div>
+ <div class="flex-item">3</div>
+</summary>
diff --git a/testing/web-platform/tests/html/rendering/the-details-element/summary-display-grid-ref.html b/testing/web-platform/tests/html/rendering/the-details-element/summary-display-grid-ref.html
new file mode 100644
index 0000000000..a7c4c4c014
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/the-details-element/summary-display-grid-ref.html
@@ -0,0 +1,72 @@
+<!DOCTYPE html>
+<link rel="author" title="Xing Xu" href="mailto:xing.xu@intel.com">
+<style>
+.grid-container {
+ display: grid;
+ grid-template-columns: 200px 10px 0.3fr 10px 0.7fr;
+ grid-template-rows: auto 20px auto;
+}
+
+.grid-element {
+ background-color: #444;
+ color: #fff;
+ padding: 20px;
+ font-size: 2em;
+}
+
+.element-a {
+ grid-column-start: 1;
+ grid-column-end: ;
+ grid-row-start: 1;
+ grid-row-end: 2;
+ background: #6F9;
+}
+
+.element-b {
+ grid-column-start: 3;
+ grid-column-end: 4;
+ grid-row-start: 1;
+ grid-row-end: 2;
+ background: #69F;
+}
+
+.element-c {
+ grid-column-start: 5;
+ grid-column-end: 6;
+ grid-row-start: 1;
+ grid-row-end: 2;
+ background: #F69;
+}
+
+.element-d {
+ grid-column-start: 1;
+ grid-column-end: 2;
+ grid-row-start: 3;
+ grid-row-end: 4;
+ background: #9F6;
+}
+
+.element-e {
+ grid-column-start: 3;
+ grid-column-end: 4;
+ grid-row-start: 3;
+ grid-row-end: 4;
+ background: #96F;
+}
+
+.element-f {
+ grid-column-start: 5;
+ grid-column-end: 6;
+ grid-row-start: 3;
+ grid-row-end: 4;
+ background: #F96;
+}
+</style>
+<div class="grid-container">
+ <div class="grid-element element-a">A</div>
+ <div class="grid-element element-b">B</div>
+ <div class="grid-element element-c">C</div>
+ <div class="grid-element element-d">D</div>
+ <div class="grid-element element-e">E</div>
+ <div class="grid-element element-f">F</div>
+</div>
diff --git a/testing/web-platform/tests/html/rendering/the-details-element/summary-display-grid.html b/testing/web-platform/tests/html/rendering/the-details-element/summary-display-grid.html
new file mode 100644
index 0000000000..934b4ff595
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/the-details-element/summary-display-grid.html
@@ -0,0 +1,77 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Test: summary with 'display: grid'</title>
+<link rel="author" title="Xing Xu" href="mailto:xing.xu@intel.com">
+<link rel="match" href="summary-display-grid-ref.html">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/rendering.html#the-details-and-summary-elements">
+<meta name="assert" content="Checks that styling a <summary> with 'display: grid' makes it a grid container.">
+<style>
+.grid-container {
+ display: grid;
+ grid-template-columns: 200px 10px 0.3fr 10px 0.7fr;
+ grid-template-rows: auto 20px auto;
+}
+
+.grid-element {
+ background-color: #444;
+ color: #fff;
+ padding: 20px;
+ font-size: 2em;
+}
+
+.element-a {
+ grid-column-start: 1;
+ grid-column-end: ;
+ grid-row-start: 1;
+ grid-row-end: 2;
+ background: #6F9;
+}
+
+.element-b {
+ grid-column-start: 3;
+ grid-column-end: 4;
+ grid-row-start: 1;
+ grid-row-end: 2;
+ background: #69F;
+}
+
+.element-c {
+ grid-column-start: 5;
+ grid-column-end: 6;
+ grid-row-start: 1;
+ grid-row-end: 2;
+ background: #F69;
+}
+
+.element-d {
+ grid-column-start: 1;
+ grid-column-end: 2;
+ grid-row-start: 3;
+ grid-row-end: 4;
+ background: #9F6;
+}
+
+.element-e {
+ grid-column-start: 3;
+ grid-column-end: 4;
+ grid-row-start: 3;
+ grid-row-end: 4;
+ background: #96F;
+}
+
+.element-f {
+ grid-column-start: 5;
+ grid-column-end: 6;
+ grid-row-start: 3;
+ grid-row-end: 4;
+ background: #F96;
+}
+</style>
+<summary class="grid-container">
+ <div class="grid-element element-a">A</div>
+ <div class="grid-element element-b">B</div>
+ <div class="grid-element element-c">C</div>
+ <div class="grid-element element-d">D</div>
+ <div class="grid-element element-e">E</div>
+ <div class="grid-element element-f">F</div>
+</summary>
diff --git a/testing/web-platform/tests/html/rendering/the-details-element/summary-display-inline-flex-ref.html b/testing/web-platform/tests/html/rendering/the-details-element/summary-display-inline-flex-ref.html
new file mode 100644
index 0000000000..25a9b315f4
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/the-details-element/summary-display-inline-flex-ref.html
@@ -0,0 +1,105 @@
+<!DOCTYPE html>
+<link rel="author" title="Xing Xu" href="mailto:xing.xu@intel.com">
+<style>
+.flex-container {
+ background: #333;
+ border: 0px;
+ display: inline-flex;
+ margin: 0px;
+ padding: 0px;
+}
+
+.flex-container.flex-direction-row {
+ flex-direction : row;
+}
+
+.flex-container.flex-direction-row-reverse {
+ flex-direction : row-reverse;
+}
+
+.flex-container.flex-direction-column {
+ flex-direction : column;
+}
+
+.flex-container.flex-direction-column-reverse {
+ flex-direction : column-reverse;
+}
+
+.flex-container.flex-direction-column-reverse {
+ flex-direction : column-reverse;
+}
+
+.flex-container.justify-content-center {
+ justify-content: center;
+}
+
+.flex-container.justify-content-space-around {
+ justify-content: space-around;
+}
+
+.flex-container.justify-content-space-between {
+ justify-content: space-between;
+}
+
+.flex-item {
+ width:50px;
+ height:50px;
+ margin:20px;
+ background: #eee;
+ line-height: 50px;
+ text-align: center;
+}
+</style>
+
+<summary>
+ <div>these fieldsshouldn't bestacked vertically</div>
+</summary>
+
+<h1>flex-direction: row</h1>
+<div class="flex-container flex-direction-row">
+ <div class="flex-item">1</div>
+ <div class="flex-item">2</div>
+ <div class="flex-item">3</div>
+</div>
+
+<h1>flex-direction: row-reverse</h1>
+<div class="flex-container flex-direction-row-reverse">
+ <div class="flex-item">1</div>
+ <div class="flex-item">2</div>
+ <div class="flex-item">3</div>
+</div>
+
+<h1>flex-direction: column</h1>
+<div class="flex-container flex-direction-column">
+ <div class="flex-item">1</div>
+ <div class="flex-item">2</div>
+ <div class="flex-item">3</div>
+</div>
+
+<h1>flex-direction: column-reverse</h1>
+<div class="flex-container flex-direction-column-reverse">
+ <div class="flex-item">1</div>
+ <div class="flex-item">2</div>
+ <div class="flex-item">3</div>
+</div>
+
+<h1>justify-content: center</h1>
+<div class="flex-container justify-content-center">
+ <div class="flex-item">1</div>
+ <div class="flex-item">2</div>
+ <div class="flex-item">3</div>
+</div>
+
+<h1>justify-content: space-around</h1>
+<div class="flex-container justify-content-space-around">
+ <div class="flex-item">1</div>
+ <div class="flex-item">2</div>
+ <div class="flex-item">3</div>
+</div>
+
+<h1>justify-content: space-between</h1>
+<div class="flex-container justify-content-space-between">
+ <div class="flex-item">1</div>
+ <div class="flex-item">2</div>
+ <div class="flex-item">3</div>
+</div>
diff --git a/testing/web-platform/tests/html/rendering/the-details-element/summary-display-inline-flex.html b/testing/web-platform/tests/html/rendering/the-details-element/summary-display-inline-flex.html
new file mode 100644
index 0000000000..2c935e42b8
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/the-details-element/summary-display-inline-flex.html
@@ -0,0 +1,112 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Test: summary with 'display: inline-flex'</title>
+<link rel="author" title="Xing Xu" href="mailto:xing.xu@intel.com">
+<link rel="match" href="summary-display-inline-flex-ref.html">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/rendering.html#the-details-and-summary-elements">
+<meta name="assert" content="Checks that styling a <summary> with 'display: inline-flex' makes it a flex container.">
+<style>
+.flex-container {
+ background: #333;
+ border: 0px;
+ display: inline-flex;
+ margin: 0px;
+ padding: 0px;
+}
+
+.flex-container.flex-direction-row {
+ flex-direction : row;
+}
+
+.flex-container.flex-direction-row-reverse {
+ flex-direction : row-reverse;
+}
+
+.flex-container.flex-direction-column {
+ flex-direction : column;
+}
+
+.flex-container.flex-direction-column-reverse {
+ flex-direction : column-reverse;
+}
+
+.flex-container.flex-direction-column-reverse {
+ flex-direction : column-reverse;
+}
+
+.flex-container.justify-content-center {
+ justify-content: center;
+}
+
+.flex-container.justify-content-space-around {
+ justify-content: space-around;
+}
+
+.flex-container.justify-content-space-between {
+ justify-content: space-between;
+}
+
+.flex-item {
+ width:50px;
+ height:50px;
+ margin:20px;
+ background: #eee;
+ line-height: 50px;
+ text-align: center;
+}
+</style>
+
+<summary style="display: inline-flex;">
+ <div>these fields</div>
+ <div>shouldn't be</div>
+ <div>stacked vertically</div>
+</summary>
+
+<h1>flex-direction: row</h1>
+<summary class="flex-container flex-direction-row">
+ <div class="flex-item">1</div>
+ <div class="flex-item">2</div>
+ <div class="flex-item">3</div>
+</summary>
+
+<h1>flex-direction: row-reverse</h1>
+<summary class="flex-container flex-direction-row-reverse">
+ <div class="flex-item">1</div>
+ <div class="flex-item">2</div>
+ <div class="flex-item">3</div>
+</summary>
+
+<h1>flex-direction: column</h1>
+<summary class="flex-container flex-direction-column">
+ <div class="flex-item">1</div>
+ <div class="flex-item">2</div>
+ <div class="flex-item">3</div>
+</summary>
+
+<h1>flex-direction: column-reverse</h1>
+<summary class="flex-container flex-direction-column-reverse">
+ <div class="flex-item">1</div>
+ <div class="flex-item">2</div>
+ <div class="flex-item">3</div>
+</summary>
+
+<h1>justify-content: center</h1>
+<summary class="flex-container justify-content-center">
+ <div class="flex-item">1</div>
+ <div class="flex-item">2</div>
+ <div class="flex-item">3</div>
+</summary>
+
+<h1>justify-content: space-around</h1>
+<summary class="flex-container justify-content-space-around">
+ <div class="flex-item">1</div>
+ <div class="flex-item">2</div>
+ <div class="flex-item">3</div>
+</summary>
+
+<h1>justify-content: space-between</h1>
+<summary class="flex-container justify-content-space-between">
+ <div class="flex-item">1</div>
+ <div class="flex-item">2</div>
+ <div class="flex-item">3</div>
+</summary>
diff --git a/testing/web-platform/tests/html/rendering/the-details-element/summary-display-inline-grid-ref.html b/testing/web-platform/tests/html/rendering/the-details-element/summary-display-inline-grid-ref.html
new file mode 100644
index 0000000000..f6a8b04bec
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/the-details-element/summary-display-inline-grid-ref.html
@@ -0,0 +1,72 @@
+<!DOCTYPE html>
+<link rel="author" title="Xing Xu" href="mailto:xing.xu@intel.com">
+<style>
+.grid-container {
+ display: inline-grid;
+ grid-template-columns: 200px 10px 0.3fr 10px 0.7fr;
+ grid-template-rows: auto 20px auto;
+}
+
+.grid-element {
+ background-color: #444;
+ color: #fff;
+ padding: 20px;
+ font-size: 2em;
+}
+
+.element-a {
+ grid-column-start: 1;
+ grid-column-end: ;
+ grid-row-start: 1;
+ grid-row-end: 2;
+ background: #6F9;
+}
+
+.element-b {
+ grid-column-start: 3;
+ grid-column-end: 4;
+ grid-row-start: 1;
+ grid-row-end: 2;
+ background: #69F;
+}
+
+.element-c {
+ grid-column-start: 5;
+ grid-column-end: 6;
+ grid-row-start: 1;
+ grid-row-end: 2;
+ background: #F69;
+}
+
+.element-d {
+ grid-column-start: 1;
+ grid-column-end: 2;
+ grid-row-start: 3;
+ grid-row-end: 4;
+ background: #9F6;
+}
+
+.element-e {
+ grid-column-start: 3;
+ grid-column-end: 4;
+ grid-row-start: 3;
+ grid-row-end: 4;
+ background: #96F;
+}
+
+.element-f {
+ grid-column-start: 5;
+ grid-column-end: 6;
+ grid-row-start: 3;
+ grid-row-end: 4;
+ background: #F96;
+}
+</style>
+<div class="grid-container">
+ <div class="grid-element element-a">A</div>
+ <div class="grid-element element-b">B</div>
+ <div class="grid-element element-c">C</div>
+ <div class="grid-element element-d">D</div>
+ <div class="grid-element element-e">E</div>
+ <div class="grid-element element-f">F</div>
+</div>
diff --git a/testing/web-platform/tests/html/rendering/the-details-element/summary-display-inline-grid.html b/testing/web-platform/tests/html/rendering/the-details-element/summary-display-inline-grid.html
new file mode 100644
index 0000000000..3578f050e2
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/the-details-element/summary-display-inline-grid.html
@@ -0,0 +1,77 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Test: summary with 'display: inline-grid'</title>
+<link rel="author" title="Xing Xu" href="mailto:xing.xu@intel.com">
+<link rel="match" href="summary-display-inline-grid-ref.html">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/rendering.html#the-details-and-summary-elements">
+<meta name="assert" content="Checks that styling a <summary> with 'display: inline-grid' makes it a grid container.">
+<style>
+.grid-container {
+ display: inline-grid;
+ grid-template-columns: 200px 10px 0.3fr 10px 0.7fr;
+ grid-template-rows: auto 20px auto;
+}
+
+.grid-element {
+ background-color: #444;
+ color: #fff;
+ padding: 20px;
+ font-size: 2em;
+}
+
+.element-a {
+ grid-column-start: 1;
+ grid-column-end: ;
+ grid-row-start: 1;
+ grid-row-end: 2;
+ background: #6F9;
+}
+
+.element-b {
+ grid-column-start: 3;
+ grid-column-end: 4;
+ grid-row-start: 1;
+ grid-row-end: 2;
+ background: #69F;
+}
+
+.element-c {
+ grid-column-start: 5;
+ grid-column-end: 6;
+ grid-row-start: 1;
+ grid-row-end: 2;
+ background: #F69;
+}
+
+.element-d {
+ grid-column-start: 1;
+ grid-column-end: 2;
+ grid-row-start: 3;
+ grid-row-end: 4;
+ background: #9F6;
+}
+
+.element-e {
+ grid-column-start: 3;
+ grid-column-end: 4;
+ grid-row-start: 3;
+ grid-row-end: 4;
+ background: #96F;
+}
+
+.element-f {
+ grid-column-start: 5;
+ grid-column-end: 6;
+ grid-row-start: 3;
+ grid-row-end: 4;
+ background: #F96;
+}
+</style>
+<summary class="grid-container">
+ <div class="grid-element element-a">A</div>
+ <div class="grid-element element-b">B</div>
+ <div class="grid-element element-c">C</div>
+ <div class="grid-element element-d">D</div>
+ <div class="grid-element element-e">E</div>
+ <div class="grid-element element-f">F</div>
+</summary>
diff --git a/testing/web-platform/tests/html/rendering/the-details-element/summary-display-list-item-001-ref.html b/testing/web-platform/tests/html/rendering/the-details-element/summary-display-list-item-001-ref.html
new file mode 100644
index 0000000000..31e98d3fdc
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/the-details-element/summary-display-list-item-001-ref.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Reference: summary with 'display: list-item'</title>
+<link rel="author" title="Oriol Brufau" href="mailto:obrufau@igalia.com">
+<style>
+details {
+ margin-left: 50px;
+}
+.inside {
+ list-style-position: inside;
+}
+</style>
+<details>
+ <summary>summary</summary>
+ content
+</details>
+<details>
+ <summary class="inside">summary</summary>
+ content
+</details>
+<details open>
+ <summary>summary</summary>
+ content
+</details>
+<details open>
+ <summary class="inside">summary</summary>
+ content
+</details>
diff --git a/testing/web-platform/tests/html/rendering/the-details-element/summary-display-list-item-001.html b/testing/web-platform/tests/html/rendering/the-details-element/summary-display-list-item-001.html
new file mode 100644
index 0000000000..8b94f10f27
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/the-details-element/summary-display-list-item-001.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Test: summary with 'display: list-item'</title>
+<link rel="author" title="Oriol Brufau" href="mailto:obrufau@igalia.com">
+<link rel="match" href="summary-display-list-item-001-ref.html">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/rendering.html#the-details-and-summary-elements">
+<meta name="assert" content="Checks that styling a <summary> with 'display: list-item' has no effect since it should already be a list item by default.">
+<style>
+summary {
+ display: list-item;
+}
+details {
+ margin-left: 50px;
+}
+.inside {
+ list-style-position: inside;
+}
+</style>
+<details>
+ <summary>summary</summary>
+ content
+</details>
+<details>
+ <summary class="inside">summary</summary>
+ content
+</details>
+<details open>
+ <summary>summary</summary>
+ content
+</details>
+<details open>
+ <summary class="inside">summary</summary>
+ content
+</details>
diff --git a/testing/web-platform/tests/html/rendering/the-details-element/summary-display-list-item-002-ref.html b/testing/web-platform/tests/html/rendering/the-details-element/summary-display-list-item-002-ref.html
new file mode 100644
index 0000000000..317e1cfe7d
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/the-details-element/summary-display-list-item-002-ref.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Test: summary with 'display: list-item' and flex children</title>
+<link rel="author" title="Cameron McCormack" href="mailto:">
+<link rel="author" title="Sergio Villar Senin" href="mailto:svillar@igalia.com">
+<div style="width: 100px;">
+ <div style="display: list-item; list-style-type: none;">
+ <div style="display: flex; justify-content: space-between;">
+ <div>AAA</div>
+ <div>BBB</div>
+ </div>
+ </div>
+</div>
diff --git a/testing/web-platform/tests/html/rendering/the-details-element/summary-display-list-item-002.html b/testing/web-platform/tests/html/rendering/the-details-element/summary-display-list-item-002.html
new file mode 100644
index 0000000000..ee32997009
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/the-details-element/summary-display-list-item-002.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Test: summary with 'display: list-item' and flex children</title>
+<link rel="author" title="Cameron McCormack" href="mailto:heycam@apple.com">
+<link rel="author" title="Sergio Villar Senin" href="mailto:svillar@igalia.com">
+<link rel="match" href="summary-display-list-item-002-ref.html">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/rendering.html#the-details-and-summary-elements">
+<style>
+summary {
+ display: list-item;
+ list-style-type: none;
+}
+/* WebKit does not support list-style-type:none yet */
+summary::-webkit-details-marker { display: none; }
+</style>
+<details style="width: 100px;">
+ <summary>
+ <div style="display: flex; justify-content: space-between;">
+ <div>AAA</div>
+ <div>BBB</div>
+ </div>
+ </summary>
+</details>
diff --git a/testing/web-platform/tests/html/rendering/the-details-element/summary-in-ol-ref.html b/testing/web-platform/tests/html/rendering/the-details-element/summary-in-ol-ref.html
new file mode 100644
index 0000000000..bb6f79b627
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/the-details-element/summary-in-ol-ref.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+
+<ol>
+ <details><summary>summary</summary></details>
+ <li value="1">1</li>
+ <li value="2">2 <details><summary>summary</summary></details></li>
+ <li value="3">3</li>
+ <details><summary>summary</summary></details>
+ <li value="4">4</li>
+</ol>
+
+<ol>
+ <summary>summary</summary>
+ <li value="1">1</li>
+ <li value="2">2 <summary>summary</summary></li>
+ <li value="3">3</li>
+ <summary>summary</summary>
+ <li value="4">4</li>
+</ol>
+
diff --git a/testing/web-platform/tests/html/rendering/the-details-element/summary-in-ol.html b/testing/web-platform/tests/html/rendering/the-details-element/summary-in-ol.html
new file mode 100644
index 0000000000..0f380bf058
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/the-details-element/summary-in-ol.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<title>Check if SUMMARY has 'counter-increment: list-item 0'</title>
+<link rel="match" href="summary-in-ol-ref.html">
+
+<ol>
+ <details><summary>summary</summary></details>
+ <li>1</li>
+ <li>2 <details><summary>summary</summary></details></li>
+ <li>3</li>
+ <details><summary>summary</summary></details>
+ <li>4</li>
+</ol>
+
+<ol>
+ <summary>summary</summary>
+ <li>1</li>
+ <li>2 <summary>summary</summary></li>
+ <li>3</li>
+ <summary>summary</summary>
+ <li>4</li>
+</ol>
+
diff --git a/testing/web-platform/tests/html/rendering/the-details-element/summary-text-decoration-ref.html b/testing/web-platform/tests/html/rendering/the-details-element/summary-text-decoration-ref.html
new file mode 100644
index 0000000000..ffdcfd25fb
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/the-details-element/summary-text-decoration-ref.html
@@ -0,0 +1,11 @@
+<!doctype html>
+<title>Test reference</title>
+<style>
+div {
+ display: list-item;
+ list-style-type: disclosure-closed;
+ list-style-position: inside;
+ text-decoration: underline;
+}
+</style>
+<div>This text should be underlined.</div>
diff --git a/testing/web-platform/tests/html/rendering/the-details-element/summary-text-decoration.html b/testing/web-platform/tests/html/rendering/the-details-element/summary-text-decoration.html
new file mode 100644
index 0000000000..80bbd44c46
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/the-details-element/summary-text-decoration.html
@@ -0,0 +1,11 @@
+<!doctype html>
+<title>Rendering of summary element with text-decoration</title>
+<link rel="match" href="summary-text-decoration-ref.html">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/rendering.html#the-details-and-summary-elements">
+<meta name="assert" content="Checks that text-decoration applies to rendered summary element.">
+<style>
+ summary { text-decoration: underline; }
+</style>
+<details>
+ <summary>This text should be underlined.</summary>
+</details>
diff --git a/testing/web-platform/tests/html/rendering/the-details-element/two-summaries-removal-crash.html b/testing/web-platform/tests/html/rendering/the-details-element/two-summaries-removal-crash.html
new file mode 100644
index 0000000000..164d3f16aa
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/the-details-element/two-summaries-removal-crash.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<link rel="author" href="mailto:masonf@chromium.org">
+<link rel="help" href="https://crbug.com/1216804">
+<meta name="assert" content="The renderer should not crash.">
+
+<details id="details" open>
+ <summary></summary>
+ <summary>
+ <details></details>
+ </summary>
+</details>
+
+<script>
+details.appendChild(document.createElement("frame"));
+details.innerText="";
+</script>
diff --git a/testing/web-platform/tests/html/rendering/unmapped-attributes.html b/testing/web-platform/tests/html/rendering/unmapped-attributes.html
new file mode 100644
index 0000000000..5824f836f0
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/unmapped-attributes.html
@@ -0,0 +1,95 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Test handling of attributes that should not be mapped into style, but
+ incorrectly were in some browsers</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<body>
+<div id="container" style="display: none"></div>
+<iframe></iframe>
+<script>
+ /*
+ * We wand to test both quirks and standards mode. We can use the fact that
+ * our document is in standards mode and the about:blank iframe we have is in
+ * quirks mode.
+ */
+test(() => {
+ assert_equals(document.compatMode, "CSS1Compat")
+}, "We should be in standards mode");
+const container = document.getElementById("container");
+
+const frameDoc = document.querySelector("iframe").contentDocument;
+test(() => {
+ assert_equals(frameDoc.compatMode, "BackCompat")
+}, "Subframe should be in quirks mode");
+const frameContainer = frameDoc.createElement("div");
+frameContainer.style.display = "none";
+frameDoc.body.appendChild(frameContainer);
+
+function newElem(name) {
+ return (parent) =>
+ parent.appendChild(parent.ownerDocument.createElement(name));
+}
+
+ /*
+ * Array of tests. Each test consists of the following information:
+ *
+ * 1) An element creation function, which takes a parent element as an
+ * argument.
+ * 2) The name of the attribute to set
+ * 3) The name of the CSS property to get.
+ */
+const tests = [
+ [ newElem("table"), "hspace", "marginLeft" ],
+ [ newElem("table"), "hspace", "marginRight" ],
+ [ newElem("table"), "vspace", "marginTop" ],
+ [ newElem("table"), "vspace", "marginBottom" ],
+ [ newElem("embed"), "border", "borderTopWidth" ],
+ [ newElem("embed"), "border", "borderRightWidth" ],
+ [ newElem("embed"), "border", "borderBottomWidth" ],
+ [ newElem("embed"), "border", "borderLeftWidth" ],
+ [ newElem("iframe"), "border", "borderTopWidth" ],
+ [ newElem("iframe"), "border", "borderRightWidth" ],
+ [ newElem("iframe"), "border", "borderBottomWidth" ],
+ [ newElem("iframe"), "border", "borderLeftWidth" ],
+ [ newElem("iframe"), "hspace", "marginLeft" ],
+ [ newElem("iframe"), "hspace", "marginRight" ],
+ [ newElem("iframe"), "vspace", "marginTop" ],
+ [ newElem("iframe"), "vspace", "marginBottom" ],
+ [ newElem("marquee"), "border", "borderTopWidth" ],
+ [ newElem("marquee"), "border", "borderRightWidth" ],
+ [ newElem("marquee"), "border", "borderBottomWidth" ],
+ [ newElem("marquee"), "border", "borderLeftWidth" ],
+ // Non-image input
+ [ newElem("input"), "border", "borderTopWidth" ],
+ [ newElem("input"), "border", "borderRightWidth" ],
+ [ newElem("input"), "border", "borderBottomWidth" ],
+ [ newElem("input"), "border", "borderLeftWidth" ],
+ [ newElem("input"), "width", "width" ],
+ [ newElem("input"), "height", "height" ],
+ [ newElem("input"), "hspace", "marginLeft" ],
+ [ newElem("input"), "hspace", "marginRight" ],
+ [ newElem("input"), "vspace", "marginTop" ],
+ [ newElem("input"), "vspace", "marginBottom" ],
+];
+
+function style(element) {
+ return element.ownerDocument.defaultView.getComputedStyle(element);
+}
+
+for (let [ctor, attr, prop] of tests) {
+ for (let parent of [container, frameContainer]) {
+ let elem = ctor(parent);
+ test(function() {
+ let default_elem = ctor(parent);
+ this.add_cleanup(() => {
+ elem.remove();
+ default_elem.remove();
+ });
+ elem.setAttribute(attr, "200");
+ assert_equals(elem.getAttribute(attr), "200");
+ assert_equals(style(elem)[prop], style(default_elem)[prop]);
+ }, `<${elem.localName} ${attr}> should not be mapped to style ${prop} in ${parent.ownerDocument.compatMode} mode`);
+ }
+}
+</script>
diff --git a/testing/web-platform/tests/html/rendering/widgets/appearance/appearance-animation-001.html b/testing/web-platform/tests/html/rendering/widgets/appearance/appearance-animation-001.html
new file mode 100644
index 0000000000..7d7474e0a4
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/widgets/appearance/appearance-animation-001.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>compute the kind of widget: author origin and animation origin</title>
+<link rel="match" href="appearance-transition-001-ref.html">
+<style>
+ input {
+ background-color: rgb(0, 0, 0);
+ }
+ .bg200 {
+ animation: 1e10s steps(2, start) animate-bg;
+ }
+ @keyframes animate-bg {
+ to {
+ background-color: rgb(0, 200, 0);
+ }
+ }
+</style>
+<input value="text" id=input>
+<script>
+ document.documentElement.offsetTop;
+ input.classList.toggle('bg200');
+</script>
+<p>PASS if the input field has a dark green background</p>
diff --git a/testing/web-platform/tests/html/rendering/widgets/appearance/appearance-animation-002-ref.html b/testing/web-platform/tests/html/rendering/widgets/appearance/appearance-animation-002-ref.html
new file mode 100644
index 0000000000..fab70234d2
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/widgets/appearance/appearance-animation-002-ref.html
@@ -0,0 +1,3 @@
+<!DOCTYPE html>
+<input value="text">
+<p>PASS if the input field does not have a red background</p>
diff --git a/testing/web-platform/tests/html/rendering/widgets/appearance/appearance-animation-002.html b/testing/web-platform/tests/html/rendering/widgets/appearance/appearance-animation-002.html
new file mode 100644
index 0000000000..acca93eae7
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/widgets/appearance/appearance-animation-002.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>compute the kind of widget: animation origin only</title>
+<link rel="match" href="appearance-animation-002-ref.html">
+<style>
+ .bg200 {
+ animation: 1e10s steps(2, start) animate-bg;
+ }
+ @keyframes animate-bg {
+ to {
+ background-color: rgb(255, 0, 0);
+ }
+ }
+</style>
+<input value="text" id=input>
+<script>
+ document.documentElement.offsetTop;
+ input.classList.toggle('bg200');
+</script>
+<p>PASS if the input field does not have a red background</p>
diff --git a/testing/web-platform/tests/html/rendering/widgets/appearance/appearance-transition-001-ref.html b/testing/web-platform/tests/html/rendering/widgets/appearance/appearance-transition-001-ref.html
new file mode 100644
index 0000000000..69726c6cd2
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/widgets/appearance/appearance-transition-001-ref.html
@@ -0,0 +1,7 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<style>
+ input { background-color: rgb(0, 100, 0); }
+</style>
+<input value="text">
+<p>PASS if the input field has a dark green background</p>
diff --git a/testing/web-platform/tests/html/rendering/widgets/appearance/appearance-transition-001.html b/testing/web-platform/tests/html/rendering/widgets/appearance/appearance-transition-001.html
new file mode 100644
index 0000000000..ec51cf9be5
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/widgets/appearance/appearance-transition-001.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>compute the kind of widget: author origin and transition origin</title>
+<link rel="help" href="https://crbug.com/1086732">
+<link rel="match" href="appearance-transition-001-ref.html">
+<style>
+ input {
+ background-color: rgb(0, 0, 0);
+ transition: background-color 1e10s steps(2, start);
+ }
+
+ .bg200 {
+ background-color: rgb(0, 200, 0);
+ }
+</style>
+<input value="text" id=input>
+<script>
+ document.documentElement.offsetTop;
+ input.classList.toggle('bg200');
+</script>
+<p>PASS if the input field has a dark green background</p>
diff --git a/testing/web-platform/tests/html/rendering/widgets/appearance/appearance-transition-002-ref.html b/testing/web-platform/tests/html/rendering/widgets/appearance/appearance-transition-002-ref.html
new file mode 100644
index 0000000000..febd6c55aa
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/widgets/appearance/appearance-transition-002-ref.html
@@ -0,0 +1,6 @@
+<!DOCTYPE html>
+<style>
+ input { background-color: rgb(128, 228, 128); }
+</style>
+<input value="text">
+<p>PASS if the input field has a light green background</p>
diff --git a/testing/web-platform/tests/html/rendering/widgets/appearance/appearance-transition-002.html b/testing/web-platform/tests/html/rendering/widgets/appearance/appearance-transition-002.html
new file mode 100644
index 0000000000..b6c2a3dcad
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/widgets/appearance/appearance-transition-002.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>compute the kind of widget: transition origin without author origin style before the transition</title>
+<link rel="match" href="appearance-transition-002-ref.html">
+<style>
+ input {
+ transition: background-color 1e10s steps(2, start);
+ }
+
+ .bg200 {
+ background-color: rgb(0, 200, 0);
+ }
+</style>
+<input value="text" id=input>
+<script>
+ document.documentElement.offsetTop;
+ input.classList.toggle('bg200');
+</script>
+<p>PASS if the input field has a light green background</p>
diff --git a/testing/web-platform/tests/html/rendering/widgets/appearance/appearance-transition-003.html b/testing/web-platform/tests/html/rendering/widgets/appearance/appearance-transition-003.html
new file mode 100644
index 0000000000..109617b7b7
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/widgets/appearance/appearance-transition-003.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>compute the kind of widget: transition origin without author origin style after the transition</title>
+<link rel="match" href="appearance-animation-002-ref.html">
+<style>
+ input {
+ transition: background-color 1e10s steps(2, start);
+ }
+
+ .bg200 {
+ background-color: rgb(255, 0, 0);
+ }
+</style>
+<input value="text" id=input class=bg200>
+<script>
+ document.documentElement.offsetTop;
+ input.classList.toggle('bg200');
+</script>
+<p>PASS if the input field does not have a red background</p>
diff --git a/testing/web-platform/tests/html/rendering/widgets/appearance/default-styles.html b/testing/web-platform/tests/html/rendering/widgets/appearance/default-styles.html
new file mode 100644
index 0000000000..8869808696
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/widgets/appearance/default-styles.html
@@ -0,0 +1,96 @@
+<!doctype html>
+<title>HTML: default style for 'appearance'</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<body>
+<script>
+// namespaces
+const htmlns = 'http://www.w3.org/1999/xhtml';
+const svgns = 'http://www.w3.org/2000/svg';
+
+// auto
+testAppearance(htmlns, 'input', null, 'auto');
+testAppearance(htmlns, 'input', {type: 'text'}, 'auto');
+testAppearance(htmlns, 'input', {type: 'TEXT'}, 'auto');
+testAppearance(htmlns, 'input', {type: 'search'}, 'auto');
+testAppearance(htmlns, 'input', {type: 'tel'}, 'auto');
+testAppearance(htmlns, 'input', {type: 'url'}, 'auto');
+testAppearance(htmlns, 'input', {type: 'email'}, 'auto');
+testAppearance(htmlns, 'input', {type: 'password'}, 'auto');
+testAppearance(htmlns, 'input', {type: 'date'}, 'auto');
+testAppearance(htmlns, 'input', {type: 'month'}, 'auto');
+testAppearance(htmlns, 'input', {type: 'week'}, 'auto');
+testAppearance(htmlns, 'input', {type: 'time'}, 'auto');
+testAppearance(htmlns, 'input', {type: 'datetime-local'}, 'auto');
+testAppearance(htmlns, 'input', {type: 'number'}, 'auto');
+testAppearance(htmlns, 'input', {type: 'range'}, 'auto');
+testAppearance(htmlns, 'input', {type: 'color'}, 'auto');
+testAppearance(htmlns, 'input', {type: 'checkbox'}, 'auto');
+testAppearance(htmlns, 'input', {type: 'radio'}, 'auto');
+testAppearance(htmlns, 'input', {type: 'submit'}, 'auto');
+testAppearance(htmlns, 'input', {type: 'reset'}, 'auto');
+testAppearance(htmlns, 'input', {type: 'button'}, 'auto');
+testAppearance(htmlns, 'input', {type: 'unknowntype'}, 'auto');
+testAppearance(htmlns, 'select', null, 'auto');
+testAppearance(htmlns, 'select', {multiple: ''}, 'auto');
+testAppearance(htmlns, 'select', {size: '2'}, 'auto');
+testAppearance(htmlns, 'button', null, 'auto');
+testAppearance(htmlns, 'textarea', null, 'auto');
+testAppearance(htmlns, 'meter', null, 'auto');
+testAppearance(htmlns, 'progress', null, 'auto');
+
+// none
+testAppearance(htmlns, 'input', {type: 'hidden'}, 'none');
+testAppearance(htmlns, 'input', {type: 'HIDDEN'}, 'none');
+testAppearance(htmlns, 'input', {type: 'file'}, 'none');
+testAppearance(htmlns, 'input', {type: 'image'}, 'none');
+testAppearance(htmlns, 'div', null, 'none');
+testAppearance(htmlns, 'details', null, 'none');
+testAppearance(htmlns, 'summary', null, 'none');
+testAppearance(htmlns, 'video', null, 'none');
+testAppearance(htmlns, 'video', {controls: ''}, 'none');
+testAppearance(htmlns, 'menuitem', null, 'none');
+testAppearance(htmlns, 'marquee', null, 'none');
+testAppearance(htmlns, 'keygen', null, 'none');
+testAppearance(null, 'input', null, 'none');
+testAppearance(svgns, 'input', null, 'none');
+
+test(t => {
+ assertAppearance(document.documentElement, 'none');
+}, 'The html element');
+
+test(t => {
+ assertAppearance(document.body, 'none');
+}, 'The body element');
+
+
+function testAppearance(ns, tag, attributes, expected) {
+ test(t => {
+ const elm = document.createElementNS(ns, tag);
+ for (const att in attributes) {
+ elm.setAttribute(att, attributes[att]);
+ }
+ document.body.appendChild(elm);
+ t.add_cleanup(() => elm.remove());
+ assertAppearance(elm, expected);
+ }, formatTestName(ns, tag, attributes));
+}
+
+function assertAppearance(elm, expected) {
+ const computedStyle = getComputedStyle(elm);
+ assert_equals(computedStyle.getPropertyValue('-webkit-appearance'), expected, '-webkit-appearance');
+ assert_equals(computedStyle.getPropertyValue('appearance'), expected, 'appearance (no prefix)');
+}
+
+function formatTestName(ns, tag, attributes) {
+ let s = `<${tag}`;
+ for (const att in attributes) {
+ s += ` ${att}="${attributes[att]}"`;
+ }
+ s += '>';
+ if (ns !== htmlns) {
+ s += ` (namespace: ${ns})`;
+ }
+ return s;
+}
+</script>
diff --git a/testing/web-platform/tests/html/rendering/widgets/baseline-alignment-and-overflow.tentative.html b/testing/web-platform/tests/html/rendering/widgets/baseline-alignment-and-overflow.tentative.html
new file mode 100644
index 0000000000..45ac762bd1
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/widgets/baseline-alignment-and-overflow.tentative.html
@@ -0,0 +1,237 @@
+<!DOCTYPE html>
+<title>HTML: widgets' baseline alignment and interaction with 'overflow'</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<!--
+This test tests where the baseline is for different widgets.
+This isn't yet specified, see https://github.com/whatwg/html/issues/5065
+
+Where the baseline is affects where *other* things on the same linebox are positioned. So this test
+makes assertions about the offsetTop for a previous sibling <span>, and compares it to a reference
+that has equivalent setup but using a styled <span> instead of an actual widget (where possible) so
+we can control where its baseline will be (assuming a correct CSS implementation).
+
+CSS has the following behavior regarding baselines (this is non-normative, also read the spec):
+
+* for a normal inline containing text, the baseline is the same as the text's baseline.
+* for replaced elements (like images), the baseline is at the bottom margin-box edge.
+* for an inline-block, it depends on its 'overflow':
+ - 'visible': the baseline is the same as the baseline for the last line box in the inline-block.
+ - otherwise: the baseline is like replaced elements.
+
+The baselines for different widgets, as implemented in Firefox, are as follows:
+
+<input type=text>
+<input type=search>
+<input type=tel>
+<input type=email>
+<input type=password>
+<input type=date>
+<input type=month>
+<input type=week>
+<input type=time>
+<input type=datetime-local>
+<input type=number>
+<input type=submit>
+<input type=reset>
+<input type=button>
+ Like inline-block but 'overflow' is forced to 'visible' and text inside is vertically centered.
+
+<input type=checkbox> with 'appearance: auto'
+<input type=radio> with 'appearance: auto'
+ At the bottom of the content-box edge (and whether there's a border depends
+ on the platform).
+
+ This is not usually how CSS works so we fake it with a negative margin-bottom.
+
+<input type=color>
+ At the content-box edge.
+
+<input type=file>
+ Like inline-block but 'overflow' is forced to to 'visible' and it contains a button; the button
+ can affect where the baseline is.
+
+<input type=image> showing alt text, with 'overflow: visible'
+ Like inline-block.
+
+<input type=image> showing an image
+<input type=image> showing alt text, with 'overflow' something other than 'visible'
+<input type=range>
+<input type=checkbox> with 'appearance: none'
+<input type=radio> with 'appearance: none'
+ Like replaced elements.
+
+-->
+<style>
+.test {
+ border-collapse: collapse;
+ font-size: 10px;
+}
+.test td {
+ border: none;
+ padding: 0;
+ margin:0;
+ outline: 1px solid silver;
+}
+
+.test td > input,
+.ref td > .fake-input-text,
+.ref td > .inline-block,
+.ref td > img,
+.ref td > button {
+ font: inherit;
+ height: 60px;
+ width: 60px;
+ padding: 10px;
+ box-sizing: border-box;
+ margin: 10px 0;
+ /* Note: a border is not specified because that would imply 'appearance: none' for some widgets */
+}
+
+.ref button img {
+ height: 100%;
+ width: 100%;
+ display: block;
+}
+
+/* Use inline-grid instead of inline-block here to more easily center the text inside */
+.ref .fake-input-text {
+ display: inline-grid;
+ border: 2px solid; /* 2px matches UA default style */
+ align-items: center;
+}
+.ref .inline-block {
+ display: inline-block;
+}
+
+.ref-file-input-like button {
+ font-size: unset;
+}
+
+[style*="appearance: none;"] {
+ -webkit-appearance: none; /* TODO(zcorpan) remove this when unprefixed appearance is supported */
+}
+</style>
+<div id="log"></div>
+<h2>refs</h2>
+<!--
+The first span's offsetTop is what we want to compare with the corresponding test's span's offsetTop.
+The sibling element is there to control where the baseline for the line box will be.
+-->
+<table class="test ref">
+ <tr class="ref-text-input-like"><td><span>ref-text-input-like</span> <span class=fake-input-text>x</span>
+ <tr class="ref-checkbox-input-appearance-auto-like"><td><span>ref-checkbox-input-appearance-auto-like</span> <img class=auto-checkbox src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAMCAIAAAD3UuoiAAAAGklEQVQoz2Nk%2BP%2BfgRqAiYFKYNSgUYOGp0EA%2BQMCFrJdTgsAAAAASUVORK5CYII%3D">
+ <tr class="ref-color-input-like"><td><span>ref-color-input-like</span> <button><img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAMCAIAAAD3UuoiAAAAGklEQVQoz2Nk%2BP%2BfgRqAiYFKYNSgUYOGp0EA%2BQMCFrJdTgsAAAAASUVORK5CYII%3D"></button>
+ <tr class="ref-file-input-like"><td><span>ref-file-input-like</span> <span class=inline-block><button>x</button></span>
+ <tr class="ref-image-input-showing-alt-overflow-visible-like"><td><span>ref-image-input-showing-alt-overflow-visible-like</span> <span class=inline-block>x</span>
+ <tr class="ref-image-input-showing-image-like"><td><span>ref-image-input-showing-image-like</span> <img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAMCAIAAAD3UuoiAAAAGklEQVQoz2Nk%2BP%2BfgRqAiYFKYNSgUYOGp0EA%2BQMCFrJdTgsAAAAASUVORK5CYII%3D">
+</table>
+<h2>template table</h2>
+<!--
+Each row in this table will be cloned into #test-table for each combination of styles to test.
+-->
+<table id="template-table">
+ <tr><td><span>text</span> <input type=text value=x></td></tr>
+ <tr><td><span>search</span> <input type=search value=x></td></tr>
+ <tr><td><span>tel</span> <input type=tel value=x></td></tr>
+ <tr><td><span>url</span> <input type=url value="data:,x"></td></tr>
+ <tr><td><span>email</span> <input type=email value=x></td></tr>
+ <tr><td><span>password</span> <input type=password value=x></td></tr>
+ <tr><td><span>date</span> <input type=date value="2020-01-01"></td></tr>
+ <tr><td><span>month</span> <input type=month value="2020-01"></td></tr>
+ <tr><td><span>week</span> <input type=week value="2020-W01"></td></tr>
+ <tr><td><span>time</span> <input type=time value="00:00"></td></tr>
+ <tr><td><span>datetime-local</span> <input type=datetime-local value="2020-01-01T00:00"></td></tr>
+ <tr><td><span>number</span> <input type=number value=0></td></tr>
+ <tr><td><span>range</span> <input type=range></td></tr>
+ <tr><td><span>color</span> <input type=color value=#000000></td></tr>
+ <tr><td><span>checkbox</span> <input type=checkbox></td></tr>
+ <tr><td><span>radio</span> <input type=radio></td></tr>
+ <tr><td><span>file</span> <input type=file></td></tr>
+ <tr><td><span>submit</span> <input type=submit value=x></td></tr>
+ <tr><td><span>image</span> <input type=image src="data:,broken" alt="x"></td></tr>
+ <tr><td><span>image-with-src</span> <input type=image src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAMCAIAAAD3UuoiAAAAGklEQVQoz2Nk%2BP%2BfgRqAiYFKYNSgUYOGp0EA%2BQMCFrJdTgsAAAAASUVORK5CYII%3D" alt="x"></td></tr>
+ <tr><td><span>reset</span> <input type=reset value=x></td></tr>
+ <tr><td><span>button</span> <input type=button value=x></td></tr>
+</table>
+<h2>tests</h2>
+<!--
+This table gets populated by the script.
+-->
+<table class="test" id="test-table"><tbody></tbody></table>
+<script>
+ "use strict";
+
+ promise_setup(async () => {
+ const templateTable = document.querySelector('#template-table');
+ const testTBody = document.querySelector('#test-table tbody');
+
+ {
+ const checkboxBorder = getComputedStyle(document.querySelector("input[type=checkbox]")).borderTopWidth;
+ const checkboxLike = document.querySelector(".auto-checkbox");
+ checkboxLike.style.border = checkboxBorder + " solid";
+ checkboxLike.style.marginBottom = "-" + checkboxBorder;
+ }
+
+ const templateRows = templateTable.querySelectorAll('tr');
+ for (const templateRow of templateRows) {
+ for (const appearanceValue of ["auto", "none"]) {
+ for (const overflowValue of ['visible', 'hidden', 'scroll']) {
+ const clonedRow = templateRow.cloneNode(true);
+ clonedRow.querySelector('input').setAttribute('style', `overflow: ${overflowValue}; appearance: ${appearanceValue};`);
+ testTBody.append(clonedRow);
+ }
+ }
+ }
+
+ // wait for images to load
+ await new Promise(resolve => window.onload = e => resolve());
+ for (const img of document.images) {
+ assert_true(img.complete); // either error state or loaded
+ }
+
+ // get layout info from refs
+ const refTextInputLikeOffsetTop = document.querySelector('.ref-text-input-like span').offsetTop;
+ const refCheckboxInputAppearanceAutoLikeOffsetTop = document.querySelector('.ref-checkbox-input-appearance-auto-like span').offsetTop;
+ const refColorInputLikeOffsetTop = document.querySelector('.ref-color-input-like span').offsetTop;
+ const refFileInputLikeOffsetTop = document.querySelector('.ref-file-input-like span').offsetTop;
+ const refImageInputShowingAltOverflowVisibleLikeOffsetTop = document.querySelector('.ref-image-input-showing-alt-overflow-visible-like span').offsetTop;
+ const refImageInputShowingImageLikeOffsetTop = document.querySelector('.ref-image-input-showing-image-like span').offsetTop;
+
+ function expectedOffsetTop(input) {
+ // TODO(zcorpan) https://github.com/whatwg/html/issues/5065
+ // for now this is intended to match Firefox
+ const style = input.getAttribute('style');
+ const src = input.getAttribute('src');
+ switch (input.type) {
+ case 'file':
+ return refFileInputLikeOffsetTop;
+ case 'range':
+ return refImageInputShowingImageLikeOffsetTop;
+ case 'color':
+ return refColorInputLikeOffsetTop;
+ case 'checkbox':
+ case 'radio':
+ return (style.includes('appearance: none;')) ? refImageInputShowingImageLikeOffsetTop : refCheckboxInputAppearanceAutoLikeOffsetTop;
+ case 'image':
+ return (src === 'data:,broken' && style.includes('overflow: visible;')) ? refImageInputShowingAltOverflowVisibleLikeOffsetTop : refImageInputShowingImageLikeOffsetTop;
+ default:
+ return refTextInputLikeOffsetTop;
+ }
+ }
+
+ function testName(markup) {
+ return markup.replace(/data:image\/png[^"]+/, 'data:(png)');
+ }
+
+ for (const row of testTBody.children) {
+ const input = row.firstChild.lastElementChild;
+ // This is not using test() because promise_setup() only allows promise_test().
+ promise_test(async () => {
+ assert_equals(input.type, input.getAttribute('type'), 'input type should be supported')
+ const offsetTopActual = row.firstChild.firstChild.offsetTop;
+ assert_equals(offsetTopActual, expectedOffsetTop(input), '<span>.offsetTop');
+ }, testName(input.outerHTML));
+ }
+ });
+</script>
diff --git a/testing/web-platform/tests/html/rendering/widgets/button-layout/anonymous-button-content-box-ref.html b/testing/web-platform/tests/html/rendering/widgets/button-layout/anonymous-button-content-box-ref.html
new file mode 100644
index 0000000000..243f0add0d
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/widgets/button-layout/anonymous-button-content-box-ref.html
@@ -0,0 +1,31 @@
+<!doctype html>
+<title>Reference for Anonymous button content box</title>
+<style>
+body { margin: 0 }
+.button { width: 124px; height: 124px; background: papayawhip; border: 2px solid; display: table-cell; vertical-align: middle; text-align: center; box-sizing: border-box; }
+.top { vertical-align: top }
+.left { text-align: left }
+.float { display: block; float: left; }
+body > div { clear: left; }
+.button > div { width: 50px; height: 50px; border: solid }
+.button > .tall { height: 150px }
+.button > .wide { width: 150px; margin-top: 32px }
+</style>
+<div>
+ <div class=button>input</div>
+ <div class="button">input grid</div>
+ <div class="button">input flex</div>
+ <div class=button>button</div>
+</div>
+<div>
+ <div class=button style="text-align: left">button left</div>
+ <div class=button><div>div</div></div>
+ <div class="button top">grid</div>
+ <div class="button top"><div>grid</div></div>
+</div>
+<div>
+ <div class="button top left float">flex</div>
+ <div class="button top float"><div>flex</div></div>
+ <div class="button float"><div class=tall>tall</div></div>
+ <div class="button float"><div class=wide>wide</div></div>
+</div>
diff --git a/testing/web-platform/tests/html/rendering/widgets/button-layout/anonymous-button-content-box.html b/testing/web-platform/tests/html/rendering/widgets/button-layout/anonymous-button-content-box.html
new file mode 100644
index 0000000000..07c7b8e366
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/widgets/button-layout/anonymous-button-content-box.html
@@ -0,0 +1,31 @@
+<!doctype html>
+<title>Anonymous button content box</title>
+<link rel=match href=anonymous-button-content-box-ref.html>
+<style>
+body { margin: 0 }
+button, input { width: 124px; height: 124px; background: papayawhip; border: 2px solid; margin: 0; padding: 0; float: left; font: inherit }
+body > div { clear: left; }
+button > div { width: 50px; height: 50px; border: solid }
+.grid { display: grid }
+.flex { display: flex }
+.tall { height: 150px }
+.wide { width: 150px }
+</style>
+<div>
+ <input type=button value=input>
+ <input type=button value="input grid" class=grid>
+ <input type=button value="input flex" class=flex>
+ <button>button</button>
+</div>
+<div>
+ <button style="text-align: left">button left</button>
+ <button><div>div</div></button>
+ <button class=grid>grid</button>
+ <button class=grid><div>grid</div></button>
+</div>
+<div>
+ <button class=flex>flex</button>
+ <button class=flex><div>flex</div></button>
+ <button><div class=tall>tall</div></button>
+ <button><div class=wide>wide</div></button>
+</div>
diff --git a/testing/web-platform/tests/html/rendering/widgets/button-layout/computed-style.html b/testing/web-platform/tests/html/rendering/widgets/button-layout/computed-style.html
new file mode 100644
index 0000000000..d18e5d365d
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/widgets/button-layout/computed-style.html
@@ -0,0 +1,52 @@
+<!doctype html>
+<title>computed style on buttons</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div class="tests">
+ <input type="reset">
+ <input type="button">
+ <input type="submit">
+ <input type="color">
+ <input type="image">
+ <button></button>
+</div>
+<script>
+// "behave as" doesn't change computed value.
+const displayValues = ['inline', 'block', 'list-item', 'inline-block', 'table', 'inline-table', 'table-row-group', 'table-header-group', 'table-footer-group', 'table-row', 'table-column-group', 'table-column', 'table-cell', 'table-caption', 'none', 'contents', 'flow', 'flow-root', 'flex', 'grid', 'ruby', 'ruby-base', 'ruby-text', 'ruby-base-container', 'ruby-text-container', 'inline-flex', 'inline-grid'];
+for (const val of displayValues) {
+ [].slice.call(document.querySelectorAll('.tests > *')).forEach(el => {
+ el.style.display = ''
+ el.style.display = val;
+ const attrs = el.type ? ` type=${el.type}` : '';
+ const tag = `<${el.localName}${attrs}>`;
+ test(() => {
+ assert_not_equals(el.style.display, '', `display: ${val} is not supported`)
+ let expectedVal = val;
+ if (el instanceof HTMLInputElement && val === 'contents') {
+ expectedVal = 'none'; // https://drafts.csswg.org/css-display/#unbox-html
+ }
+ if (val == 'flow') {
+ // Use the more backwards-compatible form, `block` is better than `flow`
+ // https://drafts.csswg.org/cssom/#serializing-css-values
+ expectedVal = 'block';
+ }
+ assert_equals(getComputedStyle(el).display, expectedVal);
+ }, `computed display of ${tag} with display: ${val}`);
+ });
+}
+
+for (let input of document.querySelectorAll("input")) {
+ test(() => {
+ if (input.type == "image") {
+ assert_equals(getComputedStyle(input).overflow, "visible", "Should not be clip by default");
+ return;
+ }
+ assert_equals(getComputedStyle(input).overflow, "clip", "Should be clip by default");
+ assert_equals(getComputedStyle(input).overflowClipMargin, "0px", "Should use 0 margin");
+ input.style.overflow = "visible";
+ input.style.overflowClipMargin = "10px";
+ assert_equals(getComputedStyle(input).overflow, "clip", "Clip be !important");
+ assert_equals(getComputedStyle(input).overflowClipMargin, "0px", "Clip margin should be !important too");
+ }, `<input type=${input.type}> overflow/overflow-clip-margin`);
+}
+</script>
diff --git a/testing/web-platform/tests/html/rendering/widgets/button-layout/display-other.html b/testing/web-platform/tests/html/rendering/widgets/button-layout/display-other.html
new file mode 100644
index 0000000000..6ed3f5894a
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/widgets/button-layout/display-other.html
@@ -0,0 +1,52 @@
+<!doctype html>
+<title>button with other display values</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<style>
+body { margin: 0 }
+.float { width: 100px; height: 100px; float: left; background: blue; margin: 10px }
+</style>
+<div class=float></div>
+<button id=button style="display: block;"><div class=float></div></button><span id=after>after</span>
+<script>
+// These should all behave as flow-root.
+const displayValues = ['run-in', 'flow', 'flow-root', 'table', 'list-item',
+ 'table-row-group', 'table-header-group', 'table-footer-group',
+ 'table-row', 'table-cell', 'table-column-group', 'table-column',
+ 'table-caption', 'ruby-base', 'ruby-text', 'ruby-base-container',
+ 'ruby-text-container'];
+const button = document.getElementById('button');
+const after = document.getElementById('after');
+function getValues() {
+ return {
+ buttonLeft: button.offsetLeft,
+ buttonTop: button.offsetTop,
+ buttonWidth: button.clientWidth,
+ buttonHeight: button.clientHeight,
+ afterLeft: after.offsetLeft,
+ afterTop: after.offsetTop,
+ };
+}
+const expected = getValues();
+test(t => {
+ assert_equals(expected.buttonLeft, 120, 'buttonLeft');
+ assert_equals(expected.buttonTop, 0, 'buttonTop');
+ assert_greater_than_equal(expected.buttonWidth, 120, 'buttonWidth');
+ assert_greater_than_equal(expected.buttonHeight, 120, 'buttonHeight');
+ assert_equals(expected.afterLeft, 0, 'afterLeft');
+ assert_greater_than_equal(expected.afterTop, 120, 'afterTop');
+}, 'display: block');
+for (const val of displayValues) {
+ test(t => {
+ t.add_cleanup(() => {
+ button.style.display = 'block';
+ });
+ assert_true(CSS.supports(`display: ${val}`), `display: ${val} is not supported`);
+ button.style.display = val;
+ const values = getValues();
+ for (const prop in values) {
+ assert_equals(values[prop], expected[prop], prop);
+ }
+ }, `display: ${val}`);
+}
+</script>
diff --git a/testing/web-platform/tests/html/rendering/widgets/button-layout/flex.html b/testing/web-platform/tests/html/rendering/widgets/button-layout/flex.html
new file mode 100644
index 0000000000..7f159fc232
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/widgets/button-layout/flex.html
@@ -0,0 +1,61 @@
+<!doctype html>
+<title>button with flex/inline-flex</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<style>
+#inline-flex { display: inline-flex }
+#flex { display: flex }
+#ref > div { display: flex }
+
+#flexstart {
+ border: none;
+ padding: 0;
+ display: flex;
+ align-items: flex-start;
+ height: 3em;
+}
+
+#stretch {
+ border: none;
+ padding: 0;
+ display: flex;
+ align-items: stretch;
+ height: 3em;
+}
+</style>
+<button id=inline-flex><div>1</div><div>2</div><div>3</div><div>4</div></button>
+<button id=flex><div>1</div><div>2</div><div>3</div><div>4</div></button>
+<button id=ref><div><div>1</div><div>2</div><div>3</div><div>4</div></div></button>
+
+<div><button id="flexstart"><span id="flexstart-item">abc</span></button></div>
+
+<div><button id="stretch"><span id="stretch-item">abc</span></button></div>
+<script>
+const ref = document.getElementById('ref');
+const expectedWidth = ref.clientWidth;
+const expectedHeight = ref.clientHeight;
+for (const elm of [document.getElementById('inline-flex'),
+ document.getElementById('flex')]) {
+ test(() => {
+ // check that flex is supported
+ const flexValue = elm.id;
+ assert_equals(getComputedStyle(elm).display, flexValue, `${flexValue} is not supported`);
+ const width = elm.clientWidth;
+ const height = elm.clientHeight;
+ assert_equals(width, expectedWidth, 'clientWidth');
+ assert_equals(height, expectedHeight, 'clientHeight');
+ }, elm.id);
+}
+
+// crbug.com/700029
+test(() => {
+ assert_equals(document.getElementById('flexstart').offsetTop,
+ document.getElementById('flexstart-item').offsetTop);
+}, 'align-items:flex-start should work');
+
+// crbug.com/1004163
+test(() => {
+ assert_equals(document.getElementById('stretch').offsetHeight,
+ document.getElementById('stretch-item').offsetHeight);
+}, 'align-items:stretch should work');
+</script>
diff --git a/testing/web-platform/tests/html/rendering/widgets/button-layout/grid.html b/testing/web-platform/tests/html/rendering/widgets/button-layout/grid.html
new file mode 100644
index 0000000000..7c2a467099
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/widgets/button-layout/grid.html
@@ -0,0 +1,30 @@
+<!doctype html>
+<title>button with grid/inline-grid</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<style>
+#inline-grid { display: inline-grid }
+#grid { display: grid }
+#ref > div { display: grid }
+#inline-grid, #grid, #ref > div { grid-template: auto auto / auto auto }
+</style>
+<button id=inline-grid><div>1</div><div>2</div><div>3</div><div>4</div></button>
+<button id=grid><div>1</div><div>2</div><div>3</div><div>4</div></button>
+<button id=ref><div><div>1</div><div>2</div><div>3</div><div>4</div></div></button>
+<script>
+const ref = document.getElementById('ref');
+const expectedWidth = ref.clientWidth;
+const expectedHeight = ref.clientHeight;
+for (const elm of [document.getElementById('inline-grid'),
+ document.getElementById('grid')]) {
+ test(() => {
+ // check that grid is supported
+ const gridValue = elm.id;
+ assert_equals(getComputedStyle(elm).display, gridValue, `${gridValue} is not supported`);
+ const width = elm.clientWidth;
+ const height = elm.clientHeight;
+ assert_equals(width, expectedWidth, 'clientWidth');
+ assert_equals(height, expectedHeight, 'clientHeight');
+ }, elm.id);
+}
+</script>
diff --git a/testing/web-platform/tests/html/rendering/widgets/button-layout/inline-level-ref.html b/testing/web-platform/tests/html/rendering/widgets/button-layout/inline-level-ref.html
new file mode 100644
index 0000000000..3784cc30db
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/widgets/button-layout/inline-level-ref.html
@@ -0,0 +1,10 @@
+<!doctype html>
+<title>Reference for button with inline-level display</title>
+<style>
+button { font: inherit }
+</style>
+<p>There should be three buttons below containing "1" and "2" on separate lines, and "a" and "b" before and after on the same baseline as the "2".</p>
+<p>a<button>1<br>2</button>b</p>
+<p>a<button>1<br>2</button>b</p>
+<p>a<button>1<br>2</button>b</p>
+<p>a<button>1<br>2</button>b</p>
diff --git a/testing/web-platform/tests/html/rendering/widgets/button-layout/inline-level.html b/testing/web-platform/tests/html/rendering/widgets/button-layout/inline-level.html
new file mode 100644
index 0000000000..e23aba731c
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/widgets/button-layout/inline-level.html
@@ -0,0 +1,25 @@
+<!doctype html>
+<title>button with inline-level display</title>
+<link rel=match href=inline-level-ref.html>
+<style>
+button, input { font: inherit }
+.inline { display: inline }
+.inline-block { display: inline-block }
+.inline-table { display: inline-table }
+</style>
+<p>There should be three buttons below containing "1" and "2" on separate lines, and "a" and "b" before and after on the same baseline as the "2".</p>
+<p>a<button class=inline>1<br><span class=check-baseline>2</span></button><span class=ref-baseline>b</span></p>
+<p>a<button class=inline-block>1<br><span class=check-baseline>2</span></button><span class=ref-baseline>b</span></p>
+<p>a<button class=inline-table>1<br><span class=check-baseline>2</span></button><span class=ref-baseline>b</span></p>
+<p>a<input type=button class=inline-table value="1&#10;2">b</p>
+<script>
+const spans = document.querySelectorAll('.check-baseline');
+for (const span of [].slice.call(spans)) {
+ const baseline = span.offsetTop + span.offsetHeight;
+ const refSpan = span.parentNode.nextSibling;
+ const refBaseline = refSpan.offsetTop + refSpan.offsetHeight;
+ if (baseline !== refBaseline) {
+ refSpan.textContent += " (wrong baseline)";
+ }
+}
+</script>
diff --git a/testing/web-platform/tests/html/rendering/widgets/button-layout/input-type-button-clip-ref.html b/testing/web-platform/tests/html/rendering/widgets/button-layout/input-type-button-clip-ref.html
new file mode 100644
index 0000000000..8f956d36f5
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/widgets/button-layout/input-type-button-clip-ref.html
@@ -0,0 +1,9 @@
+<!doctype html>
+<style>
+ button {
+ width: 10ch;
+ overflow: clip;
+ text-overflow: ellipsis;
+ }
+</style>
+<button>aaaaaaaaaaaaaaaaaaaaaa</button>
diff --git a/testing/web-platform/tests/html/rendering/widgets/button-layout/input-type-button-clip.html b/testing/web-platform/tests/html/rendering/widgets/button-layout/input-type-button-clip.html
new file mode 100644
index 0000000000..db1ad35cce
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/widgets/button-layout/input-type-button-clip.html
@@ -0,0 +1,15 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>button input is clipped by default, and text-overflow: ellipsis works</title>
+<link rel="help" href="https://github.com/whatwg/html/issues/9976">
+<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1800077">
+<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
+<link rel="author" title="Mozilla" href="https://mozilla.org">
+<link rel="match" href="input-type-button-clip-ref.html">
+<style>
+ input {
+ width: 10ch;
+ text-overflow: ellipsis;
+ }
+</style>
+<input type="button" value="aaaaaaaaaaaaaaaaaaaaaa">
diff --git a/testing/web-platform/tests/html/rendering/widgets/button-layout/input-type-button-newline-2-mismatch.html b/testing/web-platform/tests/html/rendering/widgets/button-layout/input-type-button-newline-2-mismatch.html
new file mode 100644
index 0000000000..19930b947b
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/widgets/button-layout/input-type-button-newline-2-mismatch.html
@@ -0,0 +1,2 @@
+<!DOCTYPE html>
+<input type=button value="1">
diff --git a/testing/web-platform/tests/html/rendering/widgets/button-layout/input-type-button-newline-2.html b/testing/web-platform/tests/html/rendering/widgets/button-layout/input-type-button-newline-2.html
new file mode 100644
index 0000000000..6e21c9e98e
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/widgets/button-layout/input-type-button-newline-2.html
@@ -0,0 +1,6 @@
+<!DOCTYPE html>
+<link rel=author href="mailto:jarhar@chromium.org">
+<link rel=help href="https://bugs.chromium.org/p/chromium/issues/detail?id=922011">
+<link rel=mismatch href="input-type-button-newline-2-mismatch.html">
+
+<input type=button value="1&#10;2">
diff --git a/testing/web-platform/tests/html/rendering/widgets/button-layout/input-type-button-newline-mismatch.html b/testing/web-platform/tests/html/rendering/widgets/button-layout/input-type-button-newline-mismatch.html
new file mode 100644
index 0000000000..3d6495de66
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/widgets/button-layout/input-type-button-newline-mismatch.html
@@ -0,0 +1,2 @@
+<!DOCTYPE html>
+<input type=button value="12">
diff --git a/testing/web-platform/tests/html/rendering/widgets/button-layout/input-type-button-newline.html b/testing/web-platform/tests/html/rendering/widgets/button-layout/input-type-button-newline.html
new file mode 100644
index 0000000000..139893ed42
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/widgets/button-layout/input-type-button-newline.html
@@ -0,0 +1,6 @@
+<!DOCTYPE html>
+<link rel=author href="mailto:jarhar@chromium.org">
+<link rel=help href="https://bugs.chromium.org/p/chromium/issues/detail?id=922011">
+<link rel=mismatch href="input-type-button-newline-mismatch.html">
+
+<input type=button value="1&#10;2">
diff --git a/testing/web-platform/tests/html/rendering/widgets/button-layout/propagate-text-decoration-ref.html b/testing/web-platform/tests/html/rendering/widgets/button-layout/propagate-text-decoration-ref.html
new file mode 100644
index 0000000000..f33a011a20
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/widgets/button-layout/propagate-text-decoration-ref.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<title>Reference for propagating text-decoration into buttons</title>
+<style>
+button { font: inherit }
+</style>
+<p>The text in the following buttons should be underlined.</p>
+<p><button><u>foo</u></button><button><u>foo</u></button></p>
+<p>The text in the following buttons should NOT be underlined.</p>
+<p><button>foo</button><button>foo</button></p>
diff --git a/testing/web-platform/tests/html/rendering/widgets/button-layout/propagate-text-decoration.html b/testing/web-platform/tests/html/rendering/widgets/button-layout/propagate-text-decoration.html
new file mode 100644
index 0000000000..83608402c1
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/widgets/button-layout/propagate-text-decoration.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<title>propagating text-decoration into buttons</title>
+<link rel=match href=propagate-text-decoration-ref.html>
+<meta name=fuzzy content="maxDifference=0-40;totalPixels=0-50">
+<style>
+button, input { font: inherit }
+.inline > u > * { display: inline }
+.inline-block > u > * { display: inline-block }
+</style>
+<p>The text in the following buttons should be underlined.</p>
+<p class=inline><u><button>foo</button><input type=button value=foo></u></p>
+<p>The text in the following buttons should NOT be underlined.</p>
+<p class=inline-block><u><button>foo</button><input type=button value=foo></u></p>
diff --git a/testing/web-platform/tests/html/rendering/widgets/button-layout/shrink-wrap.html b/testing/web-platform/tests/html/rendering/widgets/button-layout/shrink-wrap.html
new file mode 100644
index 0000000000..6d61102608
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/widgets/button-layout/shrink-wrap.html
@@ -0,0 +1,42 @@
+<!doctype html>
+<title>shrink-wrap button</title>
+<link rel=help href=https://html.spec.whatwg.org/multipage/rendering.html#button-layout>
+<link rel=help href=https://drafts.csswg.org/css2/visudet.html#shrink-to-fit-float>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<!--
+ minimum preferred width 100px
+ preferred width 250px
+ available width vary
+-->
+<style>
+div.available-width { border: thin dotted red; margin: 1em 0; padding: 1em 0 }
+button { border: none; margin: 0; padding: 0; background: papayawhip; }
+button > span.minimum-preferred-width { width: 100px }
+button > span { width: 50px; display: inline-block; outline: thin dotted blue }
+</style>
+<div class="available-width" style="width: 50px">
+ <button data-expected="100"><span class="minimum-preferred-width">x</span><span>x</span><span>x</span><span>x</span></button>
+</div>
+
+<div class="available-width" style="width: 200px">
+ <button data-expected="200"><span class="minimum-preferred-width">x</span><span>x</span><span>x</span><span>x</span></button>
+</div>
+
+<div class="available-width" style="width: 300px">
+ <button data-expected="250"><span class="minimum-preferred-width">x</span><span>x</span><span>x</span><span>x</span></button>
+</div>
+
+<script>
+const styles = ['display: block', 'display: inline', 'display: inline-block',
+ 'display: list-item', 'display: table', 'display: table-row',
+ 'display: table-cell', 'float: left'];
+for (const style of styles) {
+ for (const button of [].slice.call(document.querySelectorAll('button'))) {
+ test(() => {
+ button.setAttribute('style', style);
+ assert_equals(button.clientWidth, parseInt(button.dataset.expected, 10));
+ }, `${style} - available ${button.parentNode.getAttribute('style')}`);
+ }
+}
+</script>
diff --git a/testing/web-platform/tests/html/rendering/widgets/field-sizing-input-number.html b/testing/web-platform/tests/html/rendering/widgets/field-sizing-input-number.html
new file mode 100644
index 0000000000..859d35197b
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/widgets/field-sizing-input-number.html
@@ -0,0 +1,149 @@
+<!DOCTYPE html>
+<link rel="help" href="https://drafts.csswg.org/css-ui-4/#field-sizing">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<style>
+.disable-default {
+ field-sizing: content;
+}
+
+.small-placeholder {
+ font-size: 32px;
+}
+.small-placeholder::placeholder {
+ font-size: 16px;
+}
+
+.large-placeholder {
+ font-size: 20px;
+}
+.large-placeholder::placeholder {
+ font-size: 40px;
+}
+</style>
+<body>
+<div id="container"></div>
+<script>
+const DISABLE = 'class="disable-default"';
+const LONG_VALUE = '12345678901234567890.123';
+const LONG_TEXT = 'The quick brown fox jumps over the lazy dog.';
+
+function addElements(source) {
+ const container = document.querySelector('#container');
+ container.innerHTML = source + source;
+ container.lastElementChild.classList.add('disable-default');
+ return {
+ fixed: container.firstElementChild,
+ content: container.lastElementChild
+ };
+}
+
+function addTwoElements(source1, source2) {
+ const container = document.querySelector('#container');
+ container.innerHTML = source1 + source2;
+ return {
+ e1: container.firstElementChild,
+ e2: container.lastElementChild
+ };
+}
+
+['number'].forEach(type => {
+ test(() => {
+ let pair = addElements(`<input type=${type}>`);
+ // A text <input> has approximately 20ch width by default.
+ // A text <input> with field-sizing:content must be shorter than the default.
+ assert_less_than(pair.content.offsetWidth, pair.fixed.offsetWidth);
+ assert_equals(pair.content.offsetHeight, pair.fixed.offsetHeight);
+
+ pair = addTwoElements(`<input type=${type} ${DISABLE}>`,
+ `<input type=${type} ${DISABLE} value="123">`);
+ assert_less_than(pair.e1.offsetWidth, pair.e2.offsetWidth);
+ assert_equals(pair.e1.offsetHeight, pair.e2.offsetHeight);
+ }, `${type}: Empty value`);
+
+ test(() => {
+ let pair = addElements(`<input type=${type} value="${LONG_VALUE}">`);
+ assert_greater_than(pair.content.offsetWidth, pair.fixed.offsetWidth);
+ pair = addElements(`<input type=${type} placeholder="${LONG_TEXT}">`);
+ assert_greater_than(pair.content.offsetWidth, pair.fixed.offsetWidth);
+ }, `${type}: Auto width and auto height with a long text`);
+
+ test(() => {
+ let pair = addElements(`<input type=${type} style="width:20ch; height:2lh">`);
+ assert_equals(pair.content.offsetWidth, pair.fixed.offsetWidth);
+ assert_equals(pair.content.offsetHeight, pair.fixed.offsetHeight);
+
+ pair = addElements(`<input type=${type} style="width:20ch; height:2lh" value="${LONG_VALUE}">`);
+ assert_equals(pair.content.offsetWidth, pair.fixed.offsetWidth);
+ assert_equals(pair.content.offsetHeight, pair.fixed.offsetHeight);
+
+ pair = addElements(`<input type=${type} style="width:20ch; height:2lh" placeholder="${LONG_TEXT}">`);
+ assert_equals(pair.content.offsetWidth, pair.fixed.offsetWidth);
+ assert_equals(pair.content.offsetHeight, pair.fixed.offsetHeight);
+ }, `${type}: Explicit width and heigth`);
+
+ test(() => {
+ let pair = addElements(`<input type=${type} style="width:20ch">`);
+ assert_equals(pair.content.offsetWidth, pair.fixed.offsetWidth);
+ assert_equals(pair.content.offsetHeight, pair.fixed.offsetHeight);
+
+ pair = addElements(`<input type=${type} style="width:20ch" value="${LONG_VALUE}">`);
+ assert_equals(pair.content.offsetWidth, pair.fixed.offsetWidth);
+ assert_equals(pair.content.offsetHeight, pair.fixed.offsetHeight);
+
+ pair = addElements(`<input type=${type} style="width:20ch" placeholder="${LONG_TEXT}">`);
+ assert_equals(pair.content.offsetWidth, pair.fixed.offsetWidth);
+ assert_equals(pair.content.offsetHeight, pair.fixed.offsetHeight);
+ }, `${type}: Explicit width and auto height`);
+
+ test(() => {
+ let pair = addElements(`<input type=${type} style="height:2lh">`);
+ assert_less_than(pair.content.offsetWidth, pair.fixed.offsetWidth);
+ assert_equals(pair.content.offsetHeight, pair.fixed.offsetHeight);
+
+ pair = addElements(`<input type=${type} style="height:2lh" value="${LONG_VALUE}">`);
+ assert_greater_than(pair.content.offsetWidth, pair.fixed.offsetWidth);
+ assert_equals(pair.content.offsetHeight, pair.fixed.offsetHeight);
+
+ pair = addElements(`<input type=${type} style="height:2lh" placeholder="${LONG_TEXT}">`);
+ assert_greater_than(pair.content.offsetWidth, pair.fixed.offsetWidth);
+ assert_equals(pair.content.offsetHeight, pair.fixed.offsetHeight);
+ }, `${type}: Explicit height and auto width`);
+
+ test(() => {
+ let pair = addTwoElements(
+ `<input type=${type} class="disable-default small-placeholder">`,
+ `<input type=${type} class="disable-default small-placeholder" placeholder="foo bar">`);
+ assert_less_than(pair.e1.offsetWidth, pair.e2.offsetWidth);
+ assert_equals(pair.e1.offsetHeight, pair.e2.offsetHeight);
+ }, `${type}: Text caret is taller than the placeholder`);
+
+ test(() => {
+ let pair = addTwoElements(
+ `<input type=${type} class="disable-default large-placeholder">`,
+ `<input type=${type} class="disable-default large-placeholder" placeholder="foo bar">`);
+ assert_less_than(pair.e1.offsetWidth, pair.e2.offsetWidth);
+ assert_less_than(pair.e1.offsetHeight, pair.e2.offsetHeight);
+
+ pair = addTwoElements(
+ `<input type=${type} class="disable-default" style="font-size:40px; padding:16px">`,
+ `<input type=${type} class="disable-default large-placeholder"
+ placeholder="foo bar" style="font-size:40px; padding:16px">`);
+ assert_equals(pair.e1.offsetHeight, pair.e2.offsetHeight);
+ assert_equals(pair.e1.offsetTop, pair.e2.offsetTop);
+ }, `${type}: Text caret is shorter than the placeholder`);
+
+ test(() => {
+ const container = document.querySelector('#container');
+ container.innerHTML = `<input type=${type}>`;
+ const element = container.firstChild;
+ const w = element.offsetWidth;
+ const h = element.offsetHeight;
+ element.classList.add('disable-default');
+ assert_less_than(element.offsetWidth, w);
+ assert_equals(element.offsetHeight, h);
+ }, `${type}: Update field-sizing property dynamically`);
+
+});
+</script>
+</body>
diff --git a/testing/web-platform/tests/html/rendering/widgets/field-sizing-input-text.html b/testing/web-platform/tests/html/rendering/widgets/field-sizing-input-text.html
new file mode 100644
index 0000000000..f421ad602c
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/widgets/field-sizing-input-text.html
@@ -0,0 +1,154 @@
+<!DOCTYPE html>
+<link rel="help" href="https://drafts.csswg.org/css-ui-4/#field-sizing">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<style>
+.disable-default {
+ field-sizing: content;
+}
+
+.small-placeholder {
+ font-size: 32px;
+}
+.small-placeholder::placeholder {
+ font-size: 16px;
+}
+
+.large-placeholder {
+ font-size: 20px;
+}
+.large-placeholder::placeholder {
+ font-size: 40px;
+}
+</style>
+<body>
+<div id="container"></div>
+<script>
+const DISABLE = 'class="disable-default"';
+const LONG_TEXT = 'The quick brown fox jumps over the lazy dog.';
+
+function addElements(source) {
+ const container = document.querySelector('#container');
+ container.innerHTML = source + source;
+ container.lastElementChild.classList.add('disable-default');
+ return {
+ fixed: container.firstElementChild,
+ content: container.lastElementChild
+ };
+}
+
+function addTwoElements(source1, source2) {
+ const container = document.querySelector('#container');
+ container.innerHTML = source1 + source2;
+ return {
+ e1: container.firstElementChild,
+ e2: container.lastElementChild
+ };
+}
+
+['text', 'search', 'tel', 'url', 'email', 'password'].forEach(type => {
+ test(() => {
+ let pair = addElements(`<input type=${type}>`);
+ // A text <input> has approximately 20ch width by default.
+ // A text <input> with field-sizing:content must be shorter than the default.
+ assert_less_than(pair.content.offsetWidth, pair.fixed.offsetWidth);
+ assert_equals(pair.content.offsetHeight, pair.fixed.offsetHeight);
+
+ pair = addTwoElements(`<input type=${type} ${DISABLE}>`,
+ `<input type=${type} ${DISABLE} value="foo">`);
+ assert_less_than(pair.e1.offsetWidth, pair.e2.offsetWidth);
+ assert_equals(pair.e1.offsetHeight, pair.e2.offsetHeight);
+ }, `${type}: Empty value`);
+
+ test(() => {
+ let pair = addElements(`<input type=${type} size="10">`);
+ assert_less_than(pair.content.offsetWidth, pair.fixed.offsetWidth);
+ assert_equals(pair.content.offsetHeight, pair.fixed.offsetHeight);
+ }, `${type}: Empty value with a size atttribute`);
+
+ test(() => {
+ let pair = addElements(`<input type=${type} value="${LONG_TEXT}">`);
+ assert_greater_than(pair.content.offsetWidth, pair.fixed.offsetWidth);
+ pair = addElements(`<input type=${type} placeholder="${LONG_TEXT}">`);
+ assert_greater_than(pair.content.offsetWidth, pair.fixed.offsetWidth);
+ }, `${type}: Auto width and auto height with a long text`);
+
+ test(() => {
+ let pair = addElements(`<input type=${type} style="width:20ch; height:2lh">`);
+ assert_equals(pair.content.offsetWidth, pair.fixed.offsetWidth);
+ assert_equals(pair.content.offsetHeight, pair.fixed.offsetHeight);
+
+ pair = addElements(`<input type=${type} style="width:20ch; height:2lh" value="${LONG_TEXT}">`);
+ assert_equals(pair.content.offsetWidth, pair.fixed.offsetWidth);
+ assert_equals(pair.content.offsetHeight, pair.fixed.offsetHeight);
+
+ pair = addElements(`<input type=${type} style="width:20ch; height:2lh" placeholder="${LONG_TEXT}">`);
+ assert_equals(pair.content.offsetWidth, pair.fixed.offsetWidth);
+ assert_equals(pair.content.offsetHeight, pair.fixed.offsetHeight);
+ }, `${type}: Explicit width and heigth`);
+
+ test(() => {
+ let pair = addElements(`<input type=${type} style="width:20ch">`);
+ assert_equals(pair.content.offsetWidth, pair.fixed.offsetWidth);
+ assert_equals(pair.content.offsetHeight, pair.fixed.offsetHeight);
+
+ pair = addElements(`<input type=${type} style="width:20ch" value="${LONG_TEXT}">`);
+ assert_equals(pair.content.offsetWidth, pair.fixed.offsetWidth);
+ assert_equals(pair.content.offsetHeight, pair.fixed.offsetHeight);
+
+ pair = addElements(`<input type=${type} style="width:20ch" placeholder="${LONG_TEXT}">`);
+ assert_equals(pair.content.offsetWidth, pair.fixed.offsetWidth);
+ assert_equals(pair.content.offsetHeight, pair.fixed.offsetHeight);
+ }, `${type}: Explicit width and auto height`);
+
+ test(() => {
+ let pair = addElements(`<input type=${type} style="height:2lh">`);
+ assert_less_than(pair.content.offsetWidth, pair.fixed.offsetWidth);
+ assert_equals(pair.content.offsetHeight, pair.fixed.offsetHeight);
+
+ pair = addElements(`<input type=${type} style="height:2lh" value="${LONG_TEXT}">`);
+ assert_greater_than(pair.content.offsetWidth, pair.fixed.offsetWidth);
+ assert_equals(pair.content.offsetHeight, pair.fixed.offsetHeight);
+
+ pair = addElements(`<input type=${type} style="height:2lh" placeholder="${LONG_TEXT}">`);
+ assert_greater_than(pair.content.offsetWidth, pair.fixed.offsetWidth);
+ assert_equals(pair.content.offsetHeight, pair.fixed.offsetHeight);
+ }, `${type}: Explicit height and auto width`);
+
+ test(() => {
+ let pair = addTwoElements(
+ `<input type=${type} class="disable-default small-placeholder">`,
+ `<input type=${type} class="disable-default small-placeholder" placeholder="foo bar">`);
+ assert_less_than(pair.e1.offsetWidth, pair.e2.offsetWidth);
+ assert_equals(pair.e1.offsetHeight, pair.e2.offsetHeight);
+ }, `${type}: Text caret is taller than the placeholder`);
+
+ test(() => {
+ let pair = addTwoElements(
+ `<input type=${type} class="disable-default large-placeholder">`,
+ `<input type=${type} class="disable-default large-placeholder" placeholder="foo bar">`);
+ assert_less_than(pair.e1.offsetWidth, pair.e2.offsetWidth);
+ assert_less_than(pair.e1.offsetHeight, pair.e2.offsetHeight);
+
+ pair = addTwoElements(
+ `<input type=${type} class="disable-default" style="font-size:40px; padding:16px">`,
+ `<input type=${type} class="disable-default large-placeholder"
+ placeholder="foo bar" style="font-size:40px; padding:16px">`);
+ assert_equals(pair.e1.offsetHeight, pair.e2.offsetHeight);
+ assert_equals(pair.e1.offsetTop, pair.e2.offsetTop);
+ }, `${type}: Text caret is shorter than the placeholder`);
+
+ test(() => {
+ const container = document.querySelector('#container');
+ container.innerHTML = `<input type=${type}>`;
+ const element = container.firstChild;
+ const w = element.offsetWidth;
+ const h = element.offsetHeight;
+ element.classList.add('disable-default');
+ assert_less_than(element.offsetWidth, w);
+ assert_equals(element.offsetHeight, h);
+ }, `${type}: Update field-sizing property dynamically`);
+
+});
+</script>
+</body>
diff --git a/testing/web-platform/tests/html/rendering/widgets/field-sizing-select.html b/testing/web-platform/tests/html/rendering/widgets/field-sizing-select.html
new file mode 100644
index 0000000000..d55898105e
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/widgets/field-sizing-select.html
@@ -0,0 +1,87 @@
+<!DOCTYPE html>
+<link rel="help" href="https://drafts.csswg.org/css-ui-4/#field-sizing">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<body>
+<style>
+.disable-default {
+ field-sizing: content;
+}
+</style>
+<div id="container"></div>
+<script>
+const container = document.querySelector('#container');
+const DISABLE = 'class="disable-default"';
+
+// Tests for drop-down box ====================================================
+
+test(() => {
+ const s = '<select>><option>1<option>quick brown<option>fox</select>';
+ container.innerHTML = s + s;
+ container.lastElementChild.style.fieldSizing = 'content';
+ const widthForContent1 = container.lastElementChild.offsetWidth;
+ assert_greater_than(container.firstElementChild.offsetWidth,
+ widthForContent1);
+ container.lastElementChild.selectedIndex = 1;
+ const widthForContentQuickBrown = container.lastElementChild.offsetWidth;
+ assert_greater_than(widthForContentQuickBrown, widthForContent1);
+}, 'dropdown: The width should depend on the selected OPTION');
+
+test(() => {
+ container.innerHTML = '<select><option>foo<option>quick brown fox</select>';
+ const select = container.firstElementChild;
+ const initialWidth = select.offsetWidth;
+ select.style.fieldSizing = 'content';
+ assert_less_than(select.offsetWidth, initialWidth);
+ select.style.fieldSizing = 'fixed';
+ assert_equals(select.offsetWidth, initialWidth);
+}, 'dropdown: Change the field-sizing value dynamically');
+
+// Tests for list box =========================================================
+
+// Some paltforms don't support list box rendering.
+container.innerHTML = '<select></select><select multiple></select>';
+if (container.firstElementChild.offsetHeight != container.lastElementChild.offsetHeight) {
+
+ test(() => {
+ container.innerHTML = `<select multiple><option>fox</select>` +
+ `<select multiple ${DISABLE}><option>fox</select>`;
+ const former = container.firstElementChild;
+ const latter = container.lastElementChild;
+ const widthForOneItem = latter.offsetWidth;
+ const heightForOneItem = latter.offsetHeight;
+ assert_equals(former.offsetWidth, widthForOneItem);
+ assert_greater_than(former.offsetHeight, heightForOneItem);
+
+ latter.add(new Option('quick brown'));
+ assert_greater_than(latter.offsetWidth, widthForOneItem);
+ assert_greater_than(latter.offsetHeight, heightForOneItem);
+ }, 'listbox: The size depend on the content');
+
+ test(() => {
+ container.innerHTML = `<select size="4"></select><select size="4" ${DISABLE}></select>`;
+ const former = container.firstElementChild;
+ const latter = container.lastElementChild;
+ const widthForZeroItem = latter.offsetWidth;
+ const heightForZeroItem = latter.offsetHeight;
+ assert_equals(former.offsetWidth, widthForZeroItem);
+ assert_greater_than(former.offsetHeight, heightForZeroItem);
+
+ latter.add(new Option('quick brown'));
+ assert_greater_than(latter.offsetWidth, widthForZeroItem);
+ assert_greater_than(latter.offsetHeight, heightForZeroItem);
+ }, 'listbox: The size attribute value is ignored');
+
+ test(() => {
+ container.innerHTML = '<select multiple><option>foo<option>quick brown fox</select>';
+ const select = container.firstElementChild;
+ const initialHeight = select.offsetHeight;
+ select.style.fieldSizing = 'content';
+ assert_less_than(select.offsetHeight, initialHeight);
+ select.style.fieldSizing = 'fixed';
+ assert_equals(select.offsetHeight, initialHeight);
+ }, 'listbox: Change the field-sizing value dynamically');
+
+}
+</script>
+</body>
diff --git a/testing/web-platform/tests/html/rendering/widgets/field-sizing-textarea.html b/testing/web-platform/tests/html/rendering/widgets/field-sizing-textarea.html
new file mode 100644
index 0000000000..f8d90dc659
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/widgets/field-sizing-textarea.html
@@ -0,0 +1,141 @@
+<!DOCTYPE html>
+<link rel="help" href="https://drafts.csswg.org/css-ui-4/#field-sizing">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<style>
+.disable-default {
+ field-sizing: content;
+}
+
+.small-placeholder {
+ font-size: 32px;
+}
+.small-placeholder::placeholder {
+ font-size: 16px;
+}
+
+.large-placeholder {
+ font-size: 20px;
+}
+.large-placeholder::placeholder {
+ font-size: 40px;
+}
+</style>
+<body>
+<div id="container"></div>
+<script>
+const DISABLE = 'class="disable-default"';
+const LONG_TEXT = 'The quick brown fox jumps over the lazy dog.';
+
+function addElements(source) {
+ const container = document.querySelector('#container');
+ container.innerHTML = source + source;
+ container.lastElementChild.classList.add('disable-default');
+ return {
+ fixed: container.firstElementChild,
+ content: container.lastElementChild
+ };
+}
+
+function addTwoElements(source1, source2) {
+ const container = document.querySelector('#container');
+ container.innerHTML = source1 + source2;
+ return {
+ e1: container.firstElementChild,
+ e2: container.lastElementChild
+ };
+}
+
+test(() => {
+ let pair = addElements('<textarea></textarea>');
+ // Historically a <textarea> has approximately 20ch x 2lh size by default.
+ // A <textarea> with field-sizing:content must be samller than the default.
+ assert_less_than(pair.content.offsetWidth, pair.fixed.offsetWidth);
+ assert_less_than(pair.content.offsetHeight, pair.fixed.offsetHeight);
+
+ pair = addTwoElements(`<textarea ${DISABLE}></textarea>`, `<textarea ${DISABLE}>foo</textarea>`);
+ assert_less_than(pair.e1.offsetWidth, pair.e2.offsetWidth);
+ assert_equals(pair.e1.offsetHeight, pair.e2.offsetHeight);
+}, 'Empty value');
+
+test(() => {
+ let pair = addElements('<textarea cols="10" rows="3"></textarea>');
+ assert_less_than(pair.content.offsetWidth, pair.fixed.offsetWidth);
+ assert_less_than(pair.content.offsetHeight, pair.fixed.offsetHeight);
+}, 'Empty value with cols/rows');
+
+test(() => {
+ let pair = addElements(`<textarea>${LONG_TEXT}</textarea>`);
+ assert_greater_than(pair.content.offsetWidth, pair.fixed.offsetWidth);
+ pair = addElements(`<textarea placeholder="${LONG_TEXT}"></textarea>`);
+ assert_greater_than(pair.content.offsetWidth, pair.fixed.offsetWidth);
+}, 'Auto width and auto height with a long text');
+
+test(() => {
+ let pair = addElements('<textarea style="width:20ch; height:2lh"></textarea>');
+ assert_equals(pair.content.offsetWidth, pair.fixed.offsetWidth);
+ assert_equals(pair.content.offsetHeight, pair.fixed.offsetHeight);
+
+ pair = addElements(`<textarea style="width:20ch; height:2lh">${LONG_TEXT}</textarea>`);
+ assert_equals(pair.content.offsetWidth, pair.fixed.offsetWidth);
+ assert_equals(pair.content.offsetHeight, pair.fixed.offsetHeight);
+
+ pair = addElements(`<textarea style="width:20ch; height:2lh" placeholder="${LONG_TEXT}"></textarea>`);
+ assert_equals(pair.content.offsetWidth, pair.fixed.offsetWidth);
+ assert_equals(pair.content.offsetHeight, pair.fixed.offsetHeight);
+}, 'Explicit width and heigth');
+
+test(() => {
+ let pair = addElements('<textarea style="width:20ch"></textarea>');
+ assert_equals(pair.content.offsetWidth, pair.fixed.offsetWidth);
+ assert_less_than(pair.content.offsetHeight, pair.fixed.offsetHeight);
+
+ pair = addElements(`<textarea style="width:20ch">${LONG_TEXT}</textarea>`);
+ assert_equals(pair.content.offsetWidth, pair.fixed.offsetWidth);
+ assert_greater_than(pair.content.offsetHeight, pair.fixed.offsetHeight);
+
+ pair = addElements(`<textarea style="width:20ch" placeholder="${LONG_TEXT}"></textarea>`);
+ assert_equals(pair.content.offsetWidth, pair.fixed.offsetWidth);
+ assert_greater_than(pair.content.offsetHeight, pair.fixed.offsetHeight);
+}, 'Explicit width and auto height');
+
+test(() => {
+ let pair = addElements('<textarea style="height:2lh"></textarea>');
+ assert_less_than(pair.content.offsetWidth, pair.fixed.offsetWidth);
+ assert_equals(pair.content.offsetHeight, pair.fixed.offsetHeight);
+
+ pair = addElements(`<textarea style="height:2lh">${LONG_TEXT}</textarea>`);
+ assert_greater_than(pair.content.offsetWidth, pair.fixed.offsetWidth);
+ assert_equals(pair.content.offsetHeight, pair.fixed.offsetHeight);
+
+ pair = addElements(`<textarea style="height:2lh" placeholder="${LONG_TEXT}"></textarea>`);
+ assert_greater_than(pair.content.offsetWidth, pair.fixed.offsetWidth);
+ assert_equals(pair.content.offsetHeight, pair.fixed.offsetHeight);
+}, 'Explicit height and auto width');
+
+test(() => {
+ let pair = addTwoElements(`<textarea class="disable-default small-placeholder"></textarea>`,
+ `<textarea class="disable-default small-placeholder" placeholder="foo"></textarea>`);
+ assert_less_than(pair.e1.offsetWidth, pair.e2.offsetWidth);
+ assert_equals(pair.e1.offsetHeight, pair.e2.offsetHeight);
+}, 'Text caret is taller than the placeholder');
+
+test(() => {
+ let pair = addTwoElements(`<textarea class="disable-default large-placeholder"></textarea>`,
+ `<textarea class="disable-default large-placeholder" placeholder="foo"></textarea>`);
+ assert_less_than(pair.e1.offsetWidth, pair.e2.offsetWidth, 'width');
+ assert_less_than(pair.e1.offsetHeight, pair.e2.offsetHeight, 'height');
+}, 'Text caret is shorter than the placeholder');
+
+test(() => {
+ const container = document.querySelector('#container');
+ container.innerHTML = '<textarea></textarea>';
+ const element = container.firstChild;
+ const w = element.offsetWidth;
+ const h = element.offsetHeight;
+ element.classList.add('disable-default');
+ assert_less_than(element.offsetWidth, w);
+ assert_less_than(element.offsetHeight, h);
+}, 'Update field-sizing property dynamically');
+</script>
+</body>
diff --git a/testing/web-platform/tests/html/rendering/widgets/input-checkbox-disabled-checked-notref.html b/testing/web-platform/tests/html/rendering/widgets/input-checkbox-disabled-checked-notref.html
new file mode 100644
index 0000000000..8caced027a
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/widgets/input-checkbox-disabled-checked-notref.html
@@ -0,0 +1,2 @@
+<!doctype html>
+<input type=checkbox disabled>
diff --git a/testing/web-platform/tests/html/rendering/widgets/input-checkbox-disabled-checked.html b/testing/web-platform/tests/html/rendering/widgets/input-checkbox-disabled-checked.html
new file mode 100644
index 0000000000..f72fdf62fd
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/widgets/input-checkbox-disabled-checked.html
@@ -0,0 +1,5 @@
+<!doctype html>
+<title>checkbox with disabled and checked attributes renders differently than unchecked</title>
+<link rel=help href="https://bugzilla.mozilla.org/show_bug.cgi?id=1735077">
+<link rel=mismatch href="input-checkbox-disabled-checked-notref.html">
+<input type=checkbox disabled checked>
diff --git a/testing/web-platform/tests/html/rendering/widgets/input-checkbox-no-centering.html b/testing/web-platform/tests/html/rendering/widgets/input-checkbox-no-centering.html
new file mode 100644
index 0000000000..7dba149c75
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/widgets/input-checkbox-no-centering.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1441341">
+<link rel="match" href="input-no-centering-ref.html">
+<style>
+input {
+ appearance: none;
+ margin: 0;
+ width: 200px;
+ height: 200px;
+}
+input:before {
+ content: "";
+ display: block;
+ width: 100px;
+ height: 100px;
+ background: green;
+}
+</style>
+<input type="checkbox">
diff --git a/testing/web-platform/tests/html/rendering/widgets/input-checkbox-switch-indeterminate-ref.html b/testing/web-platform/tests/html/rendering/widgets/input-checkbox-switch-indeterminate-ref.html
new file mode 100644
index 0000000000..cb9a76aa21
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/widgets/input-checkbox-switch-indeterminate-ref.html
@@ -0,0 +1,2 @@
+<!doctype html>
+<input type=checkbox switch>
diff --git a/testing/web-platform/tests/html/rendering/widgets/input-checkbox-switch-indeterminate.tentative.html b/testing/web-platform/tests/html/rendering/widgets/input-checkbox-switch-indeterminate.tentative.html
new file mode 100644
index 0000000000..bd4137c1b5
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/widgets/input-checkbox-switch-indeterminate.tentative.html
@@ -0,0 +1,7 @@
+<!doctype html>
+<title>Checkbox with switch attribute set does not render differently when the indeterminate attribute is set</title>
+<link rel=match href="input-checkbox-switch-indeterminate-ref.html">
+<input id="input" type=checkbox switch>
+<script>
+ input.indeterminate = true;
+</script>
diff --git a/testing/web-platform/tests/html/rendering/widgets/input-checkbox-switch-notref.html b/testing/web-platform/tests/html/rendering/widgets/input-checkbox-switch-notref.html
new file mode 100644
index 0000000000..75fff5d94f
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/widgets/input-checkbox-switch-notref.html
@@ -0,0 +1,4 @@
+<!doctype html>
+<input type=checkbox>
+<input type=checkbox>
+<input type=checkbox switch>
diff --git a/testing/web-platform/tests/html/rendering/widgets/input-checkbox-switch-ref.html b/testing/web-platform/tests/html/rendering/widgets/input-checkbox-switch-ref.html
new file mode 100644
index 0000000000..94aa1b7ecd
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/widgets/input-checkbox-switch-ref.html
@@ -0,0 +1,4 @@
+<!doctype html>
+<input type=checkbox switch>
+<input type=checkbox switch>
+<input type=checkbox>
diff --git a/testing/web-platform/tests/html/rendering/widgets/input-checkbox-switch-rtl-notref.html b/testing/web-platform/tests/html/rendering/widgets/input-checkbox-switch-rtl-notref.html
new file mode 100644
index 0000000000..02d57baf43
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/widgets/input-checkbox-switch-rtl-notref.html
@@ -0,0 +1 @@
+<input type=checkbox switch>
diff --git a/testing/web-platform/tests/html/rendering/widgets/input-checkbox-switch-rtl.tentative.html b/testing/web-platform/tests/html/rendering/widgets/input-checkbox-switch-rtl.tentative.html
new file mode 100644
index 0000000000..3e0c5d44c9
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/widgets/input-checkbox-switch-rtl.tentative.html
@@ -0,0 +1,3 @@
+<!doctype html>
+<link rel=mismatch href=input-checkbox-switch-rtl-notref.html>
+<input type=checkbox switch dir=rtl>
diff --git a/testing/web-platform/tests/html/rendering/widgets/input-checkbox-switch.tentative.html b/testing/web-platform/tests/html/rendering/widgets/input-checkbox-switch.tentative.html
new file mode 100644
index 0000000000..315728d539
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/widgets/input-checkbox-switch.tentative.html
@@ -0,0 +1,14 @@
+<!doctype html>
+<html class="reftest-wait">
+<title>Checkbox with switch attribute set renders differently than a checkbox without switch attribute</title>
+<link rel=match href="input-checkbox-switch-ref.html">
+<link rel=mismatch href="input-checkbox-switch-notref.html">
+<input type=checkbox switch>
+<input id='input2' type=checkbox>
+<input id='input3' type=checkbox switch>
+<script>
+ input2.setAttribute('switch','');
+ input3.removeAttribute('switch');
+ document.documentElement.classList.remove("reftest-wait");
+</script>
+</html>
diff --git a/testing/web-platform/tests/html/rendering/widgets/input-checkbox-switch.tentative.window.js b/testing/web-platform/tests/html/rendering/widgets/input-checkbox-switch.tentative.window.js
new file mode 100644
index 0000000000..84198eda10
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/widgets/input-checkbox-switch.tentative.window.js
@@ -0,0 +1,34 @@
+test(t => {
+ const input = document.body.appendChild(document.createElement("input"));
+ t.add_cleanup(() => input.remove());
+ input.type = "checkbox";
+ input.switch = true;
+ assert_equals(getComputedStyle(input).appearance, "auto");
+}, "Default appearance value");
+
+test(t => {
+ const input = document.body.appendChild(document.createElement("input"));
+ t.add_cleanup(() => input.remove());
+ input.type = "checkbox";
+ input.switch = true;
+ input.style.display = "none"
+ assert_equals(getComputedStyle(input).display, "none");
+}, "Default appearance value: display:none");
+
+test(t => {
+ const input = document.body.appendChild(document.createElement("input"));
+ t.add_cleanup(() => input.remove());
+ input.type = "checkbox";
+ input.switch = true;
+ input.style.appearance = "none";
+ assert_equals(getComputedStyle(input).appearance, "none");
+}, "appearance:none should work");
+
+test(t => {
+ const input = document.body.appendChild(document.createElement("input"));
+ t.add_cleanup(() => input.remove());
+ input.type = "checkbox";
+ input.switch = true;
+ input.style.appearance = "none";
+ assert_equals(getComputedStyle(input).display, "inline");
+}, "appearance:none should work: display gets its initial value");
diff --git a/testing/web-platform/tests/html/rendering/widgets/input-date-baseline-min-height-ref.html b/testing/web-platform/tests/html/rendering/widgets/input-date-baseline-min-height-ref.html
new file mode 100644
index 0000000000..249076a5b7
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/widgets/input-date-baseline-min-height-ref.html
@@ -0,0 +1,6 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>CSS Test Reference</title>
+<div>
+ abc <input type=date style="height: 40px"> def
+</div>
diff --git a/testing/web-platform/tests/html/rendering/widgets/input-date-baseline-min-height.html b/testing/web-platform/tests/html/rendering/widgets/input-date-baseline-min-height.html
new file mode 100644
index 0000000000..86b552ab80
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/widgets/input-date-baseline-min-height.html
@@ -0,0 +1,10 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>date input baseline should account for min-height</title>
+<link rel="match" href="input-date-baseline-min-height-ref.html">
+<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1825709">
+<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
+<link rel="author" title="Mozilla" href="https://mozilla.org">
+<div>
+ abc <input type=date style="min-height: 40px"> def
+</div>
diff --git a/testing/web-platform/tests/html/rendering/widgets/input-date-baseline-print.html b/testing/web-platform/tests/html/rendering/widgets/input-date-baseline-print.html
new file mode 100644
index 0000000000..dda06c69fb
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/widgets/input-date-baseline-print.html
@@ -0,0 +1,25 @@
+<!doctype html>
+<title>date input baseline shouldn't be insane when printing</title>
+<link rel="match" href="input-date-baseline-ref.html">
+<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1667510">
+<link rel="stylesheet" href="/fonts/ahem.css">
+<style>
+ div {
+ border: 1px solid black;
+ line-height: 0;
+ }
+
+ input {
+ height: 20px;
+ font: 20px/1 Ahem;
+ box-sizing: border-box;
+ padding: 1px; /* Needed to trigger the bug */
+ border: 0;
+ visibility: hidden;
+ -webkit-appearance: none;
+ appearance: none;
+ }
+</style>
+<div>
+ <input type="date">
+</div>
diff --git a/testing/web-platform/tests/html/rendering/widgets/input-date-baseline-ref.html b/testing/web-platform/tests/html/rendering/widgets/input-date-baseline-ref.html
new file mode 100644
index 0000000000..dcef656bad
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/widgets/input-date-baseline-ref.html
@@ -0,0 +1,16 @@
+<!doctype html>
+<title>Test reference</title>
+<link rel="stylesheet" href="/fonts/ahem.css">
+<style>
+ div {
+ border: 1px solid black;
+ line-height: 0;
+ }
+ span {
+ font: 20px/1 Ahem;
+ visibility: hidden;
+ }
+</style>
+<div>
+ <span>A</span>
+</div>
diff --git a/testing/web-platform/tests/html/rendering/widgets/input-date-baseline.html b/testing/web-platform/tests/html/rendering/widgets/input-date-baseline.html
new file mode 100644
index 0000000000..0d8f46c064
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/widgets/input-date-baseline.html
@@ -0,0 +1,25 @@
+<!doctype html>
+<title>date input baseline shouldn't be insane</title>
+<link rel="match" href="input-date-baseline-ref.html">
+<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1667510">
+<link rel="stylesheet" href="/fonts/ahem.css">
+<style>
+ div {
+ border: 1px solid black;
+ line-height: 0;
+ }
+
+ input {
+ height: 20px;
+ font: 20px/1 Ahem;
+ box-sizing: border-box;
+ padding: 1px; /* needed to trigger the bug */
+ border: 0;
+ visibility: hidden;
+ -webkit-appearance: none;
+ appearance: none;
+ }
+</style>
+<div>
+ <input type="date">
+</div>
diff --git a/testing/web-platform/tests/html/rendering/widgets/input-date-content-size-ref.html b/testing/web-platform/tests/html/rendering/widgets/input-date-content-size-ref.html
new file mode 100644
index 0000000000..18019c56b1
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/widgets/input-date-content-size-ref.html
@@ -0,0 +1,9 @@
+<!doctype html>
+<title>Test reference</title>
+<link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com">
+<link rel="author" href="https://mozilla.org" title="Mozilla">
+<body>
+ <input type="date">
+ <br>
+ <input type="date">
+</body>
diff --git a/testing/web-platform/tests/html/rendering/widgets/input-date-content-size.html b/testing/web-platform/tests/html/rendering/widgets/input-date-content-size.html
new file mode 100644
index 0000000000..d026771f3c
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/widgets/input-date-content-size.html
@@ -0,0 +1,11 @@
+<!doctype html>
+<title>Test: the date field's min-content and max-content sizes should be the same as its automatic size</title>
+<link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com">
+<link rel="author" href="https://mozilla.org" title="Mozilla">
+<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1695578">
+<link rel="match" href="input-date-content-size-ref.html">
+<body>
+ <input type="date" style="width: min-content">
+ <br>
+ <input type="date" style="width: max-content">
+</body>
diff --git a/testing/web-platform/tests/html/rendering/widgets/input-date-no-resize-on-hover.html b/testing/web-platform/tests/html/rendering/widgets/input-date-no-resize-on-hover.html
new file mode 100644
index 0000000000..74952ca239
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/widgets/input-date-no-resize-on-hover.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>Date input should not resize on hover when using web fonts</title>
+<link rel="help" href="https://crbug.com/1167555">
+<link rel="author" href="mailto:xiaochengh@chromium.org">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/testdriver.js"></script>
+<script src="/resources/testdriver-actions.js"></script>
+<script src="/resources/testdriver-vendor.js"></script>
+
+<input id="target" type="date" style="font-family: custom-font">
+
+<script>
+function mouseMoveToTarget(target) {
+ return new test_driver.Actions().pointerMove(0, 0, {origin: target}).send();
+}
+
+promise_test(async () => {
+ // Update layout before font loads
+ document.body.offsetWidth;
+
+ const font_sheet = document.createElement('style');
+ font_sheet.textContent = '@font-face { font-family: custom-font; src: url(/fonts/Revalia.woff) }';
+ document.body.appendChild(font_sheet);
+
+ await document.fonts.ready;
+
+ const target = document.getElementById('target');
+ const width_before_hover = target.offsetWidth;
+ await mouseMoveToTarget(target);
+ const width_after_hover = target.offsetWidth;
+ assert_equals(width_before_hover, width_after_hover);
+});
+</script>
diff --git a/testing/web-platform/tests/html/rendering/widgets/input-no-centering-ref.html b/testing/web-platform/tests/html/rendering/widgets/input-no-centering-ref.html
new file mode 100644
index 0000000000..5b2ea91fe5
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/widgets/input-no-centering-ref.html
@@ -0,0 +1,2 @@
+<!DOCTYPE html>
+<div style="width: 100px; height: 100px; background: green;"></div>
diff --git a/testing/web-platform/tests/html/rendering/widgets/input-radio-disabled-checked-notref.html b/testing/web-platform/tests/html/rendering/widgets/input-radio-disabled-checked-notref.html
new file mode 100644
index 0000000000..987e03cd92
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/widgets/input-radio-disabled-checked-notref.html
@@ -0,0 +1,2 @@
+<!doctype html>
+<input type=radio disabled>
diff --git a/testing/web-platform/tests/html/rendering/widgets/input-radio-disabled-checked.html b/testing/web-platform/tests/html/rendering/widgets/input-radio-disabled-checked.html
new file mode 100644
index 0000000000..3ac2a37199
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/widgets/input-radio-disabled-checked.html
@@ -0,0 +1,5 @@
+<!doctype html>
+<title>radio with disabled and checked attributes renders differently than unchecked</title>
+<link rel=help href="https://bugzilla.mozilla.org/show_bug.cgi?id=1735077">
+<link rel=mismatch href="input-radio-disabled-checked-notref.html">
+<input type=radio disabled checked>
diff --git a/testing/web-platform/tests/html/rendering/widgets/input-radio-no-centering.html b/testing/web-platform/tests/html/rendering/widgets/input-radio-no-centering.html
new file mode 100644
index 0000000000..6a714f8460
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/widgets/input-radio-no-centering.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<link rel="help" href="https://bugs.chromium.org/p/chromium/issues/detail?id=1441341">
+<link rel="match" href="input-no-centering-ref.html">
+<style>
+input {
+ appearance: none;
+ margin: 0;
+ width: 200px;
+ height: 200px;
+}
+input:before {
+ content: "";
+ display: block;
+ width: 100px;
+ height: 100px;
+ background: green;
+}
+</style>
+<input type="radio">
diff --git a/testing/web-platform/tests/html/rendering/widgets/input-text-size.html b/testing/web-platform/tests/html/rendering/widgets/input-text-size.html
new file mode 100644
index 0000000000..fb3008df08
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/widgets/input-text-size.html
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<link rel="help" href="https://html.spec.whatwg.org/C/#the-input-element-as-a-text-entry-widget">
+<title>Test `size` attribute behaivor</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<body>
+
+<input id="missing">
+<input id="invalid" size="-1">
+<input id="size0" size="0">
+<input id="size1" size="1">
+<input id="size10" size="10">
+<input id="size20" size="20">
+<input id="size21" size="21">
+<input id="computed" style="border:none; padding:0;" size="19">
+<input id="computedNone" style="display:none" size="17">
+
+<script>
+test(() => {
+ assert_equals(missing.offsetWidth, size20.offsetWidth);
+}, 'A misssing attribute is equivalent to size=20');
+
+test(() => {
+ assert_equals(invalid.offsetWidth, size20.offsetWidth, 'size="-1"');
+ assert_equals(size0.offsetWidth, size20.offsetWidth, 'size="0"');
+}, 'An invalid attribute value is equivalent to size=20');
+
+test(() => {
+ assert_less_than(size1.offsetWidth, size10.offsetWidth, '1 < 10');
+ assert_less_than(size10.offsetWidth, size20.offsetWidth, '10 < 20');
+ assert_less_than(size20.offsetWidth, size21.offsetWidth, '20 < 21');
+}, 'The width depends on a size attribute');
+
+test(() => {
+ const computedString = getComputedStyle(computed).width;
+ assert_equals(computed.offsetWidth,
+ parseInt(computedString.substring(0, computedString.length - 2)));
+}, 'Size attribute value affects layout-dependent computed style');
+
+test(() => {
+ const computedString = getComputedStyle(computedNone).width;
+ assert_equals(computedString, 'auto');
+}, 'Size attribute value is not a presentational hint');
+</script>
+
diff --git a/testing/web-platform/tests/html/rendering/widgets/input-time-content-size-ref.html b/testing/web-platform/tests/html/rendering/widgets/input-time-content-size-ref.html
new file mode 100644
index 0000000000..938d2659a8
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/widgets/input-time-content-size-ref.html
@@ -0,0 +1,9 @@
+<!doctype html>
+<title>Test reference</title>
+<link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com">
+<link rel="author" href="https://mozilla.org" title="Mozilla">
+<body>
+ <input type="time">
+ <br>
+ <input type="time">
+</body>
diff --git a/testing/web-platform/tests/html/rendering/widgets/input-time-content-size.html b/testing/web-platform/tests/html/rendering/widgets/input-time-content-size.html
new file mode 100644
index 0000000000..4a378f6923
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/widgets/input-time-content-size.html
@@ -0,0 +1,11 @@
+<!doctype html>
+<title>Test: the time field's min-content and max-content sizes should be the same as its automatic size</title>
+<link rel="author" title="Daniel Holbert" href="mailto:dholbert@mozilla.com">
+<link rel="author" href="https://mozilla.org" title="Mozilla">
+<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1695578">
+<link rel="match" href="input-time-content-size-ref.html">
+<body>
+ <input type="time" style="width: min-content">
+ <br>
+ <input type="time" style="width: max-content">
+</body>
diff --git a/testing/web-platform/tests/html/rendering/widgets/select-wrap-no-spill.optional.html b/testing/web-platform/tests/html/rendering/widgets/select-wrap-no-spill.optional.html
new file mode 100644
index 0000000000..84aa5602ac
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/widgets/select-wrap-no-spill.optional.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<body>
+<table>
+<tr><td id="target">
+<select style="width:80px; white-space:pre-wrap;">
+<option>ab option with a very long text that does not fit but should not spill</option>
+</select>
+<tr><td id="reference"><select style="width:80px;">
+<option>ab option with a very long text that does not fit but should not spill</option>
+</select>
+</table>
+<script>
+// crbug.com/924929
+test(() => {
+ assert_equals(document.querySelector('#target').offsetHeight,
+ document.querySelector('#reference').offsetHeight);
+}, 'Selected OPTION label with white-space:pre-wrap should not spill out.');
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/rendering/widgets/textarea-cols-rows.html b/testing/web-platform/tests/html/rendering/widgets/textarea-cols-rows.html
new file mode 100644
index 0000000000..6ad24a2eb8
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/widgets/textarea-cols-rows.html
@@ -0,0 +1,64 @@
+<!DOCTYPE html>
+<link rel="help" href="https://html.spec.whatwg.org/C/#the-textarea-element-2">
+<title>Test `cols` `rows` attributes behaivor</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<body>
+
+<textarea id="missing"></textarea>
+<textarea id="invalid" cols="-1" rows="-1"></textarea>
+<textarea id="computed" style="border:none; padding:0;" cols="19" rows="5"></textarea>
+<textarea id="computedNone" style="display:none" cols="17" rows="7"></textarea>
+
+<textarea id="cols0" cols="0"></textarea>
+<textarea id="cols1" cols="1"></textarea>
+<textarea id="cols10" cols="10"></textarea>
+<textarea id="cols20" cols="20"></textarea>
+<textarea id="cols21" cols="21"></textarea>
+
+<textarea id="rows0" rows="0"></textarea>
+<textarea id="rows1" rows="1"></textarea>
+<textarea id="rows2" rows="2"></textarea>
+<textarea id="rows3" rows="3"></textarea>
+
+<script>
+test(() => {
+ assert_equals(missing.offsetWidth, cols20.offsetWidth);
+ assert_equals(missing.offsetHeight, rows2.offsetHeight);
+}, 'A misssing attribute is equivalent to cols=20 rows=2');
+
+test(() => {
+ assert_equals(invalid.offsetWidth, cols20.offsetWidth);
+ assert_equals(invalid.offsetHeight, rows2.offsetHeight);
+ assert_equals(cols0.offsetWidth, cols20.offsetWidth);
+ assert_equals(rows0.offsetHeight, rows2.offsetHeight);
+}, 'An invalid attribute value is equivalent to cols=20 rows=2');
+
+test(() => {
+ assert_less_than(cols1.offsetWidth, cols10.offsetWidth, '1 < 10');
+ assert_less_than(cols10.offsetWidth, cols20.offsetWidth, '10 < 20');
+ assert_less_than(cols20.offsetWidth, cols21.offsetWidth, '20 < 21');
+}, 'The width depends on a cols attribute');
+
+test(() => {
+ assert_less_than(rows1.offsetHeight, rows2.offsetHeight, '1 < 2');
+ assert_less_than(rows2.offsetHeight, rows3.offsetHeight, '2 < 3');
+}, 'The height depends on a rows attribute');
+
+test(() => {
+ const computedWidth = getComputedStyle(computed).width;
+ assert_equals(computed.offsetWidth,
+ parseInt(computedWidth.substring(0, computedWidth.length - 2)));
+
+ const computedHeight = getComputedStyle(computed).height;
+ assert_equals(computed.offsetHeight,
+ parseInt(computedHeight.substring(0, computedHeight.length - 2)));
+}, 'Cols/rows attribute values affect layout-dependent computed style');
+
+test(() => {
+ const computedNoneStyle = getComputedStyle(computedNone);
+ assert_equals(computedNoneStyle.width, 'auto');
+ assert_equals(computedNoneStyle.height, 'auto');
+}, 'Cols/rows attribute values are not presentational hints');
+</script>
+
diff --git a/testing/web-platform/tests/html/rendering/widgets/the-select-element/option-add-label-quirks.html b/testing/web-platform/tests/html/rendering/widgets/the-select-element/option-add-label-quirks.html
new file mode 100644
index 0000000000..2c3c8093e2
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/widgets/the-select-element/option-add-label-quirks.html
@@ -0,0 +1,20 @@
+<meta charset="utf-8">
+<title>OPTION's label attribute in SELECT -- Adding a label (quirks)</title>
+<link rel="help" href="https://html.spec.whatwg.org/multipage/rendering.html#the-select-element-2">
+<link rel="match" href="option-label-ref.html">
+<meta name="assert" content="An option element is expected to be rendered by displaying the element's label.">
+
+<select>
+ <option>Element Text</option>
+</select>
+<br/>
+<select size="4">
+ <option>Element Text</option>
+</select>
+<script>
+let options = document.querySelectorAll("option");
+options[0].getBoundingClientRect(); // force layout.
+for (let option of options) {
+ option.setAttribute("label", "Label Text");
+}
+</script>
diff --git a/testing/web-platform/tests/html/rendering/widgets/the-select-element/option-add-label.html b/testing/web-platform/tests/html/rendering/widgets/the-select-element/option-add-label.html
new file mode 100644
index 0000000000..5110164c31
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/widgets/the-select-element/option-add-label.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>OPTION's label attribute in SELECT -- Adding a label</title>
+<link rel="help" href="https://html.spec.whatwg.org/multipage/rendering.html#the-select-element-2">
+<link rel="match" href="option-label-ref.html">
+<meta name="assert" content="An option element is expected to be rendered by displaying the element's label.">
+
+<select>
+ <option>Element Text</option>
+</select>
+<br/>
+<select size="4">
+ <option>Element Text</option>
+</select>
+<script>
+let options = document.querySelectorAll("option");
+options[0].getBoundingClientRect(); // force layout.
+for (let option of options) {
+ option.setAttribute("label", "Label Text");
+}
+</script>
diff --git a/testing/web-platform/tests/html/rendering/widgets/the-select-element/option-checked-styling-ref.html b/testing/web-platform/tests/html/rendering/widgets/the-select-element/option-checked-styling-ref.html
new file mode 100644
index 0000000000..92504a47b5
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/widgets/the-select-element/option-checked-styling-ref.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>Stylability of select>option with :checked pseudo</title>
+<link rel="author" href="mailto:masonf@chromium.org">
+
+<style>
+ option {
+ color: black;
+ }
+ #option2 {
+ background-color: red;
+ }
+ #option1 {
+ background: green;
+ }
+</style>
+
+<select id=select size=3 multiple>
+ <option id=option1>Option #1 (should be green)</option>
+ <option id=option2>Option #2 (should be red)</option>
+</select>
diff --git a/testing/web-platform/tests/html/rendering/widgets/the-select-element/option-checked-styling.html b/testing/web-platform/tests/html/rendering/widgets/the-select-element/option-checked-styling.html
new file mode 100644
index 0000000000..216b03a88a
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/widgets/the-select-element/option-checked-styling.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>Stylability of select>option with :checked pseudo</title>
+<link rel="author" href="mailto:masonf@chromium.org">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/form-elements.html#the-select-element">
+<link rel="match" href="option-checked-styling-ref.html">
+
+<style>
+ option {
+ color: black;
+ background-color: red;
+ }
+ option:checked {
+ background: green;
+ }
+</style>
+
+<select id=select size=3 multiple>
+ <option id=option1 selected>Option #1 (should be green)</option>
+ <option id=option2>Option #2 (should be red)</option>
+</select>
diff --git a/testing/web-platform/tests/html/rendering/widgets/the-select-element/option-empty-label-to-empty-string.html b/testing/web-platform/tests/html/rendering/widgets/the-select-element/option-empty-label-to-empty-string.html
new file mode 100644
index 0000000000..c8aa4d20b2
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/widgets/the-select-element/option-empty-label-to-empty-string.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>OPTION's label attribute in SELECT -- Adding a label</title>
+<link rel="help" href="https://html.spec.whatwg.org/multipage/rendering.html#the-select-element-2">
+<link rel="match" href="option-label-ref.html">
+<meta name="assert" content="An option element is expected to be rendered by displaying the element's label.">
+
+<select>
+ <option label="Element Text">Label Text</option>
+</select>
+<br/>
+<select size="4">
+ <option label="Element Text">Label Text</option>
+</select>
+<script>
+let options = document.querySelectorAll("option");
+options[0].getBoundingClientRect(); // force layout.
+for (let option of options) {
+ option.setAttribute("label", "");
+}
+</script>
diff --git a/testing/web-platform/tests/html/rendering/widgets/the-select-element/option-empty-label.html b/testing/web-platform/tests/html/rendering/widgets/the-select-element/option-empty-label.html
new file mode 100644
index 0000000000..a34c41d299
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/widgets/the-select-element/option-empty-label.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>OPTION's label attribute in SELECT -- Empty label uses Element text</title>
+<link rel="help" href="https://html.spec.whatwg.org/multipage/rendering.html#the-select-element-2">
+<link rel="match" href="option-label-ref.html">
+<meta name="assert" content="An option element is expected to be rendered by displaying the element's label.">
+
+<select>
+ <option label>Label Text</option>
+</select>
+<br/>
+<select size="4">
+ <option label>Label Text</option>
+</select>
diff --git a/testing/web-platform/tests/html/rendering/widgets/the-select-element/option-label-and-text.html b/testing/web-platform/tests/html/rendering/widgets/the-select-element/option-label-and-text.html
new file mode 100644
index 0000000000..152bfdcb6a
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/widgets/the-select-element/option-label-and-text.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>OPTION's label attribute in SELECT - Prefers label over element text</title>
+<link rel="help" href="https://html.spec.whatwg.org/multipage/rendering.html#the-select-element-2">
+<link rel="match" href="option-label-ref.html">
+<meta name="assert" content="An option element is expected to be rendered by displaying the element's label.">
+
+<select>
+ <option label="Label Text">Element Text</option>
+</select>
+<br/>
+<select size="4">
+ <option label="Label Text">Element Text</option>
+</select>
diff --git a/testing/web-platform/tests/html/rendering/widgets/the-select-element/option-label-ref.html b/testing/web-platform/tests/html/rendering/widgets/the-select-element/option-label-ref.html
new file mode 100644
index 0000000000..3dd07b8dc2
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/widgets/the-select-element/option-label-ref.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>OPTION's label attribute in SELECT (reference)</title>
+<link rel="help" href="https://html.spec.whatwg.org/multipage/rendering.html#the-select-element-2">
+
+<select>
+ <option>Label Text</option>
+</select>
+<br/>
+<select size="4">
+ <option>Label Text</option>
+</select>
diff --git a/testing/web-platform/tests/html/rendering/widgets/the-select-element/option-only-label.html b/testing/web-platform/tests/html/rendering/widgets/the-select-element/option-only-label.html
new file mode 100644
index 0000000000..5e3c06cd66
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/widgets/the-select-element/option-only-label.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>OPTION's label attribute in SELECT -- Only a label</title>
+<link rel="help" href="https://html.spec.whatwg.org/multipage/rendering.html#the-select-element-2">
+<link rel="match" href="option-label-ref.html">
+<meta name="assert" content="An option element is expected to be rendered by displaying the element's label.">
+
+<select>
+ <option label="Label Text"></option>
+</select>
+<br/>
+<select size="4">
+ <option label="Label Text"></option>
+</select>
diff --git a/testing/web-platform/tests/html/rendering/widgets/the-select-element/option-rm-label.html b/testing/web-platform/tests/html/rendering/widgets/the-select-element/option-rm-label.html
new file mode 100644
index 0000000000..a5272cf6f1
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/widgets/the-select-element/option-rm-label.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>OPTION's label attribute in SELECT -- Removing the label</title>
+<link rel="help" href="https://html.spec.whatwg.org/multipage/rendering.html#the-select-element-2">
+<link rel="match" href="option-label-ref.html">
+<meta name="assert" content="An option element is expected to be rendered by displaying the element's label.">
+
+<select>
+ <option label="Bad Label Text">Label Text</option>
+</select>
+<br/>
+<select size="4">
+ <option label="Bad Label Text">Label Text</option>
+</select>
+<script>
+let options = document.querySelectorAll("option");
+options[0].getBoundingClientRect(); // force layout.
+for (let option of options) {
+ option.removeAttribute("label");
+}
+</script>
diff --git a/testing/web-platform/tests/html/rendering/widgets/the-select-element/select-as-listbox-default-styles.tentative.html b/testing/web-platform/tests/html/rendering/widgets/the-select-element/select-as-listbox-default-styles.tentative.html
new file mode 100644
index 0000000000..3e9b001f99
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/widgets/the-select-element/select-as-listbox-default-styles.tentative.html
@@ -0,0 +1,113 @@
+<!doctype html>
+<title>default styles for select as a listbox</title>
+<meta name="viewport" content="width=device-width">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/rendering/support/test-ua-stylesheet.js"></script>
+<style>
+/* Specify this bogus namespace, so the rules in this stylesheet only apply to the `fakeClone`d elements in #refs, not the HTML elements in #tests. */
+@namespace url(urn:not-html);
+
+select {
+ letter-spacing: initial;
+ word-spacing: initial;
+ line-height: initial;
+ text-transform: initial;
+ text-indent: initial;
+ text-shadow: initial;
+ appearance: auto;
+}
+
+select {
+ text-align: initial;
+}
+
+select {
+ box-sizing: border-box;
+}
+
+/* When the element renders as a list box, it is a devolvable widget expected to render as an 'inline-block' box whose 'height' is the height necessary to contain as many rows for items as given by the element's display size, or four rows if the attribute is absent, and whose 'width' is the width of the select's labels plus the width of a scrollbar. */
+select {
+ display: inline-block;
+}
+
+</style>
+
+<style>
+/* non-initial styles on parent to test 'initial' in UA stylesheet */
+#tests, #refs {
+ letter-spacing: 1px;
+ word-spacing: 1px;
+ line-height: 20px;
+ text-transform: lowercase;
+ text-indent: 1px;
+ text-shadow: 0px 0px;
+ text-align: justify;
+}
+</style>
+
+<div id="log"></div>
+
+<div id="tests">
+
+ <select multiple><option>1</option><optgroup label=2><option>3</select>
+
+</div>
+
+<div id="refs"></div>
+
+<script>
+ const props = [
+ 'display',
+ 'margin-top',
+ 'margin-right',
+ 'margin-bottom',
+ 'margin-left',
+ 'padding-top',
+ 'padding-right',
+ 'padding-bottom',
+ 'padding-left',
+ 'letter-spacing',
+ 'word-spacing',
+ 'text-transform',
+ 'text-indent',
+ 'text-shadow',
+ 'appearance',
+ 'box-sizing',
+ 'border-top-width',
+ 'border-right-width',
+ 'border-bottom-width',
+ 'border-left-width',
+ 'border-top-style',
+ 'border-right-style',
+ 'border-bottom-style',
+ 'border-left-style',
+ 'border-top-color',
+ 'border-right-color',
+ 'border-bottom-color',
+ 'border-left-color',
+ 'align-items',
+ 'white-space',
+ 'color',
+ 'background-color',
+ 'cursor',
+ 'font-style',
+ 'font-weight',
+ 'font-size',
+ 'font-family',
+ 'writing-mode',
+ 'scrollbar-width',
+ 'overflow',
+ 'vertical-align',
+ 'user-select',
+ 'page-break-inside',
+ 'overflow-clip-box',
+ 'font-variant-ligatures',
+ 'font-variant-caps',
+ 'font-variant-numeric',
+ 'font-variant-east-asian',
+ 'text-rendering',
+ ];
+ runUAStyleTests(props);
+
+</script>
diff --git a/testing/web-platform/tests/html/rendering/widgets/the-select-element/select-invalidation-ref.html b/testing/web-platform/tests/html/rendering/widgets/the-select-element/select-invalidation-ref.html
new file mode 100644
index 0000000000..7a3dd1d50d
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/widgets/the-select-element/select-invalidation-ref.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>Select rendering invalidation</title>
+<link rel="author" href="mailto:masonf@chromium.org">
+
+<style>
+ select {
+ color: lime;
+ }
+</style>
+
+<select id=select>
+ <option>The down arrow should be green</option>
+ <option>value B</option>
+</select>
diff --git a/testing/web-platform/tests/html/rendering/widgets/the-select-element/select-invalidation.html b/testing/web-platform/tests/html/rendering/widgets/the-select-element/select-invalidation.html
new file mode 100644
index 0000000000..199db0b7aa
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/widgets/the-select-element/select-invalidation.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<meta charset="utf-8">
+<title>Select rendering invalidation</title>
+<link rel="author" href="mailto:masonf@chromium.org">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/form-elements.html#the-select-element">
+<link rel="match" href="select-invalidation-ref.html">
+
+<style>
+ select {
+ color: red;
+ }
+</style>
+
+<select id=select>
+ <option>The down arrow should be green</option>
+ <option>value B</option>
+</select>
+
+<script>
+ requestAnimationFrame(() => {
+ requestAnimationFrame(() => {
+ select.style.color = "lime";
+ requestAnimationFrame(() => {
+ requestAnimationFrame(() => {
+ document.documentElement.classList.remove("reftest-wait");
+ });
+ });
+ });
+ });
+</script>
diff --git a/testing/web-platform/tests/html/rendering/widgets/the-select-element/select-size-001.html b/testing/web-platform/tests/html/rendering/widgets/the-select-element/select-size-001.html
new file mode 100644
index 0000000000..ad4055415d
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/widgets/the-select-element/select-size-001.html
@@ -0,0 +1,11 @@
+<!doctype html>
+<title>select size=1 renders the same as plain select</title>
+<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1643279">
+<link rel="author" title="Mozilla" href="https://mozilla.org">
+<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
+<link rel="match" href="select-size-ref.html">
+<select size="1">
+ <option value ="1">1</option>
+ <option value ="2">2</option>
+ <option value ="3">3</option>
+</select>
diff --git a/testing/web-platform/tests/html/rendering/widgets/the-select-element/select-size-002.html b/testing/web-platform/tests/html/rendering/widgets/the-select-element/select-size-002.html
new file mode 100644
index 0000000000..0838e7a3c6
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/widgets/the-select-element/select-size-002.html
@@ -0,0 +1,11 @@
+<!doctype html>
+<title>select size=0 renders the same as plain select</title>
+<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1643279">
+<link rel="author" title="Mozilla" href="https://mozilla.org">
+<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io">
+<link rel="match" href="select-size-ref.html">
+<select size="0">
+ <option value ="1">1</option>
+ <option value ="2">2</option>
+ <option value ="3">3</option>
+</select>
diff --git a/testing/web-platform/tests/html/rendering/widgets/the-select-element/select-size-ref.html b/testing/web-platform/tests/html/rendering/widgets/the-select-element/select-size-ref.html
new file mode 100644
index 0000000000..fc3b3be6e5
--- /dev/null
+++ b/testing/web-platform/tests/html/rendering/widgets/the-select-element/select-size-ref.html
@@ -0,0 +1,7 @@
+<!doctype html>
+<title>Test reference.</title>
+<select>
+ <option value ="1">1</option>
+ <option value ="2">2</option>
+ <option value ="3">3</option>
+</select>