summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/html/semantics
diff options
context:
space:
mode:
Diffstat (limited to 'testing/web-platform/tests/html/semantics')
-rw-r--r--testing/web-platform/tests/html/semantics/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/common-idioms/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/common-idioms/conversations/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/common-idioms/footnotes/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/common-idioms/rel-up/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/common-idioms/tag-clouds/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/common-idioms/the-main-part-of-the-content/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/disabled-elements/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/disabled-elements/disabledElement.html44
-rw-r--r--testing/web-platform/tests/html/semantics/document-metadata/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/document-metadata/styling/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/document-metadata/styling/LinkStyle.html72
-rw-r--r--testing/web-platform/tests/html/semantics/document-metadata/styling/support/alternate.css7
-rw-r--r--testing/web-platform/tests/html/semantics/document-metadata/styling/support/emptytitle.css4
-rw-r--r--testing/web-platform/tests/html/semantics/document-metadata/styling/support/normal.css5
-rw-r--r--testing/web-platform/tests/html/semantics/document-metadata/styling/support/notitle.css4
-rw-r--r--testing/web-platform/tests/html/semantics/document-metadata/styling/support/unmatch.css4
-rw-r--r--testing/web-platform/tests/html/semantics/document-metadata/the-base-element/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/document-metadata/the-base-element/base_about_blank.html19
-rw-r--r--testing/web-platform/tests/html/semantics/document-metadata/the-base-element/base_href_empty.html29
-rw-r--r--testing/web-platform/tests/html/semantics/document-metadata/the-base-element/base_href_invalid.html12
-rw-r--r--testing/web-platform/tests/html/semantics/document-metadata/the-base-element/base_href_specified.sub.html33
-rw-r--r--testing/web-platform/tests/html/semantics/document-metadata/the-base-element/base_href_unspecified.html30
-rw-r--r--testing/web-platform/tests/html/semantics/document-metadata/the-base-element/base_multiple.html29
-rw-r--r--testing/web-platform/tests/html/semantics/document-metadata/the-base-element/base_srcdoc.html19
-rw-r--r--testing/web-platform/tests/html/semantics/document-metadata/the-base-element/example.html7
-rw-r--r--testing/web-platform/tests/html/semantics/document-metadata/the-base-element/example2.html5
-rw-r--r--testing/web-platform/tests/html/semantics/document-metadata/the-head-element/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/document-metadata/the-link-element/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/document-metadata/the-link-element/document-without-browsing-context.html35
-rw-r--r--testing/web-platform/tests/html/semantics/document-metadata/the-link-element/link-load-event.html18
-rw-r--r--testing/web-platform/tests/html/semantics/document-metadata/the-link-element/link-rellist.html25
-rw-r--r--testing/web-platform/tests/html/semantics/document-metadata/the-link-element/link-style-error-01.html48
-rw-r--r--testing/web-platform/tests/html/semantics/document-metadata/the-link-element/resources/stylesheet.css3
-rw-r--r--testing/web-platform/tests/html/semantics/document-metadata/the-link-element/style.css3
-rw-r--r--testing/web-platform/tests/html/semantics/document-metadata/the-link-element/stylesheet-with-base-ref.html11
-rw-r--r--testing/web-platform/tests/html/semantics/document-metadata/the-link-element/stylesheet-with-base.html11
-rw-r--r--testing/web-platform/tests/html/semantics/document-metadata/the-link-element/stylesheet.css3
-rw-r--r--testing/web-platform/tests/html/semantics/document-metadata/the-link-element/stylesheet.py9
-rw-r--r--testing/web-platform/tests/html/semantics/document-metadata/the-meta-element/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/document-metadata/the-meta-element/contains.json22
-rw-r--r--testing/web-platform/tests/html/semantics/document-metadata/the-meta-element/pragma-directives/attr-meta-http-equiv-refresh/parsing.html112
-rw-r--r--testing/web-platform/tests/html/semantics/document-metadata/the-meta-element/pragma-directives/attr-meta-http-equiv-refresh/support/;url=foo1
-rw-r--r--testing/web-platform/tests/html/semantics/document-metadata/the-meta-element/pragma-directives/attr-meta-http-equiv-refresh/support/__dir__.headers1
-rw-r--r--testing/web-platform/tests/html/semantics/document-metadata/the-meta-element/pragma-directives/attr-meta-http-equiv-refresh/support/foo1
-rw-r--r--testing/web-platform/tests/html/semantics/document-metadata/the-meta-element/pragma-directives/attr-meta-http-equiv-refresh/support/foo'bar1
-rw-r--r--testing/web-platform/tests/html/semantics/document-metadata/the-meta-element/pragma-directives/attr-meta-http-equiv-refresh/support/refresh.sub.html1
-rw-r--r--testing/web-platform/tests/html/semantics/document-metadata/the-meta-element/pragma-directives/attr-meta-http-equiv-refresh/support/ufoo1
-rw-r--r--testing/web-platform/tests/html/semantics/document-metadata/the-meta-element/pragma-directives/attr-meta-http-equiv-refresh/support/urfoo1
-rw-r--r--testing/web-platform/tests/html/semantics/document-metadata/the-meta-element/pragma-directives/attr-meta-http-equiv-refresh/support/url foo1
-rw-r--r--testing/web-platform/tests/html/semantics/document-metadata/the-meta-element/pragma-directives/attr-meta-http-equiv-refresh/support/urlfoo1
-rw-r--r--testing/web-platform/tests/html/semantics/document-metadata/the-meta-element/pragma-directives/attr-meta-http-equiv-refresh/support/x;url=foo1
-rw-r--r--testing/web-platform/tests/html/semantics/document-metadata/the-meta-element/the-lang-attribute-012.html51
-rw-r--r--testing/web-platform/tests/html/semantics/document-metadata/the-style-element/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/document-metadata/the-style-element/historical.html14
-rw-r--r--testing/web-platform/tests/html/semantics/document-metadata/the-style-element/html_style_in_comment-ref.html18
-rw-r--r--testing/web-platform/tests/html/semantics/document-metadata/the-style-element/html_style_in_comment.xhtml18
-rw-r--r--testing/web-platform/tests/html/semantics/document-metadata/the-style-element/style-error-01.html32
-rw-r--r--testing/web-platform/tests/html/semantics/document-metadata/the-style-element/style_disabled.html39
-rw-r--r--testing/web-platform/tests/html/semantics/document-metadata/the-style-element/style_events.html36
-rw-r--r--testing/web-platform/tests/html/semantics/document-metadata/the-style-element/style_media.html40
-rw-r--r--testing/web-platform/tests/html/semantics/document-metadata/the-title-element/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/document-metadata/the-title-element/title.text-01.html25
-rw-r--r--testing/web-platform/tests/html/semantics/document-metadata/the-title-element/title.text-02.xhtml30
-rw-r--r--testing/web-platform/tests/html/semantics/document-metadata/the-title-element/title.text-03.html32
-rw-r--r--testing/web-platform/tests/html/semantics/document-metadata/the-title-element/title.text-04.xhtml37
-rw-r--r--testing/web-platform/tests/html/semantics/edits/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/edits/attributes-common-to-ins-and-del-elements/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/edits/edits-and-lists/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/edits/edits-and-paragraphs/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/edits/edits-and-tables/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/edits/the-del-element/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/edits/the-del-element/del_effect.html19
-rw-r--r--testing/web-platform/tests/html/semantics/edits/the-ins-element/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/edits/the-ins-element/ins_effect.html19
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/dimension-attributes/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/image-maps/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/image-maps/contains.json10
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/mathml/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/audio_controls_present-manual.html14
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/audio_loop_base.html42
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/audio_muted_overriding_volume-manual.html21
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/audio_muted_present-manual.html20
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/audio_volume_check.html58
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/audio_volume_loudest-manual.html21
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/audio_volume_silent-manual.html21
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/contains.json132
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/error-codes/error.html38
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_canplay.html38
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_canplay_noautoplay.html36
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_canplaythrough.html38
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_canplaythrough_noautoplay.html36
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_loadeddata.html38
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_loadeddata_noautoplay.html36
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_loadedmetadata.html38
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_loadedmetadata_noautoplay.html36
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_loadstart.html38
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_loadstart_noautoplay.html36
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_order_canplay_canplaythrough.html52
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_order_canplay_playing.html52
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_order_loadedmetadata_loadeddata.html52
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_order_loadstart_progress.html52
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_pause.html48
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_pause_noautoplay.html40
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_play.html38
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_play_noautoplay.html40
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_playing.html38
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_playing_noautoplay.html40
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_progress.html38
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_progress_noautoplay.html36
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_timeupdate.html34
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_timeupdate_noautoplay.html40
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_volumechange.html72
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/historical.html53
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/HTMLElement/HTMLMediaElement/addTextTrack.html116
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/HTMLElement/HTMLMediaElement/textTracks.html13
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/HTMLElement/HTMLTrackElement/default.html55
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/HTMLElement/HTMLTrackElement/kind.html146
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/HTMLElement/HTMLTrackElement/label.html83
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/HTMLElement/HTMLTrackElement/readyState.html11
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/HTMLElement/HTMLTrackElement/src.html43
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/HTMLElement/HTMLTrackElement/srclang.html82
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/HTMLElement/HTMLTrackElement/track.html12
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrack/activeCues.html104
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrack/addCue.html68
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrack/constants.html23
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrack/cues.html100
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrack/kind.html31
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrack/label.html29
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrack/language.html29
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrack/mode.html55
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrack/oncuechange.html33
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrack/removeCue.html50
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrackCue/endTime.html39
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrackCue/id.html39
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrackCue/onenter.html36
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrackCue/onexit.html36
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrackCue/pauseOnExit.html40
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrackCue/startTime.html39
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrackCue/track.html38
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrackCueList/getCueById.html53
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrackCueList/getter.html49
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrackCueList/length.html22
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrackList/getTrackById.html16
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrackList/getter.html32
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrackList/length.html18
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrackList/onaddtrack.html33
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrackList/onremovetrack.html33
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TrackEvent/constructor.html24
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TrackEvent/createEvent.html15
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/autoplay-overrides-preload.html28
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/load-events-networkState.html67
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/load-removes-queued-error-event.html44
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-candidate-insert-before.html29
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-candidate-moved.html21
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-candidate-remove-addEventListener.html26
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-candidate-remove-no-listener.html26
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-candidate-remove-onerror.html26
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-audio-constructor-no-src.html13
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-audio-constructor.html12
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-in-sync-event.html32
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-insert-fragment-into-document.html22
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-insert-into-document.html12
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-insert-into-iframe.html23
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-insert-parent-into-document.html19
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-insert-source-in-div.html14
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-insert-source-in-namespace.html14
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-insert-source-networkState.html38
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-insert-source-not-in-document.html13
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-insert-source.html14
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-load.html20
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-pause-networkState.html28
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-pause.html20
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-play.html20
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-remove-from-document-networkState.html29
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-remove-from-document.html21
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-remove-src.html22
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-set-src-in-namespace.html14
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-set-src-networkState.html16
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-set-src-not-in-document.html13
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-set-src.html14
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-pointer-control.html26
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-pointer-insert-br.html33
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-pointer-insert-source.html44
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-pointer-insert-text.html33
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-pointer-remove-source-after.html56
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-pointer-remove-source.html43
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-pointer-remove-text.html33
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-remove-source.html24
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-remove-src.html22
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-source-media.html14
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resources/delayed-broken-video.py5
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/stable-state-beforeunload-manual.html30
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/stable-state-dialogs-manual.html18
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/stable-state-print-manual.html22
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/location-of-the-media-resource/currentSrc.html44
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/mime-types/canPlayType.html110
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/networkState_during_loadstart.html42
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/networkState_during_progress.html42
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/networkState_initial.html33
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/offsets-into-the-media-resource/currentTime.html32
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/offsets-into-the-media-resource/duration.html11
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/paused_false_during_play.html44
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/paused_true_during_pause.html46
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/playing-the-media-resource/pause-move-to-other-document.html25
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/playing-the-media-resource/pause-move-within-document.html25
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/playing-the-media-resource/pause-remove-from-document-networkState.html21
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/playing-the-media-resource/pause-remove-from-document.html37
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/playing-the-media-resource/play-in-detached-document.html23
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/playing-the-media-resource/playbackRate.html19
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/preload_reflects_none_autoplay.html31
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/ready-states/autoplay.html73
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/readyState_during_canplay.html44
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/readyState_during_canplaythrough.html46
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/readyState_during_loadeddata.html44
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/readyState_during_loadedmetadata.html44
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/readyState_during_playing.html44
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/readyState_initial.html33
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/seeking/seek-to-currentTime.html33
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/seeking/seek-to-max-value.htm23
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/seeking/seek-to-negative-time.htm23
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/src_reflects_attribute_not_source_elements.html33
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cloneNode.html86
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/003.html10
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/004.html10
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/005.html10
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/006.html10
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/007.html10
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/008.html10
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/009.html10
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/010.html10
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/011.html10
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/012.html10
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/013.html10
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/014.html10
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/015.html10
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/016.html10
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/017.html10
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/018.html10
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/019.html10
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/020.html10
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/021.html10
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/022.html10
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/023.html10
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/024.html10
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/025.html10
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/026.html10
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/027.html10
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/028.html10
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/029.html10
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/030.html10
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/031.html10
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/032.html10
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/033.html10
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/034.html10
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/035.html10
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/036.html10
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/037.html10
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/038.html10
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/039.html10
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/040.html10
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/041.html10
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/042.html10
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/043.html10
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/044.html10
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/045.html10
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/046.html10
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/support/common.js144
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/support/cors-tester.py51
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/support/remove-cookie.html6
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/support/set-cookie.html6
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/resources/track.de.vtt4
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/resources/track.en.vtt4
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/resources/track.fr.vtt4
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/resources/track.vtt4
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/src-clear-cues.html52
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/track-api-texttracks.html36
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/user-interface/muted.html152
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/video_008.htm45
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/video_controls_present-manual.html14
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/video_loop_base.html41
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/video_muted_overriding_volume-manual.html21
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/video_muted_present-manual.html20
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/video_volume_check.html58
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/video_volume_loudest-manual.html21
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/video_volume_silent-manual.html21
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/media-elements/volume_nonfinite.html18
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/svg/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-area-element/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-area-element/area-coords.html47
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-area-element/area-processing.html32
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-area-element/area-shape.html36
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-area-element/area-stringifier.html16
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-area-element/support/hit-test.js42
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-audio-element/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-audio-element/audio_001.htm18
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-audio-element/audio_002.htm18
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-audio-element/audio_constructor.html50
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-audio-element/audio_content-ref.htm13
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/2d.canvas.readonly.html31
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/2d.canvas.reference.html27
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/2d.getcontext.exists.html27
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/2d.getcontext.extraargs.html27
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/2d.getcontext.shared.html31
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/2d.getcontext.unique.html27
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/2d.scaled-manual.html30
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/2d.scaled.pngbin0 -> 219 bytes
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/2d.type.exists.html27
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/2d.type.extend.html34
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/2d.type.prototype.html36
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/2d.type.replace.html35
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/contains.json10
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/context.arguments.missing.html27
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/context.casesensitive.html27
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/context.emptystring.html27
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/context.unrecognised.badname.html27
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/context.unrecognised.badsuffix.html27
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/context.unrecognised.nullsuffix.html27
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/context.unrecognised.unicode.html27
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/fallback.basic.html27
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/fallback.multiple.html27
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/fallback.nested.html27
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/historical.html77
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/initial.colour.html30
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/initial.colour.pngbin0 -> 117 bytes
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/initial.reset.2dstate.html103
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/initial.reset.clip.html33
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/initial.reset.different.html31
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/initial.reset.different.pngbin0 -> 107 bytes
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/initial.reset.gradient.html36
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/initial.reset.path.html32
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/initial.reset.path.pngbin0 -> 117 bytes
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/initial.reset.pattern.html36
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/initial.reset.same.html32
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/initial.reset.same.pngbin0 -> 117 bytes
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/initial.reset.transform.html32
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/security.dataURI.html40
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/security.drawImage.canvas.html36
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/security.drawImage.image.html31
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/security.pattern.canvas.fillStyle.html38
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/security.pattern.canvas.strokeStyle.html38
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/security.pattern.canvas.timing.html41
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/security.pattern.create.html32
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/security.pattern.cross.html39
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/security.pattern.image.fillStyle.html33
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/security.pattern.image.strokeStyle.html33
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/security.reset.html33
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.default.html30
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.default.pngbin0 -> 272 bytes
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.get.pngbin0 -> 125 bytes
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.idl.html50
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.idl.set.zero.html30
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.parse.decimal.html31
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.parse.decimal.pngbin0 -> 137 bytes
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.parse.em.html31
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.parse.em.pngbin0 -> 137 bytes
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.parse.empty.html30
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.parse.empty.pngbin0 -> 272 bytes
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.parse.exp.html31
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.parse.exp.pngbin0 -> 137 bytes
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.parse.hex.html31
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.parse.junk.html30
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.parse.junk.pngbin0 -> 272 bytes
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.parse.minus.html30
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.parse.minus.pngbin0 -> 272 bytes
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.parse.octal.html31
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.parse.octal.pngbin0 -> 137 bytes
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.parse.onlyspace.html30
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.parse.onlyspace.pngbin0 -> 272 bytes
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.parse.percent.html31
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.parse.percent.pngbin0 -> 137 bytes
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.parse.plus.html31
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.parse.plus.pngbin0 -> 137 bytes
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.parse.space.html31
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.parse.space.pngbin0 -> 137 bytes
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.parse.trailingjunk.html31
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.parse.trailingjunk.pngbin0 -> 137 bytes
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.parse.whitespace.html33
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.parse.whitespace.pngbin0 -> 137 bytes
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.parse.zero.html31
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.reflect.setcontent.html32
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.reflect.setcontent.pngbin0 -> 125 bytes
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.reflect.setidl.html32
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.reflect.setidl.pngbin0 -> 125 bytes
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.reflect.setidlzero.html32
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.removed.html29
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.removed.pngbin0 -> 168 bytes
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.set.pngbin0 -> 125 bytes
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.setAttribute.decimal.html33
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.setAttribute.decimal.pngbin0 -> 137 bytes
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.setAttribute.em.html33
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.setAttribute.em.pngbin0 -> 137 bytes
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.setAttribute.empty.html32
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.setAttribute.empty.pngbin0 -> 272 bytes
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.setAttribute.exp.html33
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.setAttribute.exp.pngbin0 -> 137 bytes
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.setAttribute.hex.html33
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.setAttribute.junk.html32
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.setAttribute.junk.pngbin0 -> 272 bytes
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.setAttribute.minus.html32
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.setAttribute.minus.pngbin0 -> 272 bytes
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.setAttribute.octal.html33
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.setAttribute.octal.pngbin0 -> 137 bytes
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.setAttribute.onlyspace.html32
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.setAttribute.onlyspace.pngbin0 -> 272 bytes
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.setAttribute.percent.html33
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.setAttribute.percent.pngbin0 -> 137 bytes
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.setAttribute.plus.html33
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.setAttribute.plus.pngbin0 -> 137 bytes
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.setAttribute.space.html33
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.setAttribute.space.pngbin0 -> 137 bytes
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.setAttribute.trailingjunk.html33
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.setAttribute.trailingjunk.pngbin0 -> 137 bytes
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.setAttribute.whitespace.html33
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.setAttribute.whitespace.pngbin0 -> 137 bytes
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.setAttribute.zero.html33
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.style.html28
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.style.pngbin0 -> 117 bytes
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/toBlob.jpeg.html29
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/toBlob.png.html29
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/toDataURL.arguments.1.html28
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/toDataURL.arguments.2.html28
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/toDataURL.arguments.3.html29
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/toDataURL.bogustype.html28
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/toDataURL.default.html28
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/toDataURL.jpeg.alpha.html45
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/toDataURL.jpeg.alpha.pngbin0 -> 208 bytes
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/toDataURL.jpeg.primarycolours.html48
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/toDataURL.jpeg.primarycolours.pngbin0 -> 220 bytes
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/toDataURL.jpeg.quality.basic.html56
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/toDataURL.jpeg.quality.basic.pngbin0 -> 213 bytes
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/toDataURL.jpeg.quality.notnumber.html42
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/toDataURL.jpeg.quality.outsiderange.html43
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/toDataURL.jpg.html28
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/toDataURL.lowercase.ascii.html35
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/toDataURL.lowercase.unicode.html32
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/toDataURL.nocontext.html30
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/toDataURL.png.complexcolours.html48
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/toDataURL.png.complexcolours.pngbin0 -> 242 bytes
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/toDataURL.png.html28
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/toDataURL.png.primarycolours.html48
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/toDataURL.png.primarycolours.pngbin0 -> 220 bytes
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/toDataURL.unrecognised.html28
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/toDataURL.zeroheight.html28
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/toDataURL.zerosize.html28
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/toDataURL.zerowidth.html28
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/type.delete.html28
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/type.exists.html27
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/type.extend.html28
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/type.name.html27
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/type.prototype.html36
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/type.replace.html28
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-embed-element/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-embed-element/embed-dimension.html20
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-embed-element/embed-document.html17
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-embed-element/embed-iframe.html7
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-embed-element/embed-ignored-in-media-element.html22
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-embed-element/embed-in-object-fallback-subdocument.html4
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-embed-element/embed-in-object-fallback.html38
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-embed-element/embed-represent-nothing-01.html18
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-embed-element/embed-represent-nothing-02.html22
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-embed-element/embed-represent-nothing-03.html20
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-embed-element/embed-represent-nothing-04.html20
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-embed-element/embed-represent-nothing-ref.html7
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/change_child.html14
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/change_grandchild.html4
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/change_parentage.html22
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/cross_origin_child.html12
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/cross_origin_grandchild.html11
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/cross_origin_parentage.html19
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/historical.html16
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/iframe-allowfullscreen.html55
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/iframe-append-to-child-document.html17
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/iframe-load-event.html48
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/iframe-with-base-ref.html9
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/iframe-with-base.html11
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/iframe_harness.js26
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/iframe_javascript_url_01.htm53
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_allow_script.html46
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_escaping-1.html25
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_escaping-2.html31
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_escaping-3.html25
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_helper-1.html16
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_helper-2.html27
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_helper-3.html17
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_nonescaping-1.html15
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_nonescaping-2.html18
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_nonescaping-3.html15
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/move_iframe_in_dom_01.html20
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/move_iframe_in_dom_02.html22
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/move_iframe_in_dom_03.html20
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/move_iframe_in_dom_04.html22
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/same_origin_child.html12
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/same_origin_grandchild.html11
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/same_origin_parentage.html19
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/stash.py10
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/support/blank.htm1
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/support/sandbox_allow_script.html8
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-img-element/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-img-element/3.jpgbin0 -> 91072 bytes
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-img-element/Image-constructor.html29
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-img-element/brokenimg.jpg4
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-img-element/contains.json60
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-img-element/current-pixel-density/basic.html37
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-img-element/current-pixel-density/error.html31
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-img-element/document-base-url-ref.html5
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-img-element/document-base-url.html7
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-img-element/environment-changes/iframed.sub.html78
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-img-element/environment-changes/viewport-change.html65
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-img-element/image-1.jpgbin0 -> 389245 bytes
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-img-element/image.pngbin0 -> 268 bytes
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-img-element/img.complete.html82
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-img-element/invalid-src.html42
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-img-element/nonexistent-image.html21
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-img-element/relevant-mutations.html416
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-img-element/resources/cat.jpgbin0 -> 21474 bytes
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-img-element/sizes/parse-a-sizes-attribute.html42
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-img-element/sizes/sizes-iframed.sub.html178
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-img-element/srcset/common.js25
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-img-element/srcset/parse-a-srcset-attribute.html245
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-img-element/srcset/select-an-image-source.html20
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-img-element/update-media.html32
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-img-element/update-src-complete.html23
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-img-element/update-the-image-data/fail-to-resolve.html25
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-img-element/update-the-source-set.html140
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-map-element/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-object-element/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-object-element/object-attributes.html50
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-object-element/object-events.html80
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-object-element/object-fallback.html41
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-object-element/object-handler.html33
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-object-element/test0.html10
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-object-element/test1.html9
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-object-element/test2.html4
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-param-element/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-source-element/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-track-element/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-video-element/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-video-element/video-tabindex.html18
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-video-element/video_content-ref.htm12
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-video-element/video_content_image.htm16
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-video-element/video_content_text.htm16
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-video-element/video_dynamic_poster-ref.htm5
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-video-element/video_dynamic_poster_absolute.htm12
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-video-element/video_dynamic_poster_relative.htm12
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-video-element/video_initially_paused-ref.html8
-rw-r--r--testing/web-platform/tests/html/semantics/embedded-content/the-video-element/video_initially_paused.html21
-rw-r--r--testing/web-platform/tests/html/semantics/forms/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/forms/attributes-common-to-form-controls/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/forms/attributes-common-to-form-controls/contains.json34
-rw-r--r--testing/web-platform/tests/html/semantics/forms/attributes-common-to-form-controls/dirname-ltr-iframe.html4
-rw-r--r--testing/web-platform/tests/html/semantics/forms/attributes-common-to-form-controls/dirname-ltr.html29
-rw-r--r--testing/web-platform/tests/html/semantics/forms/attributes-common-to-form-controls/dirname-rtl-manual.html26
-rw-r--r--testing/web-platform/tests/html/semantics/forms/attributes-common-to-form-controls/disabled-elements-01.html84
-rw-r--r--testing/web-platform/tests/html/semantics/forms/attributes-common-to-form-controls/formAction_document_address.html74
-rw-r--r--testing/web-platform/tests/html/semantics/forms/attributes-common-to-form-controls/formaction.html42
-rw-r--r--testing/web-platform/tests/html/semantics/forms/categories/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/forms/constraints/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/forms/constraints/contains.json18
-rw-r--r--testing/web-platform/tests/html/semantics/forms/constraints/form-validation-checkValidity.html145
-rw-r--r--testing/web-platform/tests/html/semantics/forms/constraints/form-validation-reportValidity.html145
-rw-r--r--testing/web-platform/tests/html/semantics/forms/constraints/form-validation-validate.html127
-rw-r--r--testing/web-platform/tests/html/semantics/forms/constraints/form-validation-validity-badInput.html46
-rw-r--r--testing/web-platform/tests/html/semantics/forms/constraints/form-validation-validity-customError.html48
-rw-r--r--testing/web-platform/tests/html/semantics/forms/constraints/form-validation-validity-patternMismatch.html27
-rw-r--r--testing/web-platform/tests/html/semantics/forms/constraints/form-validation-validity-rangeOverflow.html115
-rw-r--r--testing/web-platform/tests/html/semantics/forms/constraints/form-validation-validity-rangeUnderflow.html113
-rw-r--r--testing/web-platform/tests/html/semantics/forms/constraints/form-validation-validity-stepMismatch.html77
-rw-r--r--testing/web-platform/tests/html/semantics/forms/constraints/form-validation-validity-tooLong.html50
-rw-r--r--testing/web-platform/tests/html/semantics/forms/constraints/form-validation-validity-tooShort.html52
-rw-r--r--testing/web-platform/tests/html/semantics/forms/constraints/form-validation-validity-typeMismatch.html41
-rw-r--r--testing/web-platform/tests/html/semantics/forms/constraints/form-validation-validity-valid.html130
-rw-r--r--testing/web-platform/tests/html/semantics/forms/constraints/form-validation-validity-valueMissing.html168
-rw-r--r--testing/web-platform/tests/html/semantics/forms/constraints/form-validation-willValidate.html90
-rw-r--r--testing/web-platform/tests/html/semantics/forms/constraints/inputwillvalidate.html26
-rw-r--r--testing/web-platform/tests/html/semantics/forms/constraints/support/validator.js377
-rw-r--r--testing/web-platform/tests/html/semantics/forms/constraints/tooLong-input-email-delete-manual.html30
-rw-r--r--testing/web-platform/tests/html/semantics/forms/constraints/tooLong-input-password-delete-manual.html30
-rw-r--r--testing/web-platform/tests/html/semantics/forms/constraints/tooLong-input-search-delete-manual.html30
-rw-r--r--testing/web-platform/tests/html/semantics/forms/constraints/tooLong-input-tel-delete-manual.html30
-rw-r--r--testing/web-platform/tests/html/semantics/forms/constraints/tooLong-input-text-delete-manual.html30
-rw-r--r--testing/web-platform/tests/html/semantics/forms/constraints/tooLong-input-url-delete-manual.html30
-rw-r--r--testing/web-platform/tests/html/semantics/forms/constraints/tooLong-textarea-delete-manual.html30
-rw-r--r--testing/web-platform/tests/html/semantics/forms/form-control-infrastructure/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/forms/form-control-infrastructure/contains.json14
-rw-r--r--testing/web-platform/tests/html/semantics/forms/form-control-infrastructure/form.html97
-rw-r--r--testing/web-platform/tests/html/semantics/forms/form-submission-0/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/forms/form-submission-0/contains.json30
-rw-r--r--testing/web-platform/tests/html/semantics/forms/form-submission-0/getactionurl.html39
-rw-r--r--testing/web-platform/tests/html/semantics/forms/form-submission-0/submit-entity-body.html113
-rw-r--r--testing/web-platform/tests/html/semantics/forms/form-submission-0/url-encoded.html46
-rw-r--r--testing/web-platform/tests/html/semantics/forms/historical.html85
-rw-r--r--testing/web-platform/tests/html/semantics/forms/introduction-1/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/forms/introduction-1/contains.json34
-rw-r--r--testing/web-platform/tests/html/semantics/forms/resetting-a-form/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/forms/resetting-a-form/reset-form.html105
-rw-r--r--testing/web-platform/tests/html/semantics/forms/textfieldselection/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/forms/textfieldselection/original-id.json1
-rw-r--r--testing/web-platform/tests/html/semantics/forms/textfieldselection/select-event.html45
-rw-r--r--testing/web-platform/tests/html/semantics/forms/textfieldselection/selection-after-content-change.html18
-rw-r--r--testing/web-platform/tests/html/semantics/forms/textfieldselection/selection-not-application-textarea.html20
-rw-r--r--testing/web-platform/tests/html/semantics/forms/textfieldselection/selection-not-application.html48
-rw-r--r--testing/web-platform/tests/html/semantics/forms/textfieldselection/selection.html145
-rw-r--r--testing/web-platform/tests/html/semantics/forms/textfieldselection/textfieldselection-setRangeText.html120
-rw-r--r--testing/web-platform/tests/html/semantics/forms/textfieldselection/textfieldselection-setSelectionRange.html274
-rw-r--r--testing/web-platform/tests/html/semantics/forms/the-button-element/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/forms/the-button-element/button-activate-frame.html3
-rw-r--r--testing/web-platform/tests/html/semantics/forms/the-button-element/button-activate.html17
-rw-r--r--testing/web-platform/tests/html/semantics/forms/the-button-element/button-events.html66
-rw-r--r--testing/web-platform/tests/html/semantics/forms/the-button-element/button-validation.html29
-rw-r--r--testing/web-platform/tests/html/semantics/forms/the-datalist-element/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/forms/the-datalist-element/datalistoptions.html43
-rw-r--r--testing/web-platform/tests/html/semantics/forms/the-fieldset-element/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/forms/the-fieldset-element/HTMLFieldSetElement.html54
-rw-r--r--testing/web-platform/tests/html/semantics/forms/the-fieldset-element/disabled-001.html71
-rw-r--r--testing/web-platform/tests/html/semantics/forms/the-fieldset-element/disabled-002.xhtml25
-rw-r--r--testing/web-platform/tests/html/semantics/forms/the-form-element/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/forms/the-form-element/form-autocomplete.html59
-rw-r--r--testing/web-platform/tests/html/semantics/forms/the-form-element/form-elements-interfaces-01.html20
-rw-r--r--testing/web-platform/tests/html/semantics/forms/the-form-element/form-elements-matches.html46
-rw-r--r--testing/web-platform/tests/html/semantics/forms/the-form-element/form-elements-nameditem-01.html43
-rw-r--r--testing/web-platform/tests/html/semantics/forms/the-form-element/form-elements-nameditem-02.html28
-rw-r--r--testing/web-platform/tests/html/semantics/forms/the-form-element/form-elements-sameobject.html20
-rw-r--r--testing/web-platform/tests/html/semantics/forms/the-form-element/form-indexed-element.html45
-rw-r--r--testing/web-platform/tests/html/semantics/forms/the-form-element/form-nameditem.html330
-rw-r--r--testing/web-platform/tests/html/semantics/forms/the-input-element/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/forms/the-input-element/button.html66
-rw-r--r--testing/web-platform/tests/html/semantics/forms/the-input-element/checkbox.html149
-rw-r--r--testing/web-platform/tests/html/semantics/forms/the-input-element/checked.xhtml19
-rw-r--r--testing/web-platform/tests/html/semantics/forms/the-input-element/clone.html150
-rw-r--r--testing/web-platform/tests/html/semantics/forms/the-input-element/cloning-steps.html53
-rw-r--r--testing/web-platform/tests/html/semantics/forms/the-input-element/color.html45
-rw-r--r--testing/web-platform/tests/html/semantics/forms/the-input-element/contains.json154
-rw-r--r--testing/web-platform/tests/html/semantics/forms/the-input-element/date.html90
-rw-r--r--testing/web-platform/tests/html/semantics/forms/the-input-element/datetime-local.html36
-rw-r--r--testing/web-platform/tests/html/semantics/forms/the-input-element/datetime.html106
-rw-r--r--testing/web-platform/tests/html/semantics/forms/the-input-element/email.html58
-rw-r--r--testing/web-platform/tests/html/semantics/forms/the-input-element/file-manual.html30
-rw-r--r--testing/web-platform/tests/html/semantics/forms/the-input-element/files.html48
-rw-r--r--testing/web-platform/tests/html/semantics/forms/the-input-element/hidden.html74
-rw-r--r--testing/web-platform/tests/html/semantics/forms/the-input-element/image01-ref.html5
-rw-r--r--testing/web-platform/tests/html/semantics/forms/the-input-element/image01.html7
-rw-r--r--testing/web-platform/tests/html/semantics/forms/the-input-element/input-type-button.html51
-rw-r--r--testing/web-platform/tests/html/semantics/forms/the-input-element/input-type-checkbox.html60
-rw-r--r--testing/web-platform/tests/html/semantics/forms/the-input-element/maxlength-manual.html37
-rw-r--r--testing/web-platform/tests/html/semantics/forms/the-input-element/maxlength.html55
-rw-r--r--testing/web-platform/tests/html/semantics/forms/the-input-element/minlength.html55
-rw-r--r--testing/web-platform/tests/html/semantics/forms/the-input-element/month.html65
-rw-r--r--testing/web-platform/tests/html/semantics/forms/the-input-element/number.html53
-rw-r--r--testing/web-platform/tests/html/semantics/forms/the-input-element/password.html79
-rw-r--r--testing/web-platform/tests/html/semantics/forms/the-input-element/pattern_attribute.html34
-rw-r--r--testing/web-platform/tests/html/semantics/forms/the-input-element/radio-groupname-case.html75
-rw-r--r--testing/web-platform/tests/html/semantics/forms/the-input-element/radio.html144
-rw-r--r--testing/web-platform/tests/html/semantics/forms/the-input-element/range-2.html43
-rw-r--r--testing/web-platform/tests/html/semantics/forms/the-input-element/range.html276
-rw-r--r--testing/web-platform/tests/html/semantics/forms/the-input-element/required_attribute.html34
-rw-r--r--testing/web-platform/tests/html/semantics/forms/the-input-element/reset.html113
-rw-r--r--testing/web-platform/tests/html/semantics/forms/the-input-element/search_input.html35
-rw-r--r--testing/web-platform/tests/html/semantics/forms/the-input-element/selection.html135
-rw-r--r--testing/web-platform/tests/html/semantics/forms/the-input-element/telephone.html84
-rw-r--r--testing/web-platform/tests/html/semantics/forms/the-input-element/text.html104
-rw-r--r--testing/web-platform/tests/html/semantics/forms/the-input-element/time-2.html42
-rw-r--r--testing/web-platform/tests/html/semantics/forms/the-input-element/time.html207
-rw-r--r--testing/web-platform/tests/html/semantics/forms/the-input-element/type-change-state.html62
-rw-r--r--testing/web-platform/tests/html/semantics/forms/the-input-element/url.html59
-rw-r--r--testing/web-platform/tests/html/semantics/forms/the-input-element/valueMode.html72
-rw-r--r--testing/web-platform/tests/html/semantics/forms/the-input-element/week.html38
-rw-r--r--testing/web-platform/tests/html/semantics/forms/the-keygen-element/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/forms/the-label-element/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/forms/the-label-element/label-attributes.html137
-rw-r--r--testing/web-platform/tests/html/semantics/forms/the-label-element/labelable-elements.html156
-rw-r--r--testing/web-platform/tests/html/semantics/forms/the-legend-element/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/forms/the-legend-element/legend-form.html33
-rw-r--r--testing/web-platform/tests/html/semantics/forms/the-meter-element/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/forms/the-meter-element/meter.html250
-rw-r--r--testing/web-platform/tests/html/semantics/forms/the-optgroup-element/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/forms/the-optgroup-element/optgroup-disabled-manual.html35
-rw-r--r--testing/web-platform/tests/html/semantics/forms/the-option-element/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/forms/the-option-element/option-disabled-manual.html28
-rw-r--r--testing/web-platform/tests/html/semantics/forms/the-option-element/option-form.html32
-rw-r--r--testing/web-platform/tests/html/semantics/forms/the-option-element/option-label-value.js82
-rw-r--r--testing/web-platform/tests/html/semantics/forms/the-option-element/option-label.html12
-rw-r--r--testing/web-platform/tests/html/semantics/forms/the-option-element/option-selected.html61
-rw-r--r--testing/web-platform/tests/html/semantics/forms/the-option-element/option-text-backslash.html15
-rw-r--r--testing/web-platform/tests/html/semantics/forms/the-option-element/option-text-label.html23
-rw-r--r--testing/web-platform/tests/html/semantics/forms/the-option-element/option-text-recurse.html92
-rw-r--r--testing/web-platform/tests/html/semantics/forms/the-option-element/option-text-spaces.html75
-rw-r--r--testing/web-platform/tests/html/semantics/forms/the-option-element/option-value.html12
-rw-r--r--testing/web-platform/tests/html/semantics/forms/the-output-element/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/forms/the-output-element/output.html39
-rw-r--r--testing/web-platform/tests/html/semantics/forms/the-progress-element/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/forms/the-progress-element/progress-2.html34
-rw-r--r--testing/web-platform/tests/html/semantics/forms/the-progress-element/progress.html74
-rw-r--r--testing/web-platform/tests/html/semantics/forms/the-select-element/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/forms/the-select-element/common-HTMLOptionsCollection-namedItem.html54
-rw-r--r--testing/web-platform/tests/html/semantics/forms/the-select-element/common-HTMLOptionsCollection.html70
-rw-r--r--testing/web-platform/tests/html/semantics/forms/the-select-element/select-ask-for-reset.html97
-rw-r--r--testing/web-platform/tests/html/semantics/forms/the-select-element/select-named-getter.html46
-rw-r--r--testing/web-platform/tests/html/semantics/forms/the-select-element/select-remove.html64
-rw-r--r--testing/web-platform/tests/html/semantics/forms/the-textarea-element/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/forms/the-textarea-element/cloning-steps.html34
-rw-r--r--testing/web-platform/tests/html/semantics/forms/the-textarea-element/textarea-newline-bidi-ref.html19
-rw-r--r--testing/web-platform/tests/html/semantics/forms/the-textarea-element/textarea-newline-bidi.html23
-rw-r--r--testing/web-platform/tests/html/semantics/forms/the-textarea-element/textarea-placeholder-manual.html14
-rw-r--r--testing/web-platform/tests/html/semantics/forms/the-textarea-element/textarea-select-event-manual.html31
-rw-r--r--testing/web-platform/tests/html/semantics/forms/the-textarea-element/textarea-select-manual.html13
-rw-r--r--testing/web-platform/tests/html/semantics/forms/the-textarea-element/textarea-type.html16
-rw-r--r--testing/web-platform/tests/html/semantics/forms/the-textarea-element/wrap-reflect-1-ref.html5
-rw-r--r--testing/web-platform/tests/html/semantics/forms/the-textarea-element/wrap-reflect-1a.html9
-rw-r--r--testing/web-platform/tests/html/semantics/forms/the-textarea-element/wrap-reflect-1b.html9
-rw-r--r--testing/web-platform/tests/html/semantics/grouping-content/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/grouping-content/the-blockquote-element/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/grouping-content/the-dd-element/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/grouping-content/the-dd-element/grouping-dd.html27
-rw-r--r--testing/web-platform/tests/html/semantics/grouping-content/the-div-element/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/grouping-content/the-div-element/grouping-div.html28
-rw-r--r--testing/web-platform/tests/html/semantics/grouping-content/the-dl-element/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/grouping-content/the-dl-element/grouping-dl.html30
-rw-r--r--testing/web-platform/tests/html/semantics/grouping-content/the-dt-element/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/grouping-content/the-dt-element/grouping-dt.html28
-rw-r--r--testing/web-platform/tests/html/semantics/grouping-content/the-figcaption-element/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/grouping-content/the-figcaption-element/grouping-figcaption.html28
-rw-r--r--testing/web-platform/tests/html/semantics/grouping-content/the-figure-element/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/grouping-content/the-figure-element/grouping-figure.html29
-rw-r--r--testing/web-platform/tests/html/semantics/grouping-content/the-hr-element/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/grouping-content/the-hr-element/grouping-hr.html30
-rw-r--r--testing/web-platform/tests/html/semantics/grouping-content/the-li-element/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/grouping-content/the-li-element/grouping-li-novalue-manual.html148
-rw-r--r--testing/web-platform/tests/html/semantics/grouping-content/the-li-element/grouping-li-reftest-001-ref.html48
-rw-r--r--testing/web-platform/tests/html/semantics/grouping-content/the-li-element/grouping-li-reftest-001.html49
-rw-r--r--testing/web-platform/tests/html/semantics/grouping-content/the-li-element/grouping-li-reftest-002-ref.html34
-rw-r--r--testing/web-platform/tests/html/semantics/grouping-content/the-li-element/grouping-li-reftest-002.html36
-rw-r--r--testing/web-platform/tests/html/semantics/grouping-content/the-li-element/grouping-li.html193
-rw-r--r--testing/web-platform/tests/html/semantics/grouping-content/the-ol-element/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/grouping-content/the-ol-element/grouping-ol-rev-reftest-001-ref.html53
-rw-r--r--testing/web-platform/tests/html/semantics/grouping-content/the-ol-element/grouping-ol-rev-reftest-001.html59
-rw-r--r--testing/web-platform/tests/html/semantics/grouping-content/the-ol-element/grouping-ol-start-reftest-001-ref.html57
-rw-r--r--testing/web-platform/tests/html/semantics/grouping-content/the-ol-element/grouping-ol-start-reftest-001.html64
-rw-r--r--testing/web-platform/tests/html/semantics/grouping-content/the-ol-element/grouping-ol-start-reftest-002-ref.html57
-rw-r--r--testing/web-platform/tests/html/semantics/grouping-content/the-ol-element/grouping-ol-start-reftest-002.html61
-rw-r--r--testing/web-platform/tests/html/semantics/grouping-content/the-ol-element/grouping-ol-type-reftest-001-ref.html55
-rw-r--r--testing/web-platform/tests/html/semantics/grouping-content/the-ol-element/grouping-ol-type-reftest-001.html58
-rw-r--r--testing/web-platform/tests/html/semantics/grouping-content/the-ol-element/grouping-ol-type-reftest-002-ref.html62
-rw-r--r--testing/web-platform/tests/html/semantics/grouping-content/the-ol-element/grouping-ol-type-reftest-002.html65
-rw-r--r--testing/web-platform/tests/html/semantics/grouping-content/the-ol-element/grouping-ol-type-reftest-003-ref.html78
-rw-r--r--testing/web-platform/tests/html/semantics/grouping-content/the-ol-element/grouping-ol-type-reftest-003.html81
-rw-r--r--testing/web-platform/tests/html/semantics/grouping-content/the-ol-element/grouping-ol.html314
-rw-r--r--testing/web-platform/tests/html/semantics/grouping-content/the-ol-element/ol.start-reflection-1.html25
-rw-r--r--testing/web-platform/tests/html/semantics/grouping-content/the-ol-element/ol.start-reflection-2.html25
-rw-r--r--testing/web-platform/tests/html/semantics/grouping-content/the-ol-element/reversed-1-ref.html6
-rw-r--r--testing/web-platform/tests/html/semantics/grouping-content/the-ol-element/reversed-1a.html10
-rw-r--r--testing/web-platform/tests/html/semantics/grouping-content/the-ol-element/reversed-1b.html15
-rw-r--r--testing/web-platform/tests/html/semantics/grouping-content/the-ol-element/reversed-1c.html16
-rw-r--r--testing/web-platform/tests/html/semantics/grouping-content/the-ol-element/reversed-1d.html12
-rw-r--r--testing/web-platform/tests/html/semantics/grouping-content/the-ol-element/reversed-1e.html11
-rw-r--r--testing/web-platform/tests/html/semantics/grouping-content/the-ol-element/reversed-2-ref.html6
-rw-r--r--testing/web-platform/tests/html/semantics/grouping-content/the-ol-element/reversed-2.html7
-rw-r--r--testing/web-platform/tests/html/semantics/grouping-content/the-p-element/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/grouping-content/the-p-element/grouping-p.html28
-rw-r--r--testing/web-platform/tests/html/semantics/grouping-content/the-pre-element/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/grouping-content/the-pre-element/grouping-pre-reftest-001-ref.html22
-rw-r--r--testing/web-platform/tests/html/semantics/grouping-content/the-pre-element/grouping-pre-reftest-001.html23
-rw-r--r--testing/web-platform/tests/html/semantics/grouping-content/the-pre-element/grouping-pre.html28
-rw-r--r--testing/web-platform/tests/html/semantics/grouping-content/the-pre-element/pre-newline-bidi-ref.html19
-rw-r--r--testing/web-platform/tests/html/semantics/grouping-content/the-pre-element/pre-newline-bidi.html23
-rw-r--r--testing/web-platform/tests/html/semantics/grouping-content/the-ul-element/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/grouping-content/the-ul-element/grouping-ul.html28
-rw-r--r--testing/web-platform/tests/html/semantics/interactive-elements/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/interactive-elements/commands/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/interactive-elements/commands/contains.json38
-rw-r--r--testing/web-platform/tests/html/semantics/interactive-elements/the-command-element/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/interactive-elements/the-details-element/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/interactive-elements/the-details-element/details.html47
-rw-r--r--testing/web-platform/tests/html/semantics/interactive-elements/the-details-element/toggleEvent.html157
-rw-r--r--testing/web-platform/tests/html/semantics/interactive-elements/the-dialog-element/contains.json6
-rw-r--r--testing/web-platform/tests/html/semantics/interactive-elements/the-dialog-element/dialog-close.html77
-rw-r--r--testing/web-platform/tests/html/semantics/interactive-elements/the-dialog-element/dialog-open.html30
-rw-r--r--testing/web-platform/tests/html/semantics/interactive-elements/the-dialog-element/dialog-showModal.html125
-rw-r--r--testing/web-platform/tests/html/semantics/interactive-elements/the-menu-element/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/interactive-elements/the-menu-element/contains.json18
-rw-r--r--testing/web-platform/tests/html/semantics/interactive-elements/the-summary-element/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/interfaces.html47
-rw-r--r--testing/web-platform/tests/html/semantics/interfaces.js150
-rw-r--r--testing/web-platform/tests/html/semantics/links/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/links/downloading-resources/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/links/downloading-resources/contains.json6
-rw-r--r--testing/web-platform/tests/html/semantics/links/following-hyperlinks/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/links/introduction-3/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/links/links-created-by-a-and-area-elements/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/links/links-created-by-a-and-area-elements/htmlanchorelement_attribute-getter-setter.html65
-rw-r--r--testing/web-platform/tests/html/semantics/links/links-created-by-a-and-area-elements/htmlanchorelement_getter.html48
-rw-r--r--testing/web-platform/tests/html/semantics/links/links-created-by-a-and-area-elements/htmlanchorelement_noopener.html78
-rw-r--r--testing/web-platform/tests/html/semantics/links/links-created-by-a-and-area-elements/support/noopener-popup.html19
-rw-r--r--testing/web-platform/tests/html/semantics/links/links-created-by-a-and-area-elements/support/noopener-target-1.html4
-rw-r--r--testing/web-platform/tests/html/semantics/links/links-created-by-a-and-area-elements/support/noopener-target-2.html8
-rw-r--r--testing/web-platform/tests/html/semantics/links/linktypes/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/links/linktypes/alternate-css-ref.html5
-rw-r--r--testing/web-platform/tests/html/semantics/links/linktypes/alternate-css.html7
-rw-r--r--testing/web-platform/tests/html/semantics/links/linktypes/alternate.css3
-rw-r--r--testing/web-platform/tests/html/semantics/links/linktypes/contains.json68
-rw-r--r--testing/web-platform/tests/html/semantics/links/linktypes/original-id.json1
-rw-r--r--testing/web-platform/tests/html/semantics/links/linktypes/preferred.css3
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-noscript-element/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/async_001.htm18
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/async_002.htm31
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/async_003.htm39
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/async_004.htm37
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/async_005.htm39
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/async_006.htm45
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/async_007.htm48
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/async_008.htm47
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/async_009.htm25
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/async_010.htm54
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/async_011.htm19
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/contains.json18
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/external-script-utf8.js5
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/external-script-windows1250.js5
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/fetch-src/alpha/base.html15
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/fetch-src/alpha/test.js1
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/fetch-src/beta/test.js1
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/fetch-src/empty-with-base.html27
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/fetch-src/empty.html32
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/fetch-src/failure.html25
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/fetch-src/unreachable.js1
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/historical.html53
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/load-event.html24
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/log.py13
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/resources/cross-origin.py10
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-charset-01.html89
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-charset-02.html40
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-charset-03.html20
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-crossorigin-network.html49
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-crossorigin.html39
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-for-event-xhtml.xhtml22
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-for-event.html93
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-language-type.html18
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-languages-01.html24
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-languages-02.html98
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-noembed-noframes-iframe.xhtml36
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-not-executed-after-shutdown-child.html12
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-not-executed-after-shutdown.html18
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-not-executed-after-shutdown.js1
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-not-found-not-executed-2.py4
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-not-found-not-executed.html19
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-not-found-not-executed.py4
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-onerror-insertion-point-1.html12
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-onerror-insertion-point-2.html13
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-onload-insertion-point.html12
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-onload-string.html17
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-text-xhtml.xhtml28
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-text.html72
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/scripting-enabled.html16
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/serve-with-content-type.py15
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/support/script-onerror-insertion-point-1-helper.html2
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/support/script-onerror-insertion-point-2-helper.html2
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/support/script-onload-insertion-point-helper.html2
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-script-element/support/script-onload-insertion-point-helper.js1
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-template-element/additions-to-parsing-xhtml-documents/node-document.html150
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-template-element/additions-to-parsing-xhtml-documents/template-child-nodes.html102
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-template-element/additions-to-serializing-xhtml-documents/outerhtml.html71
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-template-element/additions-to-the-css-user-agent-style-sheet/css-user-agent-style-sheet-test-001-ref.html6
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-template-element/additions-to-the-css-user-agent-style-sheet/css-user-agent-style-sheet-test-001.html12
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-template-element/additions-to-the-css-user-agent-style-sheet/css-user-agent-style-sheet-test-002.html12
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-template-element/additions-to-the-css-user-agent-style-sheet/css-user-agent-style-sheet-test-003.html19
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-template-element/additions-to-the-steps-to-clone-a-node/template-clone-children.html82
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-template-element/additions-to-the-steps-to-clone-a-node/templates-copy-document-owner.html126
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-template-element/definitions/template-contents-owner-document-type.html83
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-template-element/definitions/template-contents-owner-test-001.html44
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-template-element/definitions/template-contents-owner-test-002.html67
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-template-element/definitions/template-contents.html172
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-template-element/innerhtml-on-templates/innerhtml.html86
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/end-template-tag-in-body.html12
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/end-template-tag-in-head.html12
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/frameset-end-tag.html10
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/head-template-contents-div-no-end-tag.html12
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/head-template-contents-table-no-end-tag.html14
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/html-start-tag.html10
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-child-nodes-div.xhtml14
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-child-nodes-nested.xhtml16
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-contents-attribute.html10
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-contents-body.html10
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-contents-div-no-end-tag.html12
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-contents-empty.html11
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-contents-frameset.html10
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-contents-head.html10
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-contents-html.html10
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-contents-nested.html10
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-contents-table-no-end-tag.html14
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-contents-text.html10
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-contents.html12
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-descendant-body.html12
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-descendant-frameset.html12
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-descendant-head.html13
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/two-templates.html17
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-template-element/serializing-html-templates/outerhtml.html70
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-template-element/template-element/content-attribute.html114
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-template-element/template-element/node-document-changes.html199
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-template-element/template-element/template-as-a-descendant.html135
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-template-element/template-element/template-content-node-document.html59
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-template-element/template-element/template-content.html77
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-template-element/template-element/template-descendant-body.html26
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-template-element/template-element/template-descendant-frameset.html62
-rw-r--r--testing/web-platform/tests/html/semantics/scripting-1/the-template-element/template-element/template-descendant-head.html26
-rw-r--r--testing/web-platform/tests/html/semantics/sections/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/sections/headings-and-sections/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/sections/headings-and-sections/contains.json6
-rw-r--r--testing/web-platform/tests/html/semantics/sections/the-address-element/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/sections/the-article-element/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/sections/the-aside-element/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/sections/the-body-element/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/sections/the-footer-element/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/sections/the-h1-h2-h3-h4-h5-and-h6-elements/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/sections/the-h1-h2-h3-h4-h5-and-h6-elements/original-id.json1
-rw-r--r--testing/web-platform/tests/html/semantics/sections/the-header-element/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/sections/the-hgroup-element/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/sections/the-nav-element/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/sections/the-section-element/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/sections/usage-summary-0/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/selectors/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/selectors/case-sensitivity/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/selectors/pseudo-classes/checked-001-manual.html18
-rw-r--r--testing/web-platform/tests/html/semantics/selectors/pseudo-classes/checked.html43
-rw-r--r--testing/web-platform/tests/html/semantics/selectors/pseudo-classes/default.html64
-rw-r--r--testing/web-platform/tests/html/semantics/selectors/pseudo-classes/dir.html46
-rw-r--r--testing/web-platform/tests/html/semantics/selectors/pseudo-classes/dir01.html18
-rw-r--r--testing/web-platform/tests/html/semantics/selectors/pseudo-classes/disabled.html60
-rw-r--r--testing/web-platform/tests/html/semantics/selectors/pseudo-classes/enabled.html42
-rw-r--r--testing/web-platform/tests/html/semantics/selectors/pseudo-classes/focus-autofocus.html24
-rw-r--r--testing/web-platform/tests/html/semantics/selectors/pseudo-classes/focus-iframe.html5
-rw-r--r--testing/web-platform/tests/html/semantics/selectors/pseudo-classes/focus.html51
-rw-r--r--testing/web-platform/tests/html/semantics/selectors/pseudo-classes/indeterminate-radio.html26
-rw-r--r--testing/web-platform/tests/html/semantics/selectors/pseudo-classes/indeterminate.html37
-rw-r--r--testing/web-platform/tests/html/semantics/selectors/pseudo-classes/inrange-outofrange.html84
-rw-r--r--testing/web-platform/tests/html/semantics/selectors/pseudo-classes/link.html23
-rw-r--r--testing/web-platform/tests/html/semantics/selectors/pseudo-classes/readwrite-readonly.html89
-rw-r--r--testing/web-platform/tests/html/semantics/selectors/pseudo-classes/required-optional.html35
-rw-r--r--testing/web-platform/tests/html/semantics/selectors/pseudo-classes/utils.js20
-rw-r--r--testing/web-platform/tests/html/semantics/selectors/pseudo-classes/valid-invalid.html146
-rw-r--r--testing/web-platform/tests/html/semantics/tabular-data/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/tabular-data/attributes-common-to-td-and-th-elements/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/tabular-data/attributes-common-to-td-and-th-elements/cellIndex.html50
-rw-r--r--testing/web-platform/tests/html/semantics/tabular-data/examples/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/tabular-data/historical.html25
-rw-r--r--testing/web-platform/tests/html/semantics/tabular-data/html-table-section-element.js22
-rw-r--r--testing/web-platform/tests/html/semantics/tabular-data/processing-model-1/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/tabular-data/processing-model-1/contains.json10
-rw-r--r--testing/web-platform/tests/html/semantics/tabular-data/the-caption-element/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/tabular-data/the-caption-element/caption_001.html70
-rw-r--r--testing/web-platform/tests/html/semantics/tabular-data/the-col-element/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/tabular-data/the-colgroup-element/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/tabular-data/the-table-element/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/tabular-data/the-table-element/caption-methods.html100
-rw-r--r--testing/web-platform/tests/html/semantics/tabular-data/the-table-element/contains.json10
-rw-r--r--testing/web-platform/tests/html/semantics/tabular-data/the-table-element/createTBody.html173
-rw-r--r--testing/web-platform/tests/html/semantics/tabular-data/the-table-element/delete-caption.html94
-rw-r--r--testing/web-platform/tests/html/semantics/tabular-data/the-table-element/insertRow-method-01.html24
-rw-r--r--testing/web-platform/tests/html/semantics/tabular-data/the-table-element/insertRow-method-02.html34
-rw-r--r--testing/web-platform/tests/html/semantics/tabular-data/the-table-element/insertRow-method-03.html32
-rw-r--r--testing/web-platform/tests/html/semantics/tabular-data/the-table-element/remove-row.html50
-rw-r--r--testing/web-platform/tests/html/semantics/tabular-data/the-table-element/tBodies.html40
-rw-r--r--testing/web-platform/tests/html/semantics/tabular-data/the-table-element/tFoot.html57
-rw-r--r--testing/web-platform/tests/html/semantics/tabular-data/the-table-element/tHead.html66
-rw-r--r--testing/web-platform/tests/html/semantics/tabular-data/the-table-element/table-insertRow.html56
-rw-r--r--testing/web-platform/tests/html/semantics/tabular-data/the-table-element/table-rows.html234
-rw-r--r--testing/web-platform/tests/html/semantics/tabular-data/the-tbody-element/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/tabular-data/the-tbody-element/deleteRow.html54
-rw-r--r--testing/web-platform/tests/html/semantics/tabular-data/the-tbody-element/insertRow.html56
-rw-r--r--testing/web-platform/tests/html/semantics/tabular-data/the-tbody-element/rows.html15
-rw-r--r--testing/web-platform/tests/html/semantics/tabular-data/the-td-element/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/tabular-data/the-tfoot-element/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/tabular-data/the-tfoot-element/rows.html15
-rw-r--r--testing/web-platform/tests/html/semantics/tabular-data/the-th-element/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/tabular-data/the-thead-element/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/tabular-data/the-thead-element/rows.html15
-rw-r--r--testing/web-platform/tests/html/semantics/tabular-data/the-tr-element/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/tabular-data/the-tr-element/cells.html28
-rw-r--r--testing/web-platform/tests/html/semantics/tabular-data/the-tr-element/deleteCell.html54
-rw-r--r--testing/web-platform/tests/html/semantics/tabular-data/the-tr-element/insertCell.html55
-rw-r--r--testing/web-platform/tests/html/semantics/tabular-data/the-tr-element/rowIndex.html77
-rw-r--r--testing/web-platform/tests/html/semantics/tabular-data/the-tr-element/sectionRowIndex.html130
-rw-r--r--testing/web-platform/tests/html/semantics/text-level-semantics/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/text-level-semantics/historical.html32
-rw-r--r--testing/web-platform/tests/html/semantics/text-level-semantics/the-a-element/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/text-level-semantics/the-a-element/a-stringifier.html16
-rw-r--r--testing/web-platform/tests/html/semantics/text-level-semantics/the-a-element/a.text-getter-01.html34
-rw-r--r--testing/web-platform/tests/html/semantics/text-level-semantics/the-a-element/a.text-setter-01.html41
-rw-r--r--testing/web-platform/tests/html/semantics/text-level-semantics/the-abbr-element/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/text-level-semantics/the-b-element/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-auto-dir-default-ref.html36
-rw-r--r--testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-auto-dir-default.html46
-rw-r--r--testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-missing-pdf-ref.html44
-rw-r--r--testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-missing-pdf.html56
-rw-r--r--testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-nested-ref.html44
-rw-r--r--testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-nested.html52
-rw-r--r--testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-number-ref.html44
-rw-r--r--testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-number.html53
-rw-r--r--testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-separate-ref.html36
-rw-r--r--testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-separate.html47
-rw-r--r--testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-to-another-bdi-1-ref.html47
-rw-r--r--testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-to-another-bdi-1.html58
-rw-r--r--testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-to-another-bdi-2-ref.html47
-rw-r--r--testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-to-another-bdi-2.html59
-rw-r--r--testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-to-letter-following-1-ref.html45
-rw-r--r--testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-to-letter-following-1.html54
-rw-r--r--testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-to-letter-following-2-ref.html45
-rw-r--r--testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-to-letter-following-2.html54
-rw-r--r--testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-to-letter-preceding-1-ref.html45
-rw-r--r--testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-to-letter-preceding-1.html54
-rw-r--r--testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-to-letter-preceding-2-ref.html45
-rw-r--r--testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-to-letter-preceding-2.html54
-rw-r--r--testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-to-number-following-1-ref.html45
-rw-r--r--testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-to-number-following-1.html54
-rw-r--r--testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-to-number-following-2-ref.html45
-rw-r--r--testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-to-number-following-2.html53
-rw-r--r--testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-to-surrounding-run-ref.html44
-rw-r--r--testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-to-surrounding-run.html56
-rw-r--r--testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-wrapped-ref.html52
-rw-r--r--testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-wrapped.html73
-rw-r--r--testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-paragraph-level-container-ref.html36
-rw-r--r--testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-paragraph-level-container.html46
-rw-r--r--testing/web-platform/tests/html/semantics/text-level-semantics/the-bdo-element/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/text-level-semantics/the-bdo-element/bdo-child.html17
-rw-r--r--testing/web-platform/tests/html/semantics/text-level-semantics/the-bdo-element/bdo-ltr.html15
-rw-r--r--testing/web-platform/tests/html/semantics/text-level-semantics/the-bdo-element/bdo-override.html18
-rw-r--r--testing/web-platform/tests/html/semantics/text-level-semantics/the-bdo-element/bidi-001-ref.html11
-rw-r--r--testing/web-platform/tests/html/semantics/text-level-semantics/the-bdo-element/bidi-001.html14
-rw-r--r--testing/web-platform/tests/html/semantics/text-level-semantics/the-br-element/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/text-level-semantics/the-br-element/br-bidi-in-inline-ancestors-ref.html38
-rw-r--r--testing/web-platform/tests/html/semantics/text-level-semantics/the-br-element/br-bidi-in-inline-ancestors.html59
-rw-r--r--testing/web-platform/tests/html/semantics/text-level-semantics/the-br-element/br-bidi-ref.html19
-rw-r--r--testing/web-platform/tests/html/semantics/text-level-semantics/the-br-element/br-bidi.html22
-rw-r--r--testing/web-platform/tests/html/semantics/text-level-semantics/the-cite-element/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/text-level-semantics/the-code-element/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/text-level-semantics/the-data-element/data.value-001.html66
-rw-r--r--testing/web-platform/tests/html/semantics/text-level-semantics/the-dfn-element/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/text-level-semantics/the-em-element/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/text-level-semantics/the-i-element/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/text-level-semantics/the-kbd-element/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/text-level-semantics/the-mark-element/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/text-level-semantics/the-q-element/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/text-level-semantics/the-rp-element/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/text-level-semantics/the-rt-element/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/text-level-semantics/the-ruby-element/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/text-level-semantics/the-s-element/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/text-level-semantics/the-samp-element/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/text-level-semantics/the-small-element/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/text-level-semantics/the-span-element/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/text-level-semantics/the-strong-element/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/text-level-semantics/the-sub-and-sup-elements/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/text-level-semantics/the-time-element/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/text-level-semantics/the-time-element/001.html68
-rw-r--r--testing/web-platform/tests/html/semantics/text-level-semantics/the-u-element/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/text-level-semantics/the-var-element/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/text-level-semantics/the-wbr-element/wbr-element-ref.html9
-rw-r--r--testing/web-platform/tests/html/semantics/text-level-semantics/the-wbr-element/wbr-element.html11
-rw-r--r--testing/web-platform/tests/html/semantics/text-level-semantics/usage-summary/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/the-root-element/.gitkeep0
-rw-r--r--testing/web-platform/tests/html/semantics/the-root-element/the-html-element/.gitkeep0
1065 files changed, 34636 insertions, 0 deletions
diff --git a/testing/web-platform/tests/html/semantics/.gitkeep b/testing/web-platform/tests/html/semantics/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/common-idioms/.gitkeep b/testing/web-platform/tests/html/semantics/common-idioms/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/common-idioms/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/common-idioms/conversations/.gitkeep b/testing/web-platform/tests/html/semantics/common-idioms/conversations/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/common-idioms/conversations/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/common-idioms/footnotes/.gitkeep b/testing/web-platform/tests/html/semantics/common-idioms/footnotes/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/common-idioms/footnotes/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/common-idioms/rel-up/.gitkeep b/testing/web-platform/tests/html/semantics/common-idioms/rel-up/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/common-idioms/rel-up/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/common-idioms/tag-clouds/.gitkeep b/testing/web-platform/tests/html/semantics/common-idioms/tag-clouds/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/common-idioms/tag-clouds/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/common-idioms/the-main-part-of-the-content/.gitkeep b/testing/web-platform/tests/html/semantics/common-idioms/the-main-part-of-the-content/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/common-idioms/the-main-part-of-the-content/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/disabled-elements/.gitkeep b/testing/web-platform/tests/html/semantics/disabled-elements/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/disabled-elements/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/disabled-elements/disabledElement.html b/testing/web-platform/tests/html/semantics/disabled-elements/disabledElement.html
new file mode 100644
index 000000000..03f57424d
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/disabled-elements/disabledElement.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Disabled elements</title>
+<link rel="author" title="Denis Ah-Kang" href="mailto:denis@w3.org">
+<link rel=help href="https://html.spec.whatwg.org/multipage/#disabled-elements">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<button disabled>button</button>
+<input disabled>
+<select disabled>
+ <optgroup label="options" disabled>
+ <option value="option1" disabled>option1
+ <option value="option2">option2
+</select>
+<textarea disabled>textarea</textarea>
+<fieldset disabled>
+ <input type=radio name=c value=0 checked>
+ <input type=radio name=c value=1>
+</fieldset>
+<a href="http://www.w3.org/" disabled>w3</a>
+<span tabindex=0 disabled>foobar</span>
+
+<script>
+ test(function(){
+ assert_equals(document.activeElement, document.body);
+ }, "The body element must be the active element if no element is focused");
+
+ ["button", "input", "select", "optgroup", "option", "textarea", "input[type=radio]"].forEach(function(el) {
+ test(function() {
+ var element = document.querySelector(el);
+ element.focus();
+ assert_equals(document.activeElement, document.body, "activeElement after focus on a disabled <" + el + "> remains unchanged");
+ }, "A disabled <" + el + "> should not be focusable");
+ });
+
+ ["a", "span"].forEach(function(el) {
+ test(function() {
+ var element = document.querySelector(el);
+ element.focus();
+ assert_equals(document.activeElement, element, "focus on a <" + el + "> with a disabled attribute should make it the activeElement");
+ }, "A disabled <" + el + "> should be focusable");
+ });
+</script>
diff --git a/testing/web-platform/tests/html/semantics/document-metadata/.gitkeep b/testing/web-platform/tests/html/semantics/document-metadata/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/document-metadata/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/document-metadata/styling/.gitkeep b/testing/web-platform/tests/html/semantics/document-metadata/styling/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/document-metadata/styling/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/document-metadata/styling/LinkStyle.html b/testing/web-platform/tests/html/semantics/document-metadata/styling/LinkStyle.html
new file mode 100644
index 000000000..09278d202
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/document-metadata/styling/LinkStyle.html
@@ -0,0 +1,72 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>HTML Test: Styling</title>
+ <link rel="author" title="Intel" href="http://www.intel.com/">
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#styling">
+ <link id="style1" rel="text" title="Intel" href="./support/unmatch.css">
+ <link id="style2" rel="alternate stylesheet" type="text/css" title="" href="./support/emptytitle.css">
+ <link id="style3" rel="alternate stylesheet" type="text/css" href="./support/notitle.css">
+ <link id="style5" rel="stylesheet" type="text/css" href="./support/normal.css">
+ <link id="style6" rel="alternate stylesheet" type="text/css" href="./support/normal.css" title="./support/alternate.css">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <style id="style4" type="text/html">
+ #test {
+ height: 100px;
+ width: 100px;
+ }
+ </style>
+ <style id="style7" type="text/css" media="all" title="./support/alternate.css">
+ #test {
+ background-color: green;
+ }
+ </style>
+ </head>
+ <body>
+ <div id="log"></div>
+ <div id="test" style="display:none">STYLING TEST</div>
+
+ <script>
+ test(function() {
+ var style = null,
+ i;
+ for (i = 1; i < 5; i++) {
+ style = document.getElementById("style" + i);
+ assert_equals(style.sheet, null, "The sheet attribute of style" + i + " should be null.");
+ assert_false(style.disabled, "The disabled attribute of style" + i + " should be false.");
+ }
+ }, "The LinkStyle interface's sheet attribute must return null; the disabled attribute must be false");
+
+ test(function() {
+ var style = document.createElement("style"),
+ link = document.createElement("link");
+ assert_equals(style.sheet, null, "The sheet attribute of the style element not in a document should be null.");
+ assert_equals(link.sheet, null, "The sheet attribute of the link element not in a document should be null.");
+ }, "The LinkStyle interface's sheet attribute must return null if the corresponding element is not in a Document");
+
+ test(function() {
+ var style = null,
+ i;
+ for (i = 5; i < 8; i++) {
+ style = document.getElementById("style" + i);
+ assert_true(style.sheet instanceof StyleSheet, "The sheet attribute of style" + i + " should be a StyleSheet object.");
+ assert_equals(style.disabled, style.sheet.disabled, "The disabled attribute of style" + i + " should equal to the same attribute of StyleSheet.");
+ }
+ }, "The LinkStyle interface's sheet attribute must return StyleSheet object; the disabled attribute must be same as the StyleSheet's disabled attribute");
+
+ test(function() {
+ assert_equals(document.getElementById("style2").title, "", "The title attribute of style2 is incorrect.");
+ assert_equals(document.getElementById("style5").title, "", "The title attribute of style5 is incorrect.");
+ assert_equals(document.getElementById("style6").title, "./support/alternate.css", "The title attribute of style6 is incorrect.");
+ assert_equals(document.getElementById("style7").title, "./support/alternate.css", "The title attribute of style7 is incorrect.");
+ }, "The title must be the same as the value of the element's title content attribute");
+
+ test(function() {
+ assert_equals(document.getElementById("style5").media, "", "The media attribute of style5 is incorrect.");
+ assert_equals(document.getElementById("style7").media, "all", "The media attribute of style7 is incorrect.");
+ }, "The media must be the same as the value of the element's media content attribute, or the empty string if it is omitted");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/document-metadata/styling/support/alternate.css b/testing/web-platform/tests/html/semantics/document-metadata/styling/support/alternate.css
new file mode 100644
index 000000000..b8deb07b0
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/document-metadata/styling/support/alternate.css
@@ -0,0 +1,7 @@
+#test {
+ color: yellow;
+ background-color: blue;
+ width: 100px;
+ height: 50px;
+ font-size: .5em;
+}
diff --git a/testing/web-platform/tests/html/semantics/document-metadata/styling/support/emptytitle.css b/testing/web-platform/tests/html/semantics/document-metadata/styling/support/emptytitle.css
new file mode 100644
index 000000000..e62fe701b
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/document-metadata/styling/support/emptytitle.css
@@ -0,0 +1,4 @@
+#test {
+ width: 100px;
+ height: 100px;
+}
diff --git a/testing/web-platform/tests/html/semantics/document-metadata/styling/support/normal.css b/testing/web-platform/tests/html/semantics/document-metadata/styling/support/normal.css
new file mode 100644
index 000000000..a803c2211
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/document-metadata/styling/support/normal.css
@@ -0,0 +1,5 @@
+#test {
+ width: 100px;
+ height: 50px;
+ font-size: 10px;
+}
diff --git a/testing/web-platform/tests/html/semantics/document-metadata/styling/support/notitle.css b/testing/web-platform/tests/html/semantics/document-metadata/styling/support/notitle.css
new file mode 100644
index 000000000..e62fe701b
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/document-metadata/styling/support/notitle.css
@@ -0,0 +1,4 @@
+#test {
+ width: 100px;
+ height: 100px;
+}
diff --git a/testing/web-platform/tests/html/semantics/document-metadata/styling/support/unmatch.css b/testing/web-platform/tests/html/semantics/document-metadata/styling/support/unmatch.css
new file mode 100644
index 000000000..e62fe701b
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/document-metadata/styling/support/unmatch.css
@@ -0,0 +1,4 @@
+#test {
+ width: 100px;
+ height: 100px;
+}
diff --git a/testing/web-platform/tests/html/semantics/document-metadata/the-base-element/.gitkeep b/testing/web-platform/tests/html/semantics/document-metadata/the-base-element/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/document-metadata/the-base-element/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/document-metadata/the-base-element/base_about_blank.html b/testing/web-platform/tests/html/semantics/document-metadata/the-base-element/base_about_blank.html
new file mode 100644
index 000000000..54c479454
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/document-metadata/the-base-element/base_about_blank.html
@@ -0,0 +1,19 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>base element in about:blank document should resolve against its fallback base URI</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<iframe></iframe>
+<script>
+var t = async_test();
+addEventListener("load", t.step_func_done(function() {
+ var doc = frames[0].document;
+ var b = doc.createElement("base");
+ b.setAttribute("href", "test");
+ var newBaseValue = location.href.replace(/\/[^/]*$/, "/") + "test";
+ assert_equals(b.href, newBaseValue);
+ assert_equals(doc.baseURI, location.href);
+ doc.head.appendChild(b);
+ assert_equals(doc.baseURI, newBaseValue);
+}));
+</script>
diff --git a/testing/web-platform/tests/html/semantics/document-metadata/the-base-element/base_href_empty.html b/testing/web-platform/tests/html/semantics/document-metadata/the-base-element/base_href_empty.html
new file mode 100644
index 000000000..7737556a1
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/document-metadata/the-base-element/base_href_empty.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>HTML Test: base_href_empty</title>
+<link rel="author" title="Intel" href="http://www.intel.com/">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#the-base-element">
+<base id="base" href="" target="_blank">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<img id="test" src="/images/blue-100x100.png" style="display:none">
+
+<script>
+ var testElement,
+ baseElement;
+
+ setup(function() {
+ testElement = document.getElementById("test");
+ baseElement = document.getElementById("base");
+ });
+
+ test(function() {
+ assert_equals(baseElement.href, document.location.href, "The href of base element is incorrect.");
+ }, "The value of the href attribute must be the document's address if it is empty");
+
+ test(function() {
+ var exp = testElement.src.substring(0, testElement.src.lastIndexOf("/images/blue-100x100.png") + 1);
+ assert_true(baseElement.href.indexOf(exp) != -1, "The src of img element is incorrect.");
+ }, "The src attribute of the img element must relative to document's address");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/document-metadata/the-base-element/base_href_invalid.html b/testing/web-platform/tests/html/semantics/document-metadata/the-base-element/base_href_invalid.html
new file mode 100644
index 000000000..6d12d29e8
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/document-metadata/the-base-element/base_href_invalid.html
@@ -0,0 +1,12 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>base element with unparseable href should have .href getter return attr value</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script>
+test(function() {
+ var b = document.createElement("base");
+ b.setAttribute("href", "//test:test");
+ assert_equals(b.href, "//test:test");
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/document-metadata/the-base-element/base_href_specified.sub.html b/testing/web-platform/tests/html/semantics/document-metadata/the-base-element/base_href_specified.sub.html
new file mode 100644
index 000000000..83e71387a
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/document-metadata/the-base-element/base_href_specified.sub.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>HTML Test: base_href_specified</title>
+<link rel="author" title="Intel" href="http://www.intel.com/">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#the-base-element">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/get-host-info.sub.js"></script>
+<base id="base">
+<div id="log"></div>
+<img id="test" src="test.ico" style="display:none">
+
+<script>
+ var testElement;
+ var baseElement;
+
+ var otherOrigin = get_host_info().HTTP_REMOTE_ORIGIN;
+
+ setup(function() {
+ testElement = document.getElementById("test");
+ baseElement = document.getElementById("base");
+
+ baseElement.setAttribute("href", otherOrigin);
+ });
+
+ test(function() {
+ assert_equals(baseElement.href, otherOrigin + "/", "The href attribute of the base element is incorrect.");
+ }, "The href attribute of the base element is specified");
+
+ test(function() {
+ assert_equals(testElement.src, otherOrigin + "/test.ico", "The src attribute of the img element is incorrect.");
+ }, "The src attribute of the img element must relative to the href attribute of the base element");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/document-metadata/the-base-element/base_href_unspecified.html b/testing/web-platform/tests/html/semantics/document-metadata/the-base-element/base_href_unspecified.html
new file mode 100644
index 000000000..cf883f723
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/document-metadata/the-base-element/base_href_unspecified.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>HTML Test: base_href_unspecified</title>
+<link rel="author" title="Intel" href="http://www.intel.com/">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#the-base-element">
+<base id="base" target="_blank">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<div id="log"></div>
+<img id="test" src="/images/blue-100x100.png" style="display:none">
+
+<script>
+ var testElement,
+ baseElement;
+
+ setup(function () {
+ testElement = document.getElementById("test");
+ baseElement = document.getElementById("base");
+ });
+
+ test(function() {
+ assert_equals(baseElement.href, document.location.href, "Return the document base URL if the base element has no href content attribute.");
+ }, "The value of the href attribute must be the document's address if it is unspecified");
+
+ test(function() {
+ var exp = testElement.src.substring(0, testElement.src.lastIndexOf("/images/blue-100x100.png") + 1);
+ assert_true(baseElement.href.indexOf(exp) != -1, "The src attribute of the img element is incorrect.");
+ }, "The src attribute of the img element must relative to document's address");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/document-metadata/the-base-element/base_multiple.html b/testing/web-platform/tests/html/semantics/document-metadata/the-base-element/base_multiple.html
new file mode 100644
index 000000000..4b7c0d213
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/document-metadata/the-base-element/base_multiple.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>HTML Test: base_multiple</title>
+<link rel="author" title="Intel" href="http://www.intel.com/">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#the-base-element">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<body>
+ <div id="log"></div>
+ <iframe id="test1" src="example.html" style="width:0;height:0" frameborder="0"></iframe>
+ <iframe id="test2" src="example.html" name="targetWin" style="width:0;height:0" frameborder="0"></iframe>
+ <script>
+ async_test(function() {
+ window.onload = this.step_func(function() {
+ var fr1 = document.getElementById("test1");
+ fr1.addEventListener("load", this.unreached_func("loaded in the wrong iframe"));
+
+ var fr2 = document.getElementById("test2");
+ fr2.addEventListener("load", this.step_func_done(function () {
+ var doc2 = fr2.contentDocument;
+ assert_not_equals(doc2.location.href.indexOf("example2.html"), -1, "The target attribute does not impact the a element.");
+ assert_equals(doc2.getElementById("d1").innerHTML, "PASS", "The opend page should be the example2.html.");
+ }), true);
+
+ fr1.contentDocument.getElementById("a1").click();
+ });
+ }, "The attributes of the a element must be affected by the first base element");
+ </script>
+</body>
diff --git a/testing/web-platform/tests/html/semantics/document-metadata/the-base-element/base_srcdoc.html b/testing/web-platform/tests/html/semantics/document-metadata/the-base-element/base_srcdoc.html
new file mode 100644
index 000000000..eea1efe51
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/document-metadata/the-base-element/base_srcdoc.html
@@ -0,0 +1,19 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>base element in srcdoc document should resolve against its fallback base URI</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<iframe srcdoc=""></iframe>
+<script>
+var t = async_test();
+addEventListener("load", t.step_func_done(function() {
+ var doc = frames[0].document;
+ var b = doc.createElement("base");
+ b.setAttribute("href", "test");
+ var newBaseValue = location.href.replace(/\/[^/]*$/, "/") + "test";
+ assert_equals(b.href, newBaseValue);
+ assert_equals(doc.baseURI, location.href);
+ doc.head.appendChild(b);
+ assert_equals(doc.baseURI, newBaseValue);
+}));
+</script>
diff --git a/testing/web-platform/tests/html/semantics/document-metadata/the-base-element/example.html b/testing/web-platform/tests/html/semantics/document-metadata/the-base-element/example.html
new file mode 100644
index 000000000..49dc772f9
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/document-metadata/the-base-element/example.html
@@ -0,0 +1,7 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>Example</title>
+<base target="targetWin" href="">
+<base target="_self" href="http://www.example.com/">
+<link rel="author" title="Intel" href="http://www.intel.com/">
+<a id="a1" href="example2.html" target="">click me</a>
diff --git a/testing/web-platform/tests/html/semantics/document-metadata/the-base-element/example2.html b/testing/web-platform/tests/html/semantics/document-metadata/the-base-element/example2.html
new file mode 100644
index 000000000..0e57cb9c5
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/document-metadata/the-base-element/example2.html
@@ -0,0 +1,5 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>Example</title>
+<link rel="author" title="Intel" href="http://www.intel.com/">
+<div id="d1">PASS</div>
diff --git a/testing/web-platform/tests/html/semantics/document-metadata/the-head-element/.gitkeep b/testing/web-platform/tests/html/semantics/document-metadata/the-head-element/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/document-metadata/the-head-element/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/document-metadata/the-link-element/.gitkeep b/testing/web-platform/tests/html/semantics/document-metadata/the-link-element/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/document-metadata/the-link-element/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/document-metadata/the-link-element/document-without-browsing-context.html b/testing/web-platform/tests/html/semantics/document-metadata/the-link-element/document-without-browsing-context.html
new file mode 100644
index 000000000..127b253f5
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/document-metadata/the-link-element/document-without-browsing-context.html
@@ -0,0 +1,35 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>Documents without browsing contexts should not load stylesheets</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/utils.js"></script>
+<body>
+<script>
+ function count(id, t) {
+ var xhr = new XMLHttpRequest();
+ xhr.open('GET', 'stylesheet.py?count=1&id=' + id);
+ xhr.onload = t.step_func_done(function() {
+ assert_equals(xhr.responseText, "1");
+ });
+ xhr.onerror = t.unreached_func();
+ xhr.send();
+ }
+
+ async_test(function(t) {
+ var id = token();
+ var doc = (new DOMParser()).parseFromString('<link rel="stylesheet" href="stylesheet.py?id=' + id + '"></link>', 'text/html');
+ var link = doc.querySelector('link');
+ document.head.appendChild(link);
+ t.step_timeout(function() { count(id, t) }, 500);
+ }, 'Create a document, adopt the node');
+
+ async_test(function(t) {
+ var id = token();
+ var d = document.createElement('div');
+ document.body.appendChild(d);
+ d.innerHTML = '<link rel="stylesheet" href="stylesheet.py?id=' + id + '"></link>';
+ t.step_timeout(function() { count(id, t) }, 500);
+ }, 'Create a stylesheet in innerHTML document');
+</script>
+</body>
diff --git a/testing/web-platform/tests/html/semantics/document-metadata/the-link-element/link-load-event.html b/testing/web-platform/tests/html/semantics/document-metadata/the-link-element/link-load-event.html
new file mode 100644
index 000000000..6f6172a2d
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/document-metadata/the-link-element/link-load-event.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<link rel="author" title="Josh Matthews" href="mailto:josh@joshmatthews.net">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#the-link-element">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<link href="style.css?pipe=trickle(d3)" rel="stylesheet" id="style_test"></link>
+<script>
+var saw_link_onload = false;
+var t = async_test("Check if the stylesheet's load event blocks the document load event");
+document.getElementById('style_test').onload = t.step_func(function() {
+ saw_link_onload = true;
+});
+window.addEventListener('load', t.step_func_done(function() {
+ assert_true(saw_link_onload);
+}));
+</script>
+</head>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/document-metadata/the-link-element/link-rellist.html b/testing/web-platform/tests/html/semantics/document-metadata/the-link-element/link-rellist.html
new file mode 100644
index 000000000..414965195
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/document-metadata/the-link-element/link-rellist.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<title>link.relList: non-string contains</title>
+<link rel="author" title="Ms2ger" href="mailto:ms2ger@gmail.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#the-link-element">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#domtokenlist">
+<link rel="help" href="https://heycam.github.io/webidl/#ecmascript-binding">
+<link rel="help" href="http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-262.pdf#page=57">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<link id="link" rel="undefined null 0 NaN Infinity">
+<div id="log"></div>
+<script>
+test(function() {
+ var list = document.getElementById("link").relList;
+ assert_equals(list.contains(undefined), true); //"undefined"
+ assert_equals(list.contains(null), true); //"null"
+ assert_equals(list.contains(-0), true); //"0"
+ assert_equals(list.contains(+0), true); //"0"
+ assert_equals(list.contains(NaN), true); //"NaN"
+ assert_equals(list.contains(+Infinity), true); //"Infinity"
+ assert_equals(list.contains(-Infinity), false); //"-Infinity"
+ assert_equals(list.supports("stylesheet"), true);
+ assert_equals(list.supports("nosuchrelvalueever"), false);
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/document-metadata/the-link-element/link-style-error-01.html b/testing/web-platform/tests/html/semantics/document-metadata/the-link-element/link-style-error-01.html
new file mode 100644
index 000000000..7a86a8638
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/document-metadata/the-link-element/link-style-error-01.html
@@ -0,0 +1,48 @@
+<!DOCTYPE html>
+<title>link: error events</title>
+<link rel="author" title="Ms2ger" href="mailto:ms2ger@gmail.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#the-link-element">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<div id="test">
+<script>
+var t404 = async_test("Should get an error event for a 404 error.")
+t404.step(function() {
+ var elt = document.createElement("link");
+ elt.onerror = t404.step_func(function() {
+ assert_true(true, "Got error event for 404 error.")
+ t404.step_timeout(function() { t404.done() }, 0);
+ })
+ elt.onload = t404.unreached_func("load event should not be fired");
+ elt.rel = "stylesheet";
+ elt.href = "nonexistent_stylesheet.css";
+ document.getElementsByTagName("head")[0].appendChild(elt);
+})
+
+var tUnsupported = async_test("Should get an error event for an unsupported URL.")
+tUnsupported.step(function() {
+ var elt = document.createElement("link");
+ elt.onerror = tUnsupported.step_func(function() {
+ assert_true(true, "Got error event for unsupported URL.")
+ tUnsupported.step_timeout(function() { tUnsupported.done() }, 0);
+ })
+ elt.onload = tUnsupported.unreached_func("load event should not be fired");
+ elt.rel = "stylesheet";
+ elt.href = "nonexistent:stylesheet.css";
+ document.getElementsByTagName("head")[0].appendChild(elt);
+})
+
+var tText = async_test("Should get an error event for a text/plain response.")
+tText.step(function() {
+ var elt = document.createElement("link");
+ elt.onerror = tText.step_func(function() {
+ assert_true(true, "Got error event for 404 error.")
+ tText.done()
+ })
+ elt.onload = tText.unreached_func("load event should not be fired");
+ elt.rel = "stylesheet";
+ elt.href = "../../../../../common/css-red.txt";
+ document.getElementsByTagName("head")[0].appendChild(elt);
+})
+</script>
diff --git a/testing/web-platform/tests/html/semantics/document-metadata/the-link-element/resources/stylesheet.css b/testing/web-platform/tests/html/semantics/document-metadata/the-link-element/resources/stylesheet.css
new file mode 100644
index 000000000..e1b2552ff
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/document-metadata/the-link-element/resources/stylesheet.css
@@ -0,0 +1,3 @@
+body {
+ background-color: green;
+}
diff --git a/testing/web-platform/tests/html/semantics/document-metadata/the-link-element/style.css b/testing/web-platform/tests/html/semantics/document-metadata/the-link-element/style.css
new file mode 100644
index 000000000..d48115e56
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/document-metadata/the-link-element/style.css
@@ -0,0 +1,3 @@
+body {
+ background-color: white;
+} \ No newline at end of file
diff --git a/testing/web-platform/tests/html/semantics/document-metadata/the-link-element/stylesheet-with-base-ref.html b/testing/web-platform/tests/html/semantics/document-metadata/the-link-element/stylesheet-with-base-ref.html
new file mode 100644
index 000000000..83f0d0677
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/document-metadata/the-link-element/stylesheet-with-base-ref.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>Stylesheet Without Base Tag</title>
+ <style>
+ body { background-color: green; }
+ </style>
+</head>
+<body>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/document-metadata/the-link-element/stylesheet-with-base.html b/testing/web-platform/tests/html/semantics/document-metadata/the-link-element/stylesheet-with-base.html
new file mode 100644
index 000000000..a9f2a8bce
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/document-metadata/the-link-element/stylesheet-with-base.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>Stylesheet With Base Tag</title>
+ <link rel="match" href="stylesheet-with-base-ref.html">
+ <base href="resources/">
+ <link rel="stylesheet" href="stylesheet.css">
+</head>
+<body>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/document-metadata/the-link-element/stylesheet.css b/testing/web-platform/tests/html/semantics/document-metadata/the-link-element/stylesheet.css
new file mode 100644
index 000000000..e8f24f94a
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/document-metadata/the-link-element/stylesheet.css
@@ -0,0 +1,3 @@
+body {
+ background-color: red;
+}
diff --git a/testing/web-platform/tests/html/semantics/document-metadata/the-link-element/stylesheet.py b/testing/web-platform/tests/html/semantics/document-metadata/the-link-element/stylesheet.py
new file mode 100644
index 000000000..a312e9e87
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/document-metadata/the-link-element/stylesheet.py
@@ -0,0 +1,9 @@
+def main(request, response):
+ try:
+ count = int(request.server.stash.take(request.GET["id"]))
+ except:
+ count = 0
+ if "count" in request.GET:
+ return str(count)
+ request.server.stash.put(request.GET["id"], str(count + 1))
+ return 'body { color: red }'
diff --git a/testing/web-platform/tests/html/semantics/document-metadata/the-meta-element/.gitkeep b/testing/web-platform/tests/html/semantics/document-metadata/the-meta-element/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/document-metadata/the-meta-element/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/document-metadata/the-meta-element/contains.json b/testing/web-platform/tests/html/semantics/document-metadata/the-meta-element/contains.json
new file mode 100644
index 000000000..70a454691
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/document-metadata/the-meta-element/contains.json
@@ -0,0 +1,22 @@
+[
+ {
+ "id": "standard-metadata-names",
+ "original_id": "standard-metadata-names"
+ },
+ {
+ "id": "other-metadata-names",
+ "original_id": "other-metadata-names"
+ },
+ {
+ "id": "pragma-directives",
+ "original_id": "pragma-directives"
+ },
+ {
+ "id": "other-pragma-directives",
+ "original_id": "other-pragma-directives"
+ },
+ {
+ "id": "charset",
+ "original_id": "charset"
+ }
+] \ No newline at end of file
diff --git a/testing/web-platform/tests/html/semantics/document-metadata/the-meta-element/pragma-directives/attr-meta-http-equiv-refresh/parsing.html b/testing/web-platform/tests/html/semantics/document-metadata/the-meta-element/pragma-directives/attr-meta-http-equiv-refresh/parsing.html
new file mode 100644
index 000000000..cbfc18035
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/document-metadata/the-meta-element/pragma-directives/attr-meta-http-equiv-refresh/parsing.html
@@ -0,0 +1,112 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Parsing of meta refresh</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<style>
+iframe { display:none }
+</style>
+<body>
+<script>
+
+// failure to parse is []
+// success to parse is [time, url] where url is unresolved
+
+var tests_arr = [
+ {input: '', expected: []},
+ {input: '1', expected: [1, 'refresh.sub.html']},
+ {input: '1 ', expected: [1, 'refresh.sub.html']},
+ {input: '1\t', expected: [1, 'refresh.sub.html']},
+ {input: '1\r', expected: [1, 'refresh.sub.html']},
+ {input: '1\n', expected: [1, 'refresh.sub.html']},
+ {input: '1\f', expected: [1, 'refresh.sub.html']},
+ {input: '1;', expected: [1, 'refresh.sub.html']},
+ {input: '1,', expected: [1, 'refresh.sub.html']},
+ {input: '1; url=foo', expected: [1, 'foo']},
+ {input: '1, url=foo', expected: [1, 'foo']},
+ {input: '1 url=foo', expected: [1, 'foo']},
+ {input: '1;\turl=foo', expected: [1, 'foo']},
+ {input: '1,\turl=foo', expected: [1, 'foo']},
+ {input: '1\turl=foo', expected: [1, 'foo']},
+ {input: '1;\rurl=foo', expected: [1, 'foo']},
+ {input: '1,\rurl=foo', expected: [1, 'foo']},
+ {input: '1\rurl=foo', expected: [1, 'foo']},
+ {input: '1;\nurl=foo', expected: [1, 'foo']},
+ {input: '1,\nurl=foo', expected: [1, 'foo']},
+ {input: '1\nurl=foo', expected: [1, 'foo']},
+ {input: '1;\furl=foo', expected: [1, 'foo']},
+ {input: '1,\furl=foo', expected: [1, 'foo']},
+ {input: '1\furl=foo', expected: [1, 'foo']},
+ {input: '1url=foo', expected: []},
+ {input: '1x;url=foo', expected: []},
+ {input: '1 x;url=foo', expected: [1, 'x;url=foo']},
+ {input: '1;;url=foo', expected: [1, ';url=foo']},
+ {input: ' 1 ; url = foo', expected: [1, 'foo']},
+ {input: ' 1 , url = foo', expected: [1, 'foo']},
+ {input: ' 1 ; foo', expected: [1, 'foo']},
+ {input: ' 1 , foo', expected: [1, 'foo']},
+ {input: ' 1 url = foo', expected: [1, 'foo']},
+ {input: '1; url=foo ', expected: [1, 'foo']},
+ {input: '1; url=f\to\no', expected: [1, 'foo']},
+ {input: '1; url="foo"bar', expected: [1, 'foo']},
+ {input: '1; url=\'foo\'bar', expected: [1, 'foo']},
+ {input: '1; url="foo\'bar', expected: [1, 'foo\'bar']},
+ {input: '1; url foo', expected: [1, 'url foo']},
+ {input: '1; urlfoo', expected: [1, 'urlfoo']},
+ {input: '1; urfoo', expected: [1, 'urfoo']},
+ {input: '1; ufoo', expected: [1, 'ufoo']},
+ {input: '1; "foo"bar', expected: [1, 'foo']},
+ {input: '; foo', expected: []},
+ {input: ', foo', expected: []},
+ {input: 'foo', expected: []},
+ {input: '+1; url=foo', expected: []},
+ {input: '-1; url=foo', expected: []},
+ {input: '+0; url=foo', expected: []},
+ {input: '-0; url=foo', expected: []},
+ {input: '0; url=foo', expected: [0, 'foo']},
+ {input: '+1; foo', expected: []},
+ {input: '-1; foo', expected: []},
+ {input: '+0; foo', expected: []},
+ {input: '-0; foo', expected: []},
+ {input: '0; foo', expected: [0, 'foo']},
+ {input: '+1', expected: []},
+ {input: '-1', expected: []},
+ {input: '+0', expected: []},
+ {input: '-0', expected: []},
+ {input: '0', expected: [0, 'refresh.sub.html']},
+ {input: '1.9; url=foo', expected: [1, 'foo']},
+ {input: '1.9..5.; url=foo', expected: [1, 'foo']},
+ {input: '.9; url=foo', expected: []},
+];
+
+tests_arr.forEach(function(test_obj) {
+ async_test(function(t) {
+ var iframe = document.createElement('iframe');
+ t.add_cleanup(function() {
+ document.body.removeChild(iframe);
+ });
+ iframe.src = 'support/refresh.sub.html?input=' + encodeURIComponent(test_obj.input);
+ document.body.appendChild(iframe);
+ var loadCount = 0;
+ iframe.onload = t.step_func(function() {
+ loadCount++;
+ var got = iframe.contentDocument.body.textContent.trim();
+ if (test_obj.expected.length === 0) {
+ assert_equals(got, 'refresh.sub.html');
+ if (loadCount === 1) {
+ setTimeout(function() {
+ t.done();
+ }, 3000); // want to make sure it doesn't redirect when it shouldn't
+ } else {
+ assert_unreached('Got > 1 load events');
+ }
+ } else {
+ if (loadCount === 2) {
+ assert_equals(got, test_obj.expected[1]);
+ t.done();
+ }
+ }
+ });
+ }, format_value(test_obj.input));
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/document-metadata/the-meta-element/pragma-directives/attr-meta-http-equiv-refresh/support/;url=foo b/testing/web-platform/tests/html/semantics/document-metadata/the-meta-element/pragma-directives/attr-meta-http-equiv-refresh/support/;url=foo
new file mode 100644
index 000000000..622ff110d
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/document-metadata/the-meta-element/pragma-directives/attr-meta-http-equiv-refresh/support/;url=foo
@@ -0,0 +1 @@
+;url=foo
diff --git a/testing/web-platform/tests/html/semantics/document-metadata/the-meta-element/pragma-directives/attr-meta-http-equiv-refresh/support/__dir__.headers b/testing/web-platform/tests/html/semantics/document-metadata/the-meta-element/pragma-directives/attr-meta-http-equiv-refresh/support/__dir__.headers
new file mode 100644
index 000000000..156209f9c
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/document-metadata/the-meta-element/pragma-directives/attr-meta-http-equiv-refresh/support/__dir__.headers
@@ -0,0 +1 @@
+Content-Type: text/html
diff --git a/testing/web-platform/tests/html/semantics/document-metadata/the-meta-element/pragma-directives/attr-meta-http-equiv-refresh/support/foo b/testing/web-platform/tests/html/semantics/document-metadata/the-meta-element/pragma-directives/attr-meta-http-equiv-refresh/support/foo
new file mode 100644
index 000000000..257cc5642
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/document-metadata/the-meta-element/pragma-directives/attr-meta-http-equiv-refresh/support/foo
@@ -0,0 +1 @@
+foo
diff --git a/testing/web-platform/tests/html/semantics/document-metadata/the-meta-element/pragma-directives/attr-meta-http-equiv-refresh/support/foo'bar b/testing/web-platform/tests/html/semantics/document-metadata/the-meta-element/pragma-directives/attr-meta-http-equiv-refresh/support/foo'bar
new file mode 100644
index 000000000..80e741087
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/document-metadata/the-meta-element/pragma-directives/attr-meta-http-equiv-refresh/support/foo'bar
@@ -0,0 +1 @@
+foo'bar
diff --git a/testing/web-platform/tests/html/semantics/document-metadata/the-meta-element/pragma-directives/attr-meta-http-equiv-refresh/support/refresh.sub.html b/testing/web-platform/tests/html/semantics/document-metadata/the-meta-element/pragma-directives/attr-meta-http-equiv-refresh/support/refresh.sub.html
new file mode 100644
index 000000000..bc97f29c6
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/document-metadata/the-meta-element/pragma-directives/attr-meta-http-equiv-refresh/support/refresh.sub.html
@@ -0,0 +1 @@
+<!doctype html><meta http-equiv=refresh content="{{GET[input]}}">refresh.sub.html
diff --git a/testing/web-platform/tests/html/semantics/document-metadata/the-meta-element/pragma-directives/attr-meta-http-equiv-refresh/support/ufoo b/testing/web-platform/tests/html/semantics/document-metadata/the-meta-element/pragma-directives/attr-meta-http-equiv-refresh/support/ufoo
new file mode 100644
index 000000000..8fff3cf4f
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/document-metadata/the-meta-element/pragma-directives/attr-meta-http-equiv-refresh/support/ufoo
@@ -0,0 +1 @@
+ufoo
diff --git a/testing/web-platform/tests/html/semantics/document-metadata/the-meta-element/pragma-directives/attr-meta-http-equiv-refresh/support/urfoo b/testing/web-platform/tests/html/semantics/document-metadata/the-meta-element/pragma-directives/attr-meta-http-equiv-refresh/support/urfoo
new file mode 100644
index 000000000..7d7373f4b
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/document-metadata/the-meta-element/pragma-directives/attr-meta-http-equiv-refresh/support/urfoo
@@ -0,0 +1 @@
+urfoo
diff --git a/testing/web-platform/tests/html/semantics/document-metadata/the-meta-element/pragma-directives/attr-meta-http-equiv-refresh/support/url foo b/testing/web-platform/tests/html/semantics/document-metadata/the-meta-element/pragma-directives/attr-meta-http-equiv-refresh/support/url foo
new file mode 100644
index 000000000..a1e6a9229
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/document-metadata/the-meta-element/pragma-directives/attr-meta-http-equiv-refresh/support/url foo
@@ -0,0 +1 @@
+url foo
diff --git a/testing/web-platform/tests/html/semantics/document-metadata/the-meta-element/pragma-directives/attr-meta-http-equiv-refresh/support/urlfoo b/testing/web-platform/tests/html/semantics/document-metadata/the-meta-element/pragma-directives/attr-meta-http-equiv-refresh/support/urlfoo
new file mode 100644
index 000000000..3e67b2f7c
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/document-metadata/the-meta-element/pragma-directives/attr-meta-http-equiv-refresh/support/urlfoo
@@ -0,0 +1 @@
+urlfoo
diff --git a/testing/web-platform/tests/html/semantics/document-metadata/the-meta-element/pragma-directives/attr-meta-http-equiv-refresh/support/x;url=foo b/testing/web-platform/tests/html/semantics/document-metadata/the-meta-element/pragma-directives/attr-meta-http-equiv-refresh/support/x;url=foo
new file mode 100644
index 000000000..f10371aa7
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/document-metadata/the-meta-element/pragma-directives/attr-meta-http-equiv-refresh/support/x;url=foo
@@ -0,0 +1 @@
+x;url=foo
diff --git a/testing/web-platform/tests/html/semantics/document-metadata/the-meta-element/the-lang-attribute-012.html b/testing/web-platform/tests/html/semantics/document-metadata/the-meta-element/the-lang-attribute-012.html
new file mode 100644
index 000000000..af872d6e3
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/document-metadata/the-meta-element/the-lang-attribute-012.html
@@ -0,0 +1,51 @@
+<!DOCTYPE html>
+<html >
+<head>
+<meta charset="utf-8"/>
+ <meta http-equiv="Content-Language" content="ko,zh,ja" >
+<title>Multiple languages in Content-Language meta element</title>
+<link rel='author' title='Richard Ishida' href='mailto:ishida@w3.org'>
+<link rel='help' href='https://html.spec.whatwg.org/multipage/#pragma-directives'>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<meta name='flags' content='dom'>
+<style type='text/css'>
+ #colonlangcontroltest { color: red; font-weight: bold; width: 400px; }
+ #colonlangcontroltest:lang(xx) { display:none; }
+.test div { width: 50px; }
+
+#box:lang(ko) { width: 100px; }
+#box:lang(zh) { width: 100px; }
+#box:lang(ja) { width: 100px; }
+
+ /* styling for debugging related notes */
+ .notes span:lang(ko) { background-color: #0000FF; color: white; padding: 0 5px; }
+ .notes span:lang(zh) { background-color: #0000FF; color: white; padding: 0 5px; }
+ .notes span:lang(ja) { background-color: #0000FF; color: white; padding: 0 5px; }
+
+</style>
+</head>
+<body>
+
+
+
+<div class="test"><div id="box">&#xA0;</div></div>
+<p lang='xx' id='colonlangcontroltest'>This test failed because it relies on :lang for results, but :lang is not supported by this browser.</p>
+
+
+<!--Notes:
+
+This test uses :lang to detect whether the language has been set. If :lang is not supported, a message will appear and the test will fail.
+
+-->
+<script>
+test(function() {
+assert_equals(document.getElementById('colonlangcontroltest').offsetWidth, 0)
+assert_equals(document.getElementById('box').offsetWidth, 50);
+}, "The UA will not recognize a language declaration in the Content-Language meta element when more than one language is declared.");
+</script>
+
+<div id='log'></div>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/document-metadata/the-style-element/.gitkeep b/testing/web-platform/tests/html/semantics/document-metadata/the-style-element/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/document-metadata/the-style-element/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/document-metadata/the-style-element/historical.html b/testing/web-platform/tests/html/semantics/document-metadata/the-style-element/historical.html
new file mode 100644
index 000000000..d475f5b3c
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/document-metadata/the-style-element/historical.html
@@ -0,0 +1,14 @@
+<!doctype html>
+<title>Historical style element features should not be supported</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+function t(property) {
+ test(function() {
+ assert_false(property in document.createElement('style'));
+ }, 'style.' + property + ' should not be supported');
+}
+// added in https://github.com/whatwg/html/commit/29cf39d2163cfc85b67409f4e10390619ffb2b40
+// removed in https://github.com/whatwg/html/commit/c2a3b2a2e3db49c14b486a5e99acf7d10cfe8443
+t('scoped');
+</script>
diff --git a/testing/web-platform/tests/html/semantics/document-metadata/the-style-element/html_style_in_comment-ref.html b/testing/web-platform/tests/html/semantics/document-metadata/the-style-element/html_style_in_comment-ref.html
new file mode 100644
index 000000000..999383c76
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/document-metadata/the-style-element/html_style_in_comment-ref.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>[style] Reference file</title>
+<link rel="author" title="Intel" href="http://www.intel.com">
+<style>
+ h4 {
+ color: green;
+ }
+</style>
+<body>
+ <p>
+ This page tests that Style written inside HTML comment is not applied
+ </p>
+ This test passes if the text below is <b>Green. NOT Red.</b>
+ <h4>
+ This is some text.
+ </h4>
+</body>
diff --git a/testing/web-platform/tests/html/semantics/document-metadata/the-style-element/html_style_in_comment.xhtml b/testing/web-platform/tests/html/semantics/document-metadata/the-style-element/html_style_in_comment.xhtml
new file mode 100644
index 000000000..839548f01
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/document-metadata/the-style-element/html_style_in_comment.xhtml
@@ -0,0 +1,18 @@
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<link rel="match" href="html_style_in_comment-ref.html"/>
+<style type="text/css">
+h4 {color: green}
+<!--
+h4 {color: red}
+-->
+</style>
+</head>
+<body>
+<p> This page tests that Style written inside HTML comment is not applied</p>
+This test passes if the text below is <b>Green. NOT Red.</b>
+<h4>
+This is some text.
+</h4>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/document-metadata/the-style-element/style-error-01.html b/testing/web-platform/tests/html/semantics/document-metadata/the-style-element/style-error-01.html
new file mode 100644
index 000000000..87cb9fafd
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/document-metadata/the-style-element/style-error-01.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<title>style: error events</title>
+<link rel="author" title="Ms2ger" href="mailto:ms2ger@gmail.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#the-style-element">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<div id="test">
+<script>
+//var t404 = async_test("Should get an error event for a 404 error.")
+//t404.step(function() {
+// var elt = document.createElement("style");
+// elt.onerror = t404.step_func(function() {
+// assert_true(true, "Got error event for 404 error.")
+// t404.done()
+// })
+// elt.appendChild(
+// document.createTextNode('@import 404 error;'));
+// document.getElementsByTagName("head")[0].appendChild(elt);
+//})
+var tText = async_test("Should get an error event for a text/plain response.")
+tText.step(function() {
+ var elt = document.createElement("style");
+ elt.onerror = tText.step_func(function() {
+ assert_true(true, "Got error event for 404 error.")
+ tText.done()
+ })
+ elt.appendChild(
+ document.createTextNode('@import "../../../../common/css-red.txt";'));
+ document.getElementsByTagName("head")[0].appendChild(elt);
+})
+</script>
diff --git a/testing/web-platform/tests/html/semantics/document-metadata/the-style-element/style_disabled.html b/testing/web-platform/tests/html/semantics/document-metadata/the-style-element/style_disabled.html
new file mode 100644
index 000000000..d26746a9c
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/document-metadata/the-style-element/style_disabled.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>HTML Test: The style should not be applied if it is disabled</title>
+ <link rel="author" title="Intel" href="http://www.intel.com/">
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-style-element">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <style>
+ #test {
+ width: 100px;
+ }
+ </style>
+ <style id="style">
+ #test {
+ width: 50px;
+ }
+ </style>
+ </head>
+ <body>
+ <div id="log"></div>
+ <div id="test"></div>
+ <script>
+ test(function() {
+ var testElement = document.getElementById("test");
+ var style = document.getElementById("style");
+ var width1, width2;
+
+ width1 = window.getComputedStyle(testElement, false)["width"];
+ assert_equals(width1, "50px", "The style should be applied.");
+
+ style.disabled = true;
+ width2 = window.getComputedStyle(testElement, false)["width"];
+ assert_equals(width2, "100px", "The style should not be applied.");
+ }, "The style is not applied when it is disabled");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/document-metadata/the-style-element/style_events.html b/testing/web-platform/tests/html/semantics/document-metadata/the-style-element/style_events.html
new file mode 100644
index 000000000..5e07e5088
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/document-metadata/the-style-element/style_events.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>HTML Test: The style events</title>
+ <link rel="author" title="Intel" href="http://www.intel.com/">
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-style-element">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script>
+ var tLoad = async_test("If the style is loaded successfully, the 'load' event must be fired");
+ var tError = async_test("If the style is loaded unsuccessfully, the 'error' event must be fired");
+
+ function onstyleload(e) {
+ tLoad.done();
+ }
+
+ function onstyleerror(e) {
+ tError.done();
+ }
+ </script>
+ <style onload="onstyleload()">
+ #test {
+ height: 100px;
+ width: 100px;
+ }
+ </style>
+ <style onerror="onstyleerror()">
+ @import url(nonexistent.css);
+ </style>
+ </head>
+ <body>
+ <div id="log"></div>
+ <div id="test"></div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/document-metadata/the-style-element/style_media.html b/testing/web-platform/tests/html/semantics/document-metadata/the-style-element/style_media.html
new file mode 100644
index 000000000..5bd189a26
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/document-metadata/the-style-element/style_media.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>HTML Test: The style information must be applied to the environment specified by the media attribute</title>
+ <link rel="author" title="Intel" href="http://www.intel.com/">
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#attr-style-media">
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-style-element">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <style>
+ #test {
+ width: 100px;
+ }
+ </style>
+ <style id="style">
+ #test {
+ width: 50px;
+ }
+ </style>
+ </head>
+ <body>
+ <div id="log"></div>
+ <div id="test"></div>
+ <script>
+ test(function() {
+ var testElement = document.getElementById("test");
+ var style = document.getElementById("style");
+ var width1, width2;
+
+ width1 = window.getComputedStyle(testElement, false)["width"];
+ assert_equals(width1, "50px", "The style should be applied.");
+
+ style.media = "print";
+ width2 = window.getComputedStyle(testElement, false)["width"];
+ assert_equals(width2, "100px", "The style should not be applied.");
+ }, "The style information must be applied to the environment specified by the media attribute");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/document-metadata/the-title-element/.gitkeep b/testing/web-platform/tests/html/semantics/document-metadata/the-title-element/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/document-metadata/the-title-element/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/document-metadata/the-title-element/title.text-01.html b/testing/web-platform/tests/html/semantics/document-metadata/the-title-element/title.text-01.html
new file mode 100644
index 000000000..7f25400ea
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/document-metadata/the-title-element/title.text-01.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<title>title.text with comment and element children.</title>
+<link rel="author" title="Ms2ger" href="mailto:ms2ger@gmail.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-title-text">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<script>
+try {
+ var title = document.getElementsByTagName("title")[0];
+ while (title.childNodes.length)
+ title.removeChild(title.childNodes[0]);
+ title.appendChild(document.createComment("COMMENT"));
+ title.appendChild(document.createTextNode("TEXT"));
+ title.appendChild(document.createElement("a"))
+ .appendChild(document.createTextNode("ELEMENT"))
+} catch (e) {
+}
+</script>
+<script>
+test(function() {
+ assert_equals(title.text, "TEXT");
+ assert_equals(title.textContent, "TEXTELEMENT");
+})
+</script>
diff --git a/testing/web-platform/tests/html/semantics/document-metadata/the-title-element/title.text-02.xhtml b/testing/web-platform/tests/html/semantics/document-metadata/the-title-element/title.text-02.xhtml
new file mode 100644
index 000000000..068b10504
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/document-metadata/the-title-element/title.text-02.xhtml
@@ -0,0 +1,30 @@
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title>title.text with comment and element children.</title>
+<link rel="author" title="Ms2ger" href="mailto:ms2ger@gmail.com"/>
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-title-text"/>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+</head>
+<body>
+<div id="log"></div>
+<script>
+try {
+ var title = document.getElementsByTagName("title")[0];
+ while (title.childNodes.length)
+ title.removeChild(title.childNodes[0]);
+ title.appendChild(document.createComment("COMMENT"));
+ title.appendChild(document.createTextNode("TEXT"));
+ title.appendChild(document.createElement("a"))
+ .appendChild(document.createTextNode("ELEMENT"))
+} catch (e) {
+}
+</script>
+<script>
+test(function() {
+ assert_equals(title.text, "TEXT");
+ assert_equals(title.textContent, "TEXTELEMENT");
+})
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/document-metadata/the-title-element/title.text-03.html b/testing/web-platform/tests/html/semantics/document-metadata/the-title-element/title.text-03.html
new file mode 100644
index 000000000..1c119a825
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/document-metadata/the-title-element/title.text-03.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<title> title.text and space normalization </title>
+<link rel="author" title="Ms2ger" href="mailto:ms2ger@gmail.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-title-text">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<script>
+test(function() {
+ assert_equals(document.getElementsByTagName("title")[0].text,
+ " title.text and space normalization ");
+ assert_equals(document.getElementsByTagName("title")[0].textContent,
+ " title.text and space normalization ");
+ assert_equals(document.getElementsByTagName("title")[0].firstChild.nodeValue,
+ " title.text and space normalization ");
+}, "title.text and space normalization (markup)");
+[
+ "one space", "two spaces",
+ "one\ttab", "two\t\ttabs",
+ "one\nnewline", "two\n\nnewlines",
+ "one\fform feed", "two\f\fform feeds",
+ "one\rcarriage return", "two\r\rcarriage returns"
+].forEach(function(str) {
+ test(function() {
+ document.title = str;
+ var title = document.getElementsByTagName("title")[0];
+ assert_equals(title.text, str);
+ assert_equals(title.textContent, str);
+ assert_equals(title.firstChild.nodeValue, str);
+ }, "title.text and space normalization: " + format_value(str))
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/document-metadata/the-title-element/title.text-04.xhtml b/testing/web-platform/tests/html/semantics/document-metadata/the-title-element/title.text-04.xhtml
new file mode 100644
index 000000000..de382ab4d
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/document-metadata/the-title-element/title.text-04.xhtml
@@ -0,0 +1,37 @@
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title> title.text and space normalization </title>
+<link rel="author" title="Ms2ger" href="mailto:ms2ger@gmail.com"/>
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-title-text"/>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+</head>
+<body>
+<div id="log"></div>
+<script>
+test(function() {
+ assert_equals(document.getElementsByTagName("title")[0].text,
+ " title.text and space normalization ");
+ assert_equals(document.getElementsByTagName("title")[0].textContent,
+ " title.text and space normalization ");
+ assert_equals(document.getElementsByTagName("title")[0].firstChild.nodeValue,
+ " title.text and space normalization ");
+}, "title.text and space normalization (markup)");
+[
+ "one space", "two spaces",
+ "one\ttab", "two\t\ttabs",
+ "one\nnewline", "two\n\nnewlines",
+ "one\fform feed", "two\f\fform feeds",
+ "one\rcarriage return", "two\r\rcarriage returns"
+].forEach(function(str) {
+ test(function() {
+ document.title = str;
+ var title = document.getElementsByTagName("title")[0];
+ assert_equals(title.text, str);
+ assert_equals(title.textContent, str);
+ assert_equals(title.firstChild.nodeValue, str);
+ }, "title.text and space normalization: " + format_value(str))
+});
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/edits/.gitkeep b/testing/web-platform/tests/html/semantics/edits/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/edits/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/edits/attributes-common-to-ins-and-del-elements/.gitkeep b/testing/web-platform/tests/html/semantics/edits/attributes-common-to-ins-and-del-elements/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/edits/attributes-common-to-ins-and-del-elements/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/edits/edits-and-lists/.gitkeep b/testing/web-platform/tests/html/semantics/edits/edits-and-lists/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/edits/edits-and-lists/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/edits/edits-and-paragraphs/.gitkeep b/testing/web-platform/tests/html/semantics/edits/edits-and-paragraphs/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/edits/edits-and-paragraphs/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/edits/edits-and-tables/.gitkeep b/testing/web-platform/tests/html/semantics/edits/edits-and-tables/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/edits/edits-and-tables/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/edits/the-del-element/.gitkeep b/testing/web-platform/tests/html/semantics/edits/the-del-element/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/edits/the-del-element/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/edits/the-del-element/del_effect.html b/testing/web-platform/tests/html/semantics/edits/the-del-element/del_effect.html
new file mode 100644
index 000000000..14297e529
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/edits/the-del-element/del_effect.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<meta charset=UTF-8>
+<title>HTML Test: Text in the del element should be 'line-through'</title>
+<link rel="author" title="Intel" href="http://www.intel.com/">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#the-del-element">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<p><del>crossed-off text</del></p>
+<div id="log"></div>
+
+<script>
+ test(function() {
+ var element = document.getElementsByTagName('del')[0],
+ textDecoration = getComputedStyle(element).textDecorationLine ||
+ getComputedStyle(element).textDecoration;
+ assert_equals(textDecoration, 'line-through');
+ });
+</script>
diff --git a/testing/web-platform/tests/html/semantics/edits/the-ins-element/.gitkeep b/testing/web-platform/tests/html/semantics/edits/the-ins-element/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/edits/the-ins-element/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/edits/the-ins-element/ins_effect.html b/testing/web-platform/tests/html/semantics/edits/the-ins-element/ins_effect.html
new file mode 100644
index 000000000..6e1b34459
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/edits/the-ins-element/ins_effect.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<meta charset=UTF-8>
+<title>HTML Test: Text in the ins element should be 'underline'</title>
+<link rel="author" title="Intel" href="http://www.intel.com/">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#the-ins-element">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<p><ins>underlined text</ins></p>
+<div id="log"></div>
+
+<script>
+ test(function() {
+ var element = document.getElementsByTagName('ins')[0],
+ textDecoration = getComputedStyle(element).textDecorationLine ||
+ getComputedStyle(element).textDecoration;
+ assert_equals(textDecoration, 'underline');
+ });
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/.gitkeep b/testing/web-platform/tests/html/semantics/embedded-content/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/dimension-attributes/.gitkeep b/testing/web-platform/tests/html/semantics/embedded-content/dimension-attributes/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/dimension-attributes/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/image-maps/.gitkeep b/testing/web-platform/tests/html/semantics/embedded-content/image-maps/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/image-maps/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/image-maps/contains.json b/testing/web-platform/tests/html/semantics/embedded-content/image-maps/contains.json
new file mode 100644
index 000000000..77e0d34fa
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/image-maps/contains.json
@@ -0,0 +1,10 @@
+[
+ {
+ "id": "authoring",
+ "original_id": "authoring"
+ },
+ {
+ "id": "processing-model-0",
+ "original_id": "processing-model-0"
+ }
+] \ No newline at end of file
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/mathml/.gitkeep b/testing/web-platform/tests/html/semantics/embedded-content/mathml/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/mathml/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/.gitkeep b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/audio_controls_present-manual.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/audio_controls_present-manual.html
new file mode 100644
index 000000000..38faa4d00
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/audio_controls_present-manual.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>Audio Test: audio_controls_present.html</title>
+ <link rel="author" title="Intel" href="http://www.intel.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-media-controls" />
+ <meta name="flags" content="" />
+ <meta name="assert" content="Check if the controls attribute is present in the audio element that expecting the user agent exposes a controller user interface" />
+ </head>
+ <body>
+ <p>Test passes if a controller user interface appears below and the text 'The user agent doesn't support media element.' does not appear anywhere on this page</p>
+ <audio id="m" controls>The user agent doesn't support media element.</audio>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/audio_loop_base.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/audio_loop_base.html
new file mode 100644
index 000000000..4917d9c39
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/audio_loop_base.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>Audio Test: audio_loop_base</title>
+ <link rel="author" title="Intel" href="http://www.intel.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-media-loop" />
+ <meta name="flags" content="" />
+ <meta name="assert" content="Check if audio.loop is set to true that expecting the seeking event is fired more than once" />
+ <meta name=timeout content=long>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/media.js"></script>
+ </head>
+ <body>
+ <div id="log"></div>
+ <audio id="m" controls>The user agent doesn't support media element.</audio>
+ <script type="text/javascript">
+ var media = document.getElementById("m");
+ var name = document.getElementsByName("assert")[0].content;
+ var t = async_test(name);
+
+ var looped = false;
+
+ function startTest() {
+ if (looped) {
+ t.step(function() {
+ assert_true(true, "looped");
+ });
+ t.done();
+ media.pause();
+ }
+
+ looped = true;
+ }
+
+ media.addEventListener("seeking", startTest, false);
+ media.loop = true;
+ media.src = getAudioURI("/media/sound_5") + "?" + new Date() + Math.random();
+ media.play();
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/audio_muted_overriding_volume-manual.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/audio_muted_overriding_volume-manual.html
new file mode 100644
index 000000000..cc1892ce8
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/audio_muted_overriding_volume-manual.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>Audio Test: audio_muted_overriding_volume</title>
+ <link rel="author" title="Intel" href="http://www.intel.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-media-muted" />
+ <meta name="flags" content="" />
+ <meta name="assert" content="Check if the muted attribute is present in the audio element with volume is set to loudest that expecting the user hears no sound" />
+ <script src="/common/media.js"></script>
+ </head>
+ <body>
+ <p>Test passes if the audio is playing without sound output and the text 'The user agent doesn't support media element.' does not appear anywhere on this page</p>
+ <audio id="m" controls muted>The user agent doesn't support media element.</audio>
+ <script type="text/javascript">
+ var media = document.getElementById("m");
+ media.src = getAudioURI("/media/sound_5") + "?" + new Date() + Math.random();
+ media.volume = 1.0;
+ media.play();
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/audio_muted_present-manual.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/audio_muted_present-manual.html
new file mode 100644
index 000000000..16d6f07ee
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/audio_muted_present-manual.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>Audio Test: audio_muted_present</title>
+ <link rel="author" title="Intel" href="http://www.intel.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-media-muted" />
+ <meta name="flags" content="" />
+ <meta name="assert" content="Check if the muted attribute is present in the audio element that expecting the user hears no sound" />
+ <script src="/common/media.js"></script>
+ </head>
+ <body>
+ <p>Test passes if the audio is playing without sound output and the text 'The user agent doesn't support media element.' does not appear anywhere on this page</p>
+ <audio id="m" controls muted>The user agent doesn't support media element.</audio>
+ <script type="text/javascript">
+ var media = document.getElementById("m");
+ media.src = getAudioURI("/media/sound_5") + "?" + new Date() + Math.random();
+ media.play();
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/audio_volume_check.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/audio_volume_check.html
new file mode 100644
index 000000000..b467c702a
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/audio_volume_check.html
@@ -0,0 +1,58 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>Audio Test: audio_volume_check</title>
+ <link rel="author" title="Intel" href="http://www.intel.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-media-volume" />
+ <meta name="flags" content="" />
+ <meta name="assert" content="Check that audio.volume returns the value of the muted content attribute" />
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+ <body>
+ <div id="log"></div>
+ <audio id="m">The user agent doesn't support media element.</audio>
+ <script type="text/javascript">
+ var media = document.getElementById("m");
+ var VOLUME = {
+ 'SILENT' : 0.0,
+ 'NORMAL' : 0.5,
+ 'LOUDEST' : 1.0,
+ 'LOWER' : -1.1,
+ 'UPPER' : 1.1,
+ };
+
+ test(function() {
+ assert_false(media.volume < VOLUME.SILENT || media.volume > VOLUME.LOUDEST, "media.volume outside the range 0.0 to 1.0 inclusive");
+ }, "Check if the intial value of the audio.volume is in the range 0.0 to 1.0 inclusive");
+
+ function volume_setting(vol, name)
+ {
+ if (vol < VOLUME.SILENT || vol > VOLUME.LOUDEST) {
+ try {
+ media.volume = vol;
+ test(function() {
+ assert_true(false, "media.volume setting exception");
+ }, name);
+ } catch(e) {
+ test(function() {
+ // 1 should be e.IndexSizeError or e.INDEX_SIZE_ERR in previous spec
+ assert_equals(e.code, 1, "media.volume setting exception");
+ }, name);
+ }
+ } else {
+ media.volume = vol;
+ test(function() {
+ assert_equals(media.volume, vol, "media.volume new value");
+ }, name);
+ }
+ }
+
+ volume_setting(VOLUME.NORMAL, "Check if audio.volume is able to set to new value in the range 0.0 to 1.0");
+ volume_setting(VOLUME.SILENT, "Check if media.volume is able to set to new value 0.0 as silent");
+ volume_setting(VOLUME.LOUDEST, "Check if media.volume is able to set to new value 1.0 as loudest");
+ volume_setting(VOLUME.LOWER, "Check if media.volume is set to new value less than 0.0 that expecting an IndexSizeError exception is to be thrown");
+ volume_setting(VOLUME.UPPER, "Check if audio.volume is set to new value greater than 1.0 that expecting an IndexSizeError exception is to be thrown");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/audio_volume_loudest-manual.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/audio_volume_loudest-manual.html
new file mode 100644
index 000000000..a623e8f5c
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/audio_volume_loudest-manual.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>Audio Test: audio_volume_loudest</title>
+ <link rel="author" title="Intel" href="http://www.intel.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-media-volume" />
+ <meta name="flags" content="" />
+ <meta name="assert" content="Check if the volume attribute is set to 1.0 as loudest in the audio element that expecting the user hears sound loudly" />
+ <script src="/common/media.js"></script>
+ </head>
+ <body>
+ <p>Test passes if the audio is playing with sound heard and the text 'The user agent doesn't support media element.' does not appear anywhere on this page</p>
+ <audio id="m" controls>The user agent doesn't support media element.</audio>
+ <script type="text/javascript">
+ var media = document.getElementById("m");
+ media.src = getAudioURI("/media/sound_5") + "?" + new Date() + Math.random();
+ media.volume = 1.0;
+ media.play();
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/audio_volume_silent-manual.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/audio_volume_silent-manual.html
new file mode 100644
index 000000000..257bd4628
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/audio_volume_silent-manual.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>Audio Test: audio_volume_silent</title>
+ <link rel="author" title="Intel" href="http://www.intel.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-media-volume" />
+ <meta name="flags" content="" />
+ <meta name="assert" content="Check if the volume attribute is set to 0.0 as silent in the audio element that expecting the user hears no sound" />
+ <script src="/common/media.js"></script>
+ </head>
+ <body>
+ <p>Test passes if the audio is playing without sound heard and the text 'The user agent doesn't support media element.' does not appear anywhere on this page</p>
+ <audio id="m" controls volume=0.0>The user agent doesn't support media element.</audio>
+ <script type="text/javascript">
+ var media = document.getElementById("m");
+ media.src = getAudioURI("/media/sound_5") + "?" + new Date() + Math.random();
+ media.volume = 0.0;
+ media.play();
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/contains.json b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/contains.json
new file mode 100644
index 000000000..9cf23296c
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/contains.json
@@ -0,0 +1,132 @@
+[
+ {
+ "id": "error-codes",
+ "original_id": "error-codes"
+ },
+ {
+ "id": "location-of-the-media-resource",
+ "original_id": "location-of-the-media-resource"
+ },
+ {
+ "id": "mime-types",
+ "original_id": "mime-types"
+ },
+ {
+ "id": "network-states",
+ "original_id": "network-states"
+ },
+ {
+ "id": "loading-the-media-resource",
+ "original_id": "loading-the-media-resource"
+ },
+ {
+ "id": "offsets-into-the-media-resource",
+ "original_id": "offsets-into-the-media-resource"
+ },
+ {
+ "id": "ready-states",
+ "original_id": "ready-states"
+ },
+ {
+ "id": "playing-the-media-resource",
+ "original_id": "playing-the-media-resource"
+ },
+ {
+ "id": "seeking",
+ "original_id": "seeking"
+ },
+ {
+ "id": "media-resources-with-multiple-media-tracks",
+ "original_id": "media-resources-with-multiple-media-tracks",
+ "children": [
+ {
+ "id": "audiotracklist-and-videotracklist-objects",
+ "original_id": "audiotracklist-and-videotracklist-objects"
+ },
+ {
+ "id": "selecting-specific-audio-and-video-tracks-declaratively",
+ "original_id": "selecting-specific-audio-and-video-tracks-declaratively"
+ }
+ ]
+ },
+ {
+ "id": "synchronising-multiple-media-elements",
+ "original_id": "synchronising-multiple-media-elements",
+ "children": [
+ {
+ "id": "introduction-0",
+ "original_id": "introduction-0"
+ },
+ {
+ "id": "media-controllers",
+ "original_id": "media-controllers"
+ },
+ {
+ "id": "assigning-a-media-controller-declaratively",
+ "original_id": "assigning-a-media-controller-declaratively"
+ }
+ ]
+ },
+ {
+ "id": "timed-text-tracks",
+ "original_id": "timed-text-tracks",
+ "children": [
+ {
+ "id": "text-track-model",
+ "original_id": "text-track-model"
+ },
+ {
+ "id": "sourcing-in-band-text-tracks",
+ "original_id": "sourcing-in-band-text-tracks"
+ },
+ {
+ "id": "sourcing-out-of-band-text-tracks",
+ "original_id": "sourcing-out-of-band-text-tracks"
+ },
+ {
+ "id": "guidelines-for-exposing-cues-in-various-formats-as-text-track-cues",
+ "original_id": "guidelines-for-exposing-cues-in-various-formats-as-text-track-cues"
+ },
+ {
+ "id": "text-track-api",
+ "original_id": "text-track-api"
+ },
+ {
+ "id": "text-tracks-describing-chapters",
+ "original_id": "text-tracks-describing-chapters"
+ },
+ {
+ "id": "cue-events",
+ "original_id": "cue-events"
+ }
+ ]
+ },
+ {
+ "id": "user-interface",
+ "original_id": "user-interface"
+ },
+ {
+ "id": "time-ranges",
+ "original_id": "time-ranges"
+ },
+ {
+ "id": "event-definitions",
+ "original_id": "event-definitions"
+ },
+ {
+ "id": "mediaevents",
+ "original_id": "mediaevents"
+ },
+ {
+ "id": "security-and-privacy-considerations",
+ "original_id": "security-and-privacy-considerations"
+ },
+ {
+ "id": "best-practices-for-authors-using-media-elements",
+ "original_id": "best-practices-for-authors-using-media-elements"
+ },
+ {
+ "id": "best-practices-for-implementors-of-media-elements",
+ "original_id": "best-practices-for-implementors-of-media-elements"
+ }
+]
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/error-codes/error.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/error-codes/error.html
new file mode 100644
index 000000000..c97576041
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/error-codes/error.html
@@ -0,0 +1,38 @@
+<!doctype html>
+<title>error</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/media.js"></script>
+<div id="log"></div>
+<script>
+function error_test(tagName, src) {
+ test(function() {
+ assert_equals(document.createElement(tagName).error, null);
+ }, tagName + '.error initial value');
+
+ async_test(function(t) {
+ var e = document.createElement(tagName);
+ e.src = src;
+ e.onloadeddata = t.step_func(function() {
+ assert_equals(e.error, null);
+ t.done();
+ });
+ }, tagName + '.error after successful load');
+
+ // TODO: MEDIA_ERR_ABORTED, MEDIA_ERR_NETWORK, MEDIA_ERR_DECODE
+
+ async_test(function(t) {
+ var e = document.createElement(tagName);
+ e.src = '';
+ e.onerror = t.step_func(function() {
+ assert_true(e.error instanceof MediaError);
+ assert_equals(e.error.code, 4);
+ assert_equals(e.error.code, e.error.MEDIA_ERR_SRC_NOT_SUPPORTED);
+ t.done();
+ });
+ }, tagName + '.error after setting src to the empty string');
+}
+
+error_test('audio', getAudioURI('/media/sound_5'));
+error_test('video', getVideoURI('/media/movie_5'));
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_canplay.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_canplay.html
new file mode 100644
index 000000000..8e1b32dcb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_canplay.html
@@ -0,0 +1,38 @@
+<!doctype html>
+<html>
+ <head>
+ <title>{audio,video} events - canplay</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/media.js"></script>
+ </head>
+ <body>
+ <p><a href="https://html.spec.whatwg.org/multipage/#mediaevents">spec reference</a></p>
+ <audio id="a" autoplay controls>
+ </audio>
+ <video id="v" autoplay controls>
+ </video>
+ <div id="log"></div>
+ <script>
+test(function() {
+ var t = async_test("setting src attribute on autoplay audio should trigger canplay event", {timeout:5000});
+ var a = document.getElementById("a");
+ a.addEventListener("canplay", function() {
+ t.done();
+ a.pause();
+ }, false);
+ a.src = getAudioURI("/media/sound_5") + "?" + new Date() + Math.random();
+}, "audio events - canplay");
+
+test(function() {
+ var t = async_test("setting src attribute on autoplay video should trigger canplay event", {timeout:5000});
+ var v = document.getElementById("v");
+ v.addEventListener("canplay", function() {
+ t.done();
+ v.pause();
+ }, false);
+ v.src = getVideoURI("/media/movie_5") + "?" + new Date() + Math.random();
+}, "video events - canplay");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_canplay_noautoplay.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_canplay_noautoplay.html
new file mode 100644
index 000000000..8f3372501
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_canplay_noautoplay.html
@@ -0,0 +1,36 @@
+<!doctype html>
+<html>
+ <head>
+ <title>{audio,video} events - canplay</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/media.js"></script>
+ </head>
+ <body>
+ <p><a href="https://html.spec.whatwg.org/multipage/#mediaevents">spec reference</a></p>
+ <audio id="a" controls>
+ </audio>
+ <video id="v" controls>
+ </video>
+ <div id="log"></div>
+ <script>
+test(function () {
+ var t = async_test("setting src attribute on non-autoplay audio should trigger canplay event", {timeout:5000});
+ var a = document.getElementById("a");
+ a.addEventListener("canplay", function() {
+ t.done();
+ }, false);
+ a.src = getAudioURI("/media/sound_5") + "?" + new Date() + Math.random();
+}, "audio events - canplay");
+
+test(function () {
+ var t = async_test("setting src attribute on non-autoplay video should trigger canplay event", {timeout:5000});
+ var v = document.getElementById("v");
+ v.addEventListener("canplay", function() {
+ t.done();
+ }, false);
+ v.src = getVideoURI("/media/movie_5") + "?" + new Date() + Math.random();
+}, "video events - canplay");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_canplaythrough.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_canplaythrough.html
new file mode 100644
index 000000000..827e79607
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_canplaythrough.html
@@ -0,0 +1,38 @@
+<!doctype html>
+<html>
+ <head>
+ <title>{audio,video} events - canplaythrough</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/media.js"></script>
+ </head>
+ <body>
+ <p><a href="https://html.spec.whatwg.org/multipage/#mediaevents">spec reference</a></p>
+ <audio id="a" autoplay controls>
+ </audio>
+ <video id="v" autoplay controls>
+ </video>
+ <div id="log"></div>
+ <script>
+test(function() {
+ var t = async_test("setting src attribute on autoplay audio should trigger canplaythrough event", {timeout:5000});
+ var a = document.getElementById("a");
+ a.addEventListener("canplaythrough", function() {
+ t.done();
+ a.pause();
+ }, false);
+ a.src = getAudioURI("/media/sound_5") + "?" + new Date() + Math.random();
+}, "audio events - canplaythrough");
+
+test(function() {
+ var t = async_test("setting src attribute on autoplay video should trigger canplaythrough event", {timeout:5000});
+ var v = document.getElementById("v");
+ v.addEventListener("canplaythrough", function() {
+ t.done();
+ v.pause();
+ }, false);
+ v.src = getVideoURI("/media/movie_5") + "?" + new Date() + Math.random();
+}, "video events - canplaythrough");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_canplaythrough_noautoplay.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_canplaythrough_noautoplay.html
new file mode 100644
index 000000000..75a70985a
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_canplaythrough_noautoplay.html
@@ -0,0 +1,36 @@
+<!doctype html>
+<html>
+ <head>
+ <title>{audio,video} events - canplaythrough</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/media.js"></script>
+ </head>
+ <body>
+ <p><a href="https://html.spec.whatwg.org/multipage/#mediaevents">spec reference</a></p>
+ <audio id="a" controls>
+ </audio>
+ <video id="v" controls>
+ </video>
+ <div id="log"></div>
+ <script>
+test(function() {
+ var t = async_test("setting src attribute on non-autoplay audio should trigger canplaythrough event", {timeout:5000});
+ var a = document.getElementById("a");
+ a.addEventListener("canplaythrough", function() {
+ t.done();
+ }, false);
+ a.src = getAudioURI("/media/sound_5") + "?" + new Date() + Math.random();
+}, "audio events - canplaythrough");
+
+test(function() {
+ var t = async_test("setting src attribute on non-autoplay video should trigger canplaythrough event", {timeout:5000});
+ var v = document.getElementById("v");
+ v.addEventListener("canplaythrough", function() {
+ t.done();
+ }, false);
+ v.src = getVideoURI("/media/movie_5") + "?" + new Date() + Math.random();
+}, "video events - canplaythrough");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_loadeddata.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_loadeddata.html
new file mode 100644
index 000000000..f0e89c3c1
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_loadeddata.html
@@ -0,0 +1,38 @@
+<!doctype html>
+<html>
+ <head>
+ <title>{audio,video} events - loadeddata</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/media.js"></script>
+ </head>
+ <body>
+ <p><a href="https://html.spec.whatwg.org/multipage/#mediaevents">spec reference</a></p>
+ <audio id="a" autoplay controls>
+ </audio>
+ <video id="v" autoplay controls>
+ </video>
+ <div id="log"></div>
+ <script>
+test(function() {
+ var t = async_test("setting src attribute on autoplay audio should trigger loadeddata event", {timeout:5000});
+ var a = document.getElementById("a");
+ a.addEventListener("loadeddata", function() {
+ t.done();
+ a.pause();
+ }, false);
+ a.src = getAudioURI("/media/sound_5") + "?" + new Date() + Math.random();
+}, "audio events - loadeddata");
+
+test(function() {
+ var t = async_test("setting src attribute on autoplay video should trigger loadeddata event", {timeout:5000});
+ var a = document.getElementById("v");
+ v.addEventListener("loadeddata", function() {
+ t.done();
+ v.pause();
+ }, false);
+ v.src = getVideoURI("/media/movie_5") + "?" + new Date() + Math.random();
+}, "video events - loadeddata");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_loadeddata_noautoplay.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_loadeddata_noautoplay.html
new file mode 100644
index 000000000..0c81f335b
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_loadeddata_noautoplay.html
@@ -0,0 +1,36 @@
+<!doctype html>
+<html>
+ <head>
+ <title>{audio,video} events - loadeddata</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/media.js"></script>
+ </head>
+ <body>
+ <p><a href="https://html.spec.whatwg.org/multipage/#mediaevents">spec reference</a></p>
+ <audio id="a" controls>
+ </audio>
+ <video id="v" controls>
+ </video>
+ <div id="log"></div>
+ <script>
+test(function() {
+ var t = async_test("setting src attribute on non-autoplay audio should trigger loadeddata event", {timeout:5000});
+ var a = document.getElementById("a");
+ a.addEventListener("loadeddata", function() {
+ t.done();
+ }, false);
+ a.src = getAudioURI("/media/sound_5") + "?" + new Date() + Math.random();
+}, "audio events - loadeddata");
+
+test(function() {
+ var t = async_test("setting src attribute on non-autoplay video should trigger loadeddata event", {timeout:5000});
+ var v = document.getElementById("v");
+ v.addEventListener("loadeddata", function() {
+ t.done();
+ }, false);
+ v.src = getVideoURI("/media/movie_5") + "?" + new Date() + Math.random();
+}, "video events - loadeddata");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_loadedmetadata.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_loadedmetadata.html
new file mode 100644
index 000000000..234121e58
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_loadedmetadata.html
@@ -0,0 +1,38 @@
+<!doctype html>
+<html>
+ <head>
+ <title>{audio,video} events - loadedmetadata</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/media.js"></script>
+ </head>
+ <body>
+ <p><a href="https://html.spec.whatwg.org/multipage/#mediaevents">spec reference</a></p>
+ <audio id="a" autoplay controls>
+ </audio>
+ <video id="v" autoplay controls>
+ </video>
+ <div id="log"></div>
+ <script>
+test(function() {
+ var t = async_test("setting src attribute on autoplay audio should trigger loadedmetadata event", {timeout:5000});
+ var a = document.getElementById("a");
+ a.addEventListener("loadedmetadata", function() {
+ t.done();
+ a.pause();
+ });
+ a.src = getAudioURI("/media/sound_5") + "?" + new Date() + Math.random();
+}, "audio events - loadedmetadata");
+
+test(function() {
+ var t = async_test("setting src attribute on autoplay video should trigger loadedmetadata event", {timeout:5000});
+ var v = document.getElementById("v");
+ v.addEventListener("loadedmetadata", function() {
+ t.done();
+ v.pause();
+ });
+ v.src = getVideoURI("/media/movie_5") + "?" + new Date() + Math.random();
+}, "video events - loadedmetadata");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_loadedmetadata_noautoplay.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_loadedmetadata_noautoplay.html
new file mode 100644
index 000000000..382f3f6fb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_loadedmetadata_noautoplay.html
@@ -0,0 +1,36 @@
+<!doctype html>
+<html>
+ <head>
+ <title>{audio,video} events - loadedmetadata</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/media.js"></script>
+ </head>
+ <body>
+ <p><a href="https://html.spec.whatwg.org/multipage/#mediaevents">spec reference</a></p>
+ <audio id="a" controls>
+ </audio>
+ <video id="v" controls>
+ </video>
+ <div id="log"></div>
+ <script>
+test(function() {
+ var t = async_test("setting src attribute on non-autoplay audio should trigger loadedmetadata event", {timeout:5000});
+ var a = document.getElementById("a");
+ a.addEventListener("loadedmetadata", function() {
+ t.done();
+ }, false);
+ a.src = getAudioURI("/media/sound_5") + "?" + new Date() + Math.random();
+}, "audio events - loadedmetadata");
+
+test(function() {
+ var t = async_test("setting src attribute on non-autoplay video should trigger loadedmetadata event", {timeout:5000});
+ var v = document.getElementById("v");
+ v.addEventListener("loadedmetadata", function() {
+ t.done();
+ }, false);
+ v.src = getVideoURI("/media/movie_5") + "?" + new Date() + Math.random();
+}, "video events, loadedmetadata");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_loadstart.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_loadstart.html
new file mode 100644
index 000000000..de4568212
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_loadstart.html
@@ -0,0 +1,38 @@
+<!doctype html>
+<html>
+ <head>
+ <title>{audio,video} events - loadstart</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/media.js"></script>
+ </head>
+ <body>
+ <p><a href="https://html.spec.whatwg.org/multipage/#mediaevents">spec reference</a></p>
+ <audio id="a" autoplay controls>
+ </audio>
+ <video id="v" autoplay controls>
+ </video>
+ <div id="log"></div>
+ <script>
+test(function() {
+ var t = async_test("setting src attribute on autoplay audio should trigger loadstart event", {timeout:5000});
+ var a = document.getElementById("a");
+ a.addEventListener("loadstart", function() {
+ t.done();
+ a.pause();
+ }, false);
+ a.src = getAudioURI("/media/sound_5") + "?" + new Date() + Math.random();
+}, "audio events - loadstart");
+
+test(function() {
+ var t = async_test("setting src attribute on autoplay video should trigger loadstart event", {timeout:5000});
+ var v = document.getElementById("v");
+ v.addEventListener("loadstart", function() {
+ t.done();
+ v.pause();
+ }, false);
+ v.src = getVideoURI("/media/movie_5") + "?" + new Date() + Math.random();
+}, "video events - loadstart");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_loadstart_noautoplay.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_loadstart_noautoplay.html
new file mode 100644
index 000000000..b575e7ac8
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_loadstart_noautoplay.html
@@ -0,0 +1,36 @@
+<!doctype html>
+<html>
+ <head>
+ <title>{audio,video} events - loadstart</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/media.js"></script>
+ </head>
+ <body>
+ <p><a href="https://html.spec.whatwg.org/multipage/#mediaevents">spec reference</a></p>
+ <audio id="a" controls>
+ </audio>
+ <video id="v" controls>
+ </video>
+ <div id="log"></div>
+ <script>
+test(function() {
+ var t = async_test("setting src attribute on non-autoplay audio should trigger loadstart event", {timeout:5000});
+ var a = document.getElementById("a");
+ a.addEventListener("loadstart", function() {
+ t.done();
+ }, false);
+ a.src = getAudioURI("/media/sound_5") + "?" + new Date() + Math.random();
+}, "audio events - loadstart");
+
+test(function() {
+ var t = async_test("setting src attribute on non-autoplay video should trigger loadstart event", {timeout:5000});
+ var v = document.getElementById("v");
+ v.addEventListener("loadstart", function() {
+ t.done();
+ }, false);
+ v.src = getVideoURI("/media/movie_5") + "?" + new Date() + Math.random();
+}, "video events - loadstart");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_order_canplay_canplaythrough.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_order_canplay_canplaythrough.html
new file mode 100644
index 000000000..a1e7e4155
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_order_canplay_canplaythrough.html
@@ -0,0 +1,52 @@
+<!doctype html>
+<html>
+ <head>
+ <title>{audio,video} events - canplay, then canplaythrough</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/media.js"></script>
+ </head>
+ <body>
+ <p><a href="https://html.spec.whatwg.org/multipage/#mediaevents">spec reference</a></p>
+ <audio id="a" autoplay controls>
+ </audio>
+ <video id="v" autoplay controls>
+ </video>
+ <div id="log"></div>
+ <script>
+test(function() {
+ var t = async_test("setting src attribute on autoplay audio should trigger canplay then canplaythrough event", {timeout:5000});
+ var a = document.getElementById("a");
+ var found_canplay = false;
+ a.addEventListener("canplay", function() {
+ found_canplay = true;
+ });
+ a.addEventListener("canplaythrough", function() {
+ t.step(function() {
+ assert_true(found_canplay);
+ });
+ t.done();
+ a.pause();
+ }, false);
+ a.src = getAudioURI("/media/sound_5") + "?" + new Date() + Math.random();
+}, "audio events - canplay, then canplaythrough");
+
+test(function() {
+ var t = async_test("setting src attribute on autoplay video should trigger canplay then canplaythrough event", {timeout:5000});
+ var v = document.getElementById("v");
+ var found_canplay = false;
+ v.addEventListener("canplay", function() {
+ found_canplay = true;
+ });
+ v.addEventListener("canplaythrough", function() {
+ t.step(function() {
+ assert_true(found_canplay);
+ });
+ t.done();
+ v.pause();
+ }, false);
+ v.src = getVideoURI("/media/movie_5") + "?" + new Date() + Math.random();
+}, "video events - canplay, then canplaythrough");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_order_canplay_playing.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_order_canplay_playing.html
new file mode 100644
index 000000000..a5a67ddb2
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_order_canplay_playing.html
@@ -0,0 +1,52 @@
+<!doctype html>
+<html>
+ <head>
+ <title>{audio,video} events - canplay, then playing</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/media.js"></script>
+ </head>
+ <body>
+ <p><a href="https://html.spec.whatwg.org/multipage/#mediaevents">spec reference</a></p>
+ <audio id="a" autoplay controls>
+ </audio>
+ <video id="v" autoplay controls>
+ </video>
+ <div id="log"></div>
+ <script>
+test(function() {
+ var t = async_test("setting src attribute on autoplay audio should trigger canplay then playing event", {timeout:5000});
+ var a = document.getElementById("a");
+ var found_canplay = false;
+ a.addEventListener("canplay", function() {
+ found_canplay = true;
+ });
+ a.addEventListener("playing", function() {
+ t.step(function() {
+ assert_true(found_canplay);
+ });
+ t.done();
+ a.pause();
+ }, false);
+ a.src = getAudioURI("/media/sound_5") + "?" + new Date() + Math.random();
+}, "audio events - canplay, then playing");
+
+test(function() {
+ var t = async_test("setting src attribute on autoplay video should trigger canplay then playing event", {timeout:5000});
+ var v = document.getElementById("v");
+ var found_canplay = false;
+ v.addEventListener("canplay", function() {
+ found_canplay = true;
+ });
+ v.addEventListener("playing", function() {
+ t.step(function() {
+ assert_true(found_canplay);
+ });
+ t.done();
+ v.pause();
+ }, false);
+ v.src = getVideoURI("/media/movie_5") + "?" + new Date() + Math.random();
+}, "video events - canplay, then playing");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_order_loadedmetadata_loadeddata.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_order_loadedmetadata_loadeddata.html
new file mode 100644
index 000000000..3aba3684f
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_order_loadedmetadata_loadeddata.html
@@ -0,0 +1,52 @@
+<!doctype html>
+<html>
+ <head>
+ <title>{audio,video} events - loadedmetadata, then loadeddata</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/media.js"></script>
+ </head>
+ <body>
+ <p><a href="https://html.spec.whatwg.org/multipage/#mediaevents">spec reference</a></p>
+ <audio id="a" autoplay controls>
+ </audio>
+ <video id="v" autoplay controls>
+ </video>
+ <div id="log"></div>
+ <script>
+test(function() {
+ var t = async_test("setting src attribute on autoplay audio should trigger loadedmetadata then loadeddata event", {timeout:5000});
+ var a = document.getElementById("a");
+ var found_loadedmetadata = false;
+ a.addEventListener("loadedmetadata", function() {
+ found_loadedmetadata = true;
+ });
+ a.addEventListener("loadeddata", function() {
+ t.step(function() {
+ assert_true(found_loadedmetadata);
+ });
+ t.done();
+ a.pause();
+ }, false);
+ a.src = getAudioURI("/media/sound_5") + "?" + new Date() + Math.random();
+}, "audio events - loadedmetadata, then loadeddata");
+
+test(function() {
+ var t = async_test("setting src attribute on autoplay video should trigger loadedmetadata then loadeddata event", {timeout:5000});
+ var v = document.getElementById("v");
+ var found_loadedmetadata = false;
+ v.addEventListener("loadedmetadata", function() {
+ found_loadedmetadata = true;
+ });
+ v.addEventListener("loadeddata", function() {
+ t.step(function() {
+ assert_true(found_loadedmetadata);
+ });
+ t.done();
+ v.pause();
+ }, false);
+ v.src = getVideoURI("/media/movie_5") + "?" + new Date() + Math.random();
+}, "video events - loadedmetadata, then loadeddata");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_order_loadstart_progress.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_order_loadstart_progress.html
new file mode 100644
index 000000000..75e3ba772
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_order_loadstart_progress.html
@@ -0,0 +1,52 @@
+<!doctype html>
+<html>
+ <head>
+ <title>{audio,video} events - loadstart, then progress</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/media.js"></script>
+ </head>
+ <body>
+ <p><a href="https://html.spec.whatwg.org/multipage/#mediaevents">spec reference</a></p>
+ <audio id="a" autoplay controls>
+ </audio>
+ <video id="v" autoplay controls>
+ </video>
+ <div id="log"></div>
+ <script>
+test(function() {
+ var t = async_test("setting src attribute on autoplay audio should trigger loadstart then progress event", {timeout:5000});
+ var a = document.getElementById("a");
+ var found_loadstart = false;
+ a.addEventListener("loadstart", function() {
+ found_loadstart = true;
+ });
+ a.addEventListener("progress", function() {
+ t.step(function() {
+ assert_true(found_loadstart);
+ });
+ t.done();
+ a.pause();
+ }, false);
+ a.src = getAudioURI("/media/sound_5") + "?" + new Date() + Math.random();
+}, "audio events - loadstart, then progress");
+
+test(function() {
+ var t = async_test("setting src attribute on autoplay video should trigger loadstart then progress event", {timeout:5000});
+ var v = document.getElementById("v");
+ var found_loadstart = false;
+ v.addEventListener("loadstart", function() {
+ found_loadstart = true;
+ });
+ v.addEventListener("progress", function() {
+ t.step(function() {
+ assert_true(found_loadstart);
+ });
+ t.done();
+ v.pause();
+ }, false);
+ v.src = getVideoURI("/media/movie_5") + "?" + new Date() + Math.random();
+}, "video events - loadstart, then progress");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_pause.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_pause.html
new file mode 100644
index 000000000..1f7904c3b
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_pause.html
@@ -0,0 +1,48 @@
+<!doctype html>
+<html>
+ <head>
+ <title>{audio,video} events - pause</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/media.js"></script>
+ </head>
+ <body>
+ <p><a href="https://html.spec.whatwg.org/multipage/#mediaevents">spec reference</a></p>
+ <audio id="a" autoplay controls>
+ </audio>
+ <video id="v" autoplay controls>
+ </video>
+ <div id="log"></div>
+ <script>
+test(function() {
+ var t = async_test("calling pause() on autoplay audio should trigger pause event", {timeout:5000});
+ var a = document.getElementById("a");
+ a.addEventListener("pause", function() {
+ t.step(function() {
+ assert_true(true);
+ });
+ t.done();
+ }, false);
+ a.addEventListener("play", function() {
+ a.pause(); // pause right after play
+ });
+ a.src = getAudioURI("/media/sound_5") + "?" + new Date() + Math.random();
+}, "audio events - pause");
+
+test(function() {
+ var t = async_test("calling pause() on autoplay video should trigger pause event", {timeout:5000});
+ var v = document.getElementById("v");
+ v.addEventListener("pause", function() {
+ t.step(function() {
+ assert_true(true);
+ });
+ t.done();
+ }, false);
+ v.addEventListener("play", function() {
+ v.pause(); // pause right after play
+ });
+ v.src = getVideoURI("/media/movie_5") + "?" + new Date() + Math.random();
+}, "video events - pause");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_pause_noautoplay.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_pause_noautoplay.html
new file mode 100644
index 000000000..554823483
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_pause_noautoplay.html
@@ -0,0 +1,40 @@
+<!doctype html>
+<html>
+ <head>
+ <title>{audio,video} events - pause</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/media.js"></script>
+ </head>
+ <body>
+ <p><a href="https://html.spec.whatwg.org/multipage/#mediaevents">spec reference</a></p>
+ <audio id="a" controls>
+ </audio>
+ <video id="v" controls>
+ </video>
+ <div id="log"></div>
+ <script>
+test(function() {
+ var t = async_test("calling play() then pause() on non-autoplay audio should trigger pause event", {timeout:5000});
+ var a = document.getElementById("a");
+ a.addEventListener("pause", function() {
+ t.done();
+ }, false);
+ a.src = getAudioURI("/media/sound_5") + "?" + new Date() + Math.random();
+ a.play();
+ a.pause();
+}, "audio events - pause");
+
+test(function() {
+ var t = async_test("calling play() then pause() on non-autoplay video should trigger pause event", {timeout:5000});
+ var v = document.getElementById("v");
+ v.addEventListener("pause", function() {
+ t.done();
+ }, false);
+ v.src = getVideoURI("/media/movie_5") + "?" + new Date() + Math.random();
+ v.play();
+ v.pause();
+}, "video events - pause");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_play.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_play.html
new file mode 100644
index 000000000..82b2ca407
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_play.html
@@ -0,0 +1,38 @@
+<!doctype html>
+<html>
+ <head>
+ <title>{audio,video} events - play</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/media.js"></script>
+ </head>
+ <body>
+ <p><a href="https://html.spec.whatwg.org/multipage/#mediaevents">spec reference</a></p>
+ <audio id="a" autoplay controls>
+ </audio>
+ <video id="v" autoplay controls>
+ </video>
+ <div id="log"></div>
+ <script>
+test(function() {
+ var t = async_test("setting src attribute on autoplay audio should trigger play event", {timeout:5000});
+ var a = document.getElementById("a");
+ a.addEventListener("play", function() {
+ t.done();
+ a.pause();
+ }, false);
+ a.src = getAudioURI("/media/sound_5") + "?" + new Date() + Math.random();
+}, "audio events - play");
+
+test(function() {
+ var t = async_test("setting src attribute on autoplay video should trigger play event", {timeout:5000});
+ var v = document.getElementById("v");
+ v.addEventListener("play", function() {
+ t.done();
+ v.pause();
+ }, false);
+ v.src = getVideoURI("/media/movie_5") + "?" + new Date() + Math.random();
+}, "video events - play");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_play_noautoplay.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_play_noautoplay.html
new file mode 100644
index 000000000..67285a95a
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_play_noautoplay.html
@@ -0,0 +1,40 @@
+<!doctype html>
+<html>
+ <head>
+ <title>{audio,video} events - play</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/media.js"></script>
+ </head>
+ <body>
+ <p><a href="https://html.spec.whatwg.org/multipage/#mediaevents">spec reference</a></p>
+ <audio id="a" controls>
+ </audio>
+ <video id="v" controls>
+ </video>
+ <div id="log"></div>
+ <script>
+test(function() {
+ var t = async_test("calling play() on audio should trigger play event", {timeout:5000});
+ var a = document.getElementById("a");
+ a.addEventListener("play", function() {
+ t.done();
+ a.pause();
+ }, false);
+ a.src = getAudioURI("/media/sound_5") + "?" + new Date() + Math.random();
+ a.play();
+}, "audio events - play");
+
+test(function() {
+ var t = async_test("calling play() on video should trigger play event", {timeout:5000});
+ var v = document.getElementById("v");
+ v.addEventListener("play", function() {
+ t.done();
+ v.pause();
+ }, false);
+ v.src = getVideoURI("/media/movie_5") + "?" + new Date() + Math.random();
+ v.play();
+}, "video events - play");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_playing.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_playing.html
new file mode 100644
index 000000000..3741a1c98
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_playing.html
@@ -0,0 +1,38 @@
+<!doctype html>
+<html>
+ <head>
+ <title>{audio,video} events - playing</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/media.js"></script>
+ </head>
+ <body>
+ <p><a href="https://html.spec.whatwg.org/multipage/#mediaevents">spec reference</a></p>
+ <audio id="a" autoplay controls>
+ </audio>
+ <video id="v" autoplay controls>
+ </video>
+ <div id="log"></div>
+ <script>
+test(function() {
+ var t = async_test("setting src attribute on autoplay audio should trigger playing event", {timeout:5000});
+ var a = document.getElementById("a");
+ a.addEventListener("playing", function() {
+ t.done();
+ a.pause();
+ }, false);
+ a.src = getAudioURI("/media/sound_5") + "?" + new Date() + Math.random();
+}, "audio events - playing");
+
+test(function() {
+ var t = async_test("setting src attribute on autoplay video should trigger playing event", {timeout:5000});
+ var v = document.getElementById("v");
+ v.addEventListener("playing", function() {
+ t.done();
+ v.pause();
+ }, false);
+ v.src = getVideoURI("/media/movie_5") + "?" + new Date() + Math.random();
+}, "video events - playing");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_playing_noautoplay.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_playing_noautoplay.html
new file mode 100644
index 000000000..f750085ed
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_playing_noautoplay.html
@@ -0,0 +1,40 @@
+<!doctype html>
+<html>
+ <head>
+ <title>{audio,video} events - playing</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/media.js"></script>
+ </head>
+ <body>
+ <p><a href="https://html.spec.whatwg.org/multipage/#mediaevents">spec reference</a></p>
+ <audio id="a" controls>
+ </audio>
+ <video id="v" controls>
+ </video>
+ <div id="log"></div>
+ <script>
+test(function() {
+ var t = async_test("calling play() on audio should trigger playing event", {timeout:5000});
+ var a = document.getElementById("a");
+ a.addEventListener("playing", function() {
+ t.done();
+ a.pause();
+ });
+ a.src = getAudioURI("/media/sound_5") + "?" + new Date() + Math.random();
+ a.play();
+}, "audio events - playing");
+
+test(function() {
+ var t = async_test("calling play() on video should trigger playing event", {timeout:5000});
+ var v = document.getElementById("v");
+ v.addEventListener("playing", function() {
+ t.done();
+ v.pause();
+ });
+ v.src = getVideoURI("/media/movie_5") + "?" + new Date() + Math.random();
+ v.play();
+}, "video events - playing");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_progress.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_progress.html
new file mode 100644
index 000000000..269f824f7
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_progress.html
@@ -0,0 +1,38 @@
+<!doctype html>
+<html>
+ <head>
+ <title>{audio,video} events - progress</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/media.js"></script>
+ </head>
+ <body>
+ <p><a href="https://html.spec.whatwg.org/multipage/#mediaevents">spec reference</a></p>
+ <audio id="a" autoplay controls>
+ </audio>
+ <video id="v" autoplay controls>
+ </video>
+ <div id="log"></div>
+ <script>
+test(function() {
+ var t = async_test("setting src attribute on autoplay audio should trigger progress event", {timeout:5000});
+ var a = document.getElementById("a");
+ a.addEventListener("progress", function() {
+ t.done();
+ a.pause();
+ }, false);
+ a.src = getAudioURI("/media/sound_5") + "?" + new Date() + Math.random();
+}, "audio events - progress");
+
+test(function() {
+ var t = async_test("setting src attribute on autoplay video should trigger progress event", {timeout:5000});
+ var v = document.getElementById("v");
+ v.addEventListener("progress", function() {
+ t.done();
+ v.pause();
+ }, false);
+ v.src = getVideoURI("/media/movie_5") + "?" + new Date() + Math.random();
+}, "video events - progress");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_progress_noautoplay.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_progress_noautoplay.html
new file mode 100644
index 000000000..c594f3036
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_progress_noautoplay.html
@@ -0,0 +1,36 @@
+<!doctype html>
+<html>
+ <head>
+ <title>{audio,video} events - progress</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/media.js"></script>
+ </head>
+ <body>
+ <p><a href="https://html.spec.whatwg.org/multipage/#mediaevents">spec reference</a></p>
+ <audio id="a" controls>
+ </audio>
+ <video id="v" controls>
+ </video>
+ <div id="log"></div>
+ <script>
+test(function() {
+ var t = async_test("setting src attribute on non-autoplay audio should trigger progress event", {timeout:5000});
+ var a = document.getElementById("a");
+ a.addEventListener("progress", function() {
+ t.done();
+ }, false);
+ a.src = getAudioURI("/media/sound_5") + "?" + new Date() + Math.random();
+}, "audio events - progress");
+
+test(function() {
+ var t = async_test("setting src attribute on non-autoplay video should trigger progress event", {timeout:5000});
+ var v = document.getElementById("v");
+ v.addEventListener("progress", function() {
+ t.done();
+ }, false);
+ v.src = getVideoURI("/media/movie_5") + "?" + new Date() + Math.random();
+}, "video events - progress");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_timeupdate.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_timeupdate.html
new file mode 100644
index 000000000..cc0a17fe2
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_timeupdate.html
@@ -0,0 +1,34 @@
+<!doctype html>
+<html>
+ <head>
+ <title>{audio,video} events - timeupdate</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/media.js"></script>
+ </head>
+ <body>
+ <p><a href="https://html.spec.whatwg.org/multipage/#mediaevents">spec reference</a></p>
+ <audio id="a" autoplay controls>
+ </audio>
+ <video id="v" autoplay controls>
+ </video>
+ <div id="log"></div>
+ <script>
+var ta = async_test("setting src attribute on a sufficiently long autoplay audio should trigger timeupdate event", {timeout:5000});
+var a = document.getElementById("a");
+a.addEventListener("timeupdate", function() {
+ ta.done();
+ a.pause();
+}, false);
+a.src = getAudioURI("/media/sound_5") + "?" + new Date() + Math.random();
+
+var tv = async_test("setting src attribute on a sufficiently long autoplay video should trigger timeupdate event", {timeout:5000});
+var v = document.getElementById("v");
+v.addEventListener("timeupdate", function() {
+ tv.done();
+ v.pause();
+}, false);
+v.src = getVideoURI("/media/movie_5") + "?" + new Date() + Math.random();
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_timeupdate_noautoplay.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_timeupdate_noautoplay.html
new file mode 100644
index 000000000..feb4b8568
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_timeupdate_noautoplay.html
@@ -0,0 +1,40 @@
+<!doctype html>
+<html>
+ <head>
+ <title>{audio,video} events - timeupdate</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/media.js"></script>
+ </head>
+ <body>
+ <p><a href="https://html.spec.whatwg.org/multipage/#mediaevents">spec reference</a></p>
+ <audio id="a" controls>
+ </audio>
+ <video id="v" controls>
+ </video>
+ <div id="log"></div>
+ <script>
+test(function() {
+ var t = async_test("calling play() on a sufficiently long audio should trigger timeupdate event", {timeout:5000});
+ var a = document.getElementById("a");
+ a.addEventListener("timeupdate", function() {
+ t.done();
+ a.pause();
+ }, false);
+ a.src = getAudioURI("/media/sound_5") + "?" + new Date() + Math.random();
+ a.play();
+}, "audio events - timeupdate");
+
+test(function() {
+ var t = async_test("calling play() on a sufficiently long video should trigger timeupdate event", {timeout:5000});
+ var v = document.getElementById("v");
+ v.addEventListener("timeupdate", function() {
+ t.done();
+ v.pause();
+ }, false);
+ v.src = getVideoURI("/media/movie_5") + "?" + new Date() + Math.random();
+ v.play();
+}, "video events - timeupdate");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_volumechange.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_volumechange.html
new file mode 100644
index 000000000..3481947e8
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/event_volumechange.html
@@ -0,0 +1,72 @@
+<!doctype html>
+<title>volumechange event</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<script>
+function volumechange_test(tagName) {
+ async_test(function(t) {
+ var e = document.createElement(tagName);
+ assert_equals(e.volume, 1);
+ e.volume = 0.5;
+ assert_equals(e.volume, 0.5);
+ e.onvolumechange = t.step_func(function() {
+ assert_equals(e.volume, 0.5);
+ e.volume = 1;
+ assert_equals(e.volume, 1);
+ e.onvolumechange = t.step_func(function() {
+ assert_equals(e.volume, 1);
+ t.done();
+ });
+ });
+ }, "setting " + tagName + ".volume fires volumechange");
+
+ async_test(function(t) {
+ var e = document.createElement(tagName);
+ assert_false(e.muted);
+ e.muted = true;
+ assert_true(e.muted);
+ e.onvolumechange = t.step_func(function() {
+ assert_true(e.muted);
+ e.muted = false;
+ assert_false(e.muted);
+ e.onvolumechange = t.step_func(function() {
+ assert_false(e.muted);
+ t.done();
+ });
+ });
+ }, "setting " + tagName + ".muted fires volumechange");
+
+ async_test(function(t) {
+ var e = document.createElement(tagName);
+ e.volume = e.volume;
+ e.muted = e.muted;
+ e.onvolumechange = t.step_func(function() {
+ assert_unreached();
+ });
+ var e2 = document.createElement(tagName);
+ e2.muted = !e2.muted;
+ e2.onvolumechange = t.step_func(function() {
+ t.done();
+ });
+ }, "setting " + tagName + ".volume/muted to the same value does not fire volumechange");
+
+ async_test(function(t) {
+ var e = document.createElement(tagName);
+ e.muted = !e.muted;
+ e.volume = 1 - e.volume;
+ e.muted = !e.muted;
+ e.volume = 1 - e.volume;
+ var volumechange_count = 0;
+ e.onvolumechange = t.step_func(function() {
+ volumechange_count++;
+ if (volumechange_count == 4) {
+ t.done();
+ }
+ });
+ }, "setting " + tagName + ".volume/muted repeatedly fires volumechange repeatedly");
+}
+
+volumechange_test("audio");
+volumechange_test("video");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/historical.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/historical.html
new file mode 100644
index 000000000..451923408
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/historical.html
@@ -0,0 +1,53 @@
+<!doctype html>
+<title>Historical media element features should not be supported</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+function t(property, tagName) {
+ var tagNames = tagName ? [tagName] : ['audio', 'video'];
+ tagNames.forEach(function(tagName) {
+ test(function() {
+ assert_false(property in document.createElement(tagName));
+ }, tagName + '.' + property + ' should not be supported');
+ });
+}
+
+t('bufferingRate'); // added in r678, removed in r2872.
+t('start'); // added in r692, removed in r2401.
+t('end'); // added in r692, removed in r2401.
+t('loopStart'); // added in r692, removed in r2401.
+t('loopEnd'); // added in r692, removed in r2401.
+t('loopCount'); // added in r692, replaced with playCount in r1105.
+t('currentLoop'); // added in r692, removed in r2401.
+t('addCuePoint'); // added in r721, replaced with addCueRange in r1106.
+t('removeCuePoint'); // added in r721, replaced with removeCueRanges in r1106.
+t('playCount'); // added in r1105, removed in r2401.
+t('addCueRange'); // added in r1106, removed in r5070.
+t('removeCueRanges'); // added in r1106, removed in r5070.
+t('pixelratio', 'source'); // added in r1629, removed in r2493.
+t('bufferedBytes'); // added in r1630, removed in r2405.
+t('totalBytes'); // added in r1630, removed in r2405.
+t('bufferingThrottled'); // added in r1632, removed in r2872.
+t('autobuffer'); // added in r2855, replaced with preload in r4811.
+t('startTime'); // added in r3035, replaced with initialTime in r5310.
+t('startOffsetTime'); // added in r5310, replaced with startDate in r7045.
+t('initialTime'); // added in r5310, removed in r7046.
+t('audio', 'video'); // added in r5636, replaced with muted in r5991.
+t('startDate'); // added in r7045, replaced with getStartDate() in r8113.
+
+// TextTrackCue constructor: added in r5723, removed in r7742.
+test(function() {
+ assert_throws(new TypeError(), function() {
+ new TextTrackCue(0, 0, '');
+ });
+}, 'TextTrackCue constructor should not be supported');
+
+// added in https://github.com/whatwg/html/commit/66c5b32240c202c74f475872e7ea2cd163777b4a
+// removed in https://github.com/whatwg/html/commit/634698e70ea4586d58c989fa7d2cbfcad20d33e6
+t('mediaGroup');
+t('controller');
+test(function() {
+ assert_false('MediaController' in window);
+}, 'MediaController constructor should not be supported');
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/HTMLElement/HTMLMediaElement/addTextTrack.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/HTMLElement/HTMLMediaElement/addTextTrack.html
new file mode 100644
index 000000000..2a76b0a66
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/HTMLElement/HTMLMediaElement/addTextTrack.html
@@ -0,0 +1,116 @@
+<!doctype html>
+<title>HTMLMediaElement.addTextTrack</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<div id=log></div>
+<script>
+var video = document.createElement('video');
+test(function(){
+ assert_throws(new TypeError(), function(){
+ video.addTextTrack('foo');
+ });
+ assert_throws(new TypeError(), function(){
+ video.addTextTrack(undefined);
+ });
+ assert_throws(new TypeError(), function(){
+ video.addTextTrack(null);
+ });
+}, document.title + ' bogus first arg');
+
+test(function(){
+ assert_throws(new TypeError(), function(){
+ video.addTextTrack('SUBTITLES');
+ });
+}, document.title + ' uppercase first arg');
+
+test(function(){
+ var t = video.addTextTrack('subtitles');
+ assert_equals(t.kind, 'subtitles');
+ assert_equals(t.label, '');
+ assert_equals(t.language, '');
+ assert_equals(t.mode, 'hidden');
+ assert_true(t.cues instanceof TextTrackCueList);
+ assert_equals(t.cues.length, 0);
+}, document.title + ' subtitles first arg');
+
+test(function(){
+ var t = video.addTextTrack('captions');
+ assert_equals(t.kind, 'captions');
+ assert_equals(t.label, '');
+ assert_equals(t.language, '');
+ assert_equals(t.mode, 'hidden');
+ assert_true(t.cues instanceof TextTrackCueList);
+ assert_equals(t.cues.length, 0);
+}, document.title + ' captions first arg');
+
+test(function(){
+ var t = video.addTextTrack('descriptions');
+ assert_equals(t.kind, 'descriptions');
+ assert_equals(t.label, '');
+ assert_equals(t.language, '');
+ assert_equals(t.mode, 'hidden');
+ assert_true(t.cues instanceof TextTrackCueList);
+ assert_equals(t.cues.length, 0);
+}, document.title + ' descriptions first arg');
+
+test(function(){
+ var t = video.addTextTrack('chapters');
+ assert_equals(t.kind, 'chapters');
+ assert_equals(t.label, '');
+ assert_equals(t.language, '');
+ assert_equals(t.mode, 'hidden');
+ assert_true(t.cues instanceof TextTrackCueList);
+ assert_equals(t.cues.length, 0);
+}, document.title + ' chapters first arg');
+
+test(function(){
+ var t = video.addTextTrack('metadata');
+ assert_equals(t.kind, 'metadata');
+ assert_equals(t.label, '');
+ assert_equals(t.language, '');
+ assert_equals(t.mode, 'hidden');
+ assert_true(t.cues instanceof TextTrackCueList);
+ assert_equals(t.cues.length, 0);
+}, document.title + ' metadata first arg');
+
+test(function(){
+ var t = video.addTextTrack('subtitles', undefined, undefined);
+ assert_equals(t.kind, 'subtitles');
+ assert_equals(t.label, '');
+ assert_equals(t.language, '');
+ assert_equals(t.mode, 'hidden');
+ assert_true(t.cues instanceof TextTrackCueList);
+ assert_equals(t.cues.length, 0);
+}, document.title + ' undefined second and third arg');
+
+test(function(){
+ var t = video.addTextTrack('subtitles', null, null);
+ assert_equals(t.kind, 'subtitles');
+ assert_equals(t.label, 'null');
+ assert_equals(t.language, 'null');
+ assert_equals(t.mode, 'hidden');
+ assert_true(t.cues instanceof TextTrackCueList);
+ assert_equals(t.cues.length, 0);
+}, document.title + ' null second and third arg');
+
+test(function(){
+ var t = video.addTextTrack('subtitles', 'foo', 'bar');
+ assert_equals(t.kind, 'subtitles');
+ assert_equals(t.label, 'foo');
+ assert_equals(t.language, 'bar');
+ assert_equals(t.mode, 'hidden');
+ assert_true(t.cues instanceof TextTrackCueList);
+ assert_equals(t.cues.length, 0);
+}, document.title + ' foo and bar second and third arg');
+
+test(function(){
+ var t = video.addTextTrack('subtitles', 'foo');
+ assert_equals(t.kind, 'subtitles');
+ assert_equals(t.label, 'foo');
+ assert_equals(t.language, '');
+ assert_equals(t.mode, 'hidden');
+ assert_true(t.cues instanceof TextTrackCueList);
+ assert_equals(t.cues.length, 0);
+}, document.title + ' foo second arg, third arg omitted');
+
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/HTMLElement/HTMLMediaElement/textTracks.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/HTMLElement/HTMLMediaElement/textTracks.html
new file mode 100644
index 000000000..0f183b7e1
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/HTMLElement/HTMLMediaElement/textTracks.html
@@ -0,0 +1,13 @@
+<!doctype html>
+<title>HTMLMediaElement.textTracks</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<div id=log></div>
+<script>
+var video = document.createElement('video');
+test(function(){
+ assert_equals(video.textTracks, video.textTracks);
+ assert_equals(video.textTracks.length, 0);
+});
+
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/HTMLElement/HTMLTrackElement/default.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/HTMLElement/HTMLTrackElement/default.html
new file mode 100644
index 000000000..05fd0f7f7
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/HTMLElement/HTMLTrackElement/default.html
@@ -0,0 +1,55 @@
+<!doctype html>
+<title>HTMLTrackElement.default</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<div id=log></div>
+<script>
+test(function(){
+ var track = document.createElement('track');
+ assert_equals(track['default'], false);
+ assert_equals(track.getAttribute('default'), null);
+}, document.title + ' missing value');
+
+test(function(){
+ var track = document.createElement('track');
+ track.setAttribute('default', '');
+ assert_equals(track['default'], true);
+ assert_equals(track.getAttribute('default'), '');
+}, document.title + ' empty string content attribute');
+
+test(function(){
+ var track = document.createElement('track');
+ track['default'] = '';
+ assert_equals(track['default'], false);
+ assert_equals(track.getAttribute('default'), null);
+}, document.title + ' empty string IDL attribute');
+
+test(function(){
+ var track = document.createElement('track');
+ track.setAttribute('default', 'foo');
+ assert_equals(track['default'], true);
+ assert_equals(track.getAttribute('default'), 'foo');
+}, document.title + ' foo in content attribute');
+
+test(function(){
+ var track = document.createElement('track');
+ track['default'] = 'foo';
+ assert_equals(track['default'], true);
+ assert_equals(track.getAttribute('default'), '');
+}, document.title + ' foo in IDL attribute');
+
+test(function(){
+ var track = document.createElement('track');
+ track['default'] = true;
+ assert_equals(track['default'], true);
+ assert_equals(track.getAttribute('default'), '');
+}, document.title + ' true in IDL attribute');
+
+test(function(){
+ var track = document.createElement('track');
+ track.setAttribute('default', '');
+ track['default'] = false;
+ assert_equals(track['default'], false);
+ assert_equals(track.getAttribute('default'), null);
+}, document.title + ' false in IDL attribute');
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/HTMLElement/HTMLTrackElement/kind.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/HTMLElement/HTMLTrackElement/kind.html
new file mode 100644
index 000000000..78c3bff51
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/HTMLElement/HTMLTrackElement/kind.html
@@ -0,0 +1,146 @@
+<!doctype html>
+<title>HTMLTrackElement.kind</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<div id=log></div>
+<script>
+test(function(){
+ var track = document.createElement('track');
+ assert_equals(track.kind, 'subtitles');
+ assert_equals(track.getAttribute('kind'), null);
+}, document.title + ' missing value');
+
+test(function(){
+ var track = document.createElement('track');
+ track.setAttribute('kind', 'invalid');
+ assert_equals(track.kind, 'metadata');
+ assert_equals(track.getAttribute('kind'), 'invalid');
+}, document.title + ' invalid value in content attribute');
+
+test(function(){
+ var track = document.createElement('track');
+ track.setAttribute('kind', 'CAPTIONS');
+ assert_equals(track.kind, 'captions');
+ assert_equals(track.getAttribute('kind'), 'CAPTIONS');
+}, document.title + ' content attribute uppercase');
+
+test(function(){
+ var track = document.createElement('track');
+ track.setAttribute('kind', 'CAPT\u0130ONS');
+ assert_equals(track.kind, 'metadata');
+ assert_equals(track.getAttribute('kind'), 'CAPT\u0130ONS');
+}, document.title + ' content attribute with uppercase turkish I (with dot)');
+
+test(function(){
+ var track = document.createElement('track');
+ track.setAttribute('kind', 'capt\u0131ons');
+ assert_equals(track.kind, 'metadata');
+ assert_equals(track.getAttribute('kind'), 'capt\u0131ons');
+}, document.title + ' content attribute with lowercase turkish i (dotless)');
+
+test(function(){
+ var track = document.createElement('track');
+ track.setAttribute('kind', 'subtitles');
+ assert_equals(track.kind, 'subtitles');
+ assert_equals(track.getAttribute('kind'), 'subtitles');
+}, document.title + ' content attribute "subtitles"');
+
+test(function(){
+ var track = document.createElement('track');
+ track.setAttribute('kind', 'captions');
+ assert_equals(track.kind, 'captions');
+ assert_equals(track.getAttribute('kind'), 'captions');
+}, document.title + ' content attribute "captions"');
+
+test(function(){
+ var track = document.createElement('track');
+ track.setAttribute('kind', 'descriptions');
+ assert_equals(track.kind, 'descriptions');
+ assert_equals(track.getAttribute('kind'), 'descriptions');
+}, document.title + ' content attribute "descriptions"');
+
+test(function(){
+ var track = document.createElement('track');
+ track.setAttribute('kind', 'chapters');
+ assert_equals(track.kind, 'chapters');
+ assert_equals(track.getAttribute('kind'), 'chapters');
+}, document.title + ' content attribute "chapters"');
+
+test(function(){
+ var track = document.createElement('track');
+ track.setAttribute('kind', 'metadata');
+ assert_equals(track.kind, 'metadata');
+ assert_equals(track.getAttribute('kind'), 'metadata');
+}, document.title + ' content attribute "metadata"');
+
+test(function(){
+ var track = document.createElement('track');
+ track.setAttribute('kind', 'captions\u0000');
+ assert_equals(track.kind, 'metadata');
+ assert_equals(track.getAttribute('kind'), 'captions\u0000');
+}, document.title + ' content attribute "captions\\u0000"');
+
+test(function(){
+ var track = document.createElement('track');
+ track.kind = 'subtitles';
+ assert_equals(track.getAttribute('kind'), 'subtitles');
+ assert_equals(track.kind, 'subtitles');
+}, document.title + ' setting IDL attribute to "subtitles"');
+
+test(function(){
+ var track = document.createElement('track');
+ track.kind = 'captions';
+ assert_equals(track.getAttribute('kind'), 'captions');
+ assert_equals(track.kind, 'captions');
+}, document.title + ' setting IDL attribute to "captions"');
+
+test(function(){
+ var track = document.createElement('track');
+ track.kind = 'descriptions';
+ assert_equals(track.getAttribute('kind'), 'descriptions');
+ assert_equals(track.kind, 'descriptions');
+}, document.title + ' setting IDL attribute to "descriptions"');
+
+test(function(){
+ var track = document.createElement('track');
+ track.kind = 'chapters';
+ assert_equals(track.getAttribute('kind'), 'chapters');
+ assert_equals(track.kind, 'chapters');
+}, document.title + ' setting IDL attribute to "chapters"');
+
+test(function(){
+ var track = document.createElement('track');
+ track.kind = 'metadata';
+ assert_equals(track.getAttribute('kind'), 'metadata');
+ assert_equals(track.kind, 'metadata');
+}, document.title + ' setting IDL attribute to "metadata"');
+
+test(function(){
+ var track = document.createElement('track');
+ track.kind = 'CAPTIONS';
+ assert_equals(track.getAttribute('kind'), 'CAPTIONS');
+ assert_equals(track.kind, 'captions');
+}, document.title + ' setting IDL attribute to "CAPTIONS"');
+
+test(function(){
+ var track = document.createElement('track');
+ track.kind = 'CAPT\u0130ONS';
+ assert_equals(track.getAttribute('kind'), 'CAPT\u0130ONS');
+ assert_equals(track.kind, 'metadata');
+}, document.title + ' setting IDL attribute with uppercase turkish I (with dot)');
+
+test(function(){
+ var track = document.createElement('track');
+ track.kind = 'capt\u0131ons';
+ assert_equals(track.getAttribute('kind'), 'capt\u0131ons');
+ assert_equals(track.kind, 'metadata');
+}, document.title + ' setting IDL attribute with lowercase turkish I (dotless)');
+
+test(function(){
+ var track = document.createElement('track');
+ track.kind = 'captions\u0000';
+ assert_equals(track.getAttribute('kind'), 'captions\u0000');
+ assert_equals(track.kind, 'metadata');
+}, document.title + ' setting IDL attribute with \\u0000');
+
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/HTMLElement/HTMLTrackElement/label.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/HTMLElement/HTMLTrackElement/label.html
new file mode 100644
index 000000000..b2360315c
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/HTMLElement/HTMLTrackElement/label.html
@@ -0,0 +1,83 @@
+<!doctype html>
+<title>HTMLTrackElement.label</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<div id=log></div>
+<script>
+test(function(){
+ var track = document.createElement('track');
+ assert_equals(track.label, '');
+ assert_equals(track.getAttribute('label'), null);
+}, document.title + ' missing value');
+
+test(function(){
+ var track = document.createElement('track');
+ track.setAttribute('label', '');
+ assert_equals(track.label, '');
+ assert_equals(track.getAttribute('label'), '');
+}, document.title + ' empty string content attribute');
+
+test(function(){
+ var track = document.createElement('track');
+ track.label = '';
+ assert_equals(track.label, '');
+ assert_equals(track.getAttribute('label'), '');
+}, document.title + ' empty string IDL attribute');
+
+test(function(){
+ var track = document.createElement('track');
+ track.setAttribute('label', 'foo');
+ assert_equals(track.label, 'foo');
+ assert_equals(track.getAttribute('label'), 'foo');
+}, document.title + ' lowercase content attribute');
+
+test(function(){
+ var track = document.createElement('track');
+ track.setAttribute('label', 'FOO');
+ assert_equals(track.label, 'FOO');
+ assert_equals(track.getAttribute('label'), 'FOO');
+}, document.title + ' uppercase content attribute');
+
+test(function(){
+ var track = document.createElement('track');
+ track.setAttribute('label', '\u0000');
+ assert_equals(track.label, '\u0000');
+ assert_equals(track.getAttribute('label'), '\u0000');
+}, document.title + '\\u0000 in content attribute');
+
+test(function(){
+ var track = document.createElement('track');
+ track.label = 'foo';
+ assert_equals(track.label, 'foo');
+ assert_equals(track.getAttribute('label'), 'foo');
+}, document.title + ' lowercase IDL attribute');
+
+test(function(){
+ var track = document.createElement('track');
+ track.label = 'FOO';
+ assert_equals(track.label, 'FOO');
+ assert_equals(track.getAttribute('label'), 'FOO');
+}, document.title + ' uppercase IDL attribute');
+
+test(function(){
+ var track = document.createElement('track');
+ track.setAttribute('label', ' foo \n');
+ assert_equals(track.label, ' foo \n');
+ assert_equals(track.getAttribute('label'), ' foo \n');
+}, document.title + ' whitespace in content attribute');
+
+test(function(){
+ var track = document.createElement('track');
+ track.label = ' foo \n';
+ assert_equals(track.label, ' foo \n');
+ assert_equals(track.getAttribute('label'), ' foo \n');
+}, document.title + ' whitespace in IDL attribute');
+
+test(function(){
+ var track = document.createElement('track');
+ track.label = '\u0000';
+ assert_equals(track.label, '\u0000');
+ assert_equals(track.getAttribute('label'), '\u0000');
+}, document.title + ' \\u0000 in IDL attribute');
+
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/HTMLElement/HTMLTrackElement/readyState.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/HTMLElement/HTMLTrackElement/readyState.html
new file mode 100644
index 000000000..e18f21934
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/HTMLElement/HTMLTrackElement/readyState.html
@@ -0,0 +1,11 @@
+<!doctype html>
+<title>HTMLTrackElement.readyState</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<div id=log></div>
+<script>
+test(function(){
+ var track = document.createElement('track');
+ assert_equals(track.readyState, 0);
+}, document.title + ' default value');
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/HTMLElement/HTMLTrackElement/src.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/HTMLElement/HTMLTrackElement/src.html
new file mode 100644
index 000000000..4089913cb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/HTMLElement/HTMLTrackElement/src.html
@@ -0,0 +1,43 @@
+<!doctype html>
+<title>HTMLTrackElement.src</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<div id=log></div>
+<script>
+test(function(){
+ var track = document.createElement('track');
+ assert_equals(track.src, '');
+ assert_equals(track.getAttribute('src'), null);
+}, document.title + ' missing value');
+
+function resolve(url) {
+ var link = document.createElement('a');
+ link.setAttribute('href', url);
+ return link.href;
+}
+
+var tests = [
+ {input:'', expectedIDL:resolve(''), desc:'empty string'},
+ {input:'http://foo bar', expectedIDL:'http://foo bar', desc:'unresolvable value'},
+ {input:'test', expectedIDL:resolve('test'), desc:'resolvable value'},
+ // Leading and trailing C0 controls and space is stripped per url spec.
+ {input:'\u0000', expectedIDL:resolve(''), desc:'\\u0000'},
+ {input:'foo\u0000bar', expectedIDL:resolve('foo%00bar'), desc:'foo\\u0000bar'},
+];
+
+tests.forEach(function(t) {
+ test(function(){
+ var track = document.createElement('track');
+ track.setAttribute('src', t.input);
+ assert_equals(track.src, t.expectedIDL);
+ assert_equals(track.getAttribute('src'), t.input);
+ }, [document.title, t.desc, 'in content attribute'].join(' '));
+
+ test(function(){
+ var track = document.createElement('track');
+ track.src = t.input;
+ assert_equals(track.src, t.expectedIDL);
+ assert_equals(track.getAttribute('src'), t.input);
+ }, [document.title, 'assigning', t.desc, 'to IDL attribute'].join(' '));
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/HTMLElement/HTMLTrackElement/srclang.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/HTMLElement/HTMLTrackElement/srclang.html
new file mode 100644
index 000000000..b5071e0c3
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/HTMLElement/HTMLTrackElement/srclang.html
@@ -0,0 +1,82 @@
+<!doctype html>
+<title>HTMLTrackElement.srclang</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<div id=log></div>
+<script>
+test(function(){
+ var track = document.createElement('track');
+ assert_equals(track.srclang, '');
+ assert_equals(track.getAttribute('srclang'), null);
+}, document.title + ' missing value');
+
+test(function(){
+ var track = document.createElement('track');
+ track.setAttribute('srclang', '');
+ assert_equals(track.srclang, '');
+ assert_equals(track.getAttribute('srclang'), '');
+}, document.title + ' empty string content attribute');
+
+test(function(){
+ var track = document.createElement('track');
+ track.srclang = '';
+ assert_equals(track.srclang, '');
+ assert_equals(track.getAttribute('srclang'), '');
+}, document.title + ' empty string IDL attribute');
+
+test(function(){
+ var track = document.createElement('track');
+ track.setAttribute('srclang', 'foo');
+ assert_equals(track.srclang, 'foo');
+ assert_equals(track.getAttribute('srclang'), 'foo');
+}, document.title + ' lowercase content attribute');
+
+test(function(){
+ var track = document.createElement('track');
+ track.setAttribute('srclang', 'FOO');
+ assert_equals(track.srclang, 'FOO');
+ assert_equals(track.getAttribute('srclang'), 'FOO');
+}, document.title + ' uppercase content attribute');
+
+test(function(){
+ var track = document.createElement('track');
+ track.setAttribute('srclang', '\u0000');
+ assert_equals(track.srclang, '\u0000');
+ assert_equals(track.getAttribute('srclang'), '\u0000');
+}, document.title + ' \\u0000 content attribute');
+
+test(function(){
+ var track = document.createElement('track');
+ track.srclang = 'foo';
+ assert_equals(track.srclang, 'foo');
+ assert_equals(track.getAttribute('srclang'), 'foo');
+}, document.title + ' lowercase IDL attribute');
+
+test(function(){
+ var track = document.createElement('track');
+ track.srclang = 'FOO';
+ assert_equals(track.srclang, 'FOO');
+ assert_equals(track.getAttribute('srclang'), 'FOO');
+}, document.title + ' uppercase IDL attribute');
+
+test(function(){
+ var track = document.createElement('track');
+ track.setAttribute('srclang', ' foo \n');
+ assert_equals(track.srclang, ' foo \n');
+ assert_equals(track.getAttribute('srclang'), ' foo \n');
+}, document.title + ' whitespace in content attribute');
+
+test(function(){
+ var track = document.createElement('track');
+ track.srclang = ' foo \n';
+ assert_equals(track.srclang, ' foo \n');
+ assert_equals(track.getAttribute('srclang'), ' foo \n');
+}, document.title + ' whitespace in IDL attribute');
+
+test(function(){
+ var track = document.createElement('track');
+ track.srclang = '\u0000';
+ assert_equals(track.srclang, '\u0000');
+ assert_equals(track.getAttribute('srclang'), '\u0000');
+}, document.title + ' \\u0000 in IDL attribute');
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/HTMLElement/HTMLTrackElement/track.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/HTMLElement/HTMLTrackElement/track.html
new file mode 100644
index 000000000..1de0a8804
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/HTMLElement/HTMLTrackElement/track.html
@@ -0,0 +1,12 @@
+<!doctype html>
+<title>HTMLTrackElement.track</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<div id=log></div>
+<script>
+test(function(){
+ var track = document.createElement('track');
+ assert_equals(track.track, track.track, 'same object should be returned');
+ assert_true(track.track instanceof TextTrack, 'returned object should be a TextTrack');
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrack/activeCues.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrack/activeCues.html
new file mode 100644
index 000000000..689ec12be
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrack/activeCues.html
@@ -0,0 +1,104 @@
+<!doctype html>
+<title>TextTrack.activeCues</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script src=/common/media.js></script>
+<div id=log></div>
+<script>
+setup(function(){
+ window.video = document.createElement('video');
+ window.t1 = video.addTextTrack('subtitles');
+ window.track = document.createElement('track');
+ track['default'] = true;
+ video.appendChild(track);
+ window.t2 = track.track;
+ t2.mode = 'showing';
+ window.t1_cues = t1.activeCues;
+ window.t2_cues = t2.activeCues;
+ document.body.appendChild(video);
+ if (!t1)
+ throw new Error('t1 was undefined')
+}, {timeout:25000});
+function smoke_test() {
+ assert_true('HTMLTrackElement' in window, 'track not supported');
+}
+
+test(function(){
+ smoke_test();
+ assert_equals(t1.activeCues, t1_cues, 't1.activeCues should return same object');
+ assert_equals(t2.activeCues, t2_cues, 't2.activeCues should return same object');
+ assert_not_equals(t1.activeCues, t2.activeCues, 't1.activeCues and t2.activeCues should be different objects');
+ assert_not_equals(t1.activeCues, null, 't1.activeCues should not be null');
+ assert_not_equals(t2.activeCues, null, 't2.activeCues should not be null');
+ assert_equals(t1.activeCues.length, 0, 't1.activeCues should have length 0');
+ assert_equals(t2.activeCues.length, 0, 't2.activeCues should have length 0');
+}, document.title+', empty list');
+test(function(){
+ smoke_test();
+ var c = new VTTCue(0, 1, "text");
+ t1.addCue(c);
+ assert_equals(t1.activeCues, t1_cues, "t1.activeCues should return same object");
+ assert_equals(t1.activeCues.length, 0, "t1.activeCues.length");
+ var c2 = new VTTCue(1, 2, "text2");
+ t1.addCue(c2);
+ assert_equals(t1.activeCues, t1_cues, "t1.activeCues should return the same object after adding a second cue");
+ assert_equals(t1.activeCues.length, 0, "t1.activeCues.length after adding a second cue");
+}, document.title+', after addCue()');
+test(function(){
+ smoke_test();
+ t1.mode = 'showing';
+ assert_equals(t1.activeCues, t1_cues, "t1.activeCues should return the same object after setting mode to showing");
+ t1.mode = 'hidden';
+ assert_equals(t1.activeCues, t1_cues, "t1.activeCues should return the same object after setting mode to hidden");
+ t1.mode = 'disabled';
+ assert_equals(t1.activeCues, null, "t1.activeCues should be null when mode is disabled");
+ assert_equals(t1_cues.length, 0, "t1_cues should still be intact after setting mode to disabled");
+}, document.title+', different modes');
+
+// ok now let's load in a video
+var test1 = async_test(document.title+', video loading', {timeout:20000});
+var test2 = async_test(document.title+', video playing', {timeout:20000});
+var test3 = async_test(document.title+', adding cue during playback', {timeout:20000});
+test1.step(smoke_test);
+test2.step(smoke_test);
+test3.step(smoke_test);
+test1.step(function(){
+ t1.mode = 'showing';
+ video.onloadeddata = test1.step_func(function(e) {
+ video.onplaying = test2.step_func(function(e) {
+ try {
+ assert_equals(t1.activeCues, t1_cues, "t1.activeCues should return the same object after playing a video");
+ assert_equals(t1.activeCues.length, 1, "t1.activeCues.length after the video has started playing");
+ } catch(ex) {
+ test2.step(function() { throw ex; });
+ test3.step(function() { assert_unreached(); });
+ return;
+ }
+ test3.step(function(){
+ var c3 = new VTTCue(0, 2, "text3");
+ t1.addCue(c3);
+ assert_equals(t1.activeCues.length, 1, "t1.activeCues.length after adding a cue in the same script");
+ setTimeout(test3.step_func(function(){
+ assert_equals(t1.activeCues.length, 2, "t1.activeCues.length after the event loop has spun");
+ test3.done();
+ }, 0));
+ });
+ test2.done();
+ });
+ try {
+ assert_equals(t1.activeCues, t1_cues, "t1.activeCues should return the same object after loading a video");
+ assert_equals(t2.activeCues, t2_cues, "t2.activeCues should return the same object after loading a video");
+ assert_equals(t1.activeCues.length, 0, "t1.activeCues.length before the video has started playing");
+ assert_equals(t2.activeCues.length, 0, "t1.activeCues.length before the video has started playing");
+ } catch(ex) {
+ test1.step(function() { throw ex; });
+ test2.step(function() { assert_unreached(); });
+ test3.step(function() { assert_unreached(); });
+ return;
+ }
+ video.play();
+ test1.done();
+ });
+ video.src = getVideoURI("/media/movie_5");
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrack/addCue.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrack/addCue.html
new file mode 100644
index 000000000..267941334
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrack/addCue.html
@@ -0,0 +1,68 @@
+<!doctype html>
+<title>TextTrack.addCue()</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<div id=log></div>
+<script>
+setup(function(){
+ window.video = document.createElement('video');
+ document.body.appendChild(video);
+}, {timeout:5000});
+test(function() {
+ var t1 = video.addTextTrack('subtitles');
+ var t2 = video.addTextTrack('subtitles');
+ var c1 = new VTTCue(0, 1, 'text1');
+ t1.addCue(c1);
+ t2.addCue(c1);
+ assert_equals(c1.track, t2);
+}, document.title+', adding a cue to two different tracks');
+test(function() {
+ var t1 = video.addTextTrack('subtitles');
+ var c1 = new VTTCue(0, 1, 'text1');
+ t1.addCue(c1);
+ assert_equals(c1.track, t1);
+ t1.addCue(c1);
+ assert_equals(c1.track, t1);
+}, document.title+', adding a cue to a track twice');
+test(function() {
+ var t1 = video.addTextTrack('subtitles');
+ var t2 = video.addTextTrack('subtitles');
+ var c1 = new VTTCue(0, 1, 'text1');
+ t1.addCue(c1);
+ assert_equals(c1.track, t1);
+ t1.removeCue(c1);
+ assert_equals(c1.track, null);
+ t2.addCue(c1);
+ assert_equals(c1.track, t2);
+}, document.title+', adding a removed cue to a different track');
+test(function() {
+ var t1 = video.addTextTrack('subtitles');
+ var c1 = new VTTCue(0, 1, 'text1');
+ t1.addCue(c1);
+ assert_equals(t1.cues.length, 1, 't1.cues.length after first addition');
+ t1.removeCue(c1);
+ assert_equals(t1.cues.length, 0, 't1.cues.length after removal');
+ t1.addCue(c1);
+ assert_equals(t1.cues.length, 1, 't1.cues.length after second addition');
+}, document.title+', adding an associated but removed cue to the same track');
+
+var t = async_test(document.title+', adding a cue associated with a track element to other track');
+t.step(function(){
+ var t1 = video.addTextTrack('subtitles');
+ var track = document.createElement('track');
+ track.onload = t.step_func(function(){
+ var cue = track.track.cues[0];
+ track.track.removeCue(cue);
+ t1.addCue(cue);
+ assert_equals(cue.track, t1);
+ t.done();
+ });
+ track.onerror = t.step_func(function() {
+ assert_unreached('got error event');
+ });
+ track.src= 'data:text/vtt,'+encodeURIComponent('WEBVTT\n\n00:00:00.000 --> 00:00:01.000\ntest\n');
+ track.kind = 'subtitles';
+ track.track.mode = 'hidden';
+ video.appendChild(track);
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrack/constants.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrack/constants.html
new file mode 100644
index 000000000..3c8046cdc
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrack/constants.html
@@ -0,0 +1,23 @@
+<!doctype html>
+<title>TextTrack constants</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<div id=log></div>
+<script>
+setup(function(){
+ window.video = document.createElement('video');
+ window.t1 = video.addTextTrack('subtitles');
+});
+test(function(){
+ assert_equals(t1.DISABLED, undefined, "t1.DISABLED");
+ assert_equals(t1.HIDDEN, undefined, "t1.HIDDEN");
+ assert_equals(t1.SHOWING, undefined, "t1.SHOWING");
+ assert_equals(TextTrack.prototype.DISABLED, undefined, "TextTrack.prototype.DISABLED");
+ assert_equals(TextTrack.prototype.HIDDEN, undefined, "TextTrack.prototype.HIDDEN");
+ assert_equals(TextTrack.prototype.SHOWING, undefined, "TextTrack.prototype.SHOWING");
+ assert_equals(TextTrack.DISABLED, undefined, "TextTrack.DISABLED");
+ assert_equals(TextTrack.HIDDEN, undefined, "TextTrack.HIDDEN");
+ assert_equals(TextTrack.SHOWING, undefined, "TextTrack.SHOWING");
+});
+
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrack/cues.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrack/cues.html
new file mode 100644
index 000000000..4b7808c96
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrack/cues.html
@@ -0,0 +1,100 @@
+<!doctype html>
+<title>TextTrack.cues</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<div id=log></div>
+<script>
+test(function(){
+ var video = document.createElement('video');
+ var t1 = video.addTextTrack('subtitles');
+ assert_equals(t1.cues, t1.cues, 't1.cues should return same object');
+ assert_not_equals(t1.cues, null, 't1.cues should not be null');
+ assert_true(t1.cues instanceof TextTrackCueList, 't1.cues instanceof TextTrackCueList');
+ assert_equals(t1.cues.length, 0, 't1.cues.length');
+}, document.title+', empty list');
+
+function addCue(texttrack, start, end, text, id) {
+ var c = new VTTCue(start, end, text);
+ c.id = id;
+ texttrack.addCue(c);
+ return c;
+}
+
+test(function(){
+ var video = document.createElement('video');
+ var t1 = video.addTextTrack('subtitles');
+ var t1_cues = t1.cues;
+ var c = addCue(t1, 0, 1, 'text', 'id');
+ assert_equals(t1.cues, t1_cues, "t1.cues should return same object");
+ assert_equals(t1.cues.length, 1, "t1.cues.length");
+ var c2 = addCue(t1, 1, 2, 'text2', 'id2');
+ assert_equals(t1.cues, t1_cues, "t1.cues should return the same object after adding a second cue");
+ assert_equals(t1.cues.length, 2, "t1.cues.length after adding a second cue");
+ assert_equals(t1.cues[0].id, "id");
+ assert_equals(t1.cues[1].id, "id2");
+}, document.title+', after addCue()');
+
+test(function(){
+ var video = document.createElement('video');
+ var t1 = video.addTextTrack('subtitles');
+ var t1_cues = t1.cues;
+ var c = addCue(t1, 0, 1, 'text', 'id');
+ var c2 = addCue(t1, 1, 2, 'text2', 'id2');
+ t1.mode = 'showing';
+ assert_equals(t1.cues, t1_cues, "t1.cues should return the same object after setting mode to 'showing'");
+ t1.mode = 'hidden';
+ assert_equals(t1.cues, t1_cues, "t1.cues should return the same object after setting mode to 'hidden'");
+ t1.mode = 'disabled';
+ assert_equals(t1.cues, null, "t1.cues should be null when mode is 'disabled'");
+ assert_equals(t1_cues.length, 2, "t1_cues should still be intact after setting mode to 'disabled'");
+ assert_equals(t1_cues[0].id, "id", "t1_cues first cue should still be intact after setting mode to 'disabled'");
+ assert_equals(t1_cues[1].id, "id2", "t1_cues second cue should still be intact after setting mode to 'disabled'");
+ t1.mode = 'hidden';
+ assert_equals(t1.cues, t1_cues, "t1.cues should return the same object after setting mode to 'disabled' and then 'hidden'");
+ t1.mode = 'disabled';
+ assert_equals(t1.cues, null, "t1.cues should be null when mode is set to 'disabled' again");
+ assert_equals(t1_cues.length, 2, "t1_cues should still be intact after setting mode to 'disabled' again");
+ assert_equals(t1_cues[0].id, "id", "t1_cues first cue should still be intact after setting mode to 'disabled' again");
+ assert_equals(t1_cues[1].id, "id2", "t1_cues second cue should still be intact after setting mode to 'disabled' again");
+ t1.mode = 'showing';
+ assert_equals(t1.cues, t1_cues, "t1.cues should return the same object after setting mode to 'disabled' and then 'showing'");
+}, document.title+', different modes');
+
+test(function(){
+ var video = document.createElement('video');
+ var t1 = video.addTextTrack('subtitles');
+ var t1_cues = t1.cues;
+ var c = addCue(t1, 0, 1, 'text', 'id');
+ var c2 = addCue(t1, 1, 2, 'text2', 'id2');
+ t1.mode = 'showing';
+ t1.cues[1].startTime = 0; // this should change the text track cue order
+ assert_equals(t1.cues[0].id, 'id2');
+ assert_equals(t1.cues[1].id, 'id');
+ t1.cues[0].startTime = 0.5; // this should change it back
+ assert_equals(t1.cues[0].id, 'id');
+ assert_equals(t1.cues[1].id, 'id2');
+}, document.title+', changing order');
+
+async_test(function(){
+ var video = document.createElement('video');
+ var t1 = video.addTextTrack('subtitles');
+ var t1_cues = t1.cues;
+ t1.mode = 'hidden';
+ var track = document.createElement('track');
+ track['default'] = true;
+ video.appendChild(track); // queues a task to "honor user preferences...", media element event task source
+ var t2 = track.track;
+ assert_equals(t2.cues, null, 't2.cues should be null');
+ // We need to wait until the "honor user preferences..." steps have run so we invoke play()
+ // which queues an event with the same task source.
+ video.onplay = this.step_func(function(){
+ assert_equals(t2.cues, t2.cues, 't2.cues should return same object');
+ assert_not_equals(t1.cues, t2.cues, 't1.cues and t2.cues should be different objects');
+ assert_not_equals(t2.cues, null, 't2.cues should not be null');
+ assert_true(t2.cues instanceof TextTrackCueList, 't2.cues instanceof TextTrackCueList');
+ assert_equals(t2.cues.length, 0, 't2.cues should have length 0');
+ this.done();
+ });
+ video.play(); // queues a task to fire 'play', media element event task source
+}, document.title+', default attribute');
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrack/kind.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrack/kind.html
new file mode 100644
index 000000000..d5dbc8342
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrack/kind.html
@@ -0,0 +1,31 @@
+<!doctype html>
+<title>TextTrack.kind</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<div id=log></div>
+<script>
+test(function(){
+ var video = document.createElement('video');
+ var t1 = video.addTextTrack('subtitles');
+ var t2 = video.addTextTrack('captions');
+ var t3 = video.addTextTrack('descriptions');
+ var t4 = video.addTextTrack('chapters');
+ var t5 = video.addTextTrack('metadata');
+ assert_equals(t1.kind, 'subtitles');
+ assert_equals(t2.kind, 'captions');
+ assert_equals(t3.kind, 'descriptions');
+ assert_equals(t4.kind, 'chapters');
+ assert_equals(t5.kind, 'metadata');
+}, document.title+', addTextTrack');
+test(function(){
+ var track = document.createElement('track');
+ track.setAttribute('kind', 'CAPTIONS');
+ var t = track.track;
+ assert_equals(t.kind, 'captions');
+}, document.title+', track element');
+test(function(){
+ var track = document.createElement('track');
+ track.kind = 'captions\u0000';
+ assert_equals(track.track.kind, 'metadata');
+}, document.title+', \\u0000');
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrack/label.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrack/label.html
new file mode 100644
index 000000000..c60e85c21
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrack/label.html
@@ -0,0 +1,29 @@
+<!doctype html>
+<title>TextTrack.label</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<div id=log></div>
+<script>
+setup(function(){
+ window.video = document.createElement('video');
+ window.t1 = video.addTextTrack('subtitles', 'foo');
+ window.track = document.createElement('track');
+ track.setAttribute('label', 'bar');
+ video.appendChild(track);
+ window.t2 = track.track;
+});
+test(function(){
+ assert_equals(t1.label, 'foo');
+ assert_equals(t2.label, 'bar');
+ track.label = 'baz';
+ assert_equals(t2.label, 'baz');
+ track.removeAttribute('label');
+ assert_equals(t2.label, '');
+});
+test(function(){
+ track.label = '\u0000a';
+ assert_equals(t2.label, '\u0000a');
+ track.setAttribute('label', '\u0000b', 'IDL attribute');
+ assert_equals(t2.label, '\u0000b', 'content attribute');
+}, document.title+', \\u0000');
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrack/language.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrack/language.html
new file mode 100644
index 000000000..eda3653de
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrack/language.html
@@ -0,0 +1,29 @@
+<!doctype html>
+<title>TextTrack.language</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<div id=log></div>
+<script>
+setup(function(){
+ window.video = document.createElement('video');
+ window.t1 = video.addTextTrack('subtitles', 'foo', 'foo');
+ window.track = document.createElement('track');
+ track.setAttribute('srclang', 'bar');
+ video.appendChild(track);
+ window.t2 = track.track;
+});
+test(function(){
+ assert_equals(t1.language, 'foo');
+ assert_equals(t2.language, 'bar');
+ track.srclang = 'baz';
+ assert_equals(t2.language, 'baz');
+ track.removeAttribute('srclang');
+ assert_equals(t2.language, '');
+});
+test(function(){
+ track.srclang = '\u0000a';
+ assert_equals(t2.language, '\u0000a', 'IDL attribute');
+ track.setAttribute('srclang', '\u0000b');
+ assert_equals(t2.language, '\u0000b', 'content attribute');
+}, document.title+', \\u0000');
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrack/mode.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrack/mode.html
new file mode 100644
index 000000000..9f9415670
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrack/mode.html
@@ -0,0 +1,55 @@
+<!doctype html>
+<title>TextTrack.mode</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<div id=log></div>
+<script>
+test(function(){
+ var track = document.createElement('track');
+ assert_equals(track.track.mode, 'disabled', 'initial');
+ track.track.mode = 1;
+ assert_equals(track.track.mode, 'disabled', '1');
+ track.track.mode = '';
+ assert_equals(track.track.mode, 'disabled', '""');
+ track.track.mode = null;
+ assert_equals(track.track.mode, 'disabled', 'null');
+ track.track.mode = undefined;
+ assert_equals(track.track.mode, 'disabled', 'undefined');
+ track.track.mode = 'showing';
+ assert_equals(track.track.mode, 'showing', 'showing (correct value)');
+ track.track.mode = 'DISABLED';
+ assert_equals(track.track.mode, 'showing', '"DISABLED"');
+ track.track.mode = 'd\u0130sabled'; // dotted uppercase i
+ assert_equals(track.track.mode, 'showing', '"d\u0130sabled" (dotted uppercase i)');
+ track.track.mode = 'd\u0131sabled'; // dotless lowercase i
+ assert_equals(track.track.mode, 'showing', '"d\u0131sabled" (dotless lowercase i)');
+ track.track.mode = 'disabled ';
+ assert_equals(track.track.mode, 'showing', '"disabled "');
+ track.track.mode = ' disabled';
+ assert_equals(track.track.mode, 'showing', '" disabled"');
+ track.track.mode = {};
+ assert_equals(track.track.mode, 'showing', '{}');
+ track.track.mode = 'HIDDEN';
+ assert_equals(track.track.mode, 'showing', '"HIDDEN"');
+ track.track.mode = 'h\u0130dden'; // dotted uppercase i
+ assert_equals(track.track.mode, 'showing', '"h\u0130dden" (dotted uppercase i)');
+ track.track.mode = 'h\u0131dden'; // dotless lowercase i
+ assert_equals(track.track.mode, 'showing', '"h\u0131dden" (dotless lowercase i)');
+}, document.title+', wrong value');
+test(function() {
+ var track = document.createElement('track');
+ assert_equals(track.track.mode, 'disabled', 'initial');
+ track.track.mode = 'disabled'; // no-op
+ assert_equals(track.track.mode, 'disabled', 'disabled (1)');
+ track.track.mode = 'hidden';
+ assert_equals(track.track.mode, 'hidden', 'hidden (1)');
+ track.track.mode = 'hidden'; // no-op
+ assert_equals(track.track.mode, 'hidden', 'hidden (2)');
+ track.track.mode = 'showing';
+ assert_equals(track.track.mode, 'showing', 'showing (1)');
+ track.track.mode = 'showing'; // no-op
+ assert_equals(track.track.mode, 'showing', 'showing (2)');
+ track.track.mode = {toString:function() { return 'disabled'; }};
+ assert_equals(track.track.mode, 'disabled', '{toString:...}');
+}, document.title+', correct value');
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrack/oncuechange.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrack/oncuechange.html
new file mode 100644
index 000000000..16c76f948
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrack/oncuechange.html
@@ -0,0 +1,33 @@
+<!doctype html>
+<title>TextTrack.oncuechange</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<div id=log></div>
+<script>
+setup(function(){
+ window.video = document.createElement('video');
+ window.t1 = video.addTextTrack('subtitles');
+ window.ev = new Event('cuechange');
+ window.ran = false;
+ window.cb = function() { ran = true; };
+});
+test(function(){
+ assert_equals(t1.oncuechange, null);
+ t1.oncuechange = cb;
+ t1.dispatchEvent(ev);
+ assert_true(ran);
+ t1.oncuechange = null;
+ ran = false;
+ t1.dispatchEvent(ev);
+ assert_false(ran);
+});
+test(function(){
+ t1.addEventListener('cuechange', cb, false);
+ t1.dispatchEvent(ev);
+ assert_true(ran);
+ t1.removeEventListener('cuechange', cb, false);
+ ran = false;
+ t1.dispatchEvent(ev);
+ assert_false(ran);
+}, 'TextTrack.addEventListener/removeEventListener');
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrack/removeCue.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrack/removeCue.html
new file mode 100644
index 000000000..3623f44bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrack/removeCue.html
@@ -0,0 +1,50 @@
+<!doctype html>
+<title>TextTrack.removeCue()</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<div id=log></div>
+<script>
+setup(function(){
+ window.video = document.createElement('video');
+ document.body.appendChild(video);
+}, {timeout:5000});
+test(function() {
+ var t1 = video.addTextTrack('subtitles');
+ var t2 = video.addTextTrack('subtitles');
+ var c1 = new VTTCue(0, 1, 'text1');
+ assert_throws("NOT_FOUND_ERR", function() {
+ t1.removeCue(c1);
+ }, 'standalone');
+ t1.addCue(c1);
+ assert_throws("NOT_FOUND_ERR", function() {
+ t2.removeCue(c1);
+ }, 'listed in t1, remove from t2');
+ t1.removeCue(c1);
+ assert_throws("NOT_FOUND_ERR", function() {
+ t1.removeCue(c1);
+ }, 'standalone, remove from t1');
+ assert_throws("NOT_FOUND_ERR", function() {
+ t2.removeCue(c1);
+ }, 'standalone, remove from t2');
+}, document.title+', two elementless tracks');
+var t = async_test(document.title+', cue from track element');
+t.step(function(){
+ var t1 = video.addTextTrack('subtitles');
+ var track = document.createElement('track');
+ track.onload = t.step_func(function(){
+ var cue = track.track.cues[0];
+ assert_throws('NOT_FOUND_ERR', function() { t1.removeCue(cue); }, 'listed in track.track, remove from t1');
+ track.track.removeCue(cue);
+ assert_throws('NOT_FOUND_ERR', function() { track.track.removeCue(cue); }, 'standalone, remove from track.track');
+ assert_throws('NOT_FOUND_ERR', function() { t1.removeCue(cue); }, 'standalone, remove from t1');
+ t.done();
+ });
+ track.onerror = t.step_func(function() {
+ assert_unreached('got error event');
+ });
+ track.src= 'data:text/vtt,'+encodeURIComponent('WEBVTT\n\n00:00:00.000 --> 00:00:01.000\ntest\n');
+ track.kind = 'subtitles';
+ track.track.mode = 'hidden';
+ video.appendChild(track);
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrackCue/endTime.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrackCue/endTime.html
new file mode 100644
index 000000000..b99a12e05
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrackCue/endTime.html
@@ -0,0 +1,39 @@
+<!doctype html>
+<title>TextTrackCue.endTime</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<div id=log></div>
+<script>
+setup(function(){
+ window.video = document.createElement('video');
+ window.t1 = video.addTextTrack('subtitles');
+ document.body.appendChild(video);
+});
+test(function(){
+ var c1 = new VTTCue(-2, -1, 'text1');
+ assert_equals(c1.endTime, -1);
+ c1.endTime = c1.endTime;
+ assert_equals(c1.endTime, -1);
+ assert_throws(new TypeError(), function(){ c1.endTime = NaN; });
+ assert_throws(new TypeError(), function(){ c1.endTime = +Infinity; });
+ assert_throws(new TypeError(), function(){ c1.endTime = -Infinity; });
+}, document.title+', script-created cue');
+
+var t_parsed = async_test(document.title+', parsed cue');
+t_parsed.step(function(){
+ var t = document.createElement('track');
+ t.onload = this.step_func(function(){
+ var c = t.track.cues;
+ assert_equals(c[0].endTime, 0.001);
+ assert_equals(c[1].endTime, 3600.001);
+ this.done();
+ });
+ t.onerror = this.step_func(function() {
+ assert_unreached('got error event');
+ });
+ t.src = 'data:text/vtt,'+encodeURIComponent('WEBVTT\n\n00:00:00.000 --> 00:00:00.001\ntest'+
+ '\n\nfoobar\n01:00:00.000 --> 01:00:00.001\ntest');
+ t.track.mode = 'showing';
+ video.appendChild(t);
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrackCue/id.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrackCue/id.html
new file mode 100644
index 000000000..a88f94766
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrackCue/id.html
@@ -0,0 +1,39 @@
+<!doctype html>
+<title>TextTrackCue.id</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<div id=log></div>
+<script>
+setup(function(){
+ window.video = document.createElement('video');
+ window.t1 = video.addTextTrack('subtitles');
+ document.body.appendChild(video);
+});
+test(function(){
+ var c1 = new VTTCue(0, 1, 'text1');
+ c1.id = 'id1\r\n\u0000';
+ assert_equals(c1.id, 'id1\r\n\u0000');
+ c1.id = c1.id;
+ assert_equals(c1.id, 'id1\r\n\u0000');
+ c1.id = null;
+ assert_equals(c1.id, 'null');
+}, document.title+', script-created cue');
+
+var t_parsed = async_test(document.title+', parsed cue');
+t_parsed.step(function(){
+ var t = document.createElement('track');
+ t.onload = this.step_func(function(){
+ var c = t.track.cues;
+ assert_equals(c[0].id, '');
+ assert_equals(c[1].id, 'foobar');
+ this.done();
+ });
+ t.onerror = this.step_func(function() {
+ assert_unreached('got error event');
+ });
+ t.src = 'data:text/vtt,'+encodeURIComponent('WEBVTT\n\n00:00:00.000 --> 00:00:00.001\ntest'+
+ '\n\nfoobar\n00:00:00.000 --> 00:00:00.001\ntest');
+ t.track.mode = 'showing';
+ video.appendChild(t);
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrackCue/onenter.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrackCue/onenter.html
new file mode 100644
index 000000000..17deed053
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrackCue/onenter.html
@@ -0,0 +1,36 @@
+<!doctype html>
+<title>TextTrackCue.onenter</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<div id=log></div>
+<script>
+setup(function(){
+ window.c1 = new VTTCue(0, 1, 'text1');
+ window.ev = new Event('enter');
+ window.ran = false;
+ window.cb = function() { ran = true; };
+});
+test(function(){
+ assert_equals(c1.onenter, null, 'initial value');
+ c1.onenter = undefined;
+ assert_equals(c1.onenter, null, 'assigning undefined');
+ c1.onenter = cb;
+ assert_equals(c1.onenter, cb, 'assigning onenter');
+ c1.dispatchEvent(ev);
+ assert_true(ran, 'dispatching event');
+ c1.onenter = null;
+ assert_equals(c1.onenter, null, 'assigning null');
+ ran = false;
+ c1.dispatchEvent(ev);
+ assert_false(ran, 'dispatching event after nulling onenter');
+});
+test(function(){
+ c1.addEventListener('enter', cb, false);
+ c1.dispatchEvent(ev);
+ assert_true(ran);
+ c1.removeEventListener('enter', cb, false);
+ ran = false;
+ c1.dispatchEvent(ev);
+ assert_false(ran);
+}, 'TextTrackCue.addEventListener/removeEventListener');
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrackCue/onexit.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrackCue/onexit.html
new file mode 100644
index 000000000..815377e4d
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrackCue/onexit.html
@@ -0,0 +1,36 @@
+<!doctype html>
+<title>TextTrackCue.onexit</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<div id=log></div>
+<script>
+setup(function(){
+ window.c1 = new VTTCue(0, 1, 'text1');
+ window.ev = new Event('exit');
+ window.ran = false;
+ window.cb = function() { ran = true; };
+});
+test(function(){
+ assert_equals(c1.onexit, null, 'initial value');
+ c1.onexit = undefined;
+ assert_equals(c1.onexit, null, 'assigning undefined');
+ c1.onexit = cb;
+ assert_equals(c1.onexit, cb, 'assigning onexit');
+ c1.dispatchEvent(ev);
+ assert_true(ran, 'dispatching event');
+ c1.onexit = null;
+ assert_equals(c1.onexit, null, 'assigning null');
+ ran = false;
+ c1.dispatchEvent(ev);
+ assert_false(ran, 'dispatching event after nulling onexit');
+});
+test(function(){
+ c1.addEventListener('exit', cb, false);
+ c1.dispatchEvent(ev);
+ assert_true(ran);
+ c1.removeEventListener('exit', cb, false);
+ ran = false;
+ c1.dispatchEvent(ev);
+ assert_false(ran);
+}, 'TextTrackCue.addEventListener/removeEventListener');
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrackCue/pauseOnExit.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrackCue/pauseOnExit.html
new file mode 100644
index 000000000..31ea4c63b
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrackCue/pauseOnExit.html
@@ -0,0 +1,40 @@
+<!doctype html>
+<title>TextTrackCue.pauseOnExit</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<div id=log></div>
+<script>
+setup(function(){
+ window.video = document.createElement('video');
+ window.t1 = video.addTextTrack('subtitles');
+ document.body.appendChild(video);
+});
+test(function(){
+ var c1 = new VTTCue(0, 1, 'text1');
+ assert_equals(c1.pauseOnExit, false);
+ c1.pauseOnExit = null;
+ assert_equals(c1.pauseOnExit, false);
+ c1.pauseOnExit = 'foo';
+ assert_equals(c1.pauseOnExit, true);
+}, document.title+', script-created cue');
+
+var t_parsed = async_test(document.title+', parsed cue');
+t_parsed.step(function(){
+ var t = document.createElement('track');
+ t.onload = this.step_func(function(){
+ var c1 = t.track.cues[0];
+ assert_equals(c1.pauseOnExit, false);
+ c1.pauseOnExit = null;
+ assert_equals(c1.pauseOnExit, false);
+ c1.pauseOnExit = 'foo';
+ assert_equals(c1.pauseOnExit, true);
+ this.done();
+ });
+ t.onerror = this.step_func(function() {
+ assert_unreached('got error event');
+ });
+ t.src = 'data:text/vtt,'+encodeURIComponent('WEBVTT\n\n00:00:00.000 --> 00:00:00.001\ntest');
+ t.track.mode = 'showing';
+ video.appendChild(t);
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrackCue/startTime.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrackCue/startTime.html
new file mode 100644
index 000000000..232a7f23b
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrackCue/startTime.html
@@ -0,0 +1,39 @@
+<!doctype html>
+<title>TextTrackCue.startTime</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<div id=log></div>
+<script>
+setup(function(){
+ window.video = document.createElement('video');
+ window.t1 = video.addTextTrack('subtitles');
+ document.body.appendChild(video);
+});
+test(function(){
+ var c1 = new VTTCue(-1, 1, 'text1');
+ assert_equals(c1.startTime, -1);
+ c1.startTime = c1.startTime;
+ assert_equals(c1.startTime, -1);
+ assert_throws(new TypeError(), function(){ c1.startTime = NaN; });
+ assert_throws(new TypeError(), function(){ c1.startTime = +Infinity; });
+ assert_throws(new TypeError(), function(){ c1.startTime = -Infinity; });
+}, document.title+', script-created cue');
+
+var t_parsed = async_test(document.title+', parsed cue');
+t_parsed.step(function(){
+ var t = document.createElement('track');
+ t.onload = this.step_func(function(){
+ var c = t.track.cues;
+ assert_equals(c[0].startTime, 0);
+ assert_equals(c[1].startTime, 3600);
+ this.done();
+ });
+ t.onerror = this.step_func(function() {
+ assert_unreached('got error event');
+ });
+ t.src = 'data:text/vtt,'+encodeURIComponent('WEBVTT\n\n00:00:00.000 --> 00:00:00.001\ntest'+
+ '\n\nfoobar\n01:00:00.000 --> 01:00:00.001\ntest');
+ t.track.mode = 'showing';
+ video.appendChild(t);
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrackCue/track.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrackCue/track.html
new file mode 100644
index 000000000..219e3e703
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrackCue/track.html
@@ -0,0 +1,38 @@
+<!doctype html>
+<title>TextTrackCue.track</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<div id=log></div>
+<script>
+setup(function(){
+ window.video = document.createElement('video');
+ window.t1 = video.addTextTrack('subtitles');
+ document.body.appendChild(video);
+});
+test(function(){
+ var c1 = new VTTCue(0, 1, 'text1');
+ assert_equals(c1.track, null);
+ t1.addCue(c1);
+ assert_equals(c1.track, t1);
+ t1.removeCue(c1);
+ assert_equals(c1.track, null);
+}, document.title+', script-created cue');
+
+var t_parsed = async_test(document.title+', parsed cue');
+t_parsed.step(function(){
+ var t = document.createElement('track');
+ t.onload = this.step_func(function(){
+ var c = t.track.cues[0];
+ assert_equals(c.track, t.track);
+ t.track.removeCue(c);
+ assert_equals(c.track, null);
+ this.done();
+ });
+ t.onerror = this.step_func(function() {
+ assert_unreached('got error event');
+ });
+ t.src = 'data:text/vtt,'+encodeURIComponent('WEBVTT\n\n00:00:00.000 --> 00:00:00.001\ntest');
+ t.track.mode = 'showing';
+ video.appendChild(t);
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrackCueList/getCueById.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrackCueList/getCueById.html
new file mode 100644
index 000000000..8184189b0
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrackCueList/getCueById.html
@@ -0,0 +1,53 @@
+<!doctype html>
+<title>TextTrackCueList.getCueById</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<div id=log></div>
+<script>
+test(function(){
+ var video = document.createElement('video');
+ var t = video.addTextTrack('subtitles');
+ document.body.appendChild(video);
+ var cues = t.cues;
+ var c = new VTTCue(0, 1, 'text1');
+ t.addCue(c);
+ assert_equals(cues.getCueById(""), null, '""');
+ assert_equals(cues.getCueById(null), null, 'null');
+ assert_equals(cues.getCueById(undefined), null, 'undefined');
+}, document.title+ ', no id');
+test(function(){
+ var video = document.createElement('video');
+ var t = video.addTextTrack('subtitles');
+ document.body.appendChild(video);
+ var cues = t.cues;
+ var c = new VTTCue(0, 1, 'text1');
+ c.id = 'foo';
+ t.addCue(c);
+ assert_equals(cues.getCueById(""), null, '""');
+ assert_equals(cues.getCueById("foo"), c, '"foo"');
+ assert_equals(cues.getCueById({toString:function(){return "foo"}}), c, 'object');
+}, document.title+ ', id foo');
+test(function(){
+ var video = document.createElement('video');
+ var t = video.addTextTrack('subtitles');
+ document.body.appendChild(video);
+ var cues = t.cues;
+ var c = new VTTCue(0, 1, 'text1');
+ c.id = '1';
+ t.addCue(c);
+ assert_equals(cues.getCueById(""), null, '""');
+ assert_equals(cues.getCueById("1"), c, '"1"');
+ assert_equals(cues.getCueById(1), c, '1');
+}, document.title+ ', no 1');
+test(function(){
+ var video = document.createElement('video');
+ var t = video.addTextTrack('subtitles');
+ document.body.appendChild(video);
+ var cues = t.cues;
+ var c = new VTTCue(0, 1, 'text1');
+ c.id = 'a\u0000b';
+ t.addCue(c);
+ assert_equals(cues.getCueById("a\u0000b"), c, '"a\\u0000b"');
+ assert_equals(cues.getCueById("a"), null, '"a"');
+}, document.title+ ', id a\\u0000b');
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrackCueList/getter.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrackCueList/getter.html
new file mode 100644
index 000000000..d9cd87172
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrackCueList/getter.html
@@ -0,0 +1,49 @@
+<!doctype html>
+<title>TextTrackCueList getter</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<div id=log></div>
+<script>
+setup(function(){
+ window.video = document.createElement('video');
+ window.t1 = video.addTextTrack('subtitles');
+ document.body.appendChild(video);
+});
+test(function(){
+ var cues = t1.cues;
+ assert_equals(cues[0], undefined, 'cues[0] before');
+ var c1 = new VTTCue(0, 1, 'text1');
+ t1.addCue(c1);
+ assert_equals(cues[0], c1, 'cues[0]');
+ assert_equals(cues[1], undefined, 'cues[1]');
+ assert_equals(cues[-1], undefined, 'cues[-1]');
+ t1.removeCue(c1);
+ assert_equals(cues[0], undefined, 'cues[0] after');
+});
+test(function(){
+ var cues = t1.cues;
+ assert_equals(cues[0], undefined);
+ cues[0] = 'foo';
+ assert_equals(cues[0], undefined);
+ var c1 = new VTTCue(0, 1, 'text1');
+ t1.addCue(c1);
+ assert_equals(cues[0], c1);
+ cues[0] = 'foo';
+ assert_equals(cues[0], c1);
+ t1.removeCue(c1);
+}, document.title+', no indexed set/create');
+test(function(){
+ 'use strict';
+ var cues = t1.cues;
+ assert_equals(cues[0], undefined);
+ assert_throws(new TypeError(), function() { cues[0] = 'foo'; });
+ assert_equals(cues[0], undefined);
+ var c1 = new VTTCue(0, 1, 'text1');
+ t1.addCue(c1);
+ assert_equals(cues[0], c1);
+ assert_throws(new TypeError(), function() { cues[0] = 'foo'; });
+ assert_equals(cues[0], c1);
+ t1.removeCue(c1);
+}, document.title+', no indexed set/create (strict)');
+
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrackCueList/length.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrackCueList/length.html
new file mode 100644
index 000000000..91e6e7ff9
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrackCueList/length.html
@@ -0,0 +1,22 @@
+<!doctype html>
+<title>TextTrackCueList.length</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<div id=log></div>
+<script>
+setup(function(){
+ window.video = document.createElement('video');
+ window.t1 = video.addTextTrack('subtitles');
+ document.body.appendChild(video);
+});
+test(function(){
+ var cues = t1.cues;
+ assert_equals(cues.length, 0);
+ var c1 = new VTTCue(0, 1, 'text1');
+ t1.addCue(c1);
+ assert_equals(cues.length, 1);
+ t1.removeCue(c1);
+ assert_equals(cues.length, 0);
+});
+
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrackList/getTrackById.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrackList/getTrackById.html
new file mode 100644
index 000000000..b701dd5e7
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrackList/getTrackById.html
@@ -0,0 +1,16 @@
+<!doctype html>
+<title>TextTrackList.getTrackById</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<div id=log></div>
+<script>
+test(function(){
+ var video = document.createElement('video');
+ var track1 = video.addTextTrack('subtitles');
+ var track2 = video.addTextTrack('subtitles');
+ assert_equals(track1.id, '');
+ assert_equals(track2.id, '');
+ assert_equals(video.textTracks.getTrackById(''), track1);
+ assert_equals(video.textTracks.getTrackById('fake-id'), null);
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrackList/getter.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrackList/getter.html
new file mode 100644
index 000000000..8c5fb3759
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrackList/getter.html
@@ -0,0 +1,32 @@
+<!doctype html>
+<title>TextTrackList getter</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<div id=log></div>
+<script>
+setup(function(){
+ window.video = document.createElement('video');
+ video.addTextTrack('subtitles', 'b');
+ window.track = document.createElement('track');
+ track.label = 'a';
+ video.appendChild(track);
+ video.addTextTrack('subtitles', 'c');
+});
+test(function(){
+ assert_equals(video.textTracks[0].label, 'a');
+ assert_equals(video.textTracks[1].label, 'b');
+ assert_equals(video.textTracks[2].label, 'c');
+});
+test(function(){
+ var track_before = video.textTracks[0];
+ video.textTracks[0] = 'foo';
+ assert_equals(video.textTracks[0], track_before);
+}, document.title+', no indexed set/create');
+test(function(){
+ 'use strict';
+ var track_before = video.textTracks[0];
+ assert_throws(new TypeError(), function(){ video.textTracks[0] = 'foo'; });
+ assert_equals(video.textTracks[0], track_before);
+}, document.title+', no indexed set/create (strict)');
+
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrackList/length.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrackList/length.html
new file mode 100644
index 000000000..7a24130d1
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrackList/length.html
@@ -0,0 +1,18 @@
+<!doctype html>
+<title>TextTrackList.length</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<div id=log></div>
+<script>
+setup(function(){
+ window.video = document.createElement('video');
+ video.addTextTrack('subtitles');
+ window.track = document.createElement('track');
+ video.appendChild(track);
+ video.addTextTrack('subtitles');
+});
+test(function(){
+ assert_equals(video.textTracks.length, 3);
+});
+
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrackList/onaddtrack.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrackList/onaddtrack.html
new file mode 100644
index 000000000..114ca8904
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrackList/onaddtrack.html
@@ -0,0 +1,33 @@
+<!doctype html>
+<title>TextTrackList.onaddtrack</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<div id=log></div>
+<script>
+setup(function(){
+ window.tracks = document.createElement('video').textTracks;
+ window.ev = new Event('addtrack');
+ window.ran = false;
+ window.cb = function() { ran = true; };
+});
+test(function(){
+ assert_equals(tracks.onaddtrack, null);
+ tracks.onaddtrack = cb;
+ assert_equals(tracks.onaddtrack, cb);
+ tracks.dispatchEvent(ev);
+ assert_true(ran);
+ tracks.onaddtrack = null;
+ ran = false;
+ tracks.dispatchEvent(ev);
+ assert_false(ran);
+});
+test(function(){
+ tracks.addEventListener('addtrack', cb, false);
+ tracks.dispatchEvent(ev);
+ assert_true(ran);
+ tracks.removeEventListener('addtrack', cb, false);
+ ran = false;
+ tracks.dispatchEvent(ev);
+ assert_false(ran);
+}, 'TextTrackList.addEventListener/removeEventListener');
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrackList/onremovetrack.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrackList/onremovetrack.html
new file mode 100644
index 000000000..b8da16ce2
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TextTrackList/onremovetrack.html
@@ -0,0 +1,33 @@
+<!doctype html>
+<title>TextTrackList.onremovetrack</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<div id=log></div>
+<script>
+setup(function(){
+ window.tracks = document.createElement('video').textTracks;
+ window.ev = new Event('removetrack');
+ window.ran = false;
+ window.cb = function() { ran = true; };
+});
+test(function(){
+ assert_equals(tracks.onremovetrack, null);
+ tracks.onremovetrack = cb;
+ assert_equals(tracks.onremovetrack, cb);
+ tracks.dispatchEvent(ev);
+ assert_true(ran);
+ tracks.onremovetrack = null;
+ ran = false;
+ tracks.dispatchEvent(ev);
+ assert_false(ran);
+});
+test(function(){
+ tracks.addEventListener('removetrack', cb, false);
+ tracks.dispatchEvent(ev);
+ assert_true(ran);
+ tracks.removeEventListener('removetrack', cb, false);
+ ran = false;
+ tracks.dispatchEvent(ev);
+ assert_false(ran);
+}, 'TextTrackList.addEventListener/removeEventListener');
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TrackEvent/constructor.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TrackEvent/constructor.html
new file mode 100644
index 000000000..54567d14a
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TrackEvent/constructor.html
@@ -0,0 +1,24 @@
+<!doctype html>
+<title>TrackEvent constructor</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<div id=log></div>
+<script>
+test(function(){
+ var ev = new TrackEvent('foo');
+ assert_true(ev instanceof TrackEvent, 'ev instanceof TrackEvent');
+ assert_true(ev instanceof Event, 'ev instanceof Event');
+ assert_equals(ev.track, null, 'ev.track');
+ ev.track = {};
+ assert_equals(ev.track, null, 'ev.track after assignment');
+}, document.title+', one arg');
+test(function(){
+ var obj = {};
+ var ev = new TrackEvent('foo', {track:obj});
+ assert_true(ev instanceof TrackEvent, 'ev instanceof TrackEvent');
+ assert_true(ev instanceof Event, 'ev instanceof Event');
+ assert_equals(ev.track, obj, 'ev.track');
+ ev.track = {};
+ assert_equals(ev.track, obj, 'ev.track after assignment');
+}, document.title+', two args');
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TrackEvent/createEvent.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TrackEvent/createEvent.html
new file mode 100644
index 000000000..9bf763f1f
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/interfaces/TrackEvent/createEvent.html
@@ -0,0 +1,15 @@
+<!doctype html>
+<title>TrackEvent created with createEvent</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<div id=log></div>
+<script>
+test(function(){
+ // https://www.w3.org/Bugs/Public/show_bug.cgi?id=17268
+ assert_throws('NOT_SUPPORTED_ERR', function() {
+ var ev = document.createEvent('TrackEvent');
+ });
+ var ev = new TrackEvent('foo');
+ assert_false('initTrackEvent' in ev, 'initTrackEvent');
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/autoplay-overrides-preload.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/autoplay-overrides-preload.html
new file mode 100644
index 000000000..91103c586
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/autoplay-overrides-preload.html
@@ -0,0 +1,28 @@
+<!DOCTYPE HTML>
+<title>autoplay overrides preload</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/media.js"></script>
+<div id=log></div>
+<script>
+['none', 'metadata'].forEach(function(preload) {
+ ['first', 'last'].forEach(function(order) {
+ async_test(function(t) {
+ var a = document.createElement('audio');
+ a.src = getAudioURI('/media/sound_5');
+ if (order == 'first') {
+ a.autoplay = true;
+ a.preload = preload;
+ } else {
+ a.preload = preload;
+ a.autoplay = true;
+ }
+ a.addEventListener('playing', t.step_func(function() {
+ assert_equals(a.readyState, a.HAVE_ENOUGH_DATA);
+ assert_false(a.paused);
+ t.done();
+ }));
+ }, 'autoplay (set ' + order + ') overrides preload "' + preload + '"');
+ });
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/load-events-networkState.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/load-events-networkState.html
new file mode 100644
index 000000000..8c12011ef
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/load-events-networkState.html
@@ -0,0 +1,67 @@
+<!doctype html>
+<title>load() fires abort/emptied events when networkState is not NETWORK_EMPTY</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/media.js"></script>
+<div id=log></div>
+<script>
+function load_test(t, v) {
+ assert_not_equals(v.networkState, v.NETWORK_EMPTY);
+
+ var expected_events = [];
+ if (v.networkState == v.NETWORK_LOADING || v.networkState == v.NETWORK_IDLE) {
+ expected_events.push('abort');
+ }
+ if (v.networkState != v.NETWORK_EMPTY) {
+ expected_events.push('emptied');
+ }
+
+ var actual_events = [];
+ v.onabort = v.onemptied = t.step_func(function(e) {
+ actual_events.push(e.type);
+ });
+
+ v.onloadstart = t.step_func(function() {
+ assert_array_equals(actual_events, expected_events);
+ t.done();
+ });
+
+ v.load();
+
+ assert_array_equals(actual_events, [], 'events should be fired in queued tasks');
+}
+
+async_test(function(t) {
+ var v = document.createElement('video');
+ // suspend is fired optionally "if the user agent intends to not attempt to
+ // fetch the resource" or "once the entire media resource has been fetched"
+ v.preload = 'none';
+ v.src = getAudioURI('/media/sound_5');
+ v.onsuspend = t.step_func(function() {
+ v.onsuspend = null;
+ assert_equals(v.networkState, v.NETWORK_IDLE);
+ load_test(t, v);
+ });
+}, 'NETWORK_IDLE');
+
+async_test(function(t) {
+ var v = document.createElement('video');
+ v.src = 'resources/delayed-broken-video.py';
+ v.onloadstart = t.step_func(function() {
+ v.onloadstart = null;
+ assert_equals(v.networkState, v.NETWORK_LOADING);
+ load_test(t, v);
+ });
+}, 'NETWORK_LOADING');
+
+async_test(function(t) {
+ var v = document.createElement('video');
+ v.src = 'data:,';
+ v.onerror = t.step_func(function() {
+ v.onerror = null;
+ assert_equals(v.networkState, v.NETWORK_NO_SOURCE);
+ load_test(t, v);
+ });
+ assert_equals(v.networkState, v.NETWORK_NO_SOURCE);
+}, 'NETWORK_NO_SOURCE');
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/load-removes-queued-error-event.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/load-removes-queued-error-event.html
new file mode 100644
index 000000000..54d5c28da
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/load-removes-queued-error-event.html
@@ -0,0 +1,44 @@
+<!doctype html>
+<title>load() removes queued error event</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+// The loadstart and error event firing tasks are queued in the synchronous
+// section of the resource selection algorithm, so no tasks can come between
+// them. Calling load() in the loadstart event handler removes the queued error
+// event task at very latest opportunity, failing any implementation that fires
+// the events in the same task.
+
+async_test(function(t) {
+ var v = document.createElement('video');
+ var events = [];
+ v.onloadstart = v.onerror = t.step_func(function(e) {
+ events.push(e.type);
+ if (events.length == 1) {
+ v.load();
+ } else if (events.length == 3) {
+ assert_array_equals(events, ['loadstart', 'loadstart', 'error']);
+ t.done();
+ }
+ });
+ v.src = '';
+}, 'video error event');
+
+async_test(function(t) {
+ var v = document.createElement('video');
+ var s = document.createElement('source');
+ var events = [];
+ v.onloadstart = s.onerror = t.step_func(function(e) {
+ events.push(e.type);
+ if (events.length == 1) {
+ v.load();
+ } else if (events.length == 3) {
+ assert_array_equals(events, ['loadstart', 'loadstart', 'error']);
+ t.done();
+ }
+ });
+ v.onerror = t.step_func(function() { assert_unreached(); });
+ v.appendChild(s);
+}, 'source error event');
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-candidate-insert-before.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-candidate-insert-before.html
new file mode 100644
index 000000000..39c988750
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-candidate-insert-before.html
@@ -0,0 +1,29 @@
+<!doctype html>
+<title>inserting another source before the candidate</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+var v;
+function createSource(src) {
+ var source = document.createElement('source');
+ source.src = src;
+ return source;
+}
+var t = async_test(function(t) {
+ v = document.createElement('video');
+ v.addEventListener('loadstart', t.step_func(function() {
+ assert_equals(v.currentSrc.substr(v.currentSrc.lastIndexOf('#')), '#a');
+ t.done();
+ }), false);
+ v.appendChild(createSource('#a')); // invokes resource selection
+});
+</script>
+<!-- now resource selection algorithm will continue its sync section (the </script> tag below provides a stable state) -->
+<!-- #a is candidate -->
+<!-- pointer is between #a and the end of the list -->
+<script>
+t.step(function() {
+ v.insertBefore(createSource('#b'), v.firstChild); // pointer is unchanged, #a is still candidate
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-candidate-moved.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-candidate-moved.html
new file mode 100644
index 000000000..f59452e0d
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-candidate-moved.html
@@ -0,0 +1,21 @@
+<!doctype html>
+<title>moving the candidate source</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+var s;
+var t = async_test(function(t) {
+ var v = document.createElement('video');
+ s = document.createElement('source');
+ s.src = 'resources/delayed-broken-video.py';
+ s.onerror = t.step_func(function() { t.done(); });
+ v.appendChild(s); // invokes resource selection
+ onload = t.step_func(function() { assert_unreached(); });
+});
+</script>
+<script>
+t.step(function() {
+ document.body.appendChild(s);
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-candidate-remove-addEventListener.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-candidate-remove-addEventListener.html
new file mode 100644
index 000000000..0c1e6f0ad
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-candidate-remove-addEventListener.html
@@ -0,0 +1,26 @@
+<!doctype html>
+<title>removing the candidate source, addEventListener</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+var v;
+function createSource(src) {
+ var source = document.createElement('source');
+ source.src = src;
+ return source;
+}
+var t = async_test(function(t) {
+ v = document.createElement('video');
+ v.appendChild(createSource('resources/delayed-broken-video.py')); // invokes resource selection
+ v.firstChild.addEventListener('error', t.step_func(function() { t.done(); }), false);
+});
+</script>
+<!-- now resource selection algorithm will continue its sync section (the </script> tag below provides a stable state) -->
+<!-- the <source> is candidate -->
+<!-- pointer is between the <source> and the end of the list -->
+<script>
+t.step(function() {
+ v.removeChild(v.firstChild); // tests that we fire 'error' on it despite being removed
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-candidate-remove-no-listener.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-candidate-remove-no-listener.html
new file mode 100644
index 000000000..f384eb312
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-candidate-remove-no-listener.html
@@ -0,0 +1,26 @@
+<!doctype html>
+<title>removing the candidate source, no listener</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+var v;
+function createSource(src) {
+ var source = document.createElement('source');
+ source.src = src;
+ return source;
+}
+var t = async_test(function(t) {
+ v = document.createElement('video');
+ v.appendChild(createSource('resources/delayed-broken-video.py')); // invokes resource selection
+});
+</script>
+<!-- now resource selection algorithm will continue its sync section (the </script> tag below provides a stable state) -->
+<!-- the <source> is candidate -->
+<!-- pointer is between the <source> and the end of the list -->
+<script>
+t.step(function() {
+ v.removeChild(v.firstChild); // just tests that we don't crash
+ onload = t.step_func(function() { t.done(); });
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-candidate-remove-onerror.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-candidate-remove-onerror.html
new file mode 100644
index 000000000..c295c85bf
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-candidate-remove-onerror.html
@@ -0,0 +1,26 @@
+<!doctype html>
+<title>removing the candidate source, onerror</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+var v;
+function createSource(src) {
+ var source = document.createElement('source');
+ source.src = src;
+ return source;
+}
+var t = async_test(function(t) {
+ v = document.createElement('video');
+ v.appendChild(createSource('resources/delayed-broken-video.py')); // invokes resource selection
+ v.firstChild.onerror = t.step_func(function() { t.done(); });
+});
+</script>
+<!-- now resource selection algorithm will continue its sync section (the </script> tag below provides a stable state) -->
+<!-- the <source> is candidate -->
+<!-- pointer is between the <source> and the end of the list -->
+<script>
+t.step(function() {
+ v.removeChild(v.firstChild); // tests that we fire 'error' on it despite being removed
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-audio-constructor-no-src.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-audio-constructor-no-src.html
new file mode 100644
index 000000000..cb2a57959
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-audio-constructor-no-src.html
@@ -0,0 +1,13 @@
+<!doctype html>
+<title>NOT invoking resource selection with new Audio() sans src</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+async_test(function(t) {
+ var a = new Audio();
+ assert_equals(a.networkState, a.NETWORK_EMPTY);
+ a.onloadstart = t.step_func(function() { assert_unreached(); });
+ window.onload = t.step_func(function() { t.done(); });
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-audio-constructor.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-audio-constructor.html
new file mode 100644
index 000000000..662129756
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-audio-constructor.html
@@ -0,0 +1,12 @@
+<!doctype html>
+<title>invoking resource selection with new Audio(src)</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+async_test(function(t) {
+ var a = new Audio('');
+ a.onloadstart = t.step_func(function() { t.done(); });
+ window.onload = t.step_func(function() { assert_unreached(); });
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-in-sync-event.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-in-sync-event.html
new file mode 100644
index 000000000..55fc7c20d
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-in-sync-event.html
@@ -0,0 +1,32 @@
+<!doctype html>
+<title>await a stable state and sync event handlers</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<video></video>
+<script>
+var v;
+var t = async_test(function(t) {
+ v = document.querySelector('video');
+ var a = document.createElement('a');
+ a.onclick = t.step_func(function() {
+ v.setAttribute('src', '#'); // invokes media load which invokes resource selection
+ assert_equals(v.networkState, v.NETWORK_NO_SOURCE, 'networkState in onclick handler');
+ });
+ a.click(); // sync fires click, so sets src
+ // now we should still await a stable state because the script hasn't
+ // finished, the event handler has just returned
+ assert_equals(v.networkState, v.NETWORK_NO_SOURCE, 'networkState after click()');
+ v.removeAttribute('src');
+});
+</script>
+<script>
+t.step(function() {
+ // now the sync section of resource selection should have run and should
+ // have found no src="" or <source> thus networkState being set to NETWORK_EMPTY.
+ // if the sync section was run when onclick returned, then networkState
+ // would be either NETWORK_LOADING or NETWORK_NO_SOURCE.
+ assert_equals(v.networkState, v.NETWORK_EMPTY, 'networkState in separate script');
+ t.done();
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-insert-fragment-into-document.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-insert-fragment-into-document.html
new file mode 100644
index 000000000..5d4c32f67
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-insert-fragment-into-document.html
@@ -0,0 +1,22 @@
+<!doctype html>
+<title>NOT invoking resource selection by inserting document fragment into a document</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+var v;
+var t = async_test(function(t) {
+ v = document.createElement('video');
+ var fragment = document.createDocumentFragment();
+ fragment.appendChild(v);
+ assert_equals(v.networkState, v.NETWORK_EMPTY, 'networkState after fragment.appendChild(v)');
+ document.body.appendChild(fragment);
+ assert_equals(v.networkState, v.NETWORK_EMPTY, 'networkState after document.body.appendChild(fragment)');
+});
+</script>
+<script>
+t.step(function() {
+ assert_equals(v.networkState, v.NETWORK_EMPTY, 'networkState in separate script');
+ t.done();
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-insert-into-document.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-insert-into-document.html
new file mode 100644
index 000000000..2f9ec978a
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-insert-into-document.html
@@ -0,0 +1,12 @@
+<!doctype html>
+<title>NOT invoking resource selection by inserting into a document</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+test(function(t) {
+ var v = document.createElement('video');
+ document.body.appendChild(v);
+ assert_equals(v.networkState, v.NETWORK_EMPTY);
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-insert-into-iframe.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-insert-into-iframe.html
new file mode 100644
index 000000000..45d133d87
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-insert-into-iframe.html
@@ -0,0 +1,23 @@
+<!doctype html>
+<title>NOT invoking resource selection by inserting into other document with src set</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<iframe hidden></iframe>
+<script>
+async_test(function(t) {
+ var v = document.createElement('video');
+ v.src = 'data:,';
+ v.onerror = t.step_func(function() {
+ assert_equals(v.readyState, v.HAVE_NOTHING);
+ assert_equals(v.networkState, v.NETWORK_NO_SOURCE);
+ var iframe = document.querySelector('iframe');
+ iframe.contentDocument.body.appendChild(v);
+ v.onloadstart = t.step_func(function() { assert_unreached(); });
+ // wait for an event after the above
+ var v2 = document.createElement('video');
+ v2.src = 'data:,';
+ v2.onloadstart = t.step_func(function() { t.done(); });
+ });
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-insert-parent-into-document.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-insert-parent-into-document.html
new file mode 100644
index 000000000..6da34344f
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-insert-parent-into-document.html
@@ -0,0 +1,19 @@
+<!doctype html>
+<title>NOT invoking resource selection by inserting parent into a document</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+async_test(function(t) {
+ var v = document.createElement('video');
+ var div = document.createElement('div');
+ div.appendChild(v);
+ assert_equals(v.networkState, v.NETWORK_EMPTY, 'networkState after div.appendChild(v)');
+ document.body.appendChild(div);
+ assert_equals(v.networkState, v.NETWORK_EMPTY, 'networkState after document.body.appendChild(div)');
+ window.onload = t.step_func(function() {
+ assert_equals(v.networkState, v.NETWORK_EMPTY, 'networkState in window.onload');
+ t.done();
+ });
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-insert-source-in-div.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-insert-source-in-div.html
new file mode 100644
index 000000000..b79bea52f
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-insert-source-in-div.html
@@ -0,0 +1,14 @@
+<!doctype html>
+<title>NOT invoking resource selection by inserting &lt;source> in &lt;div> in &lt;video></title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<video><div></div></video>
+<script>
+async_test(function(t) {
+ var v = document.querySelector('video');
+ v.onloadstart = t.step_func(function() { assert_unreached(); });
+ v.firstChild.appendChild(document.createElement('source'));
+ window.onload = t.step_func(function() { t.done(); });
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-insert-source-in-namespace.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-insert-source-in-namespace.html
new file mode 100644
index 000000000..b73f229ec
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-insert-source-in-namespace.html
@@ -0,0 +1,14 @@
+<!doctype html>
+<title>NOT invoking resource selection by inserting &lt;source> in the wrong namespace</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<video></video>
+<script>
+async_test(function(t) {
+ var v = document.querySelector('video');
+ v.onloadstart = t.step_func(function() { assert_unreached(); });
+ v.appendChild(document.createElementNS('bogus','source'));
+ window.onload = t.step_func(function() { t.done(); });
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-insert-source-networkState.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-insert-source-networkState.html
new file mode 100644
index 000000000..5ef6e4cb3
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-insert-source-networkState.html
@@ -0,0 +1,38 @@
+<!doctype html>
+<title>NOT invoking resource selection by inserting &lt;source> when networkState is not NETWORK_EMPTY</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+var loadstartCount = 0;
+var s1ErrorCount = 0;
+var s2ErrorCount = 0;
+var v;
+var t = async_test(function(t) {
+ v = document.createElement('video');
+ v.onloadstart = function() { loadstartCount++; };
+ var s1 = document.createElement('source');
+ s1.src = 'resources/delayed-broken-video.py';
+ s1.onerror = function() { s1ErrorCount++; };
+ v.appendChild(s1); // invokes resource selection
+ assert_equals(v.networkState, v.NETWORK_NO_SOURCE, 'networkState in first script');
+});
+</script>
+<script>
+t.step(function() {
+ assert_equals(v.networkState, v.NETWORK_LOADING, 'networkState in second script');
+ assert_equals(s1ErrorCount, 0, 's1ErrorCount in second script');
+ var s2 = document.createElement('source');
+ s2.onerror = t.step_func(function() {
+ s2ErrorCount++;
+ assert_equals(s1ErrorCount, 1, 's1ErrorCount in s2.onerror');
+ });
+ v.appendChild(s2);
+ onload = t.step_func(function() {
+ assert_equals(s2ErrorCount, 1, 's2ErrorCount in window.onload');
+ assert_equals(loadstartCount, 1, 'loadstartCount in window.onload'); // reliable if https://www.w3.org/Bugs/Public/show_bug.cgi?id=24353 is fixed
+ assert_equals(v.networkState, v.NETWORK_NO_SOURCE, 'networkState in window.onload'); // See Waiting step
+ t.done();
+ });
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-insert-source-not-in-document.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-insert-source-not-in-document.html
new file mode 100644
index 000000000..2007b2e8b
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-insert-source-not-in-document.html
@@ -0,0 +1,13 @@
+<!doctype html>
+<title>invoking resource selection by inserting &lt;source> in video not in a document</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+async_test(function(t) {
+ var v = document.createElement('video');
+ v.onloadstart = t.step_func(function() { t.done(); });
+ v.appendChild(document.createElement('source'));
+ window.onload = t.step_func(function() { assert_unreached(); });
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-insert-source.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-insert-source.html
new file mode 100644
index 000000000..969daad62
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-insert-source.html
@@ -0,0 +1,14 @@
+<!doctype html>
+<title>invoking resource selection by inserting &lt;source></title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<video></video>
+<script>
+async_test(function(t) {
+ var v = document.querySelector('video');
+ v.onloadstart = t.step_func(function() { t.done(); });
+ v.appendChild(document.createElement('source'));
+ window.onload = t.step_func(function() { assert_unreached(); });
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-load.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-load.html
new file mode 100644
index 000000000..909c72cd1
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-load.html
@@ -0,0 +1,20 @@
+<!doctype html>
+<title>invoking resource selection with load()</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+var v;
+var t = async_test(function(t) {
+ v = document.createElement('video');
+ assert_equals(v.networkState, v.NETWORK_EMPTY, 'networkState after creating v');
+ v.load();
+ assert_equals(v.networkState, v.NETWORK_NO_SOURCE, 'networkState after v.load()');
+});
+</script>
+<script>
+t.step(function() {
+ assert_equals(v.networkState, v.NETWORK_EMPTY, 'networkState in separate script');
+ t.done();
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-pause-networkState.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-pause-networkState.html
new file mode 100644
index 000000000..18561a264
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-pause-networkState.html
@@ -0,0 +1,28 @@
+<!doctype html>
+<title>NOT invoking resource selection with pause() when networkState is not NETWORK_EMPTY</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<video></video>
+<script>
+var v;
+var t = async_test(function(t) {
+ v = document.querySelector('video');
+ v.src = 'data:,';
+ assert_equals(v.networkState, v.NETWORK_NO_SOURCE, 'networkState after setting src');
+ var errorCount = 0;
+ v.onerror = t.step_func(function() {
+ errorCount++;
+ if (errorCount == 1) {
+ assert_equals(v.networkState, v.NETWORK_NO_SOURCE, 'networkState in onerror');
+ v.pause(); // should not invoke RSA. if it does, error will be fired again.
+ } else {
+ assert_unreached();
+ }
+ });
+ onload = t.step_func(function() {
+ assert_equals(errorCount, 1, 'errorCount');
+ t.done();
+ });
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-pause.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-pause.html
new file mode 100644
index 000000000..4f1bca74d
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-pause.html
@@ -0,0 +1,20 @@
+<!doctype html>
+<title>invoking resource selection with pause()</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+var v;
+var t = async_test(function(t) {
+ v = document.createElement('video');
+ assert_equals(v.networkState, v.NETWORK_EMPTY, 'networkState after creating v');
+ v.pause();
+ assert_equals(v.networkState, v.NETWORK_NO_SOURCE, 'networkState after v.pause()');
+});
+</script>
+<script>
+t.step(function() {
+ assert_equals(v.networkState, v.NETWORK_EMPTY, 'networkState in separate script');
+ t.done();
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-play.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-play.html
new file mode 100644
index 000000000..64a440080
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-play.html
@@ -0,0 +1,20 @@
+<!doctype html>
+<title>invoking resource selection with play()</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+var v;
+var t = async_test(function(t) {
+ v = document.createElement('video');
+ assert_equals(v.networkState, v.NETWORK_EMPTY, 'networkState after creating v');
+ v.play();
+ assert_equals(v.networkState, v.NETWORK_NO_SOURCE, 'networkState after v.play()');
+});
+</script>
+<script>
+t.step(function() {
+ assert_equals(v.networkState, v.NETWORK_EMPTY, 'networkState in separate script');
+ t.done();
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-remove-from-document-networkState.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-remove-from-document-networkState.html
new file mode 100644
index 000000000..1eed276b2
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-remove-from-document-networkState.html
@@ -0,0 +1,29 @@
+<!doctype html>
+<title>NOT invoking resource selection with implicit pause() when networkState is not NETWORK_EMPTY</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<video></video>
+<script>
+var v;
+var t = async_test(function(t) {
+ v = document.querySelector('video');
+ v.src = 'data:,';
+ document.body.appendChild(v);
+ assert_equals(v.networkState, v.NETWORK_NO_SOURCE, 'networkState after setting src');
+ var errorCount = 0;
+ v.onerror = t.step_func(function() {
+ errorCount++;
+ if (errorCount == 1) {
+ assert_equals(v.networkState, v.NETWORK_NO_SOURCE, 'networkState in onerror');
+ document.body.removeChild(v); // invokes pause() which should not invoke RSA. if it does, error will be fired again.
+ } else {
+ assert_unreached();
+ }
+ });
+ onload = t.step_func(function() {
+ assert_equals(errorCount, 1, 'errorCount');
+ t.done();
+ });
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-remove-from-document.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-remove-from-document.html
new file mode 100644
index 000000000..23e7104ca
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-remove-from-document.html
@@ -0,0 +1,21 @@
+<!doctype html>
+<title>NOT invoking resource selection by removing from document with NETWORK_EMPTY</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+var v;
+var t = async_test(function(t) {
+ v = document.createElement('video');
+ document.body.appendChild(v);
+ assert_equals(v.networkState, v.NETWORK_EMPTY, 'networkState after appending v to document');
+ v.parentNode.removeChild(v); // search for "When a media element is removed from a Document,"
+ assert_equals(v.networkState, v.NETWORK_EMPTY, 'networkState after removing v');
+});
+</script>
+<script>
+t.step(function() {
+ assert_equals(v.networkState, v.NETWORK_EMPTY, 'networkState in separate script');
+ t.done();
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-remove-src.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-remove-src.html
new file mode 100644
index 000000000..6302ffeac
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-remove-src.html
@@ -0,0 +1,22 @@
+<!doctype html>
+<title>NOT invoking media load or resource selection when removing the src attribute</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+var v;
+var t = async_test(function(t) {
+ v = document.createElement('video');
+ v.setAttribute('src', ''); // invokes media load
+ assert_equals(v.networkState, v.NETWORK_NO_SOURCE, 'networkState after setting src');
+ var s = document.createElement('source');
+ s.onerror = this.step_func(function() { assert_unreached(); });
+ v.appendChild(s); // src is present so nothing happens here
+ onload = this.step_func(function() { t.done(); });
+});
+</script>
+<script>
+t.step(function() {
+ v.removeAttribute('src'); // nothing should happen
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-set-src-in-namespace.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-set-src-in-namespace.html
new file mode 100644
index 000000000..438db124d
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-set-src-in-namespace.html
@@ -0,0 +1,14 @@
+<!doctype html>
+<title>NOT invoking load by setting src in the wrong namespace</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<video></video>
+<script>
+async_test(function(t) {
+ var v = document.querySelector('video');
+ v.onloadstart = t.step_func(function() { assert_unreached(); });
+ v.setAttributeNS('bogus','src', '');
+ window.onload = t.step_func(function() { t.done(); });
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-set-src-networkState.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-set-src-networkState.html
new file mode 100644
index 000000000..e195dedb0
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-set-src-networkState.html
@@ -0,0 +1,16 @@
+<!doctype html>
+<title>invoking load by setting src when networkState is not NETWORK_EMPTY</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+test(function(t) {
+ var v = document.createElement('video');
+ v.play(); // invokes resource selection and sets .paused to false
+ assert_equals(v.networkState, v.NETWORK_NO_SOURCE, 'networkState');
+ assert_false(v.paused, 'paused');
+ v.setAttribute('src', ''); // invokes media load which sets .paused to true
+ assert_equals(v.networkState, v.NETWORK_NO_SOURCE, 'networkState after setting src');
+ assert_true(v.paused, 'paused after setting src');
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-set-src-not-in-document.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-set-src-not-in-document.html
new file mode 100644
index 000000000..f6c4f2406
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-set-src-not-in-document.html
@@ -0,0 +1,13 @@
+<!doctype html>
+<title>invoking load by setting src on video not in a document</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+async_test(function(t) {
+ var v = document.createElement('video');
+ v.onloadstart = t.step_func(function() { t.done(); });
+ v.setAttribute('src','');
+ window.onload = t.step_func(function() { assert_unreached(); });
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-set-src.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-set-src.html
new file mode 100644
index 000000000..e04b1b058
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-invoke-set-src.html
@@ -0,0 +1,14 @@
+<!doctype html>
+<title>invoking load by setting src</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<video></video>
+<script>
+async_test(function(t) {
+ var v = document.querySelector('video');
+ v.onloadstart = t.step_func(function() { t.done(); });
+ v.setAttribute('src', '');
+ window.onload = t.step_func(function() { assert_unreached(); });
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-pointer-control.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-pointer-control.html
new file mode 100644
index 000000000..dad5e5fd0
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-pointer-control.html
@@ -0,0 +1,26 @@
+<!doctype html>
+<title>pointer updates (control test)</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+var a = 0;
+var b = 0;
+var c = 0;
+</script>
+<video
+ ><source onerror=a++
+ ><source onerror=b++ src='resources/delayed-broken-video.py'
+ ><source onerror=c++
+ ></video
+>
+<script>
+async_test(function(t) {
+ window.onload = t.step_func(function() {
+ assert_equals(a, 1, 'error events on a');
+ assert_equals(b, 1, 'error events on b');
+ assert_equals(c, 1, 'error events on c');
+ t.done();
+ });
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-pointer-insert-br.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-pointer-insert-br.html
new file mode 100644
index 000000000..3ee141e30
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-pointer-insert-br.html
@@ -0,0 +1,33 @@
+<!doctype html>
+<title>pointer updates (adding br elements)</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+var a = 0;
+var b = 0;
+var c = 0;
+</script>
+<video
+ ><source onerror=a++
+ ><source onerror=b++ src='resources/delayed-broken-video.py'
+ ><source onerror=c++
+ ></video
+>
+<script>
+async_test(function(t) {
+ var video = document.querySelector('video');
+ // add br elements
+ var br = document.createElement('br');
+ video.insertBefore(br, video.querySelector('[onerror="a++"]'));
+ video.insertBefore(br.cloneNode(false), video.querySelector('[onerror="b++"]'));
+ video.insertBefore(br.cloneNode(false), video.querySelector('[onerror="c++"]'));
+ video.appendChild(br.cloneNode(false));
+ window.onload = t.step_func(function() {
+ assert_equals(a, 1, 'error events on a');
+ assert_equals(b, 1, 'error events on b');
+ assert_equals(c, 1, 'error events on c');
+ t.done();
+ });
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-pointer-insert-source.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-pointer-insert-source.html
new file mode 100644
index 000000000..2d32e6fca
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-pointer-insert-source.html
@@ -0,0 +1,44 @@
+<!doctype html>
+<title>pointer updates (adding source elements)</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+var a = 0;
+var b = 0;
+var c = 0;
+var x1 = 0;
+var x2 = 0;
+var x3 = 0;
+var x4 = 0;
+</script>
+<video
+ ><source onerror=a++
+ ><source onerror=b++ src='resources/delayed-broken-video.py'
+ ><source onerror=c++
+ ></video
+>
+<script>
+async_test(function(t) {
+ var video = document.querySelector('video');
+ // add source elements
+ var source1 = document.createElement('source'); source1.onerror = function() { x1++; };
+ var source2 = document.createElement('source'); source2.onerror = function() { x2++; };
+ var source3 = document.createElement('source'); source3.onerror = function() { x3++; };
+ var source4 = document.createElement('source'); source4.onerror = function() { x4++; };
+ video.insertBefore(source1, video.querySelector('[onerror="a++"]'));
+ video.insertBefore(source2, video.querySelector('[onerror="b++"]'));
+ video.insertBefore(source3, video.querySelector('[onerror="c++"]'));
+ video.appendChild(source4);
+ window.onload = t.step_func(function() {
+ assert_equals(a, 1, 'error events on a');
+ assert_equals(b, 1, 'error events on b');
+ assert_equals(c, 1, 'error events on c');
+ assert_equals(x1, 0, 'error events on x1');
+ assert_equals(x2, 0, 'error events on x2');
+ assert_equals(x3, 1, 'error events on x3');
+ assert_equals(x4, 1, 'error events on x4');
+ t.done();
+ });
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-pointer-insert-text.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-pointer-insert-text.html
new file mode 100644
index 000000000..15a4e4be0
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-pointer-insert-text.html
@@ -0,0 +1,33 @@
+<!doctype html>
+<title>pointer updates (adding text nodes)</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+var a = 0;
+var b = 0;
+var c = 0;
+</script>
+<video
+ ><source onerror=a++
+ ><source onerror=b++ src='resources/delayed-broken-video.py'
+ ><source onerror=c++
+ ></video
+>
+<script>
+async_test(function(t) {
+ var video = document.querySelector('video');
+ // add text nodes
+ var text = document.createTextNode('x');
+ video.insertBefore(text, video.querySelector('[onerror="a++"]'));
+ video.insertBefore(text.cloneNode(false), video.querySelector('[onerror="b++"]'));
+ video.insertBefore(text.cloneNode(false), video.querySelector('[onerror="c++"]'));
+ video.appendChild(text.cloneNode(false));
+ window.onload = t.step_func(function() {
+ assert_equals(a, 1, 'error events on a');
+ assert_equals(b, 1, 'error events on b');
+ assert_equals(c, 1, 'error events on c');
+ t.done();
+ });
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-pointer-remove-source-after.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-pointer-remove-source-after.html
new file mode 100644
index 000000000..0d1c94037
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-pointer-remove-source-after.html
@@ -0,0 +1,56 @@
+<!doctype html>
+<title>pointer updates (removing source element after pointer)</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+var a = 0;
+var b = 0;
+var c = 0;
+var x1 = 0;
+var x2 = 0;
+var x3 = 0;
+var x4 = 0;
+</script>
+<video
+ ><source onerror=a++
+ ><source onerror=b++ src='resources/delayed-broken-video.py'
+ ><source onerror=x1++
+ ><source onerror=x2++
+ ><source onerror=x3++
+ ><source onerror=x4++
+ ><source onerror=c++
+ ></video
+>
+<script>
+var v;
+var t = async_test(function(t) {
+ v = document.querySelector('video');
+ v.removeChild(document.querySelector('[onerror="x1++"]'));
+ window.onload = t.step_func(function() {
+ assert_equals(a, 1, 'error events on a');
+ assert_equals(b, 1, 'error events on b');
+ assert_equals(c, 1, 'error events on c');
+ assert_equals(x1, 0, 'error events on x1');
+ assert_equals(x2, 0, 'error events on x2');
+ assert_equals(x3, 0, 'error events on x3');
+ assert_equals(x4, 0, 'error events on x4');
+ t.done();
+ });
+});
+</script>
+<script>
+t.step(function() {
+ v.removeChild(document.querySelector('[onerror="x2++"]'));
+});
+</script>
+<script>
+t.step(function() {
+ v.removeChild(document.querySelector('[onerror="x3++"]'));
+});
+</script>
+<script>
+t.step(function() {
+ v.removeChild(document.querySelector('[onerror="x4++"]'));
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-pointer-remove-source.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-pointer-remove-source.html
new file mode 100644
index 000000000..191f9b5e2
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-pointer-remove-source.html
@@ -0,0 +1,43 @@
+<!doctype html>
+<title>pointer updates (removing source elements)</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+var a = 0;
+var b = 0;
+var c = 0;
+var x1 = 0;
+var x2 = 0;
+var x3 = 0;
+var x4 = 0;
+</script>
+<video
+ ><source onerror=x1++
+ ><source onerror=a++
+ ><source onerror=x2++
+ ><source onerror=b++ src='resources/delayed-broken-video.py'
+ ><source onerror=x3++
+ ><source onerror=c++
+ ><source onerror=x4++
+ ></video
+>
+<script>
+async_test(function(t) {
+ var video = document.querySelector('video');
+ // remove the xn elements
+ [].forEach.call(document.querySelectorAll('[onerror^="x"]'), function(elm) {
+ video.removeChild(elm);
+ });
+ window.onload = t.step_func(function() {
+ assert_equals(a, 1, 'error events on a');
+ assert_equals(b, 1, 'error events on b');
+ assert_equals(c, 1, 'error events on c');
+ assert_equals(x1, 1, 'error events on x1');
+ assert_equals(x2, 1, 'error events on x2');
+ assert_equals(x3, 0, 'error events on x3');
+ assert_equals(x4, 0, 'error events on x4');
+ t.done();
+ });
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-pointer-remove-text.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-pointer-remove-text.html
new file mode 100644
index 000000000..f0fe5da90
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-pointer-remove-text.html
@@ -0,0 +1,33 @@
+<!doctype html>
+<title>pointer updates (removing text nodes)</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+var a = 0;
+var b = 0;
+var c = 0;
+</script>
+<video
+ >x<source onerror=a++
+ >x<source onerror=b++ src='resources/delayed-broken-video.py'
+ >x<source onerror=c++
+ >x</video
+>
+<script>
+async_test(function(t) {
+ var video = document.querySelector('video');
+ // remove the text nodes
+ [].forEach.call(video.childNodes, function(node) {
+ if (node.nodeType == node.TEXT_NODE) {
+ video.removeChild(node);
+ }
+ });
+ window.onload = t.step_func(function() {
+ assert_equals(a, 1, 'error events on a');
+ assert_equals(b, 1, 'error events on b');
+ assert_equals(c, 1, 'error events on c');
+ t.done();
+ });
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-remove-source.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-remove-source.html
new file mode 100644
index 000000000..fbeead019
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-remove-source.html
@@ -0,0 +1,24 @@
+<!doctype html>
+<title>Changes to networkState when inserting and removing a &lt;source></title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+var v;
+var t = async_test(function(t) {
+ v = document.createElement('video');
+ assert_equals(v.networkState, v.NETWORK_EMPTY, 'networkState when creating the element');
+ v.appendChild(document.createElement('source')); // runs resource selection algorithm
+ assert_equals(v.networkState, v.NETWORK_NO_SOURCE, 'networkState when inserting a source element');
+ v.removeChild(v.firstChild);
+ assert_equals(v.networkState, v.NETWORK_NO_SOURCE, 'networkState after removing the source element');
+});
+</script>
+<!-- now resource selection will continue its sync section (the </script> tag below provides a stable state) -->
+<!-- will find neither src nor source, so sets networkState to NETWORK_EMPTY -->
+<script>
+t.step(function() {
+ assert_equals(v.networkState, v.NETWORK_EMPTY, 'networkState after letting the sync section of resource selection run');
+ t.done();
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-remove-src.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-remove-src.html
new file mode 100644
index 000000000..4d7887182
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-remove-src.html
@@ -0,0 +1,22 @@
+<!doctype html>
+<title>invoking resource selection by setting src; await stable state</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+var v;
+var t = async_test(function(t) {
+ v = document.createElement('video');
+ v.onloadstart = t.step_func(function() { assert_unreached(); });
+ v.setAttribute('src', ''); // runs resource selection algorithm, but it will wait running the sync section until this script has finished
+ assert_equals(v.networkState, v.NETWORK_NO_SOURCE);
+ v.removeAttribute('src'); // will make resource selection algorithm revert to NETWORK_EMPTY and abort (in the sync section)
+ assert_equals(v.networkState, v.NETWORK_NO_SOURCE);
+ window.onload = t.step_func(function() { t.done(); });
+});
+</script>
+<script>
+t.step(function() {
+ assert_equals(v.networkState, v.NETWORK_EMPTY);
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-source-media.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-source-media.html
new file mode 100644
index 000000000..6332f0890
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resource-selection-source-media.html
@@ -0,0 +1,14 @@
+<!doctype html>
+<title>the &lt;source> media attribute has no effect</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<video><source src="resources/delayed-broken-video.py" media="none"></video>
+<script>
+test(function() {
+ var v = document.querySelector('video');
+ var s = document.querySelector('source');
+ assert_equals(v.networkState, v.NETWORK_LOADING);
+ assert_equals(v.currentSrc, s.src);
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resources/delayed-broken-video.py b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resources/delayed-broken-video.py
new file mode 100644
index 000000000..88e502794
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/resources/delayed-broken-video.py
@@ -0,0 +1,5 @@
+import time
+
+def main(request, response):
+ time.sleep(0.1)
+ return [("Content-Type", "text/plain")], "FAIL"
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/stable-state-beforeunload-manual.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/stable-state-beforeunload-manual.html
new file mode 100644
index 000000000..61ed225fa
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/stable-state-beforeunload-manual.html
@@ -0,0 +1,30 @@
+<!doctype html>
+<title>stable state in beforeunload</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<button>click this button and cancel navigation</button>
+<a href="data:text/plain,FAIL: did not cancel navigation"></a>
+<script>
+async_test(function(t) {
+ window.onbeforeunload = t.step_func(function(event) {
+ var message = "foo bar";
+ event.returnValue = message;
+ return message;
+ });
+ var button = document.querySelector('button');
+ var link = document.querySelector('a');
+ button.onclick = t.step_func(function() {
+ v = document.createElement('video');
+ v.src = 'data:,';
+ assert_equals(v.networkState, v.NETWORK_NO_SOURCE, 'networkState before dialog');
+ assert_equals(v.currentSrc, '', 'currentSrc before dialog');
+ link.click();
+ assert_equals(v.networkState, v.NETWORK_NO_SOURCE, 'networkState after dialog');
+ assert_equals(v.currentSrc, '', 'currentSrc after dialog');
+ t.done();
+ window.onbeforeonload = null;
+ button.remove();
+ });
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/stable-state-dialogs-manual.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/stable-state-dialogs-manual.html
new file mode 100644
index 000000000..267dde913
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/stable-state-dialogs-manual.html
@@ -0,0 +1,18 @@
+<!doctype html>
+<title>stable state in dialogs</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+['alert', 'confirm', 'prompt'].forEach(function(dialog) {
+ test(function() {
+ v = document.createElement('video');
+ v.src = 'data:,';
+ assert_equals(v.networkState, v.NETWORK_NO_SOURCE, 'networkState before dialog');
+ assert_equals(v.currentSrc, '', 'currentSrc before dialog');
+ window[dialog]('dismiss this dialog');
+ assert_equals(v.networkState, v.NETWORK_NO_SOURCE, 'networkState after dialog');
+ assert_equals(v.currentSrc, '', 'currentSrc after dialog');
+ }, 'stable state in ' + dialog + '()');
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/stable-state-print-manual.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/stable-state-print-manual.html
new file mode 100644
index 000000000..1261a0079
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/loading-the-media-resource/stable-state-print-manual.html
@@ -0,0 +1,22 @@
+<!doctype html>
+<title>stable state in print()</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<button>click this button and dismiss the print dialog</button>
+<script>
+async_test(function(t) {
+ var button = document.querySelector('button');
+ button.onclick = t.step_func(function() {
+ v = document.createElement('video');
+ v.src = 'data:,';
+ assert_equals(v.networkState, v.NETWORK_NO_SOURCE, 'networkState before dialog');
+ assert_equals(v.currentSrc, '', 'currentSrc before dialog');
+ print();
+ assert_equals(v.networkState, v.NETWORK_NO_SOURCE, 'networkState after dialog');
+ assert_equals(v.currentSrc, '', 'currentSrc after dialog');
+ t.done();
+ button.remove();
+ });
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/location-of-the-media-resource/currentSrc.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/location-of-the-media-resource/currentSrc.html
new file mode 100644
index 000000000..2ca0a5180
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/location-of-the-media-resource/currentSrc.html
@@ -0,0 +1,44 @@
+<!doctype html>
+<title>currentSrc</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<script>
+['audio', 'video'].forEach(function(tagName) {
+ test(function() {
+ assert_equals(document.createElement(tagName).currentSrc, '');
+ }, tagName + '.currentSrc initial value');
+
+ ['', '.', ' ', 'data:,'].forEach(function(src) {
+ async_test(function(t) {
+ var e = document.createElement(tagName);
+ e.src = src;
+ assert_equals(e.currentSrc, '');
+ setTimeout(t.step_func(function() {
+ if (src == '') {
+ assert_equals(e.currentSrc, '');
+ } else {
+ assert_equals(e.currentSrc, e.src);
+ }
+ t.done();
+ }), 0);
+ }, tagName + '.currentSrc after setting src attribute "' + src + '"');
+
+ async_test(function(t) {
+ var e = document.createElement(tagName);
+ var s = document.createElement('source');
+ s.src = src;
+ e.appendChild(s);
+ assert_equals(e.currentSrc, '');
+ setTimeout(t.step_func(function() {
+ if (src == '') {
+ assert_equals(e.currentSrc, '');
+ } else {
+ assert_equals(e.currentSrc, s.src);
+ }
+ t.done();
+ }), 0);
+ }, tagName + '.currentSrc after adding source element with src attribute "' + src + '"');
+ });
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/mime-types/canPlayType.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/mime-types/canPlayType.html
new file mode 100644
index 000000000..c5d37e752
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/mime-types/canPlayType.html
@@ -0,0 +1,110 @@
+<!doctype html>
+<title>canPlayType</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<script>
+function t(type, expected) {
+ assert_equals(canPlayType(type), expected, type);
+}
+
+function mime(type, codecs) {
+ if (codecs.length) {
+ return type + '; codecs="' + codecs.join(', ') + '"';
+ }
+ return type;
+}
+
+test(function() {
+ assert_equals(mime('video/webm', []), 'video/webm');
+ assert_equals(mime('video/webm', ['vp8']), 'video/webm; codecs="vp8"');
+ assert_equals(mime('video/webm', ['vp8', 'vorbis']), 'video/webm; codecs="vp8, vorbis"');
+}, 'utility code');
+
+function canPlayType(type) {
+ var canPlay = document.createElement('audio').canPlayType(type);
+ assert_equals(canPlay, document.createElement('video').canPlayType(type),
+ 'audio.canPlayType() and video.canPlayType() agree');
+ assert_in_array(canPlay, ['', 'maybe', 'probably'],
+ 'return value is one of "", "maybe" and "probably"');
+ return canPlay;
+}
+
+test(function() {
+ t('application/octet-stream', '');
+ t('application/octet-stream; codecs="vorbis"', '');
+ t('application/octet-stream; codecs="vp8, vorbis"', '');
+ t('application/octet-stream; codecs="mp4a.40.2"', '');
+ t('application/octet-stream; codecs="theora, vorbis"', '');
+ t('application/octet-stream; codecs="avc1.42E01E, mp4a.40.2"', '');
+}, 'application/octet-stream');
+
+test(function() {
+ t('video/x-new-fictional-format', '');
+ t('video/x-new-fictional-format;codecs="kittens,bunnies"', '');
+}, 'video/x-new-fictional-format');
+
+function type_codecs_test(type, audioCodecs, videoCodecs) {
+ var typeSupported = false;
+ var codecSupported = false;
+
+ test(function() {
+ // Spec: Generally, a user agent should never return "probably" for a type
+ // that allows the codecs parameter if that parameter is not present.
+ t(type, 'maybe');
+ typeSupported = true;
+ }, type + ' (optional)');
+
+ function test_codec(codec) {
+ var typeWithCodec = mime(type, [codec]);
+ test(function() {
+ t(typeWithCodec, 'probably');
+ codecSupported = true;
+ }, typeWithCodec + ' (optional)');
+ }
+
+ audioCodecs.forEach(test_codec);
+ videoCodecs.forEach(test_codec);
+
+ if (audioCodecs.length > 0 && videoCodecs.length > 0) {
+ test(function() {
+ audioCodecs.forEach(function(ac) {
+ videoCodecs.forEach(function(vc) {
+ var canPlayBoth = canPlayType(mime(type, [ac, vc]));
+ if (canPlayBoth) {
+ t(mime(type, [ac]), canPlayBoth);
+ t(mime(type, [vc]), canPlayBoth);
+ }
+ });
+ });
+ }, type + ' codecs subset');
+
+ test(function() {
+ audioCodecs.forEach(function(ac) {
+ videoCodecs.forEach(function(vc) {
+ assert_equals(canPlayType(mime(type, [ac, vc])),
+ canPlayType(mime(type, [vc, ac])));
+ });
+ });
+ }, type + ' codecs order');
+ }
+
+ test(function() {
+ t(mime(type, ['bogus']), '');
+ }, type + ' with bogus codec');
+
+ test(function() {
+ // At least one known codec must be supported if the container format is.
+ assert_equals(typeSupported, codecSupported);
+ }, type + ' with and without codecs');
+}
+
+type_codecs_test('audio/mp4', ['mp4a.40.2'], []);
+type_codecs_test('audio/ogg', ['opus', 'vorbis'], []);
+type_codecs_test('audio/wav', ['1'], []);
+type_codecs_test('audio/webm', ['opus', 'vorbis'], []);
+type_codecs_test('video/3gpp', ['samr'], ['mp4v.20.8']);
+type_codecs_test('video/mp4', ['mp4a.40.2'], ['avc1.42E01E', 'avc1.4D401E', 'avc1.58A01E', 'avc1.64001E', 'mp4v.20.8', 'mp4v.20.240']);
+type_codecs_test('video/ogg', ['opus', 'vorbis'], ['theora']);
+type_codecs_test('video/webm', ['opus', 'vorbis'], ['vp8', 'vp8.0', 'vp9', 'vp9.0']);
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/networkState_during_loadstart.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/networkState_during_loadstart.html
new file mode 100644
index 000000000..8f0fffc61
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/networkState_during_loadstart.html
@@ -0,0 +1,42 @@
+<!doctype html>
+<html>
+ <head>
+ <title>{audio,video}.networkState - NETWORK_LOADING</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/media.js"></script>
+ </head>
+ <body>
+ <p><a href="https://html.spec.whatwg.org/multipage/#dom-media-networkstate">spec reference</a></p>
+ <audio id="a" autoplay controls>
+ </audio>
+ <video id="v" autoplay controls>
+ </video>
+ <div id="log"></div>
+ <script>
+var ta = async_test("audioElement.networkState should be NETWORK_LOADING during loadstart event", {timeout:5000});
+var a = document.getElementById("a");
+a.addEventListener("loadstart", function() {
+ ta.step(function() {
+ assert_equals(a.networkState,
+ a.NETWORK_LOADING);
+ });
+ ta.done();
+ a.pause();
+}, false);
+a.src = getAudioURI("/media/sound_5") + "?" + new Date() + Math.random();
+
+var tv = async_test("videoElement.networkState should be NETWORK_LOADING during loadstart event", {timeout:5000});
+var v = document.getElementById("v");
+v.addEventListener("loadstart", function() {
+ tv.step(function() {
+ assert_equals(a.networkState,
+ v.NETWORK_LOADING);
+ });
+ tv.done();
+ v.pause();
+}, false);
+v.src = getVideoURI("/media/movie_5") + "?" + new Date() + Math.random();
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/networkState_during_progress.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/networkState_during_progress.html
new file mode 100644
index 000000000..cf23e822c
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/networkState_during_progress.html
@@ -0,0 +1,42 @@
+<!doctype html>
+<html>
+ <head>
+ <title>{audio,video}.networkState - NETWORK_LOADING</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/media.js"></script>
+ </head>
+ <body>
+ <p><a href="https://html.spec.whatwg.org/multipage/#dom-media-networkstate">spec reference</a></p>
+ <audio id="a" autoplay controls>
+ </audio>
+ <video id="v" autoplay controls>
+ </video>
+ <div id="log"></div>
+ <script>
+var ta = async_test("audioElement.networkState should be NETWORK_LOADING during progress event", {timeout:5000});
+var a = document.getElementById("a");
+a.addEventListener("progress", function() {
+ ta.step(function() {
+ assert_equals(a.networkState,
+ a.NETWORK_LOADING);
+ });
+ ta.done();
+ a.pause();
+}, false);
+a.src = getAudioURI("/media/sound_5") + "?" + new Date() + Math.random();
+
+var tv = async_test("videoElement.networkState should be NETWORK_LOADING during progress event", {timeout:5000});
+var v = document.getElementById("v");
+v.addEventListener("progress", function() {
+ tv.step(function() {
+ assert_equals(v.networkState,
+ v.NETWORK_LOADING);
+ });
+ tv.done();
+ v.pause();
+}, false);
+v.src = getVideoURI("/media/movie_5") + "?" + new Date() + Math.random();
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/networkState_initial.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/networkState_initial.html
new file mode 100644
index 000000000..0a203e654
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/networkState_initial.html
@@ -0,0 +1,33 @@
+<!doctype html>
+<html>
+ <head>
+ <title>{audio,video}.networkState - default state</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+ <body>
+ <p><a href="https://html.spec.whatwg.org/multipage/#dom-media-networkstate">spec reference</a></p>
+ <audio id="a">
+ </audio>
+ <video id="v">
+ </video>
+ <div id="log"></div>
+ <script>
+test(function() {
+ var a = document.getElementById("a");
+ assert_equals(
+ a.networkState,
+ a.NETWORK_EMPTY,
+ "audioElement.networkState should be NETWORK_EMPTY to begin with");
+}, "audio.networkState - default state");
+
+test(function() {
+ var v = document.getElementById("v");
+ assert_equals(
+ v.networkState,
+ v.NETWORK_EMPTY,
+ "videoElement.networkState should be NETWORK_EMPTY to begin with");
+}, "video.networkState - default state");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/offsets-into-the-media-resource/currentTime.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/offsets-into-the-media-resource/currentTime.html
new file mode 100644
index 000000000..e9b658994
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/offsets-into-the-media-resource/currentTime.html
@@ -0,0 +1,32 @@
+<!doctype html>
+<title>currentTime</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/media.js"></script>
+<div id=log></div>
+<script>
+test(function() {
+ var v = document.createElement('video');
+ assert_equals(v.currentTime, 0);
+}, 'currentTime initial value');
+
+test(function() {
+ var v = document.createElement('video');
+ assert_equals(v.readyState, v.HAVE_NOTHING);
+ v.currentTime = Number.MAX_VALUE;
+ assert_equals(v.currentTime, Number.MAX_VALUE);
+ assert_false(v.seeking);
+}, 'setting currentTime when readyState is HAVE_NOTHING');
+
+async_test(function(t) {
+ var v = document.createElement('video');
+ v.src = getVideoURI('/media/movie_5');
+ v.onloadedmetadata = t.step_func(function() {
+ assert_greater_than(v.readyState, v.HAVE_NOTHING);
+ assert_false(v.seeking);
+ v.currentTime = 1;
+ assert_true(v.seeking);
+ t.done();
+ });
+}, 'setting currentTime when readyState is greater than HAVE_NOTHING');
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/offsets-into-the-media-resource/duration.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/offsets-into-the-media-resource/duration.html
new file mode 100644
index 000000000..0ac26eddb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/offsets-into-the-media-resource/duration.html
@@ -0,0 +1,11 @@
+<!doctype html>
+<title>duration</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+test(function() {
+ var v = document.createElement('video');
+ assert_true(isNaN(v.duration));
+}, 'duration initial value');
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/paused_false_during_play.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/paused_false_during_play.html
new file mode 100644
index 000000000..28c563333
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/paused_false_during_play.html
@@ -0,0 +1,44 @@
+<!doctype html>
+<html>
+ <head>
+ <title>{audio,video} events - paused property</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/media.js"></script>
+ </head>
+ <body>
+ <p><a href="https://html.spec.whatwg.org/multipage/#mediaevents">spec reference</a></p>
+ <audio id="a" autoplay controls>
+ </audio>
+ <video id="v" autoplay controls>
+ </video>
+ <div id="log"></div>
+ <script>
+test(function() {
+ var t = async_test("audio.paused should be false during play event", {timeout:5000});
+ var a = document.getElementById("a");
+ a.addEventListener("play", function() {
+ t.step(function() {
+ assert_false(a.paused);
+ });
+ t.done();
+ a.pause();
+ }, false);
+ a.src = getAudioURI("/media/sound_5") + "?" + new Date() + Math.random();
+}, "audio events - paused property");
+
+test(function() {
+ var t = async_test("video.paused should be false during play event", {timeout:5000});
+ var v = document.getElementById("v");
+ v.addEventListener("play", function() {
+ t.step(function() {
+ assert_false(v.paused);
+ });
+ t.done();
+ v.pause();
+ }, false);
+ v.src = getVideoURI("/media/movie_5") + "?" + new Date() + Math.random();
+}, "video events - paused property");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/paused_true_during_pause.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/paused_true_during_pause.html
new file mode 100644
index 000000000..6c4eb7c0c
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/paused_true_during_pause.html
@@ -0,0 +1,46 @@
+<!doctype html>
+<html>
+ <head>
+ <title>{audio,video} events - paused property</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/media.js"></script>
+ </head>
+ <body>
+ <p><a href="https://html.spec.whatwg.org/multipage/#mediaevents">spec reference</a></p>
+ <audio id="a" controls>
+ </audio>
+ <video id="v" controls>
+ </video>
+ <div id="log"></div>
+ <script>
+test(function() {
+ var t = async_test("audio.paused should be true during pause event", {timeout:5000});
+ var a = document.getElementById("a");
+ a.addEventListener("pause", function() {
+ t.step(function() {
+ assert_true(a.paused);
+ });
+ t.done();
+ }, false);
+ a.src = getAudioURI("/media/sound_5") + "?" + new Date() + Math.random();
+ a.play();
+ a.pause();
+}, "audio events - paused property");
+
+test(function() {
+ var t = async_test("video.paused should be true during pause event", {timeout:5000});
+ var v = document.getElementById("v");
+ v.addEventListener("pause", function() {
+ t.step(function() {
+ assert_true(v.paused);
+ });
+ t.done();
+ }, false);
+ v.src = getVideoURI("/media/movie_5") + "?" + new Date() + Math.random();
+ v.play();
+ v.pause();
+}, "video events - paused property");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/playing-the-media-resource/pause-move-to-other-document.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/playing-the-media-resource/pause-move-to-other-document.html
new file mode 100644
index 000000000..342771dbd
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/playing-the-media-resource/pause-move-to-other-document.html
@@ -0,0 +1,25 @@
+<!doctype html>
+<title>paused state when moving to other document</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/media.js"></script>
+<div id="log"></div>
+<video hidden></video>
+<iframe hidden></iframe>
+<script>
+async_test(function(t) {
+ var v = document.querySelector('video');
+ v.src = getVideoURI('/media/movie_300');
+ v.play();
+ v.onplaying = t.step_func(function() {
+ assert_false(v.paused, 'paused after playing');
+ document.querySelector('iframe').contentDocument.body.appendChild(v);
+ assert_false(v.paused, 'paused after moving');
+ setTimeout(t.step_func(function() {
+ assert_false(v.paused, 'paused after stable state')
+ t.done();
+ }), 0);
+ });
+ v.onpause = t.step_func(function() { assert_unreached(); });
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/playing-the-media-resource/pause-move-within-document.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/playing-the-media-resource/pause-move-within-document.html
new file mode 100644
index 000000000..a28322d4d
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/playing-the-media-resource/pause-move-within-document.html
@@ -0,0 +1,25 @@
+<!doctype html>
+<title>paused state when moving within a document</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/media.js"></script>
+<div id="log"></div>
+<video hidden></video>
+<div id="elsewhere"></div>
+<script>
+async_test(function(t) {
+ var v = document.querySelector('video');
+ v.src = getVideoURI('/media/movie_300');
+ v.play();
+ v.onplaying = t.step_func(function() {
+ assert_false(v.paused, 'paused after playing');
+ document.getElementById('elsewhere').appendChild(v);
+ assert_false(v.paused, 'paused after moving');
+ setTimeout(t.step_func(function() {
+ assert_false(v.paused, 'paused after stable state')
+ t.done();
+ }), 0);
+ });
+ v.onpause = t.step_func(function() { assert_unreached(); });
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/playing-the-media-resource/pause-remove-from-document-networkState.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/playing-the-media-resource/pause-remove-from-document-networkState.html
new file mode 100644
index 000000000..3b5849a35
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/playing-the-media-resource/pause-remove-from-document-networkState.html
@@ -0,0 +1,21 @@
+<!doctype html>
+<title>paused state when removing from a document when networkState is NETWORK_EMPTY</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<video hidden></video>
+<script>
+// Negative test for the specified behavior prior to HTML r8447.
+async_test(function(t) {
+ var v = document.querySelector('video');
+ v.play();
+ setTimeout(t.step_func(function() {
+ assert_equals(v.networkState, v.NETWORK_EMPTY,
+ 'networkState after stable state');
+ assert_false(v.paused, 'paused after stable state');
+ v.parentNode.removeChild(v);
+ assert_false(v.paused, 'paused after removing');
+ v.onpause = t.step_func(function() { t.done(); });
+ }), 0);
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/playing-the-media-resource/pause-remove-from-document.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/playing-the-media-resource/pause-remove-from-document.html
new file mode 100644
index 000000000..7a4b0bc0d
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/playing-the-media-resource/pause-remove-from-document.html
@@ -0,0 +1,37 @@
+<!doctype html>
+<title>paused state when removing from a document</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/media.js"></script>
+<div id="log"></div>
+<video hidden></video>
+<script>
+function afterStableState(func) {
+ var a = new Audio();
+ a.volume = 0;
+ a.addEventListener('volumechange', func);
+}
+
+async_test(function(t) {
+ var v = document.querySelector('video');
+ v.src = getVideoURI('/media/movie_300');
+ v.play();
+ v.onplaying = t.step_func(function() {
+ assert_false(v.paused, 'paused after playing');
+ v.parentNode.removeChild(v);
+ assert_false(v.paused, 'paused after removing');
+ afterStableState(t.step_func(function() {
+ assert_true(v.paused, 'paused after stable state');
+ v.onpause = t.step_func(function() {
+ assert_true(v.paused, 'paused in pause event');
+ // re-insert and verify that it stays paused
+ document.body.appendChild(v);
+ setTimeout(t.step_func(function() {
+ assert_true(v.paused, 'paused after re-inserting');
+ t.done();
+ }), 0);
+ });
+ }));
+ });
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/playing-the-media-resource/play-in-detached-document.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/playing-the-media-resource/play-in-detached-document.html
new file mode 100644
index 000000000..9c6fd5fab
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/playing-the-media-resource/play-in-detached-document.html
@@ -0,0 +1,23 @@
+<!doctype html>
+<title>play() in detached document</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/media.js"></script>
+<div id="log"></div>
+<script>
+// Negative test for failure to play in a detached document.
+async_test(function(t)
+{
+ var doc = document.implementation.createHTMLDocument("");
+ var v = doc.createElement("video");
+ doc.body.appendChild(v);
+ v.src = getVideoURI("/media/movie_5");
+ v.play();
+ v.addEventListener("timeupdate", t.step_func(function() {
+ assert_false(v.paused);
+ if (v.currentTime > 0) {
+ t.done();
+ }
+ }));
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/playing-the-media-resource/playbackRate.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/playing-the-media-resource/playbackRate.html
new file mode 100644
index 000000000..fa11d9944
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/playing-the-media-resource/playbackRate.html
@@ -0,0 +1,19 @@
+<!doctype html>
+<title>playbackRate</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+test(function() {
+ var v = document.createElement('video');
+ assert_equals(v.playbackRate, 1);
+}, 'playbackRate initial value');
+
+async_test(function(t) {
+ var v = document.createElement('video');
+ v.playbackRate = 2;
+ v.addEventListener('ratechange', t.step_func(function() {
+ t.done();
+ }));
+}, 'setting playbackRate');
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/preload_reflects_none_autoplay.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/preload_reflects_none_autoplay.html
new file mode 100644
index 000000000..2670b0dd8
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/preload_reflects_none_autoplay.html
@@ -0,0 +1,31 @@
+<!doctype html>
+<html>
+ <head>
+ <title>{audio,video}.preload - reflection test</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+ <body>
+ <p><a href="https://html.spec.whatwg.org/multipage/#dom-media-preload">spec reference</a></p>
+ <audio id="audio" autoplay preload="none">
+ </audio>
+ <video id="video" autoplay preload="none">
+ </video>
+ <div id="log"></div>
+ <script>
+test(function() {
+ assert_equals(
+ document.getElementById("audio").preload,
+ "none",
+ "audioElement.preload reflects 'none' value even if autoplay attribute is present");
+}, "audio.preload - reflection test");
+
+test(function() {
+ assert_equals(
+ document.getElementById("video").preload,
+ "none",
+ "videoElement.preload reflects 'none' value even if autoplay attribute is present");
+}, "video.preload - reflection test");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/ready-states/autoplay.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/ready-states/autoplay.html
new file mode 100644
index 000000000..76aef1dbc
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/ready-states/autoplay.html
@@ -0,0 +1,73 @@
+<!doctype html>
+<title>autoplay</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/media.js"></script>
+<div id="log"></div>
+<script>
+function autoplay_test(tagName, src) {
+ function expect_events(t, e, expected_events) {
+ var actual_events = [];
+ var callback = t.step_func(function(ev) {
+ actual_events.push(ev.type);
+ assert_array_equals(actual_events,
+ expected_events.slice(0, actual_events.length));
+ if (expected_events.length == actual_events.length) {
+ t.done();
+ }
+ });
+ ['canplay', 'canplaythrough',
+ 'pause', 'play', 'playing'].forEach(function(type) {
+ e.addEventListener(type, callback);
+ });
+ }
+
+ async_test(function(t) {
+ var e = document.createElement(tagName);
+ e.src = src;
+ e.autoplay = true;
+ expect_events(t, e, ['canplay', 'play', 'playing', 'canplaythrough']);
+ }, tagName + '.autoplay');
+
+ async_test(function(t) {
+ var e = document.createElement(tagName);
+ e.src = src;
+ e.autoplay = true;
+ e.pause(); // sets the autoplaying flag to false
+ e.load(); // sets the autoplaying flag to true
+ expect_events(t, e, ['canplay', 'play', 'playing', 'canplaythrough']);
+ }, tagName + '.autoplay and load()');
+
+ async_test(function(t) {
+ var e = document.createElement(tagName);
+ e.src = src;
+ e.autoplay = true;
+ e.play(); // sets the autoplaying flag to false
+ // play() also sets the paused attribute to false; there is no way for the
+ // autoplaying flag to be true when the paused attribute is false.
+ assert_equals(e.paused, false);
+ expect_events(t, e, ['play', 'canplay', 'playing', 'canplaythrough']);
+ }, tagName + '.autoplay and play()');
+
+ async_test(function(t) {
+ var e = document.createElement(tagName);
+ e.src = src;
+ e.autoplay = true;
+ e.pause(); // sets the autoplaying flag to false
+ expect_events(t, e, ['canplay', 'canplaythrough']);
+ }, tagName + '.autoplay and pause()');
+
+ async_test(function(t) {
+ var e = document.createElement(tagName);
+ e.src = src;
+ e.autoplay = true;
+ document.body.appendChild(e);
+ document.body.removeChild(e);
+ // in stable state, internal pause steps sets the autoplaying flag to false
+ expect_events(t, e, ['canplay', 'canplaythrough']);
+ }, tagName + '.autoplay and internal pause steps');
+}
+
+autoplay_test('audio', getAudioURI('/media/sound_5'));
+autoplay_test('video', getVideoURI('/media/movie_5'));
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/readyState_during_canplay.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/readyState_during_canplay.html
new file mode 100644
index 000000000..09ad89f8b
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/readyState_during_canplay.html
@@ -0,0 +1,44 @@
+<!doctype html>
+<html>
+ <head>
+ <title>{audio,video} events - readyState property during canplay</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/media.js"></script>
+ </head>
+ <body>
+ <p><a href="https://html.spec.whatwg.org/multipage/#mediaevents">spec reference</a></p>
+ <audio id="a" autoplay controls>
+ </audio>
+ <video id="v" autoplay controls>
+ </video>
+ <div id="log"></div>
+ <script>
+test(function() {
+ var t = async_test("audio.readyState should be >= HAVE_FUTURE_DATA during canplay event", {timeout:5000});
+ var a = document.getElementById("a");
+ a.addEventListener("canplay", function() {
+ t.step(function() {
+ assert_greater_than_equal(a.readyState, a.HAVE_FUTURE_DATA);
+ });
+ t.done();
+ a.pause();
+ }, false);
+ a.src = getAudioURI("/media/sound_5") + "?" + new Date() + Math.random();
+}, "audio events - readyState property during canplay");
+
+test(function() {
+ var t = async_test("video.readyState should be >= HAVE_FUTURE_DATA during canplay event", {timeout:5000});
+ var v = document.getElementById("v");
+ v.addEventListener("canplay", function() {
+ t.step(function() {
+ assert_greater_than_equal(v.readyState, v.HAVE_FUTURE_DATA);
+ });
+ t.done();
+ v.pause();
+ }, false);
+ v.src = getVideoURI("/media/movie_5") + "?" + new Date() + Math.random();
+}, "video events - readyState property during canplay");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/readyState_during_canplaythrough.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/readyState_during_canplaythrough.html
new file mode 100644
index 000000000..7ef7b5f74
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/readyState_during_canplaythrough.html
@@ -0,0 +1,46 @@
+<!doctype html>
+<html>
+ <head>
+ <title>{audio,video} events - readyState property during canplaythrough</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/media.js"></script>
+ </head>
+ <body>
+ <p><a href="https://html.spec.whatwg.org/multipage/#mediaevents">spec reference</a></p>
+ <audio id="a" autoplay controls>
+ </audio>
+ <video id="v" autoplay controls>
+ </video>
+ <div id="log"></div>
+ <script>
+test(function() {
+ var t = async_test("audio.readyState should be HAVE_ENOUGH_DATA during canplaythrough event", {timeout:5000});
+ var a = document.getElementById("a");
+ a.addEventListener("canplaythrough", function() {
+ t.step(function() {
+ assert_equals(a.readyState,
+ a.HAVE_ENOUGH_DATA);
+ });
+ t.done();
+ a.pause();
+ }, false);
+ a.src = getAudioURI("/media/sound_5") + "?" + new Date() + Math.random();
+}, "audio events - readyState property during canplaythrough");
+
+test(function() {
+ var t = async_test("video.readyState should be HAVE_ENOUGH_DATA during canplaythrough event", {timeout:5000});
+ var v = document.getElementById("v");
+ v.addEventListener("canplaythrough", function() {
+ t.step(function() {
+ assert_equals(v.readyState,
+ v.HAVE_ENOUGH_DATA);
+ });
+ t.done();
+ v.pause();
+ }, false);
+ v.src = getVideoURI("/media/movie_5") + "?" + new Date() + Math.random();
+}, "video events - readyState property during canplaythrough");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/readyState_during_loadeddata.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/readyState_during_loadeddata.html
new file mode 100644
index 000000000..1de85eb86
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/readyState_during_loadeddata.html
@@ -0,0 +1,44 @@
+<!doctype html>
+<html>
+ <head>
+ <title>{audio,video} events - readyState property during loadeddata</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/media.js"></script>
+ </head>
+ <body>
+ <p><a href="https://html.spec.whatwg.org/multipage/#mediaevents">spec reference</a></p>
+ <audio id="a" autoplay controls>
+ </audio>
+ <video id="v" autoplay controls>
+ </video>
+ <div id="log"></div>
+ <script>
+test(function() {
+ var t = async_test("audio.readyState should be >= HAVE_CURRENT_DATA during loadeddata event", {timeout:5000});
+ var a = document.getElementById("a");
+ a.addEventListener("loadeddata", function() {
+ t.step(function() {
+ assert_greater_than_equal(a.readyState, a.HAVE_CURRENT_DATA);
+ });
+ t.done();
+ a.pause();
+ }, false);
+ a.src = getAudioURI("/media/sound_5") + "?" + new Date() + Math.random();
+}, "audio events - readyState property during loadeddata");
+
+test(function() {
+ var t = async_test("video.readyState should be >= HAVE_CURRENT_DATA during loadeddata event", {timeout:5000});
+ var v = document.getElementById("v");
+ v.addEventListener("loadeddata", function() {
+ t.step(function() {
+ assert_greater_than_equal(v.readyState, v.HAVE_CURRENT_DATA);
+ });
+ t.done();
+ v.pause();
+ }, false);
+ v.src = getVideoURI("/media/movie_5") + "?" + new Date() + Math.random();
+}, "video events - readyState property during loadeddata");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/readyState_during_loadedmetadata.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/readyState_during_loadedmetadata.html
new file mode 100644
index 000000000..85db8afb7
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/readyState_during_loadedmetadata.html
@@ -0,0 +1,44 @@
+<!doctype html>
+<html>
+ <head>
+ <title>{audio,video} events - readyState property during loadedmetadata</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/media.js"></script>
+ </head>
+ <body>
+ <p><a href="https://html.spec.whatwg.org/multipage/#mediaevents">spec reference</a></p>
+ <audio id="a" autoplay controls>
+ </audio>
+ <video id="v" autoplay controls>
+ </video>
+ <div id="log"></div>
+ <script>
+test(function() {
+ var t = async_test("audio.readyState should be >= HAVE_METADATA during loadedmetadata event", {timeout:5000});
+ var a = document.getElementById("a");
+ a.addEventListener("loadedmetadata", function() {
+ t.step(function() {
+ assert_greater_than_equal(a.readyState, a.HAVE_METADATA);
+ });
+ t.done();
+ a.pause();
+ }, false);
+ a.src = getAudioURI("/media/sound_5") + "?" + new Date() + Math.random();
+}, "audio events - readyState property during loadedmetadata");
+
+test(function() {
+ var t = async_test("video.readyState should be >= HAVE_METADATA during loadedmetadata event", {timeout:5000});
+ var v = document.getElementById("v");
+ v.addEventListener("loadedmetadata", function() {
+ t.step(function() {
+ assert_greater_than_equal(v.readyState, v.HAVE_METADATA);
+ });
+ t.done();
+ v.pause();
+ }, false);
+ v.src = getVideoURI("/media/movie_5") + "?" + new Date() + Math.random();
+}, "video events - readyState property during loadedmetadata");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/readyState_during_playing.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/readyState_during_playing.html
new file mode 100644
index 000000000..92a1b7f50
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/readyState_during_playing.html
@@ -0,0 +1,44 @@
+<!doctype html>
+<html>
+ <head>
+ <title>{audio,video} events - readyState property during playing</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/media.js"></script>
+ </head>
+ <body>
+ <p><a href="https://html.spec.whatwg.org/multipage/#mediaevents">spec reference</a></p>
+ <audio id="a" autoplay controls>
+ </audio>
+ <video id="v" autoplay controls>
+ </video>
+ <div id="log"></div>
+ <script>
+test(function() {
+ var t = async_test("audio.readyState should be >= HAVE_FUTURE_DATA during playing event", {timeout:5000});
+ var a = document.getElementById("a");
+ a.addEventListener("playing", function() {
+ t.step(function() {
+ assert_greater_than_equal(a.readyState, a.HAVE_FUTURE_DATA);
+ });
+ t.done();
+ a.pause();
+ }, false);
+ a.src = getAudioURI("/media/sound_5") + "?" + new Date() + Math.random();
+}, "audio events - readyState property during playing");
+
+test(function() {
+ var t = async_test("video.readyState should be >= HAVE_FUTURE_DATA during playing event", {timeout:5000});
+ var v = document.getElementById("v");
+ v.addEventListener("playing", function() {
+ t.step(function() {
+ assert_greater_than_equal(v.readyState, v.HAVE_FUTURE_DATA);
+ });
+ t.done();
+ v.pause();
+ }, false);
+ v.src = getVideoURI("/media/movie_5") + "?" + new Date() + Math.random();
+}, "video events - readyState property during playing");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/readyState_initial.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/readyState_initial.html
new file mode 100644
index 000000000..e9c112bd2
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/readyState_initial.html
@@ -0,0 +1,33 @@
+<!doctype html>
+<html>
+ <head>
+ <title>{audio,video}.readyState - default state</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+ <body>
+ <p><a href="https://html.spec.whatwg.org/multipage/#dom-media-networkstate">spec reference</a></p>
+ <audio id="a">
+ </audio>
+ <video id="v">
+ </video>
+ <div id="log"></div>
+ <script>
+test(function() {
+ var a = document.getElementById("a");
+ assert_equals(
+ a.readyState,
+ a.HAVE_NOTHING,
+ "audioElement.readyState should be HAVE_NOTHING to begin with");
+}, "audio.readyState - default state");
+
+test(function() {
+ var v = document.getElementById("v");
+ assert_equals(
+ v.readyState,
+ v.HAVE_NOTHING,
+ "videoElement.readyState should be HAVE_NOTHING to begin with");
+}, "video.readyState - default state");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/seeking/seek-to-currentTime.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/seeking/seek-to-currentTime.html
new file mode 100644
index 000000000..3d577dac9
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/seeking/seek-to-currentTime.html
@@ -0,0 +1,33 @@
+<!doctype html>
+<title>seek to currentTime</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/media.js"></script>
+<div id=log></div>
+<script>
+async_test(function(t) {
+ var v = document.createElement('video');
+ v.src = getVideoURI('/media/movie_5');
+ v.onloadedmetadata = t.step_func(function() {
+ assert_greater_than(v.readyState, v.HAVE_NOTHING, 'readyState');
+ assert_greater_than(v.seekable.length, 0, 'seekable ranges');
+ assert_false(v.seeking, 'seeking before setting currentTime');
+ v.currentTime = v.currentTime;
+ assert_true(v.seeking, 'seeking after setting currentTime');
+ var events = [];
+ v.onseeking = v.ontimeupdate = v.onseeked = t.step_func(function(e) {
+ events.push(e.type);
+ // v.seeking can be true or false in the seeking event, see
+ // https://www.w3.org/Bugs/Public/show_bug.cgi?id=24774
+ if (e.type != 'seeking') {
+ assert_equals(v.seeking, false, 'seeking in ' + e.type + ' event');
+ }
+ if (e.type == 'seeked') {
+ assert_array_equals(events, ['seeking', 'timeupdate', 'seeked'],
+ 'fired events');
+ t.done();
+ }
+ });
+ });
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/seeking/seek-to-max-value.htm b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/seeking/seek-to-max-value.htm
new file mode 100644
index 000000000..a31f6c07a
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/seeking/seek-to-max-value.htm
@@ -0,0 +1,23 @@
+<!doctype html>
+<title>seek to Number.MAX_VALUE</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/media.js"></script>
+<div id=log></div>
+<script>
+async_test(function(t) {
+ var v = document.createElement('video');
+ v.src = getVideoURI('/media/movie_5');
+ v.onloadedmetadata = t.step_func(function() {
+ assert_equals(v.seekable.length, 1);
+ v.currentTime = Number.MAX_VALUE;
+ assert_true(v.seeking, 'seeking after setting');
+ assert_equals(v.currentTime, v.seekable.end(0), 'currentTime after setting');
+ v.onseeked = t.step_func(function(e) {
+ assert_false(v.seeking, 'seeking in seeked event');
+ assert_equals(v.currentTime, v.seekable.end(0), 'currentTime in seeked event');
+ t.done();
+ });
+ });
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/seeking/seek-to-negative-time.htm b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/seeking/seek-to-negative-time.htm
new file mode 100644
index 000000000..56a99028d
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/seeking/seek-to-negative-time.htm
@@ -0,0 +1,23 @@
+<!doctype html>
+<title>seek to negative time</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/media.js"></script>
+<div id=log></div>
+<script>
+async_test(function(t) {
+ var v = document.createElement('video');
+ v.src = getVideoURI('/media/movie_5');
+ v.onloadedmetadata = t.step_func(function() {
+ assert_equals(v.seekable.start(0), 0, 'earliest seekable time');
+ v.currentTime = -1;
+ assert_true(v.seeking, 'seeking after setting');
+ assert_equals(v.currentTime, 0, 'currentTime after setting');
+ v.onseeked = t.step_func(function(e) {
+ assert_false(v.seeking, 'seeking in seeked event');
+ assert_equals(v.currentTime, 0, 'currentTime in seeked event');
+ t.done();
+ });
+ });
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/src_reflects_attribute_not_source_elements.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/src_reflects_attribute_not_source_elements.html
new file mode 100644
index 000000000..3dd43cc3f
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/src_reflects_attribute_not_source_elements.html
@@ -0,0 +1,33 @@
+<!doctype html>
+<html>
+ <head>
+ <title>{audio,video}.src - reflection test</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+ <body>
+ <p><a href="https://html.spec.whatwg.org/multipage/#dom-media-src">spec reference</a></p>
+ <audio id="audio" src="foo">
+ <source src="barbaz" />
+ </audio>
+ <video id="video" src="foo">
+ <source src="barbaz" />
+ </video>
+ <div id="log"></div>
+ <script>
+test(function() {
+ assert_equals(
+ document.getElementById("audio").src.indexOf("barbaz"),
+ -1,
+ "audioElement.src should reflect src attribute, not source child elements");
+}, "audio.src - reflection test");
+
+test(function() {
+ assert_equals(
+ document.getElementById("video").src.indexOf("barbaz"),
+ -1,
+ "videoElement.src should reflect src attribute, not source child elements");
+}, "video.src - reflection test");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cloneNode.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cloneNode.html
new file mode 100644
index 000000000..1159a52ff
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cloneNode.html
@@ -0,0 +1,86 @@
+<!doctype html>
+<title>track element cloneNode</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+test(function() {
+ var elm = document.createElement('track');
+ assert_equals(elm.readyState, elm.NONE, 'elm.readyState after element creation');
+ var clone = elm.cloneNode(true);
+ assert_equals(clone.readyState, clone.NONE, 'clone.readyState after element creation');
+ assert_not_equals(clone.track, elm.track, 'clone.track and elm.track');
+}, document.title+', not loaded');
+
+async_test(function(t) {
+ var elm = document.createElement('track');
+ var video = document.createElement('video');
+ video.appendChild(elm);
+ elm.track.mode = 'showing';
+ assert_equals(elm.readyState, elm.NONE, 'elm.readyState after appening to video setting mode');
+ elm.src = 'resources/track.vtt?pipe=trickle(d1)';
+ assert_equals(elm.readyState, elm.NONE, 'elm.readyState after setting src');
+ setTimeout(t.step_func_done(function() {
+ assert_equals(elm.readyState, elm.LOADING, 'elm.readyState in setTimeout');
+ var clone = elm.cloneNode(true);
+ assert_equals(clone.readyState, clone.NONE, 'clone.readyState after element creation');
+ video.appendChild(clone);
+ clone.track.mode = 'showing';
+ assert_equals(clone.readyState, clone.NONE, 'clone.readyState after appending to video and setting mode');
+ assert_not_equals(clone.track, elm.track, 'clone.track and elm.track');
+ }), 0);
+}, document.title+', loading');
+
+async_test(function(t) {
+ var elm = document.createElement('track');
+ var video = document.createElement('video');
+ video.appendChild(elm);
+ elm.track.mode = 'showing';
+ elm.src = 'data:text/vtt,'+encodeURIComponent('WEBVTT\n\n00:00:00.000 --> 00:00:01.000\nfoo');
+ assert_equals(elm.readyState, elm.NONE, 'elm.readyState after setting src');
+ elm.onload = this.step_func(function() {
+ assert_equals(elm.readyState, elm.LOADED, 'elm.readyState');
+ assert_equals(elm.track.cues.length, 1, 'elm.track.cues.length');
+ assert_equals(elm.track.cues[0].startTime, 0, 'elm.track.cues[0].startTime');
+ assert_equals(elm.track.cues[0].endTime, 1, 'elm.track.cues[0].endTime');
+ assert_equals(elm.track.cues[0].text, 'foo', 'elm.track.cues[0].text');
+ var clone = elm.cloneNode(true);
+ assert_equals(clone.readyState, clone.NONE, 'clone.readyState after element creation');
+ video.appendChild(clone);
+ clone.track.mode = 'showing';
+ assert_equals(clone.readyState, clone.NONE, 'clone.readyState after appending to video and setting mode');
+ assert_not_equals(clone.track, elm.track, 'clone.track and elm.track');
+ clone.onload = this.step_func(function(){
+ assert_equals(clone.readyState, clone.LOADED, 'clone.readyState');
+ assert_not_equals(clone.track, elm.track, 'clone.track and elm.track');
+ assert_not_equals(clone.track.cues, elm.track.cues, 'clone.track.cues and elm.track.cues');
+ assert_equals(clone.track.cues.length, 1, 'clone.track.cues.length');
+ assert_not_equals(clone.track.cues[0], elm.track.cues[0], 'cues[0]');
+ assert_equals(clone.track.cues[0].startTime, 0, 'clone.track.cues[0].startTime');
+ assert_equals(clone.track.cues[0].endTime, 1, 'clone.track.cues[0].endTime');
+ assert_equals(clone.track.cues[0].text, 'foo', 'clone.track.cues[0].text');
+ this.done();
+ });
+ clone.onerror = this.step_func(function() { assert_unreached('clone got error'); });
+ });
+ elm.onerror = this.step_func(function() { assert_unreached('elm got error'); });
+}, document.title+', loaded');
+
+async_test(function(t) {
+ var elm = document.createElement('track');
+ var video = document.createElement('video');
+ video.appendChild(elm);
+ elm.track.mode = 'showing';
+ elm.onerror = t.step_func(function() {
+ assert_equals(elm.readyState, elm.ERROR, 'elm.readyState in onerror');
+ var clone = elm.cloneNode(true);
+ assert_equals(clone.readyState, clone.NONE, 'clone.readyState after element creation');
+ video.appendChild(clone);
+ clone.track.mode = 'showing';
+ assert_equals(clone.readyState, clone.NONE, 'clone.readyState after appending to video and setting mode');
+ assert_not_equals(clone.track, elm.track, 'clone.track and elm.track');
+ clone.onerror = t.step_func_done();
+ });
+ elm.src = 'javascript:"network error"';
+}, document.title+', failed to load');
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/003.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/003.html
new file mode 100644
index 000000000..4236df29b
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/003.html
@@ -0,0 +1,10 @@
+<!doctype html>
+<title>track CORS: No CORS, same-origin, no headers</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script src=/common/utils.js></script>
+<script src=support/common.js?pipe=sub></script>
+<script>
+var expected = {event:'load', requests:[{cors:'no', cookie:'yes'}]};
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/004.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/004.html
new file mode 100644
index 000000000..4f86d011a
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/004.html
@@ -0,0 +1,10 @@
+<!doctype html>
+<title>track CORS: No CORS, same-origin, with headers</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script src=/common/utils.js></script>
+<script src=support/common.js?pipe=sub></script>
+<script>
+var expected = {event:'load', requests:[{cors:'no', cookie:'yes'}]};
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/005.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/005.html
new file mode 100644
index 000000000..e6a693400
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/005.html
@@ -0,0 +1,10 @@
+<!doctype html>
+<title>track CORS: Anonymous, same-origin, no headers</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script src=/common/utils.js></script>
+<script src=support/common.js?pipe=sub></script>
+<script>
+var expected = {event:'load', requests:[{cors:'no', cookie:'yes'}]};
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/006.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/006.html
new file mode 100644
index 000000000..351b97d67
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/006.html
@@ -0,0 +1,10 @@
+<!doctype html>
+<title>track CORS: Anonymous, same-origin, with headers</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script src=/common/utils.js></script>
+<script src=support/common.js?pipe=sub></script>
+<script>
+var expected = {event:'load', requests:[{cors:'no', cookie:'yes'}]};
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/007.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/007.html
new file mode 100644
index 000000000..4ccc6b66a
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/007.html
@@ -0,0 +1,10 @@
+<!doctype html>
+<title>track CORS: Use Credentials, same-origin, no headers</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script src=/common/utils.js></script>
+<script src=support/common.js?pipe=sub></script>
+<script>
+var expected = {event:'load', requests:[{cors:'no', cookie:'yes'}]};
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/008.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/008.html
new file mode 100644
index 000000000..0444a8308
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/008.html
@@ -0,0 +1,10 @@
+<!doctype html>
+<title>track CORS: Use Credentials, same-origin, with headers</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script src=/common/utils.js></script>
+<script src=support/common.js?pipe=sub></script>
+<script>
+var expected = {event:'load', requests:[{cors:'no', cookie:'yes'}]};
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/009.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/009.html
new file mode 100644
index 000000000..dd6223275
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/009.html
@@ -0,0 +1,10 @@
+<!doctype html>
+<title>track CORS: No CORS, not same-origin, no headers</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script src=/common/utils.js></script>
+<script src=support/common.js?pipe=sub></script>
+<script>
+var expected = {event:'error', requests:[]};
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/010.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/010.html
new file mode 100644
index 000000000..d75d6f4d6
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/010.html
@@ -0,0 +1,10 @@
+<!doctype html>
+<title>track CORS: Anonymous, not same-origin, no headers</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script src=/common/utils.js></script>
+<script src=support/common.js?pipe=sub></script>
+<script>
+var expected = {event:'error', requests:[{cors:origin, cookie:'no'}]};
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/011.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/011.html
new file mode 100644
index 000000000..6d0fae6de
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/011.html
@@ -0,0 +1,10 @@
+<!doctype html>
+<title>track CORS: Anonymous, not same-origin, with headers</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script src=/common/utils.js></script>
+<script src=support/common.js?pipe=sub></script>
+<script>
+var expected = {event:'load', requests:[{cors:origin, cookie:'no'}]};
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/012.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/012.html
new file mode 100644
index 000000000..110497b49
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/012.html
@@ -0,0 +1,10 @@
+<!doctype html>
+<title>track CORS: Use Credentials, not same-origin, no headers</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script src=/common/utils.js></script>
+<script src=support/common.js?pipe=sub></script>
+<script>
+var expected = {event:'error', requests:[{cors:origin, cookie:'yes'}]};
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/013.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/013.html
new file mode 100644
index 000000000..d2a9ddb19
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/013.html
@@ -0,0 +1,10 @@
+<!doctype html>
+<title>track CORS: Use Credentials, not same-origin, with headers</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script src=/common/utils.js></script>
+<script src=support/common.js?pipe=sub></script>
+<script>
+var expected = {event:'load', requests:[{cors:origin, cookie:'yes'}]};
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/014.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/014.html
new file mode 100644
index 000000000..a1d6a8b29
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/014.html
@@ -0,0 +1,10 @@
+<!doctype html>
+<title>track CORS: No CORS, same-origin, no headers, redirects to same-origin, no headers</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script src=/common/utils.js></script>
+<script src=support/common.js?pipe=sub></script>
+<script>
+var expected = {event:'load', requests:[{cors:'no', cookie:'yes'}, {cors:'no', cookie:'yes'}]};
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/015.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/015.html
new file mode 100644
index 000000000..2850a24e1
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/015.html
@@ -0,0 +1,10 @@
+<!doctype html>
+<title>track CORS: No CORS, same-origin, with headers, redirects to same-origin, with headers</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script src=/common/utils.js></script>
+<script src=support/common.js?pipe=sub></script>
+<script>
+var expected = {event:'load', requests:[{cors:'no', cookie:'yes'}, {cors:'no', cookie:'yes'}]};
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/016.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/016.html
new file mode 100644
index 000000000..5cd5a85d4
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/016.html
@@ -0,0 +1,10 @@
+<!doctype html>
+<title>track CORS: Anonymous, same-origin, no headers, redirects to same-origin, no headers</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script src=/common/utils.js></script>
+<script src=support/common.js?pipe=sub></script>
+<script>
+var expected = {event:'load', requests:[{cors:'no', cookie:'yes'}, {cors:'no', cookie:'yes'}]};
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/017.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/017.html
new file mode 100644
index 000000000..0ec5bc329
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/017.html
@@ -0,0 +1,10 @@
+<!doctype html>
+<title>track CORS: Anonymous, same-origin, no headers, redirects to same-origin, with headers</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script src=/common/utils.js></script>
+<script src=support/common.js?pipe=sub></script>
+<script>
+var expected = {event:'load', requests:[{cors:'no', cookie:'yes'}, {cors:'no', cookie:'yes'}]};
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/018.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/018.html
new file mode 100644
index 000000000..f639d043a
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/018.html
@@ -0,0 +1,10 @@
+<!doctype html>
+<title>track CORS: Use Credentials, same-origin, no headers, redirects to same-origin, no headers</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script src=/common/utils.js></script>
+<script src=support/common.js?pipe=sub></script>
+<script>
+var expected = {event:'load', requests:[{cors:'no', cookie:'yes'}, {cors:'no', cookie:'yes'}]};
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/019.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/019.html
new file mode 100644
index 000000000..45e1291c9
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/019.html
@@ -0,0 +1,10 @@
+<!doctype html>
+<title>track CORS: Use Credentials, same-origin, with headers, redirects to same-origin, no headers</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script src=/common/utils.js></script>
+<script src=support/common.js?pipe=sub></script>
+<script>
+var expected = {event:'load', requests:[{cors:'no', cookie:'yes'}, {cors:'no', cookie:'yes'}]};
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/020.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/020.html
new file mode 100644
index 000000000..e1153b681
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/020.html
@@ -0,0 +1,10 @@
+<!doctype html>
+<title>track CORS: Anonymous, not same-origin, no headers, redirects to same-origin, no headers</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script src=/common/utils.js></script>
+<script src=support/common.js?pipe=sub></script>
+<script>
+var expected = {event:'error', requests:[{cors:origin, cookie:'no'}]}; // redirect not followed
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/021.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/021.html
new file mode 100644
index 000000000..ec2e9d8bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/021.html
@@ -0,0 +1,10 @@
+<!doctype html>
+<title>track CORS: Anonymous, not same-origin, with headers, redirects to same-origin, no headers</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script src=/common/utils.js></script>
+<script src=support/common.js?pipe=sub></script>
+<script>
+var expected = {event:'error', requests:[{cors:origin, cookie:'no'}, {cors:'null', cookie:'no'}]};
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/022.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/022.html
new file mode 100644
index 000000000..e8fb0c3d4
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/022.html
@@ -0,0 +1,10 @@
+<!doctype html>
+<title>track CORS: Anonymous, not same-origin, with headers, redirects to same-origin, with headers</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script src=/common/utils.js></script>
+<script src=support/common.js?pipe=sub></script>
+<script>
+var expected = {event:'load', requests:[{cors:origin, cookie:'no'}, {cors:'null', cookie:'no'}]};
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/023.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/023.html
new file mode 100644
index 000000000..ac9bb3546
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/023.html
@@ -0,0 +1,10 @@
+<!doctype html>
+<title>track CORS: Use Credentials, not same-origin, no headers, redirects to same-origin, no headers</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script src=/common/utils.js></script>
+<script src=support/common.js?pipe=sub></script>
+<script>
+var expected = {event:'error', requests:[{cors:origin, cookie:'yes'}]}; // redirect not followed
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/024.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/024.html
new file mode 100644
index 000000000..302340022
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/024.html
@@ -0,0 +1,10 @@
+<!doctype html>
+<title>track CORS: Use Credentials, not same-origin, with headers, redirects to same-origin, no headers</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script src=/common/utils.js></script>
+<script src=support/common.js?pipe=sub></script>
+<script>
+var expected = {event:'error', requests:[{cors:origin, cookie:'yes'}, {cors:'null', cookie:'yes'}]};
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/025.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/025.html
new file mode 100644
index 000000000..5cbe8528e
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/025.html
@@ -0,0 +1,10 @@
+<!doctype html>
+<title>track CORS: Use Credentials, not same-origin, with headers, redirects to same-origin, with headers</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script src=/common/utils.js></script>
+<script src=support/common.js?pipe=sub></script>
+<script>
+var expected = {event:'load', requests:[{cors:origin, cookie:'yes'}, {cors:'null', cookie:'yes'}]};
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/026.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/026.html
new file mode 100644
index 000000000..c8386ffff
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/026.html
@@ -0,0 +1,10 @@
+<!doctype html>
+<title>track CORS: No CORS, same-origin, with headers, redirects to not same-origin, with headers</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script src=/common/utils.js></script>
+<script src=support/common.js?pipe=sub></script>
+<script>
+var expected = {event:'error', requests:[{cors:'no', cookie:'yes'}]}; // redirect not followed
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/027.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/027.html
new file mode 100644
index 000000000..5fe4760e6
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/027.html
@@ -0,0 +1,10 @@
+<!doctype html>
+<title>track CORS: Anonymous, same-origin, no headers, redirects to not same-origin, no headers</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script src=/common/utils.js></script>
+<script src=support/common.js?pipe=sub></script>
+<script>
+var expected = {event:'error', requests:[{cors:'no', cookie:'yes'}, {cors:origin, cookie:'no'}]};
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/028.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/028.html
new file mode 100644
index 000000000..6019d37b6
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/028.html
@@ -0,0 +1,10 @@
+<!doctype html>
+<title>track CORS: Anonymous, same-origin, with headers, redirects to not same-origin, with headers</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script src=/common/utils.js></script>
+<script src=support/common.js?pipe=sub></script>
+<script>
+var expected = {event:'load', requests:[{cors:'no', cookie:'yes'}, {cors:origin, cookie:'no'}]};
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/029.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/029.html
new file mode 100644
index 000000000..7fa85456d
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/029.html
@@ -0,0 +1,10 @@
+<!doctype html>
+<title>track CORS: Use Credentials, same-origin, no headers, redirects to not same-origin, no headers</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script src=/common/utils.js></script>
+<script src=support/common.js?pipe=sub></script>
+<script>
+var expected = {event:'error', requests:[{cors:'no', cookie:'yes'}, {cors:origin, cookie:'yes'}]};
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/030.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/030.html
new file mode 100644
index 000000000..f7abf3b1e
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/030.html
@@ -0,0 +1,10 @@
+<!doctype html>
+<title>track CORS: Use Credentials, same-origin, with headers, redirects to not same-origin, with headers</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script src=/common/utils.js></script>
+<script src=support/common.js?pipe=sub></script>
+<script>
+var expected = {event:'load', requests:[{cors:'no', cookie:'yes'}, {cors:origin, cookie:'yes'}]};
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/031.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/031.html
new file mode 100644
index 000000000..d709d0bc4
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/031.html
@@ -0,0 +1,10 @@
+<!doctype html>
+<title>track CORS: Anonymous, not same-origin, no headers, redirects to not same-origin, with headers</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script src=/common/utils.js></script>
+<script src=support/common.js?pipe=sub></script>
+<script>
+var expected = {event:'error', requests:[{cors:origin, cookie:'no'}]}; // redirect not followed
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/032.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/032.html
new file mode 100644
index 000000000..62b1008a4
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/032.html
@@ -0,0 +1,10 @@
+<!doctype html>
+<title>track CORS: Anonymous, not same-origin, with headers, redirects to not same-origin, no headers</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script src=/common/utils.js></script>
+<script src=support/common.js?pipe=sub></script>
+<script>
+var expected = {event:'error', requests:[{cors:origin, cookie:'no'}, {cors:origin, cookie:'no'}]};
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/033.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/033.html
new file mode 100644
index 000000000..215cae241
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/033.html
@@ -0,0 +1,10 @@
+<!doctype html>
+<title>track CORS: Anonymous, not same-origin, with headers, redirects to not same-origin, with headers</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script src=/common/utils.js></script>
+<script src=support/common.js?pipe=sub></script>
+<script>
+var expected = {event:'load', requests:[{cors:origin, cookie:'no'}, {cors:origin, cookie:'no'}]};
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/034.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/034.html
new file mode 100644
index 000000000..bebb43ba8
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/034.html
@@ -0,0 +1,10 @@
+<!doctype html>
+<title>track CORS: Use Credentials, not same-origin, no headers, redirects to not same-origin, with headers</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script src=/common/utils.js></script>
+<script src=support/common.js?pipe=sub></script>
+<script>
+var expected = {event:'error', requests:[{cors:origin, cookie:'yes'}]}; // redirect not followed
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/035.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/035.html
new file mode 100644
index 000000000..a17fb7dfc
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/035.html
@@ -0,0 +1,10 @@
+<!doctype html>
+<title>track CORS: Use Credentials, not same-origin, with headers, redirects to not same-origin, no headers</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script src=/common/utils.js></script>
+<script src=support/common.js?pipe=sub></script>
+<script>
+var expected = {event:'error', requests:[{cors:origin, cookie:'yes'}, {cors:origin, cookie:'yes'}]};
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/036.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/036.html
new file mode 100644
index 000000000..52411177e
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/036.html
@@ -0,0 +1,10 @@
+<!doctype html>
+<title>track CORS: Use Credentials, not same-origin, with headers, redirects to not same-origin, with headers</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script src=/common/utils.js></script>
+<script src=support/common.js?pipe=sub></script>
+<script>
+var expected = {event:'load', requests:[{cors:origin, cookie:'yes'}, {cors:origin, cookie:'yes'}]};
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/037.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/037.html
new file mode 100644
index 000000000..675b913a1
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/037.html
@@ -0,0 +1,10 @@
+<!doctype html>
+<title>track CORS: Anonymous, same-origin, no headers, redirects to not same-origin, no headers, redirects to same-origin, no headers</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script src=/common/utils.js></script>
+<script src=support/common.js?pipe=sub></script>
+<script>
+var expected = {event:'error', requests:[{cors:'no', cookie:'yes'}, {cors:origin, cookie:'no'}]}; // second redirect not followed
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/038.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/038.html
new file mode 100644
index 000000000..a29b2bdea
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/038.html
@@ -0,0 +1,10 @@
+<!doctype html>
+<title>track CORS: Anonymous, same-origin, with headers, redirects to not same-origin, with headers, redirects to same-origin, with headers</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script src=/common/utils.js></script>
+<script src=support/common.js?pipe=sub></script>
+<script>
+var expected = {event:'load', requests:[{cors:'no', cookie:'yes'}, {cors:origin, cookie:'no'}, {cors:'null', cookie:'no'}]};
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/039.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/039.html
new file mode 100644
index 000000000..fcd4871dd
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/039.html
@@ -0,0 +1,10 @@
+<!doctype html>
+<title>track CORS: Anonymous, same-origin, no headers, redirects to not same-origin, with headers, redirects to same-origin, no headers</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script src=/common/utils.js></script>
+<script src=support/common.js?pipe=sub></script>
+<script>
+var expected = {event:'error', requests:[{cors:'no', cookie:'yes'}, {cors:origin, cookie:'no'}, {cors:'null', cookie:'no'}]};
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/040.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/040.html
new file mode 100644
index 000000000..3c819684c
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/040.html
@@ -0,0 +1,10 @@
+<!doctype html>
+<title>track CORS: Use Credentials, same-origin, no headers, redirects to not same-origin, no headers, redirects to same-origin, no headers</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script src=/common/utils.js></script>
+<script src=support/common.js?pipe=sub></script>
+<script>
+var expected = {event:'error', requests:[{cors:'no', cookie:'yes'}, {cors:origin, cookie:'yes'}]}; // second redirect not followed
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/041.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/041.html
new file mode 100644
index 000000000..f0f81953f
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/041.html
@@ -0,0 +1,10 @@
+<!doctype html>
+<title>track CORS: Use Credentials, same-origin, with headers, redirects to not same-origin, with headers, redirects to same-origin, with headers</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script src=/common/utils.js></script>
+<script src=support/common.js?pipe=sub></script>
+<script>
+var expected = {event:'load', requests:[{cors:'no', cookie:'yes'}, {cors:origin, cookie:'yes'}, {cors:'null', cookie:'yes'}]};
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/042.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/042.html
new file mode 100644
index 000000000..c1ffa5f1e
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/042.html
@@ -0,0 +1,10 @@
+<!doctype html>
+<title>track CORS: Use Credentials, same-origin, no headers, redirects to not same-origin, with headers, redirects to same-origin, no headers</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script src=/common/utils.js></script>
+<script src=support/common.js?pipe=sub></script>
+<script>
+var expected = {event:'error', requests:[{cors:'no', cookie:'yes'}, {cors:origin, cookie:'yes'}, {cors:'null', cookie:'yes'}]};
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/043.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/043.html
new file mode 100644
index 000000000..09072a989
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/043.html
@@ -0,0 +1,10 @@
+<!doctype html>
+<title>track CORS: Anonymous, same-origin, no headers, redirects to same-origin, no headers, redirects to not same-origin, no headers</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script src=/common/utils.js></script>
+<script src=support/common.js?pipe=sub></script>
+<script>
+var expected = {event:'error', requests:[{cors:'no', cookie:'yes'}, {cors:'no', cookie:'yes'}, {cors:origin, cookie:'no'}]};
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/044.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/044.html
new file mode 100644
index 000000000..0d4a9fefb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/044.html
@@ -0,0 +1,10 @@
+<!doctype html>
+<title>track CORS: Anonymous, same-origin, no headers, redirects to same-origin, no headers, redirects to not same-origin, with headers</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script src=/common/utils.js></script>
+<script src=support/common.js?pipe=sub></script>
+<script>
+var expected = {event:'load', requests:[{cors:'no', cookie:'yes'}, {cors:'no', cookie:'yes'}, {cors:origin, cookie:'no'}]};
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/045.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/045.html
new file mode 100644
index 000000000..7151364f9
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/045.html
@@ -0,0 +1,10 @@
+<!doctype html>
+<title>track CORS: Use Credentials, same-origin, no headers, redirects to same-origin, no headers, redirects to not same-origin, no headers</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script src=/common/utils.js></script>
+<script src=support/common.js?pipe=sub></script>
+<script>
+var expected = {event:'error', requests:[{cors:'no', cookie:'yes'}, {cors:'no', cookie:'yes'}, {cors:origin, cookie:'yes'}]};
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/046.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/046.html
new file mode 100644
index 000000000..e28646281
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/046.html
@@ -0,0 +1,10 @@
+<!doctype html>
+<title>track CORS: Use Credentials, same-origin, no headers, redirects to same-origin, no headers, redirects to not same-origin, with headers</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script src=/common/utils.js></script>
+<script src=support/common.js?pipe=sub></script>
+<script>
+var expected = {event:'load', requests:[{cors:'no', cookie:'yes'}, {cors:'no', cookie:'yes'}, {cors:origin, cookie:'yes'}]};
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/support/common.js b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/support/common.js
new file mode 100644
index 000000000..9d48abde0
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/support/common.js
@@ -0,0 +1,144 @@
+setup(function(){
+ window.id = token();
+ var p = document.createElement('p');
+ p.innerHTML = 'Test id: <samp>'+id+'</samp>';
+ document.body.appendChild(p);
+ window.actual = {event:null, requests:[]};
+ window.errors = [];
+ window.origin = location.protocol+'//'+location.host;
+ window.escapedOrigin = encodeURIComponent(origin);
+ window.sameOriginURL = "http://{{domains[]}}:{{ports[http][0]}}" + location.pathname.replace(/\/[^\/]+$/, '/');
+ window.otherOriginURL = "http://{{domains[www1]}}:{{ports[http][0]}}" + location.pathname.replace(/\/[^\/]+$/, '/');
+}, {timeout:10000, explicit_done:true});
+
+onload = function() {
+ (async_test(document.title, {timeout:10000})).step(function() {
+ // fail early if track isn't supported
+ assert_true('HTMLTrackElement' in window, 'track not supported');
+ window.corsMode = document.title.match(/^track CORS: (No CORS|Anonymous|Use Credentials)/)[1];
+ var requests_tmp = document.title.substr(('track CORS: '+corsMode+', ').length).split(/, redirects to /g);
+ window.requests = [];
+ requests_tmp.forEach(function(r) {
+ var parts = r.split(', ');
+ requests.push({sameOrigin:parts[0] == 'same-origin', withHeaders:parts[1] == 'with headers'});
+ });
+ if (document.title.indexOf('not same-origin') > -1) {
+ window.hasCrossDomainCookie = true;
+ this.step(setCrossDomainCookie);
+ } else {
+ window.hasCrossDomainCookie = false;
+ this.step(loadTrack);
+ }
+ });
+ done();
+};
+
+function setCrossDomainCookie() {
+ var iframe = document.createElement('iframe');
+ iframe.onload = this.step_func(loadTrack);
+ iframe.src = otherOriginURL + 'support/set-cookie.html#'+id;
+ document.body.appendChild(iframe);
+}
+
+function loadTrack() {
+ var video = document.createElement('video');
+ window.track = document.createElement('track');
+ if (corsMode == 'Anonymous')
+ video.setAttribute('crossorigin', 'anonymous');
+ else if (corsMode == 'Use Credentials')
+ video.setAttribute('crossorigin', 'use-credentials');
+ // else No CORS, omit the crossorigin attribute
+ video.appendChild(track);
+ document.body.appendChild(video);
+ track.track.mode = 'showing';
+ document.cookie = id+'=yes;path=/;max-age=10';
+ var url = '';
+ var r;
+ while (r = requests.pop()) {
+ url = (r.sameOrigin ? sameOriginURL : otherOriginURL) +
+ 'support/cors-tester.py?id=' + id +
+ (r.withHeaders ? '&origin=' + escapedOrigin : '') +
+ (url === '' ? '' : '&redirect=' + encodeURIComponent(url));
+ }
+ track.src = url;
+ track.onerror = track.onload = this.step_func(function(e) {
+ actual.event = e.type;
+ var xhr = new XMLHttpRequest();
+ xhr.open('GET', 'support/cors-tester.py?read=true&id=' + id, true);
+ xhr.onload = this.step_func(function() {
+ if (xhr.status == 200) {
+ var lines = xhr.responseText.split('\n');
+ lines.forEach(function(line) {
+ var chunks = line.split(' | ');
+ var current = {};
+ actual.requests.push(current);
+ chunks.forEach(function(chunk) {
+ var nameval = chunk.split(' = ');
+ var name = nameval[0];
+ var value = nameval[1];
+ current[name] = value;
+ });
+ });
+ } else if (xhr.status == 404) {
+ //No stash was found
+ } else {
+ errors.push('got unexpected xhr status: '+xhr.status);
+ }
+ this.step(removeCookies);
+ });
+ xhr.onerror = this.step_func(function() {
+ errors.push('got xhr error');
+ this.step(removeCookies);
+ });
+ xhr.send();
+ });
+}
+
+function removeCookies() {
+ document.cookie = id+'=;path=/;max-age=0';
+ var nextStep = checkData;
+ if (hasCrossDomainCookie) {
+ var iframe = document.createElement('iframe');
+ iframe.onload = this.step_func(nextStep);
+ iframe.src = otherOriginURL + 'support/cors-tester.py?delete-cookie&id=' + id;
+ document.body.appendChild(iframe);
+ } else {
+ this.step(nextStep);
+ }
+}
+
+function removeLog() {
+ var xhr = new XMLHttpRequest();
+ xhr.open('GET', 'support/cors-tester.py?cleanup&id='+id, true);
+ xhr.onload = this.step_func(function() {
+ assert_equals(xhr.responseText, 'OK', 'failed to clean up log: '+id);
+ this.step(checkData);
+ });
+ xhr.onerror = this.step_func(function() {
+ assert_unreached('failed to clean up log: '+id);
+ });
+ xhr.send();
+}
+
+function checkData() {
+ assert_equals(errors.length, 0, errors);
+ try {
+ if (actual.event == 'load' && expected.event == 'error')
+ assert_unreached('Security problem: got load event but expected error event');
+ assert_object_equals(actual, expected);
+ } catch(ex) {
+ var style = document.createElement('style');
+ style.textContent = '.json-diffs td { vertical-align:top } .json-diffs pre { margin:0 }';
+ document.head.appendChild(style);
+ var table = document.createElement('table');
+ table.border = "";
+ table.className = 'json-diffs';
+ table.innerHTML = '<tr><th>Actual<th>Expected<tr><td><pre></pre><td><pre></pre>';
+ table.getElementsByTagName('pre')[0].textContent = JSON.stringify(actual, null, 2);
+ table.getElementsByTagName('pre')[1].textContent = JSON.stringify(expected, null, 2);
+ document.body.insertBefore(table, document.getElementById('log'));
+ throw ex;
+ }
+ assert_equals(track.track.cues.length, expected.event == 'load' ? 1 : 0, 'track.track.cues.length');
+ this.done();
+}
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/support/cors-tester.py b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/support/cors-tester.py
new file mode 100644
index 000000000..1c27a0d14
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/support/cors-tester.py
@@ -0,0 +1,51 @@
+from wptserve.handlers import HTTPException
+import urllib
+
+def main(request, response):
+ if request.method != "GET":
+ raise HTTPException(400, message="Method was not GET")
+
+ if not "id" in request.GET:
+ raise HTTPException(400, message="No id")
+
+ id = request.GET['id']
+
+ if "read" in request.GET:
+ data = request.server.stash.take(id)
+ if data is None:
+ response.set_error(404, "Tried to read data not yet set")
+ return
+ return [("Content-Type", "text/plain")], data
+
+ elif "cleanup" in request.GET:
+ request.server.stash.take(id)
+ return "OK"
+
+ elif "delete-cookie" in request.GET:
+ response.delete_cookie(id)
+ return [("Content-Type", "text/plain")], "OK"
+
+ if "origin" in request.GET:
+ response.headers.set('Access-Control-Allow-Origin', request.GET['origin'])
+ response.headers.set('Access-Control-Allow-Credentials', 'true')
+
+ cors = request.headers.get("origin", "no")
+
+ cookie = request.cookies.first(id, "no")
+
+ line = 'cors = ' + cors + ' | cookie = ' + cookie.value;
+
+ data = request.server.stash.take(id)
+ if data is not None:
+ line = data + "\n" + line
+
+ request.server.stash.put(id, line)
+
+ if "redirect" in request.GET:
+ response.status = 302
+ response.headers.set('Location', request.GET['redirect'])
+ else:
+ return """WEBVTT
+
+00:00:00.000 --> 00:00:10.000
+Test"""
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/support/remove-cookie.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/support/remove-cookie.html
new file mode 100644
index 000000000..00430e3f0
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/support/remove-cookie.html
@@ -0,0 +1,6 @@
+<!doctype html>
+<title>Remove cookie from location.hash</title>
+<script>
+if (location.hash)
+ document.cookie = decodeURIComponent(location.hash.substr(1))+'=yes;path=/;max-age=0';
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/support/set-cookie.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/support/set-cookie.html
new file mode 100644
index 000000000..cc1c92638
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/cors/support/set-cookie.html
@@ -0,0 +1,6 @@
+<!doctype html>
+<title>Set cookie from location.hash</title>
+<script>
+if (location.hash)
+ document.cookie = decodeURIComponent(location.hash.substr(1))+'=yes;path=/;max-age=15';
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/resources/track.de.vtt b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/resources/track.de.vtt
new file mode 100644
index 000000000..9eaf3d31e
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/resources/track.de.vtt
@@ -0,0 +1,4 @@
+WEBVTT
+
+00:00:00.000 --> 00:00:01.000
+German
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/resources/track.en.vtt b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/resources/track.en.vtt
new file mode 100644
index 000000000..4241f35b5
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/resources/track.en.vtt
@@ -0,0 +1,4 @@
+WEBVTT
+
+00:00:00.000 --> 00:00:01.000
+English
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/resources/track.fr.vtt b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/resources/track.fr.vtt
new file mode 100644
index 000000000..5523224e0
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/resources/track.fr.vtt
@@ -0,0 +1,4 @@
+WEBVTT
+
+00:00:00.000 --> 00:00:01.000
+french
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/resources/track.vtt b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/resources/track.vtt
new file mode 100644
index 000000000..c916c0983
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/resources/track.vtt
@@ -0,0 +1,4 @@
+WEBVTT
+
+00:00:00.000 --> 00:00:01.000
+test
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/src-clear-cues.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/src-clear-cues.html
new file mode 100644
index 000000000..3ba8c9db8
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/src-clear-cues.html
@@ -0,0 +1,52 @@
+<!doctype html>
+<title>track element changing "track URL" and clearing cues</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+(async_test(document.title+', set mode, add cue, set src')).step(function(){
+ var track = document.createElement('track');
+ var c = new VTTCue(0, 1, 'foo');
+ c.id = 'id';
+ track.track.addCue(c);
+ assert_equals(track.track.cues, null, 'cues before setting src or mode');
+ track.track.mode = 'showing';
+ assert_equals(track.track.cues.length, 1, 'cues after setting mode');
+ var cues = track.track.cues;
+ track.src = 'data:,a';
+ assert_equals(track.track.cues.length, 0, 'cues.length after setting src');
+ assert_equals(track.track.cues, cues, 'track.track.cues sameness after setting src');
+ assert_equals(c.id, 'id', 'liveness of removed cue');
+ this.done();
+});
+
+(async_test(document.title+', set mode, set src, add cue, change src')).step(function(){
+ var track = document.createElement('track');
+ track.track.mode = 'showing';
+ track.src = 'data:,a';
+ var c = new VTTCue(0, 1, 'foo');
+ c.id = 'id';
+ track.track.addCue(c);
+ assert_equals(track.track.cues.length, 1, 'cues.length before changing src');
+ var cues = track.track.cues;
+ track.src = 'data:,b';
+ assert_equals(track.track.cues.length, 0, 'cues.length after changing src');
+ assert_equals(track.track.cues, cues, 'track.track.cues sameness after changing src');
+ assert_equals(c.id, 'id', 'liveness of removed cue');
+ this.done();
+});
+
+(async_test(document.title+', set mode, add cue, change mode to disabled, set src')).step(function(){
+ var track = document.createElement('track');
+ track.track.mode = 'showing';
+ var c = new VTTCue(0, 1, 'foo');
+ c.id = 'id';
+ track.track.addCue(c);
+ var cues = track.track.cues;
+ track.track.mode = 'disabled';
+ track.src = 'data:,a';
+ assert_equals(cues.length, 0, 'cues.length after changing src');
+ assert_equals(c.id, 'id', 'liveness of removed cue');
+ this.done();
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/track-api-texttracks.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/track-api-texttracks.html
new file mode 100644
index 000000000..b2840d235
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/track/track-element/track-api-texttracks.html
@@ -0,0 +1,36 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+<title>Track element - text tracks API test</title>
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#text-track-api">
+<link rel="author" title="Hyunjin Cho">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+</head>
+<body>
+<h1>Track element and API Test</h1>
+<div style="display:none;">
+ <video id="tracktest" src="/media/movie_300.mp4">
+ <track kind="subtitles" src="resources/track.en.vtt" srclang="en" label="English">
+ <track kind="captions" src="resources/track.en.vtt" srclang="en" label="English with Captions">
+ <track id="french" kind="subtitles" src="resources/track.fr.vtt" srclang="fr" label="Francais">
+ <track kind="subtitles" src="resources/track.de.vtt" srclang="de" label="Deutsch">
+ </video>
+</div>
+<div id="log"></div>
+<script>
+test(function() {
+ var t1 = document.getElementById('tracktest').textTracks;
+ assert_not_equals(t1, undefined, "textTracks member should not be undefined");
+}, "Check the track elements");
+test(function() {
+ var t2 = document.getElementById('tracktest').textTracks.getTrackById("french");
+ assert_not_equals(t2, undefined, "textTracks member should not be undefined");
+}, "Check getTrackById method");
+test(function() {
+ var t3 = document.getElementById('tracktest').textTracks.length;
+ assert_equals(t3, 4, "textTracks List should be 4");
+}, "Count track list");
+</script>
+</body>
+</html> \ No newline at end of file
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/user-interface/muted.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/user-interface/muted.html
new file mode 100644
index 000000000..906350d88
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/user-interface/muted.html
@@ -0,0 +1,152 @@
+<!doctype html>
+<title>muted</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/media.js"></script>
+<style>video { display: none; }</style>
+<div id=log></div>
+
+<script>
+function test_setting(e, muted, hasAttribute) {
+ assert_equals(e.muted, muted);
+ assert_equals(e.hasAttribute('muted'), hasAttribute);
+
+ e.muted = !e.muted;
+ assert_equals(e.muted, !muted);
+ assert_equals(e.hasAttribute('muted'), hasAttribute);
+
+ e.muted = !e.muted;
+ assert_equals(e.muted, muted);
+ assert_equals(e.hasAttribute('muted'), hasAttribute);
+}
+</script>
+
+<!-- These tests are inside <audio>/<video> so that the steps for updating the
+ muted IDL attribute cannot be delayed until the end tag is parsed. -->
+
+<audio id=a1>
+<script>
+var a1 = document.getElementById('a1');
+
+test(function() {
+ assert_false(a1.muted);
+}, 'getting audio.muted (parser-created)');
+
+test(function() {
+ test_setting(a1, false, false);
+}, 'setting audio.muted (parser-created)');
+</script>
+</audio>
+
+<audio id=a2 muted>
+<script>
+var a2 = document.getElementById('a2');
+
+test(function() {
+ assert_true(a2.muted);
+}, 'getting audio.muted with muted="" (parser-created)');
+
+test(function() {
+ test_setting(a2, true, true);
+}, 'setting audio.muted with muted="" (parser-created)');
+</script>
+</audio>
+
+<video id=v1>
+<script>
+var v1 = document.getElementById('v1');
+
+test(function() {
+ assert_false(v1.muted);
+}, 'getting video.muted (parser-created)');
+
+test(function() {
+ test_setting(v1, false, false);
+}, 'setting video.muted (parser-created)');
+</script>
+</video>
+
+<video id=v2 muted>
+<script>
+var v2 = document.getElementById('v2');
+
+test(function() {
+ assert_true(v2.muted);
+}, 'getting video.muted with muted="" (parser-created)');
+
+test(function() {
+ test_setting(v2, true, true);
+}, 'setting video.muted with muted="" (parser-created)');
+</script>
+</video>
+
+<!-- Negative test to ensure that the load algorithm does not update the
+ muted IDL attribute to match the content attribute. -->
+
+<video id=v3 muted></video>
+<script>
+async_test(function(t) {
+ var v = document.getElementById('v3');
+ assert_true(v.muted);
+ v.muted = false;
+ v.src = 'data:,'; // invokes load()
+ v.addEventListener('error', t.step_func(function() {
+ assert_false(v.muted);
+ t.done();
+ }));
+}, 'getting video.muted with muted="" after load (parser-created)');
+</script>
+
+<script>
+['audio', 'video'].forEach(function(tagName) {
+ test(function() {
+ var m = document.createElement(tagName);
+ assert_false(m.muted);
+ }, 'getting ' + tagName + '.muted (script-created)');
+
+ test(function() {
+ var m = document.createElement(tagName);
+ test_setting(m, false, false);
+ }, 'setting ' + tagName + '.muted (script-created)');
+
+ test(function() {
+ var m = document.createElement(tagName);
+ m.setAttribute('muted', '');
+ assert_false(m.muted);
+ }, 'getting ' + tagName + '.muted with muted="" (script-created)');
+
+ test(function() {
+ var m = document.createElement(tagName);
+ m.setAttribute('muted', '');
+ test_setting(m, false, true);
+ }, 'setting ' + tagName + '.muted with muted="" (script-created)');
+
+ // Spec bug: https://www.w3.org/Bugs/Public/show_bug.cgi?id=25153
+ /*
+ test(function() {
+ var m = document.createElement(tagName);
+ m.setAttribute('muted', '');
+ m = m.cloneNode(false);
+ assert_true(m.hasAttribute('muted'));
+ assert_false(m.muted);
+ }, 'getting ' + tagName + '.muted with muted="" (cloneNode-created)');
+ */
+
+ test(function() {
+ var div = document.createElement('div');
+ div.innerHTML = '<' + tagName + ' muted>';
+ m = div.firstChild;
+ assert_true(m.hasAttribute('muted'));
+ assert_true(m.muted);
+ }, 'getting ' + tagName + '.muted with muted="" (innerHTML-created)');
+
+ test(function() {
+ var id = tagName;
+ assert_equals(document.getElementById(id), null);
+ document.write('<' + tagName + ' id=' + id + ' muted>');
+ m = document.getElementById(id);
+ assert_true(m.hasAttribute('muted'));
+ assert_true(m.muted);
+ }, 'getting ' + tagName + '.muted with muted="" (document.write-created)');
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/video_008.htm b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/video_008.htm
new file mode 100644
index 000000000..dff49d824
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/video_008.htm
@@ -0,0 +1,45 @@
+<!DOCTYPE HTML>
+<html>
+ <head>
+ <title>HTML5 Media Elements: 'media' attribute</title>
+ <meta content="text/html; charset=UTF-8" http-equiv="Content-Type">
+ <link rel="author" title="Microsoft" href="http://www.microsoft.com/" />
+ <link rel="help" href="http://www.w3.org/TR/html5/video.html#the-source-element" />
+ <meta name="assert" content="'media' attribute is 'all' by default." />
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script type="text/javascript" src="/common/media.js"></script>
+ <script type="text/javascript">
+ var videotest = async_test();
+
+ function do_play(event)
+ {
+ videotest.step(function() {
+ var vid = document.getElementById("video0");
+ assert_true(vid.currentSrc.indexOf("movie_300") > 0);
+ });
+ videotest.done();
+ }
+
+ </script>
+ </head>
+ <body>
+ <div id='log'></div>
+
+ <video id="video0" autoplay onplay="do_play(event);">
+ <script type="text/javascript">
+
+ document.write(
+ "<source media='not all' src='" + getVideoURI("/media/movie_300") + "'" +
+ " />"
+ );
+ document.write(
+ "<source src='" + getVideoURI("/media/movie_5") + "'" +
+ " media='all' />"
+ );
+
+ </script>
+ Your browser does not support media elements.
+ </video>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/video_controls_present-manual.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/video_controls_present-manual.html
new file mode 100644
index 000000000..8e44951d7
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/video_controls_present-manual.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>Video Test: video_controls_present.html</title>
+ <link rel="author" title="Intel" href="http://www.intel.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-media-controls" />
+ <meta name="flags" content="" />
+ <meta name="assert" content="Check if the controls attribute is present in the video element that expecting the user agent exposes a controller user interface" />
+ </head>
+ <body>
+ <p>Test passes if a controller user interface appears below and the text 'The user agent doesn't support media element.' does not appear anywhere on this page</p>
+ <video id="m" controls>The user agent doesn't support media element.</video>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/video_loop_base.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/video_loop_base.html
new file mode 100644
index 000000000..348f1cdae
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/video_loop_base.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>Video Test: video_loop_base</title>
+ <link rel="author" title="Intel" href="http://www.intel.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-media-loop" />
+ <meta name="flags" content="" />
+ <meta name="assert" content="Check if video.loop is set to true that expecting the seeking event is fired more than once" />
+ <meta name=timeout content=long>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/common/media.js"></script>
+ </head>
+ <body>
+ <div id="log"></div>
+ <video id="m" controls>The user agent doesn't support media element.</video>
+ <script type="text/javascript">
+ var media = document.getElementById("m");
+ var name = document.getElementsByName("assert")[0].content;
+ var t = async_test(name);
+ var looped = false;
+
+ function startTest() {
+ if (looped) {
+ t.step(function() {
+ assert_true(true, "looped");
+ });
+ t.done();
+ media.pause();
+ }
+
+ looped = true;
+ }
+
+ media.addEventListener("seeking", startTest, false);
+ media.loop = true;
+ media.src = getVideoURI("/media/movie_5") + "?" + new Date() + Math.random();
+ media.play();
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/video_muted_overriding_volume-manual.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/video_muted_overriding_volume-manual.html
new file mode 100644
index 000000000..6d770666c
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/video_muted_overriding_volume-manual.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>Video Test: video_muted_overriding_volume</title>
+ <link rel="author" title="Intel" href="http://www.intel.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-media-muted" />
+ <meta name="flags" content="" />
+ <meta name="assert" content="Check if the muted attribute is present in the video element with volume is set to loudest that expecting the user hears no sound" />
+ <script src="/common/media.js"></script>
+ </head>
+ <body>
+ <p>Test passes if the video is playing without sound output and the text 'The user agent doesn't support media element.' does not appear anywhere on this page</p>
+ <video id="m" controls muted>The user agent doesn't support media element.</video>
+ <script type="text/javascript">
+ var media = document.getElementById("m");
+ media.src = getVideoURI("/media/movie_5") + "?" + new Date() + Math.random();
+ media.volume = 1.0;
+ media.play();
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/video_muted_present-manual.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/video_muted_present-manual.html
new file mode 100644
index 000000000..bc8082777
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/video_muted_present-manual.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>Video Test: video_muted_present</title>
+ <link rel="author" title="Intel" href="http://www.intel.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-media-muted" />
+ <meta name="flags" content="" />
+ <meta name="assert" content="Check if the muted attribute is present in the video element that expecting the user hears no sound" />
+ <script src="/common/media.js"></script>
+ </head>
+ <body>
+ <p>Test passes if the video is playing without sound output and the text 'The user agent doesn't support media element.' does not appear anywhere on this page</p>
+ <video id="m" controls muted>The user agent doesn't support media element.</video>
+ <script type="text/javascript">
+ var media = document.getElementById("m");
+ media.src = getVideoURI("/media/movie_5") + "?" + new Date() + Math.random();
+ media.play();
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/video_volume_check.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/video_volume_check.html
new file mode 100644
index 000000000..1a45358a7
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/video_volume_check.html
@@ -0,0 +1,58 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>Video Test: video_volume_check</title>
+ <link rel="author" title="Intel" href="http://www.intel.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-media-volume" />
+ <meta name="flags" content="" />
+ <meta name="assert" content="Check that video.volume returns the value of the muted content attribute" />
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+ <body>
+ <div id="log"></div>
+ <video id="m">The user agent doesn't support media element.</video>
+ <script type="text/javascript">
+ var media = document.getElementById("m");
+ var VOLUME = {
+ 'SILENT' : 0.0,
+ 'NORMAL' : 0.5,
+ 'LOUDEST' : 1.0,
+ 'LOWER' : -1.1,
+ 'UPPER' : 1.1,
+ };
+
+ test(function() {
+ assert_false(media.volume < VOLUME.SILENT || media.volume > VOLUME.LOUDEST, "media.volume outside the range 0.0 to 1.0 inclusive");
+ }, "Check if the intial value of the video.volume is in the range 0.0 to 1.0 inclusive");
+
+ function volume_setting(vol, name)
+ {
+ if (vol < VOLUME.SILENT || vol > VOLUME.LOUDEST) {
+ try {
+ media.volume = vol;
+ test(function() {
+ assert_true(false, "media.volume setting exception");
+ }, name);
+ } catch(e) {
+ test(function() {
+ // 1 should be e.IndexSizeError or e.INDEX_SIZE_ERR in previous spec
+ assert_equals(e.code, 1, "media.volume setting exception");
+ }, name);
+ }
+ } else {
+ media.volume = vol;
+ test(function() {
+ assert_equals(media.volume, vol, "media.volume new value");
+ }, name);
+ }
+ }
+
+ volume_setting(VOLUME.NORMAL, "Check if video.volume is able to set to new value in the range 0.0 to 1.0");
+ volume_setting(VOLUME.SILENT, "Check if media.volume is able to set to new value 0.0 as silent");
+ volume_setting(VOLUME.LOUDEST, "Check if media.volume is able to set to new value 1.0 as loudest");
+ volume_setting(VOLUME.LOWER, "Check if media.volume is set to new value less than 0.0 that expecting an IndexSizeError exception is to be thrown");
+ volume_setting(VOLUME.UPPER, "Check if video.volume is set to new value greater than 1.0 that expecting an IndexSizeError exception is to be thrown");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/video_volume_loudest-manual.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/video_volume_loudest-manual.html
new file mode 100644
index 000000000..747578120
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/video_volume_loudest-manual.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>Video Test: video_volume_loudest</title>
+ <link rel="author" title="Intel" href="http://www.intel.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-media-volume" />
+ <meta name="flags" content="" />
+ <meta name="assert" content="Check if the volume attribute is set to 1.0 as loudest in the video element that expecting the user hears sound loudly" />
+ <script src="/common/media.js"></script>
+ </head>
+ <body>
+ <p>Test passes if the video is playing with sound heard and the text 'The user agent doesn't support media element.' does not appear anywhere on this page</p>
+ <video id="m" controls>The user agent doesn't support media element.</video>
+ <script type="text/javascript">
+ var media = document.getElementById("m");
+ media.src = getVideoURI("/media/movie_5") + "?" + new Date() + Math.random();
+ media.volume = 1.0;
+ media.play();
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/video_volume_silent-manual.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/video_volume_silent-manual.html
new file mode 100644
index 000000000..1768dd4d4
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/video_volume_silent-manual.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>Video Test: video_volume_silent</title>
+ <link rel="author" title="Intel" href="http://www.intel.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-media-volume" />
+ <meta name="flags" content="" />
+ <meta name="assert" content="Check if the volume attribute is set to 0.0 as silent in the video element that expecting the user hears no sound" />
+ <script src="/common/media.js"></script>
+ </head>
+ <body>
+ <p>Test passes if the video is playing without sound heard and the text 'The user agent doesn't support media element.' does not appear anywhere on this page</p>
+ <video id="m" controls volume=0.0>The user agent doesn't support media element.</video>
+ <script type="text/javascript">
+ var media = document.getElementById("m");
+ media.src = getVideoURI("/media/movie_5") + "?" + new Date() + Math.random();
+ media.volume = 0.0;
+ media.play();
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/media-elements/volume_nonfinite.html b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/volume_nonfinite.html
new file mode 100644
index 000000000..6e90a2ebc
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/media-elements/volume_nonfinite.html
@@ -0,0 +1,18 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>Setting HTMLMediaElement.volume to non-finite numbers</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+["audio", "video"].forEach(function(aElement) {
+ [NaN, Infinity, -Infinity].forEach(function(aValue) {
+ test(function() {
+ var el = document.createElement(aElement);
+ assert_throws(new TypeError(), function() {
+ el.volume = aValue;
+ });
+ }, "Setting " + aElement + ".volume to " + String(aValue) + " should throw a TypeError");
+ });
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/svg/.gitkeep b/testing/web-platform/tests/html/semantics/embedded-content/svg/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/svg/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-area-element/.gitkeep b/testing/web-platform/tests/html/semantics/embedded-content/the-area-element/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-area-element/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-area-element/area-coords.html b/testing/web-platform/tests/html/semantics/embedded-content/the-area-element/area-coords.html
new file mode 100644
index 000000000..9ec6f3e42
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-area-element/area-coords.html
@@ -0,0 +1,47 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>HTMLAreaElement coords parsing</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<style>
+ body { margin: 0 }
+</style>
+<img src=/images/threecolors.png usemap=#x id=img width=300 height=300>
+<map name=x><area id=area></map>
+<script src=support/hit-test.js></script>
+<script>
+tests = [
+ {desc: 'COMMA', shape: 'rect', coords: "2,2,10,10", hit: hitRect},
+ {desc: 'SEMICOLON', shape: 'rect', coords: "2;2;10;10", hit: hitRect},
+ {desc: 'SPACE', shape: 'rect', coords: "2 2 10 10", hit: hitRect},
+ {desc: 'TAB', shape: 'rect', coords: "2\t2\t10\t10", hit: hitRect},
+ {desc: 'FORM FEED', shape: 'rect', coords: "2\f2\f10\f10", hit: hitRect},
+ {desc: 'LINE FEED', shape: 'rect', coords: "2\n2\n10\n10", hit: hitRect},
+ {desc: 'CARRIGAGE RETURN', shape: 'rect', coords: "2\r2\r10\r10", hit: hitRect},
+ {desc: 'LINE TABULATION', shape: 'rect', coords: "2\u000b2\u000b10\u000b10", hit: hitNone},
+ {desc: 'LINE NEXT', shape: 'rect', coords: "2\u00852\u008510\u008510", hit: hitNone},
+ {desc: 'EN QUAD', shape: 'rect', coords: "2\u20002\u200010\u200010", hit: hitNone},
+ {desc: 'abc between numbers', shape: 'rect', coords: "2a2b20c20,2,10,10", hit: hitRect},
+ {desc: 'COLON between numbers', shape: 'rect', coords: "2:2:20:20,2,10,10", hit: hitRect},
+ {desc: 'U+0000 between numbers', shape: 'rect', coords: "2\u00002\u000020\u000020,2,10,10", hit: hitRect},
+ {desc: 'leading COMMA', shape: 'rect', coords: ",2,2,10,10", hit: hitRect},
+ {desc: 'leading SPACE', shape: 'rect', coords: " 2,2,10,10", hit: hitRect},
+ {desc: 'leading SEMICOLON', shape: 'rect', coords: ";2,2,10,10", hit: hitRect},
+ {desc: 'trailing COMMA', shape: 'rect', coords: "2,2,10,", hit: hitNone},
+ {desc: 'trailing SPACE', shape: 'rect', coords: "2,2,10 ", hit: hitNone},
+ {desc: 'trailing SEMICOLON', shape: 'rect', coords: "2,2,10;", hit: hitNone},
+ {desc: 'PERCENT', shape: 'rect', coords: "2%,2%,10%,10%", hit: hitRect},
+ {desc: 'CSS units', shape: 'rect', coords: "2in,2in,10cm,10cm", hit: hitRect},
+ {desc: 'float', shape: 'rect', coords: "1.4,1.4,10,10", hit: hitRect},
+ {desc: 'number starting with PERIOD', shape: 'rect', coords: ".4,.4,10,10", hit: [[area, 1, 1], [img, 0, 0]]},
+ {desc: 'sci-not', shape: 'rect', coords: "2,2,1e1,1e1", hit: hitRect},
+ {desc: 'leading/trailing garbage', shape: 'rect', coords: "='2,2,10,10' ", hit: hitRect},
+ {desc: 'non-ascii garbage', shape: 'rect', coords: "“2,2,10,10\"", hit: hitRect},
+ {desc: 'URL garbage with number', shape: 'rect', coords: "2,2,10ls/spain/holidays/regions/10/Canary+Islands/Canary+Islands.html", hit: hitNone},
+ {desc: 'consecutive COMMAs', shape: 'rect', coords: "2,,10,10", hit: hitNone},
+ {desc: 'consecutive SPACEs', shape: 'rect', coords: "2 10,10", hit: hitNone},
+ {desc: 'consecutive SEMICOLONs', shape: 'rect', coords: "2;;10,10", hit: hitNone},
+ {desc: 'several consecutive separators', shape: 'rect', coords: ",,2;,;2,;,10 \t\r\n10;;", hit: hitRect},
+ {desc: 'one too many numbers, trailing COMMA', shape: 'poly', coords: "100,100,120,100,100,120,300,", hit: hitPoly},
+];
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-area-element/area-processing.html b/testing/web-platform/tests/html/semantics/embedded-content/the-area-element/area-processing.html
new file mode 100644
index 000000000..d1c3a83dd
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-area-element/area-processing.html
@@ -0,0 +1,32 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>HTMLAreaElement processing</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<style>
+ body { margin: 0 }
+</style>
+<img src=/images/threecolors.png usemap=#x id=img width=300 height=300>
+<map name=x><area id=area></map>
+<script src=support/hit-test.js></script>
+<script>
+var tests = [
+ {desc: 'too few numbers', shape: 'rect', coords: "2,2,10", hit: hitNone},
+ {desc: 'negative', shape: 'rect', coords: "-10,-10,10,10", hit: [[area, 1, 1], [img, 299, 299]]},
+ {desc: 'empty string', shape: 'rect', coords: "", hit: hitNone},
+ {desc: 'omitted coords', shape: 'rect', coords: null, hit: hitNone},
+ {desc: 'first > third', shape: 'rect', coords: "10,2,2,10", hit: hitRect},
+ {desc: 'second > fourth', shape: 'rect', coords: "2,10,10,2", hit: hitRect},
+ {desc: 'first > third, second > fourth', shape: 'rect', coords: "10,10,2,2", hit: hitRect},
+
+ {desc: 'negative', shape: 'default', coords: "-10,-10,-10,-10", hit: hitAll},
+
+ {desc: 'too few numbers', shape: 'circle', coords: "20,40", hit: hitNone},
+ {desc: 'negative radius', shape: 'circle', coords: "20,40,-10", hit: hitNone},
+ {desc: 'zero radius', shape: 'circle', coords: "20,40,0", hit: hitNone},
+
+ {desc: 'too few numbers', shape: 'poly', coords: "100,100,120,100,100", hit: hitNone},
+ {desc: 'one too many numbers', shape: 'poly', coords: "100,100,120,100,100,120,300", hit: hitPoly},
+ {desc: 'even-odd rule', shape: 'poly', coords: "100,100,200,100,100,200,150,50,200,200", hit: hitStar},
+];
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-area-element/area-shape.html b/testing/web-platform/tests/html/semantics/embedded-content/the-area-element/area-shape.html
new file mode 100644
index 000000000..1ad0690f9
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-area-element/area-shape.html
@@ -0,0 +1,36 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>HTMLAreaElement shape</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<style>
+ body { margin: 0 }
+</style>
+<img src=/images/threecolors.png usemap=#x id=img width=300 height=300>
+<map name=x><area id=area></map>
+<script src=support/hit-test.js></script>
+<script>
+var tests = [
+ {desc: 'missing value default', shape: null, coords: "2,2,10,10", hit: hitRect},
+ {desc: 'missing value default', shape: null, coords: "20,40,10", hit: hitNone},
+ {desc: 'missing value default', shape: null, coords: null, hit: hitNone},
+ {desc: 'invalid value default', shape: 'foobar invalid', coords: "2,2,10,10", hit: hitRect},
+ {desc: 'invalid value default', shape: '', coords: "2,2,10,10", hit: hitRect},
+
+ {desc: 'empty string', shape: 'default', coords: "", hit: hitAll},
+ {desc: 'omitted coords', shape: 'DEFAULT', coords: null, hit: hitAll},
+
+ {desc: 'simple', shape: 'rect', coords: "2,2,10,10", hit: hitRect},
+ {desc: 'simple', shape: 'rectangle', coords: "2,2,10,10", hit: hitRect},
+
+ {desc: 'simple', shape: 'circle', coords: "20,40,10", hit: hitCircle},
+ {desc: 'simple', shape: 'circ', coords: "20,40,10", hit: hitCircle},
+ {desc: 'simple', shape: 'CIRCLE', coords: "20,40,10", hit: hitCircle},
+ {desc: 'simple', shape: 'CIRC', coords: "20,40,10", hit: hitCircle},
+ {desc: 'LATIN CAPITAL LETTER I WITH DOT ABOVE', shape: 'C\u0130RCLE', coords: "20,40,10", hit: hitNone},
+ {desc: 'LATIN SMALL LETTER DOTLESS I', shape: 'c\u0131rcle', coords: "20,40,10", hit: hitNone},
+
+ {desc: 'simple', shape: 'poly', coords: "100,100,120,100,100,120", hit: hitPoly},
+ {desc: 'simple', shape: 'polygon', coords: "100,100,120,100,100,120", hit: hitPoly},
+];
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-area-element/area-stringifier.html b/testing/web-platform/tests/html/semantics/embedded-content/the-area-element/area-stringifier.html
new file mode 100644
index 000000000..d06429630
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-area-element/area-stringifier.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<title>HTMLAreaElement stringifier</title>
+<link rel="author" title="Ms2ger" href="mailto:ms2ger@gmail.com">
+<link rel="help" href="https://heycam.github.io/webidl/#es-stringifier">
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script src=/common/stringifiers.js></script>
+<div id=log></div>
+<script>
+test(function() {
+ test_stringifier_attribute(document.createElement("area"), "href", false);
+ var area = document.createElement("area");
+ area.setAttribute("href", "foo");
+ test_stringifier_attribute(area, "href", false);
+})
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-area-element/support/hit-test.js b/testing/web-platform/tests/html/semantics/embedded-content/the-area-element/support/hit-test.js
new file mode 100644
index 000000000..54cda3e5c
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-area-element/support/hit-test.js
@@ -0,0 +1,42 @@
+setup({explicit_done: true});
+
+var img = document.getElementById('img');
+var area = document.getElementById('area');
+
+var hitRect = [[area, 3, 3], [area, 9, 9], [img, 1, 3], [img, 3, 1], [img, 11, 9], [img, 9, 11], [img, 21, 41], [img, 101, 101]];
+var hitNone = [[img, 3, 3], [img, 9, 9], [img, 1, 3], [img, 3, 1], [img, 11, 9], [img, 9, 11], [img, 21, 41], [img, 101, 101]];
+var hitAll = [[area, 1, 1], [area, 1, 299], [area, 299, 1], [area, 299, 299], [area, 21, 41], [area, 101, 101]];
+var hitCircle = [[area, 11, 40], [area, 29, 40], [area, 20, 31], [area, 20, 49], [img, 12, 32], [img, 28, 48], [img, 101, 101]];
+var hitPoly = [[area, 101, 101], [area, 119, 101], [area, 101, 119], [img, 118, 118], [img, 3, 3], [img, 21, 41]];
+var hitStar = [[area, 101, 101], [area, 199, 101], [area, 150, 51], [img, 150, 125], [img, 3, 3], [img, 21, 41]];
+
+var tests;
+// The test file should have `tests` defined as follows:
+// tests = [
+// {desc: string, shape: string?, coords: string?, hit: [[element, x, y], ...]},
+// ...
+// ];
+
+onload = function() {
+ tests.forEach(function(t) {
+ test(function(t_obj) {
+ if (area.shape === null) {
+ area.removeAttribute('shape');
+ } else {
+ area.shape = t.shape;
+ }
+ if (area.coords === null) {
+ area.removeAttribute('coords');
+ } else {
+ area.coords = t.coords;
+ }
+ t.hit.forEach(function(arr) {
+ var expected = arr[0];
+ var x = arr[1];
+ var y = arr[2];
+ assert_equals(document.elementFromPoint(x, y), expected, 'elementFromPoint('+x+', '+y+')');
+ });
+ }, t.desc + ': ' + format_value(t.coords) + ' (' + t.shape + ')');
+ });
+ done();
+};
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-audio-element/.gitkeep b/testing/web-platform/tests/html/semantics/embedded-content/the-audio-element/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-audio-element/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-audio-element/audio_001.htm b/testing/web-platform/tests/html/semantics/embedded-content/the-audio-element/audio_001.htm
new file mode 100644
index 000000000..f455c6824
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-audio-element/audio_001.htm
@@ -0,0 +1,18 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>HTML5 Media Elements: Content inside the 'audio' element is not shown to the user (image).</title>
+ <meta content="text/html; charset=UTF-8" http-equiv="Content-Type">
+ <link rel="author" title="Microsoft" href="http://www.microsoft.com/" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#audio" />
+ <link rel="match" href="audio_content-ref.htm" />
+ <meta name="assert" content="Content inside the 'audio' element is not shown to the user (image)." />
+</head>
+<body>
+<p>Test passes if there is no red.</p>
+<div id='testcontent'>
+<audio><img src="../../../../images/fail.gif" /></audio>
+
+</div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-audio-element/audio_002.htm b/testing/web-platform/tests/html/semantics/embedded-content/the-audio-element/audio_002.htm
new file mode 100644
index 000000000..23b3ea188
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-audio-element/audio_002.htm
@@ -0,0 +1,18 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>HTML5 Media Elements: Content inside the 'audio' element is not shown to the user.</title>
+ <meta content="text/html; charset=UTF-8" http-equiv="Content-Type">
+ <link rel="author" title="Microsoft" href="http://www.microsoft.com/" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#audio" />
+ <link rel="match" href="audio_content-ref.htm" />
+ <meta name="assert" content="Content inside the 'audio' element is not shown to the user." />
+</head>
+<body>
+<p>Test passes if there is no red.</p>
+<div id='testcontent'>
+<audio><span style="color: red;">FAIL</span></audio>
+
+</div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-audio-element/audio_constructor.html b/testing/web-platform/tests/html/semantics/embedded-content/the-audio-element/audio_constructor.html
new file mode 100644
index 000000000..242098869
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-audio-element/audio_constructor.html
@@ -0,0 +1,50 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Audio constructor</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+test(function() {
+ var throwingObject = {
+ toString: function() { throw Error() },
+ valueOf: function() { throw Error() }
+ };
+ var tests = [
+ [function() { return new Audio() }, null, "No arguments"],
+ [function() { return new Audio("") }, "", "Empty string argument"],
+ [function() { return new Audio("src") }, "src", "Non-empty string argument"],
+ [function() { return new Audio(null) }, "null", "Null argument"],
+ [function() { return new Audio(undefined) }, null, "Undefined argument"],
+ [function() { return new Audio("", throwingObject) }, "", "Extra argument"],
+ ];
+ tests.forEach(function(t) {
+ var fn = t[0], expectedSrc = t[1], description = t[2];
+ test(function() {
+ var element = fn();
+ assert_equals(element.localName, "audio");
+ assert_equals(element.tagName, "AUDIO");
+ assert_equals(element.namespaceURI, "http://www.w3.org/1999/xhtml");
+ assert_equals(element.nodeType, Node.ELEMENT_NODE);
+ assert_equals(element.getAttribute("preload"), "auto");
+ assert_equals(element.getAttribute("src"), expectedSrc);
+ assert_equals(element.ownerDocument, document);
+ }, description);
+ });
+});
+test(function() {
+ assert_throws(new TypeError(), function() {
+ Audio();
+ });
+}, "Calling Audio should throw");
+test(function() {
+ assert_throws(new TypeError(), function() {
+ HTMLAudioElement();
+ });
+}, "Calling HTMLAudioElement should throw");
+test(function() {
+ assert_throws(new TypeError(), function() {
+ new HTMLAudioElement();
+ });
+}, "Constructing HTMLAudioElement should throw");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-audio-element/audio_content-ref.htm b/testing/web-platform/tests/html/semantics/embedded-content/the-audio-element/audio_content-ref.htm
new file mode 100644
index 000000000..ef5964496
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-audio-element/audio_content-ref.htm
@@ -0,0 +1,13 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>HTML5 Media Elements: Content inside the 'audio' element is not shown to the user.</title>
+ <meta content="text/html; charset=UTF-8" http-equiv="Content-Type">
+ <link rel="author" title="Microsoft" href="http://www.microsoft.com/" />
+</head>
+<body>
+<p>Test passes if there is no red.</p>
+<div id='testcontent'>
+</div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/.gitkeep b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/2d.canvas.readonly.html b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/2d.canvas.readonly.html
new file mode 100644
index 000000000..5e1c22d2d
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/2d.canvas.readonly.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by tools/gentest.py. -->
+<title>Canvas test: 2d.canvas.readonly</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/canvas-tests.js"></script>
+<link rel="stylesheet" href="/common/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.canvas.readonly</h1>
+<p class="desc">CanvasRenderingContext2D.canvas is readonly</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("CanvasRenderingContext2D.canvas is readonly");
+_addTest(function(canvas, ctx) {
+
+var c = document.createElement('canvas');
+var d = ctx.canvas;
+_assertDifferent(c, d, "c", "d");
+ctx.canvas = c;
+_assertSame(ctx.canvas, d, "ctx.canvas", "d");
+
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/2d.canvas.reference.html b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/2d.canvas.reference.html
new file mode 100644
index 000000000..5bdb233f6
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/2d.canvas.reference.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by tools/gentest.py. -->
+<title>Canvas test: 2d.canvas.reference</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/canvas-tests.js"></script>
+<link rel="stylesheet" href="/common/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.canvas.reference</h1>
+<p class="desc">CanvasRenderingContext2D.canvas refers back to its canvas</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("CanvasRenderingContext2D.canvas refers back to its canvas");
+_addTest(function(canvas, ctx) {
+
+_assertSame(ctx.canvas, canvas, "ctx.canvas", "canvas");
+
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/2d.getcontext.exists.html b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/2d.getcontext.exists.html
new file mode 100644
index 000000000..f8b768ad8
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/2d.getcontext.exists.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by tools/gentest.py. -->
+<title>Canvas test: 2d.getcontext.exists</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/canvas-tests.js"></script>
+<link rel="stylesheet" href="/common/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.getcontext.exists</h1>
+<p class="desc">The 2D context is implemented</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("The 2D context is implemented");
+_addTest(function(canvas, ctx) {
+
+_assertDifferent(canvas.getContext('2d'), null, "canvas.getContext('2d')", "null");
+
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/2d.getcontext.extraargs.html b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/2d.getcontext.extraargs.html
new file mode 100644
index 000000000..f58911d04
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/2d.getcontext.extraargs.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by tools/gentest.py. -->
+<title>Canvas test: 2d.getcontext.extraargs</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/canvas-tests.js"></script>
+<link rel="stylesheet" href="/common/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.getcontext.extraargs</h1>
+<p class="desc">The 2D context ignores extra getContext arguments</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("The 2D context ignores extra getContext arguments");
+_addTest(function(canvas, ctx) {
+
+_assertDifferent(canvas.getContext('2d', false, {}, [], 1, "2"), null, "canvas.getContext('2d', false, {}, [], 1, \"2\")", "null");
+
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/2d.getcontext.shared.html b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/2d.getcontext.shared.html
new file mode 100644
index 000000000..a678a135f
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/2d.getcontext.shared.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by tools/gentest.py. -->
+<title>Canvas test: 2d.getcontext.shared</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/canvas-tests.js"></script>
+<link rel="stylesheet" href="/common/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.getcontext.shared</h1>
+<p class="desc">getContext('2d') returns objects which share canvas state</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("getContext('2d') returns objects which share canvas state");
+_addTest(function(canvas, ctx) {
+
+var ctx2 = canvas.getContext('2d');
+ctx.fillStyle = '#f00';
+ctx2.fillStyle = '#0f0';
+ctx.fillRect(0, 0, 100, 50);
+_assertPixel(canvas, 50,25, 0,255,0,255, "50,25", "0,255,0,255");
+
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/2d.getcontext.unique.html b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/2d.getcontext.unique.html
new file mode 100644
index 000000000..d4d4a0d17
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/2d.getcontext.unique.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by tools/gentest.py. -->
+<title>Canvas test: 2d.getcontext.unique</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/canvas-tests.js"></script>
+<link rel="stylesheet" href="/common/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.getcontext.unique</h1>
+<p class="desc">getContext('2d') returns the same object</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("getContext('2d') returns the same object");
+_addTest(function(canvas, ctx) {
+
+_assertSame(canvas.getContext('2d'), canvas.getContext('2d'), "canvas.getContext('2d')", "canvas.getContext('2d')");
+
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/2d.scaled-manual.html b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/2d.scaled-manual.html
new file mode 100644
index 000000000..6ea8ba4b9
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/2d.scaled-manual.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by tools/gentest.py. -->
+<title>Canvas test: 2d.scaled</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/canvas-tests.js"></script>
+<link rel="stylesheet" href="/common/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.scaled</h1>
+<p class="desc">CSS-scaled canvases get drawn correctly</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="50" height="25" style="width: 100px; height: 50px"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="2d.scaled.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("CSS-scaled canvases get drawn correctly");
+_addTest(function(canvas, ctx) {
+
+ctx.fillStyle = '#00f';
+ctx.fillRect(0, 0, 50, 25);
+ctx.fillStyle = '#0ff';
+ctx.fillRect(0, 0, 25, 10);
+
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/2d.scaled.png b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/2d.scaled.png
new file mode 100644
index 000000000..875407769
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/2d.scaled.png
Binary files differ
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/2d.type.exists.html b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/2d.type.exists.html
new file mode 100644
index 000000000..f29f13926
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/2d.type.exists.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by tools/gentest.py. -->
+<title>Canvas test: 2d.type.exists</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/canvas-tests.js"></script>
+<link rel="stylesheet" href="/common/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.type.exists</h1>
+<p class="desc">The 2D context interface is a property of 'window'</p>
+
+<p class="notes">Defined in "Web IDL" (draft)
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("The 2D context interface is a property of 'window'");
+_addTest(function(canvas, ctx) {
+
+_assert(window.CanvasRenderingContext2D, "window.CanvasRenderingContext2D");
+
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/2d.type.extend.html b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/2d.type.extend.html
new file mode 100644
index 000000000..f4dfea879
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/2d.type.extend.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by tools/gentest.py. -->
+<title>Canvas test: 2d.type.extend</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/canvas-tests.js"></script>
+<link rel="stylesheet" href="/common/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.type.extend</h1>
+<p class="desc">Interface methods can be added</p>
+
+<p class="notes">Defined in "Web IDL" (draft)
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Interface methods can be added");
+_addTest(function(canvas, ctx) {
+
+window.CanvasRenderingContext2D.prototype.fillRectGreen = function (x, y, w, h)
+{
+ this.fillStyle = '#0f0';
+ this.fillRect(x, y, w, h);
+};
+ctx.fillStyle = '#f00';
+ctx.fillRectGreen(0, 0, 100, 50);
+_assertPixel(canvas, 50,25, 0,255,0,255, "50,25", "0,255,0,255");
+
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/2d.type.prototype.html b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/2d.type.prototype.html
new file mode 100644
index 000000000..9888d7b6a
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/2d.type.prototype.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by tools/gentest.py. -->
+<title>Canvas test: 2d.type.prototype</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/canvas-tests.js"></script>
+<link rel="stylesheet" href="/common/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.type.prototype</h1>
+<p class="desc">window.CanvasRenderingContext2D.prototype are not [[Writable]] and not [[Configurable]], and its methods are [[Configurable]].</p>
+
+<p class="notes">Defined in "Web IDL" (draft)
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("window.CanvasRenderingContext2D.prototype are not [[Writable]] and not [[Configurable]], and its methods are [[Configurable]].");
+_addTest(function(canvas, ctx) {
+
+_assert(window.CanvasRenderingContext2D.prototype, "window.CanvasRenderingContext2D.prototype");
+_assert(window.CanvasRenderingContext2D.prototype.fill, "window.CanvasRenderingContext2D.prototype.fill");
+window.CanvasRenderingContext2D.prototype = null;
+_assert(window.CanvasRenderingContext2D.prototype, "window.CanvasRenderingContext2D.prototype");
+delete window.CanvasRenderingContext2D.prototype;
+_assert(window.CanvasRenderingContext2D.prototype, "window.CanvasRenderingContext2D.prototype");
+window.CanvasRenderingContext2D.prototype.fill = 1;
+_assertSame(window.CanvasRenderingContext2D.prototype.fill, 1, "window.CanvasRenderingContext2D.prototype.fill", "1");
+delete window.CanvasRenderingContext2D.prototype.fill;
+_assertSame(window.CanvasRenderingContext2D.prototype.fill, undefined, "window.CanvasRenderingContext2D.prototype.fill", "undefined");
+
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/2d.type.replace.html b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/2d.type.replace.html
new file mode 100644
index 000000000..1e3337732
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/2d.type.replace.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by tools/gentest.py. -->
+<title>Canvas test: 2d.type.replace</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/canvas-tests.js"></script>
+<link rel="stylesheet" href="/common/canvas-tests.css">
+<body class="show_output">
+
+<h1>2d.type.replace</h1>
+<p class="desc">Interface methods can be overridden</p>
+
+<p class="notes">Defined in "Web IDL" (draft)
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Interface methods can be overridden");
+_addTest(function(canvas, ctx) {
+
+var fillRect = window.CanvasRenderingContext2D.prototype.fillRect;
+window.CanvasRenderingContext2D.prototype.fillRect = function (x, y, w, h)
+{
+ this.fillStyle = '#0f0';
+ fillRect.call(this, x, y, w, h);
+};
+ctx.fillStyle = '#f00';
+ctx.fillRect(0, 0, 100, 50);
+_assertPixel(canvas, 50,25, 0,255,0,255, "50,25", "0,255,0,255");
+
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/contains.json b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/contains.json
new file mode 100644
index 000000000..3f56f4fd8
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/contains.json
@@ -0,0 +1,10 @@
+[
+ {
+ "id": "color-spaces-and-color-correction",
+ "original_id": "color-spaces-and-color-correction"
+ },
+ {
+ "id": "security-with-canvas-elements",
+ "original_id": "security-with-canvas-elements"
+ }
+] \ No newline at end of file
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/context.arguments.missing.html b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/context.arguments.missing.html
new file mode 100644
index 000000000..37ae4e800
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/context.arguments.missing.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by tools/gentest.py. -->
+<title>Canvas test: context.arguments.missing</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/canvas-tests.js"></script>
+<link rel="stylesheet" href="/common/canvas-tests.css">
+<body class="show_output">
+
+<h1>context.arguments.missing</h1>
+<p class="desc"></p>
+
+<p class="notes">Defined in "Web IDL" (draft)
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("");
+_addTest(function(canvas, ctx) {
+
+assert_throws(new TypeError(), function() { canvas.getContext(); });
+
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/context.casesensitive.html b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/context.casesensitive.html
new file mode 100644
index 000000000..5c64f7a04
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/context.casesensitive.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by tools/gentest.py. -->
+<title>Canvas test: context.casesensitive</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/canvas-tests.js"></script>
+<link rel="stylesheet" href="/common/canvas-tests.css">
+<body class="show_output">
+
+<h1>context.casesensitive</h1>
+<p class="desc">Context name "2D" is unrecognised; matching is case sensitive</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Context name \"2D\" is unrecognised; matching is case sensitive");
+_addTest(function(canvas, ctx) {
+
+_assertSame(canvas.getContext('2D'), null, "canvas.getContext('2D')", "null");
+
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/context.emptystring.html b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/context.emptystring.html
new file mode 100644
index 000000000..8f8b44a23
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/context.emptystring.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by tools/gentest.py. -->
+<title>Canvas test: context.emptystring</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/canvas-tests.js"></script>
+<link rel="stylesheet" href="/common/canvas-tests.css">
+<body class="show_output">
+
+<h1>context.emptystring</h1>
+<p class="desc">getContext with empty string returns null</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("getContext with empty string returns null");
+_addTest(function(canvas, ctx) {
+
+_assertSame(canvas.getContext(""), null, "canvas.getContext(\"\")", "null");
+
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/context.unrecognised.badname.html b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/context.unrecognised.badname.html
new file mode 100644
index 000000000..75f442774
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/context.unrecognised.badname.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by tools/gentest.py. -->
+<title>Canvas test: context.unrecognised.badname</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/canvas-tests.js"></script>
+<link rel="stylesheet" href="/common/canvas-tests.css">
+<body class="show_output">
+
+<h1>context.unrecognised.badname</h1>
+<p class="desc">getContext with unrecognised context name returns null</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("getContext with unrecognised context name returns null");
+_addTest(function(canvas, ctx) {
+
+_assertSame(canvas.getContext('This is not an implemented context in any real browser'), null, "canvas.getContext('This is not an implemented context in any real browser')", "null");
+
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/context.unrecognised.badsuffix.html b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/context.unrecognised.badsuffix.html
new file mode 100644
index 000000000..2f65ae3c8
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/context.unrecognised.badsuffix.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by tools/gentest.py. -->
+<title>Canvas test: context.unrecognised.badsuffix</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/canvas-tests.js"></script>
+<link rel="stylesheet" href="/common/canvas-tests.css">
+<body class="show_output">
+
+<h1>context.unrecognised.badsuffix</h1>
+<p class="desc">Context name "2d" plus a suffix is unrecognised</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Context name \"2d\" plus a suffix is unrecognised");
+_addTest(function(canvas, ctx) {
+
+_assertSame(canvas.getContext("2d#"), null, "canvas.getContext(\"2d#\")", "null");
+
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/context.unrecognised.nullsuffix.html b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/context.unrecognised.nullsuffix.html
new file mode 100644
index 000000000..1607fec86
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/context.unrecognised.nullsuffix.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by tools/gentest.py. -->
+<title>Canvas test: context.unrecognised.nullsuffix</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/canvas-tests.js"></script>
+<link rel="stylesheet" href="/common/canvas-tests.css">
+<body class="show_output">
+
+<h1>context.unrecognised.nullsuffix</h1>
+<p class="desc">Context name "2d" plus a "\0" suffix is unrecognised</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Context name \"2d\" plus a \"\\0\" suffix is unrecognised");
+_addTest(function(canvas, ctx) {
+
+_assertSame(canvas.getContext("2d\0"), null, "canvas.getContext(\"2d\\0\")", "null");
+
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/context.unrecognised.unicode.html b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/context.unrecognised.unicode.html
new file mode 100644
index 000000000..c4eb943c2
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/context.unrecognised.unicode.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by tools/gentest.py. -->
+<title>Canvas test: context.unrecognised.unicode</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/canvas-tests.js"></script>
+<link rel="stylesheet" href="/common/canvas-tests.css">
+<body class="show_output">
+
+<h1>context.unrecognised.unicode</h1>
+<p class="desc">Context name which kind of looks like "2d" is unrecognised</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Context name which kind of looks like \"2d\" is unrecognised");
+_addTest(function(canvas, ctx) {
+
+_assertSame(canvas.getContext("2\uFF44"), null, "canvas.getContext(\"2\\uFF44\")", "null"); // Fullwidth Latin Small Letter D
+
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/fallback.basic.html b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/fallback.basic.html
new file mode 100644
index 000000000..0bae976e8
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/fallback.basic.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by tools/gentest.py. -->
+<title>Canvas test: fallback.basic</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/canvas-tests.js"></script>
+<link rel="stylesheet" href="/common/canvas-tests.css">
+<body class="show_output">
+
+<h1>fallback.basic</h1>
+<p class="desc">Fallback content is inserted into the DOM</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Fallback content is inserted into the DOM");
+_addTest(function(canvas, ctx) {
+
+_assertSame(canvas.childNodes.length, 1, "canvas.childNodes.length", "1");
+
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/fallback.multiple.html b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/fallback.multiple.html
new file mode 100644
index 000000000..5c89be519
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/fallback.multiple.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by tools/gentest.py. -->
+<title>Canvas test: fallback.multiple</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/canvas-tests.js"></script>
+<link rel="stylesheet" href="/common/canvas-tests.css">
+<body class="show_output">
+
+<h1>fallback.multiple</h1>
+<p class="desc">Fallback content with multiple elements</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL</p><p class="fallback">FAIL</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Fallback content with multiple elements");
+_addTest(function(canvas, ctx) {
+
+_assertSame(canvas.childNodes.length, 2, "canvas.childNodes.length", "2");
+
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/fallback.nested.html b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/fallback.nested.html
new file mode 100644
index 000000000..e84739c85
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/fallback.nested.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by tools/gentest.py. -->
+<title>Canvas test: fallback.nested</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/canvas-tests.js"></script>
+<link rel="stylesheet" href="/common/canvas-tests.css">
+<body class="show_output">
+
+<h1>fallback.nested</h1>
+<p class="desc">Fallback content containing another canvas (mostly testing parsers)</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><canvas><p class="fallback">FAIL (fallback content)</p></canvas><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Fallback content containing another canvas (mostly testing parsers)");
+_addTest(function(canvas, ctx) {
+
+_assertSame(canvas.childNodes.length, 2, "canvas.childNodes.length", "2");
+
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/historical.html b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/historical.html
new file mode 100644
index 000000000..58ebc5769
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/historical.html
@@ -0,0 +1,77 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Historical canvas features</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<div id=log></div>
+<script>
+var canvas, context;
+setup(function() {
+ canvas = document.createElement("canvas");
+ context = canvas.getContext('2d');
+ path2d = new Path2D();
+});
+function t(member, obj) {
+ var name = obj === canvas ? "Canvas" : String(obj).match(/\[object (\S+)\]/)[1];
+ test(function() {
+ assert_false(member in obj);
+ }, name + " support for " + member);
+}
+// added in https://github.com/whatwg/html/commit/0ecbf0e010df16d9c6d11eef6b2c58419158c4da
+// renamed in https://github.com/whatwg/html/commit/2542a12cb25ee93534cbed1f31b5e1bc05fcdd0e
+t("supportsContext", canvas);
+
+// removed in https://github.com/whatwg/html/commit/2cfb8e3f03d3166842d2ad0f661459d26e2a40eb
+t("probablySupportsContext", canvas);
+
+// removed in https://github.com/whatwg/html/commit/ef72f55da4acdf266174225c6ca8bf2a650d0219
+t("width", context);
+t("height", context);
+
+// removed in https://github.com/whatwg/html/commit/740634d0f30a3b76e9da166ac2fa8835fcc073ab
+t("setContext", canvas);
+t("transferControlToProxy", canvas);
+t("CanvasProxy", window);
+t("commit", canvas);
+test(function() {
+ assert_throws(new TypeError(), function() {
+ new CanvasRenderingContext2D();
+ }, 'no arguments');
+ assert_throws(new TypeError(), function() {
+ new CanvasRenderingContext2D(1, 1);
+ }, 'with arguments');
+}, "CanvasRenderingContext2D constructors");
+
+// removed in https://github.com/whatwg/html/commit/e1d04f49a38e2254a783c28987457a95a47d9511
+t("addPathByStrokingPath", path2d);
+t("addText", path2d);
+t("addPathByStrokingText", path2d);
+
+// renamed in https://github.com/whatwg/html/commit/fcb0756dd94d96df9b8355741d82fcd5ca0a6154
+test(function() {
+ var canvas = document.createElement('canvas');
+ var context = canvas.getContext('bitmaprenderer');
+ if (context) {
+ assert_false('transferImageBitmap' in context);
+ }
+}, 'ImageBitmapRenderingContext support for transferImageBitmap');
+
+// renamed in https://github.com/whatwg/html/commit/3aec2a7e04a3402201afd29c224b57fa54497517
+t('Path', window);
+
+// removed in https://github.com/whatwg/html/commit/d5759b0435091e4858c9bff90319cbe5b040eda2
+t('toDataURLHD', canvas);
+t('toBlobHD', canvas);
+t('createImageDataHD', context);
+t('getImageDataHD', context);
+t('putImageDataHD', context);
+test(function() {
+ if ('ImageData' in window) {
+ assert_false('resolution' in new ImageData(1, 1));
+ }
+}, 'ImageData support for resolution');
+
+// dropped/renamed in https://github.com/whatwg/html/commit/ff07c6d630fb986f6c4f64b2fb87387b4f89647d
+t('drawSystemFocusRing', context);
+t('drawCustomFocusRing', context);
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/initial.colour.html b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/initial.colour.html
new file mode 100644
index 000000000..f680d504c
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/initial.colour.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by tools/gentest.py. -->
+<title>Canvas test: initial.colour</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/canvas-tests.js"></script>
+<link rel="stylesheet" href="/common/canvas-tests.css">
+<body class="show_output">
+
+<h1>initial.colour</h1>
+<p class="desc">Initial state is transparent black</p>
+
+<p class="notes">Output should be transparent black (not transparent anything-else), but manual
+verification can only confirm that it's transparent - it's not possible to make
+the actual blackness visible.
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="initial.colour.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Initial state is transparent black");
+_addTest(function(canvas, ctx) {
+
+_assertPixel(canvas, 20,20, 0,0,0,0, "20,20", "0,0,0,0");
+
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/initial.colour.png b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/initial.colour.png
new file mode 100644
index 000000000..eeedd0ff0
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/initial.colour.png
Binary files differ
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/initial.reset.2dstate.html b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/initial.reset.2dstate.html
new file mode 100644
index 000000000..b51253a6e
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/initial.reset.2dstate.html
@@ -0,0 +1,103 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by tools/gentest.py. -->
+<title>Canvas test: initial.reset.2dstate</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/canvas-tests.js"></script>
+<link rel="stylesheet" href="/common/canvas-tests.css">
+<body class="show_output">
+
+<h1>initial.reset.2dstate</h1>
+<p class="desc">Resetting the canvas state resets 2D state variables</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Resetting the canvas state resets 2D state variables");
+_addTest(function(canvas, ctx) {
+
+canvas.width = 100;
+var default_val;
+
+default_val = ctx.strokeStyle;
+ctx.strokeStyle = "#ff0000";
+canvas.width = 100;
+_assertSame(ctx.strokeStyle, default_val, "ctx.strokeStyle", "default_val");
+
+default_val = ctx.fillStyle;
+ctx.fillStyle = "#ff0000";
+canvas.width = 100;
+_assertSame(ctx.fillStyle, default_val, "ctx.fillStyle", "default_val");
+
+default_val = ctx.globalAlpha;
+ctx.globalAlpha = 0.5;
+canvas.width = 100;
+_assertSame(ctx.globalAlpha, default_val, "ctx.globalAlpha", "default_val");
+
+default_val = ctx.lineWidth;
+ctx.lineWidth = 0.5;
+canvas.width = 100;
+_assertSame(ctx.lineWidth, default_val, "ctx.lineWidth", "default_val");
+
+default_val = ctx.lineCap;
+ctx.lineCap = "round";
+canvas.width = 100;
+_assertSame(ctx.lineCap, default_val, "ctx.lineCap", "default_val");
+
+default_val = ctx.lineJoin;
+ctx.lineJoin = "round";
+canvas.width = 100;
+_assertSame(ctx.lineJoin, default_val, "ctx.lineJoin", "default_val");
+
+default_val = ctx.miterLimit;
+ctx.miterLimit = 0.5;
+canvas.width = 100;
+_assertSame(ctx.miterLimit, default_val, "ctx.miterLimit", "default_val");
+
+default_val = ctx.shadowOffsetX;
+ctx.shadowOffsetX = 5;
+canvas.width = 100;
+_assertSame(ctx.shadowOffsetX, default_val, "ctx.shadowOffsetX", "default_val");
+
+default_val = ctx.shadowOffsetY;
+ctx.shadowOffsetY = 5;
+canvas.width = 100;
+_assertSame(ctx.shadowOffsetY, default_val, "ctx.shadowOffsetY", "default_val");
+
+default_val = ctx.shadowBlur;
+ctx.shadowBlur = 5;
+canvas.width = 100;
+_assertSame(ctx.shadowBlur, default_val, "ctx.shadowBlur", "default_val");
+
+default_val = ctx.shadowColor;
+ctx.shadowColor = "#ff0000";
+canvas.width = 100;
+_assertSame(ctx.shadowColor, default_val, "ctx.shadowColor", "default_val");
+
+default_val = ctx.globalCompositeOperation;
+ctx.globalCompositeOperation = "copy";
+canvas.width = 100;
+_assertSame(ctx.globalCompositeOperation, default_val, "ctx.globalCompositeOperation", "default_val");
+
+default_val = ctx.font;
+ctx.font = "25px serif";
+canvas.width = 100;
+_assertSame(ctx.font, default_val, "ctx.font", "default_val");
+
+default_val = ctx.textAlign;
+ctx.textAlign = "center";
+canvas.width = 100;
+_assertSame(ctx.textAlign, default_val, "ctx.textAlign", "default_val");
+
+default_val = ctx.textBaseline;
+ctx.textBaseline = "bottom";
+canvas.width = 100;
+_assertSame(ctx.textBaseline, default_val, "ctx.textBaseline", "default_val");
+
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/initial.reset.clip.html b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/initial.reset.clip.html
new file mode 100644
index 000000000..044ccc583
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/initial.reset.clip.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by tools/gentest.py. -->
+<title>Canvas test: initial.reset.clip</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/canvas-tests.js"></script>
+<link rel="stylesheet" href="/common/canvas-tests.css">
+<body class="show_output">
+
+<h1>initial.reset.clip</h1>
+<p class="desc">Resetting the canvas state resets the current clip region</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Resetting the canvas state resets the current clip region");
+_addTest(function(canvas, ctx) {
+
+canvas.width = 100;
+ctx.rect(0, 0, 1, 1);
+ctx.clip();
+canvas.width = 100;
+ctx.fillStyle = '#0f0';
+ctx.fillRect(0, 0, 100, 50);
+_assertPixel(canvas, 20,20, 0,255,0,255, "20,20", "0,255,0,255");
+
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/initial.reset.different.html b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/initial.reset.different.html
new file mode 100644
index 000000000..0d02f40d6
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/initial.reset.different.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by tools/gentest.py. -->
+<title>Canvas test: initial.reset.different</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/canvas-tests.js"></script>
+<link rel="stylesheet" href="/common/canvas-tests.css">
+<body class="show_output">
+
+<h1>initial.reset.different</h1>
+<p class="desc">Changing size resets canvas to transparent black</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="initial.reset.different.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Changing size resets canvas to transparent black");
+_addTest(function(canvas, ctx) {
+
+ctx.fillStyle = '#f00';
+ctx.fillRect(0, 0, 50, 50);
+_assertPixel(canvas, 20,20, 255,0,0,255, "20,20", "255,0,0,255");
+canvas.width = 50;
+_assertPixel(canvas, 20,20, 0,0,0,0, "20,20", "0,0,0,0");
+
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/initial.reset.different.png b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/initial.reset.different.png
new file mode 100644
index 000000000..d83fdd55b
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/initial.reset.different.png
Binary files differ
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/initial.reset.gradient.html b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/initial.reset.gradient.html
new file mode 100644
index 000000000..a1a8516d3
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/initial.reset.gradient.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by tools/gentest.py. -->
+<title>Canvas test: initial.reset.gradient</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/canvas-tests.js"></script>
+<link rel="stylesheet" href="/common/canvas-tests.css">
+<body class="show_output">
+
+<h1>initial.reset.gradient</h1>
+<p class="desc">Resetting the canvas state does not invalidate any existing gradients</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Resetting the canvas state does not invalidate any existing gradients");
+_addTest(function(canvas, ctx) {
+
+canvas.width = 50;
+var g = ctx.createLinearGradient(0, 0, 100, 0);
+g.addColorStop(0, '#0f0');
+g.addColorStop(1, '#0f0');
+canvas.width = 100;
+ctx.fillStyle = '#f00';
+ctx.fillRect(0, 0, 100, 50);
+ctx.fillStyle = g;
+ctx.fillRect(0, 0, 100, 50);
+_assertPixel(canvas, 50,25, 0,255,0,255, "50,25", "0,255,0,255");
+
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/initial.reset.path.html b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/initial.reset.path.html
new file mode 100644
index 000000000..ab59ce9a1
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/initial.reset.path.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by tools/gentest.py. -->
+<title>Canvas test: initial.reset.path</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/canvas-tests.js"></script>
+<link rel="stylesheet" href="/common/canvas-tests.css">
+<body class="show_output">
+
+<h1>initial.reset.path</h1>
+<p class="desc">Resetting the canvas state resets the current path</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="initial.reset.path.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Resetting the canvas state resets the current path");
+_addTest(function(canvas, ctx) {
+
+canvas.width = 100;
+ctx.rect(0, 0, 100, 50);
+canvas.width = 100;
+ctx.fillStyle = '#f00';
+ctx.fill();
+_assertPixel(canvas, 20,20, 0,0,0,0, "20,20", "0,0,0,0");
+
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/initial.reset.path.png b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/initial.reset.path.png
new file mode 100644
index 000000000..eeedd0ff0
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/initial.reset.path.png
Binary files differ
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/initial.reset.pattern.html b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/initial.reset.pattern.html
new file mode 100644
index 000000000..f569d21f2
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/initial.reset.pattern.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by tools/gentest.py. -->
+<title>Canvas test: initial.reset.pattern</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/canvas-tests.js"></script>
+<link rel="stylesheet" href="/common/canvas-tests.css">
+<body class="show_output">
+
+<h1>initial.reset.pattern</h1>
+<p class="desc">Resetting the canvas state does not invalidate any existing patterns</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Resetting the canvas state does not invalidate any existing patterns");
+_addTest(function(canvas, ctx) {
+
+canvas.width = 30;
+ctx.fillStyle = '#0f0';
+ctx.fillRect(0, 0, 30, 50);
+var p = ctx.createPattern(canvas, 'repeat-x');
+canvas.width = 100;
+ctx.fillStyle = '#f00';
+ctx.fillRect(0, 0, 100, 50);
+ctx.fillStyle = p;
+ctx.fillRect(0, 0, 100, 50);
+_assertPixel(canvas, 50,25, 0,255,0,255, "50,25", "0,255,0,255");
+
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/initial.reset.same.html b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/initial.reset.same.html
new file mode 100644
index 000000000..b0bf73f8f
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/initial.reset.same.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by tools/gentest.py. -->
+<title>Canvas test: initial.reset.same</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/canvas-tests.js"></script>
+<link rel="stylesheet" href="/common/canvas-tests.css">
+<body class="show_output">
+
+<h1>initial.reset.same</h1>
+<p class="desc">Setting size (not changing the value) resets canvas to transparent black</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="initial.reset.same.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Setting size (not changing the value) resets canvas to transparent black");
+_addTest(function(canvas, ctx) {
+
+canvas.width = 100;
+ctx.fillStyle = '#f00';
+ctx.fillRect(0, 0, 50, 50);
+_assertPixel(canvas, 20,20, 255,0,0,255, "20,20", "255,0,0,255");
+canvas.width = 100;
+_assertPixel(canvas, 20,20, 0,0,0,0, "20,20", "0,0,0,0");
+
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/initial.reset.same.png b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/initial.reset.same.png
new file mode 100644
index 000000000..eeedd0ff0
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/initial.reset.same.png
Binary files differ
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/initial.reset.transform.html b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/initial.reset.transform.html
new file mode 100644
index 000000000..c5a92ca0f
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/initial.reset.transform.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by tools/gentest.py. -->
+<title>Canvas test: initial.reset.transform</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/canvas-tests.js"></script>
+<link rel="stylesheet" href="/common/canvas-tests.css">
+<body class="show_output">
+
+<h1>initial.reset.transform</h1>
+<p class="desc">Resetting the canvas state resets the current transformation matrix</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Resetting the canvas state resets the current transformation matrix");
+_addTest(function(canvas, ctx) {
+
+canvas.width = 100;
+ctx.scale(0.1, 0.1);
+canvas.width = 100;
+ctx.fillStyle = '#0f0';
+ctx.fillRect(0, 0, 100, 50);
+_assertPixel(canvas, 20,20, 0,255,0,255, "20,20", "0,255,0,255");
+
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/security.dataURI.html b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/security.dataURI.html
new file mode 100644
index 000000000..d13057915
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/security.dataURI.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by tools/gentest.py. -->
+<title>Canvas test: security.dataURI</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/canvas-tests.js"></script>
+<link rel="stylesheet" href="/common/canvas-tests.css">
+<body class="show_output">
+
+<h1>security.dataURI</h1>
+<p class="desc">data: URIs do not count as different-origin, and do not taint the canvas</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="/images/green-100x50.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("data: URIs do not count as different-origin, and do not taint the canvas");
+_addTest(function(canvas, ctx) {
+
+ctx.fillStyle = '#0f0';
+ctx.fillRect(0, 0, 100, 50);
+var data = canvas.toDataURL();
+ctx.fillStyle = '#f00';
+ctx.fillRect(0, 0, 100, 50);
+var img = new Image();
+deferTest();
+img.onload = t.step_func_done(function ()
+{
+ ctx.drawImage(img, 0, 0);
+ canvas.toDataURL(); // should be permitted
+ _assertPixel(canvas, 50,25, 0,255,0,255, "50,25", "0,255,0,255");
+});
+img.src = data;
+
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/security.drawImage.canvas.html b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/security.drawImage.canvas.html
new file mode 100644
index 000000000..918bf8f8f
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/security.drawImage.canvas.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by tools/gentest.py. -->
+<title>Canvas test: security.drawImage.canvas</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/canvas-tests.js"></script>
+<link rel="stylesheet" href="/common/canvas-tests.css">
+<body class="show_output">
+
+<h1>security.drawImage.canvas</h1>
+<p class="desc">drawImage of unclean canvas makes the canvas origin-unclean</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("drawImage of unclean canvas makes the canvas origin-unclean");
+_addTest(function(canvas, ctx) {
+
+var canvas2 = document.createElement('canvas');
+canvas2.width = 100;
+canvas2.height = 50;
+var ctx2 = canvas2.getContext('2d');
+ctx2.drawImage(document.getElementById('yellow.png'), 0, 0);
+ctx.drawImage(canvas2, 0, 0);
+assert_throws("SECURITY_ERR", function() { canvas.toDataURL(); });
+assert_throws("SECURITY_ERR", function() { ctx.getImageData(0, 0, 1, 1); });
+
+
+});
+</script>
+<script src="/common/get-host-info.sub.js"></script>
+<script src="data:text/javascript,addCrossOriginYellowImage()"></script>
+
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/security.drawImage.image.html b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/security.drawImage.image.html
new file mode 100644
index 000000000..48f808aa6
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/security.drawImage.image.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by tools/gentest.py. -->
+<title>Canvas test: security.drawImage.image</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/canvas-tests.js"></script>
+<link rel="stylesheet" href="/common/canvas-tests.css">
+<body class="show_output">
+
+<h1>security.drawImage.image</h1>
+<p class="desc">drawImage of different-origin image makes the canvas origin-unclean</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("drawImage of different-origin image makes the canvas origin-unclean");
+_addTest(function(canvas, ctx) {
+
+ctx.drawImage(document.getElementById('yellow.png'), 0, 0);
+assert_throws("SECURITY_ERR", function() { canvas.toDataURL(); });
+assert_throws("SECURITY_ERR", function() { ctx.getImageData(0, 0, 1, 1); });
+
+
+});
+</script>
+<script src="/common/get-host-info.sub.js"></script>
+<script src="data:text/javascript,addCrossOriginYellowImage()"></script>
+
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/security.pattern.canvas.fillStyle.html b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/security.pattern.canvas.fillStyle.html
new file mode 100644
index 000000000..2997ef9bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/security.pattern.canvas.fillStyle.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by tools/gentest.py. -->
+<title>Canvas test: security.pattern.canvas.fillStyle</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/canvas-tests.js"></script>
+<link rel="stylesheet" href="/common/canvas-tests.css">
+<body class="show_output">
+
+<h1>security.pattern.canvas.fillStyle</h1>
+<p class="desc">Setting fillStyle to a pattern of an unclean canvas makes the canvas origin-unclean</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Setting fillStyle to a pattern of an unclean canvas makes the canvas origin-unclean");
+_addTest(function(canvas, ctx) {
+
+var canvas2 = document.createElement('canvas');
+canvas2.width = 100;
+canvas2.height = 50;
+var ctx2 = canvas2.getContext('2d');
+ctx2.drawImage(document.getElementById('yellow.png'), 0, 0);
+var p = ctx.createPattern(canvas2, 'repeat');
+ctx.fillStyle = p;
+ctx.fillStyle = 'red';
+assert_throws("SECURITY_ERR", function() { canvas.toDataURL(); });
+assert_throws("SECURITY_ERR", function() { ctx.getImageData(0, 0, 1, 1); });
+
+
+});
+</script>
+<script src="/common/get-host-info.sub.js"></script>
+<script src="data:text/javascript,addCrossOriginYellowImage()"></script>
+
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/security.pattern.canvas.strokeStyle.html b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/security.pattern.canvas.strokeStyle.html
new file mode 100644
index 000000000..8980d2d53
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/security.pattern.canvas.strokeStyle.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by tools/gentest.py. -->
+<title>Canvas test: security.pattern.canvas.strokeStyle</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/canvas-tests.js"></script>
+<link rel="stylesheet" href="/common/canvas-tests.css">
+<body class="show_output">
+
+<h1>security.pattern.canvas.strokeStyle</h1>
+<p class="desc">Setting strokeStyle to a pattern of an unclean canvas makes the canvas origin-unclean</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Setting strokeStyle to a pattern of an unclean canvas makes the canvas origin-unclean");
+_addTest(function(canvas, ctx) {
+
+var canvas2 = document.createElement('canvas');
+canvas2.width = 100;
+canvas2.height = 50;
+var ctx2 = canvas2.getContext('2d');
+ctx2.drawImage(document.getElementById('yellow.png'), 0, 0);
+var p = ctx.createPattern(canvas2, 'repeat');
+ctx.strokeStyle = p;
+ctx.strokeStyle = 'red';
+assert_throws("SECURITY_ERR", function() { canvas.toDataURL(); });
+assert_throws("SECURITY_ERR", function() { ctx.getImageData(0, 0, 1, 1); });
+
+
+});
+</script>
+<script src="/common/get-host-info.sub.js"></script>
+<script src="data:text/javascript,addCrossOriginYellowImage()"></script>
+
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/security.pattern.canvas.timing.html b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/security.pattern.canvas.timing.html
new file mode 100644
index 000000000..bb5fd58e6
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/security.pattern.canvas.timing.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by tools/gentest.py. -->
+<title>Canvas test: security.pattern.canvas.timing</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/canvas-tests.js"></script>
+<link rel="stylesheet" href="/common/canvas-tests.css">
+<body class="show_output">
+
+<h1>security.pattern.canvas.timing</h1>
+<p class="desc">Pattern safety depends on whether the source was origin-clean, not on whether it still is clean</p>
+
+<p class="notes">Disagrees with spec on "is" vs "was"
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Pattern safety depends on whether the source was origin-clean, not on whether it still is clean");
+_addTest(function(canvas, ctx) {
+
+var canvas2 = document.createElement('canvas');
+canvas2.width = 100;
+canvas2.height = 50;
+var ctx2 = canvas2.getContext('2d');
+ctx2.fillStyle = '#0f0';
+ctx2.fillRect(0, 0, 100, 50);
+var p = ctx.createPattern(canvas2, 'repeat');
+ctx2.drawImage(document.getElementById('yellow.png'), 0, 0); // make canvas2 origin-unclean
+ctx.fillStyle = p;
+ctx.fillRect(0, 0, 100, 50);
+canvas.toDataURL();
+ctx.getImageData(0, 0, 1, 1);
+_assert(true, "true"); // okay if there was no exception
+
+
+});
+</script>
+<script src="/common/get-host-info.sub.js"></script>
+<script src="data:text/javascript,addCrossOriginYellowImage()"></script>
+
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/security.pattern.create.html b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/security.pattern.create.html
new file mode 100644
index 000000000..b81c6dfa5
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/security.pattern.create.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by tools/gentest.py. -->
+<title>Canvas test: security.pattern.create</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/canvas-tests.js"></script>
+<link rel="stylesheet" href="/common/canvas-tests.css">
+<body class="show_output">
+
+<h1>security.pattern.create</h1>
+<p class="desc">Creating an unclean pattern does not make the canvas origin-unclean</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Creating an unclean pattern does not make the canvas origin-unclean");
+_addTest(function(canvas, ctx) {
+
+var p = ctx.createPattern(document.getElementById('yellow.png'), 'repeat');
+canvas.toDataURL();
+ctx.getImageData(0, 0, 1, 1);
+_assert(true, "true"); // okay if there was no exception
+
+
+});
+</script>
+<script src="/common/get-host-info.sub.js"></script>
+<script src="data:text/javascript,addCrossOriginYellowImage()"></script>
+
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/security.pattern.cross.html b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/security.pattern.cross.html
new file mode 100644
index 000000000..67e40bdaa
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/security.pattern.cross.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by tools/gentest.py. -->
+<title>Canvas test: security.pattern.cross</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/canvas-tests.js"></script>
+<link rel="stylesheet" href="/common/canvas-tests.css">
+<body class="show_output">
+
+<h1>security.pattern.cross</h1>
+<p class="desc">Using an unclean pattern makes the target canvas origin-unclean, not the pattern canvas</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Using an unclean pattern makes the target canvas origin-unclean, not the pattern canvas");
+_addTest(function(canvas, ctx) {
+
+var canvas2 = document.createElement('canvas');
+canvas2.width = 100;
+canvas2.height = 50;
+var ctx2 = canvas2.getContext('2d');
+var p = ctx2.createPattern(document.getElementById('yellow.png'), 'repeat');
+ctx.fillStyle = p;
+ctx.fillRect(0, 0, 100, 50);
+assert_throws("SECURITY_ERR", function() { canvas.toDataURL(); });
+assert_throws("SECURITY_ERR", function() { ctx.getImageData(0, 0, 1, 1); });
+canvas2.toDataURL();
+ctx2.getImageData(0, 0, 1, 1);
+
+
+});
+</script>
+<script src="/common/get-host-info.sub.js"></script>
+<script src="data:text/javascript,addCrossOriginYellowImage()"></script>
+
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/security.pattern.image.fillStyle.html b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/security.pattern.image.fillStyle.html
new file mode 100644
index 000000000..758c30a12
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/security.pattern.image.fillStyle.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by tools/gentest.py. -->
+<title>Canvas test: security.pattern.image.fillStyle</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/canvas-tests.js"></script>
+<link rel="stylesheet" href="/common/canvas-tests.css">
+<body class="show_output">
+
+<h1>security.pattern.image.fillStyle</h1>
+<p class="desc">Setting fillStyle to a pattern of a different-origin image makes the canvas origin-unclean</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Setting fillStyle to a pattern of a different-origin image makes the canvas origin-unclean");
+_addTest(function(canvas, ctx) {
+
+var p = ctx.createPattern(document.getElementById('yellow.png'), 'repeat');
+ctx.fillStyle = p;
+ctx.fillStyle = 'red';
+assert_throws("SECURITY_ERR", function() { canvas.toDataURL(); });
+assert_throws("SECURITY_ERR", function() { ctx.getImageData(0, 0, 1, 1); });
+
+
+});
+</script>
+<script src="/common/get-host-info.sub.js"></script>
+<script src="data:text/javascript,addCrossOriginYellowImage()"></script>
+
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/security.pattern.image.strokeStyle.html b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/security.pattern.image.strokeStyle.html
new file mode 100644
index 000000000..771523973
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/security.pattern.image.strokeStyle.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by tools/gentest.py. -->
+<title>Canvas test: security.pattern.image.strokeStyle</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/canvas-tests.js"></script>
+<link rel="stylesheet" href="/common/canvas-tests.css">
+<body class="show_output">
+
+<h1>security.pattern.image.strokeStyle</h1>
+<p class="desc">Setting strokeStyle to a pattern of a different-origin image makes the canvas origin-unclean</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Setting strokeStyle to a pattern of a different-origin image makes the canvas origin-unclean");
+_addTest(function(canvas, ctx) {
+
+var p = ctx.createPattern(document.getElementById('yellow.png'), 'repeat');
+ctx.strokeStyle = p;
+ctx.strokeStyle = 'red';
+assert_throws("SECURITY_ERR", function() { canvas.toDataURL(); });
+assert_throws("SECURITY_ERR", function() { ctx.getImageData(0, 0, 1, 1); });
+
+
+});
+</script>
+<script src="/common/get-host-info.sub.js"></script>
+<script src="data:text/javascript,addCrossOriginYellowImage()"></script>
+
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/security.reset.html b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/security.reset.html
new file mode 100644
index 000000000..28e65f90e
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/security.reset.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by tools/gentest.py. -->
+<title>Canvas test: security.reset</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/canvas-tests.js"></script>
+<link rel="stylesheet" href="/common/canvas-tests.css">
+<body class="show_output">
+
+<h1>security.reset</h1>
+<p class="desc">Resetting the canvas state does not reset the origin-clean flag</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Resetting the canvas state does not reset the origin-clean flag");
+_addTest(function(canvas, ctx) {
+
+canvas.width = 50;
+ctx.drawImage(document.getElementById('yellow.png'), 0, 0);
+assert_throws("SECURITY_ERR", function() { canvas.toDataURL(); });
+canvas.width = 100;
+assert_throws("SECURITY_ERR", function() { canvas.toDataURL(); });
+
+
+});
+</script>
+<script src="/common/get-host-info.sub.js"></script>
+<script src="data:text/javascript,addCrossOriginYellowImage()"></script>
+
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.default.html b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.default.html
new file mode 100644
index 000000000..004636d84
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.default.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by tools/gentest.py. -->
+<title>Canvas test: size.attributes.default</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/canvas-tests.js"></script>
+<link rel="stylesheet" href="/common/canvas-tests.css">
+<body class="show_output">
+
+<h1>size.attributes.default</h1>
+<p class="desc">Default width/height when attributes are missing</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" ><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="size.attributes.default.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Default width/height when attributes are missing");
+_addTest(function(canvas, ctx) {
+
+_assertSame(canvas.width, 300, "canvas.width", "300");
+_assertSame(canvas.height, 150, "canvas.height", "150");
+_assert(!canvas.hasAttribute('width'), "!canvas.hasAttribute('width')");
+_assert(!canvas.hasAttribute('height'), "!canvas.hasAttribute('height')");
+
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.default.png b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.default.png
new file mode 100644
index 000000000..a72d04755
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.default.png
Binary files differ
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.get.png b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.get.png
new file mode 100644
index 000000000..47830c83e
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.get.png
Binary files differ
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.idl.html b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.idl.html
new file mode 100644
index 000000000..cd6796e07
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.idl.html
@@ -0,0 +1,50 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by tools/gentest.py. -->
+<title>Canvas test: size.attributes.idl</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/canvas-tests.js"></script>
+<link rel="stylesheet" href="/common/canvas-tests.css">
+<body class="show_output">
+
+<h1>size.attributes.idl</h1>
+<p class="desc">Getting/setting width/height IDL attributes</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Getting/setting width/height IDL attributes");
+_addTest(function(canvas, ctx) {
+
+canvas.width = "100";
+canvas.height = "100";
+_assertSame(canvas.width, 100, "canvas.width", "100");
+_assertSame(canvas.height, 100, "canvas.height", "100");
+
+canvas.width = "+1.5e2";
+canvas.height = "0x96";
+_assertSame(canvas.width, 150, "canvas.width", "150");
+_assertSame(canvas.height, 150, "canvas.height", "150");
+
+canvas.width = 200 - Math.pow(2, 32);
+canvas.height = 200 - Math.pow(2, 32);
+_assertSame(canvas.width, 200, "canvas.width", "200");
+_assertSame(canvas.height, 200, "canvas.height", "200");
+
+canvas.width = 301.999;
+canvas.height = 301.001;
+_assertSame(canvas.width, 301, "canvas.width", "301");
+_assertSame(canvas.height, 301, "canvas.height", "301");
+
+canvas.width = "400x";
+canvas.height = "foo";
+_assertSame(canvas.width, 0, "canvas.width", "0");
+_assertSame(canvas.height, 0, "canvas.height", "0");
+
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.idl.set.zero.html b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.idl.set.zero.html
new file mode 100644
index 000000000..a10ac5443
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.idl.set.zero.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by tools/gentest.py. -->
+<title>Canvas test: size.attributes.idl.set.zero</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/canvas-tests.js"></script>
+<link rel="stylesheet" href="/common/canvas-tests.css">
+<body class="show_output">
+
+<h1>size.attributes.idl.set.zero</h1>
+<p class="desc">Setting width/height IDL attributes to 0</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Setting width/height IDL attributes to 0");
+_addTest(function(canvas, ctx) {
+
+canvas.width = 0;
+canvas.height = 0;
+_assertSame(canvas.width, 0, "canvas.width", "0");
+_assertSame(canvas.height, 0, "canvas.height", "0");
+
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.parse.decimal.html b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.parse.decimal.html
new file mode 100644
index 000000000..ccf579e05
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.parse.decimal.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by tools/gentest.py. -->
+<title>Canvas test: size.attributes.parse.decimal</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/canvas-tests.js"></script>
+<link rel="stylesheet" href="/common/canvas-tests.css">
+<body class="show_output">
+
+<h1>size.attributes.parse.decimal</h1>
+<p class="desc">Parsing of non-negative integers</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100.999" height="100.999"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="size.attributes.parse.decimal.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Parsing of non-negative integers");
+_addTest(function(canvas, ctx) {
+
+_assertSame(canvas.width, 100, "canvas.width", "100");
+_assertSame(canvas.height, 100, "canvas.height", "100");
+_assertSame(window.getComputedStyle(canvas, null).getPropertyValue("width"), "100px", "window.getComputedStyle(canvas, null).getPropertyValue(\"width\")", "\"100px\"");
+_assertSame(canvas.getAttribute('width'), '100.999', "canvas.getAttribute('width')", "'100.999'");
+_assertSame(canvas.getAttribute('height'), '100.999', "canvas.getAttribute('height')", "'100.999'");
+
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.parse.decimal.png b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.parse.decimal.png
new file mode 100644
index 000000000..f84267333
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.parse.decimal.png
Binary files differ
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.parse.em.html b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.parse.em.html
new file mode 100644
index 000000000..84614691a
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.parse.em.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by tools/gentest.py. -->
+<title>Canvas test: size.attributes.parse.em</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/canvas-tests.js"></script>
+<link rel="stylesheet" href="/common/canvas-tests.css">
+<body class="show_output">
+
+<h1>size.attributes.parse.em</h1>
+<p class="desc">Parsing of non-negative integers</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100em" height="100em"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="size.attributes.parse.em.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Parsing of non-negative integers");
+_addTest(function(canvas, ctx) {
+
+_assertSame(canvas.width, 100, "canvas.width", "100");
+_assertSame(canvas.height, 100, "canvas.height", "100");
+_assertSame(window.getComputedStyle(canvas, null).getPropertyValue("width"), "100px", "window.getComputedStyle(canvas, null).getPropertyValue(\"width\")", "\"100px\"");
+_assertSame(canvas.getAttribute('width'), '100em', "canvas.getAttribute('width')", "'100em'");
+_assertSame(canvas.getAttribute('height'), '100em', "canvas.getAttribute('height')", "'100em'");
+
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.parse.em.png b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.parse.em.png
new file mode 100644
index 000000000..f84267333
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.parse.em.png
Binary files differ
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.parse.empty.html b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.parse.empty.html
new file mode 100644
index 000000000..04a19b44a
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.parse.empty.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by tools/gentest.py. -->
+<title>Canvas test: size.attributes.parse.empty</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/canvas-tests.js"></script>
+<link rel="stylesheet" href="/common/canvas-tests.css">
+<body class="show_output">
+
+<h1>size.attributes.parse.empty</h1>
+<p class="desc">Parsing of non-negative integers</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="" height=""><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="size.attributes.parse.empty.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Parsing of non-negative integers");
+_addTest(function(canvas, ctx) {
+
+_assertSame(canvas.width, 300, "canvas.width", "300");
+_assertSame(canvas.height, 150, "canvas.height", "150");
+_assertSame(canvas.getAttribute('width'), '', "canvas.getAttribute('width')", "''");
+_assertSame(canvas.getAttribute('height'), '', "canvas.getAttribute('height')", "''");
+
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.parse.empty.png b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.parse.empty.png
new file mode 100644
index 000000000..a72d04755
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.parse.empty.png
Binary files differ
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.parse.exp.html b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.parse.exp.html
new file mode 100644
index 000000000..7a7c72692
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.parse.exp.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by tools/gentest.py. -->
+<title>Canvas test: size.attributes.parse.exp</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/canvas-tests.js"></script>
+<link rel="stylesheet" href="/common/canvas-tests.css">
+<body class="show_output">
+
+<h1>size.attributes.parse.exp</h1>
+<p class="desc">Parsing of non-negative integers</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100e1" height="100e1"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="size.attributes.parse.exp.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Parsing of non-negative integers");
+_addTest(function(canvas, ctx) {
+
+_assertSame(canvas.width, 100, "canvas.width", "100");
+_assertSame(canvas.height, 100, "canvas.height", "100");
+_assertSame(window.getComputedStyle(canvas, null).getPropertyValue("width"), "100px", "window.getComputedStyle(canvas, null).getPropertyValue(\"width\")", "\"100px\"");
+_assertSame(canvas.getAttribute('width'), '100e1', "canvas.getAttribute('width')", "'100e1'");
+_assertSame(canvas.getAttribute('height'), '100e1', "canvas.getAttribute('height')", "'100e1'");
+
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.parse.exp.png b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.parse.exp.png
new file mode 100644
index 000000000..f84267333
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.parse.exp.png
Binary files differ
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.parse.hex.html b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.parse.hex.html
new file mode 100644
index 000000000..7532d7753
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.parse.hex.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by tools/gentest.py. -->
+<title>Canvas test: size.attributes.parse.hex</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/canvas-tests.js"></script>
+<link rel="stylesheet" href="/common/canvas-tests.css">
+<body class="show_output">
+
+<h1>size.attributes.parse.hex</h1>
+<p class="desc">Parsing of non-negative integers</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="0x100" height="0x100"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Parsing of non-negative integers");
+_addTest(function(canvas, ctx) {
+
+_assertSame(canvas.width, 0, "canvas.width", "0");
+_assertSame(canvas.height, 0, "canvas.height", "0");
+_assertSame(window.getComputedStyle(canvas, null).getPropertyValue("width"), "0px", "window.getComputedStyle(canvas, null).getPropertyValue(\"width\")", "\"0px\"");
+_assertSame(canvas.getAttribute('width'), '0x100', "canvas.getAttribute('width')", "'0x100'");
+_assertSame(canvas.getAttribute('height'), '0x100', "canvas.getAttribute('height')", "'0x100'");
+
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.parse.junk.html b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.parse.junk.html
new file mode 100644
index 000000000..8dca5ef3c
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.parse.junk.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by tools/gentest.py. -->
+<title>Canvas test: size.attributes.parse.junk</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/canvas-tests.js"></script>
+<link rel="stylesheet" href="/common/canvas-tests.css">
+<body class="show_output">
+
+<h1>size.attributes.parse.junk</h1>
+<p class="desc">Parsing of non-negative integers</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="#!?" height="#!?"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="size.attributes.parse.junk.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Parsing of non-negative integers");
+_addTest(function(canvas, ctx) {
+
+_assertSame(canvas.width, 300, "canvas.width", "300");
+_assertSame(canvas.height, 150, "canvas.height", "150");
+_assertSame(canvas.getAttribute('width'), '#!?', "canvas.getAttribute('width')", "'#!?'");
+_assertSame(canvas.getAttribute('height'), '#!?', "canvas.getAttribute('height')", "'#!?'");
+
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.parse.junk.png b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.parse.junk.png
new file mode 100644
index 000000000..a72d04755
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.parse.junk.png
Binary files differ
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.parse.minus.html b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.parse.minus.html
new file mode 100644
index 000000000..c901dffc5
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.parse.minus.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by tools/gentest.py. -->
+<title>Canvas test: size.attributes.parse.minus</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/canvas-tests.js"></script>
+<link rel="stylesheet" href="/common/canvas-tests.css">
+<body class="show_output">
+
+<h1>size.attributes.parse.minus</h1>
+<p class="desc">Parsing of non-negative integers</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="-100" height="-100"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="size.attributes.parse.minus.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Parsing of non-negative integers");
+_addTest(function(canvas, ctx) {
+
+_assertSame(canvas.width, 300, "canvas.width", "300");
+_assertSame(canvas.height, 150, "canvas.height", "150");
+_assertSame(canvas.getAttribute('width'), '-100', "canvas.getAttribute('width')", "'-100'");
+_assertSame(canvas.getAttribute('height'), '-100', "canvas.getAttribute('height')", "'-100'");
+
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.parse.minus.png b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.parse.minus.png
new file mode 100644
index 000000000..a72d04755
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.parse.minus.png
Binary files differ
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.parse.octal.html b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.parse.octal.html
new file mode 100644
index 000000000..efdcfeb3a
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.parse.octal.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by tools/gentest.py. -->
+<title>Canvas test: size.attributes.parse.octal</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/canvas-tests.js"></script>
+<link rel="stylesheet" href="/common/canvas-tests.css">
+<body class="show_output">
+
+<h1>size.attributes.parse.octal</h1>
+<p class="desc">Parsing of non-negative integers</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="0100" height="0100"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="size.attributes.parse.octal.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Parsing of non-negative integers");
+_addTest(function(canvas, ctx) {
+
+_assertSame(canvas.width, 100, "canvas.width", "100");
+_assertSame(canvas.height, 100, "canvas.height", "100");
+_assertSame(window.getComputedStyle(canvas, null).getPropertyValue("width"), "100px", "window.getComputedStyle(canvas, null).getPropertyValue(\"width\")", "\"100px\"");
+_assertSame(canvas.getAttribute('width'), '0100', "canvas.getAttribute('width')", "'0100'");
+_assertSame(canvas.getAttribute('height'), '0100', "canvas.getAttribute('height')", "'0100'");
+
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.parse.octal.png b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.parse.octal.png
new file mode 100644
index 000000000..f84267333
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.parse.octal.png
Binary files differ
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.parse.onlyspace.html b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.parse.onlyspace.html
new file mode 100644
index 000000000..11948581e
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.parse.onlyspace.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by tools/gentest.py. -->
+<title>Canvas test: size.attributes.parse.onlyspace</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/canvas-tests.js"></script>
+<link rel="stylesheet" href="/common/canvas-tests.css">
+<body class="show_output">
+
+<h1>size.attributes.parse.onlyspace</h1>
+<p class="desc">Parsing of non-negative integers</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width=" " height=" "><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="size.attributes.parse.onlyspace.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Parsing of non-negative integers");
+_addTest(function(canvas, ctx) {
+
+_assertSame(canvas.width, 300, "canvas.width", "300");
+_assertSame(canvas.height, 150, "canvas.height", "150");
+_assertSame(canvas.getAttribute('width'), ' ', "canvas.getAttribute('width')", "' '");
+_assertSame(canvas.getAttribute('height'), ' ', "canvas.getAttribute('height')", "' '");
+
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.parse.onlyspace.png b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.parse.onlyspace.png
new file mode 100644
index 000000000..a72d04755
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.parse.onlyspace.png
Binary files differ
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.parse.percent.html b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.parse.percent.html
new file mode 100644
index 000000000..9073424e2
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.parse.percent.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by tools/gentest.py. -->
+<title>Canvas test: size.attributes.parse.percent</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/canvas-tests.js"></script>
+<link rel="stylesheet" href="/common/canvas-tests.css">
+<body class="show_output">
+
+<h1>size.attributes.parse.percent</h1>
+<p class="desc">Parsing of non-negative integers</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100%" height="100%"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="size.attributes.parse.percent.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Parsing of non-negative integers");
+_addTest(function(canvas, ctx) {
+
+_assertSame(canvas.width, 100, "canvas.width", "100");
+_assertSame(canvas.height, 100, "canvas.height", "100");
+_assertSame(window.getComputedStyle(canvas, null).getPropertyValue("width"), "100px", "window.getComputedStyle(canvas, null).getPropertyValue(\"width\")", "\"100px\"");
+_assertSame(canvas.getAttribute('width'), '100%', "canvas.getAttribute('width')", "'100%'");
+_assertSame(canvas.getAttribute('height'), '100%', "canvas.getAttribute('height')", "'100%'");
+
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.parse.percent.png b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.parse.percent.png
new file mode 100644
index 000000000..f84267333
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.parse.percent.png
Binary files differ
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.parse.plus.html b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.parse.plus.html
new file mode 100644
index 000000000..816f381d4
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.parse.plus.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by tools/gentest.py. -->
+<title>Canvas test: size.attributes.parse.plus</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/canvas-tests.js"></script>
+<link rel="stylesheet" href="/common/canvas-tests.css">
+<body class="show_output">
+
+<h1>size.attributes.parse.plus</h1>
+<p class="desc">Parsing of non-negative integers</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="+100" height="+100"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="size.attributes.parse.plus.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Parsing of non-negative integers");
+_addTest(function(canvas, ctx) {
+
+_assertSame(canvas.width, 100, "canvas.width", "100");
+_assertSame(canvas.height, 100, "canvas.height", "100");
+_assertSame(window.getComputedStyle(canvas, null).getPropertyValue("width"), "100px", "window.getComputedStyle(canvas, null).getPropertyValue(\"width\")", "\"100px\"");
+_assertSame(canvas.getAttribute('width'), '+100', "canvas.getAttribute('width')", "'+100'");
+_assertSame(canvas.getAttribute('height'), '+100', "canvas.getAttribute('height')", "'+100'");
+
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.parse.plus.png b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.parse.plus.png
new file mode 100644
index 000000000..f84267333
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.parse.plus.png
Binary files differ
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.parse.space.html b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.parse.space.html
new file mode 100644
index 000000000..417674d18
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.parse.space.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by tools/gentest.py. -->
+<title>Canvas test: size.attributes.parse.space</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/canvas-tests.js"></script>
+<link rel="stylesheet" href="/common/canvas-tests.css">
+<body class="show_output">
+
+<h1>size.attributes.parse.space</h1>
+<p class="desc">Parsing of non-negative integers</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width=" 100" height=" 100"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="size.attributes.parse.space.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Parsing of non-negative integers");
+_addTest(function(canvas, ctx) {
+
+_assertSame(canvas.width, 100, "canvas.width", "100");
+_assertSame(canvas.height, 100, "canvas.height", "100");
+_assertSame(window.getComputedStyle(canvas, null).getPropertyValue("width"), "100px", "window.getComputedStyle(canvas, null).getPropertyValue(\"width\")", "\"100px\"");
+_assertSame(canvas.getAttribute('width'), ' 100', "canvas.getAttribute('width')", "' 100'");
+_assertSame(canvas.getAttribute('height'), ' 100', "canvas.getAttribute('height')", "' 100'");
+
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.parse.space.png b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.parse.space.png
new file mode 100644
index 000000000..f84267333
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.parse.space.png
Binary files differ
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.parse.trailingjunk.html b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.parse.trailingjunk.html
new file mode 100644
index 000000000..76c6db05f
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.parse.trailingjunk.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by tools/gentest.py. -->
+<title>Canvas test: size.attributes.parse.trailingjunk</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/canvas-tests.js"></script>
+<link rel="stylesheet" href="/common/canvas-tests.css">
+<body class="show_output">
+
+<h1>size.attributes.parse.trailingjunk</h1>
+<p class="desc">Parsing of non-negative integers</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100#!?" height="100#!?"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="size.attributes.parse.trailingjunk.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Parsing of non-negative integers");
+_addTest(function(canvas, ctx) {
+
+_assertSame(canvas.width, 100, "canvas.width", "100");
+_assertSame(canvas.height, 100, "canvas.height", "100");
+_assertSame(window.getComputedStyle(canvas, null).getPropertyValue("width"), "100px", "window.getComputedStyle(canvas, null).getPropertyValue(\"width\")", "\"100px\"");
+_assertSame(canvas.getAttribute('width'), '100#!?', "canvas.getAttribute('width')", "'100#!?'");
+_assertSame(canvas.getAttribute('height'), '100#!?', "canvas.getAttribute('height')", "'100#!?'");
+
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.parse.trailingjunk.png b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.parse.trailingjunk.png
new file mode 100644
index 000000000..f84267333
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.parse.trailingjunk.png
Binary files differ
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.parse.whitespace.html b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.parse.whitespace.html
new file mode 100644
index 000000000..dc8eab52b
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.parse.whitespace.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by tools/gentest.py. -->
+<title>Canvas test: size.attributes.parse.whitespace</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/canvas-tests.js"></script>
+<link rel="stylesheet" href="/common/canvas-tests.css">
+<body class="show_output">
+
+<h1>size.attributes.parse.whitespace</h1>
+<p class="desc">Parsing of non-negative integers</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="
+ 100" height="
+ 100"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="size.attributes.parse.whitespace.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Parsing of non-negative integers");
+_addTest(function(canvas, ctx) {
+
+_assertSame(canvas.width, 100, "canvas.width", "100");
+_assertSame(canvas.height, 100, "canvas.height", "100");
+_assertSame(window.getComputedStyle(canvas, null).getPropertyValue("width"), "100px", "window.getComputedStyle(canvas, null).getPropertyValue(\"width\")", "\"100px\"");
+_assertSame(canvas.getAttribute('width'), '\n\t\x0c100', "canvas.getAttribute('width')", "'\\n\\t\\x0c100'");
+_assertSame(canvas.getAttribute('height'), '\n\t\x0c100', "canvas.getAttribute('height')", "'\\n\\t\\x0c100'");
+
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.parse.whitespace.png b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.parse.whitespace.png
new file mode 100644
index 000000000..f84267333
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.parse.whitespace.png
Binary files differ
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.parse.zero.html b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.parse.zero.html
new file mode 100644
index 000000000..e42ebeb24
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.parse.zero.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by tools/gentest.py. -->
+<title>Canvas test: size.attributes.parse.zero</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/canvas-tests.js"></script>
+<link rel="stylesheet" href="/common/canvas-tests.css">
+<body class="show_output">
+
+<h1>size.attributes.parse.zero</h1>
+<p class="desc">Parsing of non-negative integers</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="0" height="0"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Parsing of non-negative integers");
+_addTest(function(canvas, ctx) {
+
+_assertSame(canvas.width, 0, "canvas.width", "0");
+_assertSame(canvas.height, 0, "canvas.height", "0");
+_assertSame(window.getComputedStyle(canvas, null).getPropertyValue("width"), "0px", "window.getComputedStyle(canvas, null).getPropertyValue(\"width\")", "\"0px\"");
+_assertSame(canvas.getAttribute('width'), '0', "canvas.getAttribute('width')", "'0'");
+_assertSame(canvas.getAttribute('height'), '0', "canvas.getAttribute('height')", "'0'");
+
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.reflect.setcontent.html b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.reflect.setcontent.html
new file mode 100644
index 000000000..e77ca8ee0
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.reflect.setcontent.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by tools/gentest.py. -->
+<title>Canvas test: size.attributes.reflect.setcontent</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/canvas-tests.js"></script>
+<link rel="stylesheet" href="/common/canvas-tests.css">
+<body class="show_output">
+
+<h1>size.attributes.reflect.setcontent</h1>
+<p class="desc">Setting content attributes updates IDL and content attributes</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="size.attributes.reflect.setcontent.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Setting content attributes updates IDL and content attributes");
+_addTest(function(canvas, ctx) {
+
+canvas.setAttribute('width', '120');
+canvas.setAttribute('height', '60');
+_assertSame(canvas.getAttribute('width'), '120', "canvas.getAttribute('width')", "'120'");
+_assertSame(canvas.getAttribute('height'), '60', "canvas.getAttribute('height')", "'60'");
+_assertSame(canvas.width, 120, "canvas.width", "120");
+_assertSame(canvas.height, 60, "canvas.height", "60");
+
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.reflect.setcontent.png b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.reflect.setcontent.png
new file mode 100644
index 000000000..47830c83e
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.reflect.setcontent.png
Binary files differ
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.reflect.setidl.html b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.reflect.setidl.html
new file mode 100644
index 000000000..152288291
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.reflect.setidl.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by tools/gentest.py. -->
+<title>Canvas test: size.attributes.reflect.setidl</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/canvas-tests.js"></script>
+<link rel="stylesheet" href="/common/canvas-tests.css">
+<body class="show_output">
+
+<h1>size.attributes.reflect.setidl</h1>
+<p class="desc">Setting IDL attributes updates IDL and content attributes</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="size.attributes.reflect.setidl.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Setting IDL attributes updates IDL and content attributes");
+_addTest(function(canvas, ctx) {
+
+canvas.width = 120;
+canvas.height = 60;
+_assertSame(canvas.getAttribute('width'), '120', "canvas.getAttribute('width')", "'120'");
+_assertSame(canvas.getAttribute('height'), '60', "canvas.getAttribute('height')", "'60'");
+_assertSame(canvas.width, 120, "canvas.width", "120");
+_assertSame(canvas.height, 60, "canvas.height", "60");
+
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.reflect.setidl.png b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.reflect.setidl.png
new file mode 100644
index 000000000..47830c83e
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.reflect.setidl.png
Binary files differ
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.reflect.setidlzero.html b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.reflect.setidlzero.html
new file mode 100644
index 000000000..2bace5a33
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.reflect.setidlzero.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by tools/gentest.py. -->
+<title>Canvas test: size.attributes.reflect.setidlzero</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/canvas-tests.js"></script>
+<link rel="stylesheet" href="/common/canvas-tests.css">
+<body class="show_output">
+
+<h1>size.attributes.reflect.setidlzero</h1>
+<p class="desc">Setting IDL attributes to 0 updates IDL and content attributes</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Setting IDL attributes to 0 updates IDL and content attributes");
+_addTest(function(canvas, ctx) {
+
+canvas.width = 0;
+canvas.height = 0;
+_assertSame(canvas.getAttribute('width'), '0', "canvas.getAttribute('width')", "'0'");
+_assertSame(canvas.getAttribute('height'), '0', "canvas.getAttribute('height')", "'0'");
+_assertSame(canvas.width, 0, "canvas.width", "0");
+_assertSame(canvas.height, 0, "canvas.height", "0");
+
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.removed.html b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.removed.html
new file mode 100644
index 000000000..58fb899e0
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.removed.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by tools/gentest.py. -->
+<title>Canvas test: size.attributes.removed</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/canvas-tests.js"></script>
+<link rel="stylesheet" href="/common/canvas-tests.css">
+<body class="show_output">
+
+<h1>size.attributes.removed</h1>
+<p class="desc">Removing content attributes reverts to default size</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="120" height="60"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="size.attributes.removed.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Removing content attributes reverts to default size");
+_addTest(function(canvas, ctx) {
+
+_assertSame(canvas.width, 120, "canvas.width", "120");
+canvas.removeAttribute('width');
+_assertSame(canvas.width, 300, "canvas.width", "300");
+
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.removed.png b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.removed.png
new file mode 100644
index 000000000..1ebf30d8a
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.removed.png
Binary files differ
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.set.png b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.set.png
new file mode 100644
index 000000000..47830c83e
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.set.png
Binary files differ
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.setAttribute.decimal.html b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.setAttribute.decimal.html
new file mode 100644
index 000000000..0f4fb69fa
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.setAttribute.decimal.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by tools/gentest.py. -->
+<title>Canvas test: size.attributes.setAttribute.decimal</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/canvas-tests.js"></script>
+<link rel="stylesheet" href="/common/canvas-tests.css">
+<body class="show_output">
+
+<h1>size.attributes.setAttribute.decimal</h1>
+<p class="desc">Parsing of non-negative integers in setAttribute</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="50" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="size.attributes.setAttribute.decimal.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Parsing of non-negative integers in setAttribute");
+_addTest(function(canvas, ctx) {
+
+canvas.setAttribute('width', '100.999');
+canvas.setAttribute('height', '100.999');
+_assertSame(canvas.width, 100, "canvas.width", "100");
+_assertSame(canvas.height, 100, "canvas.height", "100");
+_assertSame(window.getComputedStyle(canvas, null).getPropertyValue("width"), "100px", "window.getComputedStyle(canvas, null).getPropertyValue(\"width\")", "\"100px\"");
+_assertSame(canvas.getAttribute('width'), '100.999', "canvas.getAttribute('width')", "'100.999'");
+_assertSame(canvas.getAttribute('height'), '100.999', "canvas.getAttribute('height')", "'100.999'");
+
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.setAttribute.decimal.png b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.setAttribute.decimal.png
new file mode 100644
index 000000000..f84267333
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.setAttribute.decimal.png
Binary files differ
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.setAttribute.em.html b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.setAttribute.em.html
new file mode 100644
index 000000000..5768d1727
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.setAttribute.em.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by tools/gentest.py. -->
+<title>Canvas test: size.attributes.setAttribute.em</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/canvas-tests.js"></script>
+<link rel="stylesheet" href="/common/canvas-tests.css">
+<body class="show_output">
+
+<h1>size.attributes.setAttribute.em</h1>
+<p class="desc">Parsing of non-negative integers in setAttribute</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="50" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="size.attributes.setAttribute.em.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Parsing of non-negative integers in setAttribute");
+_addTest(function(canvas, ctx) {
+
+canvas.setAttribute('width', '100em');
+canvas.setAttribute('height', '100em');
+_assertSame(canvas.width, 100, "canvas.width", "100");
+_assertSame(canvas.height, 100, "canvas.height", "100");
+_assertSame(window.getComputedStyle(canvas, null).getPropertyValue("width"), "100px", "window.getComputedStyle(canvas, null).getPropertyValue(\"width\")", "\"100px\"");
+_assertSame(canvas.getAttribute('width'), '100em', "canvas.getAttribute('width')", "'100em'");
+_assertSame(canvas.getAttribute('height'), '100em', "canvas.getAttribute('height')", "'100em'");
+
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.setAttribute.em.png b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.setAttribute.em.png
new file mode 100644
index 000000000..f84267333
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.setAttribute.em.png
Binary files differ
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.setAttribute.empty.html b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.setAttribute.empty.html
new file mode 100644
index 000000000..65a5bc0d9
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.setAttribute.empty.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by tools/gentest.py. -->
+<title>Canvas test: size.attributes.setAttribute.empty</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/canvas-tests.js"></script>
+<link rel="stylesheet" href="/common/canvas-tests.css">
+<body class="show_output">
+
+<h1>size.attributes.setAttribute.empty</h1>
+<p class="desc">Parsing of non-negative integers in setAttribute</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="50" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="size.attributes.setAttribute.empty.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Parsing of non-negative integers in setAttribute");
+_addTest(function(canvas, ctx) {
+
+canvas.setAttribute('width', '');
+canvas.setAttribute('height', '');
+_assertSame(canvas.width, 300, "canvas.width", "300");
+_assertSame(canvas.height, 150, "canvas.height", "150");
+_assertSame(canvas.getAttribute('width'), '', "canvas.getAttribute('width')", "''");
+_assertSame(canvas.getAttribute('height'), '', "canvas.getAttribute('height')", "''");
+
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.setAttribute.empty.png b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.setAttribute.empty.png
new file mode 100644
index 000000000..a72d04755
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.setAttribute.empty.png
Binary files differ
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.setAttribute.exp.html b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.setAttribute.exp.html
new file mode 100644
index 000000000..673edad56
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.setAttribute.exp.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by tools/gentest.py. -->
+<title>Canvas test: size.attributes.setAttribute.exp</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/canvas-tests.js"></script>
+<link rel="stylesheet" href="/common/canvas-tests.css">
+<body class="show_output">
+
+<h1>size.attributes.setAttribute.exp</h1>
+<p class="desc">Parsing of non-negative integers in setAttribute</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="50" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="size.attributes.setAttribute.exp.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Parsing of non-negative integers in setAttribute");
+_addTest(function(canvas, ctx) {
+
+canvas.setAttribute('width', '100e1');
+canvas.setAttribute('height', '100e1');
+_assertSame(canvas.width, 100, "canvas.width", "100");
+_assertSame(canvas.height, 100, "canvas.height", "100");
+_assertSame(window.getComputedStyle(canvas, null).getPropertyValue("width"), "100px", "window.getComputedStyle(canvas, null).getPropertyValue(\"width\")", "\"100px\"");
+_assertSame(canvas.getAttribute('width'), '100e1', "canvas.getAttribute('width')", "'100e1'");
+_assertSame(canvas.getAttribute('height'), '100e1', "canvas.getAttribute('height')", "'100e1'");
+
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.setAttribute.exp.png b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.setAttribute.exp.png
new file mode 100644
index 000000000..f84267333
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.setAttribute.exp.png
Binary files differ
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.setAttribute.hex.html b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.setAttribute.hex.html
new file mode 100644
index 000000000..e6fde5329
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.setAttribute.hex.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by tools/gentest.py. -->
+<title>Canvas test: size.attributes.setAttribute.hex</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/canvas-tests.js"></script>
+<link rel="stylesheet" href="/common/canvas-tests.css">
+<body class="show_output">
+
+<h1>size.attributes.setAttribute.hex</h1>
+<p class="desc">Parsing of non-negative integers in setAttribute</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="50" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Parsing of non-negative integers in setAttribute");
+_addTest(function(canvas, ctx) {
+
+canvas.setAttribute('width', '0x100');
+canvas.setAttribute('height', '0x100');
+_assertSame(canvas.width, 0, "canvas.width", "0");
+_assertSame(canvas.height, 0, "canvas.height", "0");
+_assertSame(window.getComputedStyle(canvas, null).getPropertyValue("width"), "0px", "window.getComputedStyle(canvas, null).getPropertyValue(\"width\")", "\"0px\"");
+_assertSame(canvas.getAttribute('width'), '0x100', "canvas.getAttribute('width')", "'0x100'");
+_assertSame(canvas.getAttribute('height'), '0x100', "canvas.getAttribute('height')", "'0x100'");
+
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.setAttribute.junk.html b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.setAttribute.junk.html
new file mode 100644
index 000000000..77b50fd11
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.setAttribute.junk.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by tools/gentest.py. -->
+<title>Canvas test: size.attributes.setAttribute.junk</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/canvas-tests.js"></script>
+<link rel="stylesheet" href="/common/canvas-tests.css">
+<body class="show_output">
+
+<h1>size.attributes.setAttribute.junk</h1>
+<p class="desc">Parsing of non-negative integers in setAttribute</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="50" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="size.attributes.setAttribute.junk.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Parsing of non-negative integers in setAttribute");
+_addTest(function(canvas, ctx) {
+
+canvas.setAttribute('width', '#!?');
+canvas.setAttribute('height', '#!?');
+_assertSame(canvas.width, 300, "canvas.width", "300");
+_assertSame(canvas.height, 150, "canvas.height", "150");
+_assertSame(canvas.getAttribute('width'), '#!?', "canvas.getAttribute('width')", "'#!?'");
+_assertSame(canvas.getAttribute('height'), '#!?', "canvas.getAttribute('height')", "'#!?'");
+
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.setAttribute.junk.png b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.setAttribute.junk.png
new file mode 100644
index 000000000..a72d04755
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.setAttribute.junk.png
Binary files differ
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.setAttribute.minus.html b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.setAttribute.minus.html
new file mode 100644
index 000000000..2bb09bbf2
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.setAttribute.minus.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by tools/gentest.py. -->
+<title>Canvas test: size.attributes.setAttribute.minus</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/canvas-tests.js"></script>
+<link rel="stylesheet" href="/common/canvas-tests.css">
+<body class="show_output">
+
+<h1>size.attributes.setAttribute.minus</h1>
+<p class="desc">Parsing of non-negative integers in setAttribute</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="50" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="size.attributes.setAttribute.minus.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Parsing of non-negative integers in setAttribute");
+_addTest(function(canvas, ctx) {
+
+canvas.setAttribute('width', '-100');
+canvas.setAttribute('height', '-100');
+_assertSame(canvas.width, 300, "canvas.width", "300");
+_assertSame(canvas.height, 150, "canvas.height", "150");
+_assertSame(canvas.getAttribute('width'), '-100', "canvas.getAttribute('width')", "'-100'");
+_assertSame(canvas.getAttribute('height'), '-100', "canvas.getAttribute('height')", "'-100'");
+
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.setAttribute.minus.png b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.setAttribute.minus.png
new file mode 100644
index 000000000..a72d04755
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.setAttribute.minus.png
Binary files differ
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.setAttribute.octal.html b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.setAttribute.octal.html
new file mode 100644
index 000000000..a6cb6d37f
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.setAttribute.octal.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by tools/gentest.py. -->
+<title>Canvas test: size.attributes.setAttribute.octal</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/canvas-tests.js"></script>
+<link rel="stylesheet" href="/common/canvas-tests.css">
+<body class="show_output">
+
+<h1>size.attributes.setAttribute.octal</h1>
+<p class="desc">Parsing of non-negative integers in setAttribute</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="50" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="size.attributes.setAttribute.octal.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Parsing of non-negative integers in setAttribute");
+_addTest(function(canvas, ctx) {
+
+canvas.setAttribute('width', '0100');
+canvas.setAttribute('height', '0100');
+_assertSame(canvas.width, 100, "canvas.width", "100");
+_assertSame(canvas.height, 100, "canvas.height", "100");
+_assertSame(window.getComputedStyle(canvas, null).getPropertyValue("width"), "100px", "window.getComputedStyle(canvas, null).getPropertyValue(\"width\")", "\"100px\"");
+_assertSame(canvas.getAttribute('width'), '0100', "canvas.getAttribute('width')", "'0100'");
+_assertSame(canvas.getAttribute('height'), '0100', "canvas.getAttribute('height')", "'0100'");
+
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.setAttribute.octal.png b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.setAttribute.octal.png
new file mode 100644
index 000000000..f84267333
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.setAttribute.octal.png
Binary files differ
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.setAttribute.onlyspace.html b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.setAttribute.onlyspace.html
new file mode 100644
index 000000000..5e2dd0c6c
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.setAttribute.onlyspace.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by tools/gentest.py. -->
+<title>Canvas test: size.attributes.setAttribute.onlyspace</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/canvas-tests.js"></script>
+<link rel="stylesheet" href="/common/canvas-tests.css">
+<body class="show_output">
+
+<h1>size.attributes.setAttribute.onlyspace</h1>
+<p class="desc">Parsing of non-negative integers in setAttribute</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="50" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="size.attributes.setAttribute.onlyspace.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Parsing of non-negative integers in setAttribute");
+_addTest(function(canvas, ctx) {
+
+canvas.setAttribute('width', ' ');
+canvas.setAttribute('height', ' ');
+_assertSame(canvas.width, 300, "canvas.width", "300");
+_assertSame(canvas.height, 150, "canvas.height", "150");
+_assertSame(canvas.getAttribute('width'), ' ', "canvas.getAttribute('width')", "' '");
+_assertSame(canvas.getAttribute('height'), ' ', "canvas.getAttribute('height')", "' '");
+
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.setAttribute.onlyspace.png b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.setAttribute.onlyspace.png
new file mode 100644
index 000000000..a72d04755
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.setAttribute.onlyspace.png
Binary files differ
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.setAttribute.percent.html b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.setAttribute.percent.html
new file mode 100644
index 000000000..2a41c667e
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.setAttribute.percent.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by tools/gentest.py. -->
+<title>Canvas test: size.attributes.setAttribute.percent</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/canvas-tests.js"></script>
+<link rel="stylesheet" href="/common/canvas-tests.css">
+<body class="show_output">
+
+<h1>size.attributes.setAttribute.percent</h1>
+<p class="desc">Parsing of non-negative integers in setAttribute</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="50" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="size.attributes.setAttribute.percent.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Parsing of non-negative integers in setAttribute");
+_addTest(function(canvas, ctx) {
+
+canvas.setAttribute('width', '100%');
+canvas.setAttribute('height', '100%');
+_assertSame(canvas.width, 100, "canvas.width", "100");
+_assertSame(canvas.height, 100, "canvas.height", "100");
+_assertSame(window.getComputedStyle(canvas, null).getPropertyValue("width"), "100px", "window.getComputedStyle(canvas, null).getPropertyValue(\"width\")", "\"100px\"");
+_assertSame(canvas.getAttribute('width'), '100%', "canvas.getAttribute('width')", "'100%'");
+_assertSame(canvas.getAttribute('height'), '100%', "canvas.getAttribute('height')", "'100%'");
+
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.setAttribute.percent.png b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.setAttribute.percent.png
new file mode 100644
index 000000000..f84267333
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.setAttribute.percent.png
Binary files differ
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.setAttribute.plus.html b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.setAttribute.plus.html
new file mode 100644
index 000000000..f384d82d3
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.setAttribute.plus.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by tools/gentest.py. -->
+<title>Canvas test: size.attributes.setAttribute.plus</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/canvas-tests.js"></script>
+<link rel="stylesheet" href="/common/canvas-tests.css">
+<body class="show_output">
+
+<h1>size.attributes.setAttribute.plus</h1>
+<p class="desc">Parsing of non-negative integers in setAttribute</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="50" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="size.attributes.setAttribute.plus.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Parsing of non-negative integers in setAttribute");
+_addTest(function(canvas, ctx) {
+
+canvas.setAttribute('width', '+100');
+canvas.setAttribute('height', '+100');
+_assertSame(canvas.width, 100, "canvas.width", "100");
+_assertSame(canvas.height, 100, "canvas.height", "100");
+_assertSame(window.getComputedStyle(canvas, null).getPropertyValue("width"), "100px", "window.getComputedStyle(canvas, null).getPropertyValue(\"width\")", "\"100px\"");
+_assertSame(canvas.getAttribute('width'), '+100', "canvas.getAttribute('width')", "'+100'");
+_assertSame(canvas.getAttribute('height'), '+100', "canvas.getAttribute('height')", "'+100'");
+
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.setAttribute.plus.png b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.setAttribute.plus.png
new file mode 100644
index 000000000..f84267333
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.setAttribute.plus.png
Binary files differ
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.setAttribute.space.html b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.setAttribute.space.html
new file mode 100644
index 000000000..8f8585279
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.setAttribute.space.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by tools/gentest.py. -->
+<title>Canvas test: size.attributes.setAttribute.space</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/canvas-tests.js"></script>
+<link rel="stylesheet" href="/common/canvas-tests.css">
+<body class="show_output">
+
+<h1>size.attributes.setAttribute.space</h1>
+<p class="desc">Parsing of non-negative integers in setAttribute</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="50" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="size.attributes.setAttribute.space.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Parsing of non-negative integers in setAttribute");
+_addTest(function(canvas, ctx) {
+
+canvas.setAttribute('width', ' 100');
+canvas.setAttribute('height', ' 100');
+_assertSame(canvas.width, 100, "canvas.width", "100");
+_assertSame(canvas.height, 100, "canvas.height", "100");
+_assertSame(window.getComputedStyle(canvas, null).getPropertyValue("width"), "100px", "window.getComputedStyle(canvas, null).getPropertyValue(\"width\")", "\"100px\"");
+_assertSame(canvas.getAttribute('width'), ' 100', "canvas.getAttribute('width')", "' 100'");
+_assertSame(canvas.getAttribute('height'), ' 100', "canvas.getAttribute('height')", "' 100'");
+
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.setAttribute.space.png b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.setAttribute.space.png
new file mode 100644
index 000000000..f84267333
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.setAttribute.space.png
Binary files differ
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.setAttribute.trailingjunk.html b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.setAttribute.trailingjunk.html
new file mode 100644
index 000000000..f6d06bab0
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.setAttribute.trailingjunk.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by tools/gentest.py. -->
+<title>Canvas test: size.attributes.setAttribute.trailingjunk</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/canvas-tests.js"></script>
+<link rel="stylesheet" href="/common/canvas-tests.css">
+<body class="show_output">
+
+<h1>size.attributes.setAttribute.trailingjunk</h1>
+<p class="desc">Parsing of non-negative integers in setAttribute</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="50" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="size.attributes.setAttribute.trailingjunk.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Parsing of non-negative integers in setAttribute");
+_addTest(function(canvas, ctx) {
+
+canvas.setAttribute('width', '100#!?');
+canvas.setAttribute('height', '100#!?');
+_assertSame(canvas.width, 100, "canvas.width", "100");
+_assertSame(canvas.height, 100, "canvas.height", "100");
+_assertSame(window.getComputedStyle(canvas, null).getPropertyValue("width"), "100px", "window.getComputedStyle(canvas, null).getPropertyValue(\"width\")", "\"100px\"");
+_assertSame(canvas.getAttribute('width'), '100#!?', "canvas.getAttribute('width')", "'100#!?'");
+_assertSame(canvas.getAttribute('height'), '100#!?', "canvas.getAttribute('height')", "'100#!?'");
+
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.setAttribute.trailingjunk.png b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.setAttribute.trailingjunk.png
new file mode 100644
index 000000000..f84267333
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.setAttribute.trailingjunk.png
Binary files differ
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.setAttribute.whitespace.html b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.setAttribute.whitespace.html
new file mode 100644
index 000000000..8a01f57ea
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.setAttribute.whitespace.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by tools/gentest.py. -->
+<title>Canvas test: size.attributes.setAttribute.whitespace</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/canvas-tests.js"></script>
+<link rel="stylesheet" href="/common/canvas-tests.css">
+<body class="show_output">
+
+<h1>size.attributes.setAttribute.whitespace</h1>
+<p class="desc">Parsing of non-negative integers in setAttribute</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="50" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="size.attributes.setAttribute.whitespace.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Parsing of non-negative integers in setAttribute");
+_addTest(function(canvas, ctx) {
+
+canvas.setAttribute('width', '\r\n\t\x0c100');
+canvas.setAttribute('height', '\r\n\t\x0c100');
+_assertSame(canvas.width, 100, "canvas.width", "100");
+_assertSame(canvas.height, 100, "canvas.height", "100");
+_assertSame(window.getComputedStyle(canvas, null).getPropertyValue("width"), "100px", "window.getComputedStyle(canvas, null).getPropertyValue(\"width\")", "\"100px\"");
+_assertSame(canvas.getAttribute('width'), '\r\n\t\x0c100', "canvas.getAttribute('width')", "'\\r\\n\\t\\x0c100'");
+_assertSame(canvas.getAttribute('height'), '\r\n\t\x0c100', "canvas.getAttribute('height')", "'\\r\\n\\t\\x0c100'");
+
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.setAttribute.whitespace.png b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.setAttribute.whitespace.png
new file mode 100644
index 000000000..f84267333
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.setAttribute.whitespace.png
Binary files differ
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.setAttribute.zero.html b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.setAttribute.zero.html
new file mode 100644
index 000000000..d1b05ad20
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.setAttribute.zero.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by tools/gentest.py. -->
+<title>Canvas test: size.attributes.setAttribute.zero</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/canvas-tests.js"></script>
+<link rel="stylesheet" href="/common/canvas-tests.css">
+<body class="show_output">
+
+<h1>size.attributes.setAttribute.zero</h1>
+<p class="desc">Parsing of non-negative integers in setAttribute</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="50" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("Parsing of non-negative integers in setAttribute");
+_addTest(function(canvas, ctx) {
+
+canvas.setAttribute('width', '0');
+canvas.setAttribute('height', '0');
+_assertSame(canvas.width, 0, "canvas.width", "0");
+_assertSame(canvas.height, 0, "canvas.height", "0");
+_assertSame(window.getComputedStyle(canvas, null).getPropertyValue("width"), "0px", "window.getComputedStyle(canvas, null).getPropertyValue(\"width\")", "\"0px\"");
+_assertSame(canvas.getAttribute('width'), '0', "canvas.getAttribute('width')", "'0'");
+_assertSame(canvas.getAttribute('height'), '0', "canvas.getAttribute('height')", "'0'");
+
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.style.html b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.style.html
new file mode 100644
index 000000000..3bab3e79d
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.style.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by tools/gentest.py. -->
+<title>Canvas test: size.attributes.style</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/canvas-tests.js"></script>
+<link rel="stylesheet" href="/common/canvas-tests.css">
+<body class="show_output">
+
+<h1>size.attributes.style</h1>
+<p class="desc">Canvas size is independent of CSS resizing</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="50" height="30" style="width: 100px; height: 50px"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="size.attributes.style.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("Canvas size is independent of CSS resizing");
+_addTest(function(canvas, ctx) {
+
+_assertSame(canvas.width, 50, "canvas.width", "50");
+_assertSame(canvas.height, 30, "canvas.height", "30");
+
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.style.png b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.style.png
new file mode 100644
index 000000000..eeedd0ff0
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/size.attributes.style.png
Binary files differ
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/toBlob.jpeg.html b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/toBlob.jpeg.html
new file mode 100644
index 000000000..37289fea2
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/toBlob.jpeg.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by tools/gentest.py. -->
+<title>Canvas test: toBlob.jpeg</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/canvas-tests.js"></script>
+<link rel="stylesheet" href="/common/canvas-tests.css">
+<body class="show_output">
+
+<h1>toBlob.jpeg</h1>
+<p class="desc">toBlob with image/jpeg returns a JPEG Blob</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("toBlob with image/jpeg returns a JPEG Blob");
+_addTest(function(canvas, ctx) {
+
+canvas.toBlob(function(data){
+ _assertSame(data.type, "image/jpeg", "data.type", "\"image/jpeg\"");
+}, 'image/jpeg');
+
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/toBlob.png.html b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/toBlob.png.html
new file mode 100644
index 000000000..80bc16c5a
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/toBlob.png.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by tools/gentest.py. -->
+<title>Canvas test: toBlob.png</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/canvas-tests.js"></script>
+<link rel="stylesheet" href="/common/canvas-tests.css">
+<body class="show_output">
+
+<h1>toBlob.png</h1>
+<p class="desc">toBlob with image/png returns a PNG Blob</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("toBlob with image/png returns a PNG Blob");
+_addTest(function(canvas, ctx) {
+
+canvas.toBlob(function(data){
+ _assertSame(data.type, "image/png", "data.type", "\"image/png\"");
+}, 'image/png');
+
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/toDataURL.arguments.1.html b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/toDataURL.arguments.1.html
new file mode 100644
index 000000000..969d4f538
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/toDataURL.arguments.1.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by tools/gentest.py. -->
+<title>Canvas test: toDataURL.arguments.1</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/canvas-tests.js"></script>
+<link rel="stylesheet" href="/common/canvas-tests.css">
+<body class="show_output">
+
+<h1>toDataURL.arguments.1</h1>
+<p class="desc">toDataURL ignores extra arguments</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("toDataURL ignores extra arguments");
+_addTest(function(canvas, ctx) {
+
+var data = canvas.toDataURL('image/png', 'another argument that should not raise an exception');
+assert_regexp_match(data, /^data:image\/png[;,]/);
+
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/toDataURL.arguments.2.html b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/toDataURL.arguments.2.html
new file mode 100644
index 000000000..378946608
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/toDataURL.arguments.2.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by tools/gentest.py. -->
+<title>Canvas test: toDataURL.arguments.2</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/canvas-tests.js"></script>
+<link rel="stylesheet" href="/common/canvas-tests.css">
+<body class="show_output">
+
+<h1>toDataURL.arguments.2</h1>
+<p class="desc">toDataURL ignores extra arguments</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("toDataURL ignores extra arguments");
+_addTest(function(canvas, ctx) {
+
+var data = canvas.toDataURL('image/png', 'another argument that should not raise an exception', 'and another');
+assert_regexp_match(data, /^data:image\/png[;,]/);
+
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/toDataURL.arguments.3.html b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/toDataURL.arguments.3.html
new file mode 100644
index 000000000..236aba5ff
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/toDataURL.arguments.3.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by tools/gentest.py. -->
+<title>Canvas test: toDataURL.arguments.3</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/canvas-tests.js"></script>
+<link rel="stylesheet" href="/common/canvas-tests.css">
+<body class="show_output">
+
+<h1>toDataURL.arguments.3</h1>
+<p class="desc">toDataURL ignores extra arguments</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("toDataURL ignores extra arguments");
+_addTest(function(canvas, ctx) {
+
+// More arguments that should not raise exceptions
+var data = canvas.toDataURL('image/png', null, null, null);
+assert_regexp_match(data, /^data:image\/png[;,]/);
+
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/toDataURL.bogustype.html b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/toDataURL.bogustype.html
new file mode 100644
index 000000000..ade95f0ac
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/toDataURL.bogustype.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by tools/gentest.py. -->
+<title>Canvas test: toDataURL.bogustype</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/canvas-tests.js"></script>
+<link rel="stylesheet" href="/common/canvas-tests.css">
+<body class="show_output">
+
+<h1>toDataURL.bogustype</h1>
+<p class="desc">toDataURL with a syntactically invalid type returns a PNG</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("toDataURL with a syntactically invalid type returns a PNG");
+_addTest(function(canvas, ctx) {
+
+var data = canvas.toDataURL('bogus');
+assert_regexp_match(data, /^data:image\/png[;,]/);
+
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/toDataURL.default.html b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/toDataURL.default.html
new file mode 100644
index 000000000..84f4c9ed4
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/toDataURL.default.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by tools/gentest.py. -->
+<title>Canvas test: toDataURL.default</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/canvas-tests.js"></script>
+<link rel="stylesheet" href="/common/canvas-tests.css">
+<body class="show_output">
+
+<h1>toDataURL.default</h1>
+<p class="desc">toDataURL with no arguments returns a PNG</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("toDataURL with no arguments returns a PNG");
+_addTest(function(canvas, ctx) {
+
+var data = canvas.toDataURL();
+assert_regexp_match(data, /^data:image\/png[;,]/);
+
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/toDataURL.jpeg.alpha.html b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/toDataURL.jpeg.alpha.html
new file mode 100644
index 000000000..80a2fca42
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/toDataURL.jpeg.alpha.html
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by tools/gentest.py. -->
+<title>Canvas test: toDataURL.jpeg.alpha</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/canvas-tests.js"></script>
+<link rel="stylesheet" href="/common/canvas-tests.css">
+<body class="show_output">
+
+<h1>toDataURL.jpeg.alpha</h1>
+<p class="desc">toDataURL with JPEG composites onto black</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="toDataURL.jpeg.alpha.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("toDataURL with JPEG composites onto black");
+_addTest(function(canvas, ctx) {
+
+ctx.fillStyle = 'rgba(128, 255, 128, 0.5)';
+ctx.fillRect(0, 0, 100, 50);
+ctx.globalCompositeOperation = 'destination-over'; // should be ignored by toDataURL
+var data = canvas.toDataURL('image/jpeg');
+ctx.globalCompositeOperation = 'source-over';
+if (!data.match(/^data:image\/jpeg[;,]/)) {
+ _assert(true, "true");
+} else {
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ var img = new Image();
+ deferTest();
+ img.onload = t.step_func_done(function ()
+ {
+ ctx.drawImage(img, 0, 0);
+ _assertPixelApprox(canvas, 50,25, 63,127,63,255, "50,25", "63,127,63,255", 8);
+ });
+ img.src = data;
+}
+
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/toDataURL.jpeg.alpha.png b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/toDataURL.jpeg.alpha.png
new file mode 100644
index 000000000..551871295
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/toDataURL.jpeg.alpha.png
Binary files differ
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/toDataURL.jpeg.primarycolours.html b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/toDataURL.jpeg.primarycolours.html
new file mode 100644
index 000000000..a896cbb5c
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/toDataURL.jpeg.primarycolours.html
@@ -0,0 +1,48 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by tools/gentest.py. -->
+<title>Canvas test: toDataURL.jpeg.primarycolours</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/canvas-tests.js"></script>
+<link rel="stylesheet" href="/common/canvas-tests.css">
+<body class="show_output">
+
+<h1>toDataURL.jpeg.primarycolours</h1>
+<p class="desc">toDataURL with JPEG handles simple colours correctly</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="toDataURL.jpeg.primarycolours.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("toDataURL with JPEG handles simple colours correctly");
+_addTest(function(canvas, ctx) {
+
+ctx.fillStyle = '#ff0';
+ctx.fillRect(0, 0, 25, 40);
+ctx.fillStyle = '#0ff';
+ctx.fillRect(25, 0, 50, 40);
+ctx.fillStyle = '#00f';
+ctx.fillRect(75, 0, 25, 40);
+ctx.fillStyle = '#fff';
+ctx.fillRect(0, 40, 100, 10);
+var data = canvas.toDataURL('image/jpeg'); // it is okay if this returns a PNG instead
+ctx.fillStyle = '#f00';
+ctx.fillRect(0, 0, 100, 50);
+var img = new Image();
+deferTest();
+img.onload = t.step_func_done(function ()
+{
+ ctx.drawImage(img, 0, 0);
+ _assertPixelApprox(canvas, 12,20, 255,255,0,255, "12,20", "255,255,0,255", 8);
+ _assertPixelApprox(canvas, 50,20, 0,255,255,255, "50,20", "0,255,255,255", 8);
+ _assertPixelApprox(canvas, 87,20, 0,0,255,255, "87,20", "0,0,255,255", 8);
+ _assertPixelApprox(canvas, 50,45, 255,255,255,255, "50,45", "255,255,255,255", 8);
+});
+img.src = data;
+
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/toDataURL.jpeg.primarycolours.png b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/toDataURL.jpeg.primarycolours.png
new file mode 100644
index 000000000..cfd136900
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/toDataURL.jpeg.primarycolours.png
Binary files differ
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/toDataURL.jpeg.quality.basic.html b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/toDataURL.jpeg.quality.basic.html
new file mode 100644
index 000000000..aad56cdd5
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/toDataURL.jpeg.quality.basic.html
@@ -0,0 +1,56 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by tools/gentest.py. -->
+<title>Canvas test: toDataURL.jpeg.quality.basic</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/canvas-tests.js"></script>
+<link rel="stylesheet" href="/common/canvas-tests.css">
+<body class="show_output">
+
+<h1>toDataURL.jpeg.quality.basic</h1>
+<p class="desc">toDataURL with JPEG uses the quality parameter</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="toDataURL.jpeg.quality.basic.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("toDataURL with JPEG uses the quality parameter");
+_addTest(function(canvas, ctx) {
+
+ctx.fillStyle = '#00f';
+ctx.fillRect(0, 0, 100, 50);
+ctx.fillStyle = '#0ff';
+ctx.fillRect(0, 3, 100, 1);
+// Check for JPEG support first
+var data = canvas.toDataURL('image/jpeg');
+if (!data.match(/^data:image\/jpeg[;,]/)) {
+ _assert(true, "true");
+} else {
+ var data_hi = canvas.toDataURL('image/jpeg', 0.99);
+ var data_lo = canvas.toDataURL('image/jpeg', 0.01);
+ ctx.fillStyle = '#f00';
+ ctx.fillRect(0, 0, 100, 50);
+ deferTest();
+ var img_hi = new Image();
+ img_hi.onload = function ()
+ {
+ var img_lo = new Image();
+ img_lo.onload = t.step_func_done(function ()
+ {
+ ctx.drawImage(img_hi, 0, 0, 50, 50, 0, 0, 50, 50);
+ ctx.drawImage(img_lo, 0, 0, 50, 50, 50, 0, 50, 50);
+ _assert(data_hi.length > data_lo.length, "data_hi.length > data_lo.length");
+ _assertPixelApprox(canvas, 25,25, 0,0,255,255, "25,25", "0,0,255,255", 8);
+ _assertPixelApprox(canvas, 75,25, 0,0,255,255, "75,25", "0,0,255,255", 32);
+ });
+ img_lo.src = data_lo;
+ };
+ img_hi.src = data_hi;
+}
+
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/toDataURL.jpeg.quality.basic.png b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/toDataURL.jpeg.quality.basic.png
new file mode 100644
index 000000000..2f8a0bc79
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/toDataURL.jpeg.quality.basic.png
Binary files differ
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/toDataURL.jpeg.quality.notnumber.html b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/toDataURL.jpeg.quality.notnumber.html
new file mode 100644
index 000000000..3167e3c09
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/toDataURL.jpeg.quality.notnumber.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by tools/gentest.py. -->
+<title>Canvas test: toDataURL.jpeg.quality.notnumber</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/canvas-tests.js"></script>
+<link rel="stylesheet" href="/common/canvas-tests.css">
+<body class="show_output">
+
+<h1>toDataURL.jpeg.quality.notnumber</h1>
+<p class="desc">toDataURL with JPEG handles non-numeric quality parameters</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("toDataURL with JPEG handles non-numeric quality parameters");
+_addTest(function(canvas, ctx) {
+
+ctx.fillStyle = '#00f';
+ctx.fillRect(0, 0, 100, 50);
+ctx.fillStyle = '#0ff';
+ctx.fillRect(0, 3, 100, 1);
+// Check for JPEG support first
+var data = canvas.toDataURL('image/jpeg');
+if (!data.match(/^data:image\/jpeg[;,]/)) {
+ _assert(true, "true");
+} else {
+ _assertSame(canvas.toDataURL('image/jpeg', 'bogus'), data, "canvas.toDataURL('image/jpeg', 'bogus')", "data");
+ _assertSame(canvas.toDataURL('image/jpeg', {}), data, "canvas.toDataURL('image/jpeg', {})", "data");
+ _assertSame(canvas.toDataURL('image/jpeg', null), data, "canvas.toDataURL('image/jpeg', null)", "data");
+ _assertSame(canvas.toDataURL('image/jpeg', undefined), data, "canvas.toDataURL('image/jpeg', undefined)", "data");
+ _assertSame(canvas.toDataURL('image/jpeg', true), data, "canvas.toDataURL('image/jpeg', true)", "data");
+ _assertSame(canvas.toDataURL('image/jpeg', '0.01'), data, "canvas.toDataURL('image/jpeg', '0.01')", "data");
+}
+
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/toDataURL.jpeg.quality.outsiderange.html b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/toDataURL.jpeg.quality.outsiderange.html
new file mode 100644
index 000000000..885dc99b8
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/toDataURL.jpeg.quality.outsiderange.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by tools/gentest.py. -->
+<title>Canvas test: toDataURL.jpeg.quality.outsiderange</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/canvas-tests.js"></script>
+<link rel="stylesheet" href="/common/canvas-tests.css">
+<body class="show_output">
+
+<h1>toDataURL.jpeg.quality.outsiderange</h1>
+<p class="desc">toDataURL with JPEG handles out-of-range quality parameters</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("toDataURL with JPEG handles out-of-range quality parameters");
+_addTest(function(canvas, ctx) {
+
+ctx.fillStyle = '#00f';
+ctx.fillRect(0, 0, 100, 50);
+ctx.fillStyle = '#0ff';
+ctx.fillRect(0, 3, 100, 1);
+// Check for JPEG support first
+var data = canvas.toDataURL('image/jpeg');
+if (!data.match(/^data:image\/jpeg[;,]/)) {
+ _assert(true, "true");
+} else {
+ _assertSame(canvas.toDataURL('image/jpeg', 10), data, "canvas.toDataURL('image/jpeg', 10)", "data");
+ _assertSame(canvas.toDataURL('image/jpeg', -10), data, "canvas.toDataURL('image/jpeg', -10)", "data");
+ _assertSame(canvas.toDataURL('image/jpeg', 1.01), data, "canvas.toDataURL('image/jpeg', 1.01)", "data");
+ _assertSame(canvas.toDataURL('image/jpeg', -0.01), data, "canvas.toDataURL('image/jpeg', -0.01)", "data");
+
+ _assert(canvas.toDataURL('image/jpeg', 1).length >= canvas.toDataURL('image/jpeg', 0.9).length, "canvas.toDataURL('image/jpeg', 1).length >= canvas.toDataURL('image/jpeg', 0.9).length");
+ _assert(canvas.toDataURL('image/jpeg', 0).length <= canvas.toDataURL('image/jpeg', 0.1).length, "canvas.toDataURL('image/jpeg', 0).length <= canvas.toDataURL('image/jpeg', 0.1).length");
+}
+
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/toDataURL.jpg.html b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/toDataURL.jpg.html
new file mode 100644
index 000000000..df12aeebc
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/toDataURL.jpg.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by tools/gentest.py. -->
+<title>Canvas test: toDataURL.jpg</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/canvas-tests.js"></script>
+<link rel="stylesheet" href="/common/canvas-tests.css">
+<body class="show_output">
+
+<h1>toDataURL.jpg</h1>
+<p class="desc">toDataURL with image/jpg is invalid type hence returns a PNG</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("toDataURL with image/jpg is invalid type hence returns a PNG");
+_addTest(function(canvas, ctx) {
+
+var data = canvas.toDataURL('image/jpg');
+assert_regexp_match(data, /^data:image\/png[;,]/);
+
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/toDataURL.lowercase.ascii.html b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/toDataURL.lowercase.ascii.html
new file mode 100644
index 000000000..b95c8285b
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/toDataURL.lowercase.ascii.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by tools/gentest.py. -->
+<title>Canvas test: toDataURL.lowercase.ascii</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/canvas-tests.js"></script>
+<link rel="stylesheet" href="/common/canvas-tests.css">
+<body class="show_output">
+
+<h1>toDataURL.lowercase.ascii</h1>
+<p class="desc">toDataURL type is case-insensitive</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("toDataURL type is case-insensitive");
+_addTest(function(canvas, ctx) {
+
+var data = canvas.toDataURL('ImAgE/PnG');
+assert_regexp_match(data, /^data:image\/png[;,]/);
+
+// If JPEG is supported at all, it must be supported case-insensitively
+data = canvas.toDataURL('image/jpeg');
+if (data.match(/^data:image\/jpeg[;,]/)) {
+ data = canvas.toDataURL('ImAgE/JpEg');
+ assert_regexp_match(data, /^data:image\/jpeg[;,]/);
+}
+
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/toDataURL.lowercase.unicode.html b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/toDataURL.lowercase.unicode.html
new file mode 100644
index 000000000..ab06d59ec
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/toDataURL.lowercase.unicode.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by tools/gentest.py. -->
+<title>Canvas test: toDataURL.lowercase.unicode</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/canvas-tests.js"></script>
+<link rel="stylesheet" href="/common/canvas-tests.css">
+<body class="show_output">
+
+<h1>toDataURL.lowercase.unicode</h1>
+<p class="desc">toDataURL type is ASCII-case-insensitive</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("toDataURL type is ASCII-case-insensitive");
+_addTest(function(canvas, ctx) {
+
+// Use LATIN CAPITAL LETTER I WITH DOT ABOVE (Unicode lowercase is "i")
+var data = canvas.toDataURL('\u0130mage/png');
+assert_regexp_match(data, /^data:image\/png[;,]/);
+
+var data = canvas.toDataURL('\u0130mage/jpeg');
+assert_regexp_match(data, /^data:image\/png[;,]/);
+
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/toDataURL.nocontext.html b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/toDataURL.nocontext.html
new file mode 100644
index 000000000..07fb85dc8
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/toDataURL.nocontext.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by tools/gentest.py. -->
+<title>Canvas test: toDataURL.nocontext</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/canvas-tests.js"></script>
+<link rel="stylesheet" href="/common/canvas-tests.css">
+<body class="show_output">
+
+<h1>toDataURL.nocontext</h1>
+<p class="desc">toDataURL works before any context has been got</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("toDataURL works before any context has been got");
+_addTest(function(canvas, ctx) {
+ var no_context_data = canvas.toDataURL();
+ var ctx = canvas.getContext('2d');
+ ctx.rect(0, 0, 100, 50);
+ ctx.fillStyle = "rgba(0, 0, 0, 0)";
+ ctx.fill();
+ var data = canvas.toDataURL();
+ assert_equals(no_context_data, data);
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/toDataURL.png.complexcolours.html b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/toDataURL.png.complexcolours.html
new file mode 100644
index 000000000..cc067b737
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/toDataURL.png.complexcolours.html
@@ -0,0 +1,48 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by tools/gentest.py. -->
+<title>Canvas test: toDataURL.png.complexcolours</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/canvas-tests.js"></script>
+<link rel="stylesheet" href="/common/canvas-tests.css">
+<body class="show_output">
+
+<h1>toDataURL.png.complexcolours</h1>
+<p class="desc">toDataURL with PNG handles non-primary and non-solid colours correctly</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="toDataURL.png.complexcolours.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("toDataURL with PNG handles non-primary and non-solid colours correctly");
+_addTest(function(canvas, ctx) {
+
+// (These values are chosen to survive relatively alright through being premultiplied)
+ctx.fillStyle = 'rgba(1, 3, 254, 1)';
+ctx.fillRect(0, 0, 25, 25);
+ctx.fillStyle = 'rgba(8, 252, 248, 0.75)';
+ctx.fillRect(25, 0, 25, 25);
+ctx.fillStyle = 'rgba(6, 10, 250, 0.502)';
+ctx.fillRect(50, 0, 25, 25);
+ctx.fillStyle = 'rgba(12, 16, 244, 0.25)';
+ctx.fillRect(75, 0, 25, 25);
+var img = new Image();
+deferTest();
+img.onload = t.step_func_done(function ()
+{
+ ctx.drawImage(img, 0, 25);
+ // (The alpha values do not really survive float->int conversion, so just
+ // do approximate comparisons)
+ _assertPixel(canvas, 12,40, 1,3,254,255, "12,40", "1,3,254,255");
+ _assertPixelApprox(canvas, 37,40, 8,252,248,191, "37,40", "8,252,248,191", 2);
+ _assertPixelApprox(canvas, 62,40, 6,10,250,127, "62,40", "6,10,250,127", 4);
+ _assertPixelApprox(canvas, 87,40, 12,16,244,63, "87,40", "12,16,244,63", 8);
+});
+img.src = canvas.toDataURL();
+
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/toDataURL.png.complexcolours.png b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/toDataURL.png.complexcolours.png
new file mode 100644
index 000000000..9bc814658
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/toDataURL.png.complexcolours.png
Binary files differ
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/toDataURL.png.html b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/toDataURL.png.html
new file mode 100644
index 000000000..39917eb23
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/toDataURL.png.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by tools/gentest.py. -->
+<title>Canvas test: toDataURL.png</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/canvas-tests.js"></script>
+<link rel="stylesheet" href="/common/canvas-tests.css">
+<body class="show_output">
+
+<h1>toDataURL.png</h1>
+<p class="desc">toDataURL with image/png returns a PNG</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("toDataURL with image/png returns a PNG");
+_addTest(function(canvas, ctx) {
+
+var data = canvas.toDataURL('image/png');
+assert_regexp_match(data, /^data:image\/png[;,]/);
+
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/toDataURL.png.primarycolours.html b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/toDataURL.png.primarycolours.html
new file mode 100644
index 000000000..b962821d7
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/toDataURL.png.primarycolours.html
@@ -0,0 +1,48 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by tools/gentest.py. -->
+<title>Canvas test: toDataURL.png.primarycolours</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/canvas-tests.js"></script>
+<link rel="stylesheet" href="/common/canvas-tests.css">
+<body class="show_output">
+
+<h1>toDataURL.png.primarycolours</h1>
+<p class="desc">toDataURL with PNG handles simple colours correctly</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+<p class="output expectedtext">Expected output:<p><img src="toDataURL.png.primarycolours.png" class="output expected" id="expected" alt="">
+<ul id="d"></ul>
+<script>
+var t = async_test("toDataURL with PNG handles simple colours correctly");
+_addTest(function(canvas, ctx) {
+
+ctx.fillStyle = '#ff0';
+ctx.fillRect(0, 0, 25, 40);
+ctx.fillStyle = '#0ff';
+ctx.fillRect(25, 0, 50, 40);
+ctx.fillStyle = '#00f';
+ctx.fillRect(75, 0, 25, 40);
+ctx.fillStyle = '#fff';
+ctx.fillRect(0, 40, 100, 10);
+var data = canvas.toDataURL();
+ctx.fillStyle = '#f00';
+ctx.fillRect(0, 0, 100, 50);
+var img = new Image();
+deferTest();
+img.onload = t.step_func_done(function ()
+{
+ ctx.drawImage(img, 0, 0);
+ _assertPixel(canvas, 12,20, 255,255,0,255, "12,20", "255,255,0,255");
+ _assertPixel(canvas, 50,20, 0,255,255,255, "50,20", "0,255,255,255");
+ _assertPixel(canvas, 87,20, 0,0,255,255, "87,20", "0,0,255,255");
+ _assertPixel(canvas, 50,45, 255,255,255,255, "50,45", "255,255,255,255");
+});
+img.src = data;
+
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/toDataURL.png.primarycolours.png b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/toDataURL.png.primarycolours.png
new file mode 100644
index 000000000..cfd136900
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/toDataURL.png.primarycolours.png
Binary files differ
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/toDataURL.unrecognised.html b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/toDataURL.unrecognised.html
new file mode 100644
index 000000000..3526cc3a2
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/toDataURL.unrecognised.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by tools/gentest.py. -->
+<title>Canvas test: toDataURL.unrecognised</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/canvas-tests.js"></script>
+<link rel="stylesheet" href="/common/canvas-tests.css">
+<body class="show_output">
+
+<h1>toDataURL.unrecognised</h1>
+<p class="desc">toDataURL with an unhandled type returns a PNG</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("toDataURL with an unhandled type returns a PNG");
+_addTest(function(canvas, ctx) {
+
+var data = canvas.toDataURL('image/example');
+assert_regexp_match(data, /^data:image\/png[;,]/);
+
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/toDataURL.zeroheight.html b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/toDataURL.zeroheight.html
new file mode 100644
index 000000000..04c113216
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/toDataURL.zeroheight.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by tools/gentest.py. -->
+<title>Canvas test: toDataURL.zeroheight</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/canvas-tests.js"></script>
+<link rel="stylesheet" href="/common/canvas-tests.css">
+<body class="show_output">
+
+<h1>toDataURL.zeroheight</h1>
+<p class="desc">toDataURL on zero-size canvas returns 'data:,'</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" height="0"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("toDataURL on zero-size canvas returns 'data:,'");
+_addTest(function(canvas, ctx) {
+
+var data = canvas.toDataURL();
+_assertSame(data, 'data:,', "data", "'data:,'");
+
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/toDataURL.zerosize.html b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/toDataURL.zerosize.html
new file mode 100644
index 000000000..7d2913d02
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/toDataURL.zerosize.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by tools/gentest.py. -->
+<title>Canvas test: toDataURL.zerosize</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/canvas-tests.js"></script>
+<link rel="stylesheet" href="/common/canvas-tests.css">
+<body class="show_output">
+
+<h1>toDataURL.zerosize</h1>
+<p class="desc">toDataURL on zero-size canvas returns 'data:,'</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="0" height="0"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("toDataURL on zero-size canvas returns 'data:,'");
+_addTest(function(canvas, ctx) {
+
+var data = canvas.toDataURL();
+_assertSame(data, 'data:,', "data", "'data:,'");
+
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/toDataURL.zerowidth.html b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/toDataURL.zerowidth.html
new file mode 100644
index 000000000..d4020aa51
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/toDataURL.zerowidth.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by tools/gentest.py. -->
+<title>Canvas test: toDataURL.zerowidth</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/canvas-tests.js"></script>
+<link rel="stylesheet" href="/common/canvas-tests.css">
+<body class="show_output">
+
+<h1>toDataURL.zerowidth</h1>
+<p class="desc">toDataURL on zero-size canvas returns 'data:,'</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="0"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("toDataURL on zero-size canvas returns 'data:,'");
+_addTest(function(canvas, ctx) {
+
+var data = canvas.toDataURL();
+_assertSame(data, 'data:,', "data", "'data:,'");
+
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/type.delete.html b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/type.delete.html
new file mode 100644
index 000000000..98b67b909
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/type.delete.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by tools/gentest.py. -->
+<title>Canvas test: type.delete</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/canvas-tests.js"></script>
+<link rel="stylesheet" href="/common/canvas-tests.css">
+<body class="show_output">
+
+<h1>type.delete</h1>
+<p class="desc">window.HTMLCanvasElement interface object is [[Configurable]]</p>
+
+<p class="notes">Defined in "Web IDL" (draft)
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("window.HTMLCanvasElement interface object is [[Configurable]]");
+_addTest(function(canvas, ctx) {
+
+_assertSame(delete window.HTMLCanvasElement, true, "delete window.HTMLCanvasElement", "true");
+_assertSame(window.HTMLCanvasElement, undefined, "window.HTMLCanvasElement", "undefined");
+
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/type.exists.html b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/type.exists.html
new file mode 100644
index 000000000..04aa97570
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/type.exists.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by tools/gentest.py. -->
+<title>Canvas test: type.exists</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/canvas-tests.js"></script>
+<link rel="stylesheet" href="/common/canvas-tests.css">
+<body class="show_output">
+
+<h1>type.exists</h1>
+<p class="desc">HTMLCanvasElement is a property of window</p>
+
+<p class="notes">Defined in "Web IDL" (draft)
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("HTMLCanvasElement is a property of window");
+_addTest(function(canvas, ctx) {
+
+_assert(window.HTMLCanvasElement, "window.HTMLCanvasElement");
+
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/type.extend.html b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/type.extend.html
new file mode 100644
index 000000000..572273083
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/type.extend.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by tools/gentest.py. -->
+<title>Canvas test: type.extend</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/canvas-tests.js"></script>
+<link rel="stylesheet" href="/common/canvas-tests.css">
+<body class="show_output">
+
+<h1>type.extend</h1>
+<p class="desc">HTMLCanvasElement methods can be added, and the new methods used by canvases</p>
+
+<p class="notes">Defined in "Web IDL" (draft)
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("HTMLCanvasElement methods can be added, and the new methods used by canvases");
+_addTest(function(canvas, ctx) {
+
+window.HTMLCanvasElement.prototype.getZero = function () { return 0; };
+_assertSame(canvas.getZero(), 0, "canvas.getZero()", "0");
+
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/type.name.html b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/type.name.html
new file mode 100644
index 000000000..a514effaa
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/type.name.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by tools/gentest.py. -->
+<title>Canvas test: type.name</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/canvas-tests.js"></script>
+<link rel="stylesheet" href="/common/canvas-tests.css">
+<body class="show_output">
+
+<h1>type.name</h1>
+<p class="desc">HTMLCanvasElement type and toString</p>
+
+
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("HTMLCanvasElement type and toString");
+_addTest(function(canvas, ctx) {
+
+_assertSame(Object.prototype.toString.call(canvas), '[object HTMLCanvasElement]', "Object.prototype.toString.call(canvas)", "'[object HTMLCanvasElement]'");
+
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/type.prototype.html b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/type.prototype.html
new file mode 100644
index 000000000..029a9fbbd
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/type.prototype.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by tools/gentest.py. -->
+<title>Canvas test: type.prototype</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/canvas-tests.js"></script>
+<link rel="stylesheet" href="/common/canvas-tests.css">
+<body class="show_output">
+
+<h1>type.prototype</h1>
+<p class="desc">window.HTMLCanvasElement has prototype, which is { ReadOnly, DontDelete }. prototype has getContext, which is not</p>
+
+<p class="notes">Defined in "Web IDL" (draft)
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("window.HTMLCanvasElement has prototype, which is { ReadOnly, DontDelete }. prototype has getContext, which is not");
+_addTest(function(canvas, ctx) {
+
+_assert(window.HTMLCanvasElement.prototype, "window.HTMLCanvasElement.prototype");
+_assert(window.HTMLCanvasElement.prototype.getContext, "window.HTMLCanvasElement.prototype.getContext");
+window.HTMLCanvasElement.prototype = null;
+_assert(window.HTMLCanvasElement.prototype, "window.HTMLCanvasElement.prototype");
+delete window.HTMLCanvasElement.prototype;
+_assert(window.HTMLCanvasElement.prototype, "window.HTMLCanvasElement.prototype");
+window.HTMLCanvasElement.prototype.getContext = 1;
+_assertSame(window.HTMLCanvasElement.prototype.getContext, 1, "window.HTMLCanvasElement.prototype.getContext", "1");
+delete window.HTMLCanvasElement.prototype.getContext;
+_assertSame(window.HTMLCanvasElement.prototype.getContext, undefined, "window.HTMLCanvasElement.prototype.getContext", "undefined");
+
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/type.replace.html b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/type.replace.html
new file mode 100644
index 000000000..70a08066e
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-canvas-element/type.replace.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<!-- DO NOT EDIT! This test has been generated by tools/gentest.py. -->
+<title>Canvas test: type.replace</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/canvas-tests.js"></script>
+<link rel="stylesheet" href="/common/canvas-tests.css">
+<body class="show_output">
+
+<h1>type.replace</h1>
+<p class="desc">HTMLCanvasElement methods can be replaced, and the replacement methods used by canvases</p>
+
+<p class="notes">Defined in "Web IDL" (draft)
+<p class="output">Actual output:</p>
+<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
+
+<ul id="d"></ul>
+<script>
+var t = async_test("HTMLCanvasElement methods can be replaced, and the replacement methods used by canvases");
+_addTest(function(canvas, ctx) {
+
+window.HTMLCanvasElement.prototype.getContext = function (name) { return 0; };
+_assertSame(canvas.getContext('2d'), 0, "canvas.getContext('2d')", "0");
+
+
+});
+</script>
+
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-embed-element/.gitkeep b/testing/web-platform/tests/html/semantics/embedded-content/the-embed-element/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-embed-element/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-embed-element/embed-dimension.html b/testing/web-platform/tests/html/semantics/embedded-content/the-embed-element/embed-dimension.html
new file mode 100644
index 000000000..608ed331c
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-embed-element/embed-dimension.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>HTML Test: dimension</title>
+<link rel="author" title="Intel" href="http://www.intel.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#the-embed-element">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<embed src="/images/blue.png" height="100" width="100" id="test">
+<script>
+ test(function () {
+ var height = getComputedStyle(document.getElementById("test"), false)["height"];
+ assert_equals(height, "100px", "The height of the embed element should be 100px.");
+ }, "Check the actual length of the embed element's height");
+
+ test(function () {
+ var width = getComputedStyle(document.getElementById("test"), false)["width"];
+ assert_equals(width, "100px", "The width of the embed element should be 100px.");
+ }, "Check the actual length of the embed element's width");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-embed-element/embed-document.html b/testing/web-platform/tests/html/semantics/embedded-content/the-embed-element/embed-document.html
new file mode 100644
index 000000000..3d44678cf
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-embed-element/embed-document.html
@@ -0,0 +1,17 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>HTML Test: The embed element represents a document</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<meta name="assert" content="Check if the embed element represents a document when a text/html resource source is used">
+<body>
+ <script type="application/javascript">
+ window.childLoaded = false;
+ async_test(function() {
+ addEventListener("load", this.step_func_done(function() {
+ assert_true(window.childLoaded);
+ }));
+ }, "Test document type embedding");
+ </script>
+ <embed src="embed-iframe.html">
+</body>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-embed-element/embed-iframe.html b/testing/web-platform/tests/html/semantics/embedded-content/the-embed-element/embed-iframe.html
new file mode 100644
index 000000000..f9b1bfdb5
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-embed-element/embed-iframe.html
@@ -0,0 +1,7 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<body>
+ <script type="application/javascript">
+ parent.childLoaded = true;
+ </script>
+</body>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-embed-element/embed-ignored-in-media-element.html b/testing/web-platform/tests/html/semantics/embedded-content/the-embed-element/embed-ignored-in-media-element.html
new file mode 100644
index 000000000..d29d520f0
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-embed-element/embed-ignored-in-media-element.html
@@ -0,0 +1,22 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>HTML Test: The embed element represents a document</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<meta name="assert" content="Check if the embed element is ignored when used inside a media element">
+<script type="application/javascript">
+ window.childLoaded = false;
+ async_test(function() {
+ addEventListener("load", this.step_func_done(function() {
+ assert_false(window.childLoaded);
+ }));
+ }, "Test embed being ignored inside media element");
+</script>
+<body>
+ <video>
+ <embed type="text/html" src="embed-iframe.html" />
+ </video>
+ <audio>
+ <embed type="text/html" src="embed-iframe.html" />
+ </audio>
+</body>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-embed-element/embed-in-object-fallback-subdocument.html b/testing/web-platform/tests/html/semantics/embedded-content/the-embed-element/embed-in-object-fallback-subdocument.html
new file mode 100644
index 000000000..a2c2a9399
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-embed-element/embed-in-object-fallback-subdocument.html
@@ -0,0 +1,4 @@
+<script>
+ var varName = location.search.substr(1);
+ parent[varName] = true;
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-embed-element/embed-in-object-fallback.html b/testing/web-platform/tests/html/semantics/embedded-content/the-embed-element/embed-in-object-fallback.html
new file mode 100644
index 000000000..52fa01b91
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-embed-element/embed-in-object-fallback.html
@@ -0,0 +1,38 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Ensure that embed elements inside object elements load when the objects
+ fall back but not otherwise</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script>
+ var child1Loaded = false;
+ var child2Loaded = false;
+ var child3Loaded = false;
+ var parent3Loaded = false;
+</script>
+<object>
+ <embed src="embed-in-object-fallback-subdocument.html?child1Loaded">
+</object>
+<object>
+ <embed id="two" src="embed-in-object-fallback-subdocument.html?child2Loaded">
+ <!-- Something that forces the embed to be in the tree before the <object>
+ is done parsing -->
+ <script>
+ test(function() {
+ assert_equals(document.getElementById("two").localName,
+ "embed");
+ }, "We have the right embed element");
+ </script>
+</object>
+<object data="embed-in-object-fallback-subdocument.html?parent3Loaded">
+ <embed src="embed-in-object-fallback-subdocument.html?child3Loaded">
+</object>
+<script>
+ var t = async_test("Check that the right things loaded");
+ onload = t.step_func_done(function() {
+ assert_true(child1Loaded, "child 1 should load");
+ assert_true(child2Loaded, "child 2 should load");
+ assert_false(child3Loaded, "child 3 should not load");
+ assert_true(parent3Loaded, "parent 3 should load");
+ });
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-embed-element/embed-represent-nothing-01.html b/testing/web-platform/tests/html/semantics/embedded-content/the-embed-element/embed-represent-nothing-01.html
new file mode 100644
index 000000000..e66bd4a90
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-embed-element/embed-represent-nothing-01.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>HTML Test: The embed element without src and type attributes represents nothing</title>
+<link rel="author" title="Intel" href="http://www.intel.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#the-embed-element">
+<link rel="match" href="embed-represent-nothing-ref.html">
+<meta name="assert" content="Check if the embed element without src and type attributes represents nothing">
+<style>
+ embed {
+ background-color: red;
+ height: 100px;
+ width: 100px;
+ }
+</style>
+<body>
+ <p>Test passes if there is <strong>no red</strong>.</p>
+ <embed>
+</body>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-embed-element/embed-represent-nothing-02.html b/testing/web-platform/tests/html/semantics/embedded-content/the-embed-element/embed-represent-nothing-02.html
new file mode 100644
index 000000000..65cd67238
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-embed-element/embed-represent-nothing-02.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>HTML Test: The embed element represents nothing when its type and src attributs are removed</title>
+<link rel="author" title="Intel" href="http://www.intel.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#the-embed-element">
+<link rel="match" href="embed-represent-nothing-ref.html">
+<meta name="assert" content="Check if the embed element represents nothing when its src and type attributes are removed">
+<style>
+ embed {
+ background-color: red;
+ height: 100px;
+ width: 100px;
+ }
+</style>
+<body>
+ <p>Test passes if there is <strong>no red</strong>.</p>
+ <embed id="embed" src="/images/red-16x16.png" type="image/png">
+ <script>
+ document.getElementById("embed").removeAttribute("src");
+ document.getElementById("embed").removeAttribute("type");
+ </script>
+</body>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-embed-element/embed-represent-nothing-03.html b/testing/web-platform/tests/html/semantics/embedded-content/the-embed-element/embed-represent-nothing-03.html
new file mode 100644
index 000000000..a16f3794a
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-embed-element/embed-represent-nothing-03.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>HTML Test: The embed element represents nothing when it has a media ancestor</title>
+<link rel="author" title="Intel" href="http://www.intel.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#the-embed-element">
+<link rel="match" href="embed-represent-nothing-ref.html">
+<meta name="assert" content="Check if the embed element represents nothing when it has a media ancestor">
+<style>
+ embed {
+ background-color: red;
+ height: 100px;
+ width: 100px;
+ }
+</style>
+<body>
+ <p>Test passes if there is <strong>no red</strong>.</p>
+ <video>
+ <embed src="/images/red-16x16.png">
+ </video>
+</body>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-embed-element/embed-represent-nothing-04.html b/testing/web-platform/tests/html/semantics/embedded-content/the-embed-element/embed-represent-nothing-04.html
new file mode 100644
index 000000000..7cc1b668a
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-embed-element/embed-represent-nothing-04.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>HTML Test: The embed element represents nothing when it has an object ancestor</title>
+<link rel="author" title="Intel" href="http://www.intel.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#the-embed-element">
+<link rel="match" href="embed-represent-nothing-ref.html">
+<meta name="assert" content="Check if the embed element represents nothing when it has a object ancestor that is not showing its fallback content">
+<style>
+ embed {
+ background-color: red;
+ height: 100px;
+ width: 100px;
+ }
+</style>
+<body>
+ <p>Test passes if there is <strong>no red</strong>.</p>
+ <object type="application/x-shockwave-flash">
+ <embed src="/images/red-16x16.png">
+ </object>
+</body>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-embed-element/embed-represent-nothing-ref.html b/testing/web-platform/tests/html/semantics/embedded-content/the-embed-element/embed-represent-nothing-ref.html
new file mode 100644
index 000000000..91d680deb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-embed-element/embed-represent-nothing-ref.html
@@ -0,0 +1,7 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>Embed Reftest Reference</title>
+<link rel="author" title="Intel" href="http://www.intel.com">
+<body>
+ <p>Test passes if there is <strong>no red</strong>.</p>
+</body>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/.gitkeep b/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/change_child.html b/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/change_child.html
new file mode 100644
index 000000000..738ceee52
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/change_child.html
@@ -0,0 +1,14 @@
+<body>
+ Child.
+ <iframe id="grandchild" src="change_grandchild.html"></iframe>
+</body>
+<script>
+ var timer = window.setInterval(poll, 100);
+ function poll() {
+ if (document.body.getAttribute("data-contains-grandchild")) {
+ var grandchild = document.getElementById("grandchild");
+ window.frameElement.parentNode.appendChild(grandchild);
+ window.clearTimeout(timer);
+ }
+ }
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/change_grandchild.html b/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/change_grandchild.html
new file mode 100644
index 000000000..885622c2b
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/change_grandchild.html
@@ -0,0 +1,4 @@
+<body>Grandchild.</body>
+<script>
+ window.frameElement.parentNode.setAttribute("data-contains-grandchild", true);
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/change_parentage.html b/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/change_parentage.html
new file mode 100644
index 000000000..1d62ccc48
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/change_parentage.html
@@ -0,0 +1,22 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>Change the frame heriarchy</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<body>
+ <iframe src="change_child.html"></iframe>
+</body>
+<script>
+ async_test(function(t) {
+ var timer = window.setInterval(t.step_func(poll), 100);
+ function poll() {
+ // We wait for the grandchild's script to set the custom attribtue.
+ // Note that if this test passes, the grandchild's script must have been run twice,
+ // once to trigger the move from the child to here, and once to pass this test.
+ if (document.body.getAttribute("data-contains-grandchild")) {
+ window.clearTimeout(timer);
+ t.done();
+ }
+ }
+ });
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/cross_origin_child.html b/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/cross_origin_child.html
new file mode 100644
index 000000000..8b44fe805
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/cross_origin_child.html
@@ -0,0 +1,12 @@
+<script src="iframe_harness.js"></script>
+<body>
+ <iframe src="cross_origin_grandchild.html"></iframe>
+</body>
+<script>
+ send_test_results({
+ "id": '79a52de8-4222-427e-92db-caec28e75f8e',
+ "parent": window.parent !== window,
+ "grandparent": window.parent.parent === window.parent,
+ "top": window.top === window.parent,
+ });
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/cross_origin_grandchild.html b/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/cross_origin_grandchild.html
new file mode 100644
index 000000000..1eff64af1
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/cross_origin_grandchild.html
@@ -0,0 +1,11 @@
+<script src="iframe_harness.js"></script>
+<body>
+</body>
+<script>
+ send_test_results({
+ "id": '6c8da65d-2c5e-44ef-bb0b-b8b9849aab19',
+ "parent": window.parent !== window,
+ "grandparent": window.parent.parent !== window.parent,
+ "top": window.top === window.parent.parent,
+ });
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/cross_origin_parentage.html b/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/cross_origin_parentage.html
new file mode 100644
index 000000000..cd27b8ea7
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/cross_origin_parentage.html
@@ -0,0 +1,19 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>Check the frame heriarchy</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="iframe_harness.js"></script>
+<body>
+ <iframe src="http://www1.web-platform.test:8000/html/semantics/embedded-content/the-iframe-element/cross_origin_child.html"></iframe>
+</body>
+<script>
+ get_test_results('bffa23ee-b45a-4e9a-9405-87ab437d5cfa');
+ get_test_results('79a52de8-4222-427e-92db-caec28e75f8e');
+ get_test_results('6c8da65d-2c5e-44ef-bb0b-b8b9849aab19');
+ send_test_results({
+ "id": 'bffa23ee-b45a-4e9a-9405-87ab437d5cfa',
+ "parent": window.parent === window,
+ "top": window.top === window,
+ });
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/historical.html b/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/historical.html
new file mode 100644
index 000000000..850a52f46
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/historical.html
@@ -0,0 +1,16 @@
+<!doctype html>
+<title>Historical iframe element features should not be supported</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+function t(property) {
+ test(function() {
+ assert_false(property in document.createElement('iframe'));
+ }, 'iframe.' + property + ' should not be supported');
+}
+
+// added in https://github.com/whatwg/html/commit/f6490f17f577fa3478791b29ad8c2b586418001f
+// removed in https://github.com/whatwg/html/commit/1490eba4dba5ab476f0981443a86c01acae01311
+t('seamless');
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/iframe-allowfullscreen.html b/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/iframe-allowfullscreen.html
new file mode 100644
index 000000000..da5791a2d
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/iframe-allowfullscreen.html
@@ -0,0 +1,55 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Check how allowfullscreen affects fullscreen enabled flag</title>
+<link rel="author" title="Xidorn Quan" href="https://www.upsuper.org">
+<link rel="author" title="Mozilla" href="https://www.mozilla.org">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/browsers.html#initialise-the-document-object">
+<link rel="help" href="https://fullscreen.spec.whatwg.org/#fullscreen-enabled-flag">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<div id="log"></div>
+<script>
+ async_test(function(t) {
+ var iframe = document.createElement("iframe");
+ iframe.src = "support/blank.htm";
+ var eventWatcher = new EventWatcher(t, iframe, "load");
+ document.body.appendChild(iframe);
+ t.add_cleanup(function() {
+ document.body.removeChild(iframe);
+ });
+
+ assert_true(document.fullscreenEnabled, "Top level document has fullscreen enabled flag set");
+ eventWatcher.wait_for("load").then(t.step_func_done(function() {
+ assert_false(iframe.contentDocument.fullscreenEnabled, "Document inside iframe without allowfullscreen attribute should not have fullscreen enabled flag set");
+ iframe.setAttribute("allowfullscreen", true);
+ assert_true(iframe.contentDocument.fullscreenEnabled, "Fullscreen should be allowed when allowfullscreen attribute is set");
+ iframe.removeAttribute("allowfullscreen");
+ assert_false(iframe.contentDocument.fullscreenEnabled, "Fullscreen should be denied when allowfullscreen attribute is removed");
+ }));
+ }, "iframe-allowfullscreen");
+
+ /* Fullscreen enabled flag with about:blank */
+
+ function test_allowfullscreen_noload(setup_iframe, check) {
+ var iframe = document.createElement("iframe");
+ setup_iframe(iframe);
+ document.body.appendChild(iframe);
+ check(iframe.contentDocument);
+ document.body.removeChild(iframe);
+ }
+
+ test(function() {
+ test_allowfullscreen_noload(function() {}, function(doc) {
+ assert_false(doc.fullscreenEnabled, "Fullscreen should not be enabled without allowfullscreen attribute");
+ });
+ }, "iframe-noload-noallowfullscreen");
+
+ test(function() {
+ test_allowfullscreen_noload(function(iframe) {
+ iframe.setAttribute("allowfullscreen", true);
+ }, function(doc) {
+ assert_true(doc.fullscreenEnabled, "Fullscreen should be enabled with allowfullscreen attribute");
+ });
+ }, "iframe-noload-allowfullscreen");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/iframe-append-to-child-document.html b/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/iframe-append-to-child-document.html
new file mode 100644
index 000000000..ac8bd5e05
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/iframe-append-to-child-document.html
@@ -0,0 +1,17 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Append iframe element to its own child document</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<iframe id=x></iframe>
+<script>
+test(function() {
+ var iframe = document.getElementById('x');
+ var childWindow = iframe.contentWindow;
+ assert_equals(childWindow.parent, window);
+ childWindow.document.body.appendChild(iframe);
+ assert_equals(childWindow.parent, null);
+ assert_equals(iframe.contentWindow, null);
+ assert_equals(childWindow.document.body.firstChild, iframe);
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/iframe-load-event.html b/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/iframe-load-event.html
new file mode 100644
index 000000000..d245bf0b9
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/iframe-load-event.html
@@ -0,0 +1,48 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Test some sanity behavior around iframe load/error events</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<body>
+<script>
+async_test(function(t) {
+ var obj = document.createElement("iframe");
+ obj.onload = t.step_func_done(function(e){
+ assert_true(obj.contentWindow instanceof Window, "The iframe element should represent a nested browsing context.")
+ assert_equals(Object.getPrototypeOf(e).constructor, Event, "The load event should use the Event interface.");
+ assert_true(e.isTrusted, "The load event should be a trusted event.");
+ assert_false(e.cancelable, "The load event should not be a cancelable event.");
+ assert_false(e.bubbles, "The load event should not be a bubble event.");
+ assert_equals(e.target, obj, "The load event target should be the corresponding object element.");
+ });
+
+ obj.onerror = t.step_func_done(function(e){
+ assert_unreached("The error event should not be fired.");
+ });
+
+ var url = URL.createObjectURL(new Blob([""], { type: "text/html" }));
+
+ obj.src = url;
+ document.body.appendChild(obj);
+}, "load event of blob URL");
+
+async_test(function(t) {
+ var obj = document.createElement("iframe");
+ obj.onload = t.step_func_done(function(e){
+ assert_true(obj.contentWindow instanceof Window, "The object element should represent a nested browsing context.")
+ assert_equals(Object.getPrototypeOf(e).constructor, Event, "The load event should use the Event interface.");
+ assert_true(e.isTrusted, "The load event should be a trusted event.");
+ assert_false(e.cancelable, "The load event should not be a cancelable event.");
+ assert_false(e.bubbles, "The load event should not be a bubble event.");
+ assert_equals(e.target, obj, "The load event target should be the corresponding object element.");
+ });
+
+ obj.onerror = t.step_func_done(function(e){
+ assert_unreached("The error event should not be fired.");
+ });
+
+ document.body.appendChild(obj);
+}, "load event of initial about:blank");
+
+</script>
+</body>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/iframe-with-base-ref.html b/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/iframe-with-base-ref.html
new file mode 100644
index 000000000..21f11d195
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/iframe-with-base-ref.html
@@ -0,0 +1,9 @@
+<!doctype html>
+<html>
+<head>
+ <title>iframe Without Base Tag</title>
+</head>
+<body>
+ <iframe src="support/blank.htm">
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/iframe-with-base.html b/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/iframe-with-base.html
new file mode 100644
index 000000000..4637a41a4
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/iframe-with-base.html
@@ -0,0 +1,11 @@
+<!doctype html>
+<html>
+<head>
+ <title>iframe With Base Tag</title>
+ <link rel="match" href="iframe-with-base-ref.html">
+ <base href="support/">
+</head>
+<body>
+ <iframe src="blank.htm">
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/iframe_harness.js b/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/iframe_harness.js
new file mode 100644
index 000000000..f4ef511d1
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/iframe_harness.js
@@ -0,0 +1,26 @@
+function get_test_results(id) {
+ async_test(function(test) {
+ var timer = window.setInterval(test.step_func(loop), 100);
+ function loop() {
+ var xhr = new XMLHttpRequest();
+ xhr.open('GET', 'stash.py?id=' + id);
+ xhr.onreadystatechange = test.step_func(function() {
+ assert_equals(xhr.status, 200);
+ if (xhr.responseText) {
+ assert_equals(xhr.responseText, "OK");
+ test.done();
+ window.clearTimeout(timer);
+ }
+ });
+ xhr.send();
+ }
+ });
+}
+
+function send_test_results(results) {
+ var ok = true;
+ for (result in results) { ok = ok && results[result]; }
+ var xhr = new XMLHttpRequest();
+ xhr.open('POST', 'stash.py?id=' + results.id);
+ xhr.send(ok ? "OK" : "FAIL: " + JSON.stringify(results));
+}
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/iframe_javascript_url_01.htm b/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/iframe_javascript_url_01.htm
new file mode 100644
index 000000000..d6c2abe7d
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/iframe_javascript_url_01.htm
@@ -0,0 +1,53 @@
+<!DOCTYPE html><html><head><title>javascript: URL creating a document in an about:blank iframe</title>
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#the-iframe-element">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#process-the-iframe-attributes">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+</head>
+<body>
+<div id="log">FAILED (test did not run)</div>
+
+<iframe src="about:blank" name="ifr1"></iframe>
+<iframe src="" name="ifr2"></iframe>
+<iframe src="./" name="ifr3"></iframe>
+
+<script>
+var test = async_test();
+var results = {};
+var expected = {
+ ifr1:{url:"about:blank", sameDom: true},
+ ifr2:{url:"about:blank", sameDom: true},
+ ifr3:{url: location.href.replace(/\/[^\/]*$/, '/'), sameDom: true },
+ ifr4:{url:"about:blank", sameDom: true}
+}
+
+var js_url = 'javascript:"<html><script>var sameDom = false; try{var cn = top.document.body.className;sameDom = true;}catch(e){}; parent.postMessage( {url: document.URL, name: name, sameDom: sameDom}, \'*\')<\/script><body><p>JS-generated document</p></body></<html>";'
+window.addEventListener('message', function(e){
+ var ifr = e.data.name;
+ results[ifr] = e.data;
+ test.step(function(){
+ assert_equals(results[ifr].url, expected[ifr].url);
+ assert_equals(results[ifr].sameDom, expected[ifr].sameDom);
+ }, 'Testing URL and details of IFRAME ' + ifr);
+ if(Object.keys(results).length === Object.keys(expected).length){
+ test.done();
+ }
+}, false);
+
+var ifr = document.createElement('iframe');
+ifr.name = 'ifr4';
+document.body.appendChild(ifr);
+
+window.onload = function () {
+ for (var i = 0, frame, frames = document.getElementsByTagName('iframe'); frame = frames[i]; i++) {
+ try{
+ frame.src = js_url;
+ }catch(e){
+ results[frame.name] = 'Exception on setting!';
+ }
+ };
+}
+
+</script>
+</body>
+</html> \ No newline at end of file
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_allow_script.html b/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_allow_script.html
new file mode 100644
index 000000000..cd05f2246
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_allow_script.html
@@ -0,0 +1,46 @@
+<!DOCTYPE html>
+<meta charset="uft-8">
+<title>HTML Test: iframe_sandbox_allow_scripts</title>
+<link rel="author" title="Intel" href="http://www.intel.com/">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#attr-iframe-sandbox">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#the-iframe-element">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<div id="log"></div>
+<script>
+ // Set up all our script stuff before the iframe starts loading, so we don't
+ // miss any messages from it.
+ var step1 = false;
+ var t = async_test("iframe_sandbox_allow_scripts");
+
+ setup({timeout:1000});
+ window.addEventListener("message", callback1, false);
+
+ function run() {
+ window.removeEventListener("message", callback1, false);
+ document.getElementById("testIframe").sandbox = "allow-scripts";
+ document.getElementById("testIframe").contentWindow.location.reload();
+ window.addEventListener("message", callback2, false);
+ }
+
+ function callback1(e) {
+ step1= !step1;
+ }
+
+ function callback2(e) {
+ t.step(function () {
+ assert_false(step1, "[allow-scripts] is not set.");
+ assert_equals(e.data, "Script executed", "[allow-scripts] is set.");
+ });
+ t.done();
+ }
+
+ // Make sure the iframe loads before we mess with it.
+ window.addEventListener("load", function() {
+ // The load event might fire before a message from the child comes in...
+ // Wait a bit to see if that message does come in.
+ setTimeout(run, 500);
+ });
+</script>
+<iframe id="testIframe" src="support/sandbox_allow_script.html" sandbox="allow-same-origin" style="display:none"></iframe>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_escaping-1.html b/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_escaping-1.html
new file mode 100644
index 000000000..342d42203
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_escaping-1.html
@@ -0,0 +1,25 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Check that popups from a sandboxed iframe escape the sandbox if
+ allow-popups-to-escape-sandbox is used</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<iframe sandbox="allow-scripts allow-popups allow-popups-to-escape-sandbox">
+</iframe>
+<script>
+ var t = async_test();
+ var ourOrigin;
+ onmessage = t.step_func(function(e) {
+ assert_equals(e.data, "hello", "This is our origin getter message");
+ ourOrigin = e.origin;
+
+ onmessage = t.step_func_done(function(e) {
+ assert_equals(e.origin, "null", "It came from a sandboxed iframe");
+ assert_equals(e.data.data, undefined, "Should have the right message");
+ assert_equals(e.data.origin, ourOrigin, "Should have escaped the sandbox");
+ });
+
+ document.querySelector("iframe").src = "iframe_sandbox_popups_helper-1.html";
+ });
+ postMessage("hello", "*");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_escaping-2.html b/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_escaping-2.html
new file mode 100644
index 000000000..40ffbb1e0
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_escaping-2.html
@@ -0,0 +1,31 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Check that popups from a sandboxed iframe escape the sandbox if
+ allow-popups-to-escape-sandbox is used</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<iframe sandbox="allow-scripts allow-popups allow-popups-to-escape-sandbox">
+</iframe>
+<script>
+ var t = async_test();
+ var ourOrigin;
+ onmessage = t.step_func(function(e) {
+ assert_equals(e.data, "hello", "This is our origin getter message");
+ ourOrigin = e.origin;
+
+ onmessage = t.step_func_done(function(e) {
+ assert_equals(e.origin, "null", "It came from a sandboxed iframe");
+ assert_equals(e.data.data, undefined, "Should have the right message");
+ assert_equals(e.data.origin, ourOrigin, "Should have escaped the sandbox");
+ });
+
+ var iframe = document.querySelector("iframe");
+ iframe.onload = function() {
+ frames[0].postMessage("start", "*");
+ }
+ iframe.src = "iframe_sandbox_popups_helper-2.html";
+ });
+ addEventListener("load", function() {
+ postMessage("hello", "*");
+ });
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_escaping-3.html b/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_escaping-3.html
new file mode 100644
index 000000000..2d35fd5fc
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_escaping-3.html
@@ -0,0 +1,25 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Check that popups from a sandboxed iframe escape the sandbox if
+ allow-popups-to-escape-sandbox is used</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<iframe sandbox="allow-scripts allow-popups allow-popups-to-escape-sandbox">
+</iframe>
+<script>
+ var t = async_test();
+ var ourOrigin;
+ onmessage = t.step_func(function(e) {
+ assert_equals(e.data, "hello", "This is our origin getter message");
+ ourOrigin = e.origin;
+
+ onmessage = t.step_func_done(function(e) {
+ assert_equals(e.origin, "null", "It came from a sandboxed iframe");
+ assert_equals(e.data.data, undefined, "Should have the right message");
+ assert_equals(e.data.origin, ourOrigin, "Should have escaped the sandbox");
+ });
+
+ document.querySelector("iframe").src = "iframe_sandbox_popups_helper-3.html";
+ });
+ postMessage("hello", "*");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_helper-1.html b/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_helper-1.html
new file mode 100644
index 000000000..6b120f15d
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_helper-1.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<script>
+ if (opener) {
+ // We're the popup. Send back our state. What we really want to send is
+ // our origin, but that will come automatically.
+ opener.postMessage(undefined, "*");
+ self.close();
+ } else {
+ // We're the child. Start listening for messages and open ourselves as the
+ // popup.
+ onmessage = function (e) {
+ parent.postMessage({ data: e.data, origin: e.origin }, "*");
+ };
+ popupWin = window.open(location.href);
+ }
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_helper-2.html b/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_helper-2.html
new file mode 100644
index 000000000..9c393fc95
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_helper-2.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<body>
+<script>
+ if (opener) {
+ // We're the popup. Send back our state. What we really want to send is
+ // our origin, but that will come automatically.
+ opener.postMessage(undefined, "*");
+ self.close();
+ } else {
+ // We're the child. Start listening for messages from our parent and open
+ // ourselves as the popup when we get the "start" message.
+ onmessage = function (e) {
+ if (e.data == "start") {
+ // Now listen for messages from the thing we plan to open.
+ onmessage = function(e) {
+ parent.postMessage({ data: e.data, origin: e.origin }, "*");
+ }
+
+ var a = document.createElement("a");
+ a.href = location.href;
+ a.target = "_blank";
+ document.body.appendChild(a);
+ a.click();
+ }
+ };
+ }
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_helper-3.html b/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_helper-3.html
new file mode 100644
index 000000000..ef3e59037
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_helper-3.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<script>
+ if (opener) {
+ // We're the popup. Send back our state. What we really want to send is
+ // our origin, but that will come automatically.
+ opener.postMessage(undefined, "*");
+ self.close();
+ } else {
+ // We're the child. Start listening for messages and open ourselves as the
+ // popup.
+ onmessage = function (e) {
+ parent.postMessage({ data: e.data, origin: e.origin }, "*");
+ };
+ var popupWin = window.open();
+ popupWin.location.href = location.href;
+ }
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_nonescaping-1.html b/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_nonescaping-1.html
new file mode 100644
index 000000000..3dee96d67
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_nonescaping-1.html
@@ -0,0 +1,15 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Check that popups from a sandboxed iframe do not escape the sandbox</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script>
+ var t = async_test();
+ onmessage = t.step_func_done(function(e) {
+ assert_equals(e.origin, "null", "It came from a sandboxed iframe");
+ assert_equals(e.data.data, undefined, "Should have the right message");
+ assert_equals(e.data.origin, "null", "Should not have escaped the sandbox");
+ });
+</script>
+<iframe sandbox="allow-scripts allow-popups"
+ src="iframe_sandbox_popups_helper-1.html"></iframe>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_nonescaping-2.html b/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_nonescaping-2.html
new file mode 100644
index 000000000..27046db74
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_nonescaping-2.html
@@ -0,0 +1,18 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Check that popups from a sandboxed iframe do not escape the sandbox</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script>
+ var t = async_test();
+ onmessage = t.step_func_done(function(e) {
+ assert_equals(e.origin, "null", "It came from a sandboxed iframe");
+ assert_equals(e.data.data, undefined, "Should have the right message");
+ assert_equals(e.data.origin, "null", "Should not have escaped the sandbox");
+ });
+ addEventListener("load", function() {
+ frames[0].postMessage("start", "*");
+ });
+</script>
+<iframe sandbox="allow-scripts allow-popups"
+ src="iframe_sandbox_popups_helper-2.html"></iframe>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_nonescaping-3.html b/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_nonescaping-3.html
new file mode 100644
index 000000000..556387e14
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_nonescaping-3.html
@@ -0,0 +1,15 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Check that popups from a sandboxed iframe do not escape the sandbox</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script>
+ var t = async_test();
+ onmessage = t.step_func_done(function(e) {
+ assert_equals(e.origin, "null", "It came from a sandboxed iframe");
+ assert_equals(e.data.data, undefined, "Should have the right message");
+ assert_equals(e.data.origin, "null", "Should not have escaped the sandbox");
+ });
+</script>
+<iframe sandbox="allow-scripts allow-popups"
+ src="iframe_sandbox_popups_helper-3.html"></iframe>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/move_iframe_in_dom_01.html b/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/move_iframe_in_dom_01.html
new file mode 100644
index 000000000..efd563f51
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/move_iframe_in_dom_01.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<title>moving modified IFRAME in document (original page about:blank, DOM modification)</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<link rel="help" href="https://html.spec.whatwg.org/#iframe-load-event-steps">
+<iframe src="about:blank"></iframe>
+<div id="target"></div>
+<script>
+onload = function() {
+ var ifr = document.getElementsByTagName('iframe')[0];
+ ifr.contentDocument.body.appendChild(ifr.contentDocument.createElement('p')).textContent = 'Modified document';
+ setTimeout(function() {
+ ifr.onload = function() {
+ assert_equals(ifr.contentDocument.body.textContent.indexOf('Modified'), -1);
+ done();
+ };
+ document.getElementById('target').appendChild(ifr);
+ }, 100);
+}
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/move_iframe_in_dom_02.html b/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/move_iframe_in_dom_02.html
new file mode 100644
index 000000000..dbe266b29
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/move_iframe_in_dom_02.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<title>moving modified IFRAME in document (original page about:blank, document.write modification)</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<link rel="help" href="https://html.spec.whatwg.org/#iframe-load-event-steps">
+<iframe src="about:blank"></iframe>
+<div id="target"></div>
+<script>
+onload = function() {
+ var ifr = document.getElementsByTagName('iframe')[0];
+ ifr.contentDocument.open();
+ ifr.contentDocument.write('Modified document');
+ ifr.contentDocument.close();
+ setTimeout(function() {
+ ifr.onload = function() {
+ assert_equals(ifr.contentDocument.body.textContent.indexOf('Modified'), -1);
+ done();
+ };
+ document.getElementById('target').appendChild(ifr);
+ }, 100);
+}
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/move_iframe_in_dom_03.html b/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/move_iframe_in_dom_03.html
new file mode 100644
index 000000000..c07dd42dc
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/move_iframe_in_dom_03.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<title>moving modified IFRAME in document (original page from server, DOM modification)</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<link rel="help" href="https://html.spec.whatwg.org/#iframe-load-event-steps">
+<iframe src="support/blank.htm"></iframe>
+<div id="target"></div>
+<script>
+onload = function() {
+ var ifr = document.getElementsByTagName('iframe')[0];
+ ifr.contentDocument.body.appendChild(ifr.contentDocument.createElement('p')).textContent = 'Modified document';
+ setTimeout(function() {
+ ifr.onload = function() {
+ assert_equals(ifr.contentDocument.body.textContent.indexOf('Modified'), -1);
+ done();
+ };
+ document.getElementById('target').appendChild(ifr);
+ }, 100);
+}
+</script> \ No newline at end of file
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/move_iframe_in_dom_04.html b/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/move_iframe_in_dom_04.html
new file mode 100644
index 000000000..755cd45d3
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/move_iframe_in_dom_04.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<title>moving modified IFRAME in document (original page from server, document.write modification)</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<link rel="help" href="https://html.spec.whatwg.org/#iframe-load-event-steps">
+<iframe src="support/blank.htm"></iframe>
+<div id="target"></div>
+<script>
+onload = function(){
+ var ifr = document.getElementsByTagName('iframe')[0];
+ ifr.contentDocument.open();
+ ifr.contentDocument.write('Modified document');
+ ifr.contentDocument.close();
+ setTimeout(function() {
+ ifr.onload = function () {
+ assert_equals(ifr.contentDocument.body.textContent.indexOf('Modified'), -1);
+ done();
+ };
+ document.getElementById('target').appendChild(ifr);
+ }, 100);
+}
+</script> \ No newline at end of file
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/same_origin_child.html b/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/same_origin_child.html
new file mode 100644
index 000000000..a36e231fa
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/same_origin_child.html
@@ -0,0 +1,12 @@
+<script src="iframe_harness.js"></script>
+<body>
+ <iframe src="same_origin_grandchild.html"></iframe>
+</body>
+<script>
+ send_test_results({
+ "id": '08782f28-e313-47ae-8cd7-419f3e194b0a',
+ "parent": window.parent !== window,
+ "grandparent": window.parent.parent === window.parent,
+ "top": window.top === window.parent,
+ });
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/same_origin_grandchild.html b/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/same_origin_grandchild.html
new file mode 100644
index 000000000..e7a2293b7
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/same_origin_grandchild.html
@@ -0,0 +1,11 @@
+<script src="iframe_harness.js"></script>
+<body>
+</body>
+<script>
+ send_test_results({
+ "id": '66de8d44-7da7-47c7-9a52-41cba4f22bfe',
+ "parent": window.parent !== window,
+ "grandparent": window.parent.parent !== window.parent,
+ "top": window.top === window.parent.parent,
+ });
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/same_origin_parentage.html b/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/same_origin_parentage.html
new file mode 100644
index 000000000..a163eb8ee
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/same_origin_parentage.html
@@ -0,0 +1,19 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>Check the frame heriarchy</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="iframe_harness.js"></script>
+<body>
+ <iframe src="same_origin_child.html"></iframe>
+</body>
+<script>
+ get_test_results('17381dae-9c3e-4661-9f2b-28eb07a5f2fc');
+ get_test_results('08782f28-e313-47ae-8cd7-419f3e194b0a');
+ get_test_results('66de8d44-7da7-47c7-9a52-41cba4f22bfe');
+ send_test_results({
+ "id": '17381dae-9c3e-4661-9f2b-28eb07a5f2fc',
+ "parent": window.parent === window,
+ "top": window.top === window,
+ });
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/stash.py b/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/stash.py
new file mode 100644
index 000000000..0b8693a90
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/stash.py
@@ -0,0 +1,10 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+def main(request, response):
+ if request.method == 'POST':
+ request.server.stash.put(request.GET["id"], request.body)
+ return ''
+ return request.server.stash.take(request.GET["id"])
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/support/blank.htm b/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/support/blank.htm
new file mode 100644
index 000000000..6c70bcfe4
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/support/blank.htm
@@ -0,0 +1 @@
+<html></html> \ No newline at end of file
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/support/sandbox_allow_script.html b/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/support/sandbox_allow_script.html
new file mode 100644
index 000000000..95c30dec1
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-iframe-element/support/sandbox_allow_script.html
@@ -0,0 +1,8 @@
+<!DOCTYPE html>
+<meta charset="uft-8">
+<title>HTML Test: sandbox_allow_scripts</title>
+<link rel="author" title="Intel" href="http://www.intel.com/">
+<div id="test">Before change</div>
+<script>
+ parent.window.postMessage("Script executed", "*");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-img-element/.gitkeep b/testing/web-platform/tests/html/semantics/embedded-content/the-img-element/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-img-element/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-img-element/3.jpg b/testing/web-platform/tests/html/semantics/embedded-content/the-img-element/3.jpg
new file mode 100644
index 000000000..d30ac2ac3
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-img-element/3.jpg
Binary files differ
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-img-element/Image-constructor.html b/testing/web-platform/tests/html/semantics/embedded-content/the-img-element/Image-constructor.html
new file mode 100644
index 000000000..1119f818f
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-img-element/Image-constructor.html
@@ -0,0 +1,29 @@
+<!DOCTYPE HTML>
+<title>DOM Image constructor Test</title>
+<meta content="text/html; charset=UTF-8" http-equiv="Content-Type">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#the-img-element" />
+<meta name="assert" content="Tests the Image constructor for the img-element">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+
+<div id="log"></div>
+<script>
+ test(function() {
+ var img = new Image();
+ assert_true(img != undefined);
+ }, "Image constructor works");
+
+ test(function() {
+ assert_true(Image.prototype === HTMLImageElement.prototype);
+ }, "Image and HTMLImageElement share a prototype");
+
+ test(function() {
+ assert_true((new Image()).localName === "img");
+ }, "Image localName is img");
+
+ test(function() {
+ assert_true((new Image()).namespaceURI === "http://www.w3.org/1999/xhtml");
+ }, "Image namespace URI is correct");
+
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-img-element/brokenimg.jpg b/testing/web-platform/tests/html/semantics/embedded-content/the-img-element/brokenimg.jpg
new file mode 100644
index 000000000..ccff177ae
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-img-element/brokenimg.jpg
@@ -0,0 +1,4 @@
+<!DOCTYPE HTML>
+<html>
+
+</html> \ No newline at end of file
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-img-element/contains.json b/testing/web-platform/tests/html/semantics/embedded-content/the-img-element/contains.json
new file mode 100644
index 000000000..9ac6d3d42
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-img-element/contains.json
@@ -0,0 +1,60 @@
+[
+ {
+ "id": "alt",
+ "original_id": "alt",
+ "children": [
+ {
+ "id": "general-guidelines",
+ "original_id": "general-guidelines"
+ },
+ {
+ "id": "a-link-or-button-containing-nothing-but-the-image",
+ "original_id": "a-link-or-button-containing-nothing-but-the-image"
+ },
+ {
+ "id": "a-phrase-or-paragraph-with-an-alternative-graphical-representation-charts-diagrams-graphs-maps-illustrations",
+ "original_id": "a-phrase-or-paragraph-with-an-alternative-graphical-representation:-charts,-diagrams,-graphs,-maps,-illustrations"
+ },
+ {
+ "id": "a-short-phrase-or-label-with-an-alternative-graphical-representation-icons-logos",
+ "original_id": "a-short-phrase-or-label-with-an-alternative-graphical-representation:-icons,-logos"
+ },
+ {
+ "id": "text-that-has-been-rendered-to-a-graphic-for-typographical-effect",
+ "original_id": "text-that-has-been-rendered-to-a-graphic-for-typographical-effect"
+ },
+ {
+ "id": "a-graphical-representation-of-some-of-the-surrounding-text",
+ "original_id": "a-graphical-representation-of-some-of-the-surrounding-text"
+ },
+ {
+ "id": "a-purely-decorative-image-that-doesn-t-add-any-information",
+ "original_id": "a-purely-decorative-image-that-doesn't-add-any-information"
+ },
+ {
+ "id": "a-group-of-images-that-form-a-single-larger-picture-with-no-links",
+ "original_id": "a-group-of-images-that-form-a-single-larger-picture-with-no-links"
+ },
+ {
+ "id": "a-group-of-images-that-form-a-single-larger-picture-with-links",
+ "original_id": "a-group-of-images-that-form-a-single-larger-picture-with-links"
+ },
+ {
+ "id": "a-key-part-of-the-content",
+ "original_id": "a-key-part-of-the-content"
+ },
+ {
+ "id": "an-image-not-intended-for-the-user",
+ "original_id": "an-image-not-intended-for-the-user"
+ },
+ {
+ "id": "guidance-for-markup-generators",
+ "original_id": "guidance-for-markup-generators"
+ },
+ {
+ "id": "guidance-for-conformance-checkers",
+ "original_id": "guidance-for-conformance-checkers"
+ }
+ ]
+ }
+] \ No newline at end of file
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-img-element/current-pixel-density/basic.html b/testing/web-platform/tests/html/semantics/embedded-content/the-img-element/current-pixel-density/basic.html
new file mode 100644
index 000000000..f7d47b364
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-img-element/current-pixel-density/basic.html
@@ -0,0 +1,37 @@
+<!doctype html>
+<title>img current pixel density basic</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<img src="/images/green-256x256.png" data-expect="256">
+<img srcset="/images/green-256x256.png 1x" data-expect="256">
+<img srcset="/images/green-256x256.png 1.6x" data-expect="160">
+<img srcset="/images/green-256x256.png 2x" data-expect="128">
+<img srcset="/images/green-256x256.png 10000x" data-expect="0">
+<img srcset="/images/green-256x256.png 9e99999999999999999999999x" data-expect="0">
+<img srcset="/images/green-256x256.png 256w" sizes="256px" data-expect="256">
+<img srcset="/images/green-256x256.png 512w" sizes="256px" data-expect="128">
+<img srcset="/images/green-256x256.png 256w" sizes="512px" data-expect="512">
+<img srcset="/images/green-256x256.png 256w" sizes="1px" data-expect="1">
+<img srcset="/images/green-256x256.png 256w" sizes="0px" data-expect="0">
+<!-- SVG -->
+<img srcset="data:image/svg+xml,<svg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='-1%20-1%202%202'%20width='20'%20height='20'><circle%20r='1'/></svg> 2x" data-expect="10">
+<img srcset="data:image/svg+xml,<svg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='-1%20-1%202%202'%20width='20'><circle%20r='1'/></svg> 2x" data-expect="10">
+<img srcset="data:image/svg+xml,<svg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='-1%20-1%202%202'%20height='20'><circle%20r='1'/></svg> 2x" data-expect="10">
+<script>
+setup({explicit_done:true});
+onload = function() {
+ [].forEach.call(document.images, function(img) {
+ test(function() {
+ var expected = parseFloat(img.dataset.expect);
+ assert_equals(img.width, expected, 'width');
+ assert_equals(img.height, expected, 'height');
+ assert_equals(img.clientWidth, expected, 'clientWidth');
+ assert_equals(img.clientHeight, expected, 'clientHeight');
+ assert_equals(img.naturalWidth, expected, 'naturalWidth');
+ assert_equals(img.naturalHeight, expected, 'naturalHeight');
+ }, img.outerHTML);
+ });
+ done();
+};
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-img-element/current-pixel-density/error.html b/testing/web-platform/tests/html/semantics/embedded-content/the-img-element/current-pixel-density/error.html
new file mode 100644
index 000000000..5e328b5e2
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-img-element/current-pixel-density/error.html
@@ -0,0 +1,31 @@
+<!doctype html>
+<title>img current pixel density error</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<img id=ref src="404" alt="testing">
+<img srcset="404" alt="testing">
+<img srcset="404 0.5x" alt="testing">
+<img srcset="404 2x" alt="testing">
+<img srcset="404 100w" alt="testing">
+<img srcset="404 100w" sizes="500px" alt="testing">
+<picture><img src="404 100w" sizes="500px" alt="testing"></picture>
+<script>
+setup({explicit_done:true});
+onload = function() {
+ var ref = document.getElementById("ref");
+ var expected_width = ref.width;
+ var expected_height = ref.height;
+ [].forEach.call(document.images, function(img) {
+ test(function() {
+ assert_not_equals(expected_width, 0, 'expected_width');
+ assert_not_equals(expected_height, 0, 'expected_height');
+ assert_equals(img.width, expected_width, 'width');
+ assert_equals(img.height, expected_height, 'height');
+ assert_equals(img.naturalWidth, 0, 'naturalWidth');
+ assert_equals(img.naturalHeight, 0, 'naturalHeight');
+ }, img.outerHTML);
+ });
+ done();
+};
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-img-element/document-base-url-ref.html b/testing/web-platform/tests/html/semantics/embedded-content/the-img-element/document-base-url-ref.html
new file mode 100644
index 000000000..6e55b21ff
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-img-element/document-base-url-ref.html
@@ -0,0 +1,5 @@
+<!DOCTYPE HTML>
+<meta charset="utf-8">
+<title>Document base URL img test</title>
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#the-img-element" />
+<img src="resources/cat.jpg" alt="cat">
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-img-element/document-base-url.html b/testing/web-platform/tests/html/semantics/embedded-content/the-img-element/document-base-url.html
new file mode 100644
index 000000000..074209cc0
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-img-element/document-base-url.html
@@ -0,0 +1,7 @@
+<!DOCTYPE HTML>
+<meta charset="utf-8">
+<title>Document base URL img test</title>
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#the-img-element" />
+<link rel="match" href="document-base-url-ref.html">
+<base href="resources/" />
+<img src="cat.jpg" alt="cat">
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-img-element/environment-changes/iframed.sub.html b/testing/web-platform/tests/html/semantics/embedded-content/the-img-element/environment-changes/iframed.sub.html
new file mode 100644
index 000000000..0f7ab9ae2
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-img-element/environment-changes/iframed.sub.html
@@ -0,0 +1,78 @@
+<!doctype html>
+
+<img
+data-desc="img (no src)"
+data-narrow=""
+data-wide=""
+data-no-change>
+
+<img src=""
+data-desc="img (empty src)"
+data-narrow=""
+data-wide=""
+data-no-change>
+
+<img src="/images/broken.png?30-{{GET[id]}}"
+data-desc="img (src only) broken image"
+data-narrow="/images/broken.png?30-{{GET[id]}}"
+data-wide="/images/broken.png?30-{{GET[id]}}"
+data-no-change>
+
+<img src="/images/green-1x1.png?40-{{GET[id]}}"
+data-desc="img (src only) valid image"
+data-narrow="/images/green-1x1.png?40-{{GET[id]}}"
+data-wide="/images/green-1x1.png?40-{{GET[id]}}"
+data-no-change>
+
+<img srcset="/images/broken.png?50-{{GET[id]}}"
+data-desc="img (srcset 1 cand) broken image"
+data-narrow="/images/broken.png?50-{{GET[id]}}"
+data-wide="/images/broken.png?50-{{GET[id]}}"
+data-no-change>
+
+<img srcset="/images/green-1x1.png?60-{{GET[id]}}"
+data-desc="img (srcset 1 cand) valid image"
+data-narrow="/images/green-1x1.png?60-{{GET[id]}}"
+data-wide="/images/green-1x1.png?60-{{GET[id]}}"
+data-no-change>
+
+<picture>
+<source media="(max-width:500px)" srcset="/images/broken.png?70-{{GET[id]}}">
+<img src="/images/broken.png?71-{{GET[id]}}"
+data-desc="picture: source (max-width:500px) broken image, img broken image"
+data-narrow="/images/broken.png?70-{{GET[id]}}"
+data-wide="/images/broken.png?71-{{GET[id]}}">
+</picture>
+
+<picture>
+<source media="(max-width:500px)" srcset="/images/broken.png?80-{{GET[id]}}">
+<img src="/images/green-2x2.png?81-{{GET[id]}}"
+data-desc="picture: source (max-width:500px) broken image, img valid image"
+data-narrow="/images/broken.png?80-{{GET[id]}}"
+data-wide="/images/green-2x2.png?81-{{GET[id]}}">
+</picture>
+
+<picture>
+<source media="(max-width:500px)" srcset="/images/green-1x1.png?90-{{GET[id]}}">
+<img src="/images/broken.png?91-{{GET[id]}}"
+data-desc="picture: source (max-width:500px) valid image, img broken image"
+data-narrow="/images/green-1x1.png?90-{{GET[id]}}"
+data-wide="/images/broken.png?91-{{GET[id]}}">
+</picture>
+
+<picture>
+<source media="(max-width:500px)" srcset="/images/green-1x1.png?100-{{GET[id]}}">
+<img src="/images/green-2x2.png?101-{{GET[id]}}"
+data-desc="picture: source (max-width:500px) valid image, img valid image"
+data-narrow="/images/green-1x1.png?100-{{GET[id]}}"
+data-wide="/images/green-2x2.png?101-{{GET[id]}}">
+</picture>
+
+<picture>
+<source media="(max-width:500px)" srcset="/images/green-1x1.png?110-{{GET[id]}}">
+<img src="/images/green-1x1.png?110-{{GET[id]}}"
+data-desc="picture: same URL in source (max-width:500px) and img"
+data-narrow="/images/green-1x1.png?110-{{GET[id]}}"
+data-wide="/images/green-1x1.png?110-{{GET[id]}}"
+data-no-change>
+</picture>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-img-element/environment-changes/viewport-change.html b/testing/web-platform/tests/html/semantics/embedded-content/the-img-element/environment-changes/viewport-change.html
new file mode 100644
index 000000000..21624712c
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-img-element/environment-changes/viewport-change.html
@@ -0,0 +1,65 @@
+<!doctype html>
+<title>img viewport change</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/utils.js"></script>
+<style>
+.narrow { width:50px }
+.wide { width:1000px }
+</style>
+<div id=log></div>
+<script>
+setup({explicit_done:true});
+
+function resolve(url) {
+ if (url === "") {
+ return url;
+ }
+ var a = document.createElement('a');
+ a.href = url;
+ return a.href;
+}
+
+function insertIframe(className) {
+ var iframe = document.createElement('iframe');
+ iframe.className = className;
+ iframe.src = 'iframed.sub.html?id=' + token();
+ document.body.appendChild(iframe);
+}
+insertIframe('narrow');
+insertIframe('wide');
+
+var start_date = new Date();
+
+onload = function() {
+ var load_time = new Date() - start_date;
+ var iframes = document.getElementsByTagName('iframe');
+ [].forEach.call(iframes, function(iframe) {
+ [].forEach.call(iframe.contentDocument.images, function(img) {
+ var expected = {wide:resolve(img.dataset.wide), narrow:resolve(img.dataset.narrow)};
+ var current = iframe.className;
+ var next = current === 'wide' ? 'narrow' : 'wide';
+ var expect_change = expected[next].indexOf('broken.png') !== 0 && !('noChange' in img.dataset);
+
+ test(function() {
+ assert_equals(img.currentSrc, expected[current]);
+ }, img.dataset.desc + ', onload, ' + current);
+
+ async_test(function() {
+ img.onload = this.unreached_func('Got unexpected load event');
+ img.onerror = this.unreached_func('Got unexpected error event');
+ if (expect_change) {
+ img.onload = this.step_func_done(function() {
+ assert_equals(img.currentSrc, expected[next]);
+ });
+ } else {
+ setTimeout(this.step_func_done(), 500 + load_time);
+ }
+ }, img.dataset.desc + ', resize to ' + next);
+ });
+ iframe.classList.toggle('wide');
+ iframe.classList.toggle('narrow');
+ });
+ done();
+}
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-img-element/image-1.jpg b/testing/web-platform/tests/html/semantics/embedded-content/the-img-element/image-1.jpg
new file mode 100644
index 000000000..2fb025560
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-img-element/image-1.jpg
Binary files differ
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-img-element/image.png b/testing/web-platform/tests/html/semantics/embedded-content/the-img-element/image.png
new file mode 100644
index 000000000..d26878c9f
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-img-element/image.png
Binary files differ
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-img-element/img.complete.html b/testing/web-platform/tests/html/semantics/embedded-content/the-img-element/img.complete.html
new file mode 100644
index 000000000..a34010aad
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-img-element/img.complete.html
@@ -0,0 +1,82 @@
+<!DOCTYPE HTML>
+<title>DOM img complete Test</title>
+<meta content="text/html; charset=UTF-8" http-equiv="Content-Type">
+<link rel="author" title="Anselm Hannemann" href="http://anselm-hannemann.com/" />
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-img-complete" />
+<meta name="assert" content="Tests the complete status of the img-element">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<img id="imgTestTag">
+<img src="" id="imgTestTag2">
+<img id="imgTestTag3" style="width: 80px; height:auto;">
+<img id="imgTestTag4">
+
+<script>
+ var imageInstance = document.createElement('img');
+ imageInstance.style.display = 'none';
+
+ document.body.appendChild(imageInstance);
+</script>
+
+<div id="log"></div>
+<script>
+ test(function() {
+ assert_true(document.getElementById("imgTestTag").complete);
+ }, "img src omitted");
+
+ test(function() {
+ assert_true(document.getElementById("imgTestTag2").complete);
+ }, "img src empty");
+
+ // test if set to true after img is completely available
+ var t = async_test("async src complete test");
+
+ t.step(function(){
+ document.getElementById("imgTestTag3").src = '3.jpg?nocache=' + Math.random();
+
+ //test if img.complete is set to false if src is changed
+ assert_false(document.getElementById("imgTestTag3").complete, "src changed, should be set to false")
+ });
+
+ document.getElementById("imgTestTag3").onload = t.step_func(function(){
+ assert_true(document.getElementById("imgTestTag3").complete);
+ t.done();
+ });
+
+ // https://html.spec.whatwg.org/multipage/multipage/embedded-content-1.html#update-the-image-data
+ // says to "await a stable state" before fetching so we use a separate <script>
+ imageInstance.src = 'image-1.jpg?pipe=trickle(d1)&nocache=' + Math.random(); // make sure the image isn't in cache
+</script>
+<script>
+ // test: The final task that is queued by the networking task source once the resource has been fetched has been queued, but has not yet been run, and the img element is not in the broken state
+ async_test(function(t) {
+ assert_false(imageInstance.complete, "imageInstance.complete should be false");
+ var startTime = Date.now();
+ while (true) {
+ if (Date.now() - startTime > 2000)
+ assert_unreached('.complete didn\'t change to true');
+ if (imageInstance.complete === true) break;
+ }
+ t.done();
+ },
+ 'IDL attribute complete returns true when image resource has been fetched but not run yet & image is not in broken state');
+
+ // test if broken img does not pass
+ var t2 = async_test("async src broken test");
+ var img4 = document.getElementById("imgTestTag4");
+
+ t2.step(
+ function(){
+ img4.src = 'brokenimg.jpg';
+
+ //test if img.complete is set to false if src is changed
+ assert_false(img4.complete, "src changed to broken img, should be set to false");
+ });
+
+ img4.onload = img4.onerror = t2.step_func(function(event){
+ assert_equals(event.type, "error");
+ assert_true(img4.complete);
+ t2.done();
+ });
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-img-element/invalid-src.html b/testing/web-platform/tests/html/semantics/embedded-content/the-img-element/invalid-src.html
new file mode 100644
index 000000000..f1fbe34c5
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-img-element/invalid-src.html
@@ -0,0 +1,42 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>Loading a non-parsing URL as an image should silently fail; triggering appropriate events</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<img id=brokenurl />
+<img id=emptysrc />
+<script>
+async_test(function(t) {
+ var img = document.getElementById("brokenurl");
+ img.src = "http://also a broken url";
+ var errorevent = false;
+
+ // The errors should be queued in the event loop, so they should only trigger
+ // after this block of code finishes, not during the img.src setter itself
+ img.addEventListener('error', t.step_func(function(){errorevent = true;}));
+ img.addEventListener('loadend', t.step_func_done(function() {
+ assert_true(errorevent, "error event fired");
+ }));
+}, 'src="http://also a broken url"');
+
+async_test(function(t) {
+ var img = document.getElementById("emptysrc");
+ img.src = "";
+ var loadendevent = false;
+
+ // Setting src to empty string triggers only error event.
+ // The errors should be queued in the event loop, so they should only trigger
+ // after this block of code finishes, not during the img.src setter itself
+ img.addEventListener('error', t.step_func(function() {
+ // Queue this check in the event loop to check there is no loadend event
+ // fired.
+ t.step_timeout(t.step_func_done(function() {
+ assert_false(loadendevent, "loadend event should not fired");
+ }), 0)
+ }));
+ img.addEventListener('loadend', t.step_func(function() {
+ loadendevent = true;
+ }));
+}, 'src=""');
+
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-img-element/nonexistent-image.html b/testing/web-platform/tests/html/semantics/embedded-content/the-img-element/nonexistent-image.html
new file mode 100644
index 000000000..f58569ede
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-img-element/nonexistent-image.html
@@ -0,0 +1,21 @@
+<!DOCTYPE HTML>
+<meta charset="utf-8">
+<title>Loading an nonexisting image should fail; triggering appropriate events</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<img>
+
+<script>
+ async_test(function(t) {
+ var img = document.querySelector("img");
+ img.onload = this.step_func_done(function() {
+ assert_unreached("image.onload() was not supposed to be called");
+ });
+ img.onerror = this.step_func_done(function(e) {
+ assert_equals(e.type, "error", "image.onerror() called");
+ t.done();
+ });
+ img.src = "404";
+ });
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-img-element/relevant-mutations.html b/testing/web-platform/tests/html/semantics/embedded-content/the-img-element/relevant-mutations.html
new file mode 100644
index 000000000..c8e09e8d0
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-img-element/relevant-mutations.html
@@ -0,0 +1,416 @@
+<!doctype html>
+<title>img relevant mutations</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+
+<!-- should invoke update the image data -->
+
+<img data-desc="src set">
+<img src="/images/green-2x2.png" data-desc="src changed">
+<img src="/images/green-2x2.png" data-desc="src removed">
+
+<img data-desc="srcset set">
+<img srcset="/images/green-2x2.png" data-desc="srcset changed">
+<img srcset="/images/green-2x2.png" data-desc="srcset removed">
+
+<img data-desc="sizes set">
+<img sizes="" data-desc="sizes changed">
+<img sizes="" data-desc="sizes removed">
+
+<img src="/images/green-2x2.png" data-desc="src set to same value">
+
+<img data-desc="crossorigin absent to empty">
+<img data-desc="crossorigin absent to anonymous">
+<img data-desc="crossorigin absent to use-credentials">
+<img crossorigin data-desc="crossorigin empty to absent">
+<img crossorigin data-desc="crossorigin empty to use-credentials">
+<img crossorigin=anonymous data-desc="crossorigin anonymous to absent">
+<img crossorigin=anonymous data-desc="crossorigin anonymous to use-credentials">
+<img crossorigin=use-credentials data-desc="crossorigin use-credentials to absent">
+<img crossorigin=use-credentials data-desc="crossorigin use-credentials to empty">
+<img crossorigin=use-credentials data-desc="crossorigin use-credentials to anonymous">
+
+<img src="/images/green-2x2.png" data-desc="inserted into picture"><picture></picture>
+
+<picture><img src="/images/green-2x2.png" data-desc="removed from picture"></picture>
+
+<picture><img src="/images/green-2x2.png" data-desc="parent is picture, previous source inserted"></picture>
+
+<picture><source><img src="/images/green-2x2.png" data-desc="parent is picture, previous source removed"></picture>
+
+<picture><source><img src="/images/green-2x2.png" data-desc="parent is picture, previous source has srcset set"></picture>
+<picture><source srcset=""><img src="/images/green-2x2.png" data-desc="parent is picture, previous source has srcset changed"></picture>
+<picture><source srcset=""><img src="/images/green-2x2.png" data-desc="parent is picture, previous source has srcset removed"></picture>
+
+<picture><source><img src="/images/green-2x2.png" data-desc="parent is picture, previous source has sizes set"></picture>
+<picture><source sizes=""><img src="/images/green-2x2.png" data-desc="parent is picture, previous source has sizes changed"></picture>
+<picture><source sizes=""><img src="/images/green-2x2.png" data-desc="parent is picture, previous source has sizes removed"></picture>
+
+<picture><source><img src="/images/green-2x2.png" data-desc="parent is picture, previous source has media set"></picture>
+<picture><source media=""><img src="/images/green-2x2.png" data-desc="parent is picture, previous source has media changed"></picture>
+<picture><source media=""><img src="/images/green-2x2.png" data-desc="parent is picture, previous source has media removed"></picture>
+
+<picture><source><img src="/images/green-2x2.png" data-desc="parent is picture, previous source has type set"></picture>
+<picture><source type=""><img src="/images/green-2x2.png" data-desc="parent is picture, previous source has type changed"></picture>
+<picture><source type=""><img src="/images/green-2x2.png" data-desc="parent is picture, previous source has type removed"></picture>
+
+<!-- should not invoke update the image data -->
+
+<img srcset="/images/green-2x2.png" data-desc="srcset is set to same value">
+<img srcset="/images/green-2x2.png" sizes data-desc="sizes is set to same value">
+
+<img src="/images/green-2x2.png" data-desc="crossorigin state not changed: absent, removeAttribute">
+<img src="/images/green-2x2.png" crossorigin data-desc="crossorigin state not changed: empty to anonymous">
+<img src="/images/green-2x2.png" crossorigin=anonymous data-desc="crossorigin state not changed: anonymous to foobar">
+<img src="/images/green-2x2.png" crossorigin=use-credentials data-desc="crossorigin state not changed: use-credentials to USE-CREDENTIALS">
+
+<img src="/images/green-2x2.png" data-desc="inserted into picture ancestor"><picture><span></span></picture>
+<picture><span><img src="/images/green-2x2.png" data-desc="removed from picture ancestor"></span></picture>
+
+<picture><span><img src="/images/green-2x2.png" data-desc="ancestor picture has a source inserted"></span></picture>
+<picture><source><span><img src="/images/green-2x2.png" data-desc="ancestor picture has a source removed"></span></picture>
+
+<picture><span><img src="/images/green-2x2.png" data-desc="ancestor picture; previous sibling source inserted"></span></picture>
+<picture><span><source><img src="/images/green-2x2.png" data-desc="ancestor picture; previous sibling source removed"></span></picture>
+
+<picture><img src="/images/green-2x2.png" data-desc="parent is picture, following sibling source inserted"></picture>
+<picture><img src="/images/green-2x2.png" data-desc="parent is picture, following sibling source removed"><source></picture>
+
+<picture><img src="/images/green-2x2.png" data-desc="parent is picture, following sibling source has srcset set"><source></picture>
+
+<img src="/images/green-2x2.png" data-desc="media on img set">
+<img src="/images/green-2x2.png" data-desc="type on img set">
+<img src="/images/green-2x2.png" data-desc="class on img set">
+<img src="/images/green-2x2.png" data-desc="alt on img set">
+
+<picture><source><img src="/images/green-2x2.png" data-desc="src on previous sibling source set"></picture>
+<picture><source><img src="/images/green-2x2.png" data-desc="class on previous sibling source set"></picture>
+
+<img src="/images/green-2x2.png" data-desc="inserted/removed children of img">
+
+<picture><img src="/images/green-2x2.png" data-desc="picture is inserted; img has src"></picture><span></span>
+<picture><img srcset="/images/green-2x2.png" data-desc="picture is inserted; img has srcset"></picture><span></span>
+<picture><source srcset="/images/green-2x2.png"><img src="/images/green-2x2.png" data-desc="picture is inserted; img has previous sibling source"></picture><span></span>
+<picture><img src="/images/green-2x2.png" data-desc="picture is inserted; img has following sibling source"><source srcset="/images/green-2x2.png"></picture><span></span>
+
+<picture><img src="/images/green-2x2.png" data-desc="picture is removed; img has src"></picture>
+<picture><img srcset="/images/green-2x2.png" data-desc="picture is removed; img has srcset"></picture>
+<picture><source srcset="/images/green-2x2.png"><img src="/images/green-2x2.png" data-desc="picture is removed; img has previous sibling source"></picture>
+<picture><img src="/images/green-2x2.png" data-desc="picture is removed; img has following sibling source"><source srcset="/images/green-2x2.png"></picture>
+
+<picture><img src="/images/green-2x2.png" data-desc="parent is picture, following img inserted"></picture>
+<picture><img src="/images/green-2x2.png" data-desc="parent is picture, following img removed"><img></picture>
+<picture><img src="/images/green-2x2.png" data-desc="parent is picture, following img has src set"><img></picture>
+<picture><img src="/images/green-2x2.png" data-desc="parent is picture, following img has srcset set"><img></picture>
+<picture><img src="/images/green-2x2.png" data-desc="parent is picture, following img has sizes set"><img></picture>
+
+
+<script>
+setup({explicit_done:true});
+
+function t(desc, func, expect) {
+ async_test(function() {
+ var img = document.querySelector('[data-desc="' + desc + '"]');
+ img.onload = img.onerror = this.unreached_func('update the image data was run');
+ if (expect == 'timeout') {
+ setTimeout(this.step_func_done(), 1000);
+ } else {
+ img['on' + expect] = this.step_func_done(function() {});
+ }
+ func.call(this, img);
+ }, desc);
+}
+
+onload = function() {
+
+ t('src set', function(img) {
+ img.src = '/images/green-2x2.png';
+ }, 'load');
+
+ t('src changed', function(img) {
+ img.src = '/images/green-2x2.png ';
+ }, 'load');
+
+ t('src removed', function(img) {
+ img.removeAttribute('src');
+ }, 'timeout');
+
+ t('srcset set', function(img) {
+ img.srcset = '/images/green-2x2.png';
+ }, 'load');
+
+ t('srcset changed', function(img) {
+ img.srcset = '/images/green-2x2.png ';
+ }, 'load');
+
+ t('srcset removed', function(img) {
+ img.removeAttribute('srcset');
+ }, 'timeout');
+
+ t('sizes set', function(img) {
+ img.sizes = '';
+ }, 'timeout');
+
+ t('sizes changed', function(img) {
+ img.sizes = ' ';
+ }, 'timeout');
+
+ t('sizes removed', function(img) {
+ img.removeAttribute('sizes');
+ }, 'timeout');
+
+ t('src set to same value', function(img) {
+ img.src = '/images/green-2x2.png';
+ }, 'load');
+
+ t('crossorigin absent to empty', function(img) {
+ img.crossOrigin = '';
+ }, 'timeout');
+
+ t('crossorigin absent to anonymous', function(img) {
+ img.crossOrigin = 'anonymous';
+ }, 'timeout');
+
+ t('crossorigin absent to use-credentials', function(img) {
+ img.crossOrigin = 'use-credentials';
+ }, 'timeout');
+
+ t('crossorigin empty to absent', function(img) {
+ img.removeAttribute('crossorigin');
+ }, 'timeout');
+
+ t('crossorigin empty to use-credentials', function(img) {
+ img.crossOrigin = 'use-credentials';
+ }, 'timeout');
+
+ t('crossorigin anonymous to absent', function(img) {
+ img.removeAttribute('crossorigin');
+ }, 'timeout');
+
+ t('crossorigin anonymous to use-credentials', function(img) {
+ img.crossOrigin = 'use-credentials';
+ }, 'timeout');
+
+ t('crossorigin use-credentials to absent', function(img) {
+ img.removeAttribute('crossorigin');
+ }, 'timeout');
+
+ t('crossorigin use-credentials to empty', function(img) {
+ img.crossOrigin = '';
+ }, 'timeout');
+
+ t('crossorigin use-credentials to anonymous', function(img) {
+ img.crossOrigin = 'anonymous';
+ }, 'timeout');
+
+ t('inserted into picture', function(img) {
+ img.nextSibling.appendChild(img);
+ }, 'load');
+
+ t('removed from picture', function(img) {
+ img.parentNode.removeChild(img);
+ }, 'load');
+
+ t('parent is picture, previous source inserted', function(img) {
+ img.parentNode.insertBefore(document.createElement('source'), img);
+ }, 'load');
+
+ t('parent is picture, previous source removed', function(img) {
+ img.parentNode.removeChild(img.previousSibling);
+ }, 'load');
+
+ t('parent is picture, previous source has srcset set', function(img) {
+ img.previousSibling.srcset = '';
+ }, 'load');
+
+ t('parent is picture, previous source has srcset changed', function(img) {
+ img.previousSibling.srcset = ' ';
+ }, 'load');
+
+ t('parent is picture, previous source has srcset removed', function(img) {
+ img.previousSibling.removeAttribute('srcset');
+ }, 'load');
+
+ t('parent is picture, previous source has sizes set', function(img) {
+ img.previousSibling.sizes = '';
+ }, 'load');
+
+ t('parent is picture, previous source has sizes changed', function(img) {
+ img.previousSibling.sizes = ' ';
+ }, 'load');
+
+ t('parent is picture, previous source has sizes removed', function(img) {
+ img.previousSibling.removeAttribute('sizes');
+ }, 'load');
+
+ t('parent is picture, previous source has media set', function(img) {
+ img.previousSibling.media = '';
+ }, 'load');
+
+ t('parent is picture, previous source has media changed', function(img) {
+ img.previousSibling.media = ' ';
+ }, 'load');
+
+ t('parent is picture, previous source has media removed', function(img) {
+ img.previousSibling.removeAttribute('media');
+ }, 'load');
+
+ t('parent is picture, previous source has type set', function(img) {
+ img.previousSibling.type = '';
+ }, 'load');
+
+ t('parent is picture, previous source has type changed', function(img) {
+ img.previousSibling.type = ' ';
+ }, 'load');
+
+ t('parent is picture, previous source has type removed', function(img) {
+ img.previousSibling.removeAttribute('type');
+ }, 'load');
+
+ t('srcset is set to same value', function(img) {
+ img.srcset = "/images/green-2x2.png";
+ }, 'timeout');
+
+ t('sizes is set to same value', function(img) {
+ img.sizes = '';
+ }, 'timeout');
+
+ t('crossorigin state not changed: absent, removeAttribute', function(img) {
+ img.removeAttribute('crossorigin');
+ }, 'timeout');
+
+ t('crossorigin state not changed: empty to anonymous', function(img) {
+ img.crossOrigin = 'anonymous';
+ }, 'timeout');
+
+ t('crossorigin state not changed: anonymous to foobar', function(img) {
+ img.crossOrigin = 'foobar';
+ }, 'timeout');
+
+ t('crossorigin state not changed: use-credentials to USE-CREDENTIALS', function(img) {
+ img.crossOrigin = 'USE-CREDENTIALS';
+ }, 'timeout');
+
+ t('inserted into picture ancestor', function(img) {
+ img.nextSibling.firstChild.appendChild(img);
+ }, 'timeout');
+
+ t('removed from picture ancestor', function(img) {
+ img.parentNode.removeChild(img);
+ }, 'timeout');
+
+ t('ancestor picture has a source inserted', function(img) {
+ img.parentNode.parentNode.insertBefore(document.createElement('source'), img.parentNode);
+ }, 'timeout');
+
+ t('ancestor picture has a source removed', function(img) {
+ img.parentNode.parentNode.removeChild(img.parentNode.previousSibling);
+ }, 'timeout');
+
+ t('ancestor picture; previous sibling source inserted', function(img) {
+ img.parentNode.insertBefore(document.createElement('source'), img);
+ }, 'timeout');
+
+ t('ancestor picture; previous sibling source removed', function(img) {
+ img.parentNode.removeChild(img.previousSibling);
+ }, 'timeout');
+
+ t('parent is picture, following sibling source inserted', function(img) {
+ img.parentNode.appendChild(document.createElement('source'));
+ }, 'timeout');
+
+ t('parent is picture, following sibling source removed', function(img) {
+ img.parentNode.removeChild(img.nextSibling);
+ }, 'timeout');
+
+ t('parent is picture, following sibling source has srcset set', function(img) {
+ img.nextSibling.srcset = '';
+ }, 'timeout');
+
+ t('media on img set', function(img) {
+ img.setAttribute('media', '');
+ }, 'timeout');
+
+ t('type on img set', function(img) {
+ img.setAttribute('type', '');
+ }, 'timeout');
+
+ t('class on img set', function(img) {
+ img.className = '';
+ }, 'timeout');
+
+ t('alt on img set', function(img) {
+ img.alt = '';
+ }, 'timeout');
+
+ t('src on previous sibling source set', function(img) {
+ img.previousSibling.setAttribute('src', '');
+ }, 'timeout');
+
+ t('class on previous sibling source set', function(img) {
+ img.previousSibling.className = '';
+ }, 'timeout');
+
+ t('inserted/removed children of img', function(img) {
+ img.appendChild(document.createElement('source'));
+ setTimeout(this.step_func(function() {
+ img.removeChild(img.firstChild);
+ }), 0);
+ }, 'timeout');
+
+ t('picture is inserted; img has src', function(img) {
+ img.parentNode.nextSibling.appendChild(img.parentNode);
+ }, 'timeout');
+
+ t('picture is inserted; img has srcset', function(img) {
+ img.parentNode.nextSibling.appendChild(img.parentNode);
+ }, 'timeout');
+
+ t('picture is inserted; img has previous sibling source', function(img) {
+ img.parentNode.nextSibling.appendChild(img.parentNode);
+ }, 'timeout');
+
+ t('picture is inserted; img has following sibling source', function(img) {
+ img.parentNode.nextSibling.appendChild(img.parentNode);
+ }, 'timeout');
+
+ t('picture is removed; img has src', function(img) {
+ img.parentNode.parentNode.removeChild(img.parentNode);
+ }, 'timeout');
+
+ t('picture is removed; img has srcset', function(img) {
+ img.parentNode.parentNode.removeChild(img.parentNode);
+ }, 'timeout');
+
+ t('picture is removed; img has previous sibling source', function(img) {
+ img.parentNode.parentNode.removeChild(img.parentNode);
+ }, 'timeout');
+
+ t('picture is removed; img has following sibling source', function(img) {
+ img.parentNode.parentNode.removeChild(img.parentNode);
+ }, 'timeout');
+
+ t('parent is picture, following img inserted', function(img) {
+ img.parentNode.appendChild(document.createElement('img'));
+ }, 'timeout');
+
+ t('parent is picture, following img removed', function(img) {
+ img.parentNode.removeChild(img.nextSibling);
+ }, 'timeout');
+
+ t('parent is picture, following img has src set', function(img) {
+ img.nextSibling.src = '';
+ }, 'timeout');
+
+ t('parent is picture, following img has srcset set', function(img) {
+ img.nextSibling.srcset = '';
+ }, 'timeout');
+
+ t('parent is picture, following img has sizes set', function(img) {
+ img.nextSibling.sizes = '';
+ }, 'timeout');
+
+ done();
+};
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-img-element/resources/cat.jpg b/testing/web-platform/tests/html/semantics/embedded-content/the-img-element/resources/cat.jpg
new file mode 100644
index 000000000..a4f14f54d
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-img-element/resources/cat.jpg
Binary files differ
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-img-element/sizes/parse-a-sizes-attribute.html b/testing/web-platform/tests/html/semantics/embedded-content/the-img-element/sizes/parse-a-sizes-attribute.html
new file mode 100644
index 000000000..bd2045420
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-img-element/sizes/parse-a-sizes-attribute.html
@@ -0,0 +1,42 @@
+<!doctype html>
+<title>img parse a sizes attribute</title>
+<meta name="timeout" content="long">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<iframe data-desc="standards mode" style="width:1000px; height:1000px" src="sizes-iframed.sub.html?doctype=doctype%20html&style="></iframe>
+<iframe data-desc="quirks mode" style="width:1000px; height:1000px" src="sizes-iframed.sub.html?doctype=----&style="></iframe>
+<iframe data-desc="display:none" style="width:1000px; height:1000px" src="sizes-iframed.sub.html?doctype=doctype%20html&style=display:none"></iframe>
+<iframe data-desc="width:1000px" style="width:1000px; height:1000px" src="sizes-iframed.sub.html?doctype=doctype%20html&style=width:1000px%3B%20height:16px"></iframe>
+<script>
+setup({explicit_done:true});
+
+function check(p, iframe) {
+ var current = p.firstElementChild;
+ var ref_sizes = current.getAttribute('sizes');
+ var expect = p.firstElementChild.currentSrc;
+ if (expect) {
+ expect = expect.split('?')[0];
+ }
+ while (current = current.nextElementSibling) {
+ test(function() {
+ if (expect === '' || expect === null || expect === undefined) {
+ assert_unreached('ref currentSrc was ' + format_value(expect));
+ }
+ var got = current.currentSrc;
+ assert_greater_than(got.indexOf('?'), -1, 'expected a "?" in currentSrc');
+ got = got.split('?')[0];
+ assert_equals(got, expect);
+ }, current.outerHTML + ' ref sizes=' + format_value(ref_sizes) + ' (' + iframe.getAttribute('data-desc') + ')');
+ }
+}
+
+onload = function() {
+ [].forEach.call(document.querySelectorAll('iframe'), function(iframe) {
+ [].forEach.call(iframe.contentDocument.querySelectorAll('p'), function(p) {
+ check(p, iframe);
+ });
+ });
+ done();
+}
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-img-element/sizes/sizes-iframed.sub.html b/testing/web-platform/tests/html/semantics/embedded-content/the-img-element/sizes/sizes-iframed.sub.html
new file mode 100644
index 000000000..925bb4699
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-img-element/sizes/sizes-iframed.sub.html
@@ -0,0 +1,178 @@
+<!{{GET[doctype]}}>
+<style> img { {{GET[style]}} } </style>
+<!-- First <img> in a <p> is the reference. The following <img>s should be equivalent -->
+<!-- default is 100vw, not 300px -->
+<p>
+<img srcset='/images/green-1x1.png?a1 300w, /images/green-16x16.png?a1 301w' sizes='100vw'>
+<img srcset='/images/green-1x1.png?a2 300w, /images/green-16x16.png?a2 301w'>
+<p>
+<img srcset='/images/green-1x1.png?b1 450w, /images/green-16x16.png?b1 451w' sizes='100vw'>
+<img srcset='/images/green-1x1.png?b2 450w, /images/green-16x16.png?b2 451w'>
+<p>
+<img srcset='/images/green-1x1.png?c1 600w, /images/green-16x16.png?c1 601w' sizes='100vw'>
+<img srcset='/images/green-1x1.png?c2 600w, /images/green-16x16.png?c2 601w'>
+<p>
+<img srcset='/images/green-1x1.png?d1 900w, /images/green-16x16.png?d1 901w' sizes='100vw'>
+<img srcset='/images/green-1x1.png?d2 900w, /images/green-16x16.png?d2 901w'>
+
+<p>
+<img srcset='/images/green-1x1.png?e1 50w, /images/green-16x16.png?e1 51w' sizes='1px'>
+<img srcset='/images/green-1x1.png?e2 50w, /images/green-16x16.png?e2 51w' sizes='0'>
+<img srcset='/images/green-1x1.png?e3 50w, /images/green-16x16.png?e3 51w' sizes='-0'>
+<img srcset='/images/green-1x1.png?e4 50w, /images/green-16x16.png?e4 51w' sizes='+0'>
+<img srcset='/images/green-1x1.png?e5 50w, /images/green-16x16.png?e5 51w' sizes='+1px'>
+<img srcset='/images/green-1x1.png?e6 50w, /images/green-16x16.png?e6 51w' sizes='.1px'>
+<img srcset='/images/green-1x1.png?e7 50w, /images/green-16x16.png?e7 51w' sizes='0.1em'>
+<img srcset='/images/green-1x1.png?e8 50w, /images/green-16x16.png?e8 51w' sizes='0.1ex'>
+<img srcset='/images/green-1x1.png?e9 50w, /images/green-16x16.png?e9 51w' sizes='0.1ch'>
+<img srcset='/images/green-1x1.png?e10 50w, /images/green-16x16.png?e10 51w' sizes='0.1rem'>
+<img srcset='/images/green-1x1.png?e11 50w, /images/green-16x16.png?e11 51w' sizes='0.1vw'>
+<img srcset='/images/green-1x1.png?e12 50w, /images/green-16x16.png?e12 51w' sizes='0.1vh'>
+<img srcset='/images/green-1x1.png?e13 50w, /images/green-16x16.png?e13 51w' sizes='0.1vmin'>
+<img srcset='/images/green-1x1.png?e14 50w, /images/green-16x16.png?e14 51w' sizes='0.1vmax'>
+<img srcset='/images/green-1x1.png?e15 50w, /images/green-16x16.png?e15 51w' sizes='0.1cm'>
+<img srcset='/images/green-1x1.png?e16 50w, /images/green-16x16.png?e16 51w' sizes='1mm'>
+<img srcset='/images/green-1x1.png?e17 50w, /images/green-16x16.png?e17 51w' sizes='1q'>
+<img srcset='/images/green-1x1.png?e18 50w, /images/green-16x16.png?e18 51w' sizes='0.01in'>
+<img srcset='/images/green-1x1.png?e19 50w, /images/green-16x16.png?e19 51w' sizes='0.1pc'>
+<img srcset='/images/green-1x1.png?e20 50w, /images/green-16x16.png?e20 51w' sizes='0.1pt'>
+<img srcset='/images/green-1x1.png?e21 50w, /images/green-16x16.png?e21 51w' sizes='/* */1px/* */'>
+<img srcset='/images/green-1x1.png?e22 50w, /images/green-16x16.png?e22 51w' sizes=' /**/ /**/ 1px /**/ /**/ '>
+<img srcset='/images/green-1x1.png?e23 50w, /images/green-16x16.png?e23 51w' sizes='(),1px'>
+<img srcset='/images/green-1x1.png?e24 50w, /images/green-16x16.png?e24 51w' sizes='x(),1px'>
+<img srcset='/images/green-1x1.png?e25 50w, /images/green-16x16.png?e25 51w' sizes='{},1px'>
+<img srcset='/images/green-1x1.png?e26 50w, /images/green-16x16.png?e26 51w' sizes='[],1px'>
+<img srcset='/images/green-1x1.png?e27 50w, /images/green-16x16.png?e27 51w' sizes='1px,('>
+<img srcset='/images/green-1x1.png?e28 50w, /images/green-16x16.png?e28 51w' sizes='1px,x('>
+<img srcset='/images/green-1x1.png?e29 50w, /images/green-16x16.png?e29 51w' sizes='1px,{'>
+<img srcset='/images/green-1x1.png?e30 50w, /images/green-16x16.png?e30 51w' sizes='1px,['>
+<img srcset='/images/green-1x1.png?e31 50w, /images/green-16x16.png?e31 51w' sizes='\(,1px'>
+<img srcset='/images/green-1x1.png?e32 50w, /images/green-16x16.png?e32 51w' sizes='x\(,1px'>
+<img srcset='/images/green-1x1.png?e33 50w, /images/green-16x16.png?e33 51w' sizes='\{,1px'>
+<img srcset='/images/green-1x1.png?e34 50w, /images/green-16x16.png?e34 51w' sizes='\[,1px'>
+<img srcset='/images/green-1x1.png?e35 50w, /images/green-16x16.png?e35 51w' sizes='1\p\x'>
+<img srcset='/images/green-1x1.png?e36 50w, /images/green-16x16.png?e36 51w' sizes='calc(1px)'>
+<img srcset='/images/green-1x1.png?e37 50w, /images/green-16x16.png?e37 51w' sizes='(min-width:0) calc(1px)'>
+<img srcset='/images/green-1x1.png?e38 50w, /images/green-16x16.png?e38 51w' sizes='(min-width:calc(0)) 1px'>
+<img srcset='/images/green-1x1.png?e39 50w, /images/green-16x16.png?e39 51w' sizes='(min-width:0) 1px, 100vw'>
+<img srcset='/images/green-1x1.png?e40 50w, /images/green-16x16.png?e40 51w' sizes='(min-width:0) 1px, (min-width:0) 100vw, 100vw'>
+<img srcset='/images/green-1x1.png?e41 50w, /images/green-16x16.png?e41 51w' sizes='(min-width:0) 1px'>
+<img srcset='/images/green-1x1.png?e42 50w, /images/green-16x16.png?e42 51w' sizes='not (min-width:0) 100vw, 1px'>
+<img srcset='/images/green-1x1.png?e43 50w, /images/green-16x16.png?e43 51w' sizes='(min-width:unknown-mf-value) 100vw, 1px'>
+<img srcset='/images/green-1x1.png?e44 50w, /images/green-16x16.png?e44 51w' sizes='not (min-width:unknown-mf-value) 100vw, 1px'>
+<img srcset='/images/green-1x1.png?e45 50w, /images/green-16x16.png?e45 51w' sizes='(min-width:-1px) 100vw, 1px'>
+<img srcset='/images/green-1x1.png?e46 50w, /images/green-16x16.png?e46 51w' sizes='not (min-width:-1px) 100vw, 1px'>
+<img srcset='/images/green-1x1.png?e47 50w, /images/green-16x16.png?e47 51w' sizes='(unknown-mf-name) 100vw, 1px'>
+<img srcset='/images/green-1x1.png?e48 50w, /images/green-16x16.png?e48 51w' sizes='not (unknown-mf-name) 100vw, 1px'>
+<img srcset='/images/green-1x1.png?e49 50w, /images/green-16x16.png?e49 51w' sizes='(unknown "general-enclosed") 100vw, 1px'>
+<img srcset='/images/green-1x1.png?e50 50w, /images/green-16x16.png?e50 51w' sizes='not (unknown "general-enclosed") 100vw, 1px'>
+<img srcset='/images/green-1x1.png?e51 50w, /images/green-16x16.png?e51 51w' sizes='unknown-general-enclosed(foo) 100vw, 1px'>
+<img srcset='/images/green-1x1.png?e52 50w, /images/green-16x16.png?e52 51w' sizes='not unknown-general-enclosed(foo) 100vw, 1px'>
+<img srcset='/images/green-1x1.png?e53 50w, /images/green-16x16.png?e53 51w' sizes='print 100vw, 1px'>
+<img srcset='/images/green-1x1.png?e54 50w, /images/green-16x16.png?e54 51w' sizes='not print 100vw, 1px'>
+<img srcset='/images/green-1x1.png?e55 50w, /images/green-16x16.png?e55 51w' sizes='unknown-media-type 100vw, 1px'>
+<img srcset='/images/green-1x1.png?e56 50w, /images/green-16x16.png?e56 51w' sizes='not unknown-media-type 100vw, 1px'>
+<img srcset='/images/green-1x1.png?e57 50w, /images/green-16x16.png?e57 51w' sizes='(min-width:0) or (min-width:0) 1px'>
+<img srcset='/images/green-1x1.png?e58 50w, /images/green-16x16.png?e58 51w' sizes='(min-width:0) or (unknown-mf-name) 1px'>
+<img srcset='/images/green-1x1.png?e59 50w, /images/green-16x16.png?e59 51w' sizes='(min-width:0) or (min-width:unknown-mf-value) 1px'>
+<img srcset='/images/green-1x1.png?e60 50w, /images/green-16x16.png?e60 51w' sizes='(min-width:0) or (min-width:-1px) 1px'>
+<img srcset='/images/green-1x1.png?e61 50w, /images/green-16x16.png?e61 51w' sizes='(min-width:0) or (unknown "general-enclosed") 1px'>
+<img srcset='/images/green-1x1.png?e62 50w, /images/green-16x16.png?e62 51w' sizes='(min-width:0) or unknown-general-enclosed(foo) 1px'>
+<img srcset='/images/green-1x1.png?e63 50w, /images/green-16x16.png?e63 51w' sizes='(min-width:0) or (!) 100vw, 1px'>
+<img srcset='/images/green-1x1.png?e64 50w, /images/green-16x16.png?e64 51w' sizes='(min-width:0) or unknown-media-type 100vw, 1px'>
+<img srcset='/images/green-1x1.png?e65 50w, /images/green-16x16.png?e65 51w' sizes='(123) 100vw, 1px'>
+<img srcset='/images/green-1x1.png?e66 50w, /images/green-16x16.png?e66 51w' sizes='not (123) 100vw, 1px'>
+<img srcset='/images/green-1x1.png?e67 50w, /images/green-16x16.png?e67 51w' sizes='(!) 100vw, 1px'>
+<img srcset='/images/green-1x1.png?e68 50w, /images/green-16x16.png?e68 51w' sizes='not (!) 100vw, 1px'>
+<img srcset='/images/green-1x1.png?e69 50w, /images/green-16x16.png?e69 51w' sizes='! 100vw, 1px'>
+<img srcset='/images/green-1x1.png?e70 50w, /images/green-16x16.png?e70 51w' sizes='not ! 100vw, 1px'>
+<img srcset='/images/green-1x1.png?e71 50w, /images/green-16x16.png?e71 51w' sizes='(]) 100vw, 1px'>
+<img srcset='/images/green-1x1.png?e72 50w, /images/green-16x16.png?e72 51w' sizes='not (]) 100vw, 1px'>
+<img srcset='/images/green-1x1.png?e73 50w, /images/green-16x16.png?e73 51w' sizes='] 100vw, 1px'>
+<img srcset='/images/green-1x1.png?e74 50w, /images/green-16x16.png?e74 51w' sizes='not ] 100vw, 1px'>
+<img srcset='/images/green-1x1.png?e75 50w, /images/green-16x16.png?e75 51w' sizes='(}) 100vw, 1px'>
+<img srcset='/images/green-1x1.png?e76 50w, /images/green-16x16.png?e76 51w' sizes='not (}) 100vw, 1px'>
+<img srcset='/images/green-1x1.png?e77 50w, /images/green-16x16.png?e77 51w' sizes='} 100vw, 1px'>
+<img srcset='/images/green-1x1.png?e78 50w, /images/green-16x16.png?e78 51w' sizes='not } 100vw, 1px'>
+<img srcset='/images/green-1x1.png?e79 50w, /images/green-16x16.png?e79 51w' sizes=') 100vw, 1px'>
+<img srcset='/images/green-1x1.png?e80 50w, /images/green-16x16.png?e80 51w' sizes='not ) 100vw, 1px'>
+<img srcset='/images/green-1x1.png?e81 50w, /images/green-16x16.png?e81 51w' sizes='(;) 100vw, 1px'>
+<img srcset='/images/green-1x1.png?e82 50w, /images/green-16x16.png?e82 51w' sizes='not (;) 100vw, 1px'>
+<img srcset='/images/green-1x1.png?e83 50w, /images/green-16x16.png?e83 51w' sizes='(.) 100vw, 1px'>
+<img srcset='/images/green-1x1.png?e84 50w, /images/green-16x16.png?e84 51w' sizes='not (.) 100vw, 1px'>
+<img srcset='/images/green-1x1.png?e85 50w, /images/green-16x16.png?e85 51w' sizes='; 100vw, 1px'>
+<img srcset='/images/green-1x1.png?e86 50w, /images/green-16x16.png?e86 51w' sizes='not ; 100vw, 1px'>
+<img srcset='/images/green-1x1.png?e87 50w, /images/green-16x16.png?e87 51w' sizes=', 1px'>
+<img srcset='/images/green-1x1.png?e88 50w, /images/green-16x16.png?e88 51w' sizes='1px,'>
+<img srcset='/images/green-1x1.png?e89 50w, /images/green-16x16.png?e89 51w' sizes='(min-width:0) 1px,'>
+<img srcset='/images/green-1x1.png?e90 50w, /images/green-16x16.png?e90 51w' sizes='-0e-0px'>
+<img srcset='/images/green-1x1.png?e91 50w, /images/green-16x16.png?e91 51w' sizes='+0.11e+01px'>
+<img srcset='/images/green-1x1.png?e92 50w, /images/green-16x16.png?e92 51w' sizes='0.2e1px'>
+<img srcset='/images/green-1x1.png?e93 50w, /images/green-16x16.png?e93 51w' sizes='0.3E1px'>
+<img srcset='/images/green-1x1.png?e94 50w, /images/green-16x16.png?e94 51w' sizes='.4E1px'>
+<img srcset='/images/green-1x1.png?e95 50w, /images/green-16x16.png?e95 51w' sizes='all 100vw, 1px'>
+<img srcset='/images/green-1x1.png?e96 50w, /images/green-16x16.png?e96 51w' sizes='all and (min-width:0) 100vw, 1px'>
+<img srcset='/images/green-1x1.png?e97 50w, /images/green-16x16.png?e97 51w' sizes='min-width:0 100vw, 1px'>
+<img srcset='/images/green-1x1.png?e98 50w, /images/green-16x16.png?e98 51w' sizes='1px, 100vw'>
+<img srcset='/images/green-1x1.png?e99 50w, /images/green-16x16.png?e99 51w' sizes='1px, (min-width:0) 100vw'>
+<img srcset='/images/green-1x1.png?e100 50w, /images/green-16x16.png?e100 51w' sizes='1px, foo bar'>
+<img srcset='/images/green-1x1.png?e101 50w, /images/green-16x16.png?e101 51w' sizes='(min-width:0) 1px, foo bar'>
+<img srcset='/images/green-1x1.png?e102 50w, /images/green-16x16.png?e102 51w' sizes='("grammar does not match") 100vw, 1px'>
+<img srcset='/images/green-1x1.png?e103 50w, /images/green-16x16.png?e103 51w' sizes='not ("grammar does not match") 100vw, 1px'>
+<img srcset='/images/green-1x1.png?e104 50w, /images/green-16x16.png?e104 51w' sizes='(unknown-general-enclosed !) 100vw, 1px'>
+<img srcset='/images/green-1x1.png?e105 50w, /images/green-16x16.png?e105 51w' sizes='not (unknown-general-enclosed !) 100vw, 1px'>
+<img srcset='/images/green-1x1.png?e106 50w, /images/green-16x16.png?e106 51w' sizes='(min-width:0) or (unknown-general-enclosed !) 1px'>
+<img srcset='/images/green-1x1.png?e107 50w, /images/green-16x16.png?e107 51w' sizes='not ((min-width:0) or (unknown "general-enclosed")) 100vw, 1px'>
+<img srcset='/images/green-1x1.png?e108 50w, /images/green-16x16.png?e108 51w' sizes='(max-width:0) or (unknown-general-enclosed !) 100vw, 1px'>
+<img srcset='/images/green-1x1.png?e109 50w, /images/green-16x16.png?e109 51w' sizes='not ((max-width:0) or (unknown "general-enclosed")) 100vw, 1px'>
+<img srcset='/images/green-1x1.png?f48 50w, /images/green-16x16.png?f48 51w' sizes='calc(1px'>
+<img srcset='/images/green-1x1.png?f49 50w, /images/green-16x16.png?f49 51w' sizes='(min-width:0) calc(1px'>
+
+<p>
+<img srcset='/images/green-1x1.png?f1 50w, /images/green-16x16.png?f1 51w' sizes='100vw'>
+<img srcset='/images/green-1x1.png?f2 50w, /images/green-16x16.png?f2 51w' sizes=''>
+<img srcset='/images/green-1x1.png?f3 50w, /images/green-16x16.png?f3 51w' sizes=','>
+<img srcset='/images/green-1x1.png?f4 50w, /images/green-16x16.png?f4 51w' sizes='-1px'>
+<img srcset='/images/green-1x1.png?f5 50w, /images/green-16x16.png?f5 51w' sizes='1'>
+<img srcset='/images/green-1x1.png?f6 50w, /images/green-16x16.png?f6 51w' sizes='0.1%'>
+<img srcset='/images/green-1x1.png?f7 50w, /images/green-16x16.png?f7 51w' sizes='0.1deg'>
+<img srcset='/images/green-1x1.png?f8 50w, /images/green-16x16.png?f8 51w' sizes='0.1grad'>
+<img srcset='/images/green-1x1.png?f9 50w, /images/green-16x16.png?f9 51w' sizes='0.1rad'>
+<img srcset='/images/green-1x1.png?f10 50w, /images/green-16x16.png?f10 51w' sizes='0.1turn'>
+<img srcset='/images/green-1x1.png?f11 50w, /images/green-16x16.png?f11 51w' sizes='0.1s'>
+<img srcset='/images/green-1x1.png?f12 50w, /images/green-16x16.png?f12 51w' sizes='0.1ms'>
+<img srcset='/images/green-1x1.png?f13 50w, /images/green-16x16.png?f13 51w' sizes='0.1Hz'>
+<img srcset='/images/green-1x1.png?f14 50w, /images/green-16x16.png?f14 51w' sizes='0.1kHz'>
+<img srcset='/images/green-1x1.png?f15 50w, /images/green-16x16.png?f15 51w' sizes='0.1dpi'>
+<img srcset='/images/green-1x1.png?f16 50w, /images/green-16x16.png?f16 51w' sizes='0.1dpcm'>
+<img srcset='/images/green-1x1.png?f17 50w, /images/green-16x16.png?f17 51w' sizes='0.1dppx'>
+<img srcset='/images/green-1x1.png?f18 50w, /images/green-16x16.png?f18 51w' data-foo='1px' sizes='attr(data-foo, length, 1px)'>
+<img srcset='/images/green-1x1.png?f19 50w, /images/green-16x16.png?f19 51w' data-foo='1' sizes='attr(data-foo, px, 1px)'>
+<img srcset='/images/green-1x1.png?f20 50w, /images/green-16x16.png?f20 51w' sizes='toggle(1px)'>
+<img srcset='/images/green-1x1.png?f21 50w, /images/green-16x16.png?f21 51w' sizes='inherit'>
+<img srcset='/images/green-1x1.png?f22 50w, /images/green-16x16.png?f22 51w' sizes='auto'>
+<img srcset='/images/green-1x1.png?f23 50w, /images/green-16x16.png?f23 51w' sizes='initial'>
+<img srcset='/images/green-1x1.png?f24 50w, /images/green-16x16.png?f24 51w' sizes='unset'>
+<img srcset='/images/green-1x1.png?f25 50w, /images/green-16x16.png?f25 51w' sizes='default'>
+<img srcset='/images/green-1x1.png?f26 50w, /images/green-16x16.png?f26 51w' sizes='1/* */px'>
+<img srcset='/images/green-1x1.png?f27 50w, /images/green-16x16.png?f27 51w' sizes='1p/* */x'>
+<img srcset='/images/green-1x1.png?f28 50w, /images/green-16x16.png?f28 51w' sizes='-/**/0'>
+<img srcset='/images/green-1x1.png?f29 50w, /images/green-16x16.png?f29 51w' sizes='((),1px'>
+<img srcset='/images/green-1x1.png?f30 50w, /images/green-16x16.png?f30 51w' sizes='x(x(),1px'>
+<img srcset='/images/green-1x1.png?f31 50w, /images/green-16x16.png?f31 51w' sizes='{{},1px'>
+<img srcset='/images/green-1x1.png?f32 50w, /images/green-16x16.png?f32 51w' sizes='[[],1px'>
+<img srcset='/images/green-1x1.png?f33 50w, /images/green-16x16.png?f33 51w' sizes='1px !important'>
+<img srcset='/images/green-1x1.png?f34 50w, /images/green-16x16.png?f34 51w' sizes='\1px'>
+<img srcset='/images/green-1x1.png?f35 50w, /images/green-16x16.png?f35 51w' sizes='all 1px'>
+<img srcset='/images/green-1x1.png?f36 50w, /images/green-16x16.png?f36 51w' sizes='all and (min-width:0) 1px'>
+<img srcset='/images/green-1x1.png?f37 50w, /images/green-16x16.png?f37 51w' sizes='min-width:0 1px'>
+<img srcset='/images/green-1x1.png?f38 50w, /images/green-16x16.png?f38 51w' sizes='100vw, 1px'>
+<img srcset='/images/green-1x1.png?f39 50w, /images/green-16x16.png?f39 51w' sizes='100vw, (min-width:0) 1px'>
+<img srcset='/images/green-1x1.png?f40 50w, /images/green-16x16.png?f40 51w' sizes='foo bar'>
+<img srcset='/images/green-1x1.png?f41 50w, /images/green-16x16.png?f41 51w' sizes='foo-bar'>
+<img srcset='/images/green-1x1.png?f42 50w, /images/green-16x16.png?f42 51w' sizes='(min-width:0) 1px foo bar'>
+<img srcset='/images/green-1x1.png?f43 50w, /images/green-16x16.png?f43 51w' sizes='(min-width:0) 0.1%'>
+<img srcset='/images/green-1x1.png?f44 50w, /images/green-16x16.png?f44 51w' sizes='(min-width:0) 1'>
+<img srcset='/images/green-1x1.png?f45 50w, /images/green-16x16.png?f45 51w' sizes='-1e0px'>
+<img srcset='/images/green-1x1.png?f46 50w, /images/green-16x16.png?f46 51w' sizes='1e1.5px'>
+<img srcset='/images/green-1x1.png?f47 50w, /images/green-16x16.png?f47 51w' style='--foo: 1px' sizes='var(--foo)'>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-img-element/srcset/common.js b/testing/web-platform/tests/html/semantics/embedded-content/the-img-element/srcset/common.js
new file mode 100644
index 000000000..d4d2c7534
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-img-element/srcset/common.js
@@ -0,0 +1,25 @@
+setup({explicit_done:true});
+
+function check(img) {
+ var name = format_value(img.getAttribute('srcset'));
+ if (img.hasAttribute('sizes')) {
+ name += ' sizes=' + format_value(img.getAttribute('sizes'));
+ }
+ if (img.hasAttribute('data-desc')) {
+ name += ' (' + img.getAttribute('data-desc') + ')';
+ }
+ test(function() {
+ var expect = img.dataset.expect;
+ if ('resolve' in img.dataset) {
+ var a = document.createElement('a');
+ a.href = expect;
+ expect = a.href;
+ }
+ assert_equals(img.currentSrc, expect);
+ }, name);
+}
+
+onload = function() {
+ [].forEach.call(document.images, check);
+ done();
+};
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-img-element/srcset/parse-a-srcset-attribute.html b/testing/web-platform/tests/html/semantics/embedded-content/the-img-element/srcset/parse-a-srcset-attribute.html
new file mode 100644
index 000000000..ce1e4cebe
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-img-element/srcset/parse-a-srcset-attribute.html
@@ -0,0 +1,245 @@
+<!doctype html>
+<title>img parse a srcset attribute</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src=common.js></script>
+<div id=log></div>
+<!-- splitting loop -->
+<img srcset='' data-expect=''>
+<img srcset=',' data-expect=''>
+<img srcset=',,,' data-expect=''>
+<img srcset=' data:,a 1x ' data-expect='data:,a'>
+<img srcset='&#x9;&#x9;data:,a&#x9;&#x9;1x&#x9;&#x9;' data-expect='data:,a'>
+<img srcset='&#xA;&#xA;data:,a&#xA;&#xA;1x&#xA;&#xA;' data-expect='data:,a'>
+<img srcset='&#xB;&#xB;data:,a&#xB;&#xB;1x&#xB;&#xB;' data-expect='&#xB;&#xB;data:,a&#xB;&#xB;1x&#xB;&#xB;' data-resolve>
+<img srcset='&#xC;&#xC;data:,a&#xC;&#xC;1x&#xC;&#xC;' data-expect='data:,a'>
+<img srcset='&#xD;&#xD;data:,a&#xD;&#xD;1x&#xD;&#xD;' data-expect='data:,a'>
+<img srcset='&#xE;&#xE;data:,a&#xE;&#xE;1x&#xE;&#xE;' data-expect='&#xE;&#xE;data:,a&#xE;&#xE;1x&#xE;&#xE;' data-resolve>
+<img srcset='&#xF;&#xF;data:,a&#xF;&#xF;1x&#xF;&#xF;' data-expect='&#xF;&#xF;data:,a&#xF;&#xF;1x&#xF;&#xF;' data-resolve>
+<img srcset='&#x10;&#x10;data:,a&#x10;&#x10;1x&#x10;&#x10;' data-expect='&#x10;&#x10;data:,a&#x10;&#x10;1x&#x10;&#x10;' data-resolve>
+<img srcset='data:,a' data-expect='data:,a'>
+<img srcset='data:,a ' data-expect='data:,a'>
+<img srcset='data:,a ,' data-expect='data:,a'>
+<img srcset='data:,a,' data-expect='data:,a'>
+<img srcset='data:,a, ' data-expect='data:,a'>
+<img srcset='data:,a,,,' data-expect='data:,a'>
+<img srcset='data:,a,, , ' data-expect='data:,a'>
+<img srcset=' data:,a' data-expect='data:,a'>
+<img srcset=',,,data:,a' data-expect='data:,a'>
+<img srcset=' , ,,data:,a' data-expect='data:,a'>
+<img srcset='&nbsp;data:,a' data-expect='&nbsp;data:,a' data-resolve>
+<img srcset='data:,a&nbsp;' data-expect='data:,a&nbsp;' data-resolve>
+<!-- descriptor tokenizer -->
+<img srcset='data:,a 1x' data-expect='data:,a'>
+<img srcset='data:,a 1x ' data-expect='data:,a'>
+<img srcset='data:,a 1x,' data-expect='data:,a'>
+<img srcset='data:,a ( , data:,b 1x, ), data:,c' data-expect='data:,c'>
+<img srcset='data:,a ((( , data:,b 1x, ), data:,c' data-expect='data:,c'>
+<img srcset='data:,a [ , data:,b 1x, ], data:,c' data-expect='data:,b'>
+<img srcset='data:,a { , data:,b 1x, }, data:,c' data-expect='data:,b'>
+<img srcset='data:,a " , data:,b 1x, ", data:,c' data-expect='data:,b'>
+<img srcset='data:,a \,data:;\,b, data:,c' data-expect='data:;\,b'>
+<img srcset='data:,a, data:,b (' data-expect='data:,a'>
+<img srcset='data:,a, data:,b ( ' data-expect='data:,a'>
+<img srcset='data:,a, data:,b (,' data-expect='data:,a'>
+<img srcset='data:,a, data:,b (x' data-expect='data:,a'>
+<img srcset='data:,a, data:,b ()' data-expect='data:,a'>
+<img srcset='data:,a (, data:,b' data-expect=''>
+<img srcset='data:,a /*, data:,b, data:,c */' data-expect='data:,b'>
+<img srcset='data:,a //, data:,b' data-expect='data:,b'>
+<!-- descriptor parser -->
+<img srcset='data:,a foo' data-expect=''>
+<img srcset='data:,a foo foo' data-expect=''>
+<img srcset='data:,a foo 1x' data-expect=''>
+<img srcset='data:,a foo 1x foo' data-expect=''>
+<img srcset='data:,a foo 1w' data-expect=''>
+<img srcset='data:,a foo 1w foo' data-expect=''>
+<img srcset='data:,a 1x 1x' data-expect=''>
+<img srcset='data:,a 1w 1w' data-expect=''>
+<img srcset='data:,a 1w 1x' data-expect=''>
+<img srcset='data:,a 1x 1w' data-expect=''>
+<img srcset='data:,a 1w 1h' data-expect='data:,a'><!-- should fail for x-only impl -->
+<img srcset='data:,a 1h 1w' data-expect='data:,a'><!-- should fail for x-only impl -->
+<img srcset='data:,a 1h 1h' data-expect=''>
+<img srcset='data:,a 1h 1x' data-expect=''>
+<img srcset='data:,a 1h 1w 1x' data-expect=''>
+<img srcset='data:,a 1x 1w 1h' data-expect=''>
+<img srcset='data:,a 1w' data-expect='data:,a'><!-- should fail for x-only impl -->
+<img srcset='data:,a 1h' data-expect=''>
+<img srcset='data:,a 1h foo' data-expect=''>
+<img srcset='data:,a foo 1h' data-expect=''>
+<img srcset='data:,a 0w' data-expect=''>
+<img srcset='data:,a -1w' data-expect=''>
+<img srcset='data:,a 1w -1w' data-expect=''>
+<img srcset='data:,a 1.0w' data-expect=''>
+<img srcset='data:,a 1w 1.0w' data-expect=''>
+<img srcset='data:,a 1e0w' data-expect=''>
+<img srcset='data:,a 1w 1e0w' data-expect=''>
+<img srcset='data:,a 1www' data-expect=''>
+<img srcset='data:,a 1w 1www' data-expect=''>
+<img srcset='data:,a +1w' data-expect=''>
+<img srcset='data:,a 1w +1w' data-expect=''>
+<img srcset='data:,a 1W' data-expect=''>
+<img srcset='data:,a 1w 1W' data-expect=''>
+<img srcset='data:,a Infinityw' data-expect=''>
+<img srcset='data:,a 1w Infinityw' data-expect=''>
+<img srcset='data:,a NaNw' data-expect=''>
+<img srcset='data:,a 1w NaNw' data-expect=''>
+<img srcset='data:,a 0x1w' data-expect=''>
+<img srcset='data:,a 0X1w' data-expect=''>
+<img srcset='data:,a 1&#x1;w' data-expect='' data-desc='trailing U+0001'>
+<img srcset='data:,a 1&nbsp;w' data-expect='' data-desc='trailing U+00A0'>
+<img srcset='data:,a 1&#x1680;w' data-expect='' data-desc='trailing U+1680'>
+<img srcset='data:,a 1&#x2000;w' data-expect='' data-desc='trailing U+2000'>
+<img srcset='data:,a 1&#x2001;w' data-expect='' data-desc='trailing U+2001'>
+<img srcset='data:,a 1&#x2002;w' data-expect='' data-desc='trailing U+2002'>
+<img srcset='data:,a 1&#x2003;w' data-expect='' data-desc='trailing U+2003'>
+<img srcset='data:,a 1&#x2004;w' data-expect='' data-desc='trailing U+2004'>
+<img srcset='data:,a 1&#x2005;w' data-expect='' data-desc='trailing U+2005'>
+<img srcset='data:,a 1&#x2006;w' data-expect='' data-desc='trailing U+2006'>
+<img srcset='data:,a 1&#x2007;w' data-expect='' data-desc='trailing U+2007'>
+<img srcset='data:,a 1&#x2008;w' data-expect='' data-desc='trailing U+2008'>
+<img srcset='data:,a 1&#x2009;w' data-expect='' data-desc='trailing U+2009'>
+<img srcset='data:,a 1&#x200A;w' data-expect='' data-desc='trailing U+200A'>
+<img srcset='data:,a 1&#x200C;w' data-expect='' data-desc='trailing U+200C'>
+<img srcset='data:,a 1&#x200D;w' data-expect='' data-desc='trailing U+200D'>
+<img srcset='data:,a 1&#x202F;w' data-expect='' data-desc='trailing U+202F'>
+<img srcset='data:,a 1&#x205F;w' data-expect='' data-desc='trailing U+205F'>
+<img srcset='data:,a 1&#x3000;w' data-expect='' data-desc='trailing U+3000'>
+<img srcset='data:,a 1&#xFEFF;w' data-expect='' data-desc='trailing U+FEFF'>
+<img srcset='data:,a &#x1;1w' data-expect='' data-desc='leading U+0001'>
+<img srcset='data:,a &nbsp;1w' data-expect='' data-desc='leading U+00A0'>
+<img srcset='data:,a &#x1680;1w' data-expect='' data-desc='leading U+1680'>
+<img srcset='data:,a &#x2000;1w' data-expect='' data-desc='leading U+2000'>
+<img srcset='data:,a &#x2001;1w' data-expect='' data-desc='leading U+2001'>
+<img srcset='data:,a &#x2002;1w' data-expect='' data-desc='leading U+2002'>
+<img srcset='data:,a &#x2003;1w' data-expect='' data-desc='leading U+2003'>
+<img srcset='data:,a &#x2004;1w' data-expect='' data-desc='leading U+2004'>
+<img srcset='data:,a &#x2005;1w' data-expect='' data-desc='leading U+2005'>
+<img srcset='data:,a &#x2006;1w' data-expect='' data-desc='leading U+2006'>
+<img srcset='data:,a &#x2007;1w' data-expect='' data-desc='leading U+2007'>
+<img srcset='data:,a &#x2008;1w' data-expect='' data-desc='leading U+2008'>
+<img srcset='data:,a &#x2009;1w' data-expect='' data-desc='leading U+2009'>
+<img srcset='data:,a &#x200A;1w' data-expect='' data-desc='leading U+200A'>
+<img srcset='data:,a &#x200C;1w' data-expect='' data-desc='leading U+200C'>
+<img srcset='data:,a &#x200D;1w' data-expect='' data-desc='leading U+200D'>
+<img srcset='data:,a &#x202F;1w' data-expect='' data-desc='leading U+202F'>
+<img srcset='data:,a &#x205F;1w' data-expect='' data-desc='leading U+205F'>
+<img srcset='data:,a &#x3000;1w' data-expect='' data-desc='leading U+3000'>
+<img srcset='data:,a &#xFEFF;1w' data-expect='' data-desc='leading U+FEFF'>
+<img srcset='data:,a 0x' data-expect='data:,a'>
+<img srcset='data:,a -0x' data-expect='data:,a'>
+<img srcset='data:,a 1x -0x' data-expect=''>
+<img srcset='data:,a -1x' data-expect=''>
+<img srcset='data:,a 1x -1x' data-expect=''>
+<img srcset='data:,a 1e0x' data-expect='data:,a'>
+<img srcset='data:,a 1E0x' data-expect='data:,a'>
+<img srcset='data:,a 1e-1x' data-expect='data:,a'>
+<img srcset='data:,a 1.5e1x' data-expect='data:,a'>
+<img srcset='data:,a -x' data-expect=''>
+<img srcset='data:,a .x' data-expect=''>
+<img srcset='data:,a -.x' data-expect=''>
+<img srcset='data:,a 1.x' data-expect=''>
+<img srcset='data:,a .5x' data-expect='data:,a'>
+<img srcset='data:,a .5e1x' data-expect='data:,a'>
+<img srcset='data:,a 1x 1.5e1x' data-expect=''>
+<img srcset='data:,a 1x 1e1.5x' data-expect=''>
+<img srcset='data:,a 1.0x' data-expect='data:,a'>
+<img srcset='data:,a 1x 1.0x' data-expect=''>
+<img srcset='data:,a +1x' data-expect=''>
+<img srcset='data:,a 1X' data-expect=''>
+<img srcset='data:,a Infinityx' data-expect=''>
+<img srcset='data:,a NaNx' data-expect=''>
+<img srcset='data:,a 0x1x' data-expect=''>
+<img srcset='data:,a 0X1x' data-expect=''>
+<img srcset='data:,a 1&#x1;x' data-expect='' data-desc='trailing U+0001'>
+<img srcset='data:,a 1&nbsp;x' data-expect='' data-desc='trailing U+00A0'>
+<img srcset='data:,a 1&#x1680;x' data-expect='' data-desc='trailing U+1680'>
+<img srcset='data:,a 1&#x2000;x' data-expect='' data-desc='trailing U+2000'>
+<img srcset='data:,a 1&#x2001;x' data-expect='' data-desc='trailing U+2001'>
+<img srcset='data:,a 1&#x2002;x' data-expect='' data-desc='trailing U+2002'>
+<img srcset='data:,a 1&#x2003;x' data-expect='' data-desc='trailing U+2003'>
+<img srcset='data:,a 1&#x2004;x' data-expect='' data-desc='trailing U+2004'>
+<img srcset='data:,a 1&#x2005;x' data-expect='' data-desc='trailing U+2005'>
+<img srcset='data:,a 1&#x2006;x' data-expect='' data-desc='trailing U+2006'>
+<img srcset='data:,a 1&#x2007;x' data-expect='' data-desc='trailing U+2007'>
+<img srcset='data:,a 1&#x2008;x' data-expect='' data-desc='trailing U+2008'>
+<img srcset='data:,a 1&#x2009;x' data-expect='' data-desc='trailing U+2009'>
+<img srcset='data:,a 1&#x200A;x' data-expect='' data-desc='trailing U+200A'>
+<img srcset='data:,a 1&#x200C;x' data-expect='' data-desc='trailing U+200C'>
+<img srcset='data:,a 1&#x200D;x' data-expect='' data-desc='trailing U+200D'>
+<img srcset='data:,a 1&#x202F;x' data-expect='' data-desc='trailing U+202F'>
+<img srcset='data:,a 1&#x205F;x' data-expect='' data-desc='trailing U+205F'>
+<img srcset='data:,a 1&#x3000;x' data-expect='' data-desc='trailing U+3000'>
+<img srcset='data:,a 1&#xFEFF;x' data-expect='' data-desc='trailing U+FEFF'>
+<img srcset='data:,a &#x1;1x' data-expect='' data-desc='leading U+0001'>
+<img srcset='data:,a &nbsp;1x' data-expect='' data-desc='leading U+00A0'>
+<img srcset='data:,a &#x1680;1x' data-expect='' data-desc='leading U+1680'>
+<img srcset='data:,a &#x2000;1x' data-expect='' data-desc='leading U+2000'>
+<img srcset='data:,a &#x2001;1x' data-expect='' data-desc='leading U+2001'>
+<img srcset='data:,a &#x2002;1x' data-expect='' data-desc='leading U+2002'>
+<img srcset='data:,a &#x2003;1x' data-expect='' data-desc='leading U+2003'>
+<img srcset='data:,a &#x2004;1x' data-expect='' data-desc='leading U+2004'>
+<img srcset='data:,a &#x2005;1x' data-expect='' data-desc='leading U+2005'>
+<img srcset='data:,a &#x2006;1x' data-expect='' data-desc='leading U+2006'>
+<img srcset='data:,a &#x2007;1x' data-expect='' data-desc='leading U+2007'>
+<img srcset='data:,a &#x2008;1x' data-expect='' data-desc='leading U+2008'>
+<img srcset='data:,a &#x2009;1x' data-expect='' data-desc='leading U+2009'>
+<img srcset='data:,a &#x200A;1x' data-expect='' data-desc='leading U+200A'>
+<img srcset='data:,a &#x200C;1x' data-expect='' data-desc='leading U+200C'>
+<img srcset='data:,a &#x200D;1x' data-expect='' data-desc='leading U+200D'>
+<img srcset='data:,a &#x202F;1x' data-expect='' data-desc='leading U+202F'>
+<img srcset='data:,a &#x205F;1x' data-expect='' data-desc='leading U+205F'>
+<img srcset='data:,a &#x3000;1x' data-expect='' data-desc='leading U+3000'>
+<img srcset='data:,a &#xFEFF;1x' data-expect='' data-desc='leading U+FEFF'>
+<img srcset='data:,a 1w 0h' data-expect=''>
+<img srcset='data:,a 1w -1h' data-expect=''>
+<img srcset='data:,a 1w 1.0h' data-expect=''>
+<img srcset='data:,a 1w 1e0h' data-expect=''>
+<img srcset='data:,a 1w 1hhh' data-expect=''>
+<img srcset='data:,a 1w +1h' data-expect=''>
+<img srcset='data:,a 1w 1H' data-expect=''>
+<img srcset='data:,a 1w Infinityh' data-expect=''>
+<img srcset='data:,a 1w NaNh' data-expect=''>
+<img srcset='data:,a 0x1h' data-expect=''>
+<img srcset='data:,a 0X1h' data-expect=''>
+<img srcset='data:,a 1w 1&#x1;h' data-expect='' data-desc='trailing U+0001'>
+<img srcset='data:,a 1w 1&nbsp;h' data-expect='' data-desc='trailing U+00A0'>
+<img srcset='data:,a 1w 1&#x1680;h' data-expect='' data-desc='trailing U+1680'>
+<img srcset='data:,a 1w 1&#x2000;h' data-expect='' data-desc='trailing U+2000'>
+<img srcset='data:,a 1w 1&#x2001;h' data-expect='' data-desc='trailing U+2001'>
+<img srcset='data:,a 1w 1&#x2002;h' data-expect='' data-desc='trailing U+2002'>
+<img srcset='data:,a 1w 1&#x2003;h' data-expect='' data-desc='trailing U+2003'>
+<img srcset='data:,a 1w 1&#x2004;h' data-expect='' data-desc='trailing U+2004'>
+<img srcset='data:,a 1w 1&#x2005;h' data-expect='' data-desc='trailing U+2005'>
+<img srcset='data:,a 1w 1&#x2006;h' data-expect='' data-desc='trailing U+2006'>
+<img srcset='data:,a 1w 1&#x2007;h' data-expect='' data-desc='trailing U+2007'>
+<img srcset='data:,a 1w 1&#x2008;h' data-expect='' data-desc='trailing U+2008'>
+<img srcset='data:,a 1w 1&#x2009;h' data-expect='' data-desc='trailing U+2009'>
+<img srcset='data:,a 1w 1&#x200A;h' data-expect='' data-desc='trailing U+200A'>
+<img srcset='data:,a 1w 1&#x200C;h' data-expect='' data-desc='trailing U+200C'>
+<img srcset='data:,a 1w 1&#x200D;h' data-expect='' data-desc='trailing U+200D'>
+<img srcset='data:,a 1w 1&#x202F;h' data-expect='' data-desc='trailing U+202F'>
+<img srcset='data:,a 1w 1&#x205F;h' data-expect='' data-desc='trailing U+205F'>
+<img srcset='data:,a 1w 1&#x3000;h' data-expect='' data-desc='trailing U+3000'>
+<img srcset='data:,a 1w 1&#xFEFF;h' data-expect='' data-desc='trailing U+FEFF'>
+<img srcset='data:,a 1w &#x1;1h' data-expect='' data-desc='leading U+0001'>
+<img srcset='data:,a 1w &nbsp;1h' data-expect='' data-desc='leading U+00A0'>
+<img srcset='data:,a 1w &#x1680;1h' data-expect='' data-desc='leading U+1680'>
+<img srcset='data:,a 1w &#x2000;1h' data-expect='' data-desc='leading U+2000'>
+<img srcset='data:,a 1w &#x2001;1h' data-expect='' data-desc='leading U+2001'>
+<img srcset='data:,a 1w &#x2002;1h' data-expect='' data-desc='leading U+2002'>
+<img srcset='data:,a 1w &#x2003;1h' data-expect='' data-desc='leading U+2003'>
+<img srcset='data:,a 1w &#x2004;1h' data-expect='' data-desc='leading U+2004'>
+<img srcset='data:,a 1w &#x2005;1h' data-expect='' data-desc='leading U+2005'>
+<img srcset='data:,a 1w &#x2006;1h' data-expect='' data-desc='leading U+2006'>
+<img srcset='data:,a 1w &#x2007;1h' data-expect='' data-desc='leading U+2007'>
+<img srcset='data:,a 1w &#x2008;1h' data-expect='' data-desc='leading U+2008'>
+<img srcset='data:,a 1w &#x2009;1h' data-expect='' data-desc='leading U+2009'>
+<img srcset='data:,a 1w &#x200A;1h' data-expect='' data-desc='leading U+200A'>
+<img srcset='data:,a 1w &#x200C;1h' data-expect='' data-desc='leading U+200C'>
+<img srcset='data:,a 1w &#x200D;1h' data-expect='' data-desc='leading U+200D'>
+<img srcset='data:,a 1w &#x202F;1h' data-expect='' data-desc='leading U+202F'>
+<img srcset='data:,a 1w &#x205F;1h' data-expect='' data-desc='leading U+205F'>
+<img srcset='data:,a 1w &#x3000;1h' data-expect='' data-desc='leading U+3000'>
+<img srcset='data:,a 1w &#xFEFF;1h' data-expect='' data-desc='leading U+FEFF'>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-img-element/srcset/select-an-image-source.html b/testing/web-platform/tests/html/semantics/embedded-content/the-img-element/srcset/select-an-image-source.html
new file mode 100644
index 000000000..292395d3a
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-img-element/srcset/select-an-image-source.html
@@ -0,0 +1,20 @@
+<!doctype html>
+<title>img select an image source</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src=common.js></script>
+<div id=log></div>
+<!-- dup entries -->
+<img srcset='data:,a 1x, data:,b 1x' data-expect='data:,a'>
+<img srcset='data:,a , data:,b 1x' data-expect='data:,a'>
+<img srcset='data:,a 1x, data:,b' data-expect='data:,a'>
+<img srcset='data:,a 1w, data:,b 1w' data-expect='data:,a'>
+<img srcset='data:,a 1w 1h, data:,b 1w' data-expect='data:,a'>
+<img srcset='data:,a 1w, data:,b 1w 1h' data-expect='data:,a'>
+<img srcset='data:,a 1w 1h, data:,b 1w 2h' data-expect='data:,a'>
+<img srcset='data:,a 1w 2h, data:,b 1w 1h' data-expect='data:,a'>
+<img srcset='data:,a , data:,b' data-expect='data:,a'>
+<img srcset='data:,a 1w, data:,b 1x' sizes='1px' data-expect='data:,a'>
+<img srcset='data:,a 1x, data:,b 1w' sizes='1px' data-expect='data:,a'>
+<img srcset='data:,a 1w, data:,b 2x' sizes='0.5px' data-expect='data:,a'>
+<img srcset='data:,a 2x, data:,b 1w' sizes='0.5px' data-expect='data:,a'>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-img-element/update-media.html b/testing/web-platform/tests/html/semantics/embedded-content/the-img-element/update-media.html
new file mode 100644
index 000000000..dd679ef57
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-img-element/update-media.html
@@ -0,0 +1,32 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>img update media</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+ var t = async_test('set media after src updates selected image');
+
+ var img;
+
+ onload = t.step_func(function() {
+ img = document.querySelector('img');
+ img.addEventListener('load', t.step_func_done(onImgLoad));
+
+ var source = document.querySelector('source[data-media]');
+ source.setAttribute('media', source.getAttribute('data-media'));
+ });
+
+ function onImgLoad() {
+ img.removeEventListener('load', onImgLoad);
+
+ assert_true(img.currentSrc.indexOf(img.getAttribute('data-expect')) > -1);
+ }
+
+</script>
+
+<div id="log"></div>
+<picture>
+ <source srcset="/images/fail.gif" data-media="(max-width: 1px)" />
+ <source srcset="/images/smiley.png" />
+ <img data-expect="/images/smiley.png">
+</picture> \ No newline at end of file
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-img-element/update-src-complete.html b/testing/web-platform/tests/html/semantics/embedded-content/the-img-element/update-src-complete.html
new file mode 100644
index 000000000..20cb95915
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-img-element/update-src-complete.html
@@ -0,0 +1,23 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>Changing the img src should retain the 'complete' property</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<p id="display"><img src="image.png"></p>
+<script>
+ function check() {
+ var img = document.querySelector("img");
+ assert_true(img.complete, "By onload, image should have loaded");
+ img.src = `image.png?${Math.random()}`;
+ assert_false(img.complete, "Now that we're loading we should no longer be complete");
+ img.onload = function () {
+ assert_true(img.complete, "The new thing should have loaded.");
+ done();
+ }
+ }
+
+ onload = function () {
+ check();
+ };
+
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-img-element/update-the-image-data/fail-to-resolve.html b/testing/web-platform/tests/html/semantics/embedded-content/the-img-element/update-the-image-data/fail-to-resolve.html
new file mode 100644
index 000000000..959ceaa97
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-img-element/update-the-image-data/fail-to-resolve.html
@@ -0,0 +1,25 @@
+<!doctype html>
+<title>img update the image data: fail to resolve URL</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+
+<img src="//[">
+<img srcset="//[">
+<img srcset="//[" src="/images/red.png">
+<img srcset="//[, /images/red.png">
+
+<script>
+setup({explicit_done: true});
+
+var expected = '//[';
+
+onload = function() {
+ [].forEach.call(document.images, function(img) {
+ test(function() {
+ assert_equals(img.currentSrc, expected);
+ }, img.outerHTML);
+ });
+ done();
+};
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-img-element/update-the-source-set.html b/testing/web-platform/tests/html/semantics/embedded-content/the-img-element/update-the-source-set.html
new file mode 100644
index 000000000..063667baa
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-img-element/update-the-source-set.html
@@ -0,0 +1,140 @@
+<!doctype html>
+<title>img update the source set</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+setup({explicit_done:true});
+
+function check(p) {
+ var img = p.querySelector('[data-expect]');
+ test(function() {
+ var expect = img.dataset.expect;
+ if ('resolve' in img.dataset) {
+ var a = document.createElement('a');
+ a.href = expect;
+ expect = a.href;
+ }
+ assert_equals(img.currentSrc, expect);
+ }, p.innerHTML);
+}
+
+onload = function() {
+ [].forEach.call(document.querySelectorAll('div:not([id])'), check);
+ done();
+};
+
+</script>
+<div id=log></div>
+<div><img data-expect=''></div>
+<div><img src data-expect=''></div>
+<div><img src='data:,a' data-expect='data:,a'></div>
+<div><img srcset src='data:,a' data-expect='data:,a'></div>
+<div><img srcset='data:,b' src='data:,a' data-expect='data:,b'></div>
+<div><img src='data:,a' srcset='data:,b' data-expect='data:,b'><!-- srcset after src --></div>
+<div><img src='data:,a' srcset='data:,b 1x' data-expect='data:,b'></div>
+<div><img src='data:,a' srcset='data:,b 1.0x' data-expect='data:,b'></div>
+<div><img src='data:,a' srcset='data:,b 1e0x' data-expect='data:,b'></div>
+<div><img src='data:,a' srcset='data:,b 10000w' sizes='1px' data-expect='data:,b'></div>
+<div><img src='data:,a' srcset='data:,b 10000w, data:,c 10000x' sizes='1px' data-expect='data:,b'></div>
+<div><img src='data:,a' srcset='data:,b 10000x, data:,c 10000w' sizes='1px' data-expect='data:,b'></div>
+<div><img src='data:,a' srcset='data:,b 1w' sizes='10000px' data-expect='data:,b'></div>
+<div><img src='data:,a' srcset='data:,b 1w, data:,c 0.0001x' sizes='10000px' data-expect='data:,b'></div>
+<div><img src='data:,a' srcset='data:,b 0.0001x, data:,c 1w' sizes='10000px' data-expect='data:,b'></div>
+<div><img srcset='data:,a' data-expect='data:,a'></div>
+
+<!-- child is not a <source> -->
+
+<div><picture>foo<img src='data:,a' data-expect='data:,a'></picture></div>
+<div><picture><!--foo--><img src='data:,a' data-expect='data:,a'></picture></div>
+<div><picture><br><img src='data:,a' data-expect='data:,a'></picture></div>
+<div><picture><p></p><img src='data:,a' data-expect='data:,a'></picture></div>
+<div><picture><video><source srcset='data:,b'></video><img src='data:,a' data-expect='data:,a'></picture></div>
+<div><picture><span><source srcset='data:,b'></span><img src='data:,a' data-expect='data:,a'></picture></div>
+<div><picture><svg><source srcset='data:,b'/></svg><img src='data:,a' data-expect='data:,a'></picture></div>
+<div><picture><svg/><source srcset='data:,b'/><img src='data:,a' data-expect='data:,b'></picture></div>
+<div><picture><svg><font/><source srcset='data:,b'/></svg><img src='data:,a' data-expect='data:,a'></picture></div>
+<div><picture><svg><!--<font face> tag breaks out of svg--><font face></font><source srcset='data:,b'/></svg><img src='data:,a' data-expect='data:,b'></picture></div>
+<div><picture><img src='data:,a'><img src='data:,b' data-expect='data:,b'></picture></div>
+
+<!-- <source> has no srcset -->
+
+<div><picture><source><img src='data:,a' data-expect='data:,a'></picture></div>
+<div><picture><source src='data:,b'><img src='data:,a' data-expect='data:,a'></picture></div>
+
+<!-- <source srcset> has zero candidates -->
+
+<div><picture><source srcset><img src='data:,a' data-expect='data:,a'></picture></div>
+<div><picture><source srcset=', ,'><img src='data:,a' data-expect='data:,a'></picture></div>
+<div><picture><source srcset='data:,b 1x 1x'><img src='data:,a' data-expect='data:,a'></picture></div>
+
+<!-- <source media> -->
+
+<div><picture><source srcset='data:,b' media><img src='data:,a' data-expect='data:,b'></picture></div>
+<div><picture><source srcset='data:,b' media='all'><img src='data:,a' data-expect='data:,b'></picture></div>
+<div><picture><source srcset='data:,b' media='all and (min-width:0)'><img src='data:,a' data-expect='data:,b'></picture></div>
+<div><picture><source srcset='data:,b' media='all and !'><img src='data:,a' data-expect='data:,a'></picture></div>
+<div><picture><source srcset='data:,b' media='all and (!)'><img src='data:,a' data-expect='data:,a'></picture></div>
+<div><picture><source srcset='data:,b' media='not all'><img src='data:,a' data-expect='data:,a'></picture></div>
+<div><picture><source srcset='data:,b' media='not all and (min-width:0)'><img src='data:,a' data-expect='data:,a'></picture></div>
+<div><picture><source srcset='data:,b' media='not all and (max-width:0)'><img src='data:,a' data-expect='data:,b'></picture></div>
+<div><picture><source srcset='data:,b' media='not all and !'><img src='data:,a' data-expect='data:,a'></picture></div>
+<div><picture><source srcset='data:,b' media='not all and (!)'><img src='data:,a' data-expect='data:,a'></picture></div>
+<div><picture><source srcset='data:,b' media='all, !'><img src='data:,a' data-expect='data:,b'></picture></div>
+<div><picture><source srcset='data:,b' media=','><img src='data:,a' data-expect='data:,a'></picture></div>
+<div><picture><source srcset='data:,b' media=', all'><img src='data:,a' data-expect='data:,b'></picture></div>
+
+<!-- <source type> assume support for gif, png, jpg, svg, ico -->
+
+<div><picture><source srcset='data:,b' type><img src='data:,a' data-expect='data:,b'></picture></div>
+<div><picture><source srcset='data:,b' type=' '><img src='data:,a' data-expect='data:,b'></picture></div>
+<div><picture><source srcset='data:,b' type='image/gif'><img src='data:,a' data-expect='data:,b'></picture></div>
+<div><picture><source srcset='data:,b' type=' image/gif'><img src='data:,a' data-expect='data:,b'></picture></div>
+<div><picture><source srcset='data:,b' type='image/gif '><img src='data:,a' data-expect='data:,b'></picture></div>
+<div><picture><source srcset='data:,b' type='image/gif;'><img src='data:,a' data-expect='data:,b'></picture></div>
+<div><picture><source srcset='data:,b' type='image/gif;encodings'><img src='data:,a' data-expect='data:,b'></picture></div>
+<div><picture><source srcset='data:,b' type='image/gif;encodings='><img src='data:,a' data-expect='data:,b'></picture></div>
+<div><picture><source srcset='data:,b' type='image/gif;encodings=foobar'><img src='data:,a' data-expect='data:,b'></picture></div>
+<div><picture><source srcset='data:,b' type='image/png'><img src='data:,a' data-expect='data:,b'></picture></div>
+<div><picture><source srcset='data:,b' type='image/jpeg'><img src='data:,a' data-expect='data:,b'></picture></div>
+<div><picture><source srcset='data:,b' type='image/svg+xml'><img src='data:,a' data-expect='data:,b'></picture></div>
+<div><picture><source srcset='data:,b' type='image/x-icon'><img src='data:,a' data-expect='data:,b'></picture></div>
+<div><picture><source srcset='data:,b' type='text/xml'><img src='data:,a' data-expect='data:,a'></picture></div>
+<div><picture><source srcset='data:,b' type='text/html'><img src='data:,a' data-expect='data:,a'></picture></div>
+<div><picture><source srcset='data:,b' type='text/plain'><img src='data:,a' data-expect='data:,a'></picture></div>
+<div><picture><source srcset='data:,b' type='text/css'><img src='data:,a' data-expect='data:,a'></picture></div>
+<div><picture><source srcset='data:,b' type='video/mp4'><img src='data:,a' data-expect='data:,a'></picture></div>
+<div><picture><source srcset='data:,b' type='video/ogg'><img src='data:,a' data-expect='data:,a'></picture></div>
+<div><picture><source srcset='data:,b' type='video/webm'><img src='data:,a' data-expect='data:,a'></picture></div>
+<div><picture><source srcset='data:,b' type='unknown/unknown'><img src='data:,a' data-expect='data:,a'></picture></div>
+<div><picture><source srcset='data:,b' type='application/octet-stream'><img src='data:,a' data-expect='data:,a'></picture></div>
+<div><picture><source srcset='data:,b' type='application/x-shockwave-flash'><img src='data:,a' data-expect='data:,a'></picture></div>
+<div><picture><source srcset='data:,b' type='image\gif'><img src='data:,a' data-expect='data:,a'></picture></div>
+<div><picture><source srcset='data:,b' type='gif'><img src='data:,a' data-expect='data:,a'></picture></div>
+<div><picture><source srcset='data:,b' type='.gif'><img src='data:,a' data-expect='data:,a'></picture></div>
+<div><picture><source srcset='data:,b' type='*'><img src='data:,a' data-expect='data:,a'></picture></div>
+<div><picture><source srcset='data:,b' type='*/*'><img src='data:,a' data-expect='data:,a'></picture></div>
+<div><picture><source srcset='data:,b' type='image/*'><img src='data:,a' data-expect='data:,a'></picture></div>
+<div><picture><source srcset='data:,b' type=','><img src='data:,a' data-expect='data:,a'></picture></div>
+<div><picture><source srcset='data:,b' type='image/gif, image/png'><img src='data:,a' data-expect='data:,a'></picture></div>
+<div><picture><source srcset='data:,b' type='image/gif image/png'><img src='data:,a' data-expect='data:,a'></picture></div>
+<div><picture><source srcset='data:,b' type='image/foobarbaz'><img src='data:,a' data-expect='data:,a'></picture></div>
+
+<!-- trailing garbage -->
+
+<div><picture><img src='data:,a' data-expect='data:,a'>foo</picture></div>
+<div><picture><img src='data:,a' data-expect='data:,a'><br></picture></div>
+<div><picture><img src='data:,a' data-expect='data:,a'><!--foo--></picture></div>
+<div><picture><img src='data:,a' data-expect='data:,a'><img src='data:,b'></picture></div>
+<div><picture><img data-expect=''><img src='data:,b'></picture></div>
+<div><picture><img src='data:,a' data-expect='data:,a'><source srcset='data:,b'></picture></div>
+<div><picture><img data-expect=''><source srcset='data:,b'></picture></div>
+
+<!-- parent not picture -->
+
+<div><picture><span><source srcset='data:,b'><img data-expect=''></span></picture></div>
+<div><picture><span><source srcset='data:,b'><img src='data:,a' data-expect='data:,a'></span></picture></div>
+<div><picture><source srcset='data:,b'><span><img src='data:,a' data-expect='data:,a'></span></picture></div>
+
+<!-- no src -->
+
+<div><picture><source srcset='data:,b'><img data-expect='data:,b'></picture></div>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-map-element/.gitkeep b/testing/web-platform/tests/html/semantics/embedded-content/the-map-element/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-map-element/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-object-element/.gitkeep b/testing/web-platform/tests/html/semantics/embedded-content/the-object-element/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-object-element/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-object-element/object-attributes.html b/testing/web-platform/tests/html/semantics/embedded-content/the-object-element/object-attributes.html
new file mode 100644
index 000000000..30fdcf520
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-object-element/object-attributes.html
@@ -0,0 +1,50 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>HTML Test: object - attributes</title>
+<link rel="author" title="Intel" href="http://www.intel.com">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<body onload="on_load()">
+<div id="log"></div>
+<form>
+ <object id="obj1" data="blue.html" name="o" height="50" width="100"></object>
+ <object id="obj2" name="p" type="image/png"></object>
+</form>
+<script>
+ var obj1;
+ var obj2;
+ var t1 = async_test("object.contentWindow");
+ var t3 = async_test("object.width");
+ var t4 = async_test("object.height");
+
+ setup(function() {
+ obj1 = document.getElementById("obj1");
+ obj2 = document.getElementById("obj2");
+ });
+
+ function on_load () {
+ t1.step(function() {
+ assert_equals(obj1.contentWindow.name, "o", "The contentWindow's name of the object element should be 'o'.");
+ assert_equals(obj2.contentWindow, null, "The contentWindow of the object element should be null when it type attribute starts with 'image/'.");
+ obj1.setAttribute("name", "o1");
+ assert_equals(obj1.name, "o1", "The name of the object element should be 'o1'.");
+ assert_equals(obj1.contentWindow.name, "o1", "The contentWindow's name of the object element should be 'o1'.");
+ obj1.removeAttribute("name");
+ assert_equals(obj1.name, "", "The name of the object element should be empty string.");
+ assert_equals(obj1.contentWindow.name, "", "The contentWindow's name of the object element should be empty string.");
+ });
+ t1.done()
+
+ t3.step(function() {
+ assert_equals(getComputedStyle(obj1, null)["width"], "100px", "The width should be 100px.");
+ });
+ t3.done();
+
+ t4.step(function() {
+ assert_equals(getComputedStyle(obj1, null)["height"], "50px", "The height should be 50px.");
+ });
+ t4.done();
+ }
+</script>
+
+</body>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-object-element/object-events.html b/testing/web-platform/tests/html/semantics/embedded-content/the-object-element/object-events.html
new file mode 100644
index 000000000..9cd567173
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-object-element/object-events.html
@@ -0,0 +1,80 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>HTML Test: object-events</title>
+<link rel="author" title="Intel" href="http://www.intel.com">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<script>
+
+async_test(function(t) {
+ var obj = document.createElement("object");
+ obj.onerror = t.step_func_done(function(e){
+ assert_equals(Object.getPrototypeOf(e).constructor, Event, "The error event should use the Event interface.");
+ assert_true(e.isTrusted, "The error event should be a trusted event.");
+ assert_false(e.cancelable, "The error event should not be a cancelable event.");
+ assert_false(e.bubbles, "The error event should not be a bubble event.");
+ assert_equals(e.target, obj, "The error event target should be the corresponding object element.");
+ });
+
+ obj.onload = t.step_func_done(function(e){
+ assert_unreached("The load event should not be fired.");
+ });
+
+ obj.data = "file:\\http://nonexistent.html";
+ document.body.appendChild(obj);
+}, "error event");
+
+async_test(function(t) {
+ var obj = document.createElement("object");
+ obj.onerror = t.step_func_done(function(e){
+ assert_equals(e.target, obj,
+ "The error event should be fired on our element");
+ });
+ obj.onload = t.step_func_done(function(e){
+ assert_unreached("The load event should not be fired.");
+ });
+
+ obj.data = "http://test:test";
+ document.body.appendChild(obj);
+}, "error event");
+
+
+async_test(function(t) {
+ var obj = document.createElement("object");
+ obj.onload = t.step_func_done(function(e){
+ assert_equals(Object.getPrototypeOf(e).constructor, Event, "The load event should use the Event interface.");
+ assert_true(e.isTrusted, "The load event should be a trusted event.");
+ assert_false(e.cancelable, "The load event should not be a cancelable event.");
+ assert_false(e.bubbles, "The load event should not be a bubble event.");
+ assert_equals(e.target, obj, "The load event target should be the corresponding object element.");
+ });
+
+ obj.onerror = t.step_func_done(function(e){
+ assert_unreached("The error event should not be fired.");
+ });
+
+ obj.data = "/images/blue.png";
+ document.body.appendChild(obj);
+}, "load event");
+
+async_test(function(t) {
+ var obj = document.createElement("object");
+ obj.onload = t.step_func_done(function(e){
+ assert_true(obj.contentWindow instanceof Window, "The object element should represent a nested browsing context.")
+ assert_equals(Object.getPrototypeOf(e).constructor, Event, "The load event should use the Event interface.");
+ assert_true(e.isTrusted, "The load event should be a trusted event.");
+ assert_false(e.cancelable, "The load event should not be a cancelable event.");
+ assert_false(e.bubbles, "The load event should not be a bubble event.");
+ assert_equals(e.target, obj, "The load event target should be the corresponding object element.");
+ });
+
+ obj.onerror = t.step_func_done(function(e){
+ assert_unreached("The error event should not be fired.");
+ });
+
+ obj.data = "about:blank";
+ document.body.appendChild(obj);
+}, "load event of about:blank");
+
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-object-element/object-fallback.html b/testing/web-platform/tests/html/semantics/embedded-content/the-object-element/object-fallback.html
new file mode 100644
index 000000000..d5469a3ed
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-object-element/object-fallback.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>HTML Test: display fallback content</title>
+<link rel="author" title="Intel" href="http://www.intel.com">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+
+var t1 = async_test("the typemustmatch attribute is specified");
+var t2 = async_test("the typemustmatch attribute is not specified");
+
+</script>
+<body onload="t1.done(); t2.done()">
+<object id="obj"></object>
+<div id="log"></div>
+<script>
+
+t1.step(function() {
+ var obj1 = document.createElement("object");
+ obj1.setAttribute("data", "/images/blue.png");
+ obj1.setAttribute("type", "text/plain");
+ obj1.setAttribute("typemustmatch", "");
+ obj1.onload = t1.step_func(function () {
+ assert_true("typeMustMatch" in obj1, "typeMustMatch is not supported.");
+ assert_unreached("The image of the first object should not be loaded.");
+ });
+ document.getElementById("obj").appendChild(obj1);
+});
+
+t2.step(function () {
+ var obj2 = document.createElement("object");
+ obj2.setAttribute("data", "test2.html");
+ obj2.setAttribute("type", "text/plain");
+ obj2.onload = t2.step_func( function () {
+ assert_not_equals(obj2.contentDocument, null, "The test2.html should be loaded.");
+ });
+ document.getElementById("obj").appendChild(obj2);
+});
+
+</script>
+</body>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-object-element/object-handler.html b/testing/web-platform/tests/html/semantics/embedded-content/the-object-element/object-handler.html
new file mode 100644
index 000000000..a24554e0c
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-object-element/object-handler.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>HTML Test: object - handler</title>
+<link rel="author" title="Intel" href="http://www.intel.com" />
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<object id="test" name="obj" data="test0.html" type="text/html"></object>
+<script>
+
+var t1 = async_test("The nested browsing context must be navigated to the resource specified by the data attribute.");
+var t2 = async_test("The object.data must not be updated if the browsing context gets further navigated.");
+
+function callback(data) {
+ if (data == "test0") {
+ t1.step(function() {
+ var testEle = document.getElementById("test");
+ assert_true(testEle.contentDocument.location.href.indexOf("test0.html") != -1, "The nested browsing context should be navigated to test0.html.");
+ window["obj"].history.replaceState({state:"ok"}, "mytitle ", "object-fallback.html");
+ assert_not_equals(testEle.contentDocument.location.href.indexOf("object-fallback.html"), -1, "The nested browsing context should be replacement enabled.");
+ });
+ t1.done();
+ } else if (data == "test1") {
+ t2.step(function() {
+ var testEle = document.getElementById("test");
+ assert_true(testEle.contentDocument.location.href.indexOf("test1.html") != -1, "The browsing context should be navigated to test1.html.");
+ assert_true(testEle.data.indexOf("test0.html") != -1, "The value of attribute data should not be updated.");
+ });
+ t2.done();
+ }
+}
+
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-object-element/test0.html b/testing/web-platform/tests/html/semantics/embedded-content/the-object-element/test0.html
new file mode 100644
index 000000000..17df71daa
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-object-element/test0.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>HTML Test</title>
+<link rel="author" title="Intel" href="http://www.intel.com">
+<script>
+
+parent.callback("test0");
+document.location.href = "test1.html";
+
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-object-element/test1.html b/testing/web-platform/tests/html/semantics/embedded-content/the-object-element/test1.html
new file mode 100644
index 000000000..cf2423275
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-object-element/test1.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>HTML Test</title>
+<link rel="author" title="Intel" href="http://www.intel.com">
+<script>
+
+parent.callback("test1");
+
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-object-element/test2.html b/testing/web-platform/tests/html/semantics/embedded-content/the-object-element/test2.html
new file mode 100644
index 000000000..e5061eaea
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-object-element/test2.html
@@ -0,0 +1,4 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>HTML Test: object - fallback</title>
+<link rel="author" title="Intel" href="http://www.intel.com">
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-param-element/.gitkeep b/testing/web-platform/tests/html/semantics/embedded-content/the-param-element/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-param-element/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-source-element/.gitkeep b/testing/web-platform/tests/html/semantics/embedded-content/the-source-element/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-source-element/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-track-element/.gitkeep b/testing/web-platform/tests/html/semantics/embedded-content/the-track-element/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-track-element/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-video-element/.gitkeep b/testing/web-platform/tests/html/semantics/embedded-content/the-video-element/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-video-element/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-video-element/video-tabindex.html b/testing/web-platform/tests/html/semantics/embedded-content/the-video-element/video-tabindex.html
new file mode 100644
index 000000000..304487478
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-video-element/video-tabindex.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<title>tabindex on video elements</title>
+<link rel="author" title="Ms2ger" href="mailto:ms2ger@gmail.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#video">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<div id="test">
+<video></video>
+</div>
+<script>
+var t = async_test("Attributes shouldn't magically appear");
+on_event(window, "load", t.step_func(function() {
+ var el = document.getElementById("test").getElementsByTagName("video")[0];
+ assert_equals(el.hasAttribute("tabindex"), false);
+ t.done()
+}))
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-video-element/video_content-ref.htm b/testing/web-platform/tests/html/semantics/embedded-content/the-video-element/video_content-ref.htm
new file mode 100644
index 000000000..c02abb123
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-video-element/video_content-ref.htm
@@ -0,0 +1,12 @@
+<!DOCTYPE HTML>
+<html>
+ <head>
+ <title>HTML5 Media Elements: Content inside the 'video' element is not shown to the user.</title>
+ <meta content="text/html; charset=UTF-8" http-equiv="Content-Type">
+ <link rel="author" title="Microsoft" href="http://www.microsoft.com/" />
+ </head>
+ <body>
+ <div id='testcontent'>
+ </div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-video-element/video_content_image.htm b/testing/web-platform/tests/html/semantics/embedded-content/the-video-element/video_content_image.htm
new file mode 100644
index 000000000..0808d894a
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-video-element/video_content_image.htm
@@ -0,0 +1,16 @@
+<!DOCTYPE HTML>
+<html>
+ <head>
+ <title>HTML5 Media Elements: Content inside the 'video' element is not shown to the user.</title>
+ <meta content="text/html; charset=UTF-8" http-equiv="Content-Type">
+ <link rel="author" title="Microsoft" href="http://www.microsoft.com/" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#video" />
+ <link rel="match" href="video_content-ref.htm" />
+ <meta name="assert" content="Content inside the 'video' element is not shown to the user (image)." />
+ </head>
+ <body>
+ <div id='testcontent'>
+ <video><img src="../../../../images/fail.gif" /></video>
+ </div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-video-element/video_content_text.htm b/testing/web-platform/tests/html/semantics/embedded-content/the-video-element/video_content_text.htm
new file mode 100644
index 000000000..639fb73f8
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-video-element/video_content_text.htm
@@ -0,0 +1,16 @@
+<!DOCTYPE HTML>
+<html>
+ <head>
+ <title>HTML5 Media Elements: Content inside the 'video' element is not shown to the user.</title>
+ <meta content="text/html; charset=UTF-8" http-equiv="Content-Type">
+ <link rel="author" title="Microsoft" href="http://www.microsoft.com/" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#video" />
+ <link rel="match" href="video_content-ref.htm" />
+ <meta name="assert" content="Content inside the 'video' element is not shown to the user." />
+ </head>
+ <body>
+ <div id='testcontent'>
+ <video><p style="color: red;">FAIL</p></video>
+ </div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-video-element/video_dynamic_poster-ref.htm b/testing/web-platform/tests/html/semantics/embedded-content/the-video-element/video_dynamic_poster-ref.htm
new file mode 100644
index 000000000..78c03626e
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-video-element/video_dynamic_poster-ref.htm
@@ -0,0 +1,5 @@
+<!DOCTYPE HTML>
+<meta charset=UTF-8>
+<title>Reference for poster tests</title>
+<link rel="author" title="Microsoft" href="http://www.microsoft.com/">
+<img src="/media/poster.png">
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-video-element/video_dynamic_poster_absolute.htm b/testing/web-platform/tests/html/semantics/embedded-content/the-video-element/video_dynamic_poster_absolute.htm
new file mode 100644
index 000000000..bec2b0fba
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-video-element/video_dynamic_poster_absolute.htm
@@ -0,0 +1,12 @@
+<!DOCTYPE HTML>
+<meta charset=UTF-8>
+<title>The 'HTMLVideoElement' interface supports setting 'poster' to an absolute URL</title>
+<link rel="author" title="Microsoft" href="http://www.microsoft.com/">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-video-poster">
+<link rel="match" href="video_dynamic_poster-ref.htm">
+<meta name="assert" content="The 'HTMLVideoElement' interface supports setting 'poster' to an absolute URL">
+<video id="video0">Your browser does not support video.</video>
+<script>
+var testElem = document.getElementById("video0");
+testElem.poster = "/media/poster.png";
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-video-element/video_dynamic_poster_relative.htm b/testing/web-platform/tests/html/semantics/embedded-content/the-video-element/video_dynamic_poster_relative.htm
new file mode 100644
index 000000000..4faca61c4
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-video-element/video_dynamic_poster_relative.htm
@@ -0,0 +1,12 @@
+<!DOCTYPE HTML>
+<meta charset=UTF-8>
+<title>The 'HTMLVideoElement' interface supports setting 'poster' to a relative URL</title>
+<link rel="author" title="Microsoft" href="http://www.microsoft.com/">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-video-poster">
+<link rel="match" href="video_dynamic_poster-ref.htm">
+<meta name="assert" content="The 'HTMLVideoElement' interface supports setting 'poster' to a relative URL">
+<video id="video0">Your browser does not support video.</video>
+<script>
+var testElem = document.getElementById("video0");
+testElem.poster = "../../../../media/poster.png";
+</script>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-video-element/video_initially_paused-ref.html b/testing/web-platform/tests/html/semantics/embedded-content/the-video-element/video_initially_paused-ref.html
new file mode 100644
index 000000000..8556aabf2
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-video-element/video_initially_paused-ref.html
@@ -0,0 +1,8 @@
+<!DOCTYPE HTML>
+<meta charset=UTF-8>
+<title>Video elements should initially be paused</title>
+<link rel="author" title="Microsoft" href="http://www.microsoft.com/">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-media-paused">
+<script src="/common/media.js"></script>
+<p>The following video element should be paused. (All clocks at zero).</p>
+<img src='/images/movie_300_frame_0.png'>
diff --git a/testing/web-platform/tests/html/semantics/embedded-content/the-video-element/video_initially_paused.html b/testing/web-platform/tests/html/semantics/embedded-content/the-video-element/video_initially_paused.html
new file mode 100644
index 000000000..b2725b04a
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/embedded-content/the-video-element/video_initially_paused.html
@@ -0,0 +1,21 @@
+<!DOCTYPE HTML>
+<meta charset=UTF-8>
+<title>Video elements should initially be paused</title>
+<link rel="match" href="video_initially_paused-ref.html">
+<link rel="author" title="Microsoft" href="http://www.microsoft.com/">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-media-paused">
+<script src="/common/media.js"></script>
+<style>
+div#video {
+ padding: 6px 3px;
+}
+</style>
+<p>The following video element should be paused. (All clocks at zero).</p>
+<div id=video>
+<script>
+document.write(
+ "<video src='"+ getVideoURI('/media/movie_300') + "' >" +
+ "Your browser does not support the video element." +
+ "<\/video>");
+</script>
+</div>
diff --git a/testing/web-platform/tests/html/semantics/forms/.gitkeep b/testing/web-platform/tests/html/semantics/forms/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/forms/attributes-common-to-form-controls/.gitkeep b/testing/web-platform/tests/html/semantics/forms/attributes-common-to-form-controls/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/attributes-common-to-form-controls/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/forms/attributes-common-to-form-controls/contains.json b/testing/web-platform/tests/html/semantics/forms/attributes-common-to-form-controls/contains.json
new file mode 100644
index 000000000..357a1e6a7
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/attributes-common-to-form-controls/contains.json
@@ -0,0 +1,34 @@
+[
+ {
+ "id": "naming-form-controls-the-name-attribute",
+ "original_id": "naming-form-controls:-the-name-attribute"
+ },
+ {
+ "id": "submitting-element-directionality-the-dirname-attribute",
+ "original_id": "submitting-element-directionality:-the-dirname-attribute"
+ },
+ {
+ "id": "limiting-user-input-length-the-maxlength-attribute",
+ "original_id": "limiting-user-input-length:-the-maxlength-attribute"
+ },
+ {
+ "id": "enabling-and-disabling-form-controls-the-disabled-attribute",
+ "original_id": "enabling-and-disabling-form-controls:-the-disabled-attribute"
+ },
+ {
+ "id": "form-submission",
+ "original_id": "form-submission"
+ },
+ {
+ "id": "autofocusing-a-form-control-the-autofocus-attribute",
+ "original_id": "autofocusing-a-form-control:-the-autofocus-attribute"
+ },
+ {
+ "id": "input-modalities-the-inputmode-attribute",
+ "original_id": "input-modalities:-the-inputmode-attribute"
+ },
+ {
+ "id": "autofilling-form-controls-the-autocomplete-attribute",
+ "original_id": "autofilling-form-controls:-the-autocomplete-attribute"
+ }
+] \ No newline at end of file
diff --git a/testing/web-platform/tests/html/semantics/forms/attributes-common-to-form-controls/dirname-ltr-iframe.html b/testing/web-platform/tests/html/semantics/forms/attributes-common-to-form-controls/dirname-ltr-iframe.html
new file mode 100644
index 000000000..b5ed7e3d9
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/attributes-common-to-form-controls/dirname-ltr-iframe.html
@@ -0,0 +1,4 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Submitting element directionality: the dirname attribute support</title>
+<link rel="author" title="Denis Ah-Kang" href="mailto:denis@w3.org">
diff --git a/testing/web-platform/tests/html/semantics/forms/attributes-common-to-form-controls/dirname-ltr.html b/testing/web-platform/tests/html/semantics/forms/attributes-common-to-form-controls/dirname-ltr.html
new file mode 100644
index 000000000..28d1c150b
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/attributes-common-to-form-controls/dirname-ltr.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Submitting element directionality: the dirname attribute</title>
+<link rel="author" title="Denis Ah-Kang" href="mailto:denis@w3.org">
+<link rel=help href="https://html.spec.whatwg.org/multipage/#submitting-element-directionality:-the-dirname-attribute">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<form action="dirname-ltr-iframe.html" method=get target="iframe">
+ <p><label>Comment: <input type=text name="comment" dirname="comment.dir" required></label></p>
+ <p><button type=submit>Post Comment</button></p>
+</form>
+<iframe name="iframe"></iframe>
+<script>
+ function getParameterByName(name) {
+ name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]");
+ var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"),
+ results = regex.exec(document.querySelector("iframe").contentWindow.location.search);
+ return results == null ? "" : decodeURIComponent(results[1].replace(/\+/g, " "));
+ }
+
+ var t = async_test("submit element directionality");
+ document.querySelector("input").value="foobar";
+ document.querySelector("button").click();
+
+ document.querySelector("iframe").onload = t.step_func_done(function() {
+ assert_equals(getParameterByName("comment.dir"), "ltr");
+ });
+</script>
diff --git a/testing/web-platform/tests/html/semantics/forms/attributes-common-to-form-controls/dirname-rtl-manual.html b/testing/web-platform/tests/html/semantics/forms/attributes-common-to-form-controls/dirname-rtl-manual.html
new file mode 100644
index 000000000..cb00f6972
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/attributes-common-to-form-controls/dirname-rtl-manual.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Submitting element directionality: the dirname attribute (rtl)</title>
+<link rel="author" title="Denis Ah-Kang" href="mailto:denis@w3.org">
+<link rel=help href="https://html.spec.whatwg.org/multipage/#submitting-element-directionality:-the-dirname-attribute">
+<form action="dirname-rtl-manual.html" method=get>
+ <p><label>Comment: <input type=text name="comment" dirname="comment.dir" required></label></p>
+ <p><button type=submit>Post Comment</button></p>
+</form>
+<p>Switch to a right-to-left writing direction, enter a text in the input and submit the form.</p>
+<p>Test passes if the word "PASS" appears below</p>
+<script>
+ function getParameterByName(name) {
+ name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]");
+ var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"),
+ results = regex.exec(location.search);
+ return results == null ? "" : decodeURIComponent(results[1].replace(/\+/g, " "));
+ }
+
+ var commentDir = getParameterByName("comment.dir");
+ if (commentDir) {
+ var p = document.createElement("p");
+ p.textContent = (commentDir == "rtl") ? "PASS" : "FAIL";
+ document.body.appendChild(p);
+ }
+</script>
diff --git a/testing/web-platform/tests/html/semantics/forms/attributes-common-to-form-controls/disabled-elements-01.html b/testing/web-platform/tests/html/semantics/forms/attributes-common-to-form-controls/disabled-elements-01.html
new file mode 100644
index 000000000..14443e409
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/attributes-common-to-form-controls/disabled-elements-01.html
@@ -0,0 +1,84 @@
+<!DOCTYPE html>
+<title>HTMLFormElement: the disabled attribute</title>
+<link rel="author" title="Eric Casler" href="mailto:ericorange@gmail.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#enabling-and-disabling-form-controls:-the-disabled-attribute">
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<div id="log"></div>
+<div id="root"></div>
+<script>
+// Elements tested for in this file
+var types = ["button", "input", "select", "textarea"];
+// no tests for: optgroup, option, fieldset
+
+var root = document.getElementById("root");
+for (var element_type = 0; element_type < types.length; element_type++) {
+ test(function() {
+ root.innerHTML = "<"+types[element_type]+" + id='elem'></"+types[element_type]+">";
+
+ var elem = document.getElementById("elem");
+ assert_false(elem.disabled);
+ },
+ "Test ["+types[element_type]+"]: default behaviour is NOT disabled");
+
+ test(function() {
+ var formats = ["disabled",
+ "disabled=disabled", "disabled='disabled'",
+ "disabled='true'", "disabled=true",
+ "disabled='false'", "disabled=false"];
+
+ for (var f = 0; f < formats.length; f++) {
+ root.innerHTML = "<"+types[element_type]+" id='elem' " + formats[f] + "></"+types[element_type]+">";
+
+ var elem = document.getElementById("elem");
+ assert_true(elem.disabled);
+ }
+ },
+ "Test ["+types[element_type]+"]: verify disabled acts as boolean attribute");
+
+ test(function() {
+ root.innerHTML = "<"+types[element_type]+" id='elem'></"+types[element_type]+"><input id='other' value='no event dispatched'></input>";
+ var elem = document.getElementById("elem"),
+ other = document.getElementById("other");
+
+ assert_equals(other.value, "no event dispatched");
+
+ elem.disabled = true;
+ assert_true(elem.disabled);
+
+ elem.onclick = function () {
+ // change value of other element, to avoid *.value returning "" for disabled elements
+ document.getElementById("other").value = "event dispatched";
+ };
+
+ // Check if dispatched event executes
+ var evObj = document.createEvent('Events');
+ evObj.initEvent("click", true, false);
+ elem.dispatchEvent(evObj);
+ assert_equals(other.value, "event dispatched");
+ },
+ "Test ["+types[element_type]+"]: synthetic click events should be dispatched");
+
+ test(function() {
+ root.innerHTML = "<"+types[element_type]+" id='elem'></"+types[element_type]+"><input id='other' value='no event dispatched'></input>";
+ var elem = document.getElementById("elem"),
+ other = document.getElementById("other");
+
+ assert_equals(other.value, "no event dispatched");
+
+ elem.disabled = true;
+ assert_true(elem.disabled);
+
+ elem.onclick = function () {
+ // change value of other element, to avoid *.value returning "" for disabled elements
+ document.getElementById("other").value = "event dispatched";
+ };
+
+ // Check that click() on a disabled element doesn't dispatch a click event.
+ elem.click();
+ assert_equals(other.value, "no event dispatched");
+ },
+ "Test ["+types[element_type]+"]: click() should not dispatch a click event");
+}
+root.innerHTML = "";
+</script>
diff --git a/testing/web-platform/tests/html/semantics/forms/attributes-common-to-form-controls/formAction_document_address.html b/testing/web-platform/tests/html/semantics/forms/attributes-common-to-form-controls/formAction_document_address.html
new file mode 100644
index 000000000..d14cad532
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/attributes-common-to-form-controls/formAction_document_address.html
@@ -0,0 +1,74 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>HTML Test: formAction_document_address</title>
+ <link rel="author" title="Intel" href="http://www.intel.com/">
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-fs-formaction">
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-document's-address">
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-button-element">
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-input-element">
+ <meta name="assert" content="On getting the formAction IDL attribute, when the content attribute is missing or its value is the empty string, the document's address must be returned instead.">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+ <body>
+ <div id="log"></div>
+
+ <div id="missing" style="display:none">
+ <button type="submit">Submit</button>
+ <input type="submit">
+ </div>
+
+ <div id="empty_string" style="display:none">
+ <button type="submit" formaction="">Submit</button>
+ <input type="submit" formaction="">
+ </div>
+
+ <div id="no_assigned_value" style="display:none">
+ <button type="submit" formaction>Submit</button>
+ <input type="submit" formaction>
+ </div>
+
+ <script>
+ // formaction content attribute is missing
+ test(function() {
+ var formAction = document.querySelector('#missing button').formAction;
+ var address = document.location.href;
+ assert_equals(formAction, address);
+ }, "Check if button.formAction is the document's address when formaction content attribute is missing");
+
+ test(function() {
+ var formAction = document.querySelector('#missing input').formAction;
+ var address = document.location.href;
+ assert_equals(formAction, address);
+ }, "Check if input.formAction is the document's address when formaction content attribute is missing");
+
+ // formaction content attribute value is empty string
+ test(function() {
+ var formAction = document.querySelector('#empty_string button').formAction;
+ var address = document.location.href;
+ assert_equals(formAction, address);
+ }, "Check if button.formAction is the document's address when formaction content attribute value is empty string");
+
+ test(function() {
+ var formAction = document.querySelector('#empty_string input').formAction;
+ var address = document.location.href;
+ assert_equals(formAction, address);
+ }, "Check if input.formAction is the document's address when formaction content attribute value is empty string");
+
+ // formaction content attribute value is not assigned, just for comparison with empty string above
+ test(function() {
+ var formAction = document.querySelector('#no_assigned_value button').formAction;
+ var address = document.location.href;
+ assert_equals(formAction, address);
+ }, "Check if button.formAction is the document's address when formaction content attribute value is not assigned");
+
+ test(function() {
+ var formAction = document.querySelector('#no_assigned_value input').formAction;
+ var address = document.location.href;
+ assert_equals(formAction, address);
+ }, "Check if input.formAction is the document's address when formaction content attribute value is not assigned");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/forms/attributes-common-to-form-controls/formaction.html b/testing/web-platform/tests/html/semantics/forms/attributes-common-to-form-controls/formaction.html
new file mode 100644
index 000000000..82798eaa8
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/attributes-common-to-form-controls/formaction.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<html><head>
+ <title>formaction on button element</title>
+ <meta content="text/html; charset=UTF-8" http-equiv="content-type">
+ <meta content="formaction on button element" name="description">
+ <link href="https://html.spec.whatwg.org/multipage/#dom-fs-formaction" rel="help">
+</head>
+ <body>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+
+ <div id="log"></div>
+ <button formaction="http://www.example.com/" style="display: none" type="submit">Submit</button>
+ <input formaction="http://www.example.com/" style="display: none" type="submit" value="submit">
+ <input style="display: none" type="submit" value="submit">
+ <input formaction="" style="display: none" type="submit" value="submit">
+
+ <script type="text/javascript">
+ function relativeToAbsolute(relativeURL) {
+ var a = document.createElement('a');
+ a.href = relativeURL;
+ return a.href;
+ }
+ test(function() {assert_equals(document.getElementsByTagName("button")[0].formAction, "http://www.example.com/")}, "formAction on button support");
+ test(function() {assert_equals(document.getElementsByTagName("input")[0].formAction, "http://www.example.com/")}, "formAction on input support");
+
+ var testElem = document.getElementsByTagName("input")[0];
+ testElem.formAction = "http://www.example.com/page2.html";
+
+ test(function() {assert_equals(document.getElementsByTagName("input")[0].formAction, "http://www.example.com/page2.html")}, "formaction absolute URL value on input reflects correct value after being updated by the DOM");
+ test(function() {assert_equals(document.getElementsByTagName("input")[0].getAttribute("formaction"), "http://www.example.com/page2.html")}, "formAction absolute URL value is correct using getAttribute");
+
+ var testElem = document.getElementsByTagName("input")[0];
+ testElem.formAction = "../page3.html";
+
+ test(function() {assert_equals(document.getElementsByTagName("input")[0].formAction, relativeToAbsolute('../page3.html'))}, "formAction relative URL value on input reflects correct value after being updated by the DOM");
+ test(function() {assert_equals(document.getElementsByTagName("input")[0].getAttribute("formaction"), "../page3.html")}, "formAction relative URL value is correct using getAttribute");
+
+ test(function() {assert_equals(document.getElementsByTagName("input")[1].formAction, document.URL)}, "On getting, when formaction is missing, the document's address must be returned");
+ test(function() {assert_equals(document.getElementsByTagName("input")[2].formAction, document.URL)}, "On getting, when formaction value is the empty string, the document's address must be returned");
+ </script>
+</body></html>
diff --git a/testing/web-platform/tests/html/semantics/forms/categories/.gitkeep b/testing/web-platform/tests/html/semantics/forms/categories/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/categories/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/forms/constraints/.gitkeep b/testing/web-platform/tests/html/semantics/forms/constraints/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/constraints/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/forms/constraints/contains.json b/testing/web-platform/tests/html/semantics/forms/constraints/contains.json
new file mode 100644
index 000000000..67e4c3b12
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/constraints/contains.json
@@ -0,0 +1,18 @@
+[
+ {
+ "id": "definitions",
+ "original_id": "definitions"
+ },
+ {
+ "id": "constraint-validation",
+ "original_id": "constraint-validation"
+ },
+ {
+ "id": "the-constraint-validation-api",
+ "original_id": "the-constraint-validation-api"
+ },
+ {
+ "id": "security-forms",
+ "original_id": "security-forms"
+ }
+] \ No newline at end of file
diff --git a/testing/web-platform/tests/html/semantics/forms/constraints/form-validation-checkValidity.html b/testing/web-platform/tests/html/semantics/forms/constraints/form-validation-checkValidity.html
new file mode 100644
index 000000000..2e790c75d
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/constraints/form-validation-checkValidity.html
@@ -0,0 +1,145 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>The constraint validation API Test: element.checkValidity()</title>
+<link rel="author" title="Intel" href="http://www.intel.com/">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-cva-checkvalidity">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#the-constraint-validation-api">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="support/validator.js"></script>
+<div id="log"></div>
+<script>
+ var testElements = [
+ {
+ tag: "input",
+ types: ["text", "search", "tel", "password"],
+ testData: [
+ {conditions: {}, expected: true, name: "[target] no constraint"},
+ {conditions: {maxLength: "4", value: "abcdef"}, expected: true, name: "[target] not suffering from being too long", dirty: true},
+ {conditions: {pattern: "[A-Z]", value: "abc"}, expected: false, name: "[target] suffering from a pattern mismatch"},
+ {conditions: {required: true, value: ""}, expected: false, name: "[target] suffering from being missing"}
+ ]
+ },
+ {
+ tag: "input",
+ types: ["url"],
+ testData: [
+ {conditions: {}, expected: true, name: "[target] no constraint"},
+ {conditions: {maxLength: "20", value: "http://www.example.com"}, expected: true, name: "[target] suffering from being too long", dirty: true},
+ {conditions: {pattern: "http://www.example.com", value: "http://www.example.net"}, expected: false, name: "[target] suffering from a pattern mismatch"},
+ {conditions: {value: "abc"}, expected: false, name: "[target] suffering from a type mismatch"},
+ {conditions: {required: true, value: ""}, expected: false, name: "[target] suffering from being missing"}
+ ]
+ },
+ {
+ tag: "input",
+ types: ["email"],
+ testData: [
+ {conditions: {}, expected: true, name: "[target] no constraint"},
+ {conditions: {maxLength: "10", value: "test@example.com"}, expected: true, name: "[target] not suffering from being too long", dirty: true},
+ {conditions: {pattern: "test@example.com", value: "test@example.net"}, expected: false, name: "[target] suffering from a pattern mismatch"},
+ {conditions: {value: "abc"}, expected: false, name: "[target] suffering from a type mismatch"},
+ {conditions: {required: true, value: ""}, expected: false, name: "[target] suffering from being missing"}
+ ]
+ },
+ {
+ tag: "input",
+ types: ["datetime-local"],
+ testData: [
+ {conditions: {}, expected: true, name: "[target] no constraint"},
+ {conditions: {max: "2000-01-01T12:00:00", value: "2001-01-01T12:00:00"}, expected: false, name: "[target] suffering from an overflow"},
+ {conditions: {min: "2001-01-01T12:00:00", value: "2000-01-01T12:00:00"}, expected: false, name: "[target] suffering from an underflow"},
+ {conditions: {step: 2 * 60 * 1000, value: "2001-01-01T12:03:00"}, expected: false, name: "[target] suffering from a step mismatch"},
+ {conditions: {required: true, value: ""}, expected: false, name: "[target] suffering from being missing"}
+ ]
+ },
+ {
+ tag: "input",
+ types: ["date"],
+ testData: [
+ {conditions: {}, expected: true, name: "[target] no constraint"},
+ {conditions: {max: "2000-01-01", value: "2001-01-01"}, expected: false, name: "[target] suffering from an overflow"},
+ {conditions: {min: "2001-01-01", value: "2000-01-01"}, expected: false, name: "[target] suffering from an underflow"},
+ {conditions: {step: 2 * 1 * 86400000, value: "2001-01-03"}, expected: false, name: "[target] suffering from a step mismatch"},
+ {conditions: {required: true, value: ""}, expected: false, name: "[target] suffering from being missing"}
+ ]
+ },
+ {
+ tag: "input",
+ types: ["month"],
+ testData: [
+ {conditions: {}, expected: true, name: "[target] no constraint"},
+ {conditions: {max: "2000-01", value: "2001-01"}, expected: false, name: "[target] suffering from an overflow"},
+ {conditions: {min: "2001-01", value: "2000-01"}, expected: false, name: "[target] suffering from an underflow"},
+ {conditions: {step: 3 * 1 * 1, value: "2001-03"}, expected: false, name: "[target] suffering from a step mismatch"},
+ {conditions: {required: true, value: ""}, expected: false, name: "[target] suffering from being missing"}
+ ]
+ },
+ {
+ tag: "input",
+ types: ["week"],
+ testData: [
+ {conditions: {}, expected: true, name: "[target] no constraint"},
+ {conditions: {max: "2000-W01", value: "2001-W01"}, expected: false, name: "[target] suffering from an overflow"},
+ {conditions: {min: "2001-W01", value: "2000-W01"}, expected: false, name: "[target] suffering from an underflow"},
+ {conditions: {step: 2 * 1 * 604800000, value: "2001-W03"}, expected: false, name: "[target] suffering from a step mismatch"},
+ {conditions: {required: true, value: ""}, expected: false, name: "[target] suffering from being missing"}
+ ]
+ },
+ {
+ tag: "input",
+ types: ["time"],
+ testData: [
+ {conditions: {}, expected: true, name: "[target] no constraint"},
+ {conditions: {max: "12:00:00", value: "13:00:00"}, expected: false, name: "[target] suffering from an overflow"},
+ {conditions: {min: "12:00:00", value: "11:00:00"}, expected: false, name: "[target] suffering from an underflow"},
+ {conditions: {step: 2 * 60 * 1000, value: "12:03:00"}, expected: false, name: "[target] suffering from a step mismatch"},
+ {conditions: {required: true, value: ""}, expected: false, name: "[target] suffering from being missing"}
+ ]
+ },
+ {
+ tag: "input",
+ types: ["number"],
+ testData: [
+ {conditions: {max: "5", value: "6"}, expected: false, name: "[target] suffering from an overflow"},
+ {conditions: {min: "5", value: "4"}, expected: false, name: "[target] suffering from an underflow"},
+ {conditions: {step: 2 * 1 * 1, value: "3"}, expected: false, name: "[target] suffering from a step mismatch"},
+ {conditions: {required: true, value: ""}, expected: false, name: "[target] suffering from being missing"}
+ ]
+ },
+ {
+ tag: "input",
+ types: ["checkbox", "radio"],
+ testData: [
+ {conditions: {}, expected: true, name: "[target] no constraint"},
+ {conditions: {required: true, checked: false, name: "test1"}, expected: false, name: "[target] suffering from being missing"}
+ ]
+ },
+ {
+ tag: "input",
+ types: ["file"],
+ testData: [
+ {conditions: {}, expected: true, name: "[target] no constraint"},
+ {conditions: {required: true, files: null}, expected: false, name: "[target] suffering from being missing"}
+ ]
+ },
+ {
+ tag: "select",
+ types: [],
+ testData: [
+ {conditions: {}, expected: true, name: "[target] no constraint"},
+ {conditions: {required: true, value: ""}, expected: false, name: "[target] suffering from being missing"}
+ ]
+ },
+ {
+ tag: "textarea",
+ types: [],
+ testData: [
+ {conditions: {}, expected: true, name: "[target] no constraint"},
+ {conditions: {required: true, value: ""}, expected: false, name: "[target] suffering from being missing"}
+ ]
+ }
+ ];
+
+ validator.run_test(testElements, "checkValidity");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/forms/constraints/form-validation-reportValidity.html b/testing/web-platform/tests/html/semantics/forms/constraints/form-validation-reportValidity.html
new file mode 100644
index 000000000..c68e21c9d
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/constraints/form-validation-reportValidity.html
@@ -0,0 +1,145 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>The constraint validation API Test: element.reportValidity()</title>
+<link rel="author" title="Intel" href="http://www.intel.com/">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-cva-reportvalidity">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#the-constraint-validation-api">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="support/validator.js"></script>
+<div id="log"></div>
+<script>
+ var testElements = [
+ {
+ tag: "input",
+ types: ["text", "search", "tel", "password"],
+ testData: [
+ {conditions: {}, expected: true, name: "[target] no constraint"},
+ {conditions: {maxLength: "4", value: "abcdef"}, expected: true, name: "[target] not suffering from being too long", dirty: true},
+ {conditions: {pattern: "[A-Z]", value: "abc"}, expected: false, name: "[target] suffering from a pattern mismatch"},
+ {conditions: {required: true, value: ""}, expected: false, name: "[target] suffering from being missing"}
+ ]
+ },
+ {
+ tag: "input",
+ types: ["url"],
+ testData: [
+ {conditions: {}, expected: true, name: "[target] no constraint"},
+ {conditions: {maxLength: "20", value: "http://www.example.com"}, expected: true, name: "[target] not suffering from being too long", dirty: true},
+ {conditions: {pattern: "http://www.example.com", value: "http://www.example.net"}, expected: false, name: "[target] suffering from a pattern mismatch"},
+ {conditions: {value: "abc"}, expected: false, name: "[target] suffering from a type mismatch"},
+ {conditions: {required: true, value: ""}, expected: false, name: "[target] suffering from being missing"}
+ ]
+ },
+ {
+ tag: "input",
+ types: ["email"],
+ testData: [
+ {conditions: {}, expected: true, name: "[target] no constraint"},
+ {conditions: {maxLength: "10", value: "test@example.com"}, expected: true, name: "[target] not suffering from being too long", dirty: true},
+ {conditions: {pattern: "test@example.com", value: "test@example.net"}, expected: false, name: "[target] suffering from a pattern mismatch"},
+ {conditions: {value: "abc"}, expected: false, name: "[target] suffering from a type mismatch"},
+ {conditions: {required: true, value: ""}, expected: false, name: "[target] suffering from being missing"}
+ ]
+ },
+ {
+ tag: "input",
+ types: ["datetime-local"],
+ testData: [
+ {conditions: {}, expected: true, name: "[target] no constraint"},
+ {conditions: {max: "2000-01-01T12:00:00", value: "2001-01-01T12:00:00"}, expected: false, name: "[target] suffering from an overflow"},
+ {conditions: {min: "2001-01-01T12:00:00", value: "2000-01-01T12:00:00"}, expected: false, name: "[target] suffering from an underflow"},
+ {conditions: {step: 2 * 60 * 1000, value: "2001-01-01T12:03:00"}, expected: false, name: "[target] suffering from a step mismatch"},
+ {conditions: {required: true, value: ""}, expected: false, name: "[target] suffering from being missing"}
+ ]
+ },
+ {
+ tag: "input",
+ types: ["date"],
+ testData: [
+ {conditions: {}, expected: true, name: "[target] no constraint"},
+ {conditions: {max: "2000-01-01", value: "2001-01-01"}, expected: false, name: "[target] suffering from an overflow"},
+ {conditions: {min: "2001-01-01", value: "2000-01-01"}, expected: false, name: "[target] suffering from an underflow"},
+ {conditions: {step: 2 * 1 * 86400000, value: "2001-01-03"}, expected: false, name: "[target] suffering from a step mismatch"},
+ {conditions: {required: true, value: ""}, expected: false, name: "[target] suffering from being missing"}
+ ]
+ },
+ {
+ tag: "input",
+ types: ["month"],
+ testData: [
+ {conditions: {}, expected: true, name: "[target] no constraint"},
+ {conditions: {max: "2000-01", value: "2001-01"}, expected: false, name: "[target] suffering from an overflow"},
+ {conditions: {min: "2001-01", value: "2000-01"}, expected: false, name: "[target] suffering from an underflow"},
+ {conditions: {step: 3 * 1 * 1, value: "2001-03"}, expected: false, name: "[target] suffering from a step mismatch"},
+ {conditions: {required: true, value: ""}, expected: false, name: "[target] suffering from being missing"}
+ ]
+ },
+ {
+ tag: "input",
+ types: ["week"],
+ testData: [
+ {conditions: {}, expected: true, name: "[target] no constraint"},
+ {conditions: {max: "2000-W01", value: "2001-W01"}, expected: false, name: "[target] suffering from an overflow"},
+ {conditions: {min: "2001-W01", value: "2000-W01"}, expected: false, name: "[target] suffering from an underflow"},
+ {conditions: {step: 2 * 1 * 604800000, value: "2001-W03"}, expected: false, name: "[target] suffering from a step mismatch"},
+ {conditions: {required: true, value: ""}, expected: false, name: "[target] suffering from being missing"}
+ ]
+ },
+ {
+ tag: "input",
+ types: ["time"],
+ testData: [
+ {conditions: {}, expected: true, name: "[target] no constraint"},
+ {conditions: {max: "12:00:00", value: "13:00:00"}, expected: false, name: "[target] suffering from an overflow"},
+ {conditions: {min: "12:00:00", value: "11:00:00"}, expected: false, name: "[target] suffering from an underflow"},
+ {conditions: {step: 2 * 60 * 1000, value: "12:03:00"}, expected: false, name: "[target] suffering from a step mismatch"},
+ {conditions: {required: true, value: ""}, expected: false, name: "[target] suffering from being missing"}
+ ]
+ },
+ {
+ tag: "input",
+ types: ["number"],
+ testData: [
+ {conditions: {max: "5", value: "6"}, expected: false, name: "[target] suffering from an overflow"},
+ {conditions: {min: "5", value: "4"}, expected: false, name: "[target] suffering from an underflow"},
+ {conditions: {step: 2 * 1 * 1, value: "3"}, expected: false, name: "[target] suffering from a step mismatch"},
+ {conditions: {required: true, value: ""}, expected: false, name: "[target] suffering from being missing"}
+ ]
+ },
+ {
+ tag: "input",
+ types: ["checkbox", "radio"],
+ testData: [
+ {conditions: {}, expected: true, name: "[target] no constraint"},
+ {conditions: {required: true, checked: false, name: "test1"}, expected: false, name: "[target] suffering from being missing"}
+ ]
+ },
+ {
+ tag: "input",
+ types: ["file"],
+ testData: [
+ {conditions: {}, expected: true, name: "[target] no constraint"},
+ {conditions: {required: true, files: null}, expected: false, name: "[target] suffering from being missing"}
+ ]
+ },
+ {
+ tag: "select",
+ types: [],
+ testData: [
+ {conditions: {}, expected: true, name: "[target] no constraint"},
+ {conditions: {required: true, value: ""}, expected: false, name: "[target] suffering from being missing"}
+ ]
+ },
+ {
+ tag: "textarea",
+ types: [],
+ testData: [
+ {conditions: {}, expected: true, name: "[target] no constraint"},
+ {conditions: {required: true, value: ""}, expected: false, name: "[target] suffering from being missing"}
+ ]
+ }
+ ];
+
+ validator.run_test(testElements, "reportValidity");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/forms/constraints/form-validation-validate.html b/testing/web-platform/tests/html/semantics/forms/constraints/form-validation-validate.html
new file mode 100644
index 000000000..47b41ffeb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/constraints/form-validation-validate.html
@@ -0,0 +1,127 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>Constraint validation</title>
+<link rel="author" title="Intel" href="http://www.intel.com/">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#constraint-validation">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<form id="fm1" style="display:none">
+ <fieldset id="test0">
+ <input type="text" required value="" id="test1">
+ </fieldset>
+ <input type="email" value="abc" id="test2">
+ <button id="test3">TEST</button>
+ <select id="test4"></select>
+ <textarea id="test5"></textarea>
+ <output id="test6"></output>
+</form>
+<form id="fm2" style="display:none">
+ <fieldset>
+ <input type="text" required value="abc">
+ </fieldset>
+ <input type="email" value="test@example.com">
+ <button>TEST</button>
+ <select></select>
+ <textarea></textarea>
+ <output></output>
+</form>
+<form id="fm3" style="display:none">
+ <fieldset id="fs">
+ <legend><input type="text" id="inp1"></legend>
+ <input type="text" required value="" id="inp2">
+ </fieldset>
+</form>
+
+<script>
+ var cancelable = true,
+ times1 = 0,
+ times2 = 0,
+ invalidList1 = [],
+ invalidList2 = [],
+ test1,
+ test2,
+ fm1,
+ fm2,
+ fm3;
+
+ setup(function () {
+ fm1 = document.getElementById("fm1");
+ fm2 = document.getElementById("fm2");
+ fm3 = document.getElementById("fm3");
+ test1 = document.getElementById("test1");
+ test2 = document.getElementById("test2");
+ for (var index = 0; index < fm1.elements.length; index++) {
+ var ele = fm1.elements.item(index);
+ ele.addEventListener("invalid", function (e) {
+ times1++;
+ invalidList1.push(e.target);
+ if (!e.cancelable)
+ cancelable = e.cancelable;
+ }, false);
+ }
+
+ for (var index = 0; index < fm1.elements.length; index++) {
+ var ele = fm2.elements.item(index);
+ ele.addEventListener("invalid", function (e) {
+ times2++;
+ invalidList2.push(ele);
+ }, false);
+ }
+ });
+
+ test(function(){
+ assert_false(fm1.checkValidity(), "The checkValidity method should be false.");
+ }, "If there is any invalid submittable element whose form owner is the form, the form.checkValidity must be false");
+
+ test(function(){
+ assert_true("reportValidity" in fm1, "The reportValidity method is not supported");
+ assert_false(fm1.reportValidity(), "The reportValidity method should be false.");
+ }, "If there is any invalid submittable element whose form owner is the form, the form.reportValidity must be false");
+
+ test(function(){
+ assert_true(fm2.checkValidity(), "The checkValidity method should be true.");
+ }, "If all of the submittable elements whose form owner is the form are valid, the form.checkValidity must be true");
+
+ test(function(){
+ assert_true("reportValidity" in fm2, "The reportValidity method is not supported.");
+ assert_true(fm2.reportValidity(), "The reportValidity method should be true.");
+ }, "If all of the submittable elements whose form owner is the form are valid, the form.reportValidity must be true");
+
+ test(function(){
+ assert_false(fm3.checkValidity(), "The checkValidity method should be false.");
+ document.getElementById("fs").disabled = true;
+ assert_true(fm3.checkValidity(), "The checkValidity method should be true.");
+
+ document.getElementById("inp1").value = "aaa";
+ document.getElementById("inp1").type = "url";
+ assert_false(fm3.checkValidity(), "The checkValidity method should be false.");
+ }, "Check the checkValidity method of the form element when it has a fieldset child");
+
+ test(function(){
+ // Restore the condition to default which was modified during the previous test.
+ document.getElementById("fs").disabled = false;
+ document.getElementById("inp1").value = "";
+ document.getElementById("inp1").type = "text";
+
+ assert_true("reportValidity" in fm3, "The reportValidity method is not supported.");
+ assert_false(fm3.reportValidity(), "The reportValidity method should be false.");
+ document.getElementById("fs").disabled = true;
+ assert_true(fm3.reportValidity(), "The reportValidity method should be true.");
+
+ document.getElementById("inp1").value = "aaa";
+ document.getElementById("inp1").type = "url";
+ assert_false(fm3.reportValidity(), "The reportValidity method should be false.");
+ }, "Check the reportValidity method of the form element when it has a fieldset child");
+
+ test(function () {
+ assert_equals(times1, 4, "The invalid event will be fired if the checkValidity or reportValidity method are called.");
+ assert_array_equals(invalidList1, [test1, test2, test1, test2], "The invalid event must be fired at the invalid control");
+ assert_true(cancelable, "The invalid event is cancelable.");
+ }, "The invalid event must be fired at the invalid controls");
+
+ test(function () {
+ assert_equals(times2, 0, "The invalid event should not be fired, times should be 0.");
+ assert_array_equals(invalidList2, [], "The invalid event should not be fired, invalid list should be empty");
+ }, "The invalid event must not be fired at the invalid controls");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/forms/constraints/form-validation-validity-badInput.html b/testing/web-platform/tests/html/semantics/forms/constraints/form-validation-validity-badInput.html
new file mode 100644
index 000000000..8f6153b92
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/constraints/form-validation-validity-badInput.html
@@ -0,0 +1,46 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>The constraint validation API Test: element.validity.badInput</title>
+<link rel="author" title="Intel" href="http://www.intel.com/">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/multipage/association-of-controls-and-forms.html#suffering-from-bad-input">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/multipage/the-button-element.html#the-constraint-validation-api">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="support/validator.js"></script>
+<div id="log"></div>
+<script>
+var testElements = [
+ {
+ tag: "input",
+ types: ["email"],
+ testData: [
+ {conditions: {multiple: false, value: ""}, expected: false, name: "[target] The multiple attribute is false and the value attribute is empty"},
+ {conditions: {multiple: false, value: "test1@example.com"}, expected: false, name: "[target] The multiple attribute is false and the value attribute is a valid e-mail address"},
+ {conditions: {multiple: true, value: "test1@example.com,test2@eample.com"}, expected: false, name: "[target] The multiple attribute is true and the value contains valid e-mail addresses"},
+ {conditions: {multiple: true, value: "test,1@example.com"}, expected: false, name: "[target] The multiple attribute is true and the value attribute contains a ','"}
+ //TODO, the value contains characters that cannot be converted to punycode.
+ //Can not find a character that cannot be converted to punycode.
+ ]
+ },
+ {
+ tag: "input",
+ types: ["datetime-local"],
+ testData: [
+ {conditions: {value: ""}, expected: false, name: "[target] The value attribute is empty"},
+ {conditions: {value: "2000-01-01T12:00:00"}, expected: false, name: "[target] The value attribute is a valid date and time string"},
+ {conditions: {value: "abc"}, expected: false, name: "[target] The value attribute cannot convert to a valid normalized forced-UTC global date and time string"}
+ ]
+ },
+ {
+ tag: "input",
+ types: ["color"],
+ testData: [
+ {conditions: {value: ""}, expected: false, name: "[target] The value attribute is empty"},
+ {conditions: {value: "#000000"}, expected: false, name: "[target] The value attribute is a valid sample color"},
+ {conditions: {value: "#FFFFFF"}, expected: false, name: "[target] The value attribute is not a valid lowercase sample color"},
+ {conditions: {value: "abc"}, expected: false, name: "[target] The value attribute cannot convert to a valid sample color"}
+ ]
+ },
+ ];
+ validator.run_test (testElements, "badInput");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/forms/constraints/form-validation-validity-customError.html b/testing/web-platform/tests/html/semantics/forms/constraints/form-validation-validity-customError.html
new file mode 100644
index 000000000..16e642147
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/constraints/form-validation-validity-customError.html
@@ -0,0 +1,48 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>The constraint validation API Test: element.validity.customError</title>
+<link rel="author" title="Intel" href="http://www.intel.com/">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-validitystate-customerror">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#the-constraint-validation-api">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="support/validator.js"></script>
+<div id="log"></div>
+<script>
+var testElements = [
+ {
+ tag: "input",
+ types: [],
+ testData: [
+ {conditions: {message: "My custom error"}, expected: true, name: "[target] The validity.customError must be true if the custom validity error message is not empty"},
+ {conditions: {message: ""}, expected: false, name: "[target] The validity.customError must be false if the custom validity error message is empty"}
+ ]
+ },
+ {
+ tag: "button",
+ types: [],
+ testData: [
+ {conditions: {message: "My custom error"}, expected: true, name: "[target] The validity.customError must be true if the custom validity error message is not empty"},
+ {conditions: {message: ""}, expected: false, name: "[target] The validity.customError must be false if the custom validity error message is empty"}
+ ]
+ },
+ {
+ tag: "select",
+ types: [],
+ testData: [
+ {conditions: {message: "My custom error"}, expected: true, name: "[target] The validity.customError must be true if the custom validity error message is not empty"},
+ {conditions: {message: ""}, expected: false, name: "[target] The validity.customError must be false i the custom validity error message is empty"}
+ ]
+ },
+ {
+ tag: "textarea",
+ types: [],
+ testData: [
+ {conditions: {message: "My custom error"}, expected: true, name: "[target] The validity.customError must be true if the custom validity error message is not empty"},
+ {conditions: {message: ""}, expected: false, name: "[target] The validity.customError must be false if the custom validity error message is empty"}
+ ]
+ }
+ ]
+
+ validator.run_test(testElements, "customError");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/forms/constraints/form-validation-validity-patternMismatch.html b/testing/web-platform/tests/html/semantics/forms/constraints/form-validation-validity-patternMismatch.html
new file mode 100644
index 000000000..5a0012b0e
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/constraints/form-validation-validity-patternMismatch.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>The constraint validation API Test: element.validity.patternMismatch</title>
+<link rel="author" title="Intel" href="http://www.intel.com/">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-validitystate-patternmismatch">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#the-constraint-validation-api">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="support/validator.js"></script>
+<div id="log"></div>
+<script>
+ var testElements = [
+ {
+ tag: "input",
+ types: ["text", "search", "tel", "url", "email", "password"],
+ testData: [
+ {conditions: {pattern: null, value: "abc"}, expected: false, name: "[target] The pattern attribute is not set"},
+ {conditions: {pattern: "[A-Z]+", value: ""}, expected: false, name: "[target] The value attibute is empty string"},
+ {conditions: {pattern: "[A-Z]{1}", value: "A"}, expected: false, name: "[target] The value attribute matches the pattern attribute"},
+ {conditions: {pattern: "[A-Z]+", value: "\u0041\u0042\u0043"}, expected: false, name: "[target] The value(ABC) in unicode attribute matches the pattern attribute"},
+ {conditions: {pattern: "[a-z]{3,}", value: "ABCD"}, expected: true, name: "[target] The value attribute mismatches the pattern attribute"}
+ ]
+ }
+ ];
+
+ validator.run_test (testElements, "patternMismatch");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/forms/constraints/form-validation-validity-rangeOverflow.html b/testing/web-platform/tests/html/semantics/forms/constraints/form-validation-validity-rangeOverflow.html
new file mode 100644
index 000000000..ca423ef9e
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/constraints/form-validation-validity-rangeOverflow.html
@@ -0,0 +1,115 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>The constraint validation API Test: element.validity.rangeOverflow</title>
+<link rel="author" title="Intel" href="http://www.intel.com/">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-validitystate-rangeoverflow">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#the-constraint-validation-api">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="support/validator.js"></script>
+<div id="log"></div>
+<script>
+ var testElements = [
+ {
+ tag: "input",
+ types: ["datetime-local"],
+ testData: [
+ {conditions: {max: "", value: "2000-01-01T12:00:00"}, expected: false, name: "[target] The max attribute is not set"},
+ {conditions: {max: "2000-01-01T12:00:00", value: ""}, expected: false, name: "[target] Value is empty string"},
+ {conditions: {max: "2000-01-01 12:00:00", value: "2001-01-01T12:00:00"}, expected: false, name: "[target] The max attribute is an invalid local date time string"},
+ {conditions: {max: "2000-01-01T12:00:00", value: "2000-01-01T11:00:00"}, expected: false, name: "[target] The max attribute is greater than the value attribute"},
+ {conditions: {max: "2000-01-01T23:59:59", value: "2001-01-01T24:00:00"}, expected: false, name: "[target] The value is an invalid local date time string(hour is greater than 23)"},
+ {conditions: {max: "1970-01-01T12:00", value: "80-01-01T12:00"}, expected: false, name: "[target] The value if an invalid local date time string(year is two digits)"},
+ {conditions: {max: "2000-01-01T12:00:00", value: "2001-01-01T13:00:00"}, expected: true, name: "[target] The value is greater than max"},
+ {conditions: {max: "2000-01-01T12:00:00.1", value: "2000-01-01T12:00:00.2"}, expected: true, name: "[target] The value is greater than max(with millisecond in 1 digit)"},
+ {conditions: {max: "2000-01-01T12:00:00.01", value: "2000-01-01T12:00:00.02"}, expected: true, name: "[target] The value is greater than max(with millisecond in 2 digits)"},
+ {conditions: {max: "2000-01-01T12:00:00.001", value: "2000-01-01T12:00:00.002"}, expected: true, name: "[target] The value is greater than max(with millisecond in 3 digits)"},
+ {conditions: {max: "2000-01-01T12:00:00", value: "10000-01-01T12:00:00"}, expected: true, name: "[target] The value is greater than max(Year is 10000 should be valid)"},
+ ]
+ },
+ {
+ tag: "input",
+ types: ["date"],
+ testData: [
+ {conditions: {max: "", value: "2000-01-01"}, expected: false, name: "[target] The max attribute is not set"},
+ {conditions: {max: "2000-01-01", value: ""}, expected: false, name: "[target] Value is empty string"},
+ {conditions: {max: "2000/01/01", value: "2002-01-01"}, expected: false, name: "[target] The max attribute is an invalid date"},
+ {conditions: {max: "2000-01-01", value: "2000-2-2"}, expected: false, name: "[target] The value attribute is an invalid date"},
+ {conditions: {max: "987-01-01", value: "988-01-01"}, expected: false, name: "[target] The value is an invalid date(year is three digits)"},
+ {conditions: {max: "2000-01-01", value: "2000-13-01"}, expected: false, name: "[target] The value is an invalid date(month is greater than 12)"},
+ {conditions: {max: "2000-01-01", value: "2000-02-30"}, expected: false, name: "[target] The value is an invalid date(date is greater than 29 for Feb)"},
+ {conditions: {max: "2000-12-01", value: "2000-01-01"}, expected: false, name: "[target] The max attribute is greater than value attribute"},
+ {conditions: {max: "2000-12-01", value: "2001-01-01"}, expected: true, name: "[target] The value attribute is greater than max attribute"},
+ {conditions: {max: "9999-01-01", value: "10000-01-01"}, expected: true, name: "[target] The value attribute is greater than max attribute(Year is 10000 should be valid)"}
+ ]
+ },
+ {
+ tag: "input",
+ types: ["month"],
+ testData: [
+ {conditions: {max: "", value: "2000-01"}, expected: false, name: "[target] The max attribute is not set"},
+ {conditions: {max: "2000-01", value: ""}, expected: false, name: "[target] Value is empty string"},
+ {conditions: {max: "2000/01", value: "2001-02"}, expected: false, name: "[target] The max attribute is an invalid month string"},
+ {conditions: {max: "2000-01", value: "2000-1"}, expected: false, name: "[target] The value attribute is an invalid month string"},
+ {conditions: {max: "987-01", value: "988-01"}, expected: false, name: "[target] The value is an invalid month string(year is three digits)"},
+ {conditions: {max: "2000-01", value: "2000-13"}, expected: false, name: "[target] The value is an invalid month string(month is greater than 12)"},
+ {conditions: {max: "2000-12", value: "2000-01"}, expected: false, name: "[target] The max attribute is greater than value attribute"},
+ {conditions: {max: "2000-01", value: "2000-12"}, expected: true, name: "[target] The value attribute is greater than max attribute"},
+ {conditions: {max: "9999-01", value: "10000-01"}, expected: true, name: "[target] The value attribute is greater than max attribute(Year is 10000 should be valid)"}
+ ]
+ },
+ {
+ tag: "input",
+ types: ["week"],
+ testData: [
+ {conditions: {max: "", value: "2000-W01"}, expected: false, name: "[target] The max attribute is not set"},
+ {conditions: {max: "2000-W01", value: ""}, expected: false, name: "[target] Value is empty string"},
+ {conditions: {max: "2000/W01", value: "2001-W02"}, expected: false, name: "[target] The max attribute is an invalid week string"},
+ {conditions: {max: "2000-W01", value: "2000-W2"}, expected: false, name: "[target] The value attribute is an invalid week string"},
+ {conditions: {max: "2000-W01", value: "2000-w02"}, expected: false, name: "[target] The value attribute is an invalid week string(w is in lowercase)"},
+ {conditions: {max: "987-W01", value: "988-W01"}, expected: false, name: "[target] The value is an invalid week string(year is three digits)"},
+ {conditions: {max: "2000-W01", value: "2000-W57"}, expected: false, name: "[target] The value is an invalid week string(week is too greater)"},
+ {conditions: {max: "2000-W12", value: "2000-W01"}, expected: false, name: "[target] The max attribute is greater than value attribute"},
+ {conditions: {max: "2000-W01", value: "2000-W12"}, expected: true, name: "[target] The value attribute is greater than max attribute"},
+ {conditions: {max: "9999-W01", value: "10000-W01"}, expected: true, name: "[target] The value attribute is greater than max attribute(Year is 10000 should be valid)"}
+ ]
+ },
+ {
+ tag: "input",
+ types: ["time"],
+ testData: [
+ {conditions: {max: "", value: "12:00:00"}, expected: false, name: "[target] The max attribute is not set"},
+ {conditions: {max: "12:00:00", value: ""}, expected: false, name: "[target] Value is empty string"},
+ {conditions: {max: "12.00.00", value: "12:00:01"}, expected: false, name: "[target] The max attribute is an invalid time string"},
+ {conditions: {max: "12:00:00", value: "12.00.01"}, expected: false, name: "[target] The value attribute is an invalid time string"},
+ {conditions: {max: "23:59:59", value: "24:00:00"}, expected: false, name: "[target] The value attribute is an invalid time string(hour is greater than 23)"},
+ {conditions: {max: "23:59:59", value: "23:60:00"}, expected: false, name: "[target] The value attribute is an invalid time string(minute is greater than 59)"},
+ {conditions: {max: "23:59:59", value: "23:59:60"}, expected: false, name: "[target] The value attribute is an invalid time string(second is greater than 59)"},
+ {conditions: {max: "13:00:00", value: "12:00:00"}, expected: false, name: "[target] The max attribute is greater than value attribute"},
+ {conditions: {max: "12:00:00", value: "13"}, expected: false, name: "[target] The time missing second and minute parts is invalid"},
+ {conditions: {max: "12:00:00", value: "12:00:02"}, expected: true, name: "[target] The value attribute is greater than max attribute"},
+ {conditions: {max: "12:00:00.1", value: "12:00:00.2"}, expected: true, name: "[target] The value is greater than max(with millisecond in 1 digit)"},
+ {conditions: {max: "12:00:00.01", value: "12:00:00.02"}, expected: true, name: "[target] The value is greater than max(with millisecond in 2 digit)"},
+ {conditions: {max: "12:00:00.001", value: "12:00:00.002"}, expected: true, name: "[target] The value is greater than max(with millisecond in 3 digit)"},
+ {conditions: {max: "12:00:00", value: "12:01"}, expected: true, name: "[target] The time missing second part is valid"}
+ ]
+ },
+ {
+ tag: "input",
+ types: ["number"],
+ testData: [
+ {conditions: {max: "", value: "10"}, expected: false, name: "[target] The max attribute is not set"},
+ {conditions: {max: "5", value: ""}, expected: false, name: "[target] Value is empty string"},
+ {conditions: {max: "5", value: "4"}, expected: false, name: "[target] The max is greater than value(integer)"},
+ {conditions: {max: "-5.5", value: "-5.6"}, expected: false, name: "[target] The max is greater than value(floating number)"},
+ {conditions: {max: "-0", value: "0"}, expected: false, name: "[target] The max equals to value"},
+ {conditions: {max: "5", value: "1abc"}, expected: false, name: "[target] The value is not a number"},
+ {conditions: {max: "5", value: "6"}, expected: true, name: "[target] The value is greater than max(integer)"},
+ {conditions: {max: "-5.5", value: "-5.4"}, expected: true, name: "[target] The value is greater than max(floating number)"},
+ {conditions: {max: "-5e-1", value: "5e+2"}, expected: true, name: "[target] The value is greater than max(scientific notation)"}
+ ]
+ }
+ ];
+
+ validator.run_test(testElements, "rangeOverflow");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/forms/constraints/form-validation-validity-rangeUnderflow.html b/testing/web-platform/tests/html/semantics/forms/constraints/form-validation-validity-rangeUnderflow.html
new file mode 100644
index 000000000..d6bf86060
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/constraints/form-validation-validity-rangeUnderflow.html
@@ -0,0 +1,113 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>The constraint validation API Test: element.validity.rangeUnderflow</title>
+<link rel="author" title="Intel" href="http://www.intel.com/">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-validitystate-rangeunderflow">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#the-constraint-validation-api">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="support/validator.js"></script>
+<div id="log"></div>
+<script>
+ var testElements = [
+ {
+ tag: "input",
+ types: ["datetime-local"],
+ testData: [
+ {conditions: {min: "", value: "2000-01-01T12:00:00"}, expected: false, name: "[target] The min attribute is not set"},
+ {conditions: {min: "2000-01-01T12:00:00", value: ""}, expected: false, name: "[target] Value is empty string"},
+ {conditions: {min: "2001-01-01 12:00:00", value: "2000-01-01T12:00:00"}, expected: false, name: "[target] The min attribute is an invalid local date time string"},
+ {conditions: {min: "2000-01-01T11:00:00", value: "2000-01-01T12:00:00"}, expected: false, name: "[target] The min attribute is less than the value attribute"},
+ {conditions: {min: "2001-01-01T23:59:59", value: "2000-01-01T24:00:00"}, expected: false, name: "[target] The value is an invalid local date time string(hour is greater than 23)"},
+ {conditions: {min: "1980-01-01T12:00", value: "79-01-01T12:00"}, expected: false, name: "[target] The value is an invalid local date time string(year is two digits)"},
+ {conditions: {min: "2000-01-01T13:00:00", value: "2000-01-01T12:00:00"}, expected: true, name: "[target] The value is less than min"},
+ {conditions: {min: "2000-01-01T12:00:00.2", value: "2000-01-01T12:00:00.1"}, expected: true, name: "[target] The value is less than min(with millisecond in 1 digit)"},
+ {conditions: {min: "2000-01-01T12:00:00.02", value: "2000-01-01T12:00:00.01"}, expected: true, name: "[target] The value is less than min(with millisecond in 2 digits)"},
+ {conditions: {min: "2000-01-01T12:00:00.002", value: "2000-01-01T12:00:00.001"}, expected: true, name: "[target] The value is less than min(with millisecond in 3 digits)"},
+ {conditions: {min: "10000-01-01T12:00:00", value: "2000-01-01T12:00:00"}, expected: true, name: "[target] The value is less than min(Year is 10000 should be valid)"},
+ {conditions: {max: "8593-01-01T02:09", value: "8592-01-01T02:09"}, expected: false, name: "[target] The value is greater than max"}
+ ]
+ },
+ {
+ tag: "input",
+ types: ["date"],
+ testData: [
+ {conditions: {min: "", value: "2000-01-01"}, expected: false, name: "[target] The min attribute is not set"},
+ {conditions: {min: "2000-01-01", value: ""}, expected: false, name: "[target] Value is empty string"},
+ {conditions: {min: "2001/01/01", value: "2000-01-01"}, expected: false, name: "[target] The min attribute is an invalid date"},
+ {conditions: {min: "2000-02-02", value: "2000-1-1"}, expected: false, name: "[target] The value attribute is an invalid date"},
+ {conditions: {min: "988-01-01", value: "987-01-01"}, expected: false, name: "[target] The value is an invalid date(year is three digits)"},
+ {conditions: {min: "2001-01-01", value: "2000-13-01"}, expected: false, name: "[target] The value is an invalid date(month is less than 12)"},
+ {conditions: {min: "2001-01-01", value: "2000-02-30"}, expected: false, name: "[target] The value is an invalid date(date is less than 29 for Feb)"},
+ {conditions: {min: "2000-01-01", value: "2000-12-01"}, expected: false, name: "[target] The min attribute is less than value attribute"},
+ {conditions: {min: "2000-12-01", value: "2000-01-01"}, expected: true, name: "[target] The value attribute is less than min attribute"},
+ {conditions: {min: "10000-01-01", value: "9999-01-01"}, expected: true, name: "[target] The value attribute is less than min attribute(Year is 10000 should be valid)"}
+ ]
+ },
+ {
+ tag: "input",
+ types: ["month"],
+ testData: [
+ {conditions: {min: "", value: "2000-01"}, expected: false, name: "[target] The min attribute is not set"},
+ {conditions: {min: "2000-01", value: ""}, expected: false, name: "[target] Value is empty string"},
+ {conditions: {min: "2001/01", value: "2000-02"}, expected: false, name: "[target] The min attribute is an invalid month string"},
+ {conditions: {min: "2000-02", value: "2000-1"}, expected: false, name: "[target] The value attribute is an invalid month string"},
+ {conditions: {min: "988-01", value: "987-01"}, expected: false, name: "[target] The value is an invalid month string(year is three digits)"},
+ {conditions: {min: "2001-01", value: "2000-13"}, expected: false, name: "[target] The value is an invalid month string(month is less than 12)"},
+ {conditions: {min: "2000-01", value: "2000-12"}, expected: false, name: "[target] The min attribute is less than value attribute"},
+ {conditions: {min: "2001-01", value: "2000-12"}, expected: true, name: "[target] The value attribute is less than min attribute"},
+ {conditions: {min: "10000-01", value: "2000-01"}, expected: true, name: "[target] The value attribute is less than min attribute(Year is 10000 should be valid)"}
+ ]
+ },
+ {
+ tag: "input",
+ types: ["week"],
+ testData: [
+ {conditions: {min: "", value: "2000-W01"}, expected: false, name: "[target] The min attribute is not set"},
+ {conditions: {min: "2000-W01", value: ""}, expected: false, name: "[target] Value is empty string"},
+ {conditions: {min: "2001/W02", value: "2000-W01"}, expected: false, name: "[target] The min attribute is an invalid week string"},
+ {conditions: {min: "2001-W02", value: "2000-W1"}, expected: false, name: "[target] The value attribute is an invalid week string"},
+ {conditions: {min: "2001-W02", value: "2000-w01"}, expected: false, name: "[target] The value attribute is an invalid week string(w is in lowercase)"},
+ {conditions: {min: "988-W01", value: "987-W01"}, expected: false, name: "[target] The value is an invalid week string(year is three digits)"},
+ {conditions: {min: "2001-W01", value: "2000-W57"}, expected: false, name: "[target] The value is an invalid week string(week is too greater)"},
+ {conditions: {min: "2000-W01", value: "2000-W12"}, expected: false, name: "[target] The min attribute is less than value attribute"},
+ {conditions: {min: "2000-W12", value: "2000-W01"}, expected: true, name: "[target] The value attribute is less than min attribute"},
+ {conditions: {min: "10000-W01", value: "2000-W01"}, expected: true, name: "[target] The value attribute is less than min attribute(Year is 10000 should be valid)"}
+ ]
+ },
+ {
+ tag: "input",
+ types: ["time"],
+ testData: [
+ {conditions: {min: "", value: "12:00:00"}, expected: false, name: "[target] The min attribute is not set"},
+ {conditions: {min: "12:00:00", value: ""}, expected: false, name: "[target] Value is empty string"},
+ {conditions: {min: "12.00.01", value: "12:00:00"}, expected: false, name: "[target] The min attribute is an invalid time string"},
+ {conditions: {min: "12:00:01", value: "12.00.00"}, expected: false, name: "[target] The value attribute is an invalid time string"},
+ {conditions: {min: "12:00:00", value: "13:00:00"}, expected: false, name: "[target] The min attribute is less than value attribute"},
+ {conditions: {min: "13:00:00", value: "12"}, expected: false, name: "[target] The time missing second and minute parts is invalid"},
+ {conditions: {min: "12:00:02", value: "12:00:00"}, expected: true, name: "[target] The value attribute is less than min attribute"},
+ {conditions: {min: "12:00:00.2", value: "12:00:00.1"}, expected: true, name: "[target] The value is less than min(with millisecond in 1 digit)"},
+ {conditions: {min: "12:00:00.02", value: "12:00:00.01"}, expected: true, name: "[target] The value is less than min(with millisecond in 2 digit)"},
+ {conditions: {min: "12:00:00.002", value: "12:00:00.001"}, expected: true, name: "[target] The value is less than min(with millisecond in 3 digit)"},
+ {conditions: {min: "12:00:00", value: "11:59"}, expected: true, name: "[target] The time missing second part is valid"}
+ ]
+ },
+ {
+ tag: "input",
+ types: ["number"],
+ testData: [
+ {conditions: {min: "", value: "10"}, expected: false, name: "[target] The min attribute is not set"},
+ {conditions: {min: "5", value: ""}, expected: false, name: "[target] Value is empty string"},
+ {conditions: {min: "4", value: "5"}, expected: false, name: "[target] The min is less than value(integer)"},
+ {conditions: {min: "-5.6", value: "-5.5"}, expected: false, name: "[target] The min is less than value(floating number)"},
+ {conditions: {min: "0", value: "-0"}, expected: false, name: "[target] The min equals to value"},
+ {conditions: {min: "5", value: "6abc"}, expected: false, name: "[target] The value is not a number"},
+ {conditions: {min: "6", value: "5"}, expected: true, name: "[target] The value is less than min(integer)"},
+ {conditions: {min: "-5.4", value: "-5.5"}, expected: true, name: "[target] The value is less than min(floating number)"},
+ {conditions: {min: "5e+2", value: "-5e-1"}, expected: true, name: "[target] The value is less than min(scientific notation)"}
+ ]
+ }
+ ];
+
+ validator.run_test(testElements, "rangeUnderflow");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/forms/constraints/form-validation-validity-stepMismatch.html b/testing/web-platform/tests/html/semantics/forms/constraints/form-validation-validity-stepMismatch.html
new file mode 100644
index 000000000..174ecaf33
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/constraints/form-validation-validity-stepMismatch.html
@@ -0,0 +1,77 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>The constraint validation API Test: element.validity.stepMismatch</title>
+<link rel="author" title="Intel" href="http://www.intel.com/">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-validitystate-stepmismatch">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#the-constraint-validation-api">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="support/validator.js"></script>
+<div id="log"></div>
+<script>
+ //set step = 2 * default step * factor
+ var testElements = [
+ {
+ tag: "input",
+ types: ["date"],
+ testData: [
+ {conditions: {step: "", value: "2000-01-01"}, expected: false, name: "[target] The step attribute is not set"},
+ {conditions: {step: 2, value: ""}, expected: false, name: "[target] The value attibute is empty string"},
+ {conditions: {step: 2, value: "1970-01-03"}, expected: false, name: "[target] The value must match the step"},
+ {conditions: {step: 2, value: "1970-01-02"}, expected: true, name: "[target] The value must mismatch the step"}
+ ]
+ },
+ {
+ tag: "input",
+ types: ["month"],
+ testData: [
+ {conditions: {step: "", value: "2000-01"}, expected: false, name: "[target] The step attribute is not set"},
+ {conditions: {step: 2, value: ""}, expected: false, name: "[target] The value attibute is empty string"},
+ {conditions: {step: 2, value: "1970-03"}, expected: false, name: "[target] The value must match the step"},
+ {conditions: {step: 2, value: "1970-04"}, expected: true, name: "[target] The value must mismatch the step"}
+ ]
+ },
+ {
+ tag: "input",
+ types: ["week"],
+ testData: [
+ {conditions: {step: "", value: "1970-W01"}, expected: false, name: "[target] The step attribute is not set"},
+ {conditions: {step: 2, value: ""}, expected: false, name: "[target] The value attibute is empty string"},
+ {conditions: {step: 2, value: "1970-W03"}, expected: false, name: "[target] The value must match the step"},
+ {conditions: {step: 2, value: "1970-W04"}, expected: true, name: "[target] The value must mismatch the step"}
+ ]
+ },
+ {
+ tag: "input",
+ types: ["time"],
+ testData: [
+ {conditions: {step: "", value: "12:00:00"}, expected: false, name: "[target] The step attribute is not set"},
+ {conditions: {step: 2 * 60, value: ""}, expected: false, name: "[target] The value attibute is empty string"},
+ {conditions: {step: 2 * 60, value: "12:02:00"}, expected: false, name: "[target] The value must match the step"},
+ {conditions: {step: 2 * 60, value: "12:03:00"}, expected: true, name: "[target] The value must mismatch the step"}
+ ]
+ },
+ {
+ tag: "input",
+ types: ["datetime-local"],
+ testData: [
+ {conditions: {step: "", value: "2000-01-01T12:00:00"}, expected: false, name: "[target] The step attribute is not set"},
+ {conditions: {step: 2 * 60, value: ""}, expected: false, name: "[target] The value attibute is empty string"},
+ {conditions: {step: 2 * 60, value: "1970-01-01T12:02:00"}, expected: false, name: "[target] The value must match the step"},
+ {conditions: {step: 2 * 60, value: "1970-01-01T12:03:00"}, expected: true, name: "[target] The value must mismatch the step"}
+ ]
+ },
+ {
+ tag: "input",
+ types: ["number"],
+ testData: [
+ {conditions: {step: "", value: "1"}, expected: false, name: "[target] The step attribute is not set"},
+ {conditions: {step: 2 * 1 * 1, value: ""}, expected: false, name: "[target] The value attibute is empty string"},
+ {conditions: {step: 2 * 1 * 1, value: "2"}, expected: false, name: "[target] The value must match the step"},
+ {conditions: {step: 2 * 1 * 1, value: "3"}, expected: true, name: "[target] The value must mismatch the step"}
+ ]
+ }
+ ];
+
+ validator.run_test(testElements, "stepMismatch");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/forms/constraints/form-validation-validity-tooLong.html b/testing/web-platform/tests/html/semantics/forms/constraints/form-validation-validity-tooLong.html
new file mode 100644
index 000000000..aa787d471
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/constraints/form-validation-validity-tooLong.html
@@ -0,0 +1,50 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>The constraint validation API Test: element.validity.tooLong</title>
+<link rel="author" title="Intel" href="http://www.intel.com/">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-validitystate-toolong">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#the-constraint-validation-api">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="support/validator.js"></script>
+<div id="log"></div>
+<script>
+ var testElements = [
+ {
+ tag: "input",
+ types: ["text", "search", "tel", "url", "email", "password"],
+ testData: [ // Non-dirty value
+ {conditions: {maxLength: "", value: "abc"}, expected: false, name: "[target] Non-dirty value - maxlength is not set"},
+ {conditions: {maxLength: "4", value: ""}, expected: false, name: "[target] Non-dirty value - value is empty string"},
+ {conditions: {maxLength: "4", value: "abc"}, expected: false, name: "[target] Non-dirty value - length of value is less than maxlength"},
+ {conditions: {maxLength: "4", value: "abcd"}, expected: false, name: "[target] Non-dirty value - length of value equals to maxlength"},
+ {conditions: {maxLength: "4", value: "abcde"}, expected: false, name: "[target] Non-dirty value - length of value is greater than maxlength"},
+ //Dirty value
+ {conditions: {maxLength: "4", value: "abc"}, expected: false, name: "[target] Dirty value - value is less than maxlength", dirty: true},
+ {conditions: {maxLength: "4", value: "\u0041\u0041\u0041"}, expected: false, name: "[target] Dirty value - length of value(AAA) in unicode is less than maxlength", dirty: true},
+ {conditions: {maxLength: "4", value: "abcd"}, expected: false, name: "[target] Dirty value - value equals to maxlength", dirty: true},
+ // False due to lack of required interactive editing by the user
+ {conditions: {maxLength: "4", value: "abcde"}, expected: false, name: "[target] Dirty value - length of value is greater than maxlength", dirty: true}
+ ]
+ },
+ {
+ tag: "textarea",
+ types: [],
+ testData: [
+ {conditions: {maxLength: "", value: "abc"}, expected: false, name: "[target] Non-dirty value - maxlength is not set"},
+ {conditions: {maxLength: "4", value: ""}, expected: false, name: "[target] Non-dirty value - value is empty string"},
+ {conditions: {maxLength: "4", value: "abc"}, expected: false, name: "[target] Non-dirty value - length of value is less than maxlength"},
+ {conditions: {maxLength: "4", value: "abcd"}, expected: false, name: "[target] Non-dirty value - length of value equals to maxlength"},
+ {conditions: {maxLength: "4", value: "abcde"}, expected: false, name: "[target] Non-dirty value - length of value is greater than maxlength"},
+ //Dirty value
+ {conditions: {maxLength: "4", value: "abc"}, expected: false, name: "[target] Dirty value - value is less than maxlength", dirty: true},
+ {conditions: {maxLength: "4", value: "\u000D\u000A"}, expected: false, name: "[target] Dirty value - length of value(LF, CRLF) in unicode is less than maxlength", dirty: true},
+ {conditions: {maxLength: "4", value: "abcd"}, expected: false, name: "[target] Dirty value - length of value equals to maxlength", dirty: true},
+ // False due to lack of required interactive editing by the user
+ {conditions: {maxLength: "4", value: "abcde"}, expected: false, name: "[target] Dirty value - length of value is greater than maxlength", dirty: true}
+ ]
+ }
+ ];
+
+ validator.run_test (testElements, "tooLong");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/forms/constraints/form-validation-validity-tooShort.html b/testing/web-platform/tests/html/semantics/forms/constraints/form-validation-validity-tooShort.html
new file mode 100644
index 000000000..b6c0e4399
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/constraints/form-validation-validity-tooShort.html
@@ -0,0 +1,52 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>The constraint validation API Test: element.validity.tooShort</title>
+<link rel="author" title="Intel" href="http://www.intel.com/">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#suffering-from-being-too-short">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#the-constraint-validation-api">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="support/validator.js"></script>
+<div id="log"></div>
+<script>
+ var testElements = [
+ {
+ tag: "input",
+ types: ["text", "search", "tel", "url", "email", "password"],
+ testData: [
+ // Non-dirty value
+ {conditions: {minLength: "", value: "abc"}, expected: false, name: "[target] Non-dirty value - minLength is not set"},
+ {conditions: {minLength: "4", value: ""}, expected: false, name: "[target] Non-dirty value - value is empty string"},
+ {conditions: {minLength: "4", value: "abcde"}, expected: false, name: "[target] Non-dirty value - length of value is greater than minLength"},
+ {conditions: {minLength: "4", value: "abcd"}, expected: false, name: "[target] Non-dirty value - length of value equals to minLength"},
+ {conditions: {minLength: "4", value: "abc"}, expected: false, name: "[target] Non-dirty value - length of value is less than minLength"},
+ //Dirty value
+ {conditions: {minLength: "4", value: "abcde"}, expected: false, name: "[target] Dirty value - value is greater than minLength", dirty: true},
+ {conditions: {minLength: "4", value: "\u0041\u0041\u0041\u0041\u0041"}, expected: false, name: "[target] Dirty value - length of value(AAAAA) in unicode is greater than minLength", dirty: true},
+ {conditions: {minLength: "4", value: "abcd"}, expected: false, name: "[target] Dirty value - value equals to minLength", dirty: true},
+ // False due to lack of required interactive editing by the user
+ {conditions: {minLength: "4", value: "abc"}, expected: false, name: "[target] Dirty value - length of value is less than minLength", dirty: true}
+ ]
+ },
+ {
+ tag: "textarea",
+ types: [],
+ testData: [
+ // Non-dirty value
+ {conditions: {minLength: "", value: "abc"}, expected: false, name: "[target] Non-dirty value - minLength is no set"},
+ {conditions: {minLength: "4", value: ""}, expected: false, name: "[target] Non-dirty value - value is empty string"},
+ {conditions: {minLength: "4", value: "abcde"}, expected: false, name: "[target] Non-dirty value - length of value is greater than minLength"},
+ {conditions: {minLength: "4", value: "abcd"}, expected: false, name: "[target] Non-dirty value - length of value equals to minLength"},
+ {conditions: {minLength: "4", value: "abc"}, expected: false, name: "[target] Non-dirty value - length of length of value is greater than minLength"},
+ //Dirty value
+ {conditions: {minLength: "4", value: "abcde"}, expected: false, name: "[target] Dirty value - value is less than minLength", dirty: true},
+ {conditions: {minLength: "4", value: "\u000D\u000A\u000D\u000A\u000D\u000A"}, expected: false, name: "[target] Dirty value - length of value(LF, CRLF) in unicode is less than minLength", dirty: true},
+ {conditions: {minLength: "4", value: "abcd"}, expected: false, name: "[target] Dirty value - length of value equals to minLength", dirty: true},
+ // False due to lack of required interactive editing by the user
+ {conditions: {minLength: "4", value: "abc"}, expected: false, name: "[target] Dirty value - length of value is greater than minLength", dirty: true}
+ ]
+ }
+ ];
+
+ validator.run_test (testElements, "tooShort");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/forms/constraints/form-validation-validity-typeMismatch.html b/testing/web-platform/tests/html/semantics/forms/constraints/form-validation-validity-typeMismatch.html
new file mode 100644
index 000000000..40444277c
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/constraints/form-validation-validity-typeMismatch.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>The constraint validation API Test: element.validity.typeMismatch</title>
+<link rel="author" title="Intel" href="http://www.intel.com/">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-validitystate-typemismatch">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#the-constraint-validation-api">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="support/validator.js"></script>
+<div id="log"></div>
+<script>
+ var testElements = [
+ {
+ tag: "input",
+ types: ["email"],
+ testData: [
+ // multiple is false
+ {conditions: {multiple: false, value: ""}, expected: false, name: "[target] The value is empty"},
+ {conditions: {multiple: false, value: "test@example.com"}, expected: false, name: "[target] The value is a valid email address"},
+ {conditions: {multiple: false, value: "\u000A\u000D\u0020\u0009 test@example.com \u000A\u000D\u0020\u0009"}, expected: false, name: "[target] The value is a valid email address with some white spaces."},
+ {conditions: {multiple: false, value: "abc"}, expected: true, name: "[target] The value is not an email address"},
+ {conditions: {multiple: false, value: "test1@example.com,test2@example.com"}, expected: true, name: "[target] The value contains multiple email addresses"},
+ //multiple is true
+ {conditions: {multiple: true, value: "test1@example.com,test2@example.com"}, expected: false, name: "[target] The value is valid email addresses"},
+ {conditions: {multiple: true, value: "test1@example.com;test2@example.com"}, expected: true, name: "[target] The value contains invalid separator"}
+ ]
+ },
+ {
+ tag: "input",
+ types: ["url"],
+ testData: [
+ {conditions: {multiple: false, value: ""}, expected: false, name: "[target] The value is empty"},
+ {conditions: {multiple: false, value: "http://www.example.com"}, expected: false, name: "[target] The value is a valid url"},
+ {conditions: {multiple: false, value: "\u000A\u000D\u0020\u0009 http://www.example.com \u000A\u000D\u0020\u0009 "}, expected: false, name: "[target] The value is a valid url with some white spaces."},
+ {conditions: {multiple: false, value: "abc"}, expected: true, name: "[target] The value is not an url"}
+ ]
+ }
+ ];
+
+ validator.run_test(testElements, "typeMismatch");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/forms/constraints/form-validation-validity-valid.html b/testing/web-platform/tests/html/semantics/forms/constraints/form-validation-validity-valid.html
new file mode 100644
index 000000000..5dacfeae3
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/constraints/form-validation-validity-valid.html
@@ -0,0 +1,130 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>The constraint validation API Test: element.validity.valid</title>
+<link rel="author" title="Intel" href="http://www.intel.com/">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-validitystate-valid">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#the-constraint-validation-api">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="support/validator.js"></script>
+<div id="log"></div>
+<script>
+ var testElements = [
+ {
+ tag: "input",
+ types: ["text", "search", "tel", "password"],
+ testData: [
+ {conditions: {pattern: "[A-Z]", value: "abc"}, expected: false, name: "[target] validity.valid must be false if validity.patternMismatch is true"},
+ {conditions: {required: true, value: ""}, expected: false, name: "[target] validity.valid must be false if validity.valueMissing is true"}
+ ]
+ },
+ {
+ tag: "input",
+ types: ["url"],
+ testData: [
+ {conditions: {pattern: "http://www.example.com", value: "http://www.example.net"}, expected: false, name: "[target] validity.valid must be false if validity.patternMismatch is true"},
+ {conditions: {value: "abc"}, expected: false, name: "[target] validity.valid must be false if validity.typeMismatch is true"},
+ {conditions: {required: true, value: ""}, expected: false, name: "[target] validity.valid must be false if validity.valueMissing is true"}
+ ]
+ },
+ {
+ tag: "input",
+ types: ["email"],
+ testData: [
+ {conditions: {pattern: "test@example.com", value: "test@example.net"}, expected: false, name: "[target] validity.valid must be false if validity.patternMismatch is true"},
+ {conditions: {value: "abc"}, expected: false, name: "[target] validity.valid must be false if validity.typeMismatch is true"},
+ {conditions: {required: true, value: ""}, expected: false, name: "[target] validity.valid must be false if validity.valueMissing is true"}
+ ]
+ },
+ {
+ tag: "input",
+ types: ["datetime-local"],
+ testData: [
+ {conditions: {max: "2000-01-01T12:00:00", value: "2001-01-01T12:00:00"}, expected: false, name: "[target] validity.valid must be false if validity.rangeOverflow is true"},
+ {conditions: {min: "2001-01-01T12:00:00", value: "2000-01-01T12:00:00"}, expected: false, name: "[target] validity.valid must be false if validity.rangeUnderflow is true"},
+ {conditions: {step: 2 * 60 * 1000, value: "2001-01-01T12:03:00"}, expected: false, name: "[target] validity.valid must be false if validity.stepMismatch is true"},
+ {conditions: {required: true, value: ""}, expected: false, name: "[target] validity.valid must be false if validity.valueMissing is true"}
+ ]
+ },
+ {
+ tag: "input",
+ types: ["date"],
+ testData: [
+ {conditions: {max: "2000-01-01", value: "2001-01-01"}, expected: false, name: "[target] validity.valid must be false if validity.rangeOverflow is true"},
+ {conditions: {min: "2001-01-01", value: "2000-01-01"}, expected: false, name: "[target] validity.valid must be false if validity.rangeUnderflow is true"},
+ {conditions: {step: 2 * 1 * 86400000, value: "2000-01-03"}, expected: false, name: "[target] validity.valid must be false if validity.stepMismatch is true"},
+ {conditions: {required: true, value: ""}, expected: false, name: "[target] validity.valid must be false if validity.valueMissing is true"}
+ ]
+ },
+ {
+ tag: "input",
+ types: ["month"],
+ testData: [
+ {conditions: {max: "2000-01", value: "2001-01"}, expected: false, name: "[target] validity.valid must be false if validity.rangeOverflow is true"},
+ {conditions: {min: "2001-01", value: "2000-01"}, expected: false, name: "[target] validity.valid must be false if validity.rangeUnderflow is true"},
+ {conditions: {step: 2 * 1 * 1, value: "2001-03"}, expected: false, name: "[target] validity.valid must be false if validity.stepMismatch is true"},
+ {conditions: {required: true, value: ""}, expected: false, name: "[target] validity.valid must be false if validity.valueMissing is true"}
+ ]
+ },
+ {
+ tag: "input",
+ types: ["week"],
+ testData: [
+ {conditions: {max: "2000-W01", value: "2001-W01"}, expected: false, name: "[target] validity.valid must be false if validity.rangeOverflow is true"},
+ {conditions: {min: "2001-W01", value: "2000-W01"}, expected: false, name: "[target] validity.valid must be false if validity.rangeUnderflow is true"},
+ {conditions: {step: 2 * 1 * 604800000, value: "2001-W03"}, expected: false, name: "[target] validity.valid must be false if validity.stepMismatch is true"},
+ {conditions: {required: true, value: ""}, expected: false, name: "[target] validity.valid must be false if validity.valueMissing is true"}
+ ]
+ },
+ {
+ tag: "input",
+ types: ["time"],
+ testData: [
+ {conditions: {max: "12:00:00", value: "13:00:00"}, expected: false, name: "[target] validity.valid must be false if validity.rangeOverflow is true"},
+ {conditions: {min: "12:00:00", value: "11:00:00"}, expected: false, name: "[target] validity.valid must be false if validity.rangeUnderflow is true"},
+ {conditions: {step: 2 * 60 * 1000, value: "12:03:00"}, expected: false, name: "[target] validity.valid must be false if validity.stepMismatch is true"},
+ {conditions: {required: true, value: ""}, expected: false, name: "[target] validity.valid must be false if validity.valueMissing is true"}
+ ]
+ },
+ {
+ tag: "input",
+ types: ["number"],
+ testData: [
+ {conditions: {max: "5", value: "6"}, expected: false, name: "[target] validity.valid must be false if validity.rangeOverflow is true"},
+ {conditions: {min: "5", value: "4"}, expected: false, name: "[target] validity.valid must be false if validity.rangeUnderflow is true"},
+ {conditions: {step: 2 * 1 * 1, value: "3"}, expected: false, name: "[target] validity.valid must be false if validity.stepMismatch is true"},
+ {conditions: {required: true, value: ""}, expected: false, name: "[target] validity.valid must be false if validity.valueMissing is true"}
+ ]
+ },
+ {
+ tag: "input",
+ types: ["checkbox", "radio"],
+ testData: [
+ {conditions: {required: true, checked: false, name: "test1"}, expected: false, name: "[target] validity.valid must be false if validity.valueMissing is true"}
+ ]
+ },
+ {
+ tag: "input",
+ types: ["file"],
+ testData: [
+ {conditions: {required: true, files: null}, expected: false, name: "[target] validity.valid must be false if validity.valueMissing is true"}
+ ]
+ },
+ {
+ tag: "select",
+ types: [],
+ testData: [
+ {conditions: {required: true, value: ""}, expected: false, name: "[target] validity.valid must be false if validity.valueMissing is true"}
+ ]
+ },
+ {
+ tag: "textarea",
+ types: [],
+ testData: [
+ {conditions: {required: true, value: ""}, expected: false, name: "[target] validity.valid must be false if validity.valueMissing is true"}
+ ]
+ }
+ ];
+
+ validator.run_test(testElements, "isValid");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/forms/constraints/form-validation-validity-valueMissing.html b/testing/web-platform/tests/html/semantics/forms/constraints/form-validation-validity-valueMissing.html
new file mode 100644
index 000000000..3c9e4c4cb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/constraints/form-validation-validity-valueMissing.html
@@ -0,0 +1,168 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>The constraint validation API Test: element.validity.valueMissing</title>
+<link rel="author" title="Intel" href="http://www.intel.com/">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-validitystate-valuemissing">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#the-constraint-validation-api">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="support/validator.js"></script>
+<div id="log"></div>
+<script>
+ var testElements = [
+ {
+ tag: "input",
+ types: ["text", "search", "tel", "url", "email", "password"],
+ testData: [
+ {conditions: {required: false, value: ""}, expected: false, name: "[target] The required attribute is not set"},
+ {conditions: {required: true, value: "abc"}, expected: false, name: "[target] The value is not empty and required is true"},
+ {conditions: {required: true, value: ""}, expected: true, name: "[target] The value is empty and required is true"}
+ ]
+ },
+ {
+ tag: "input",
+ types: ["datetime-local"],
+ testData: [
+ {conditions: {required: false, value: ""}, expected: false, name: "[target] The required attribute is not set"},
+ {conditions: {required: true, value: "2000-12-10T12:00:00"}, expected: false, name: "[target] Valid local date and time string(2000-12-10T12:00:00)"},
+ {conditions: {required: true, value: "2000-12-10 12:00"}, expected: false, name: "[target] Valid local date and time string(2000-12-10 12:00)"},
+ {conditions: {required: true, value: "1979-10-14T12:00:00.001"}, expected: false, name: "[target] Valid local date and time string(1979-10-14T12:00:00.001)"},
+ {conditions: {required: true, value: 1234567}, expected: true, name: "[target] The value attribute is a number(1234567)"},
+ {conditions: {required: true, value: new Date()}, expected: true, name: "[target] The value attribute is a Date object"},
+ {conditions: {required: true, value: "1979-10-99 99:99"}, expected: true, name: "[target] Invalid local date and time string(1979-10-99 99:99)"},
+ {conditions: {required: true, value: "1979-10-14 12:00:00"}, expected: false, name: "[target] Valid local date and time string(1979-10-14 12:00:00)"},
+ {conditions: {required: true, value: "2001-12-21 12:00"}, expected: true, name: "[target] Invalid local date and time string(2001-12-21 12:00)-two white space"},
+ {conditions: {required: true, value: "abc"}, expected: true, name: "[target] the value attribute is a string(abc)"},
+ {conditions: {required: true, value: ""}, expected: true, name: "[target] The value attribute is empty string"}
+ ]
+ },
+ {
+ tag: "input",
+ types: ["date"],
+ testData: [
+ {conditions: {required: false, value: ""}, expected: false, name: "[target] The required attribute is not set"},
+ {conditions: {required: true, value: "2000-12-10"}, expected: false, name: "[target] Valid date string(2000-12-10)"},
+ {conditions: {required: true, value: "9999-01-01"}, expected: false, name: "[target] Valid date string(9999-01-01)"},
+ {conditions: {required: true, value: 1234567}, expected: true, name: "[target] The value attribute is a number(1234567)"},
+ {conditions: {required: true, value: new Date()}, expected: true, name: "[target] The value attribute is a Date object"},
+ {conditions: {required: true, value: "9999-99-99"}, expected: true, name: "[target] Invalid date string(9999-99-99)"},
+ {conditions: {required: true, value: "37/01/01"}, expected: true, name: "[target] Invalid date string(37-01-01)"},
+ {conditions: {required: true, value: "2000/01/01"}, expected: true, name: "[target] Invalid date string(2000/01/01)"},
+ {conditions: {required: true, value: ""}, expected: true, name: "[target] The value attribute is empty string"}
+ ]
+ },
+ {
+ tag: "input",
+ types: ["month"],
+ testData: [
+ {conditions: {required: false, value: ""}, expected: false, name: "[target] The required attribute is not set"},
+ {conditions: {required: true, value: "2000-12"}, expected: false, name: "[target] Valid month string(2000-12)"},
+ {conditions: {required: true, value: "9999-01"}, expected: false, name: "[target] Valid month string(9999-01)"},
+ {conditions: {required: true, value: 1234567}, expected: true, name: "[target] The value attribute is a number(1234567)"},
+ {conditions: {required: true, value: new Date()}, expected: true, name: "[target] The value attribute is a Date object"},
+ {conditions: {required: true, value: "2000-99"}, expected: true, name: "[target] Invalid month string(2000-99)"},
+ {conditions: {required: true, value: "37-01"}, expected: true, name: "[target] Invalid month string(37-01)"},
+ {conditions: {required: true, value: "2000/01"}, expected: true, name: "[target] Invalid month string(2000/01)"},
+ {conditions: {required: true, value: ""}, expected: true, name: "[target] The value attribute is empty string"}
+ ]
+ },
+ {
+ tag: "input",
+ types: ["week"],
+ testData: [
+ {conditions: {required: false, value: ""}, expected: false, name: "[target] The required attribute is not set"},
+ {conditions: {required: true, value: "2000-W12"}, expected: false, name: "[target] Valid week string(2000-W12)"},
+ {conditions: {required: true, value: "9999-W01"}, expected: false, name: "[target] Valid week string(9999-W01)"},
+ {conditions: {required: true, value: 1234567}, expected: true, name: "[target] The value attribute is a number(1234567)"},
+ {conditions: {required: true, value: new Date()}, expected: true, name: "[target] The value attribute is a Date object"},
+ {conditions: {required: true, value: "2000-W99"}, expected: true, name: "[target] Invalid week string(2000-W99)"},
+ {conditions: {required: true, value: "2000-W00"}, expected: true, name: "[target] invalid week string(2000-W00)"},
+ {conditions: {required: true, value: "2000-w01"}, expected: true, name: "[target] invalid week string(2000-w01)"},
+ {conditions: {required: true, value: ""}, expected: true, name: "[target] The value attribute is empty string"}
+ ]
+ },
+ {
+ tag: "input",
+ types: ["time"],
+ testData: [
+ {conditions: {required: false, value: ""}, expected: false, name: "[target] The required attribute is not set"},
+ {conditions: {required: true, value: "12:00:00"}, expected: false, name: "[target] Validtime string(12:00:00)"},
+ {conditions: {required: true, value: "12:00"}, expected: false, name: "[target] Validtime string(12:00)"},
+ {conditions: {required: true, value: "12:00:00.001"}, expected: false, name: "[target] Valid time string(12:00:60.001)"},
+ {conditions: {required: true, value: "12:00:00.01"}, expected: false, name: "[target] Valid time string(12:00:60.01)"},
+ {conditions: {required: true, value: "12:00:00.1"}, expected: false, name: "[target] Valid time string(12:00:60.1)"},
+ {conditions: {required: true, value: 1234567}, expected: true, name: "[target] The value attribute is a number(1234567)"},
+ {conditions: {required: true, value: new Date()}, expected: true, name: "[target] The value attribute is a time object"},
+ {conditions: {required: true, value: "25:00:00"}, expected: true, name: "[target] Invalid time string(25:00:00)"},
+ {conditions: {required: true, value: "12:60:00"}, expected: true, name: "[target] Invalid time string(12:60:00)"},
+ {conditions: {required: true, value: "12:00:60"}, expected: true, name: "[target] Invalid time string(12:00:60)"},
+ {conditions: {required: true, value: "12:00:00:001"}, expected: true, name: "[target] Invalid time string(12:00:00:001)"},
+ {conditions: {required: true, value: ""}, expected: true, name: "[target] The value attribute is empty string"}
+ ]
+ },
+ {
+ tag: "input",
+ types: ["number"],
+ testData: [
+ {conditions: {required: false, value: ""}, expected: false, name: "[target] The required attribute is not set"},
+ {conditions: {required: true, value: "123"}, expected: false, name: "[target] Value is an integer with a leading symbol '+'"},
+ {conditions: {required: true, value: "-123.45"}, expected: false, name: "[target] Value is a number with a '-' symbol"},
+ {conditions: {required: true, value: "123.01e-10"}, expected: false, name: "[target] Value is a number in scientific notation form(e is in lowercase)"},
+ {conditions: {required: true, value: "123.01E+10"}, expected: false, name: "[target] Value is a number in scientific notation form(E is in uppercase)"},
+ {conditions: {required: true, value: "-0"}, expected: false, name: "[target] Value is -0"},
+ {conditions: {required: true, value: " 123 "}, expected: true, name: "[target] Value is a number with some white spaces"},
+ {conditions: {required: true, value: Math.pow(2, 1024)}, expected: true, name: "[target] Value is Math.pow(2, 1024)"},
+ {conditions: {required: true, value: Math.pow(-2, 1024)}, expected: true, name: "[target] Value is Math.pow(-2, 1024)"},
+ {conditions: {required: true, value: "abc"}, expected: true, name: "[target] Value is a string that cannot be converted to a number"},
+ {conditions: {required: true, value: ""}, expected: true, name: "[target] The value attribute is empty string"}
+ ]
+ },
+ {
+ tag: "input",
+ types: ["checkbox"],
+ testData: [
+ {conditions: {required: false, checked: false, name: "test1"}, expected: false, name: "[target] The required attribute is not set"},
+ {conditions: {required: true, checked: true, name: "test2"}, expected: false, name: "[target] The checked attribute is true"},
+ {conditions: {required: true, checked: false, name: "test3"}, expected: true, name: "[target] The checked attribute is false"}
+ ]
+ },
+ {
+ tag: "input",
+ types: ["radio"],
+ testData: [
+ {conditions: {required: false, checked: false, name: "test4"}, expected: false, name: "[target] The required attribute is not set"},
+ {conditions: {required: true, checked: true, name: "test5"}, expected: false, name: "[target] The checked attribute is true"},
+ {conditions: {required: true, checked: false, name: "test6"}, expected: true, name: "[target] The checked attribute is false"}
+ ]
+ },
+ {
+ tag: "input",
+ types: ["file"],
+ testData: [
+ {conditions: {required: false, files: null}, expected: false, name: "[target] The required attribute is not set"},
+ {conditions: {required: true, files: null}, expected: true, name: "[target] The Files attribute is null"}
+ //ToDo: Add a case to test the files is not null
+ ]
+ },
+ {
+ tag: "select",
+ types: [],
+ testData: [
+ {conditions: {required: false, value: ""}, expected: false, name: "[target] The required attribute is not set"},
+ {conditions: {required: true, value: 1}, expected: false, name: "[target] Selected the option with value equals to 1"},
+ {conditions: {required: true, value: ""}, expected: true, name: "[target] Selected the option with value equals to empty"}
+ ]
+ },
+ {
+ tag: "textarea",
+ types: [],
+ testData: [
+ {conditions: {required: false, value: ""}, expected: false, name: "[target] The required attribute is not set"},
+ {conditions: {required: true, value: "abc"}, expected: false, name: "[target] The value is not empty"},
+ {conditions: {required: true, value: ""}, expected: true , name: "[target] The value is empty"}
+ ]
+ }
+ ];
+
+ validator.run_test(testElements, "valueMissing");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/forms/constraints/form-validation-willValidate.html b/testing/web-platform/tests/html/semantics/forms/constraints/form-validation-willValidate.html
new file mode 100644
index 000000000..237572b0f
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/constraints/form-validation-willValidate.html
@@ -0,0 +1,90 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>The constraint validation API Test: element.willValidate</title>
+<link rel="author" title="Intel" href="http://www.intel.com/">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-cva-willvalidate">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#the-constraint-validation-api">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="support/validator.js"></script>
+<div id="log"></div>
+<script>
+ var testElements = [
+ //input in hidden, button and reset status must be barred from the constraint validation
+ {
+ tag: "input",
+ types: ["hidden", "button", "reset"],
+ testData: [{conditions: {}, expected: false, name: "[target] Must be barred from the constraint validation"}]
+ },
+ //button in button and reset status must be barred from the constraint validation
+ {
+ tag: "button",
+ types: ["button", "reset"],
+ testData: [{conditions: {}, expected: false, name: "[target] Must be barred from the constraint validation"}]
+ },
+ //FIELDSET, OUTPUT elements should not be barred from the constraint validation
+ {
+ tag: "fieldset",
+ types: [],
+ testData: [{conditions: {}, expected: true, name: "[target] Must not be barred from the constraint validation"}]
+ },
+ {
+ tag: "output",
+ types: [],
+ testData: [{conditions: {}, expected: true, name: "[target] Must not be barred from the constraint validation"}]
+ },
+ //OBJECT, KEYGEN, elements must be barred from the constraint validation
+ {
+ tag: "object",
+ types: [],
+ testData: [{conditions: {}, expected: false, name: "[target] Must be barred from the constraint validation"}]
+ },
+ {
+ tag: "keygen",
+ types: [],
+ testData: [{conditions: {}, expected: false, name: "[target] Must be barred from the constraint validation"}]
+ },
+ //If an element is disabled, it is barred from constraint validation.
+ //The willValidate attribute must be true if an element is mutable
+ //If the readonly attribute is specified on an INPUT element, the element is barred from constraint validation.
+ {
+ tag: "input",
+ types: ["text", "search", "tel", "url", "email", "password", "datetime-local", "date", "month", "week", "time", "color", "file", "submit"],
+ testData: [
+ {conditions: {disabled: true}, expected: false, name: "[target] Must be barred from the constraint validation if it is disabled"},
+ {conditions: {disabled: false, readOnly: false}, expected: true, name: "[target] The willValidate attribute must be true if an element is mutable"},
+ {conditions: {readOnly: true}, expected: false, name: "[target] Must be barred from the constraint validation if it is readonly"},
+ {conditions: {disabled: false, readOnly: false}, expected: false, name: "[target] The willValidate attribute must be false if it has a datalist ancestor", ancestor: "datalist"},
+ ]
+ },
+ {
+ tag: "button",
+ types: ["submit"],
+ testData: [
+ {conditions: {disabled: true}, expected: false, name: "[target] Must be barred from the constraint validation"},
+ {conditions: {disabled: false}, expected: true, name: "[target] The willValidate attribute must be true if an element is mutable"},
+ {conditions: {disabled: false}, expected: false, name: "[target] The willValidate attribute must be false if it has a datalist ancestor", ancestor: "datalist"}
+ ]
+ },
+ {
+ tag: "select",
+ types: [],
+ testData: [
+ {conditions: {disabled: true}, expected: false, name: "[target] Must be barred from the constraint validation"},
+ {conditions: {disabled: false}, expected: true, name: "[target] The willValidate attribute must be true if an element is mutable"},
+ {conditions: {disabled: false}, expected: false, name: "[target] The willValidate attribute must be false if it has a datalist ancestor", ancestor: "datalist"}
+ ]
+ },
+ {
+ tag: "textarea",
+ types: [],
+ testData: [,
+ {conditions: {disabled: true}, expected: false, name: "[target] Must be barred from the constraint validation"},
+ {conditions: {disabled: false}, expected: true, name: "[target] The willValidate attribute must be true if an element is mutable"},
+ {conditions: {disabled: false}, expected: false, name: "[target] The willValidate attribute must be false if it has a datalist ancestor", ancestor: "datalist"}
+ ]
+ }
+ ];
+
+ validator.run_test(testElements, "willValidate");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/forms/constraints/inputwillvalidate.html b/testing/web-platform/tests/html/semantics/forms/constraints/inputwillvalidate.html
new file mode 100644
index 000000000..909fd889b
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/constraints/inputwillvalidate.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<html><head>
+ <title>willValidate property on the input element</title>
+ <meta content="text/html; charset=UTF-8" http-equiv="content-type">
+ <meta content="willValidate property on the input element" name="description">
+ <link href="https://html.spec.whatwg.org/multipage/#dom-cva-willvalidate" rel="help">
+ </head>
+ <body>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+
+ <div id="log"></div>
+
+ <form action="http://www.example.com/" style="display : none">
+ <input required="" type="text">
+ <input disabled="" type="text">
+ </form>
+
+ <script type="text/javascript">
+
+ test(function() {assert_true(document.getElementsByTagName("input")[0].willValidate)}, "willValidate property returns true when required attribute exists");
+ test(function() {assert_false(document.getElementsByTagName("input")[1].willValidate)}, "willValidate property returns false when disabled attribute exists");
+
+ </script>
+
+</body></html>
diff --git a/testing/web-platform/tests/html/semantics/forms/constraints/support/validator.js b/testing/web-platform/tests/html/semantics/forms/constraints/support/validator.js
new file mode 100644
index 000000000..e969ce460
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/constraints/support/validator.js
@@ -0,0 +1,377 @@
+var validator = {
+ test_tooLong: function(ctl, data) {
+ var self = this;
+ test(function () {
+ self.pre_check(ctl, "tooLong");
+ self.set_conditions(ctl, data.conditions);
+ if (data.dirty)
+ self.set_dirty(ctl);
+
+ if (data.expected)
+ assert_true(ctl.validity.tooLong, "The validity.tooLong should be true.");
+ else
+ assert_false(ctl.validity.tooLong, "The validity.tooLong should be false.");
+ }, data.name);
+ },
+
+ test_tooShort: function(ctl, data) {
+ var self = this;
+ test(function () {
+ self.pre_check(ctl, "tooShort");
+ self.set_conditions(ctl, data.conditions);
+ if (data.dirty)
+ self.set_dirty(ctl);
+
+ if (data.expected)
+ assert_true(ctl.validity.tooShort, "The validity.tooShort should be true.");
+ else
+ assert_false(ctl.validity.tooShort, "The validity.tooShort should be false.");
+ }, data.name);
+ },
+
+ test_patternMismatch: function(ctl, data) {
+ var self = this;
+ test(function () {
+ self.pre_check(ctl, "patternMismatch");
+ self.set_conditions(ctl, data.conditions);
+
+ if (data.expected)
+ assert_true(ctl.validity.patternMismatch, "The validity.patternMismatch should be true.");
+ else
+ assert_false(ctl.validity.patternMismatch, "The validity.patternMismatch should be false.");
+ }, data.name);
+ },
+
+ test_valueMissing: function(ctl, data) {
+ var self = this;
+ test(function () {
+ self.pre_check(ctl, "valueMissing");
+ self.set_conditions(ctl, data.conditions);
+ if (data.expected)
+ assert_true(ctl.validity.valueMissing, "The validity.valueMissing should be true.");
+ else
+ assert_false(ctl.validity.valueMissing, "The validity.valueMissing should be false.");
+ }, data.name);
+ },
+
+ test_typeMismatch: function(ctl, data) {
+ var self = this;
+ test(function () {
+ self.pre_check(ctl, "typeMismatch");
+ self.set_conditions(ctl, data.conditions);
+
+ if (data.expected)
+ assert_true(ctl.validity.typeMismatch, "The validity.typeMismatch should be true.");
+ else
+ assert_false(ctl.validity.typeMismatch, "The validity.typeMismatch should be false.");
+ }, data.name);
+ },
+
+ test_rangeOverflow: function(ctl, data) {
+ var self = this;
+ test(function () {
+ self.pre_check(ctl, "rangeOverflow");
+ self.set_conditions(ctl, data.conditions);
+
+ if (data.expected)
+ assert_true(ctl.validity.rangeOverflow, "The validity.rangeOverflow should be true.");
+ else
+ assert_false(ctl.validity.rangeOverflow, "The validity.rangeOverflow should be false.");
+ }, data.name);
+ },
+
+ test_rangeUnderflow: function(ctl, data) {
+ var self = this;
+ test(function () {
+ self.pre_check(ctl, "rangeUnderflow");
+ self.set_conditions(ctl, data.conditions);
+ if (data.expected)
+ assert_true(ctl.validity.rangeUnderflow, "The validity.rangeUnderflow should be true.");
+ else
+ assert_false(ctl.validity.rangeUnderflow, "The validity.rangeUnderflow should be false.");
+ }, data.name);
+ },
+
+ test_stepMismatch: function(ctl, data) {
+ var self = this;
+ test(function () {
+ self.pre_check(ctl, "stepMismatch");
+ self.set_conditions(ctl, data.conditions);
+
+ if (data.expected)
+ assert_true(ctl.validity.stepMismatch, "The validity.stepMismatch should be true.");
+ else
+ assert_false(ctl.validity.stepMismatch, "The validity.stepMismatch should be false.");
+ }, data.name);
+ },
+
+ test_badInput: function(ctl, data) {
+ var self = this;
+ test(function () {
+ self.pre_check(ctl, "badInput");
+ self.set_conditions(ctl, data.conditions);
+
+ if (data.expected)
+ assert_true(ctl.validity.badInput, "The validity.badInput should be true.");
+ else
+ assert_false(ctl.validity.badInput, "The validity.badInput should be false.");
+ }, data.name);
+ },
+
+ test_customError: function(ctl, data) {
+ var self = this;
+ test(function () {
+ self.pre_check(ctl, "customError");
+ ctl.setCustomValidity(data.conditions.message);
+
+ if (data.expected) {
+ assert_true(ctl.validity.customError, "The validity.customError attribute should be true.");
+ assert_equals(ctl.validationMessage, data.conditions.message,
+ "The validationMessage attribute should be '" + data.conditions.message + "'.");
+ } else {
+ assert_false(ctl.validity.customError, "The validity.customError attribute should be false.");
+ assert_equals(ctl.validationMessage, "", "The validationMessage attribute must be empty.");
+ }
+ }, data.name);
+ },
+
+ test_isValid: function (ctl, data) {
+ var self = this;
+ test(function () {
+ self.set_conditions(ctl, data.conditions);
+ if (data.dirty)
+ self.set_dirty(ctl);
+
+ if (data.expected)
+ assert_true(ctl.validity.valid, "The validity.valid should be true.");
+ else
+ assert_false(ctl.validity.valid, "The validity.valid should be false.");
+ }, data.name);
+ },
+
+ test_willValidate: function(ctl, data) {
+ var self = this;
+ test(function () {
+ self.pre_check(ctl, "willValidate");
+ self.set_conditions(ctl, data.conditions);
+ if (data.ancestor) {
+ var dl = document.createElement("datalist");
+ dl.appendChild(ctl);
+ }
+
+ if (data.expected)
+ assert_true(ctl.willValidate, "The willValidate attribute should be true.");
+ else
+ assert_false(ctl.willValidate, "The willValidate attribute should be false.");
+ }, data.name);
+ },
+
+ test_checkValidity: function (ctl, data) {
+ var self = this;
+ test(function () {
+ var eventFired = false;
+ self.pre_check(ctl, "checkValidity");
+ self.set_conditions(ctl, data.conditions);
+ if (data.dirty)
+ self.set_dirty(ctl);
+
+ on_event(ctl, "invalid", function(e){
+ assert_equals(e.type, "invalid", "The invalid event should be fired.");
+ eventFired = true;
+ });
+
+ if (data.expected) {
+ assert_true(ctl.checkValidity(), "The checkValidity method should be true.");
+ assert_false(eventFired, "The invalid event should not be fired.");
+ } else {
+ assert_false(ctl.checkValidity(), "The checkValidity method should be false.");
+ assert_true(eventFired, "The invalid event should be fired.");
+ }
+ }, data.name);
+
+ test(function () {
+ var fm = document.createElement("form");
+ var ctl2 = ctl.cloneNode(true);
+
+ self.pre_check(ctl, "checkValidity");
+ self.set_conditions(ctl2, data.conditions);
+ fm.appendChild(ctl2);
+ document.body.appendChild(fm);
+ if (data.dirty)
+ self.set_dirty(ctl2);
+
+ var result = fm.checkValidity();
+ document.body.removeChild(fm);
+
+ if (data.expected)
+ assert_true(result, "The checkValidity method of the element's form owner should return true.");
+ else
+ assert_false(result, "The checkValidity method of the element's form owner should return false.");
+ }, data.name + " (in a form)");
+ },
+
+ test_reportValidity: function (ctl, data) {
+ var self = this;
+ test(function () {
+ var eventFired = false;
+
+ self.pre_check(ctl, "reportValidity");
+ self.set_conditions(ctl, data.conditions);
+ if (data.dirty)
+ self.set_dirty(ctl);
+
+ on_event(ctl, "invalid", function(e){
+ assert_equals(e.type, "invalid", "The invalid event should be fired.");
+ eventFired = true;
+ });
+
+ if (data.expected) {
+ assert_true(ctl.reportValidity(), "The reportValidity method should be true.");
+ assert_false(eventFired, "The invalid event should not be fired.");
+ } else {
+ assert_false(ctl.reportValidity(), "The reportValidity method should be false.");
+ assert_true(eventFired, "The invalid event should be fired.");
+ }
+ }, data.name);
+
+ test(function () {
+ var fm = document.createElement("form");
+ var ctl2 = ctl.cloneNode(true);
+
+ self.pre_check(ctl, "reportValidity");
+ self.set_conditions(ctl2, data.conditions);
+ fm.appendChild(ctl2);
+ document.body.appendChild(fm);
+ if (data.dirty)
+ self.set_dirty(ctl2);
+
+ var result = fm.reportValidity();
+ document.body.removeChild(fm);
+
+ if (data.expected)
+ assert_true(result, "The reportValidity method of the element's form owner should return true.");
+ else
+ assert_false(result, "The reportValidity method of the element's form owner should return false.");
+ }, data.name + " (in a form)");
+ },
+
+ test_support_type: function (ctl, typ, testName) {
+ test(function () {
+ assert_equals(ctl.type, typ, "The " + typ + " type should be supported.");
+ }, testName);
+ },
+
+ set_conditions: function (ctl, obj) {
+ [
+ "checked",
+ "disabled",
+ "max",
+ "maxlength",
+ "min",
+ "minlength",
+ "multiple",
+ "pattern",
+ "required",
+ "selected",
+ "step",
+ "value"
+ ].forEach(function(item) {
+ ctl.removeAttribute(item);
+ });
+ for (var attr in obj) {
+ if (attr === "checked" || obj[attr] || obj[attr] === "")
+ ctl[attr] = obj[attr];
+ }
+ },
+
+ set_dirty: function(ctl) {
+ ctl.focus();
+ var old_value = ctl.value;
+ ctl.value = "a";
+ ctl.value = old_value;
+ },
+
+ pre_check: function(ctl, item) {
+ switch (item) {
+ case "willValidate":
+ assert_true(item in ctl, "The " + item + " attribute doesn't exist.");
+ break;
+ case "checkValidity":
+ case "reportValidity":
+ assert_true(item in ctl, "The " + item + " method doesn't exist.");
+ break;
+ case "tooLong":
+ case "tooShort":
+ case "patternMismatch":
+ case "typeMismatch":
+ case "stepMismatch":
+ case "rangeOverflow":
+ case "rangeUnderflow":
+ case "valueMissing":
+ case "badInput":
+ case "valid":
+ assert_true("validity" in ctl, "The validity attribute doesn't exist.");
+ assert_true(item in ctl.validity, "The " + item + " attribute doesn't exist.");
+ break;
+ case "customError":
+ assert_true("validity" in ctl, "The validity attribute doesn't exist.");
+ assert_true("setCustomValidity" in ctl, "The validity attribute doesn't exist.");
+ assert_true("validationMessage" in ctl, "The validity attribute doesn't exist.");
+ assert_true(item in ctl.validity, "The " + item + " attribute doesn't exist.");
+ break;
+ }
+ },
+
+ run_test: function (testee, method) {
+ var testMethod = "test_" + method;
+ if (typeof this[testMethod] !== "function") {
+ return false;
+ }
+
+ var ele = null,
+ prefix = "";
+
+ for (var i = 0; i < testee.length; i++) {
+ if (testee[i].types.length > 0) {
+ for (var typ in testee[i].types) {
+ ele = document.createElement(testee[i].tag);
+ document.body.appendChild(ele);
+ try {
+ ele.type = testee[i].types[typ];
+ } catch (e) {
+ //Do nothing, avoid the runtime error breaking the test
+ }
+
+ prefix = "[" + testee[i].tag.toUpperCase() + " in " + testee[i].types[typ].toUpperCase() + " status] ";
+ if (ele.type != testee[i].types[typ]) {
+ this.test_support_type(
+ ele,
+ testee[i].types[typ],
+ prefix + "The " + testee[i].types[typ] + " type must be supported."
+ );
+ continue;
+ }
+
+ for (var j = 0; j < testee[i].testData.length; j++) {
+ testee[i].testData[j].name = testee[i].testData[j].name.replace(/\[.*\]\s/g, prefix);
+ this[testMethod](ele, testee[i].testData[j]);
+ }
+ }
+ } else {
+ ele = document.createElement(testee[i].tag);
+ document.body.appendChild(ele);
+ prefix = "[" + testee[i].tag + "] ";
+
+ if (testElements[i].tag === "select") {
+ ele.add(new Option("test1", ""));
+ ele.add(new Option("test2", 1));
+ }
+
+ for (var item in testee[i].testData) {
+ testee[i].testData[item].name = testee[i].testData[item].name.replace("[target]", prefix);
+ this[testMethod](ele, testee[i].testData[item]);
+ }
+ }
+ }
+ }
+}
diff --git a/testing/web-platform/tests/html/semantics/forms/constraints/tooLong-input-email-delete-manual.html b/testing/web-platform/tests/html/semantics/forms/constraints/tooLong-input-email-delete-manual.html
new file mode 100644
index 000000000..008089f39
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/constraints/tooLong-input-email-delete-manual.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>input[type="email"], ValidityState.tooLong and user editing</title>
+ <link rel="author" title="Chris Rebert" href="http://chrisrebert.com">
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#limiting-user-input-length:-the-maxlength-attribute">
+ <meta name="flags" content="interact">
+ <meta name="assert" content="Per the 'Constraint validation' definition in the referenced section, an input whose value was edited by the user but still exceeds the input's maxlength should suffer from being too long.">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+ <body>
+ <p>Delete one character from the following text input:</p>
+ <input type="email" value="jane.doe@example.com" maxlength="5" autocomplete="off" id="testinput">
+
+ <div id="log"></div>
+ <script>
+var input = document.getElementById('testinput');
+setup({explicit_timeout: true, explicit_done: true});
+on_event(input, "input", function () {
+ test(function() {
+ assert_class_string(input.validity, 'ValidityState', 'HTMLInputElement.validity must be a ValidityState instance');
+ assert_true(input.validity.tooLong, "tooLong must be true since the user just changed the input's value and the value exceeds the maxlength");
+ });
+ done();
+});
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/forms/constraints/tooLong-input-password-delete-manual.html b/testing/web-platform/tests/html/semantics/forms/constraints/tooLong-input-password-delete-manual.html
new file mode 100644
index 000000000..353d9466d
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/constraints/tooLong-input-password-delete-manual.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>input[type="password"], ValidityState.tooLong and user editing</title>
+ <link rel="author" title="Chris Rebert" href="http://chrisrebert.com">
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#limiting-user-input-length:-the-maxlength-attribute">
+ <meta name="flags" content="interact">
+ <meta name="assert" content="Per the 'Constraint validation' definition in the referenced section, an input whose value was edited by the user but still exceeds the input's maxlength should suffer from being too long.">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+ <body>
+ <p>Delete one character from the following text input:</p>
+ <input type="password" value="swordfish" maxlength="5" autocomplete="off" id="testinput">
+
+ <div id="log"></div>
+ <script>
+var input = document.getElementById('testinput');
+setup({explicit_timeout: true, explicit_done: true});
+on_event(input, "input", function () {
+ test(function() {
+ assert_class_string(input.validity, 'ValidityState', 'HTMLInputElement.validity must be a ValidityState instance');
+ assert_true(input.validity.tooLong, "tooLong must be true since the user just changed the input's value and the value exceeds the maxlength");
+ });
+ done();
+});
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/forms/constraints/tooLong-input-search-delete-manual.html b/testing/web-platform/tests/html/semantics/forms/constraints/tooLong-input-search-delete-manual.html
new file mode 100644
index 000000000..73be3b6d8
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/constraints/tooLong-input-search-delete-manual.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>input[type="search"], ValidityState.tooLong and user editing</title>
+ <link rel="author" title="Chris Rebert" href="http://chrisrebert.com">
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#limiting-user-input-length:-the-maxlength-attribute">
+ <meta name="flags" content="interact">
+ <meta name="assert" content="Per the 'Constraint validation' definition in the referenced section, an input whose value was edited by the user but still exceeds the input's maxlength should suffer from being too long.">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+ <body>
+ <p>Delete one character from the following text input:</p>
+ <input type="search" value="abcdefghi" maxlength="5" autocomplete="off" id="testinput">
+
+ <div id="log"></div>
+ <script>
+var input = document.getElementById('testinput');
+setup({explicit_timeout: true, explicit_done: true});
+on_event(input, "input", function () {
+ test(function() {
+ assert_class_string(input.validity, 'ValidityState', 'HTMLInputElement.validity must be a ValidityState instance');
+ assert_true(input.validity.tooLong, "tooLong must be true since the user just changed the input's value and the value exceeds the maxlength");
+ });
+ done();
+});
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/forms/constraints/tooLong-input-tel-delete-manual.html b/testing/web-platform/tests/html/semantics/forms/constraints/tooLong-input-tel-delete-manual.html
new file mode 100644
index 000000000..bf7682af3
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/constraints/tooLong-input-tel-delete-manual.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>input[type="tel"], ValidityState.tooLong and user editing</title>
+ <link rel="author" title="Chris Rebert" href="http://chrisrebert.com">
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#limiting-user-input-length:-the-maxlength-attribute">
+ <meta name="flags" content="interact">
+ <meta name="assert" content="Per the 'Constraint validation' definition in the referenced section, an input whose value was edited by the user but still exceeds the input's maxlength should suffer from being too long.">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+ <body>
+ <p>Delete one character from the following text input:</p>
+ <input type="tel" value="123-456-7890" maxlength="7" autocomplete="off" id="testinput">
+
+ <div id="log"></div>
+ <script>
+var input = document.getElementById('testinput');
+setup({explicit_timeout: true, explicit_done: true});
+on_event(input, "input", function () {
+ test(function() {
+ assert_class_string(input.validity, 'ValidityState', 'HTMLInputElement.validity must be a ValidityState instance');
+ assert_true(input.validity.tooLong, "tooLong must be true since the user just changed the input's value and the value exceeds the maxlength");
+ });
+ done();
+});
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/forms/constraints/tooLong-input-text-delete-manual.html b/testing/web-platform/tests/html/semantics/forms/constraints/tooLong-input-text-delete-manual.html
new file mode 100644
index 000000000..2eea2b724
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/constraints/tooLong-input-text-delete-manual.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>input[type="text"], ValidityState.tooLong and user editing</title>
+ <link rel="author" title="Chris Rebert" href="http://chrisrebert.com">
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#limiting-user-input-length:-the-maxlength-attribute">
+ <meta name="flags" content="interact">
+ <meta name="assert" content="Per the 'Constraint validation' definition in the referenced section, an input whose value was edited by the user but still exceeds the input's maxlength should suffer from being too long.">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+ <body>
+ <p>Delete one character from the following text input:</p>
+ <input type="text" value="0123456789" maxlength="5" autocomplete="off" id="testinput">
+
+ <div id="log"></div>
+ <script>
+var input = document.getElementById('testinput');
+setup({explicit_timeout: true, explicit_done: true});
+on_event(input, "input", function () {
+ test(function() {
+ assert_class_string(input.validity, 'ValidityState', 'HTMLInputElement.validity must be a ValidityState instance');
+ assert_true(input.validity.tooLong, "tooLong must be true since the user just changed the input's value and the value exceeds the maxlength");
+ });
+ done();
+});
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/forms/constraints/tooLong-input-url-delete-manual.html b/testing/web-platform/tests/html/semantics/forms/constraints/tooLong-input-url-delete-manual.html
new file mode 100644
index 000000000..17039a71a
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/constraints/tooLong-input-url-delete-manual.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>input[type="url"], ValidityState.tooLong and user editing</title>
+ <link rel="author" title="Chris Rebert" href="http://chrisrebert.com">
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#limiting-user-input-length:-the-maxlength-attribute">
+ <meta name="flags" content="interact">
+ <meta name="assert" content="Per the 'Constraint validation' definition in the referenced section, an input whose value was edited by the user but still exceeds the input's maxlength should suffer from being too long.">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+ <body>
+ <p>Delete one character from the following text input:</p>
+ <input type="url" value="http://example.com/foo" maxlength="12" autocomplete="off" id="testinput">
+
+ <div id="log"></div>
+ <script>
+var input = document.getElementById('testinput');
+setup({explicit_timeout: true, explicit_done: true});
+on_event(input, "input", function () {
+ test(function() {
+ assert_class_string(input.validity, 'ValidityState', 'HTMLInputElement.validity must be a ValidityState instance');
+ assert_true(input.validity.tooLong, "tooLong must be true since the user just changed the input's value and the value exceeds the maxlength");
+ });
+ done();
+});
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/forms/constraints/tooLong-textarea-delete-manual.html b/testing/web-platform/tests/html/semantics/forms/constraints/tooLong-textarea-delete-manual.html
new file mode 100644
index 000000000..2212a1ca9
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/constraints/tooLong-textarea-delete-manual.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>textarea, ValidityState.tooLong and user editing</title>
+ <link rel="author" title="Chris Rebert" href="http://chrisrebert.com">
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#limiting-user-input-length:-the-maxlength-attribute">
+ <meta name="flags" content="interact">
+ <meta name="assert" content="Per the 'Constraint validation' definition in the referenced section, a textarea whose value was edited by the user but still exceeds the textarea's maxlength should suffer from being too long.">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+ <body>
+ <p>Delete one character from the following text area:</p>
+ <textarea maxlength="5" autocomplete="off" id="testinput">0123456789</textarea>
+
+ <div id="log"></div>
+ <script>
+var input = document.getElementById('testinput');
+setup({explicit_timeout: true, explicit_done: true});
+on_event(input, "input", function () {
+ test(function() {
+ assert_class_string(input.validity, 'ValidityState', 'HTMLTextAreaElement.validity must be a ValidityState instance');
+ assert_true(input.validity.tooLong, "tooLong must be true since the user just changed the input's value and the value exceeds the maxlength");
+ });
+ done();
+});
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/forms/form-control-infrastructure/.gitkeep b/testing/web-platform/tests/html/semantics/forms/form-control-infrastructure/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/form-control-infrastructure/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/forms/form-control-infrastructure/contains.json b/testing/web-platform/tests/html/semantics/forms/form-control-infrastructure/contains.json
new file mode 100644
index 000000000..754a6901d
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/form-control-infrastructure/contains.json
@@ -0,0 +1,14 @@
+[
+ {
+ "id": "a-form-control-s-value",
+ "original_id": "a-form-control's-value"
+ },
+ {
+ "id": "mutability",
+ "original_id": "mutability"
+ },
+ {
+ "id": "association-of-controls-and-forms",
+ "original_id": "association-of-controls-and-forms"
+ }
+] \ No newline at end of file
diff --git a/testing/web-platform/tests/html/semantics/forms/form-control-infrastructure/form.html b/testing/web-platform/tests/html/semantics/forms/form-control-infrastructure/form.html
new file mode 100644
index 000000000..29a14ca57
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/form-control-infrastructure/form.html
@@ -0,0 +1,97 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>HTMLInputElement#form</title>
+<link rel="author" title="Ms2ger" href="mailto:Ms2ger@gmail.com">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<form id="form">
+<p><button id="button">button</button>
+<p><fieldset id="fieldset">fieldset</fieldset>
+<p><input id="input">
+<p><keygen id="keygen">
+<p><object id="object">object</object>
+<p><output id="output">output</output>
+<p><select id="select"><option>select</option></select>
+<p><textarea id="textarea">textarea</textarea>
+
+<!-- label is special: label.form is an alias for label.control.form -->
+<p><label id="label">label</label>
+<p><label id="label-form" form="form">label-form</label>
+<p><label id="label-form-form2" form="form2">label-form-form2</label>
+<p><label id="label-with-control">label-with-control <input></label>
+<p><label id="label-for" for="control-for-label">label-for</label> <input id="control-for-label">
+<p><label id="label-with-progress">label-with-progress <progress></progress></label>
+<p><label id="label-with-meter">label-with-meter <meter></meter></label>
+<p>
+ <input id="input-with-form-attr-in-form" form="form2">
+ <label id="label-for-control-form-in-form" for="input-with-form-attr-in-form">label-for-control-form-in-form</label>
+</p>
+</form>
+<form id="form2"></form>
+<p>
+ <input id="input-with-form-attr" form="form2">
+ <label id="label-for-control-form" for="input-with-form-attr">label-for-control-form</label>
+</p>
+<!-- misnested tags where form-association is set by the HTML parser -->
+<table>
+ <form id="form3"><!-- self-closes but sets the form element pointer -->
+ <tr>
+ <td><label id="label-in-table">label-in-table</label>
+ <td><label id="label-in-table-with-control">label-in-table <input></label>
+ <td><label id="label-in-table-for" for="input-in-table">label-in-table-for</label>
+ <td><input id="input-in-table"><!-- is associated with form3 -->
+ </tr>
+ </form>
+</table>
+<script>
+var form;
+setup(function() {
+ form = document.getElementById("form");
+ form2 = document.getElementById("form2");
+ form3 = document.getElementById("form3");
+ if (!form || !form2 || !form3) {
+ throw new TypeError("Didn't find all forms");
+ }
+});
+
+var listedElements = [
+ "button",
+ "fieldset",
+ "input",
+ "keygen",
+ "object",
+ "output",
+ "select",
+ "textarea",
+];
+
+listedElements.forEach(function(localName) {
+ test(function() {
+ var control = document.getElementById(localName);
+ assert_equals(control.form, form);
+ }, localName + ".form");
+});
+
+// label
+function testLabel(id, expected) {
+ test(function() {
+ var label = document.getElementById(id);
+ assert_equals(label.control && label.control.form, expected, 'Sanity check: label.control.form');
+ assert_equals(label.form, expected, 'label.form');
+ }, id + ".form");
+}
+
+testLabel("label", null);
+testLabel("label-form", null);
+testLabel("label-form-form2", null);
+testLabel("label-with-control", form);
+testLabel("label-for", form);
+testLabel("label-with-progress", null);
+testLabel("label-with-meter", null);
+testLabel("label-for-control-form-in-form", form2);
+testLabel("label-for-control-form", form2);
+testLabel("label-in-table", null);
+testLabel("label-in-table-with-control", form3);
+testLabel("label-in-table-for", form3);
+</script>
diff --git a/testing/web-platform/tests/html/semantics/forms/form-submission-0/.gitkeep b/testing/web-platform/tests/html/semantics/forms/form-submission-0/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/form-submission-0/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/forms/form-submission-0/contains.json b/testing/web-platform/tests/html/semantics/forms/form-submission-0/contains.json
new file mode 100644
index 000000000..f9d0d63bf
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/form-submission-0/contains.json
@@ -0,0 +1,30 @@
+[
+ {
+ "id": "introduction-2",
+ "original_id": "introduction-2"
+ },
+ {
+ "id": "implicit-submission",
+ "original_id": "implicit-submission"
+ },
+ {
+ "id": "form-submission-algorithm",
+ "original_id": "form-submission-algorithm"
+ },
+ {
+ "id": "constructing-form-data-set",
+ "original_id": "constructing-form-data-set"
+ },
+ {
+ "id": "url-encoded-form-data",
+ "original_id": "url-encoded-form-data"
+ },
+ {
+ "id": "multipart-form-data",
+ "original_id": "multipart-form-data"
+ },
+ {
+ "id": "plain-text-form-data",
+ "original_id": "plain-text-form-data"
+ }
+] \ No newline at end of file
diff --git a/testing/web-platform/tests/html/semantics/forms/form-submission-0/getactionurl.html b/testing/web-platform/tests/html/semantics/forms/form-submission-0/getactionurl.html
new file mode 100644
index 000000000..83de22026
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/form-submission-0/getactionurl.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<iframe id=testframe src="/common/blank.html"></iframe>
+<script>
+var tests = [
+ {
+ name: "Navigating to URL with a data scheme",
+ action: "data:,hello%20world",
+ output: "hello world"
+ }
+];
+tests.forEach(function(test_obj) {
+ test_obj.test = async_test(test_obj.name);
+});
+
+function run_test() {
+ if (tests.length == 0) {
+ return;
+ }
+ var test_obj = tests.pop();
+ var t = test_obj.test;
+ var testframe = document.getElementById("testframe");
+ var testdocument = testframe.contentWindow.document;
+ testdocument.body.innerHTML =
+ "<form id=testform method=get action=\"" + test_obj.action +"\"></form>";
+ testframe.onload = function() {
+ t.step(function() {
+ var body_text = testframe.contentWindow.document.textContent;
+ assert_equals(body_text, test_obj.output);
+ });
+ t.done();
+ run_test();
+ };
+ testdocument.getElementById("testform").submit();
+};
+document.getElementById("testframe").onload = run_test;
+</script>
diff --git a/testing/web-platform/tests/html/semantics/forms/form-submission-0/submit-entity-body.html b/testing/web-platform/tests/html/semantics/forms/form-submission-0/submit-entity-body.html
new file mode 100644
index 000000000..0edc0f3df
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/form-submission-0/submit-entity-body.html
@@ -0,0 +1,113 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+var simple_tests = [
+ {
+ name: "form submission from form should navigate to url with x-www-form-urlencoded",
+ input: "<input name=foo value=bara>",
+ enctype: "application/x-www-form-urlencoded",
+ submitelement: "",
+ submitaction: function(doc) { doc.getElementById("testform").submit(); }
+ },
+ {
+ name: "form submission from form should navigate to url with multipart/form-data",
+ input: "<textarea name=foo>bar</textarea>",
+ enctype: "multipart/form-data",
+ submitelement: "",
+ submitaction: function(doc) { doc.getElementById("testform").submit(); }
+ },
+ {
+ name: "form submission from form should navigate to url with text/plain",
+ input: "<textarea name=qux>baz</textarea>",
+ enctype: "text/plain",
+ submitelement: "",
+ submitaction: function(doc) { doc.getElementById("testform").submit(); }
+ },
+ {
+ name: "form submission from button should navigate to url with x-www-form-urlencoded",
+ input: "<input name=foo value=bara>",
+ enctype: "application/x-www-form-urlencoded",
+ submitelement: "<button id=buttonsubmit type=\"submit\">Submit</button>",
+ submitaction: function(doc) { doc.getElementById("buttonsubmit").click(); }
+ },
+ {
+ name: "form submission from button should navigate to url with multipart/form-data",
+ input: "<textarea name=foo>bar</textarea>",
+ enctype: "multipart/form-data",
+ submitelement: "<button id=buttonsubmit type=\"submit\">Submit</button>",
+ submitaction: function(doc) { doc.getElementById("buttonsubmit").click(); }
+ },
+ {
+ name: "form submission from button should navigate to url with text/plain",
+ input: "<textarea name=qux>baz</textarea>",
+ enctype: "text/plain",
+ submitelement: "<button id=buttonsubmit type=\"submit\">Submit</button>",
+ submitaction: function(doc) { doc.getElementById("buttonsubmit").click(); }
+ },
+ {
+ name: "form submission from input should navigate to url with x-www-form-urlencoded",
+ input: "<input name=foo value=bara>",
+ enctype: "application/x-www-form-urlencoded",
+ submitelement: "<input id=inputsubmit type=\"submit\">Submit</input>",
+ submitaction: function(doc) { doc.getElementById("inputsubmit").click(); }
+ },
+ {
+ name: "form submission from input should navigate to url with multipart/form-data",
+ input: "<textarea name=foo>bar</textarea>",
+ enctype: "multipart/form-data",
+ submitelement: "<input id=inputsubmit type=\"submit\">Submit</input>",
+ submitaction: function(doc) { doc.getElementById("inputsubmit").click(); }
+ },
+ {
+ name: "form submission from input should navigate to url with text/plain",
+ input: "<input name=qux value=baz>",
+ enctype: "text/plain",
+ submitelement: "<input id=inputsubmit type=\"submit\">Submit</input>",
+ submitaction: function(doc) { doc.getElementById("inputsubmit").click(); }
+ },
+ {
+ name: "form submission from submit input should contain submit button value",
+ input: "<button type=submit name=notclicked value=nope>not clicked</button>",
+ enctype: "application/x-www-form-urlencoded",
+ submitelement: "<button id=inputsubmit type=\"submit\" name=foo value=bara>Submit</button>",
+ submitaction: function(doc) { doc.getElementById("inputsubmit").click(); }
+ }
+,
+ {
+ name: "form submission from submit button should contain submit button value",
+ input: "<input type=submit name=notclicked value=nope/>",
+ enctype: "application/x-www-form-urlencoded",
+ submitelement: "<input id=inputsubmit type=\"submit\" name=foo value=bara >",
+ submitaction: function(doc) { doc.getElementById("inputsubmit").click(); }
+ }
+];
+simple_tests.forEach(function(test_obj) {
+ test_obj.test = async_test(test_obj.name);
+});
+function run_simple_test() {
+ if (simple_tests.length == 0) {
+ return;
+ }
+ var test_obj = simple_tests.pop();
+ var t = test_obj.test;
+ var testframe = document.getElementById("testframe");
+ var testdocument = testframe.contentWindow.document;
+ testdocument.body.innerHTML =
+ "<form id=testform method=post action=\"form-submission.py\" enctype=\"" + test_obj.enctype + "\">" +
+ test_obj.input +
+ test_obj.submitelement +
+ "</form>";
+ testframe.onload = function() {
+ t.step(function (){
+ var response = testframe.contentDocument.documentElement.textContent;
+ assert_equals(response, "OK");
+ });
+ t.done();
+ run_simple_test();
+ };
+ test_obj.submitaction(testdocument);
+}
+</script>
+<iframe id=testframe src="/common/blank.html" onload="run_simple_test();"></iframe>
diff --git a/testing/web-platform/tests/html/semantics/forms/form-submission-0/url-encoded.html b/testing/web-platform/tests/html/semantics/forms/form-submission-0/url-encoded.html
new file mode 100644
index 000000000..5965b6633
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/form-submission-0/url-encoded.html
@@ -0,0 +1,46 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<iframe id=testframe src="/common/blank.html"></iframe>
+<script>
+var simple_tests = [
+ {
+ name: "text.simple",
+ input: "<input name=foo value=bara>",
+ output: "foo=bara"
+ },
+ {
+ name: "textarea.simple",
+ input: "<textarea name=foo>bar</textarea>",
+ output: "foo=bar"
+ },
+];
+simple_tests.forEach(function(test_obj) {
+ test_obj.test = async_test(test_obj.name);
+});
+function run_simple_test() {
+ if (simple_tests.length == 0) {
+ return;
+ }
+ test_obj = simple_tests.pop();
+ var t = test_obj.test;
+ var testframe = document.getElementById("testframe");
+ var testdocument = testframe.contentWindow.document;
+ testdocument.body.innerHTML =
+ "<form id=testform action=\"/common/blank.html\">" +
+ test_obj.input +
+ "</form>";
+ testframe.onload = function() {
+ t.step(function (){
+ var get_url = testframe.contentWindow.location.toString();
+ var encoded = get_url.substr(get_url.indexOf("?") + 1);
+ assert_equals(encoded, test_obj.output);
+ });
+ t.done();
+ run_simple_test();
+ };
+ testdocument.getElementById("testform").submit();
+}
+document.getElementById("testframe").onload = run_simple_test;
+</script>
diff --git a/testing/web-platform/tests/html/semantics/forms/historical.html b/testing/web-platform/tests/html/semantics/forms/historical.html
new file mode 100644
index 000000000..6873ecd25
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/historical.html
@@ -0,0 +1,85 @@
+<!doctype html>
+<title>Historical forms features should not be supported</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<form id=form hidden>
+ <label id=label></label>
+ <input id=input>
+ <button id=button></button>
+ <select id=select>
+ <optgroup id=optgroup>
+ <option id=option>
+ </select>
+ <datalist id=datalist></datalist>
+ <textarea id=textarea></textarea>
+ <progress id=progress></progress>
+ <meter id=meter></meter>
+ <fieldset id=fieldset>
+ <legend id=legend></legend>
+ </fieldset>
+</form>
+
+<form hidden action="isindex-support.txt" target=isindex_iframe id=isindex_form>
+ <input name=isindex value=x>
+ <iframe name=isindex_iframe id=isindex_iframe></iframe>
+</form>
+<script>
+var tags = ['form', 'label', 'input', 'button', 'select', 'datalist',
+'optgroup', 'option', 'textarea', 'progress', 'meter', 'fieldset', 'legend'];
+
+function t(property, tagName) {
+ var tagNames = tagName ? [tagName] : tags;
+ tagNames.forEach(function(tagName) {
+ test(function() {
+ assert_false(property in document.getElementById(tagName));
+ }, tagName + '.' + property + ' should not be supported');
+ });
+}
+
+function inputType(type) {
+ test(function() {
+ var input = document.createElement('input');
+ input.type = type;
+ assert_equals(input.type, 'text');
+ }, '<input type=' + type + '> should not be supported');
+}
+
+// <input type=range multiple>
+// added in https://github.com/whatwg/html/commit/1efac390abb3f95df61f2d2ac6c0feb47349d97b
+// removed in https://github.com/whatwg/html/commit/b598d4f873fb8c27d4b23b033837108edfbc3d75
+t('valueLow', 'input');
+t('valueHigh', 'input');
+
+// requestAutoComplete()
+// added in https://github.com/whatwg/html/commit/321659e4db11228857632487ab72b6959db1ba86
+// removed in https://github.com/whatwg/html/commit/6a257aae619f85390eee20b47767f34887450fcd
+t('requestAutocomplete', 'form');
+t('onautocomplete', 'form');
+t('onautocompleteerror', 'form');
+
+// <input type=datetime>
+// added in WF2
+// removed in https://github.com/whatwg/html/commit/80ba4fa24e5d3d81a10aa1bbd8a2f72f4bcc3f7c
+inputType('datetime');
+
+// <progress form>, <meter form>
+// removed in https://github.com/whatwg/html/commit/3814376a311837ddfac229d9a631cd10adf53157
+t('form', 'progress');
+t('form', 'meter');
+
+// form.item(), form.namedItem()
+// removed in https://github.com/whatwg/html/commit/da87ab9009d5aeca95a602e718439e35b00d0731
+t('item', 'form');
+t('namedItem', 'form');
+
+// <input name=isindex>
+// removed in https://github.com/whatwg/html/commit/5c44abc734eb483f9a7ec79da5844d2fe63d9c3b
+async_test(function() {
+ var iframe = document.getElementById('isindex_iframe');
+ iframe.onload = this.step_func_done(function() {
+ assert_regexp_match(iframe.contentWindow.location.href, /\?isindex=x$/);
+ });
+ document.getElementById('isindex_form').submit();
+}, '<input name=isindex> should not be supported');
+</script>
diff --git a/testing/web-platform/tests/html/semantics/forms/introduction-1/.gitkeep b/testing/web-platform/tests/html/semantics/forms/introduction-1/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/introduction-1/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/forms/introduction-1/contains.json b/testing/web-platform/tests/html/semantics/forms/introduction-1/contains.json
new file mode 100644
index 000000000..12a866813
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/introduction-1/contains.json
@@ -0,0 +1,34 @@
+[
+ {
+ "id": "writing-a-form-s-user-interface",
+ "original_id": "writing-a-form's-user-interface"
+ },
+ {
+ "id": "implementing-the-server-side-processing-for-a-form",
+ "original_id": "implementing-the-server-side-processing-for-a-form"
+ },
+ {
+ "id": "configuring-a-form-to-communicate-with-a-server",
+ "original_id": "configuring-a-form-to-communicate-with-a-server"
+ },
+ {
+ "id": "client-side-form-validation",
+ "original_id": "client-side-form-validation"
+ },
+ {
+ "id": "enabling-client-side-automatic-filling-of-form-controls",
+ "original_id": "enabling-client-side-automatic-filling-of-form-controls"
+ },
+ {
+ "id": "improving-the-user-experience-on-mobile-devices",
+ "original_id": "improving-the-user-experience-on-mobile-devices"
+ },
+ {
+ "id": "the-difference-between-the-field-type-the-autofill-field-name-and-the-input-modality",
+ "original_id": "the-difference-between-the-field-type,-the-autofill-field-name,-and-the-input-modality"
+ },
+ {
+ "id": "input-author-notes",
+ "original_id": "input-author-notes"
+ }
+] \ No newline at end of file
diff --git a/testing/web-platform/tests/html/semantics/forms/resetting-a-form/.gitkeep b/testing/web-platform/tests/html/semantics/forms/resetting-a-form/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/resetting-a-form/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/forms/resetting-a-form/reset-form.html b/testing/web-platform/tests/html/semantics/forms/resetting-a-form/reset-form.html
new file mode 100644
index 000000000..b74b52c46
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/resetting-a-form/reset-form.html
@@ -0,0 +1,105 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>HTML Test: Resetting a form</title>
+<link rel="author" title="Intel" href="http://www.intel.com/">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#concept-form-reset">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#category-reset">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<form name="fm1" style="display:none">
+ <input value="abc" id="ipt1" />
+ <input id="ipt2" />
+ <input type="radio" id="rd1" checked="checked" />
+ <input type="radio" id="rd2"/>
+ <input type="checkbox" id="cb1" checked="checked" />
+ <input type="checkbox" id="cb2" />
+ <textarea id="ta">abc</textarea>
+ <!--<keygen id="kg"></keygen>-->
+ <output id="opt">5</output>
+ <select id="slt1">
+ <option value="1">ITEM1</option>
+ <option value="2">ITEM2</option>
+ </select>
+ <select id="slt2">
+ <option value="1">ITEM1</option>
+ <option value="2" selected>ITEM2</option>
+ </select>
+ <select id="slt3" multiple>
+ <option value="1">ITEM1</option>
+ <option value="2" selected>ITEM2</option>
+ <option value="3" selected>ITEM3</option>
+ </select>
+ <button id="rst1" type="reset">Reset1</button>
+ <input id="rst2" type="reset" value="Reset2" />
+</form>
+<script>
+
+runTest(function() {
+ document.forms.fm1.reset();
+}, "by calling the reset() method");
+
+runTest(function() {
+ document.getElementById("rst1").click();
+}, "by clicking the button in reset status");
+
+runTest(function() {
+ document.getElementById("rst2").click();
+}, "by clicking the input in reset status");
+
+function setPreconditions (arg) {
+ document.getElementById("ipt1").value = "123";
+ document.getElementById("ipt2").value = "123";
+ document.getElementById("rd1").checked = false;
+ document.getElementById("rd2").checked = true;
+ document.getElementById("cb1").checked = false;
+ document.getElementById("cb2").checked = true;
+ document.getElementById("ta").value = "123";
+ document.getElementById("opt").textContent = "abc";
+ document.getElementById("slt1").value = "2";
+ document.getElementById("slt2").value = "1";
+ document.getElementById("slt3").options[0].selected = true;
+ document.getElementById("slt3").options[1].selected = false;
+ document.getElementById("slt3").options[2].selected = false;
+
+ assert_equals(document.getElementById("ipt1").value, "123", "Precondition 1");
+ assert_equals(document.getElementById("ipt2").value, "123", "Precondition 2");
+ assert_false(document.getElementById("rd1").checked, "Precondition 3");
+ assert_true(document.getElementById("rd2").checked, "Precondition 4");
+ assert_false(document.getElementById("cb1").checked, "Precondition 5");
+ assert_true(document.getElementById("cb2").checked, "Precondition 6");
+ assert_equals(document.getElementById("ta").value, "123", "Precondition 17");
+ assert_equals(document.getElementById("opt").textContent, "abc", "Precondition 8");
+ assert_true(document.getElementById("slt1").options[1].selected, "Precondition 9");
+ assert_true(document.getElementById("slt2").options[0].selected, "Precondition 10");
+ assert_true(document.getElementById("slt3").options[0].selected, "Precondition 11");
+ assert_false(document.getElementById("slt3").options[1].selected, "Precondition 12");
+ assert_false(document.getElementById("slt3").options[2].selected, "Precondition 13");
+}
+
+function runTest(reset, description) {
+ test(function() {
+ setPreconditions("Setting preconditions for resetting " + description);
+ reset();
+ assert_equals(document.getElementById("ipt1").value, "abc", "The value of the input element in text status should be 'abc'.");
+ assert_equals(document.getElementById("ipt2").value, "", "The value of the input element in text status should be empty string.");
+ assert_true(document.getElementById("rd1").checked, "The checked attribute of the input element in radio should be true.");
+ assert_false(document.getElementById("rd2").checked, "The checked attribute of the input element in radio should be false.");
+ assert_true(document.getElementById("cb1").checked, "The checked attribute of the input element in checkbox should be true.");
+ assert_false(document.getElementById("cb2").checked, "The checked attribute of the input element in checkbox should be false.");
+ assert_equals(document.getElementById("ta").value, document.getElementById("ta").textContent, "The value attribute of the textarea element should be reset.");
+ assert_equals(document.getElementById("ta").value, "abc", "The value attribute of the textarea element should be 'abc'.");
+ assert_equals(document.getElementById("opt").textContent, document.getElementById("opt").defaultValue, "The textContent of the output element should be reset.");
+ assert_equals(document.getElementById("opt").textContent, "abc", "The textContent of the output element should be 'abc'.");
+ assert_true(document.getElementById("slt1").options[0].selected, "The first option in the select element should be selected.");
+ assert_false(document.getElementById("slt1").options[1].selected, "The second option in the select element should not be selected.");
+ assert_false(document.getElementById("slt2").options[0].selected, "The first option in the select element should not be selected.");
+ assert_true(document.getElementById("slt2").options[1].selected, "The second option in the select element should be selected.");
+ assert_false(document.getElementById("slt3").options[0].selected, "The first option in the select element with multiple attribute should not be selected.");
+ assert_true(document.getElementById("slt3").options[1].selected, "The second option in the select element with multiple attribute should be selected.");
+ assert_true(document.getElementById("slt3").options[2].selected, "The third option in the select element with multiple attribute should be selected.");
+ //TODO: The keygen reset algorithm
+ }, "Resetting the form " + description);
+}
+
+</script>
diff --git a/testing/web-platform/tests/html/semantics/forms/textfieldselection/.gitkeep b/testing/web-platform/tests/html/semantics/forms/textfieldselection/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/textfieldselection/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/forms/textfieldselection/original-id.json b/testing/web-platform/tests/html/semantics/forms/textfieldselection/original-id.json
new file mode 100644
index 000000000..d9fe43585
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/textfieldselection/original-id.json
@@ -0,0 +1 @@
+{"original_id":"textFieldSelection"} \ No newline at end of file
diff --git a/testing/web-platform/tests/html/semantics/forms/textfieldselection/select-event.html b/testing/web-platform/tests/html/semantics/forms/textfieldselection/select-event.html
new file mode 100644
index 000000000..92a12d12e
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/textfieldselection/select-event.html
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>text field selection: select()</title>
+<link rel="author" title="Denis Ah-Kang" href="mailto:denis@w3.org">
+<link rel=help href="https://html.spec.whatwg.org/multipage/#textFieldSelection">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<textarea>foobar</textarea>
+<script>
+ var input_types = ["text", "search", "tel", "url", "password"],
+ t1 = async_test("select() on textarea queues select event"),
+ q1 = false;
+
+ input_types.forEach(function(type) {
+ var input = document.createElement("input"),
+ t = async_test("select() on input type " + type + " queues select event"),
+ q = false;
+ t.step(function() {
+ input.type = type;
+ input.value = "foobar";
+ document.body.appendChild(input);
+ input.onselect = t.step_func_done(function(e) {
+ assert_true(q, "event should be queued");
+ assert_true(e.isTrusted, "event is trusted");
+ assert_true(e.bubbles, "event bubbles");
+ assert_false(e.cancelable, "event is not cancelable");
+ });
+ input.select();
+ q=true;
+ });
+ });
+
+ document.querySelector("textarea").onselect = t1.step_func_done(function(e) {
+ assert_true(q1, "event should be queued");
+ assert_true(e.isTrusted, "event is trusted");
+ assert_true(e.bubbles, "event bubbles");
+ assert_false(e.cancelable, "event is not cancelable");
+ });
+
+ t1.step(function() {
+ document.querySelector("textarea").select();
+ q1=true;
+ });
+</script>
diff --git a/testing/web-platform/tests/html/semantics/forms/textfieldselection/selection-after-content-change.html b/testing/web-platform/tests/html/semantics/forms/textfieldselection/selection-after-content-change.html
new file mode 100644
index 000000000..90ebc28a2
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/textfieldselection/selection-after-content-change.html
@@ -0,0 +1,18 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>Selection indices after content change</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+ test(function() {
+ var input = document.createElement("input");
+ input.focus();
+ input.value = "something something something dark side";
+ input.setSelectionRange(4,20);
+ assert_equals(input.selectionStart, 4);
+ assert_equals(input.selectionEnd, 20);
+ input.value = "It's a trap!";
+ assert_equals(input.selectionStart, input.value.length);
+ assert_equals(input.selectionEnd, input.value.length);
+}, "Selection indices after reseting content");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/forms/textfieldselection/selection-not-application-textarea.html b/testing/web-platform/tests/html/semantics/forms/textfieldselection/selection-not-application-textarea.html
new file mode 100644
index 000000000..c17ad3232
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/textfieldselection/selection-not-application-textarea.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>text field selection (textarea)</title>
+<link rel="author" title="Denis Ah-Kang" href="mailto:denis@w3.org">
+<link rel=help href="https://html.spec.whatwg.org/multipage/#textFieldSelection">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<script>
+ test(function() {
+ var el = document.createElement("textarea");
+ assert_equals(el.selectionStart, 0);
+ assert_equals(el.selectionEnd, 0);
+ el.selectionStart = 1;
+ el.selectionEnd = 1;
+ el.selectionDirection = "forward";
+ el.setRangeText("foobar");
+ el.setSelectionRange(0, 1);
+ }, "text field selection for the input textarea");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/forms/textfieldselection/selection-not-application.html b/testing/web-platform/tests/html/semantics/forms/textfieldselection/selection-not-application.html
new file mode 100644
index 000000000..576e6d125
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/textfieldselection/selection-not-application.html
@@ -0,0 +1,48 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>text field selection</title>
+<link rel="author" title="Denis Ah-Kang" href="mailto:denis@w3.org">
+<link rel=help href="https://html.spec.whatwg.org/multipage/#textFieldSelection">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<script>
+ var types = ["hidden", "email", "datetime-local", "date", "month", "week", "time", "number", "range", "color", "checkbox", "radio", "file", "submit", "image", "reset", "button"]; //types for which the API doesn't apply
+ var types2 = ["text", "search", "tel", "url", "password"]; //types for which the API applies
+
+ types.forEach(function(type){
+ test(function(){
+ var el = document.createElement("input");
+ el.type = type;
+ assert_throws("InvalidStateError", function(){
+ el.selectionStart;
+ });
+ assert_throws("InvalidStateError", function(){
+ el.selectionEnd;
+ });
+ assert_throws("InvalidStateError", function(){
+ el.selectionDirection;
+ });
+ assert_throws("InvalidStateError", function(){
+ el.setRangeText("foobar");
+ });
+ assert_throws("InvalidStateError", function(){
+ el.setSelectionRange(0, 1);
+ });
+ }, "text field selection for the input " + type);
+ });
+
+ types2.forEach(function(type) {
+ test(function() {
+ var el = document.createElement("input");
+ el.type = type;
+ assert_equals(el.selectionStart, 0);
+ assert_equals(el.selectionEnd, 0);
+ el.selectionStart = 1;
+ el.selectionEnd = 1;
+ el.selectionDirection = "forward";
+ el.setRangeText("foobar");
+ el.setSelectionRange(0, 1);
+ }, "text field selection for the input " + type);
+ });
+</script>
diff --git a/testing/web-platform/tests/html/semantics/forms/textfieldselection/selection.html b/testing/web-platform/tests/html/semantics/forms/textfieldselection/selection.html
new file mode 100644
index 000000000..709d26e86
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/textfieldselection/selection.html
@@ -0,0 +1,145 @@
+<!DOCTYPE HTML>
+<title>test if select() API returns correct attributes</title>
+<meta charset="UTF-8">
+<meta name="timeout" content="long">
+<link rel="author" title="Koji Tashiro" href="mailto:koji.tashiro@gmail.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/multipage/association-of-controls-and-forms.html#textFieldSelection">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<div id="log"></div>
+
+<script>
+ var body = document.getElementsByTagName("body").item(0);
+ var dirs = ['forward', 'backward', 'none'];
+ var sampleText = "0123456789";
+
+ var createInputElement = function(value) {
+ var el = document.createElement("input");
+ el.type = "text";
+ el.value = value;
+ body.appendChild(el);
+ return el;
+ };
+
+ var createTextareaElement = function(value) {
+ var el = document.createElement("textarea");
+ el.value = value;
+ body.appendChild(el);
+ return el;
+ };
+
+
+ test(function() {
+ var text = 'a';
+ for (var i=0; i<255; i++) {
+ var el = createInputElement(text);
+ el.select();
+ var selectionText = el.value.substring(el.selectionStart, el.selectionEnd);
+ assert_equals(selectionText, text, "Selection text mismatched");
+ el.parentNode.removeChild(el);
+ text += 'a';
+ }
+ }, "test if selection text is correct for input");
+
+
+ test(function() {
+ var text = 'a';
+ for (var i=0; i<255; i++) {
+ var el = createTextareaElement(text);
+ el.select();
+ var selectionText = el.value.substring(el.selectionStart, el.selectionEnd);
+ assert_equals(selectionText, text, "Selection text mismatched");
+ el.parentNode.removeChild(el);
+ text += 'a';
+ }
+ }, "test if selection text is correct for textarea");
+
+
+ test(function() {
+ var text = 'ã‚';
+ for (var i=0; i<255; i++) {
+ var el = createInputElement(text);
+ el.select();
+ var selectionText = el.value.substring(el.selectionStart, el.selectionEnd);
+ assert_equals(selectionText, text, "Selection text mismatched");
+ el.parentNode.removeChild(el);
+ text += 'ã‚';
+ }
+ }, "test if non-ascii selection text is correct for input");
+
+
+ test(function() {
+ var text = 'ã‚';
+ for (var i=0; i<255; i++) {
+ var el = createTextareaElement(text);
+ el.select();
+ var selectionText = el.value.substring(el.selectionStart, el.selectionEnd);
+ assert_equals(selectionText, text, "Selection text mismatched");
+ el.parentNode.removeChild(el);
+ text += 'ã‚';
+ }
+ }, "test if non-ascii selection text is correct for textarea");
+
+
+ test(function() {
+ var el = createInputElement(sampleText);
+ // If there is no selection, then it must return the offset(in logical order)
+ // to the character that immediately follows the text entry cursor.
+ assert_equals(el.selectionStart, el.value.length, "SelectionStart offset without selection");
+ el.select();
+ assert_equals(el.selectionStart, 0, "SelectionStart offset");
+ el.parentNode.removeChild(el);
+ }, "test SelectionStart offset for input");
+
+
+ test(function() {
+ var el = createTextareaElement(sampleText);
+ // If there is no selection, then it must return the offset(in logical order)
+ // to the character that immediately follows the text entry cursor.
+ assert_equals(el.selectionStart, el.value.length, "SelectionStart offset without selection");
+ el.select();
+ assert_equals(el.selectionStart, 0, "SelectionStart offset");
+ el.parentNode.removeChild(el);
+ }, "test SelectionStart offset for textarea");
+
+
+ test(function() {
+ var el = createInputElement(sampleText);
+ // If there is no selection, then it must return the offset(in logical order)
+ // to the character that immediately follows the text entry cursor.
+ assert_equals(el.selectionEnd, el.value.length, "SelectionEnd offset without selection");
+ el.select();
+ assert_equals(el.selectionEnd, el.value.length, "SelectionEnd offset");
+ el.parentNode.removeChild(el);
+ }, "test SelectionEnd offset for input");
+
+
+ test(function() {
+ var el = createTextareaElement(sampleText);
+ // If there is no selection, then it must return the offset(in logical order)
+ // to the character that immediately follows the text entry cursor.
+ assert_equals(el.selectionEnd, el.value.length, "SelectionEnd offset without selection");
+ el.select();
+ assert_equals(el.selectionEnd, el.value.length, "SelectionEnd offset");
+ el.parentNode.removeChild(el);
+ }, "test SelectionEnd offset for textarea");
+
+
+ test(function() {
+ var el = createInputElement(sampleText);
+ assert_in_array(el.selectionDirection, dirs, "SelectionDirection");
+ el.select();
+ assert_in_array(el.selectionDirection, dirs, "SelectionDirection");
+ el.parentNode.removeChild(el);
+ }, "test SelectionDirection for input");
+
+
+ test(function() {
+ var el = createInputElement(sampleText);
+ assert_in_array(el.selectionDirection, dirs, "SelectionDirection");
+ el.select();
+ assert_in_array(el.selectionDirection, dirs, "SelectionDirection");
+ el.parentNode.removeChild(el);
+ }, "test SelectionDirection for textarea");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/forms/textfieldselection/textfieldselection-setRangeText.html b/testing/web-platform/tests/html/semantics/forms/textfieldselection/textfieldselection-setRangeText.html
new file mode 100644
index 000000000..edc8f2a86
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/textfieldselection/textfieldselection-setRangeText.html
@@ -0,0 +1,120 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>text field selection: setRangeText</title>
+<link rel="author" title="Denis Ah-Kang" href="mailto:denis@w3.org">
+<link rel=help href="https://html.spec.whatwg.org/multipage/#textFieldSelection">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<style>
+ #display_none {display:none;}
+</style>
+<div id="log"></div>
+<input type=text id=text value="foobar">
+<input type=search id=search value="foobar">
+<input type=tel id=tel value="foobar">
+<input type=url id=url value="foobar">
+<input type=password id=password value="foobar">
+<input id=display_none value="foobar">
+<textarea id=textarea>foobar</textarea>
+<script>
+ var input = document.createElement("input");
+ input.id = "input_not_in_doc";
+ input.value = "foobar";
+
+ var elements = [
+ document.getElementById("text"),
+ document.getElementById("search"),
+ document.getElementById("tel"),
+ document.getElementById("url"),
+ document.getElementById("password"),
+ document.getElementById("display_none"),
+ document.getElementById("textarea"),
+ input,
+ ]
+
+ elements.forEach(function(element) {
+ test(function() {
+ element.value = "foobar";
+ element.selectionStart = 0;
+ element.selectionEnd = 3;
+ assert_equals(element.selectionStart, 0);
+ assert_equals(element.selectionEnd, 3);
+ element.setRangeText("foobar2");
+ assert_equals(element.value, "foobar2bar");
+ assert_equals(element.selectionStart, 0);
+ assert_equals(element.selectionEnd, 7);
+ element.setRangeText("foobar3", 7, 10);
+ assert_equals(element.value, "foobar2foobar3");
+ }, element.id + " setRangeText with only one argument replaces the value between selectionStart and selectionEnd, otherwise replaces the value between 2nd and 3rd arguments");
+
+ test(function(){
+ element.value = "foobar";
+ element.selectionStart = 0;
+ element.selectionEnd = 0;
+
+ element.setRangeText("foobar2", 0, 3); // no 4th arg, default "preserve"
+ assert_equals(element.value, "foobar2bar");
+ assert_equals(element.selectionStart, 0);
+ assert_equals(element.selectionEnd, 0);
+ }, element.id + " selectionMode missing");
+
+ test(function(){
+ element.value = "foobar"
+ element.setRangeText("foo", 3, 6, "select");
+ assert_equals(element.value, "foofoo");
+ assert_equals(element.selectionStart, 3);
+ assert_equals(element.selectionEnd, 6);
+ }, element.id + " selectionMode 'select'");
+
+ test(function(){
+ element.value = "foobar"
+ element.setRangeText("foo", 3, 6, "start");
+ assert_equals(element.value, "foofoo");
+ assert_equals(element.selectionStart, 3);
+ assert_equals(element.selectionEnd, 3);
+ }, element.id + " selectionMode 'start'");
+
+ test(function(){
+ element.value = "foobar"
+ element.setRangeText("foobar", 3, 6, "end");
+ assert_equals(element.value, "foofoobar");
+ assert_equals(element.selectionStart, 9);
+ assert_equals(element.selectionEnd, 9);
+ }, element.id + " selectionMode 'end'");
+
+ test(function(){
+ element.value = "foobar"
+ element.selectionStart = 0;
+ element.selectionEnd = 5;
+ assert_equals(element.selectionStart, 0);
+ element.setRangeText("", 3, 6, "preserve");
+ assert_equals(element.value, "foo");
+ assert_equals(element.selectionStart, 0);
+ assert_equals(element.selectionEnd, 3);
+ }, element.id + " selectionMode 'preserve'");
+
+ test(function(){
+ assert_throws("INDEX_SIZE_ERR", function() {
+ element.setRangeText("barfoo", 2, 1);
+ });
+ }, element.id + " setRangeText with 3rd argument greater than 2nd argument throws an IndexSizeError exception");
+
+ test(function(){
+ assert_throws(new TypeError(), function() {
+ element.setRangeText();
+ });
+ }, element.id + " setRangeText without argument throws a type error");
+
+ async_test(function() {
+ var q = false;
+ element.onselect = this.step_func_done(function(e) {
+ assert_true(q, "event should be queued");
+ assert_true(e.isTrusted, "event is trusted");
+ assert_false(e.bubbles, "event bubbles");
+ assert_false(e.cancelable, "event is not cancelable");
+ });
+ element.setRangeText("foobar2", 0, 6);
+ q = true;
+ }, element.id + " setRangeText fires a select event");
+ })
+</script>
diff --git a/testing/web-platform/tests/html/semantics/forms/textfieldselection/textfieldselection-setSelectionRange.html b/testing/web-platform/tests/html/semantics/forms/textfieldselection/textfieldselection-setSelectionRange.html
new file mode 100644
index 000000000..60d591baf
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/textfieldselection/textfieldselection-setSelectionRange.html
@@ -0,0 +1,274 @@
+<!DOCTYPE HTML>
+<title>Test of text field setSelectionRange</title>
+<link rel="author" title="Takeharu.Oshida" href="mailto:georgeosddev@gmail.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-textarea/input-setselectionrange">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<div id="hide" style="display: block">
+ <input id="a" type="text" value="abcde">
+ <textarea id="b">abcde</textarea>
+</div>
+<script>
+test(function() {
+ var input = document.getElementById("a");
+ test(function() {
+ assert_equals(typeof(input.setSelectionRange), "function", "element must have 'setSelectionRange' function");
+ },"input typeof(input.setSelectionRange)'");
+
+ test(function() {
+ assert_equals(input.setSelectionRange(0,1,"forward"),undefined,"setSelectionRange is void functuon");
+ },"input setSelectionRange return void");
+
+ test(function() {
+ input.setSelectionRange(0,1)
+ assert_equals(input.selectionStart, 0, "element.selectionStart should be 0");
+ assert_equals(input.selectionEnd, 1, "element.selectionEnd should be 1");
+ },'input setSelectionRange(0,1)');
+
+ test(function() {
+ input.setSelectionRange(0,input.value.length+1)
+ assert_equals(input.selectionEnd, input.value.length, "Arguments greater than the length of the value of the text field must be treated as pointing at the end of the text field");
+ },'input setSelectionRange(0,input.value.length+1)');
+
+ test(function() {
+ input.setSelectionRange(input.value.length+1,input.value.length+1)
+ assert_equals(input.selectionStart, input.value.length, "Arguments (start) greater than the length of the value of the text field must be treated as pointing at the end of the text field");
+ assert_equals(input.selectionEnd, input.value.length, "Arguments (end) greater than the length of the value of the text field must be treated as pointing at the end of the text field");
+ },'input setSelectionRange(input.value.length+1,input.value.length+1)');
+
+ test(function() {
+ input.setSelectionRange(input.value.length+1,1)
+ assert_equals(input.selectionStart, 1, "If end is less than or equal to start then the start of the selection and the end of the selection must both be placed immediately before the character with offset end");
+ assert_equals(input.selectionEnd, 1, "element.selectionEnd should be 1");
+ },'input setSelectionRange(input.value.length+1,input.value.length+1)');
+
+ test(function() {
+ input.setSelectionRange(2,2)
+ assert_equals(input.selectionStart, 2, "If end is less than or equal to start then the start of the selection and the end of the selection must both be placed immediately before the character with offset end");
+ assert_equals(input.selectionEnd, 2, "If end is less than or equal to start then the start of the selection and the end of the selection must both be placed immediately before the character with offset end");
+ },'input setSelectionRange(2,2)');
+
+ test(function() {
+ input.setSelectionRange(2,1)
+ assert_equals(input.selectionStart, 1, "If end is less than or equal to start then the start of the selection and the end of the selection must both be placed immediately before the character with offset end");
+ assert_equals(input.selectionEnd, 1, "If end is less than or equal to start then the start of the selection and the end of the selection must both be placed immediately before the character with offset end");
+ },'input setSelectionRange(2,1)');
+
+ test(function() {
+ input.setSelectionRange(0,1,"backward")
+ assert_equals(input.selectionDirection, "backward", 'The direction of the selection must be set to backward if direction is a case-sensitive match for the string "backward"');
+ },'input direction of setSelectionRange(0,1,"backward")');
+
+ test(function() {
+ input.setSelectionRange(0,1,"forward")
+ assert_equals(input.selectionDirection, "forward", 'The direction of the selection must be set to forward if direction is a case-sensitive match for the string "forward"');
+ },'input direction of setSelectionRange(0,1,"forward")');
+
+ test(function() {
+ input.setSelectionRange(0,1,"none")
+ assert_equals(input.selectionDirection, "none", 'The direction of the selection must be set to forward if direction is a case-sensitive match for the string "none"');
+ },'input direction of setSelectionRange(0,1,"none")');
+
+ test(function() {
+ input.setSelectionRange(0,1,"hoge")
+ assert_equals(input.selectionDirection, "none", "otherwise");
+ },'input direction of setSelectionRange(0,1,"hoge")');
+
+ test(function() {
+ input.setSelectionRange(0,1,"BACKWARD")
+ assert_equals(input.selectionDirection, "none", "selectionDirection should be 'none'");
+ },'input direction of setSelectionRange(0,1,"BACKWARD")');
+
+ test(function() {
+ input.setSelectionRange(0,1)
+ assert_equals(input.selectionDirection, "none", "if the argument is omitted");
+ },'input direction of setSelectionRange(0,1)');
+
+ test(function() {
+ input.setSelectionRange(1,-1);
+ assert_equals(input.selectionStart, 1, "element.selectionStart should be 1");
+ assert_equals(input.selectionEnd, input.value.length, "ECMAScript conversion to unsigned long");
+ },'input setSelectionRange(1,-1)');
+
+ test(function() {
+ input.setSelectionRange(-1,1);
+ assert_equals(input.selectionStart, 1, "ECMAScript conversion to unsigned long + if end is less than or equal to start then the start of the selection and the end of the selection must both be placed immediately before the character with offset end");
+ assert_equals(input.selectionEnd, 1, "element.selectionEnd should be 1");
+ },'input setSelectionRange(-1,1)');
+
+ test(function() {
+ input.setSelectionRange("string",1);
+ assert_equals(input.selectionStart, 0, "element.selectionStart should be 0");
+ assert_equals(input.selectionEnd, 1, "element.selectionEnd should be 1");
+ },'input setSelectionRange("string",1)');
+
+ test(function() {
+ input.setSelectionRange(true,1);
+ assert_equals(input.selectionStart, 1, "element.selectionStart should be 1");
+ assert_equals(input.selectionEnd, 1, "element.selectionEnd should be 1");
+ },'input setSelectionRange(true,1)');
+
+ test(function() {
+ input.setSelectionRange([],1);
+ assert_equals(input.selectionStart, 0, "element.selectionStart should be 0");
+ assert_equals(input.selectionEnd, 1, "element.selectionEnd should be 1");
+ },'input setSelectionRange([],1)');
+
+ test(function() {
+ input.setSelectionRange({},1);
+ assert_equals(input.selectionStart, 0, "element.selectionStart should be 0");
+ assert_equals(input.selectionEnd, 1, "element.selectionEnd should be 1");
+ },'input setSelectionRange({},1)');
+
+ test(function() {
+ input.setSelectionRange(NaN,1);
+ assert_equals(input.selectionStart, 0, "element.selectionStart should be 0");
+ assert_equals(input.selectionEnd, 1, "element.selectionEnd should be 1");
+ },'input setSelectionRange(NaN,1)');
+
+ test(function() {
+ input.setSelectionRange(null,1);
+ assert_equals(input.selectionStart, 0, "element.selectionStart should be 0");
+ assert_equals(input.selectionEnd, 1, "element.selectionEnd should be 1");
+ },'input setSelectionRange(null,1)');
+
+ test(function() {
+ input.setSelectionRange(undefined,1);
+ assert_equals(input.selectionStart, 0, "element.selectionStart should be 0");
+ assert_equals(input.selectionEnd, 1, "element.selectionEnd should be 1");
+ },'input setSelectionRange(undefined,1)');
+},"test of input.setSelectionRange");
+
+async_test(function() {
+ var q = false;
+ var input = document.getElementById("a");
+ input.addEventListener("select", this.step_func_done(function(e) {
+ assert_true(q, "event should be queued");
+ assert_true(e.isTrusted, "event is trusted");
+ assert_true(e.bubbles, "event bubbles");
+ assert_false(e.cancelable, "event is not cancelable");
+ }));
+ input.setSelectionRange(0, 1);
+ q = true;
+}, "input setSelectionRange fires a select event");
+
+test(function() {
+ var textarea = document.getElementById("b");
+ test(function() {
+ assert_equals(typeof(textarea.setSelectionRange), "function", "element must have 'setSelectionRange' function");
+ },"textarea typeof(input.setSelectionRange)'");
+
+ test(function() {
+ assert_equals(textarea.setSelectionRange(0,1,"forward"),undefined,"setSelectionRange is void functuon");
+ },"textarea setSelectionRange return void");
+
+ test(function() {
+ textarea.setSelectionRange(0,1)
+ assert_equals(textarea.selectionStart, 0, "element.selectionStart should be 0");
+ assert_equals(textarea.selectionEnd, 1, "element.selectionEnd should be 1");
+ },'textarea setSelectionRange(0,1)');
+
+ test(function() {
+ textarea.setSelectionRange(0,textarea.value.length+1)
+ assert_equals(textarea.selectionEnd, textarea.value.length, "Arguments greater than the length of the value of the text field must be treated as pointing at the end of the text field");
+ },'textarea setSelectionRange(0,textarea.value.length+1)');
+
+ test(function() {
+ textarea.setSelectionRange(2,2)
+ assert_equals(textarea.selectionStart, 2, "If end is less than or equal to start then the start of the selection and the end of the selection must both be placed immediately before the character with offset end");
+ assert_equals(textarea.selectionEnd, 2, "If end is less than or equal to start then the start of the selection and the end of the selection must both be placed immediately before the character with offset end");
+ },'textarea setSelectionRange(2,2)');
+
+ test(function() {
+ textarea.setSelectionRange(2,1)
+ assert_equals(textarea.selectionStart, 1, "If end is less than or equal to start then the start of the selection and the end of the selection must both be placed immediately before the character with offset end");
+ assert_equals(textarea.selectionEnd, 1, "If end is less than or equal to start then the start of the selection and the end of the selection must both be placed immediately before the character with offset end");
+ },'textarea setSelectionRange(2,1)');
+
+ test(function() {
+ textarea.setSelectionRange(0,1,"backward")
+ assert_equals(textarea.selectionDirection, "backward", 'The direction of the selection must be set to backward if direction is a case-sensitive match for the string "backward"');
+ },'textarea direction of setSelectionRange(0,1,"backward")');
+
+ test(function() {
+ textarea.setSelectionRange(0,1,"forward")
+ assert_equals(textarea.selectionDirection, "forward", 'The direction of the selection must be set to forward if direction is a case-sensitive match for the string "forward"');
+ },'textarea direction of setSelectionRange(0,1,"forward")');
+
+ test(function() {
+ textarea.setSelectionRange(0,1,"none")
+ assert_equals(textarea.selectionDirection, "none", 'The direction of the selection must be set to forward if direction is a case-sensitive match for the string "none"');
+ },'textarea direction of setSelectionRange(0,1,"none")');
+
+ test(function() {
+ textarea.setSelectionRange(0,1,"hoge")
+ assert_equals(textarea.selectionDirection, "none", "otherwise");
+ },'textarea direction of setSelectionRange(0,1,"hoge")');
+
+ test(function() {
+ textarea.setSelectionRange(0,1,"BACKWARD")
+ assert_equals(textarea.selectionDirection, "none", "selectionDirection should be 'none'");
+ },'textarea direction of setSelectionRange(0,1,"BACKWARD")');
+
+ test(function() {
+ textarea.setSelectionRange(0,1)
+ assert_equals(textarea.selectionDirection, "none", "if the argument is omitted");
+ },'textarea direction of setSelectionRange(0,1)');
+
+ test(function() {
+ textarea.setSelectionRange("string",1);
+ assert_equals(textarea.selectionStart, 0, "element.selectionStart should be 0");
+ assert_equals(textarea.selectionEnd, 1, "element.selectionStart should be 1");
+ },'textarea setSelectionRange("string",1)');
+
+ test(function() {
+ textarea.setSelectionRange(true,1);
+ assert_equals(textarea.selectionStart, 1, "element.selectionStart should be 1");
+ assert_equals(textarea.selectionEnd, 1, "element.selectionStart should be 1");
+ },'textarea setSelectionRange(true,1)');
+
+ test(function() {
+ textarea.setSelectionRange([],1);
+ assert_equals(textarea.selectionStart, 0, "element.selectionStart should be 0");
+ assert_equals(textarea.selectionEnd, 1, "element.selectionStart should be 1");
+ },'textarea setSelectionRange([],1)');
+
+ test(function() {
+ textarea.setSelectionRange({},1);
+ assert_equals(textarea.selectionStart, 0, "element.selectionStart should be 0");
+ assert_equals(textarea.selectionEnd, 1, "element.selectionStart should be 1");
+ },'textarea setSelectionRange({},1)');
+
+ test(function() {
+ textarea.setSelectionRange(NaN,1);
+ assert_equals(textarea.selectionStart, 0, "element.selectionStart should be 0");
+ assert_equals(textarea.selectionEnd, 1, "element.selectionStart should be 1");
+ },'textarea setSelectionRange(NaN,1)');
+
+ test(function() {
+ textarea.setSelectionRange(null,1);
+ assert_equals(textarea.selectionStart, 0, "element.selectionStart should be 0");
+ assert_equals(textarea.selectionEnd, 1, "element.selectionStart should be 1");
+ },'textarea setSelectionRange(null,1)');
+
+ test(function() {
+ textarea.setSelectionRange(undefined,1);
+ assert_equals(textarea.selectionStart, 0, "element.selectionStart should be 0");
+ assert_equals(textarea.selectionEnd, 1, "element.selectionStart should be 1");
+ },'textarea setSelectionRange(undefined,1)');
+},"test of textarea.setSelectionRange");
+
+async_test(function() {
+ var q = false;
+ var textarea = document.getElementById("b");
+ textarea.addEventListener("select", this.step_func_done(function(e) {
+ assert_true(q, "event should be queued");
+ assert_true(e.isTrusted, "event is trusted");
+ assert_true(e.bubbles, "event bubbles");
+ assert_false(e.cancelable, "event is not cancelable");
+ }));
+ textarea.setSelectionRange(0, 1);
+ q = true;
+}, "textarea setSelectionRange fires a select event");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/forms/the-button-element/.gitkeep b/testing/web-platform/tests/html/semantics/forms/the-button-element/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/the-button-element/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/forms/the-button-element/button-activate-frame.html b/testing/web-platform/tests/html/semantics/forms/the-button-element/button-activate-frame.html
new file mode 100644
index 000000000..37619d791
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/the-button-element/button-activate-frame.html
@@ -0,0 +1,3 @@
+<form action="about:blank">
+ <button id="submit">Submit</button>
+</form>
diff --git a/testing/web-platform/tests/html/semantics/forms/the-button-element/button-activate.html b/testing/web-platform/tests/html/semantics/forms/the-button-element/button-activate.html
new file mode 100644
index 000000000..43fe96d39
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/the-button-element/button-activate.html
@@ -0,0 +1,17 @@
+<!doctype html>
+<meta charset="utf-8">
+<title></title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<iframe src="button-activate-frame.html" onload="runTest()"></iframe>
+<script>
+var t = async_test("button activation behaviour submits form");
+function runTest() {
+ var iframe = document.querySelector('iframe');
+ iframe.onload = t.step_func(function() {
+ t.done();
+ });
+ var doc = iframe.contentDocument;
+ doc.querySelector('button').click();
+}
+</script>
diff --git a/testing/web-platform/tests/html/semantics/forms/the-button-element/button-events.html b/testing/web-platform/tests/html/semantics/forms/the-button-element/button-events.html
new file mode 100644
index 000000000..9d308bbed
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/the-button-element/button-events.html
@@ -0,0 +1,66 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>HTML Test: Button - events</title>
+<link rel="author" title="Intel" href="http://www.intel.com/">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#the-button-element">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<form name="fm1" style="display:none">
+ <button id="btn">BUTTON</button>
+ <button id="menu_btn" type="menu" menu="menu">MENU BUTTON</button>
+ <menu id="menu" label="MENU">
+ <li>Menu item</li>
+ </menu>
+</form>
+<script>
+
+var btn = document.getElementById("btn"),
+ menu_btn = document.getElementById("menu_btn"),
+ t1 = async_test("The submit event must be fired when click a button in submit status"),
+ t2 = async_test("The reset event must be fired when click a button in reset status"),
+ t3 = async_test("The show event must be fired when click a button in menu status");
+
+document.forms.fm1.onsubmit = t1.step_func(function (evt) {
+ evt.preventDefault();
+ assert_true(evt.isTrusted, "The isTrusted attribute of the submit event should be true.");
+ assert_true(evt.bubbles, "The bubbles attribute of the submit event should be true.");
+ assert_true(evt.cancelable, "The cancelable attribute of the submit event should be true.");
+ assert_true(evt instanceof Event, "The submit event is an instance of Event interface.");
+ t1.done();
+});
+
+document.forms.fm1.onreset = t2.step_func(function (evt) {
+ assert_true(evt.isTrusted, "The isTrusted attribute of the reset event should be true.");
+ assert_true(evt.bubbles, "The bubbles attribute of the reset event should be true.");
+ assert_true(evt.cancelable, "The cancelable attribute of the reset event should be true.");
+ assert_true(evt instanceof Event, "The reset event is an instance of Event interface.");
+ t2.done();
+});
+
+document.getElementById("menu").onshow = t3.step_func(function (evt) {
+ assert_true(evt.isTrusted, "The isTrusted attribute of the show event should be true.");
+ assert_equals(evt.relatedTarget, menu_btn, "The relatedTarget attribute should be initialized to the related button element.");
+ assert_true(evt.cancelable, "The cancelable attribute of the show event should be true.");
+ assert_true(evt instanceof RelatedEvent, "The show event is an instance of RelatedEvent interface.");
+ t3.done();
+});
+
+t1.step(function () {
+ btn.type = "submit";
+ assert_equals(btn.type, "submit", "The button type should be 'submit'.");
+ btn.click();
+});
+
+t2.step(function () {
+ btn.type = "reset";
+ assert_equals(btn.type, "reset", "The button type should be 'reset'.");
+ btn.click();
+});
+
+t3.step(function () {
+ assert_equals(menu_btn.type, "menu", "The button type should be 'menu'.");
+ menu_btn.click();
+});
+
+</script>
diff --git a/testing/web-platform/tests/html/semantics/forms/the-button-element/button-validation.html b/testing/web-platform/tests/html/semantics/forms/the-button-element/button-validation.html
new file mode 100644
index 000000000..a153907d7
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/the-button-element/button-validation.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>button element validation</title>
+<link rel="author" title="Denis Ah-Kang" href="mailto:denis@w3.org">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#the-button-element">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<button id=btn1>button</button>
+<button id=btn2 type=submit>button</button>
+<button id=btn3 type=reset>button</button>
+<button id=btn4 type=button>button</button>
+<button id=btn5 type=menu>button</button>
+<button id=btn6 type=foobar>button</button>
+<script>
+ function willValid(element, expectedType, willValidate, desc) {
+ test(function(){
+ assert_equals(element.type, expectedType);
+ assert_equals(element.willValidate, willValidate);
+ }, desc);
+ }
+
+ willValid(document.getElementById('btn1'), "submit", true, "missing type attribute");
+ willValid(document.getElementById('btn2'), "submit", true, "submit type attribute");
+ willValid(document.getElementById('btn3'), "reset", false, "reset type attribute");
+ willValid(document.getElementById('btn4'), "button", false, "button type attribute");
+ willValid(document.getElementById('btn5'), "menu", false, "menu type attribute");
+ willValid(document.getElementById('btn6'), "submit", true, "invalid type attribute");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/forms/the-datalist-element/.gitkeep b/testing/web-platform/tests/html/semantics/forms/the-datalist-element/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/the-datalist-element/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/forms/the-datalist-element/datalistoptions.html b/testing/web-platform/tests/html/semantics/forms/the-datalist-element/datalistoptions.html
new file mode 100644
index 000000000..245d43cec
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/the-datalist-element/datalistoptions.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Datalist element options</title>
+<link rel="author" title="Denis Ah-Kang" href="mailto:denis@w3.org">
+<link rel=help href="https://html.spec.whatwg.org/multipage/#the-datalist-element">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<label>
+ Number:
+ <input list=numbers>
+</label>
+<datalist id=numbers>
+ <label> Select number:
+ <select id=num>
+ <option label="zero" value="0">
+ <option label="one" value="1">
+ <option label="two">2
+ <option label="three" disabled>3
+ <option>
+ </select>
+ </label>
+</datalist>
+<script>
+ test(function(){
+ var datalist = document.getElementById('numbers'),
+ labels = [],
+ values = [];
+ assert_equals(datalist.options.length, 5);
+
+ for (var i = 0, len = datalist.options.length; i < len; i++) {
+ assert_equals(datalist.options[i], datalist.options.item(i));
+ labels.push(datalist.options[i].label);
+ values.push(datalist.options[i].value);
+ }
+ assert_array_equals(labels, ["zero", "one", "two", "three", ""]);
+ assert_array_equals(values, ["0", "1", "2", "3", ""]);
+ }, "options label/value");
+
+ test(function(){
+ assert_false(document.getElementById('num').willValidate);
+ }, "If an element has a datalist element ancestor, it is barred from constraint validation");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/forms/the-fieldset-element/.gitkeep b/testing/web-platform/tests/html/semantics/forms/the-fieldset-element/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/the-fieldset-element/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/forms/the-fieldset-element/HTMLFieldSetElement.html b/testing/web-platform/tests/html/semantics/forms/the-fieldset-element/HTMLFieldSetElement.html
new file mode 100644
index 000000000..0c394cbed
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/the-fieldset-element/HTMLFieldSetElement.html
@@ -0,0 +1,54 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>HTML Test: HTMLFieldSetElement interface</title>
+<link rel="author" title="Intel" href="http://www.intel.com/">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#the-fieldset-element">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<form name="fm1" style="display:none">
+ <fieldset id="fs_outer">
+ <legend><input type="checkbox" name="cb"></legend>
+ <input type=text name="txt" id="ctl1">
+ <button id="ctl2" name="btn">BUTTON</button>
+ <fieldset id="fs_inner">
+ <input type="text" name="txt_inner">
+ <progress name="pg" value="0.5"></progress>
+ </fieldset>
+ </fieldset>
+</form>
+<script>
+
+var fm1,
+ fs_outer,
+ children_outer;
+
+setup(function () {
+ fm1 = document.forms.fm1;
+ fs_outer = document.getElementById("fs_outer");
+ children_outer = fs_outer.elements;
+});
+
+test(function () {
+ assert_equals(fs_outer.type, "fieldset", "The value of type attribute is incorrect.");
+}, "The type attribute must return 'fieldset'");
+
+test(function () {
+ assert_equals(fs_outer.form, fm1, "The fieldset should have a form owner.");
+}, "The form attribute must return the fieldset's form owner");
+
+test(function () {
+ assert_true(children_outer instanceof HTMLFormControlsCollection,
+ "The elements attribute should be an HTMLFormControlsCollection object");
+}, "The elements must return an HTMLFormControlsCollection object");
+
+test(function () {
+ var fs_inner = document.getElementById("fs_inner");
+ var children_inner = fs_inner.elements;
+ assert_array_equals(children_inner, [fm1.txt_inner],
+ "The items in the collection must be children of the inner fieldset element.");
+ assert_array_equals(children_outer, [fm1.cb, fm1.txt, fm1.btn, fm1.fs_inner, fm1.txt_inner],
+ "The items in the collection must be children of the outer fieldset element.");
+}, "The controls must root at the fieldset element");
+
+</script>
diff --git a/testing/web-platform/tests/html/semantics/forms/the-fieldset-element/disabled-001.html b/testing/web-platform/tests/html/semantics/forms/the-fieldset-element/disabled-001.html
new file mode 100644
index 000000000..cbbda4ab0
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/the-fieldset-element/disabled-001.html
@@ -0,0 +1,71 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>Fieldset disabled</title>
+<link rel="author" title="Denis Ah-Kang" href="mailto:denis@w3.org">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#the-fieldset-element">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<form>
+ <fieldset id=fs disabled>
+ <legend>
+ <input type=checkbox id=clubc_l1>
+ <input type=radio id=clubr_l1>
+ <input type=text id=clubt_l1>
+ </legend>
+ <legend><input type=checkbox id=club_l2></legend>
+ <p><label>Name on card: <input id=clubname required></label></p>
+ <p><label>Card number: <input id=clubnum required pattern="[-0-9]+"></label></p>
+ </fieldset>
+ <fieldset id=fs2 disabled>
+ <p><legend><input type=checkbox id=club2></legend></p>
+ <p><label>Name on card: <input id=clubname2 required></label></p>
+ <p><label>Card number: <input id=clubnum2 required pattern="[-0-9]+"></label></p>
+ </fieldset>
+ <fieldset id=fs3 disabled>
+ <fieldset>
+ <legend><input type=checkbox id=club3></legend>
+ </fieldset>
+ <p><label>Name on card: <input id=clubname3 required></label></p>
+ <p><label>Card number: <input id=clubnum3 required pattern="[-0-9]+"></label></p>
+ </fieldset>
+ <fieldset id=fs4 disabled>
+ <legend>
+ <fieldset><input type=checkbox id=club4></fieldset>
+ </legend>
+ <p><label>Name on card: <input id=clubname4 required></label></p>
+ <p><label>Card number: <input id=clubnum4 required pattern="[-0-9]+"></label></p>
+ </fieldset>
+</form>
+<script>
+ test(function () {
+ assert_true(document.getElementById('fs').disabled, "The fieldset is disabled");
+ assert_false(document.getElementById('clubname').willValidate, "fieldset is disabled so is input 'clubname'");
+ assert_false(document.getElementById('clubnum').willValidate, "fieldset is disabled so is input 'clubnum'");
+ assert_true(document.getElementById('clubc_l1').willValidate, "input 'clubc_l1' is descendant of the first legend child of the fieldset. It should not be disabled");
+ assert_true(document.getElementById('clubr_l1').willValidate, "input 'clubr_l1' is descendant of the first legend child of the fieldset. It should not be disabled");
+ assert_true(document.getElementById('clubt_l1').willValidate, "input 'clubt_l1' is descendant of the first legend child of the fieldset. It should not be disabled");
+ assert_false(document.getElementById('club_l2').willValidate, "input 'club_l2' is a descendant of the second legend child of the fieldset. It should be disabled");
+ }, "The disabled attribute, when specified, causes all the form control descendants of the fieldset element, excluding those that are descendants of the fieldset element's first legend element child, if any, to be disabled.");
+
+ test(function () {
+ assert_true(document.getElementById('fs2').disabled, "The fieldset is disabled");
+ assert_false(document.getElementById('clubname2').willValidate, "fieldset is disabled so is input 'clubname2'");
+ assert_false(document.getElementById('clubnum2').willValidate, "fieldset is disabled so is input 'clubnum2'");
+ assert_false(document.getElementById('club2').willValidate, "the first legend is not a child of the disbled fieldset: input 'club2' is disabled");
+ }, "The first 'legend' element is not a child of the disabled fieldset: Its descendants should be disabled.");
+
+ test(function () {
+ assert_true(document.getElementById('fs3').disabled, "The fieldset is disabled");
+ assert_false(document.getElementById('clubname3').willValidate, "fieldset is disabled so is input 'clubname3'");
+ assert_false(document.getElementById('clubnum3').willValidate, "fieldset is disabled so is input 'clubnum3'");
+ assert_false(document.getElementById('club3').willValidate, "the first legend is not a child of the disbled fieldset: input 'club3' is disabled");
+ }, "The <legend> element is not a child of the disabled fieldset: Its descendants should be disabled.");
+
+ test(function () {
+ assert_true(document.getElementById('fs4').disabled, "The fieldset is disabled");
+ assert_false(document.getElementById('clubname4').willValidate, "fieldset is disabled so is input 'clubname4'");
+ assert_false(document.getElementById('clubnum4').willValidate, "fieldset is disabled so is input 'clubnum4'");
+ assert_true(document.getElementById('club4').willValidate, "the first legend a child of the disbled fieldset: input 'club4' is disabled");
+ }, "The <legend> element is child of the disabled fieldset: Its descendants should be disabled.");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/forms/the-fieldset-element/disabled-002.xhtml b/testing/web-platform/tests/html/semantics/forms/the-fieldset-element/disabled-002.xhtml
new file mode 100644
index 000000000..896d737df
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/the-fieldset-element/disabled-002.xhtml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+ <title>File input descendants of disabled fieldsets</title>
+ <link rel="author" title="Chris Rebert" href="http://chrisrebert.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#attr-fieldset-disabled" />
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+</head>
+<body>
+ <div id="log"></div>
+ <form>
+ <fieldset id="fs" disabled="disabled">
+ <input id="myfile" type="file" />
+ </fieldset>
+ </form>
+ <script>
+ test(function () {
+ assert_true(document.getElementById('fs').disabled, "disabled fieldset should be disabled");
+ assert_false(document.getElementById('myfile').willValidate, "form control descendant of disabled fieldset that is not also a descendant of a legend should be disabled");
+ }, "A file input without a disabled attribute that is a descendant of a disabled fieldset should be disabled (modulo legend-related complications that don't apply here)");
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/forms/the-form-element/.gitkeep b/testing/web-platform/tests/html/semantics/forms/the-form-element/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/the-form-element/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/forms/the-form-element/form-autocomplete.html b/testing/web-platform/tests/html/semantics/forms/the-form-element/form-autocomplete.html
new file mode 100644
index 000000000..c50ea7317
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/the-form-element/form-autocomplete.html
@@ -0,0 +1,59 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>form autocomplete attribute</title>
+<link rel="author" title="Denis Ah-Kang" href="mailto:denis@w3.org">
+<link rel=help href="https://html.spec.whatwg.org/multipage/#the-form-element">
+<link rel=help href="https://html.spec.whatwg.org/multipage/#attr-fe-autocomplete">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<form name="missing_attribute">
+ <input>
+ <input autocomplete="on">
+ <input autocomplete="off">
+ <input autocomplete="foobar">
+</form>
+<form name="autocomplete_on" autocomplete="on">
+ <input>
+ <input autocomplete="on">
+ <input autocomplete="off">
+ <input autocomplete="foobar">
+</form>
+<form name="autocomplete_off" autocomplete="off">
+ <input>
+ <input autocomplete="on">
+ <input autocomplete="off">
+ <input autocomplete="foobar">
+</form>
+<form name="autocomplete_invalid" autocomplete="foobar">
+ <input>
+ <input autocomplete="on">
+ <input autocomplete="off">
+ <input autocomplete="foobar">
+</form>
+<script>
+ function autocompletetest(form, expectedValues, desc) {
+ test(function(){
+ assert_equals(form.autocomplete, expectedValues[0]);
+ assert_equals(form.elements[0].autocomplete, expectedValues[1]);
+ assert_equals(form.elements[1].autocomplete, expectedValues[2]);
+ assert_equals(form.elements[2].autocomplete, expectedValues[3]);
+ assert_equals(form.elements[3].autocomplete, expectedValues[4]);
+ }, desc);
+ }
+
+ autocompletetest(document.forms.missing_attribute, ["on", "on", "on", "off", ""], "form autocomplete attribute missing");
+ autocompletetest(document.forms.autocomplete_on, ["on", "on", "on", "off", ""], "form autocomplete attribute on");
+ autocompletetest(document.forms.autocomplete_off, ["off", "off", "on", "off", ""], "form autocomplete attribute off");
+ autocompletetest(document.forms.autocomplete_invalid, ["on", "on", "on", "off", ""], "form autocomplete attribute invalid");
+
+ var keywords = [ "name", "honorific-prefix", "given-name", "additional-name", "family-name", "honorific-suffix", "nickname", "username", "new-password", "current-password", "organization-title", "organization", "street-address", "address-line1", "address-line2", "address-line3", "address-level4", "address-level3", "address-level2", "address-level1", "country", "country-name", "postal-code", "cc-name", "cc-given-name", "cc-additional-name", "cc-family-name", "cc-number", "cc-exp", "cc-exp-month", "cc-exp-year", "cc-csc", "cc-type", "transaction-currency", "transaction-amount", "language", "bday", "bday-day", "bday-month", "bday-year", "sex", "url", "photo", "tel", "tel-country-code", "tel-national", "tel-area-code", "tel-local", "tel-local-prefix", "tel-local-suffix", "tel-extension", "email", "impp" ];
+
+ keywords.forEach(function(keyword) {
+ test(function(){
+ var input = document.createElement("input");
+ input.setAttribute("autocomplete", keyword);
+ assert_equals(input.autocomplete, keyword);
+ }, keyword + " is an allowed autocomplete field name");
+ });
+</script>
diff --git a/testing/web-platform/tests/html/semantics/forms/the-form-element/form-elements-interfaces-01.html b/testing/web-platform/tests/html/semantics/forms/the-form-element/form-elements-interfaces-01.html
new file mode 100644
index 000000000..c8b4a6c71
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/the-form-element/form-elements-interfaces-01.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<title>form.elements: interfaces</title>
+<link rel="author" title="Ms2ger" href="mailto:ms2ger@gmail.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-form-elements">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#htmlformcontrolscollection">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<script>
+test(function() {
+ var form = document.createElement("form");
+ ["HTMLFormControlsCollection", "HTMLCollection"].forEach(function(i) {
+ test(function() {
+ assert_true(i in window, "Interface should exist")
+ assert_true(form.elements instanceof window[i],
+ "elements should implement the interface")
+ }, "Testing interface " + i)
+ })
+})
+</script>
diff --git a/testing/web-platform/tests/html/semantics/forms/the-form-element/form-elements-matches.html b/testing/web-platform/tests/html/semantics/forms/the-form-element/form-elements-matches.html
new file mode 100644
index 000000000..792162726
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/the-form-element/form-elements-matches.html
@@ -0,0 +1,46 @@
+<!DOCTYPE html>
+<title>form.elements: matches</title>
+<link rel="author" title="Ms2ger" href="mailto:ms2ger@gmail.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-form-elements">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<div id="test">
+<form id="form">
+<input type="image">
+</form>
+</div>
+<script>
+test(function() {
+ assert_equals(document.getElementById("form").elements.length, 0);
+}, "input type=image should not be present in the form.elements collection")
+test(function() {
+ var form = document.getElementById("form");
+ var i = document.createElement("input");
+ i.name = "2";
+ form.appendChild(i);
+ var j = document.createElement("input");
+ j.name = "03";
+ form.appendChild(j);
+ assert_equals(form.elements[-1], undefined, '[-1]');
+ assert_equals(form.elements["-1"], undefined, '["-1"]');
+ assert_equals(form.elements[0], i, '[0]');
+ assert_equals(form.elements["0"], i, '["0"]');
+ assert_equals(form.elements[1], j, '[1]');
+ assert_equals(form.elements["1"], j, '["1"]');
+ assert_equals(form.elements[2], undefined, '[2]');
+ assert_equals(form.elements["2"], undefined, '["2"]');
+ assert_equals(form.elements[03], undefined, '[03]');
+ assert_equals(form.elements["03"], j, '["03"]');
+ assert_equals(form.elements.item(-1), null, 'item(-1)');
+ assert_equals(form.elements.item(0), i, 'item(0)');
+ assert_equals(form.elements.item(1), j, 'item(1)');
+ assert_equals(form.elements.item(2), null, 'item(2)');
+ assert_equals(form.elements.namedItem("2"), i, 'namedItem("2")');
+ assert_equals(form.elements.namedItem("03"), j, 'namedItem("03")');
+ assert_equals(form.elements.namedItem("3"), null, 'namedItem("3")');
+ assert_array_equals(form.elements, [i, j]);
+ form.removeChild(i);
+ form.removeChild(j);
+}, "form.elements should include elements whose name starts with a number");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/forms/the-form-element/form-elements-nameditem-01.html b/testing/web-platform/tests/html/semantics/forms/the-form-element/form-elements-nameditem-01.html
new file mode 100644
index 000000000..0b5aeb8ef
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/the-form-element/form-elements-nameditem-01.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<title>form.elements: namedItem</title>
+<link rel="author" title="Ms2ger" href="mailto:ms2ger@gmail.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-form-elements">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<div id="test">
+<form id=form>
+<input name=b id=i1>
+<input name=b id=i2>
+</form>
+</div>
+<script>
+test(function() {
+ assert_true("RadioNodeList" in window, "RadioNodeList should exist");
+}, "RadioNodeList should exist")
+test(function() {
+ var nl = document.forms.form.elements["b"];
+ assert_true(nl instanceof NodeList, "Should get a NodeList");
+ if ("RadioNodeList" in window) {
+ assert_true(nl instanceof RadioNodeList, "Should get a RadioNodeList");
+ }
+ assert_array_equals(nl,
+ [document.getElementById("i1"),
+ document.getElementById("i2")]);
+
+ var el = nl[0];
+ el.parentNode.removeChild(el);
+ assert_true(nl instanceof NodeList, "Should get a NodeList");
+ if ("RadioNodeList" in window) {
+ assert_true(nl instanceof RadioNodeList, "Should get a RadioNodeList");
+ }
+ assert_array_equals(nl, [document.getElementById("i2")]);
+ assert_equals(document.forms.form.elements["b"], document.getElementById("i2"));
+}, "elements collection should return elements or RadioNodeLists")
+test(function() {
+ var fs = document.forms.form.appendChild(document.createElement("fieldset"));
+ fs.name = "fs";
+ assert_equals(document.forms.form.elements.fs, fs);
+ fs.parentNode.removeChild(fs);
+}, "elements collection should include fieldsets")
+</script>
diff --git a/testing/web-platform/tests/html/semantics/forms/the-form-element/form-elements-nameditem-02.html b/testing/web-platform/tests/html/semantics/forms/the-form-element/form-elements-nameditem-02.html
new file mode 100644
index 000000000..c25e554de
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/the-form-element/form-elements-nameditem-02.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<title>form.elements: parsing</title>
+<link rel="author" title="Ms2ger" href="mailto:ms2ger@gmail.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-form-elements">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#parsing-main-intr">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<div id="test">
+<form id=form>
+<table>
+<tr>
+<td><input type="radio" name="radio1" id="r1" value=1></td>
+<td><input type="radio" name="radio2" id="r2" value=2></td>
+<input type="radio" name="radio0" id="r0" value=0>
+</tr>
+</table>
+</form>
+</div>
+<script>
+test(function() {
+ var form = document.getElementById("form");
+ assert_array_equals(form.elements,
+ [document.getElementById("r0"),
+ document.getElementById("r1"),
+ document.getElementById("r2")]);
+}, "form.elements should work correctly in the face of table syntax errors")
+</script>
diff --git a/testing/web-platform/tests/html/semantics/forms/the-form-element/form-elements-sameobject.html b/testing/web-platform/tests/html/semantics/forms/the-form-element/form-elements-sameobject.html
new file mode 100644
index 000000000..d1ebac07f
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/the-form-element/form-elements-sameobject.html
@@ -0,0 +1,20 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>Testing [SameObject] on the 'elements' attribute on the 'form' element</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+
+<form>
+ <input>
+</form>
+
+<script>
+test(function() {
+ var form = document.querySelector('form');
+ var elements = form.elements;
+ assert_true(elements === form.elements);
+ form.appendChild(document.createElement('input'));
+ assert_true(elements === form.elements);
+}, "[SameObject] should apply to 'elements' attr on <form>");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/forms/the-form-element/form-indexed-element.html b/testing/web-platform/tests/html/semantics/forms/the-form-element/form-indexed-element.html
new file mode 100644
index 000000000..66f00e761
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/the-form-element/form-indexed-element.html
@@ -0,0 +1,45 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>form.elements: indexed</title>
+<link rel="author" title="Ivan.Yang" href="mailto:jsyangwenjie@gmail.com">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<div id="test">
+<form id=form>
+<input type="radio" name="radio1" id="r1" value=1>
+<input type="radio" name="radio2" id="r2" value=2>
+</form>
+</div>
+<script>
+test(function() {
+ var form = document.getElementById("form");
+ assert_equals(form[0], document.getElementById("r1"));
+ assert_equals(form[1], document.getElementById("r2"));
+ assert_equals(form[2], undefined);
+ assert_equals(form[-1], undefined);
+}, "form.elements should be accessed correctly by index")
+
+test(function(){
+ var form = document.getElementById("form");
+ var old_item = form[0];
+ var old_desc = Object.getOwnPropertyDescriptor(form, 0);
+ assert_equals(old_desc.value, old_item);
+ assert_true(old_desc.enumerable);
+ assert_true(old_desc.configurable);
+ assert_false(old_desc.writable);
+
+ Object.prototype[0] = 5;
+ this.add_cleanup(function () { delete Object.prototype[0]; });
+ assert_equals(form[0], old_item);
+
+ delete form[0];
+ assert_equals(form[0], old_item);
+
+ assert_throws(new TypeError(), function() {
+ "use strict";
+ delete form[0];
+ });
+ assert_equals(form[0], old_item);
+}, 'Trying to delete an indexed property name should never work');
+</script>
diff --git a/testing/web-platform/tests/html/semantics/forms/the-form-element/form-nameditem.html b/testing/web-platform/tests/html/semantics/forms/the-form-element/form-nameditem.html
new file mode 100644
index 000000000..3edf903b7
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/the-form-element/form-nameditem.html
@@ -0,0 +1,330 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Form named getter</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<!-- XXX Nothing tests id attributes yet. -->
+<!-- XXX Keygen. -->
+<!-- XXX We also need tests for moving inputs and forms in the DOM. -->
+<form>
+<input type=button name=button>
+<input type=radio name=radio value=x>
+<input type=radio name=radio value=y>
+<input type=radio name=radio value=z>
+</form>
+
+<form>
+<button name=l1></button>
+<fieldset name=l2></fieldset>
+<input type=hidden name=l3>
+<input type=text name=l4>
+<input type=search name=l5>
+<input type=tel name=l6>
+<input type=url name=l7>
+<input type=email name=l8>
+<input type=password name=l9>
+<input type=datetime name=l10>
+<input type=date name=l11>
+<input type=month name=l12>
+<input type=week name=l13>
+<input type=time name=l14>
+<input type=datetime-local name=l15>
+<input type=number name=l16>
+<input type=range name=l17>
+<input type=color name=l18>
+<input type=checkbox name=l19>
+<input type=radio name=l20>
+<input type=file name=l21>
+<input type=submit name=l22>
+<input type=image name=l23>
+<input type=reset name=l24>
+<input type=button name=l25>
+<input type=foo name=l26>
+<input name=l27>
+<object name=l28></object>
+<output name=l29></output>
+<select name=l30></select>
+<textarea name=l31></textarea>
+</form>
+
+<form>
+<!-- EventTarget -->
+<input type=radio name=addEventListener>
+<input type=radio name=removeEventListener>
+<input type=radio name=dispatchEvent>
+
+<!-- Node -->
+<input type=radio name=nodeType>
+<input type=radio name=nodeName>
+<input type=radio name=ownerDocument>
+
+<!-- Element -->
+<input type=radio name=namespaceURI>
+<input type=radio name=prefix>
+<input type=radio name=localName>
+
+<!-- HTMLElement -->
+<input type=radio name=title>
+<input type=radio name=lang>
+<input type=radio name=dir>
+
+<!-- HTMLFormElement -->
+<input type=radio name=acceptCharset>
+<input type=radio name=action>
+<input type=radio name=autocomplete>
+<input type=radio name=enctype>
+<input type=radio name=encoding>
+<input type=radio name=method>
+<input type=radio name=name>
+<input type=radio name=noValidate>
+<input type=radio name=target>
+<input type=radio name=elements>
+<input type=radio name=length>
+<input type=radio name=submit>
+<input type=radio name=reset>
+<input type=radio name=checkValidity>
+</form>
+
+<img name=x>
+<form></form><!-- no child nodes -->
+<img name=y>
+<form><!-- a child node --></form>
+<img name=z>
+
+<input form=a name=b>
+<form id=a></form>
+<input form=c name=d>
+<input form=c name=d>
+<form id=c></form>
+<script>
+test(function() {
+ var form = document.getElementsByTagName("form")[0]
+ assert_equals(form.item, undefined)
+ assert_false("item" in form)
+}, "Forms should not have an item method")
+
+test(function() {
+ var form = document.getElementsByTagName("form")[0]
+ assert_equals(form.namedItem, undefined)
+ assert_false("namedItem" in form)
+}, "Forms should not have a namedItem method")
+
+test(function() {
+ var form = document.getElementsByTagName("form")[0]
+ var button = document.getElementsByTagName("input")[0]
+ assert_equals(button.type, "button")
+ assert_equals(form.button, button)
+ var desc = Object.getOwnPropertyDescriptor(form, "button");
+ assert_equals(desc.value, button);
+ assert_false(desc.writable);
+ assert_true(desc.configurable);
+ assert_false(desc.enumerable);
+ assert_equals(form.button.length, undefined)
+}, "Name for a single element should work")
+
+test(function() {
+ var form = document.getElementsByTagName("form")[0]
+ assert_equals(form.radio.item(-1), null)
+ assert_array_equals([0, 1, 2].map(function(i) {
+ return form.radio.item(i).value
+ }), ["x", "y", "z"])
+ assert_equals(form.radio.item(3), null)
+}, "Calling item() on the NodeList returned from the named getter should work")
+
+test(function() {
+ var form = document.getElementsByTagName("form")[0]
+ assert_equals(form.radio.length, 3)
+ assert_equals(form.radio[-1], undefined)
+ assert_array_equals([0, 1, 2].map(function(i) {
+ return form.radio[i].value
+ }), ["x", "y", "z"])
+ assert_equals(form.radio[3], undefined)
+}, "Indexed getter on the NodeList returned from the named getter should work")
+
+test(function() {
+ var form = document.getElementsByTagName("form")[0]
+ var indices = [-1, 0, 1, 2, 3]
+ indices.forEach(function(i) {
+ assert_throws(new TypeError(), function() {
+ form.radio(i)
+ })
+ })
+}, "Invoking a legacycaller on the NodeList returned from the named getter " +
+ "should not work")
+
+test(function() {
+ var form = document.getElementsByTagName("form")[1]
+ for (var i = 1; i <= 31; ++i) {
+ if (i == 23) {
+ // input type=image
+ assert_equals(form["l" + i], undefined)
+ } else {
+ assert_equals(form["l" + i], form.children[i - 1])
+ }
+ }
+}, "All listed elements except input type=image should be present in the form")
+
+test(function() {
+ var names = [
+ // EventTarget
+ "addEventListener", "removeEventListener", "dispatchEvent",
+ // Node
+ "nodeType", "nodeName", "ownerDocument",
+ // Element
+ "namespaceURI", "prefix", "localName",
+ // HTMLElement
+ "title", "lang", "dir",
+ // HTMLFormElement
+ "acceptCharset", "action", "autocomplete", "enctype", "encoding", "method",
+ "name", "noValidate", "target", "elements", "length", "submit", "reset",
+ "checkValidity"
+ ]
+ var form = document.getElementsByTagName("form")[2]
+ names.forEach(function(name, i) {
+ assert_equals(form[name], form.children[i])
+ })
+}, "Named elements should override builtins")
+
+test(function() {
+ var form = document.getElementsByTagName("form")[3]
+ assert_equals(form.x, undefined, "x should not be associated with the form")
+ assert_equals(form.y, undefined, "y should not be associated with the form")
+ assert_equals(form.z, undefined, "z should not be associated with the form")
+ assert_equals(form[0], undefined, "The form should not have supported property indices")
+ assert_equals(form.length, 0)
+}, "Named items outside the form should not be returned (no children)")
+
+test(function() {
+ var form = document.getElementsByTagName("form")[4]
+ assert_equals(form.x, undefined, "x should not be associated with the form")
+ assert_equals(form.y, undefined, "y should not be associated with the form")
+ assert_equals(form.z, undefined, "z should not be associated with the form")
+ assert_equals(form[0], undefined, "The form should not have supported property indices")
+ assert_equals(form.length, 0)
+}, "Named items outside the form should not be returned (one child)")
+
+test(function() {
+ var form = document.getElementsByTagName("form")[5]
+ assert_equals(form.id, "a")
+
+ var input = document.getElementsByName("b")[0]
+ assert_equals(input.localName, "input")
+ assert_equals(input.getAttribute("form"), "a")
+
+ assert_equals(form.b, input);
+}, "The form attribute should be taken into account for named getters (single element)")
+
+test(function() {
+ var form = document.getElementsByTagName("form")[6]
+ assert_equals(form.id, "c")
+
+ var input1 = document.getElementsByName("d")[0]
+ assert_equals(input1.localName, "input")
+ assert_equals(input1.getAttribute("form"), "c")
+
+ var input2 = document.getElementsByName("d")[1]
+ assert_equals(input2.localName, "input")
+ assert_equals(input2.getAttribute("form"), "c")
+
+ var desc = Object.getOwnPropertyDescriptor(form, "d");
+ assert_equals(desc.value, form.d);
+ assert_false(desc.writable);
+ assert_true(desc.configurable);
+ assert_false(desc.enumerable);
+
+ assert_true(form.d instanceof NodeList, "form.d should be a NodeList")
+ assert_array_equals(form.d, [input1, input2])
+}, "The form attribute should be taken into account for named getters (multiple elements)")
+
+test(function() {
+ var f = document.body.appendChild(document.createElement("form"))
+ f.id = "f"
+ var g = f.appendChild(document.createElement("form"))
+ g.id = "g"
+ var input = g.appendChild(document.createElement("input"))
+ input.name = "x"
+ assert_equals(f.x, undefined)
+ assert_equals(g.x, input)
+}, "Input should only be a named property on the innermost form that contains it")
+
+test(function() {
+ var form = document.getElementsByTagName("form")[1];
+ var old_item = form["l1"];
+ var old_desc = Object.getOwnPropertyDescriptor(form, "l1");
+ assert_equals(old_desc.value, old_item);
+ assert_false(old_desc.enumerable);
+ assert_true(old_desc.configurable);
+ assert_false(old_desc.writable);
+
+ form["l1"] = 5;
+ assert_equals(form["l1"], old_item);
+ assert_throws(new TypeError(), function() {
+ "use strict";
+ form["l1"] = 5;
+ });
+ assert_throws(new TypeError(), function() {
+ Object.defineProperty(form, "l1", { value: 5 });
+ });
+
+ delete form["l1"];
+ assert_equals(form["l1"], old_item);
+
+ assert_throws(new TypeError(), function() {
+ "use strict";
+ delete form["l1"];
+ });
+ assert_equals(form["l1"], old_item);
+
+}, 'Trying to set an expando that would shadow an already-existing named property');
+
+test(function() {
+ var form = document.getElementsByTagName("form")[1];
+ var old_item = form["new-name"];
+ var old_desc = Object.getOwnPropertyDescriptor(form, "new-name");
+ assert_equals(old_item, undefined);
+ assert_equals(old_desc, undefined);
+
+ form["new-name"] = 5;
+ assert_equals(form["new-name"], 5);
+
+ var input = document.createElement("input");
+ this.add_cleanup(function () {input.remove();});
+ input.name = "new-name";
+ form.appendChild(input);
+
+ assert_equals(form["new-name"], 5);
+
+ delete form["new-name"];
+ assert_equals(form["new-name"], input);
+}, 'Trying to set an expando that shadows a named property that gets added later');
+
+test(function() {
+ var form = document.getElementsByTagName("form")[1];
+ var old_item = form["new-name2"];
+ var old_desc = Object.getOwnPropertyDescriptor(form, "new-name2");
+ assert_equals(old_item, undefined);
+ assert_equals(old_desc, undefined);
+
+ Object.defineProperty(form, "new-name2", { configurable: false, writable:
+ false, value: 5 });
+ assert_equals(form["new-name2"], 5);
+
+ var input = document.createElement("input");
+ this.add_cleanup(function () {input.remove();});
+ input.name = "new-name2";
+ form.appendChild(input);
+
+ assert_equals(form["new-name2"], 5);
+
+ delete form["new-name2"];
+ assert_equals(form["new-name2"], 5);
+
+ assert_throws(new TypeError(), function() {
+ "use strict";
+ delete form["new-name2"];
+ });
+ assert_equals(form["new-name2"], 5);
+}, 'Trying to set a non-configurable expando that shadows a named property that gets added later');
+
+</script>
diff --git a/testing/web-platform/tests/html/semantics/forms/the-input-element/.gitkeep b/testing/web-platform/tests/html/semantics/forms/the-input-element/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/the-input-element/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/forms/the-input-element/button.html b/testing/web-platform/tests/html/semantics/forms/the-input-element/button.html
new file mode 100644
index 000000000..3c826a975
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/the-input-element/button.html
@@ -0,0 +1,66 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>input type button</title>
+<link rel="author" title="Denis Ah-Kang" href="mailto:denis@w3.org">
+<link rel=help href="https://html.spec.whatwg.org/multipage/#button-state-(type=button)">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<form id=f1>
+ <input type=button id=b1 name=b1>
+</form>
+<form>
+ <input id=i1 value="foo">
+ <input type=button id=b2 name=b2>
+</form>
+<form>
+ <input type=radio id=i2 checked name=b3>
+ <input type=button id=b3 name=b3>
+</form>
+<form>
+ <input type=checkbox id=i3>
+ <input type=button id=b4 name=b4>
+</form>
+
+<script>
+ var t = async_test("clicking on button should not submit a form"),
+ b1 = document.getElementById('b1'),
+ b2 = document.getElementById('b2'),
+ b3 = document.getElementById('b3'),
+ b4 = document.getElementById('b4'),
+ i1 = document.getElementById('i1'),
+ i2 = document.getElementById('i2'),
+ i3 = document.getElementById('i3');
+
+ test(function(){
+ assert_false(b1.willValidate);
+ }, "the element is barred from constraint validation");
+
+ document.getElementById('f1').onsubmit = t.step_func(function(e) {
+ e.preventDefault();
+ assert_unreached("form has been submitted");
+ });
+
+ t.step(function() {
+ b1.click();
+ });
+ t.done();
+
+ test(function(){
+ i1.value = "bar";
+ b2.click();
+ assert_equals(i1.value, "bar");
+ }, "clicking on button should not reset other form fields");
+
+ test(function(){
+ assert_true(i2.checked);
+ b3.click();
+ assert_true(i2.checked);
+ }, "clicking on button should not unchecked radio buttons");
+
+ test(function(){
+ assert_false(i3.indeterminate);
+ b4.click();
+ assert_false(i3.indeterminate);
+ }, "clicking on button should not change its indeterminate IDL attribute");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/forms/the-input-element/checkbox.html b/testing/web-platform/tests/html/semantics/forms/the-input-element/checkbox.html
new file mode 100644
index 000000000..b1ccc64c1
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/the-input-element/checkbox.html
@@ -0,0 +1,149 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>input type checkbox</title>
+<link rel="author" title="Denis Ah-Kang" href="mailto:denis@w3.org">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#checkbox-state-(type=checkbox)">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#run-synthetic-click-activation-steps">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<input type=checkbox id=checkbox1>
+<input type=checkbox id=checkbox2 disabled>
+<input type=checkbox id=checkbox3>
+<input type=checkbox id=checkbox4 checked>
+<input type=checkbox id=checkbox5>
+<input type=checkbox id=checkbox6>
+<script>
+ var checkbox1 = document.getElementById('checkbox1'),
+ checkbox2 = document.getElementById('checkbox2'),
+ checkbox3 = document.getElementById('checkbox3'),
+ checkbox4 = document.getElementById('checkbox4'),
+ checkbox5 = document.getElementById('checkbox5'),
+ checkbox6 = document.getElementById('checkbox6'),
+ c1_click_fired = false,
+ c1_input_fired = false,
+ c1_change_fired = false,
+ t1 = async_test("click on mutable checkbox fires a click event, then an input event, then a change event"),
+ t2 = async_test("click on non-mutable checkbox doesn't fire the input or change event"),
+ t3 = async_test("pre-activation steps on unchecked checkbox"),
+ t4 = async_test("pre-activation steps on checked checkbox"),
+ t5 = async_test("canceled activation steps on unchecked checkbox"),
+ t6 = async_test("canceled activation steps on unchecked checkbox (indeterminate=true in onclick)");
+
+ checkbox1.onclick = t1.step_func(function(e) {
+ c1_click_fired = true;
+ assert_false(c1_input_fired, "click event should fire before input event");
+ assert_false(c1_change_fired, "click event should fire before change event");
+ assert_false(e.isTrusted, "click()-initiated click event should not be trusted");
+ });
+ checkbox1.oninput = t1.step_func(function(e) {
+ c1_input_fired = true;
+ assert_true(c1_click_fired, "input event should fire after click event");
+ assert_false(c1_change_fired, "input event should fire before change event");
+ assert_true(e.bubbles, "event should bubble");
+ assert_true(e.isTrusted, "click()-initiated event should be trusted");
+ assert_false(e.cancelable, "event should not be cancelable");
+ assert_true(checkbox1.checked, "checkbox is checked");
+ assert_false(checkbox1.indeterminate, "checkbox is not indeterminate");
+ });
+
+ checkbox1.onchange = t1.step_func(function(e) {
+ c1_change_fired = true;
+ assert_true(c1_click_fired, "change event should fire after click event");
+ assert_true(c1_input_fired, "change event should fire after input event");
+ assert_true(e.bubbles, "event should bubble")
+ assert_true(e.isTrusted, "click()-initiated event should be trusted");
+ assert_false(e.cancelable, "event should not be cancelable");
+ assert_true(checkbox1.checked, "checkbox is checked");
+ assert_false(checkbox1.indeterminate, "checkbox is not indeterminate");
+ });
+
+ checkbox2.oninput= t2.step_func(function(e) {
+ assert_unreached("event input fired");
+ });
+
+ checkbox2.onchange = t2.step_func(function(e) {
+ assert_unreached("event change fired");
+ });
+
+ t1.step(function() {
+ checkbox1.click();
+ assert_true(c1_input_fired);
+ assert_true(c1_change_fired);
+ t1.done();
+ });
+
+ t2.step(function() {
+ checkbox2.click();
+ t2.done();
+ });
+
+ t3.step(function() {
+ checkbox3.indeterminate = true;
+ checkbox3.click();
+ assert_true(checkbox3.checked);
+ assert_false(checkbox3.indeterminate);
+ t3.done();
+ });
+
+ t4.step(function() {
+ checkbox4.indeterminate = true;
+ checkbox4.click();
+ assert_false(checkbox4.checked);
+ assert_false(checkbox4.indeterminate);
+ t4.done();
+ });
+
+ checkbox5.onclick = t5.step_func(function(e) {
+ e.preventDefault();
+ /*
+ The prevention of the click doesn't have an effect until after all the
+ click event handlers have been run.
+ */
+ assert_true(checkbox5.checked);
+ assert_false(checkbox5.indeterminate);
+ window.setTimeout(t5.step_func(function(e) {
+ /*
+ The click event has finished being dispatched, so the checkedness and
+ determinateness have been toggled back by now because the event
+ was preventDefault-ed.
+ */
+ assert_false(checkbox5.checked);
+ assert_false(checkbox5.indeterminate);
+ t5.done();
+ }), 0);
+ });
+
+ t5.step(function(){
+ assert_false(checkbox5.checked);
+ assert_false(checkbox5.indeterminate);
+ checkbox5.click();
+ });
+
+ checkbox6.onclick = t6.step_func(function(e) {
+ checkbox6.indeterminate = true;
+ e.preventDefault();
+ /*
+ The prevention of the click doesn't have an effect until after all the
+ click event handlers have been run.
+ */
+ assert_true(checkbox6.checked);
+ assert_true(checkbox6.indeterminate);
+ window.setTimeout(t6.step_func(function(e) {
+ /*
+ The click event has finished being dispatched, so the checkedness and
+ determinateness have been toggled back by now because the event
+ was preventDefault-ed.
+ */
+ assert_false(checkbox6.checked);
+ assert_false(checkbox6.indeterminate);
+ t6.done();
+ }), 0);
+ });
+
+ t6.step(function(){
+ assert_false(checkbox6.checked);
+ assert_false(checkbox6.indeterminate);
+ checkbox6.click();
+ });
+</script>
diff --git a/testing/web-platform/tests/html/semantics/forms/the-input-element/checked.xhtml b/testing/web-platform/tests/html/semantics/forms/the-input-element/checked.xhtml
new file mode 100644
index 000000000..70aeb5109
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/the-input-element/checked.xhtml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title>input@checked is immediately reflected to 'checked' IDL attribute</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+</head>
+<body>
+<div id="log"></div>
+<input style="display: none" type="checkbox" checked="">
+<script>
+test(function(){
+assert_true(document.querySelector('input').checked, 'Examining "checked" IDL attribute value:')
+});
+</script>
+</input>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/forms/the-input-element/clone.html b/testing/web-platform/tests/html/semantics/forms/the-input-element/clone.html
new file mode 100644
index 000000000..0f7e053ba
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/the-input-element/clone.html
@@ -0,0 +1,150 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Test input value retention upon clone</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<style>form {display: none;} </style>
+<form>
+<p><input type=checkbox> This checkbox is initially unchecked.</p>
+<p><input type=checkbox checked="checked"> This checkbox is initially checked.</p>
+<p><input type=radio name=radio> This radiobutton is initially unchecked.</p>
+<p><input type=radio checked="checked" name=radio> This radiobutton is initially checked.</p>
+<p><input type=hidden value="DEFAULT
+DEFAULT"> This hidden field has the initial value "DEFAULT\nDEFAULT".</p>
+<p><input type=text value=DEFAULT> This text field has the initial value "DEFAULT".</p>
+<p><input type=search value=DEFAULT> This search field has the initial value "DEFAULT".</p>
+<p><input type=tel value=DEFAULT> This phone number field has the initial value "DEFAULT".</p>
+<p><input type=url value=https://default.invalid/> This URL field has the initial value "https://default.invalid/".</p>
+<p><input type=email value=default@default.invalid> This email field has the initial value "default@default.invalid".</p>
+<p><input type=password value=DEFAULT> This password field has the initial value "DEFAULT".</p>
+<p><input type=date value=2015-01-01> This date field has the initial value "2015-01-01".</p>
+<p><input type=month value=2015-01> This month field has the initial value "2015-01".</p>
+<p><input type=week value=2015-W01> This week field has the initial value "2015-W01".</p>
+<p><input type=time value=12:00> This time field has the initial value "12:00".</p>
+<p><input type=datetime-local value=2015-01-01T12:00> This datetime (local) field has the initial value "2015-01-01T12:00".</p>
+<p><input type=number value=1> This number field has the initial value "1".</p>
+<p><input type=range value=1> This range control has the initial value "1".</p>
+<p><input type=color value=#ff0000> This color picker has the initial value "#FF0000".</p>
+<p><input type="button" value="Clone" onclick="clone();"></p>
+</form>
+<script>
+setup(function() {
+ let form = document.getElementsByTagName("form")[0];
+ let inputs = form.getElementsByTagName("input");
+ inputs[0].checked = true;
+ inputs[1].checked = false;
+ inputs[2].checked = true;
+ inputs[4].value = "CHANGED\nCHANGED";
+ inputs[5].value = "CHANGED";
+ inputs[6].value = "CHANGED";
+ inputs[7].value = "CHANGED";
+ inputs[8].value = "https://changed.invalid/";
+ inputs[9].value = "changed@changed.invalid";
+ inputs[10].value = "CHANGED";
+ inputs[11].value = "2016-01-01";
+ inputs[12].value = "2016-01";
+ inputs[13].value = "2016-W01";
+ inputs[14].value = "12:30";
+ inputs[15].value = "2016-01-01T12:30";
+ inputs[16].value = "2";
+ inputs[17].value = "2";
+ inputs[18].value = "#00ff00";
+ let clone = form.cloneNode(true);
+ document.body.appendChild(clone);
+});
+test(function() {
+ let clone = document.getElementsByTagName("form")[1];
+ let inputs = clone.getElementsByTagName("input");
+ assert_true(inputs[0].checked, "Should have retained checked state");
+}, "Checkbox must retain checked state.");
+test(function() {
+ let clone = document.getElementsByTagName("form")[1];
+ let inputs = clone.getElementsByTagName("input");
+ assert_false(inputs[1].checked, "Should have retained unchecked state");
+}, "Checkbox must retain unchecked state.");
+test(function() {
+ let clone = document.getElementsByTagName("form")[1];
+ let inputs = clone.getElementsByTagName("input");
+ assert_true(inputs[2].checked, "Should have retained checked state");
+}, "Radiobutton must retain checked state.");
+test(function() {
+ let clone = document.getElementsByTagName("form")[1];
+ let inputs = clone.getElementsByTagName("input");
+ assert_false(inputs[3].checked, "Should have retained unchecked state");
+}, "Radiobutton must retain unchecked state.");
+test(function() {
+ let clone = document.getElementsByTagName("form")[1];
+ let inputs = clone.getElementsByTagName("input");
+ assert_equals(inputs[4].value, "CHANGED\nCHANGED", "Should have retained the changed value.");
+}, "Hidden field must retain changed value.");
+test(function() {
+ let clone = document.getElementsByTagName("form")[1];
+ let inputs = clone.getElementsByTagName("input");
+ assert_equals(inputs[5].value, "CHANGED", "Should have retained the changed value.");
+}, "Text field must retain changed value.");
+test(function() {
+ let clone = document.getElementsByTagName("form")[1];
+ let inputs = clone.getElementsByTagName("input");
+ assert_equals(inputs[6].value, "CHANGED", "Should have retained the changed value.");
+}, "Search field must retain changed value.");
+test(function() {
+ let clone = document.getElementsByTagName("form")[1];
+ let inputs = clone.getElementsByTagName("input");
+ assert_equals(inputs[7].value, "CHANGED", "Should have retained the changed value.");
+}, "Phone number field must retain changed value.");
+test(function() {
+ let clone = document.getElementsByTagName("form")[1];
+ let inputs = clone.getElementsByTagName("input");
+ assert_equals(inputs[8].value, "https://changed.invalid/", "Should have retained the changed value.");
+}, "URL field must retain changed value.");
+test(function() {
+ let clone = document.getElementsByTagName("form")[1];
+ let inputs = clone.getElementsByTagName("input");
+ assert_equals(inputs[9].value, "changed@changed.invalid", "Should have retained the changed value.");
+}, "Email field must retain changed value.");
+test(function() {
+ let clone = document.getElementsByTagName("form")[1];
+ let inputs = clone.getElementsByTagName("input");
+ assert_equals(inputs[10].value, "CHANGED", "Should have retained the changed value.");
+}, "Password field must retain changed value.");
+test(function() {
+ let clone = document.getElementsByTagName("form")[1];
+ let inputs = clone.getElementsByTagName("input");
+ assert_equals(inputs[11].value, "2016-01-01", "Should have retained the changed value.");
+}, "Date field must retain changed value.");
+test(function() {
+ let clone = document.getElementsByTagName("form")[1];
+ let inputs = clone.getElementsByTagName("input");
+ assert_equals(inputs[12].value, "2016-01", "Should have retained the changed value.");
+}, "Month field must retain changed value.");
+test(function() {
+ let clone = document.getElementsByTagName("form")[1];
+ let inputs = clone.getElementsByTagName("input");
+ assert_equals(inputs[13].value, "2016-W01", "Should have retained the changed value.");
+}, "Week field must retain changed value.");
+test(function() {
+ let clone = document.getElementsByTagName("form")[1];
+ let inputs = clone.getElementsByTagName("input");
+ assert_equals(inputs[14].value, "12:30", "Should have retained the changed value.");
+}, "Time field must retain changed value.");
+test(function() {
+ let clone = document.getElementsByTagName("form")[1];
+ let inputs = clone.getElementsByTagName("input");
+ assert_equals(inputs[15].value, "2016-01-01T12:30", "Should have retained the changed value.");
+}, "Datetime (local) field must retain changed value.");
+test(function() {
+ let clone = document.getElementsByTagName("form")[1];
+ let inputs = clone.getElementsByTagName("input");
+ assert_equals(inputs[16].value, "2", "Should have retained the changed value.");
+}, "Number field must retain changed value.");
+test(function() {
+ let clone = document.getElementsByTagName("form")[1];
+ let inputs = clone.getElementsByTagName("input");
+ assert_equals(inputs[17].value, "2", "Should have retained the changed value.");
+}, "Range control must retain changed value.");
+test(function() {
+ let clone = document.getElementsByTagName("form")[1];
+ let inputs = clone.getElementsByTagName("input");
+ assert_equals(inputs[18].value, "#00ff00", "Should have retained the changed value.");
+}, "Color picker must retain changed value.");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/forms/the-input-element/cloning-steps.html b/testing/web-platform/tests/html/semantics/forms/the-input-element/cloning-steps.html
new file mode 100644
index 000000000..9e6c46fd7
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/the-input-element/cloning-steps.html
@@ -0,0 +1,53 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>Cloning of input elements</title>
+<link rel="help" href="https://dom.spec.whatwg.org/#dom-node-clonenode">
+<link rel="help" href="https://dom.spec.whatwg.org/#concept-node-clone">
+<link rel="help" href="https://dom.spec.whatwg.org/#concept-node-clone-ext">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/forms.html#the-input-element:concept-node-clone-ext">
+<link rel="author" title="Matthew Phillips" href="mailto:matthew@matthewphillips.info">
+
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<script>
+"use strict";
+
+test(function() {
+ var input = document.createElement("input");
+ input.value = "foo bar";
+
+ var copy = input.cloneNode();
+ assert_equals(copy.value, "foo bar");
+}, "input element's value should be cloned");
+
+test(function() {
+ var input = document.createElement("input");
+ input.value = "foo bar";
+
+ var copy = input.cloneNode();
+ copy.setAttribute("value", "something else");
+
+ assert_equals(copy.value, "foo bar");
+}, "input element's dirty value flag should be cloned, so setAttribute doesn't affect the cloned input's value");
+
+test(function() {
+ var input = document.createElement("input");
+ input.setAttribute("type", "radio");
+ input.checked = true;
+
+ var copy = input.cloneNode();
+ assert_equals(copy.checked, true);
+}, "input element's checkedness should be cloned");
+
+test(function() {
+ var input = document.createElement("input");
+ input.setAttribute("type", "radio");
+ input.checked = false;
+
+ var copy = input.cloneNode();
+ copy.setAttribute("checked", "checked");
+
+ assert_equals(copy.checked, false);
+}, "input element's dirty checkedness should be cloned, so setAttribute doesn't affect the cloned input's checkedness");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/forms/the-input-element/color.html b/testing/web-platform/tests/html/semantics/forms/the-input-element/color.html
new file mode 100644
index 000000000..6164815f6
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/the-input-element/color.html
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Form input type=color</title>
+<link rel="author" title="Denis Ah-Kang" href="mailto:denis@w3.org">
+<link rel=help href="https://html.spec.whatwg.org/multipage/multipage/common-microsyntaxes.html#colors">
+<link rel=help href="https://html.spec.whatwg.org/multipage/multipage/states-of-the-type-attribute.html#color-state-(type=color)">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<script>
+ var colors = [
+ {value: "", expected: "#000000", testname: "Empty value should return #000000"},
+ {expected: "#000000", testname: "Missing value should return #000000"},
+ {value: "#ffffff", expected: "#ffffff", testname: "Valid simple color: should return #ffffff"},
+ {value: "#FFFFFF", expected: "#ffffff", testname: "Valid simple color (containing LATIN CAPITAL LETTERS): should return #ffffff (converted to ASCII lowercase)"},
+ {value: "#0F0F0F", expected: "#0f0f0f", testname: "Zero-padding"},
+ {value: "#fff", expected: "#000000", testname: "Invalid simple color: not 7 characters long"},
+ {value: "fffffff", expected: "#000000", testname: "Invalid simple color: no starting # sign"},
+ {value: "#gggggg", expected: "#000000", testname: "Invalid simple color: non ASCII hex digits"},
+ {value: "foobar", expected: "#000000", testname: "Invalid simple color: foobar"},
+ {value: "#ffffff\u0000", expected: "#000000", testname: "Invalid color: trailing Null (U+0000)"},
+ {value: "#ffffff;", expected: "#000000", testname: "Invalid color: trailing ;"},
+ {value: " #ffffff", expected: "#000000", testname: "Invalid color: leading space"},
+ {value: "#ffffff ", expected: "#000000", testname: "Invalid color: trailing space"},
+ {value: " #ffffff ", expected: "#000000", testname: "Invalid color: leading+trailing spaces"},
+ {value: "crimson", expected: "#000000", testname: "Invalid color: keyword crimson"},
+ {value: "bisque", expected: "#000000", testname: "Invalid color: keyword bisque"},
+ {value: "currentColor", expected: "#000000", testname: "Invalid color: keyword currentColor"},
+ {value: "transparent", expected: "#000000", testname: "Invalid color: keyword transparent"},
+ {value: "ActiveBorder", expected: "#000000", testname: "Invalid color: keyword ActiveBorder"},
+ {value: "inherit", expected: "#000000", testname: "Invalid color: keyword inherit"},
+ {value: "rgb(1,1,1)", expected: "#000000", testname: "Invalid color: rgb(1,1,1)"},
+ {value: "rgb(1,1,1,1)", expected: "#000000", testname: "Invalid color: rgb(1,1,1,1)"},
+ {value: "#FFFFF\u1F4A9", expected: "#000000", testname: "Invalid color: PILE OF POO (U+1F4A9)"}
+ ];
+ for (var i = 0; i < colors.length; i++) {
+ var w = colors[i];
+ test(function() {
+ var input = document.createElement("input");
+ input.type = "color";
+ input.value = w.value;
+ assert_equals(input.value, w.expected);
+ }, w.testname);
+ }
+</script>
diff --git a/testing/web-platform/tests/html/semantics/forms/the-input-element/contains.json b/testing/web-platform/tests/html/semantics/forms/the-input-element/contains.json
new file mode 100644
index 000000000..c2b780f0b
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/the-input-element/contains.json
@@ -0,0 +1,154 @@
+[
+ {
+ "id": "states-of-the-type-attribute",
+ "original_id": "states-of-the-type-attribute",
+ "children": [
+ {
+ "id": "hidden-state-type-hidden",
+ "original_id": "hidden-state-(type=hidden)"
+ },
+ {
+ "id": "text-type-text-state-and-search-state-type-search",
+ "original_id": "text-(type=text)-state-and-search-state-(type=search)"
+ },
+ {
+ "id": "telephone-state-type-tel",
+ "original_id": "telephone-state-(type=tel)"
+ },
+ {
+ "id": "url-state-type-url",
+ "original_id": "url-state-(type=url)"
+ },
+ {
+ "id": "e-mail-state-type-email",
+ "original_id": "e-mail-state-(type=email)"
+ },
+ {
+ "id": "password-state-type-password",
+ "original_id": "password-state-(type=password)"
+ },
+ {
+ "id": "date-and-time-state-type-datetime",
+ "original_id": "date-and-time-state-(type=datetime)"
+ },
+ {
+ "id": "date-state-type-date",
+ "original_id": "date-state-(type=date)"
+ },
+ {
+ "id": "month-state-type-month",
+ "original_id": "month-state-(type=month)"
+ },
+ {
+ "id": "week-state-type-week",
+ "original_id": "week-state-(type=week)"
+ },
+ {
+ "id": "time-state-type-time",
+ "original_id": "time-state-(type=time)"
+ },
+ {
+ "id": "local-date-and-time-state-type-datetime-local",
+ "original_id": "local-date-and-time-state-(type=datetime-local)"
+ },
+ {
+ "id": "number-state-type-number",
+ "original_id": "number-state-(type=number)"
+ },
+ {
+ "id": "range-state-type-range",
+ "original_id": "range-state-(type=range)"
+ },
+ {
+ "id": "color-state-type-color",
+ "original_id": "color-state-(type=color)"
+ },
+ {
+ "id": "checkbox-state-type-checkbox",
+ "original_id": "checkbox-state-(type=checkbox)"
+ },
+ {
+ "id": "radio-button-state-type-radio",
+ "original_id": "radio-button-state-(type=radio)"
+ },
+ {
+ "id": "file-upload-state-type-file",
+ "original_id": "file-upload-state-(type=file)"
+ },
+ {
+ "id": "submit-button-state-type-submit",
+ "original_id": "submit-button-state-(type=submit)"
+ },
+ {
+ "id": "image-button-state-type-image",
+ "original_id": "image-button-state-(type=image)"
+ },
+ {
+ "id": "reset-button-state-type-reset",
+ "original_id": "reset-button-state-(type=reset)"
+ },
+ {
+ "id": "button-state-type-button",
+ "original_id": "button-state-(type=button)"
+ }
+ ]
+ },
+ {
+ "id": "input-impl-notes",
+ "original_id": "input-impl-notes"
+ },
+ {
+ "id": "common-input-element-attributes",
+ "original_id": "common-input-element-attributes",
+ "children": [
+ {
+ "id": "the-maxlength-attribute",
+ "original_id": "the-maxlength-attribute"
+ },
+ {
+ "id": "the-size-attribute",
+ "original_id": "the-size-attribute"
+ },
+ {
+ "id": "the-readonly-attribute",
+ "original_id": "the-readonly-attribute"
+ },
+ {
+ "id": "the-required-attribute",
+ "original_id": "the-required-attribute"
+ },
+ {
+ "id": "the-multiple-attribute",
+ "original_id": "the-multiple-attribute"
+ },
+ {
+ "id": "the-pattern-attribute",
+ "original_id": "the-pattern-attribute"
+ },
+ {
+ "id": "the-min-and-max-attributes",
+ "original_id": "the-min-and-max-attributes"
+ },
+ {
+ "id": "the-step-attribute",
+ "original_id": "the-step-attribute"
+ },
+ {
+ "id": "the-list-attribute",
+ "original_id": "the-list-attribute"
+ },
+ {
+ "id": "the-placeholder-attribute",
+ "original_id": "the-placeholder-attribute"
+ }
+ ]
+ },
+ {
+ "id": "common-input-element-apis",
+ "original_id": "common-input-element-apis"
+ },
+ {
+ "id": "common-event-behaviors",
+ "original_id": "common-event-behaviors"
+ }
+] \ No newline at end of file
diff --git a/testing/web-platform/tests/html/semantics/forms/the-input-element/date.html b/testing/web-platform/tests/html/semantics/forms/the-input-element/date.html
new file mode 100644
index 000000000..70885ed05
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/the-input-element/date.html
@@ -0,0 +1,90 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>Inputs Date</title>
+ <link rel="author" title="Morishita Hiromitsu" href="mailto:hero@asterisk-works.jp">
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#date-state-(type=date)">
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#dates-and-times">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+ <body>
+ <h1>Inputs Date</h1>
+ <div style="display: none">
+ <input id="valid" type="date" value="2011-11-01" min="2011-01-01" max="2011-12-31" />
+ <input id="too_small_value" type="date" value="1999-01-31" min="2011-01-01" max="2011-12-31"/>
+ <input id="too_large_value" type="date" value="2099-01-31" min="2011-01-01" max="2011-12-31"/>
+ <input id="invalid_min" type="date" value="2011-01-01" min="1999-1" max="2011-12-31"/>
+ <input id="invalid_max" type="date" value="2011-01-01" min="2011-01-01" max="2011-13-162-777"/>
+ <input id="min_larger_than_max" type="date" value="2011-01-01" min="2099-01" max="2011-12-31"/>
+ <input id="invalid_value" type="date" value="invalid-date" min="2011-01-01" max="2011-12-31"/>
+ </div>
+
+ <div id="log"></div>
+
+ <script type="text/javascript">
+ test(function() {
+ assert_equals(document.getElementById("valid").type, "date")
+ }, "date type support on input element");
+
+ test(function() {
+ assert_equals(document.getElementById("valid").value, "2011-11-01");
+ assert_equals(document.getElementById("too_small_value").value, "2011-01-01");
+ assert_equals(document.getElementById("too_large_value").value, "2011-12-31");
+ }, "The value attribute, if specified and not empty, must have a value that is a valid date string.");
+
+ test(function() {
+ assert_equals(document.getElementById("valid").min, "2011-01-01"),
+ assert_equals(document.getElementById("invalid_min").min, "")
+ }, "The min attribute, if specified, must have a value that is a valid date string.");
+
+ test(function() {
+ assert_equals(document.getElementById("valid").max, "2011-12-31"),
+ assert_equals(document.getElementById("min_larger_than_max").max, "2099-01"),
+ assert_equals(document.getElementById("invalid_max").max, "")
+ },"The max attribute, if specified, must have a value that is a valid date string.");
+
+ test(function() {
+ assert_equals(document.getElementById("invalid_value").value, "");
+ }, "User agents must not allow the user to set the value to a non-empty string that is not a valid date string.");
+ test(function() {
+ var numDays = [
+ // the number of days in month month of year year is: 31 if month is 1, 3, 5, 7, 8, 10, or 12;
+ {value: "2014-01-31", expected: "2014-01-31", testname: "January has 31 days"},
+ {value: "2014-01-32", expected: "", testname: "January has 31 days"},
+ {value: "2014-03-31", expected: "2014-03-31", testname: "March has 31 days"},
+ {value: "2014-03-32", expected: "", testname: "March has 31 days"},
+ {value: "2014-05-31", expected: "2014-05-31", testname: "May has 31 days"},
+ {value: "2014-05-32", expected: "", testname: "May has 31 days"},
+ {value: "2014-07-31", expected: "2014-07-31", testname: "July has 31 days"},
+ {value: "2014-07-32", expected: "", testname: "July has 31 days"},
+ {value: "2014-08-31", expected: "2014-08-31", testname: "August has 31 days"},
+ {value: "2014-08-32", expected: "", testname: "August has 31 days"},
+ {value: "2014-10-31", expected: "2014-10-31", testname: "October has 31 days"},
+ {value: "2014-10-32", expected: "", testname: "October has 31 days"},
+ {value: "2014-12-31", expected: "2014-12-31", testname: "December has 31 days"},
+ {value: "2014-12-32", expected: "", testname: "December has 31 days"},
+ // the number of days in month month of year year is: 30 if month is 4, 6, 9, or 11;
+ {value: "2014-04-30", expected: "2014-04-30", testname: "April has 30 days"},
+ {value: "2014-04-31", expected: "", testname: "April has 30 days"},
+ {value: "2014-06-30", expected: "2014-06-30", testname: "June has 30 days"},
+ {value: "2014-06-31", expected: "", testname: "June has 30 days"},
+ {value: "2014-09-30", expected: "2014-09-30", testname: "September has 30 days"},
+ {value: "2014-09-31", expected: "", testname: "September has 30 days"},
+ {value: "2014-11-30", expected: "2014-11-30", testname: "November has 30 days"},
+ {value: "2014-11-31", expected: "", testname: "November has 30 days"},
+ // leap years
+ {value: "2014-02-28", expected: "2014-02-28", testname: "2014 is not a leap year: February has 28 days"},
+ {value: "2014-02-29", expected: "", testname: "2014 is not a leap year: February has 28 days: value should be empty"},
+ {value: "2016-02-29", expected: "2016-02-29", testname: "2016 is a leap year: February has 29 days"}
+ ];
+ for (var i = 0; i < numDays.length; i++) {
+ var input = document.createElement("input");
+ input.type = "date";
+ input.value = numDays[i].value;
+ assert_equals(input.value, numDays[i].expected, numDays[i].testname);
+ }
+ }, "Number of days");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/forms/the-input-element/datetime-local.html b/testing/web-platform/tests/html/semantics/forms/the-input-element/datetime-local.html
new file mode 100644
index 000000000..b4548b77a
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/the-input-element/datetime-local.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Form input type=datetime-local</title>
+<link rel="author" title="Denis Ah-Kang" href="mailto:denis@w3.org">
+<link rel=help href="https://html.spec.whatwg.org/multipage/multipage/common-microsyntaxes.html#local-dates-and-times">
+<link rel=help href="https://html.spec.whatwg.org/multipage/multipage/states-of-the-type-attribute.html#local-date-and-time-state-(type=datetime-local)">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<script>
+ var datetimeLocal = [
+ {value: "", expected: "", testname: "empty value"},
+ {value: "2014-01-01T11:11:11.111", expected: "2014-01-01T11:11:11.111", testname: "datetime-local input value set to 2014-01-01T11:11:11.111 without min/max"},
+ {value: "2014-01-01 11:11:11.111", expected: "2014-01-01T11:11:11.111", testname: "datetime-local input value set to 2014-01-01 11:11:11.111 without min/max"},
+ {value: "2014-01-01 11:11", expected: "2014-01-01T11:11", testname: "datetime-local input value set to 2014-01-01 11:11 without min/max"},
+ {value: "2014-01-01 00:00:00.000", expected: "2014-01-01T00:00", testname: "datetime-local input value set to 2014-01-01 00:00:00.000 without min/max"},
+ {value: "2014-01-0 11:11", expected: "", testname: "datetime-local input value set to 2014-01-0 11:11 without min/max"},
+ {value: "2014-01-01 11:1", expected: "", testname: "datetime-local input value set to 2014-01-01 11:1 without min/max"},
+ {value: "2014-01-01 11:12", attributes: { min: "2014-01-01 11:11" }, expected: "2014-01-01T11:12", testname: "Value >= min attribute"},
+ {value: "2014-01-01 11:10", attributes: { min: "2014-01-01 11:11" }, expected: "2014-01-01T11:11", testname: "Value < min attribute"},
+ {value: "2014-01-01 11:10", attributes: { max: "2014-01-01 11:11" }, expected: "2014-01-01T11:10", testname: "Value <= max attribute"},
+ {value: "2014-01-01 11:12", attributes: { max: "2014-01-01 11:11" }, expected: "2014-01-01T11:11", testname: "Value > max attribute"}
+ ];
+ for (var i = 0; i < datetimeLocal.length; i++) {
+ var w = datetimeLocal[i];
+ test(function() {
+ var input = document.createElement("input");
+ input.type = "datetime-local";
+ input.value = w.value;
+ for(var attr in w.attributes) {
+ input[attr] = w.attributes[attr];
+ }
+ assert_equals(input.value, w.expected);
+ }, w.testname);
+ }
+</script>
diff --git a/testing/web-platform/tests/html/semantics/forms/the-input-element/datetime.html b/testing/web-platform/tests/html/semantics/forms/the-input-element/datetime.html
new file mode 100644
index 000000000..2e909da2d
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/the-input-element/datetime.html
@@ -0,0 +1,106 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>Date & Time Inputs</title>
+ <meta name=viewport content="width=device-width, maximum-scale=1.0, user-scalable=no" />
+ <link rel="author" title="Fabrice Clari" href="mailto:f.clari@inno-group.com">
+ <link rel="author" title="Dimitri Bocquet" href="mailto:Dimitri.Bocquet@mosquito-fp7.eu">
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-input-element">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+ <body>
+
+ <h1>Date & Time Inputs</h1>
+ <div style="display: none">
+ <input type="date" value="2011-12-01" min="2011-12-01" max="2011-12-31" step="5" />
+ <input type="time" value= "12:00" min="11:30" max="14:00" step="600" />
+ <input type="datetime" value="2011-12-01T12:00Z" min="2011-12-01T12:00Z" max="2011-12-31T22:00Z" step="7200" />
+ <input type="month" value="2011-01" min="2011-01" max="2011-12" step="2" />
+ <input type="week" value="2011-W40" min="2011-W20" max="2011-W50" step="2" />
+ </div>
+
+ <div id="log">
+ </div>
+
+ <script type="text/javascript">
+ test(function() {assert_equals(document.getElementsByTagName("input")[0].type, "date")}, "date type support on input element", {
+ "help" : "https://html.spec.whatwg.org/multipage/#dom-input-type" });
+ test(function() {assert_equals(document.getElementsByTagName("input")[0].value, "2011-12-01")}, "[date] The value must be a valid global date and time string", {
+ "help" : "https://html.spec.whatwg.org/multipage/#dom-input-value" });
+ test(function() {assert_equals(document.getElementsByTagName("input")[0].min, "2011-12-01")}, "[date] The min attribute must have a value that is a valid global date and time string", {
+ "help" : "https://html.spec.whatwg.org/multipage/#dom-input-min" });
+ test(function() {assert_equals(document.getElementsByTagName("input")[0].max, "2011-12-31")}, "[date] The max attribute must have a value that is a valid global date and time string", {
+ "help" : "https://html.spec.whatwg.org/multipage/#dom-input-max" });
+ test(function() {assert_equals(document.getElementsByTagName("input")[0].step, "5")}, "[date] The step attribute must be expressed in seconds", {
+ "help" : "https://html.spec.whatwg.org/multipage/#dom-input-step" });
+ test(function() {assert_true(typeof(document.getElementsByTagName("input")[0].stepUp) == "function")}, "[date] stepUp method support on input 'date' element", {
+ "help" : "https://html.spec.whatwg.org/multipage/#dom-input-stepup" });
+ test(function() {assert_true(typeof(document.getElementsByTagName("input")[0].stepDown) == "function")}, "[date] stepDown method support on input 'date' element", {
+ "help" : "https://html.spec.whatwg.org/multipage/#dom-input-stepdown" });
+
+ test(function() {assert_equals(document.getElementsByTagName("input")[1].type, "time")}, "[time] time type support on input element", {
+ "help" : "https://html.spec.whatwg.org/multipage/#dom-input-type" });
+ test(function() {assert_equals(document.getElementsByTagName("input")[1].value, "12:00")}, "[time] The value must be a valid global date and time string", {
+ "help" : "https://html.spec.whatwg.org/multipage/#dom-input-value" });
+ test(function() {assert_equals(document.getElementsByTagName("input")[1].min, "11:30")}, "[time] The min attribute must have a value that is a valid global date and time string", {
+ "help" : "https://html.spec.whatwg.org/multipage/#dom-input-min" });
+ test(function() {assert_equals(document.getElementsByTagName("input")[1].max, "14:00")}, "[time] The max attribute must have a value that is a valid global date and time string", {
+ "help" : "https://html.spec.whatwg.org/multipage/#dom-input-max" });
+ test(function() {assert_equals(document.getElementsByTagName("input")[1].step, "600")}, "[time] The step attribute must be expressed in seconds", {
+ "help" : "https://html.spec.whatwg.org/multipage/#dom-input-step" });
+ test(function() {assert_true(typeof(document.getElementsByTagName("input")[1].stepUp) == "function")}, "[time] stepUp method support on input 'time' element", {
+ "help" : "https://html.spec.whatwg.org/multipage/#dom-input-stepup" });
+ test(function() {assert_true(typeof(document.getElementsByTagName("input")[1].stepDown) == "function")}, "[time] stepDown method support on input 'time' element", {
+ "help" : "https://html.spec.whatwg.org/multipage/#dom-input-stepdown" });
+
+ test(function() {assert_equals(document.getElementsByTagName("input")[2].type, "datetime")}, "datetime type support on input element", {
+ "help" : "https://html.spec.whatwg.org/multipage/#dom-input-type" });
+ test(function() {assert_equals(document.getElementsByTagName("input")[2].value, "2011-12-01T12:00Z")}, "[datetime] The must be a valid global date and time string", {
+ "help" : "https://html.spec.whatwg.org/multipage/#dom-input-value" });
+ test(function() {assert_equals(document.getElementsByTagName("input")[2].min, "2011-12-01T12:00Z")}, "[datetime] The min attribute must have a value that is a valid global date and time string", {
+ "help" : "https://html.spec.whatwg.org/multipage/#dom-input-min" });
+ test(function() {assert_equals(document.getElementsByTagName("input")[2].max, "2011-12-31T22:00Z")}, "[datetime] The max attribute must have a value that is a valid global date and time string", {
+ "help" : "https://html.spec.whatwg.org/multipage/#dom-input-max" });
+ test(function() {assert_equals(document.getElementsByTagName("input")[2].step, "7200")}, "[datetime] The step attribute must be expressed in seconds", {
+ "help" : "https://html.spec.whatwg.org/multipage/#dom-input-step" });
+ test(function() {assert_true(typeof(document.getElementsByTagName("input")[2].stepUp) == "function")}, "[datetime] stepUp method support on input 'datetime' element", {
+ "help" : "https://html.spec.whatwg.org/multipage/#dom-input-stepup" });
+ test(function() {assert_true(typeof(document.getElementsByTagName("input")[2].stepDown) == "function")}, "[datetime] stepDown method support on input 'datetime' element", {
+ "help" : "https://html.spec.whatwg.org/multipage/#dom-input-stepdown" });
+
+ test(function() {assert_equals(document.getElementsByTagName("input")[3].type, "month")}, "month type support on input element", {
+ "help" : "https://html.spec.whatwg.org/multipage/#dom-input-type" });
+ test(function() {assert_equals(document.getElementsByTagName("input")[3].value, "2011-01")}, "[month] The value must be a value that is a valid global date and time string", {
+ "help" : "https://html.spec.whatwg.org/multipage/#dom-input-value" });
+ test(function() {assert_equals(document.getElementsByTagName("input")[3].min, "2011-01")}, "[month] The min attribute must have a value that is a valid global date and time string", {
+ "help" : "https://html.spec.whatwg.org/multipage/#dom-input-min" });
+ test(function() {assert_equals(document.getElementsByTagName("input")[3].max, "2011-12")}, "[month] The max attribute must have a value that is a valid global date and time string", {
+ "help" : "https://html.spec.whatwg.org/multipage/#dom-input-max" });
+ test(function() {assert_equals(document.getElementsByTagName("input")[3].step, "2")}, "[month] The step attribute must be expressed in seconds", {
+ "help" : "https://html.spec.whatwg.org/multipage/#dom-input-step" });
+ test(function() {assert_true(typeof(document.getElementsByTagName("input")[3].stepUp) == "function")}, "[month] stepUp method support on input 'month' element", {
+ "help" : "https://html.spec.whatwg.org/multipage/#dom-input-stepup" });
+ test(function() {assert_true(typeof(document.getElementsByTagName("input")[3].stepDown) == "function")}, "[month] stepDown method support on input 'month' element", {
+ "help" : "https://html.spec.whatwg.org/multipage/#dom-input-stepdown" });
+
+ test(function() {assert_equals(document.getElementsByTagName("input")[4].type, "week")}, "week type support on input element", {
+ "help" : "https://html.spec.whatwg.org/multipage/#dom-input-type" });
+ test(function() {assert_equals(document.getElementsByTagName("input")[4].value, "2011-W40")}, "[week] The value must be a value that is a valid global date and time string", {
+ "help" : "https://html.spec.whatwg.org/multipage/#dom-input-value" });
+ test(function() {assert_equals(document.getElementsByTagName("input")[4].min, "2011-W20")}, "[week] The min attribute must have a value that is a valid global date and time string", {
+ "help" : "https://html.spec.whatwg.org/multipage/#dom-input-min" });
+ test(function() {assert_equals(document.getElementsByTagName("input")[4].max, "2011-W50")}, "[week] The max attribute must have a value that is a valid global date and time string", {
+ "help" : "https://html.spec.whatwg.org/multipage/#dom-input-max" });
+ test(function() {assert_equals(document.getElementsByTagName("input")[4].step, "2")}, "[week] The step attribute must be expressed in seconds", {
+ "help" : "https://html.spec.whatwg.org/multipage/#dom-input-step" });
+ test(function() {assert_true(typeof(document.getElementsByTagName("input")[4].stepUp) == "function")}, "[week] stepUp method support on input 'week' element", {
+ "help" : "https://html.spec.whatwg.org/multipage/#dom-input-stepup" });
+ test(function() {assert_true(typeof(document.getElementsByTagName("input")[4].stepDown) == "function")}, "[week] stepDown method support on input 'week' element", {
+ "help" : "https://html.spec.whatwg.org/multipage/#dom-input-stepdown" });
+
+ </script>
+
+ </body>
+
+</html>
diff --git a/testing/web-platform/tests/html/semantics/forms/the-input-element/email.html b/testing/web-platform/tests/html/semantics/forms/the-input-element/email.html
new file mode 100644
index 000000000..fc92529ef
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/the-input-element/email.html
@@ -0,0 +1,58 @@
+<!DOCTYPE html>
+<title>Input Email</title>
+<link rel="author" title="Kazuki Kanamori" href="mailto:yogurito@gmail.com">
+<link rel="author" title="Denis Ah-Kang" href="mailto:denis@w3.org">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#e-mail-state-(type=email)">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<input type="email" id="single_email" value="user@example.com"/>
+<input type="email" id="multiple_email" value="user1@example.com, user2@test.com" multiple/>
+<div id="log"></div>
+
+<script type="text/javascript">
+ var single = document.getElementById('single_email'),
+ mult = document.getElementById('multiple_email');
+
+ test(function(){
+ assert_false(single.multiple);
+ }, "single_email doesn't have the multiple attribute");
+
+ test(function(){
+ single.value = 'user2@example.com\u000A';
+ assert_equals(single.value, 'user2@example.com');
+ single.value = 'user3@example.com\u000D';
+ assert_equals(single.value, 'user3@example.com');
+ }, 'value should be sanitized: strip line breaks');
+
+ test(function(){
+ single.value = 'user4@example.com';
+ assert_true(single.validity.valid);
+ single.value = 'example.com';
+ assert_false(single.validity.valid);
+ }, 'Email address validity');
+
+ test(function(){
+ single.setAttribute('multiple', true);
+ single.value = ' user@example.com , user2@example.com ';
+ assert_equals(single.value, 'user@example.com,user2@example.com');
+ single.removeAttribute('multiple');
+ assert_equals(single.value, 'user@example.com,user2@example.com');
+ }, 'When the multiple attribute is removed, the user agent must run the value sanitization algorithm');
+
+ test(function(){
+ assert_true(mult.multiple);
+ }, "multiple_email has the multiple attribute");
+
+ test(function(){
+ mult.value = ' user1@example.com , user2@test.com, user3@test.com ';
+ assert_equals(mult.value, 'user1@example.com,user2@test.com,user3@test.com');
+ }, "run the value sanitization algorithm after setting a new value");
+
+ test(function(){
+ mult.value = 'user1@example.com,user2@test.com,user3@test.com';
+ assert_true(mult.validity.valid);
+
+ mult.value = 'u,ser1@example.com,user2@test.com,user3@test.com';
+ assert_false(mult.validity.valid);
+ }, "valid value is a set of valid email addresses separated by a single ','");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/forms/the-input-element/file-manual.html b/testing/web-platform/tests/html/semantics/forms/the-input-element/file-manual.html
new file mode 100644
index 000000000..9e2d47c42
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/the-input-element/file-manual.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>input type file</title>
+<link rel="author" title="Denis Ah-Kang" href="mailto:denis@w3.org">
+<link rel=help href="https://html.spec.whatwg.org/multipage/#file-upload-state-(type=file)">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<p>Manual test: clicking on the input should open a prompt allowing you to select a file.</p>
+<input type=file id=file>
+<script>
+ setup({explicit_timeout:true});
+
+ var input = document.getElementById('file'),
+ t1 = async_test("selecting files should fire the input event at the input element"),
+ t2 = async_test("selecting files should fire the change event at the input element");
+
+ document.getElementById('file').oninput = t1.step_func_done(function(e) {
+ assert_true(e.bubbles, "input event bubbles");
+ assert_true(e.isTrusted, "input event should be trusted");
+ assert_false(e.cancelable, "input event should not be cancelable");
+ })
+ document.getElementById('file').onchange = t2.step_func_done(function(e) {
+ assert_true(e.bubbles, "change event bubbles");
+ assert_true(e.isTrusted, "change event should be trusted");
+ assert_false(e.cancelable, "change event should not be cancelable");
+ assert_true(input.files instanceof FileList);
+ assert_equals(input.value, "C:\\fakepath\\" + input.files[0].name);
+ })
+</script>
diff --git a/testing/web-platform/tests/html/semantics/forms/the-input-element/files.html b/testing/web-platform/tests/html/semantics/forms/the-input-element/files.html
new file mode 100644
index 000000000..107b86c08
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/the-input-element/files.html
@@ -0,0 +1,48 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>HTMLInputElement#files</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+var types = [
+ "hidden",
+ "text",
+ "search",
+ "tel",
+ "url",
+ "email",
+ "password",
+ "date",
+ "month",
+ "week",
+ "time",
+ "datetime-local",
+ "number",
+ "range",
+ "color",
+ "checkbox",
+ "radio",
+ "submit",
+ "image",
+ "reset",
+ "button",
+];
+
+types.forEach(function(type) {
+ test(function() {
+ var input = document.createElement("input");
+ input.type = type;
+ assert_equals(input.files, null, "files should be null");
+ }, "files for input type=" + type);
+});
+
+test(function() {
+ var input = document.createElement("input");
+ input.type = "file";
+ assert_not_equals(input.files, null);
+ assert_true(input.files instanceof FileList, "files should be a FileList");
+ var files = input.files;
+ assert_equals(input.files, files, "files should return the same object");
+}, "files for input type=file");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/forms/the-input-element/hidden.html b/testing/web-platform/tests/html/semantics/forms/the-input-element/hidden.html
new file mode 100644
index 000000000..4aca00d8c
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/the-input-element/hidden.html
@@ -0,0 +1,74 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>Hidden input element</title>
+ <link rel="author" title="Kinuko Yasuda" href="mailto:kinuko@chromium.org">
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#hidden-state-(type=hidden)">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+
+ <body>
+ <h1>Hidden input element</h1>
+ <div style="display: none">
+
+ <input id="hidden" type="hidden" />
+ <input id="hidden_with_value" type="hidden" value="foo" />
+
+ </div>
+ <div id="log"></div>
+ <script type="text/javascript">
+
+ test(
+ function() {
+ assert_equals(document.getElementById("hidden").value, "");
+ assert_equals(document.getElementById("hidden_with_value").value, "foo");
+ }, "Value returns the current value for hidden");
+
+ test(
+ function() {
+ document.getElementById("hidden").value = "A";
+ assert_equals(document.getElementById("hidden").value, "A");
+ document.getElementById("hidden").value = "B";
+ assert_equals(document.getElementById("hidden").value, "B");
+ }, "Setting value changes the current value for hidden");
+
+ test(
+ function() {
+ assert_equals(document.getElementById("hidden").files, null);
+ }, "files attribute must return null for hidden");
+
+ test(
+ function() {
+ assert_equals(document.getElementById("hidden").valueAsDate, null);
+ }, "valueAsDate attribute must return null for hidden");
+
+ test(
+ function() {
+ assert_equals(document.getElementById("hidden").valueAsNumber, NaN);
+ }, "valueAsNumber attribute must return NaN for hidden");
+
+ test(
+ function() {
+ assert_equals(document.getElementById("hidden").list, null);
+ }, "list attribute must return null for hidden");
+
+ test(
+ function() {
+ var el = document.getElementById("hidden");
+ assert_throws("InvalidStateError", function() { el.stepDown(); }, "");
+ }, "stepDown does not apply for hidden");
+
+ test(
+ function() {
+ var el = document.getElementById("hidden");
+ assert_throws("InvalidStateError", function() { el.stepUp(); }, "");
+ }, "stepUp does not apply for hidden");
+
+ test(function(){
+ var el = document.getElementById("hidden");
+ assert_false(el.willValidate);
+ }, "input type=hidden is barred from constraint validation");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/forms/the-input-element/image01-ref.html b/testing/web-platform/tests/html/semantics/forms/the-input-element/image01-ref.html
new file mode 100644
index 000000000..62c141d96
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/the-input-element/image01-ref.html
@@ -0,0 +1,5 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>input type image reference file</title>
+<link rel="author" title="Denis Ah-Kang" href="mailto:denis@w3.org">
+<img src="/media/poster.png"/>
diff --git a/testing/web-platform/tests/html/semantics/forms/the-input-element/image01.html b/testing/web-platform/tests/html/semantics/forms/the-input-element/image01.html
new file mode 100644
index 000000000..e9028dcee
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/the-input-element/image01.html
@@ -0,0 +1,7 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>input type image</title>
+<link rel="author" title="Denis Ah-Kang" href="mailto:denis@w3.org">
+<link rel=help href="https://html.spec.whatwg.org/multipage/#image-button-state-(type=image)">
+<link rel="match" href="image01-ref.html">
+<input type=image id=image src="/media/poster.png">
diff --git a/testing/web-platform/tests/html/semantics/forms/the-input-element/input-type-button.html b/testing/web-platform/tests/html/semantics/forms/the-input-element/input-type-button.html
new file mode 100644
index 000000000..0f269355a
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/the-input-element/input-type-button.html
@@ -0,0 +1,51 @@
+<!DOCTYPE HTML>
+<head>
+<title>input type button</title>
+<link rel="author" title="Takeharu.Oshida" href="mailto:georgeosddev@gmail.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#button-state-(type=button)">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+</head>
+<body>
+<div id="log"></div>
+<div id="hide" style="display">
+ <input type="button"/>
+ <input type="button" value="BUTTON"/>
+ <form action="/" method="get" onsubmit="isSubmitted = true;return false;">
+ <input type="button" value="mutable"/>
+ </form>
+ <form action="/" method="get" onsubmit="isSubmitted = true;return false;">
+ <input type="button" value="immutable" disabled/>
+ </form>
+</div>
+<script>
+var isSubmitted = false;
+var buttons = document.getElementsByTagName("input");
+
+test(function() {
+ assert_equals(buttons[0].click(), undefined, "The input element represents a button with no default behavior");
+},"default behavior");
+
+test(function() {
+ assert_equals(buttons[0].value, "", "It must be the empty string");
+},"empty value attribute");
+
+test(function() {
+ document.getElementById("hide").style.display = "block";
+ assert_not_equals(buttons[0].offsetWidth, buttons[1].offsetWidth, "If the element has a value attribute, the button's label must be the value of that attribute");
+ document.getElementById("hide").style.display = "none";
+},"label value");
+
+test(function() {
+ isSubmitted = false;
+ buttons[2].click();
+ assert_equals(isSubmitted, false, "If the element is mutable, the element's activation behavior is to do nothing.");
+},"mutable element's activation behavior is to do nothing.");
+
+test(function() {
+ isSubmitted = false;
+ buttons[3].click()
+ assert_equals(isSubmitted, false, "If the element is immutable, the element has no activation behavior.");
+},"immutable element has no activation behavior.");
+</script>
+</body>
diff --git a/testing/web-platform/tests/html/semantics/forms/the-input-element/input-type-checkbox.html b/testing/web-platform/tests/html/semantics/forms/the-input-element/input-type-checkbox.html
new file mode 100644
index 000000000..7dd2f26b1
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/the-input-element/input-type-checkbox.html
@@ -0,0 +1,60 @@
+<!DOCTYPE HTML>
+<head>
+<title>input type checkbox</title>
+<link rel="author" title="Gary Gao" href="mailto:angrytoast@gmail.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#checkbox-state-(type=checkbox)">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+</head>
+<body>
+<div style="display:none;">
+ <input id="checkbox_default" type="checkbox" width="20" />
+
+ <input id="checkbox_checked" type="checkbox" checked />
+
+ <input id="checkbox_indeterminate" type="checkbox" />
+
+ <input id="checkbox_default_value" type="checkbox" />
+</div>
+
+<div id="log"></div>
+
+<script>
+ var checkbox_default = document.getElementById('checkbox_default'),
+ checkbox_checked = document.getElementById('checkbox_checked'),
+ checkbox_indeterminate = document.getElementById('checkbox_indeterminate'),
+ checkbox_default_value = document.getElementById('checkbox_default_value');
+
+ test(function() {
+ assert_false(checkbox_default.checked);
+ }, "default checkbox has no checkedness state");
+
+ test(function() {
+ assert_true(checkbox_checked.checked);
+ }, "checkbox with initial state set to checked has checkedness state");
+
+ test(function() {
+ checkbox_default.checked = 'chicken'
+ assert_true(checkbox_default.checked);
+ }, "changing the checked attribute to a string sets the checkedness state");
+
+ test(function() {
+ assert_false(checkbox_indeterminate.indeterminate);
+ }, "a checkbox has an indeterminate state set to false onload");
+
+ test(function() {
+ checkbox_indeterminate.indeterminate = true,
+ assert_true(checkbox_indeterminate.indeterminate);
+ }, "on setting, a checkbox's indeterminate state must be set to the new value and returns the last value it was set to");
+
+ test(function() {
+ assert_equals(checkbox_default_value.value, 'on');
+ }, "default/on: on getting, if the element has a value attribute, it must return that attribute's value; otherwise, it must return the string 'on'");
+
+ test(function() {
+ checkbox_default_value.value = 'chicken'
+ assert_equals(checkbox_default_value.value, 'chicken');
+ }, "on getting, if the element has a value attribute, it must return that attribute's value");
+</script>
+
+</body>
diff --git a/testing/web-platform/tests/html/semantics/forms/the-input-element/maxlength-manual.html b/testing/web-platform/tests/html/semantics/forms/the-input-element/maxlength-manual.html
new file mode 100644
index 000000000..fdf6c2644
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/the-input-element/maxlength-manual.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset=utf-8>
+ <title>input max length</title>
+ <link rel="author" title="Sam Gibson" href="mailto:sam@ifdown.net">
+ <link rel=help href="https://html.spec.whatwg.org/multipage/forms.html#the-maxlength-and-minlength-attributes">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+
+ <body>
+ <div id="log"></div>
+ <p>Type a letter anywhere into the input field (do not select any text, or otherwise manipulate the input)</p>
+ <input type=text maxlength=4 id=only-four value="inpu"></input>
+
+ <script>
+ var input;
+ setup(function() {
+ input = document.getElementById('only-four');
+ }, {explicit_done: true, explicit_timeout: true});
+
+
+ on_event(input, 'keyup', function(event) {
+ if ((event.keyCode >= 65 && event.keyCode <= 90) ||
+ (event.keyCode >= 97 && event.keyCode <= 122)) {
+ test(function() {
+ assert_equals(input.value, "inpu");
+ }, 'input content should limit to maxlength')
+
+ done();
+ }
+ });
+ </script>
+ </body>
+</html>
+
diff --git a/testing/web-platform/tests/html/semantics/forms/the-input-element/maxlength.html b/testing/web-platform/tests/html/semantics/forms/the-input-element/maxlength.html
new file mode 100644
index 000000000..8f0a2567d
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/the-input-element/maxlength.html
@@ -0,0 +1,55 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>input max length</title>
+ <link rel="author" title="Sam Gibson" href="mailto:sam@ifdown.net">
+ <link rel=help href="https://html.spec.whatwg.org/multipage/forms.html#the-maxlength-and-minlength-attributes">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+
+ <body>
+ <h1>Text input element</h1>
+
+ <div style="display: none">
+ <input id="none" />
+ <input id="negative" type="-5" />
+ <input id="non-numeric" type="not-a-number" />
+ <input id="assign-negative" />
+ <input id="assign-non-numeric" />
+ </div>
+
+ <div id="log"></div>
+
+ <script type="text/javascript">
+ test(
+ function() {
+ assert_equals(document.getElementById("none").maxLength, -1);
+ }, "Unset maxlength is -1");
+
+ test(
+ function() {
+ assert_equals(document.getElementById("negative").maxLength, -1);
+ }, "Negative maxlength is always -1");
+
+ test(
+ function() {
+ assert_equals(document.getElementById("non-numeric").maxLength, -1);
+ }, "Non-numeric maxlength is -1");
+
+ test(
+ function() {
+ assert_throws("INDEX_SIZE_ERR", function() {
+ document.getElementById("assign-negative").maxLength = -5;
+ });
+ }, "Assigning negative integer throws IndexSizeError");
+
+ test(
+ function() {
+ document.getElementById("assign-non-numeric").maxLength = "not-a-number";
+ assert_equals(document.getElementById("assign-non-numeric").maxLength, 0);
+ }, "Assigning non-numeric to maxlength sets maxlength to 0");
+ </script>
+ </body>
+</html>
+
diff --git a/testing/web-platform/tests/html/semantics/forms/the-input-element/minlength.html b/testing/web-platform/tests/html/semantics/forms/the-input-element/minlength.html
new file mode 100644
index 000000000..7bfdf189a
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/the-input-element/minlength.html
@@ -0,0 +1,55 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>input min length</title>
+ <link rel="author" title="Taryn Hill" href="mailto:Phrohdoh@gmail.com">
+ <link rel=help href="https://html.spec.whatwg.org/multipage/forms.html#the-minlength-and-minlength-attributes">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+
+ <body>
+ <h1>Text input element</h1>
+
+ <div style="display: none">
+ <input id="none" />
+ <input id="negative" minlength=-5 />
+ <input id="non-numeric" minlength="not-a-number" />
+ <input id="assign-negative" />
+ <input id="assign-non-numeric" />
+ </div>
+
+ <div id="log"></div>
+
+ <script type="text/javascript">
+ test(
+ function() {
+ assert_equals(document.getElementById("none").minLength, -1);
+ }, "Unset minlength is -1");
+
+ test(
+ function() {
+ assert_equals(document.getElementById("negative").minLength, -1);
+ }, "Negative minlength is always -1");
+
+ test(
+ function() {
+ assert_equals(document.getElementById("non-numeric").minLength, -1);
+ }, "Non-numeric minlength is -1");
+
+ test(
+ function() {
+ assert_throws("INDEX_SIZE_ERR", function() {
+ document.getElementById("assign-negative").minLength = -5;
+ });
+ }, "Assigning negative integer throws IndexSizeError");
+
+ test(
+ function() {
+ document.getElementById("assign-non-numeric").minLength = "not-a-number";
+ assert_equals(document.getElementById("assign-non-numeric").minLength, 0);
+ }, "Assigning non-numeric to minlength sets minlength to 0");
+ </script>
+ </body>
+</html>
+
diff --git a/testing/web-platform/tests/html/semantics/forms/the-input-element/month.html b/testing/web-platform/tests/html/semantics/forms/the-input-element/month.html
new file mode 100644
index 000000000..15fa76dd4
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/the-input-element/month.html
@@ -0,0 +1,65 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>Inputs Month</title>
+ <link rel="author" title="Morishita Hiromitsu" href="mailto:hero@asterisk-works.jp">
+ <link rel="author" title="kaseijin" href="mailto:pcmkas@gmail.com">
+ <link rel="author" title="Denis Ah-Kang" href="mailto:denis@w3.org">
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#months">
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#month-state-(type=month)">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+ <body>
+ <h1>Inputs Month</h1>
+ <div style="display: none">
+ <input id="valid" type="month" value="2011-11" min="2011-01" max="2011-12" />
+ <input id="invalid_value" type="month" value="invalid-month" min="2011-01" max="2011-12"/>
+ <input id="value_can_be_empty_string" type="month" value="2013-06" />
+ <input id="invalid_value_with_two_digits_year" type="month" value="13-06" />
+ <input id="invalid_value_is_set" type="month" />
+ <input id="step_attribute_is_invalid_value" type="month" value="2013-06" step="invalid_step_value" />
+ <input id="invalid_month_too_high" type="month" value="2013-13" />
+ <input id="invalid_month_too_low" type="month" value="2013-00" />
+ </div>
+
+ <div id="log"></div>
+
+ <script>
+ test(function() {
+ assert_equals(document.getElementById("valid").type, "month")
+ }, "month type support on input element");
+
+ test(function() {
+ assert_equals(document.getElementById("invalid_value").value, "")
+ }, "User agents must not allow the user to set the value to a non-empty string that is not a valid month string.");
+
+ test(function() {
+ document.getElementById("value_can_be_empty_string").value = "";
+ assert_equals(document.getElementById("value_can_be_empty_string").value, "")
+ }, "Month value can be empty string.");
+
+ test(function() {
+ assert_equals(document.getElementById("invalid_value_with_two_digits_year").value, "")
+ }, "When value attribute has two digits year value, the value,which is invalid, must return empty string.");
+
+ test(function() {
+ document.getElementById("invalid_value_is_set").value = "invalid value";
+ assert_equals(document.getElementById("invalid_value_is_set").value, "")
+ }, "When value is set with invalid value, the value must return empty string.");
+
+ test(function() {
+ document.getElementById("step_attribute_is_invalid_value").stepUp();
+ assert_equals(document.getElementById("step_attribute_is_invalid_value").value, "2013-07")
+ }, "When step attribute is given invalid value, it must ignore the invalid value and use defaul value instead.");
+
+ test(function() {
+ assert_equals(document.getElementById("invalid_month_too_high").value, "");
+ }, "Month should be <= 13: If the value of the element is not a valid month string, then set it to the empty string instead.");
+
+ test(function() {
+ assert_equals(document.getElementById("invalid_month_too_low").value, "");
+ }, "Month should be > 0: If the value of the element is not a valid month string, then set it to the empty string instead.>");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/forms/the-input-element/number.html b/testing/web-platform/tests/html/semantics/forms/the-input-element/number.html
new file mode 100644
index 000000000..5067d0e2f
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/the-input-element/number.html
@@ -0,0 +1,53 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Form input type=number</title>
+<link rel="author" title="Denis Ah-Kang" href="mailto:denis@w3.org">
+<link rel=help href="https://html.spec.whatwg.org/multipage/#password-state-(type=number)">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<script>
+ var numbers = [
+ {value: "", expected: "", testname: "empty value"},
+ {value: "11", expected: "11", testname: "value = 11"},
+ {value: "11.12", expected: "11.12", testname: "value = 11.12"},
+ {value: "-11111", expected: "-11111", testname: "value = -11111"},
+ {value: "-11111.123", expected: "-11111.123", testname: "value = -11111.123"},
+ {value: "1e2", expected: "1e2", testname: "value = 1e2"},
+ {value: "1E2", expected: "1E2", testname: "value = 1E2"},
+ {value: "1e+2", expected: "1e+2", testname: "value = 1e+2"},
+ {value: "1e-2", expected: "1e-2", testname: "value = 1e-2"},
+ {value: "1d+2", expected: "", testname: "value is not a valid floating-point number: 1d+2"},
+ {value: "foobar", expected: "", testname: "value not a valid floating-point number: random string"},
+ {value: "11", attributes: { min: "10" }, expected: "11", testname: "Value >= min attribute"},
+ {value: "9", attributes: { min: "10" }, expected: "9", testname: "Value < min attribute"},
+ {value: "19", attributes: { max: "20" }, expected: "19", testname: "Value <= max attribute"},
+ {value: "21", attributes: { max: "20" }, expected: "21", testname: "Value > max attribute"},
+ {value: ".1", expected: ".1", testname: "value with a leading '.'"},
+ {value: "1.", expected: "", testname: "value ending with '.'"},
+ {value: "-0", expected: "-0", testname: "value = -0"},
+ {value: "Infinity", expected: "", testname: " value = Infinity"},
+ {value: "-Infinity", expected: "", testname: "value = -Infinity"},
+ {value: "NaN", expected: "", testname: "value = NaN"},
+ {value: "9007199254740993", expected: "9007199254740992", testname: "value = 2^53+1"},
+ {value: "2e308", expected: "", testname: "value >= Number.MAX_VALUE"},
+ {value: "1e", expected: "", testname: "value = 1e"},
+ {value: "+1", expected: "1", testname: "value = +1"},
+ {value: "+", expected: "", testname: "value = '+'"},
+ {value: "-", expected: "", testname: "value = '-'"},
+ {value: " 1", expected: "1", testname: "value with a leading whitespace"},
+ {value: "1trailing junk", expected: "1", testname: "value = 1trailing junk"}
+ ];
+ for (var i = 0; i < numbers.length; i++) {
+ var w = numbers[i];
+ test(function() {
+ var input = document.createElement("input");
+ input.type = "number";
+ input.value = w.value;
+ for(var attr in w.attributes) {
+ input[attr] = w.attributes[attr];
+ }
+ assert_equals(input.value, w.expected);
+ }, w.testname);
+ }
+</script>
diff --git a/testing/web-platform/tests/html/semantics/forms/the-input-element/password.html b/testing/web-platform/tests/html/semantics/forms/the-input-element/password.html
new file mode 100644
index 000000000..aac54aa1c
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/the-input-element/password.html
@@ -0,0 +1,79 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Password input element</title>
+<link rel="author" title="Denis Ah-Kang" href="mailto:denis@w3.org">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#password-state-%28type=password%29">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<div style="display: none">
+<input id="password" type="password" />
+<input id=password2 type=password value="password">
+<input id="password_with_value" type="password" value="foobar" />
+</div>
+<script type="text/javascript">
+ setup(function() {
+ window.password = document.getElementById("password");
+ });
+
+ test(function() {
+ assert_equals(password.value, "");
+ assert_equals(document.getElementById("password_with_value").value, "foobar");
+ }, "Value returns the current value for password");
+
+ test(function() {
+ password.value = "A";
+ assert_equals(password.value, "A");
+ assert_equals(password.getAttribute("value"), null);
+ password.value = "B";
+ assert_equals(password.value, "B");
+ assert_equals(password.getAttribute("value"), null);
+ }, "Setting value changes the current value for password, but not the value content attribute");
+
+ test(function() {
+ // Any LF (\n) must be stripped.
+ password.value = "\nAB";
+ assert_equals(password.value, "AB");
+ password.value = "A\nB";
+ assert_equals(password.value, "AB");
+ password.value = "AB\n";
+ assert_equals(password.value, "AB");
+
+ // Any CR (\r) must be stripped.
+ password.value = "\rAB";
+ assert_equals(password.value, "AB");
+ password.value = "A\rB";
+ assert_equals(password.value, "AB");
+ password.value = "AB\r";
+ assert_equals(password.value, "AB");
+
+ // Any combinations of LF CR must be stripped.
+ password.value = "\r\nAB";
+ assert_equals(password.value, "AB");
+ password.value = "A\r\nB";
+ assert_equals(password.value, "AB");
+ password.value = "AB\r\n";
+ assert_equals(password.value, "AB");
+ password.value = "\r\nA\n\rB\r\n";
+ assert_equals(password.value, "AB");
+ }, "Value sanitization algorithm should strip line breaks for password");
+
+ var pass = document.getElementById('password2');
+
+ test(function(){
+ assert_equals(pass.value, "password");
+ pass.value = " pass word ";
+ assert_equals(pass.value, " pass word ");
+ }, "sanitization algorithm doesn't strip leading and trailing whitespaces");
+
+ test(function(){
+ pass.value = "pass\u000Aword";
+ assert_equals(pass.value, "password");
+ pass.value = "\u000Apassword\u000A";
+ assert_equals(pass.value, "password");
+ pass.value = "pass\u000Dword";
+ assert_equals(pass.value, "password");
+ pass.value = "\u000Dpassword\u000D";
+ assert_equals(pass.value, "password");
+ }, "sanitization algorithm strips line breaks");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/forms/the-input-element/pattern_attribute.html b/testing/web-platform/tests/html/semantics/forms/the-input-element/pattern_attribute.html
new file mode 100644
index 000000000..ef01c2972
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/the-input-element/pattern_attribute.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<html>
+
+ <head>
+ <title>Pattern Attribute</title>
+ <meta name=viewport content="width=device-width, maximum-scale=1.0, user-scalable=no" />
+ <link rel="author" title="Fabrice Clari" href="mailto:f.clari@inno-group.com">
+ <link rel="author" title="Dimitri Bocquet" href="mailto:Dimitri.Bocquet@mosquito-fp7.eu">
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#attr-input-pattern">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+
+ <body>
+
+
+ <h1>Pattern Attribute</h1>
+ <div style="display: none">
+ <input pattern="[a-z]{3}" value="abcd" title="three letters max"/>
+ </div>
+
+ <div id="log">
+ </div>
+
+ <script type="text/javascript">
+
+
+ test(function() {assert_equals(document.getElementsByTagName("input")[0].getAttribute("pattern"), "[a-z]{3}")}, "pattern attribute support on input element");
+
+ </script>
+
+ </body>
+
+</html>
diff --git a/testing/web-platform/tests/html/semantics/forms/the-input-element/radio-groupname-case.html b/testing/web-platform/tests/html/semantics/forms/the-input-element/radio-groupname-case.html
new file mode 100644
index 000000000..05192fc7d
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/the-input-element/radio-groupname-case.html
@@ -0,0 +1,75 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>radio group name compatibility caseless</title>
+<link rel="author" title="Denis Ah-Kang" href="mailto:denis@w3.org">
+<link rel="help" href="http://people.mozilla.org/~jdaggett/tests/radiobuttonnamecase.html">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<input id=r1 type="radio" name="sImPlE">
+<input id=r2 type="radio" name="simple">
+<input id=r3 type="radio" name="SIMPLE">
+
+<input id=r4 type="radio" name="paSSfield-killroyß">
+<input id=r5 type="radio" name="passfield-killroyß">
+<input id=r6 type="radio" name="PASSFIELD-KILLROYß">
+<input id=r7 type="radio" name="paſſfield-killroyß">
+<input id=r8 type="radio" name="passfield-&#x212a;illroyß">
+<input id=r9 type="radio" name="paßfield-killroyß">
+<input id=r10 type="radio" name="paẞfield-killroyß">
+<input id=r11 type="radio" name="passfield-killroyẞ">
+<input id=r12 type="radio" name="passï¬eld-killroyß">
+<input id=r13 type="radio" name="passfıeld-killroyß">
+<input id=r14 type="radio" name="passfİeld-killroyß">
+
+<input id=r15 type="radio" name="глупый">
+<input id=r16 type="radio" name="глупы&#x438;&#x306;">
+<input id=r17 type="radio" name="ГЛУПЫЙ">
+<input id=r18 type="radio" name="ГЛУПЫ&#x418;&#x306;">
+
+<input id=r19 type="radio" name="åωk">
+<input id=r20 type="radio" name="ÅΩK">
+<input id=r21 type="radio" name="&#x212b;ωk">
+<input id=r22 type="radio" name="Ã¥&#x2126;k">
+<input id=r23 type="radio" name="åω&#x212a;">
+
+<input id=r24 type="radio" name="blah1">
+<input id=r25 type="radio" name="blah&#x2460;">
+<input id=r26 type="radio" name="bl&#x24b6;h1">
+<input id=r27 type="radio" name="bl&#x24d0;h1">
+
+<input id=r28 type="radio" name="t&Eacute;dz5アパートFi">
+<input id=r29 type="radio" name="T&Eacute;DZ5アパートFi">
+<input id=r30 type="radio" name="T&eacute;&#x01F1;&#x2075;アパートFi">
+<input id=r31 type="radio" name="t&Eacute;dz5&#x3300;Fi">
+<input id=r32 type="radio" name="t&Eacute;dz5&#x30A2;&#x30CF;&#x309A;&#x30FC;&#x30C8;Fi">
+<input id=r33 type="radio" name="t&Eacute;dz5&#x30A2;&#x30D1;&#x30FC;&#x30C8;Fi">
+<input id=r34 type="radio" name="T&Eacute;DZâµã‚¢ãƒ‘ートFi">
+<input id=r35 type="radio" name="T&Eacute;DZ5アパートï¬">
+
+<input id=r36 type="radio" name="ΣΣ">
+<input id=r37 type="radio" name="σς">
+<script>
+ var groups = [["r1" ,"r2", "r3"],
+ ["r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r13", "r14"],
+ ["r15", "r16", "r17", "r18"],
+ ["r19", "r20", "r21", "r22", "r23"],
+ ["r24", "r25", "r26", "r27"],
+ ["r28", "r29", "r30", "r31", "r32", "r33", "r34", "r35"],
+ ["r36", "r37"]],
+ groupName = ["sImPlE", "paSSfield-killroyß", "глупый", "åωk", "blah1", "tÉdz5アパートFi", "ΣΣ"];
+ groups.forEach(function(group, index) {
+ test(function(){
+ group.forEach(function(radioId) {
+ assert_false(document.getElementById(radioId).checked);
+ });
+ for (var i = 0; i < group.length; i++) {
+ document.getElementById(group[i]).checked = true;
+ assert_true(document.getElementById(group[i]).checked);
+ for (var j = 0; j < group.length; j++) {
+ if (j != i) assert_false(document.getElementById(group[j]).checked);
+ }
+ }
+ }, "radio button group name = " + groupName[index]);
+ });
+</script>
diff --git a/testing/web-platform/tests/html/semantics/forms/the-input-element/radio.html b/testing/web-platform/tests/html/semantics/forms/the-input-element/radio.html
new file mode 100644
index 000000000..6681b3506
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/the-input-element/radio.html
@@ -0,0 +1,144 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>input type radio</title>
+<link rel="author" title="Denis Ah-Kang" href="mailto:denis@w3.org">
+<link rel=help href="https://html.spec.whatwg.org/multipage/#radio-button-state-(type=radio)">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<input type=radio name=group1 id=radio1>
+<input type=radio name=group1 id=radio2>
+
+<input type=radio name=groüp2 id=radio3>
+<input type=radio name=groÃœp2 id=radio4>
+
+<input type=radio id=radio5>
+<input type=radio id=radio6 disabled>
+
+<input type=radio name="group5" id=radio71 checked>
+<input type=radio name="group5" id=radio72>
+
+<input type=radio name=group3 id=radio8 checked>
+<input type=radio name=group3 id=radio9>
+<input type=radio name=group4 id=radio10>
+<input type=radio name=group4 id=radio11 checked>
+
+
+<script>
+ var radio1 = document.getElementById('radio1'),
+ radio2 = document.getElementById('radio2'),
+ radio3 = document.getElementById('radio3'),
+ radio4 = document.getElementById('radio4'),
+ radio5 = document.getElementById('radio5'),
+ radio6 = document.getElementById('radio6'),
+ radio71 = document.getElementById('radio71'),
+ radio72 = document.getElementById('radio72'),
+ radio8 = document.getElementById('radio8'),
+ radio9 = document.getElementById('radio9'),
+ radio10 = document.getElementById('radio10'),
+ radio11 = document.getElementById('radio11'),
+ t1 = async_test("click on mutable radio fires click event, then input event, then change event"),
+ t3 = async_test("click on non-mutable radio doesn't fire the input event"),
+ t4 = async_test("click on non-mutable radio doesn't fire the change event"),
+ t5 = async_test("canceled activation steps on unchecked radio"),
+ input_fired = false,
+ change_fired = false;
+
+ test(function(){
+ assert_false(radio1.checked);
+ assert_false(radio2.checked);
+ radio1.checked = true;
+ assert_true(radio1.checked);
+ assert_false(radio2.checked);
+ radio2.checked = true;
+ assert_false(radio1.checked);
+ assert_true(radio2.checked);
+ }, "only one control of a radio button group can have its checkedness set to true");
+
+ test(function(){
+ assert_false(radio3.checked);
+ assert_false(radio4.checked);
+ radio3.checked = true;
+ assert_true(radio3.checked);
+ assert_false(radio4.checked);
+ radio4.checked = true;
+ assert_false(radio3.checked);
+ assert_true(radio4.checked);
+ }, "radio inputs with name attributes groüp2 and groÜp2 belong to the same radio button group");
+
+ test(function(){
+ assert_true(radio8.checked);
+ assert_false(radio9.checked);
+ assert_false(radio10.checked);
+ assert_true(radio11.checked);
+ radio9.name="group4";
+ radio9.checked = true;
+ assert_true(radio8.checked);
+ assert_true(radio9.checked);
+ assert_false(radio10.checked);
+ assert_false(radio11.checked);
+ }, "changing the name of a radio input element and setting its checkedness to true makes all the other elements' checkedness in the same radio button group be set to false");
+
+ radio5.onclick = t1.step_func(function(e) {
+ click_fired = true;
+ assert_false(input_fired, "click event should fire before input event");
+ assert_false(change_fired, "click event should fire before change event");
+ assert_false(e.isTrusted, "click()-initiated click event shouldn't be trusted");
+ });
+
+ radio5.oninput = t1.step_func(function(e) {
+ input_fired = true;
+ assert_true(click_fired, "input event should fire after click event");
+ assert_false(change_fired, "input event should fire before change event");
+ assert_true(e.bubbles, "input event should bubble")
+ assert_true(e.isTrusted, "input event should be trusted");
+ assert_false(e.cancelable, "input event should not be cancelable");
+ });
+
+ radio5.onchange = t1.step_func(function(e) {
+ change_fired = true;
+ assert_true(click_fired, "change event should fire after click event");
+ assert_true(input_fired, "change event should fire after input event");
+ assert_true(e.bubbles, "change event should bubble")
+ assert_true(e.isTrusted, "change event should be trusted");
+ assert_false(e.cancelable, "change event should not be cancelable");
+ });
+
+ radio6.oninput= t3.step_func_done(function(e) {
+ assert_unreached("event input fired");
+ });
+
+ radio6.onchange = t4.step_func_done(function(e) {
+ assert_unreached("event change fired");
+ });
+
+ t1.step(function() {
+ radio5.click();
+ assert_true(input_fired);
+ t1.done();
+ });
+
+ t3.step(function(){
+ radio6.click();
+ t3.done();
+ t4.done();
+ });
+
+ radio72.onclick = t5.step_func_done(function(e){
+ assert_false(radio71.checked, "click on radio should uncheck other radio in same group");
+ assert_true(radio72.checked, "click on radio should check that radio");
+ e.preventDefault();
+ // The cancelation of the click doesn't have an effect until after all the click event handlers have been run.
+ assert_false(radio71.checked, "radio remains unchecked immediately after click event on other radio in same group is canceled");
+ assert_true(radio72.checked, "clicked radio remains checked immediately after click event is canceled");
+ });
+
+ t5.step(function(){
+ assert_true(radio71.checked, "initially checked radio should be checked");
+ assert_false(radio72.checked, "other radios in same group as initially-checked radio should be unchecked");
+ radio72.click();
+ // Now that the click event has been fully dispatched, its cancelation has taken effect.
+ assert_true(radio71.checked, "canceled click event on radio should leave the previously-checked radio checked");
+ assert_false(radio72.checked, "canceled click event on previously-unchecked radio should leave that radio unchecked");
+ });
+</script>
diff --git a/testing/web-platform/tests/html/semantics/forms/the-input-element/range-2.html b/testing/web-platform/tests/html/semantics/forms/the-input-element/range-2.html
new file mode 100644
index 000000000..3277dfc07
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/the-input-element/range-2.html
@@ -0,0 +1,43 @@
+<!DOCTYPE HTML>
+<meta charset=utf-8>
+<title>range input Tests</title>
+<link rel="author" title="Microsoft" href="http://www.microsoft.com" />
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<input type="range" id="r00" min="0" max="100" step="20" value="40" style="display:none">
+<input type="range" id="r01" min="0" max="1" step=".1" value=".2" style="display:none">
+<input type="range" id="r02" style="display:none">
+<input type="range" id="r03" style="display:none">
+<input type="range" id="r04" style="display:none">
+
+<script>
+test(function rangeElementTest0() {
+ document.getElementById('r00').value = "";
+ assert_equals(document.getElementById('r00').type, "range");
+ assert_equals(document.getElementById('r00').value, "60");
+}, "range input value set to ''");
+
+test(function rangeElementTest1() {
+ document.getElementById('r01').value = .6;
+ assert_equals(document.getElementById('r01').type, "range");
+ assert_equals(document.getElementById('r01').value, "0.6");
+}, "range input value set to an integer");
+
+test(function rangeElementTest2() {
+ assert_equals(document.getElementById('r02').type, "range");
+ assert_equals(document.getElementById('r02').value, "50");
+}, "range input value equals 50");
+
+test(function rangeElementTest3() {
+ document.getElementById('r03').value = 200;
+ assert_equals(document.getElementById('r03').type, "range");
+ assert_equals(document.getElementById('r03').value, "100");
+}, "range input value equals 100");
+
+test(function rangeElementTest4() {
+ document.getElementById('r04').value = 2.1;
+ assert_equals(document.getElementById('r04').type, "range");
+ assert_equals(document.getElementById('r04').value, "2");
+}, "range input value equals 2");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/forms/the-input-element/range.html b/testing/web-platform/tests/html/semantics/forms/the-input-element/range.html
new file mode 100644
index 000000000..2e7a85ea9
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/the-input-element/range.html
@@ -0,0 +1,276 @@
+<!DOCTYPE html>
+<html>
+
+ <head>
+ <title>Input Range</title>
+ <meta name=viewport content="width=device-width, maximum-scale=1.0, user-scalable=no" />
+ <link rel="author" title="Fabrice Clari" href="mailto:f.clari@inno-group.com">
+ <link rel="author" title="Dimitri Bocquet" href="mailto:Dimitri.Bocquet@mosquito-fp7.eu">
+ <link rel="author" title="Tomoyuki SHIMIZU" href="mailto:tomoyuki.labs@gmail.com">
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-input-element">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+
+ <body>
+
+
+ <h1>Input Range</h1>
+ <div style="display:none">
+ <input type="range" id="range_basic" min=0 max=5 />
+ <input type="range" id="value_smaller_than_min" min=0 max=5 value=-10 />
+ <input type="range" id="value_larger_than_max" min=0 max=5 value=7 />
+ <input type="range" id="empty_attributes" />
+ <input type="range" id="value_not_specified" min=2 max=6 />
+ <input type="range" id="control_step_mismatch" min=0 max=7 step=2 />
+ <input type="range" id="max_smaller_than_min" min=2 max=-3 />
+ <input type="range" id="default_step_scale_factor_1" min=5 max=12.6 value=6.7 />
+ <input type="range" id="default_step_scale_factor_2" min=5.3 max=12 value=6.7 />
+ <input type="range" id="default_step_scale_factor_3"min=5 max=12.6 step=0.5 value=6.7 />
+ <input type="range" id="float_step_scale_factor" min=5.3 max=12 step=0.5 value=6.7 />
+ <input type="range" id="stepup" min=3 max=14 value=6 step=3 />
+ <input type="range" id="stepdown" min=3 max=11 value=9 step=3 />
+ <input type="range" id="stepup_beyond_max" min=3 max=14 value=9 step=3 />
+ <input type="range" id="stepdown_beyond_min" min=3 max=11 value=6 step=3 />
+ <input type="range" id="illegal_min_and_max" min="ab" max="f" />
+ <input type="range" id="illegal_value_and_step" min=0 max=5 value="ppp" step="xyz" />
+ </div>
+
+ <div id="log">
+ </div>
+
+ <script type="text/javascript">
+
+ test(
+ function() {
+ assert_equals(document.getElementById('range_basic').type, "range");
+ },
+ "range type support on input element",
+ {
+ "help" : "https://html.spec.whatwg.org/multipage/#dom-input-type"
+ }
+ );
+
+ test(
+ function() {
+ assert_equals(document.getElementById('range_basic').min, "0")
+ },
+ "min attribute support on input element",
+ {
+ "help" : "https://html.spec.whatwg.org/multipage/#dom-input-min"
+ }
+ );
+
+ test(
+ function() {
+ assert_equals(document.getElementById('range_basic').max, "5")
+ },
+ "max attribute support on input element",
+ {
+ "help" : "https://html.spec.whatwg.org/multipage/#dom-input-max"
+ }
+ );
+
+ // HTML5 spec says the default vaules of min and max attributes are 0 and 100 respectively,
+ // however, Chrome, Opera and Firefox would not give any default value at all...
+ test(
+ function() {
+ assert_equals(document.getElementById('illegal_min_and_max').min, "0")
+ },
+ "Illegal value of min attribute",
+ {
+ "help" : "https://html.spec.whatwg.org/multipage/#range-state-(type=range)"
+ }
+ );
+
+ test(
+ function() {
+ assert_equals(document.getElementById('illegal_min_and_max').max, "100")
+ },
+ "Illegal value of max attribute",
+ { "help" : "https://html.spec.whatwg.org/multipage/#range-state-(type=range)" }
+ );
+
+ test(
+ function() {
+ assert_equals(document.getElementById('illegal_value_and_step').value, "3")
+ },
+ "Converting an illegal string to the default value",
+ {
+ "help" : "https://html.spec.whatwg.org/multipage/#range-state-(type=range)"
+ }
+ );
+
+ test(
+ function() {
+ assert_equals(document.getElementById('illegal_value_and_step').step, "1")
+ },
+ "Converting an illegal string to the default step",
+ { "help" : "https://html.spec.whatwg.org/multipage/#range-state-(type=range)" }
+ );
+
+ test(
+ function() {
+ assert_equals(document.getElementById('value_smaller_than_min').value, "0")
+ },
+ "the value is set to min when a smaller value than min attribute is given",
+ {
+ "help" : "https://html.spec.whatwg.org/multipage/#range-state-(type=range)"
+ }
+ );
+
+ test(
+ function() {
+ assert_equals(document.getElementById('value_larger_than_max').value, "5")
+ },
+ "the value is set to max when a larger value than max attribute is given",
+ {
+ "help" : "https://html.spec.whatwg.org/multipage/#range-state-(type=range)"
+ }
+ );
+
+ test(
+ function() {
+ assert_equals(document.getElementById('empty_attributes').min, "0")
+ },
+ "default value of min attribute in input type=range",
+ { "help" : "https://html.spec.whatwg.org/multipage/#dom-input-min" }
+ );
+
+ test(
+ function() {
+ assert_equals(document.getElementById('empty_attributes').max, "100")
+ },
+ "default value of max attribute in input type=range",
+ {
+ "help" : "https://html.spec.whatwg.org/multipage/#dom-input-max"
+ }
+ );
+
+ test(
+ function() {
+ assert_equals(document.getElementById('value_not_specified').value, "4")
+ },
+ "default value when min and max attributes are given (= min plus half the difference between min and max)",
+ {
+ "help" : "https://html.spec.whatwg.org/multipage/#range-state-(type=range)"
+ }
+ );
+
+ test(
+ function() {
+ assert_equals(document.getElementById('control_step_mismatch').value, "4")
+ },
+ "default value with step control when both min and max attributes are given",
+ {
+ "help" : "https://html.spec.whatwg.org/multipage/#range-state-(type=range)"
+ }
+ );
+
+ // Chrome would result in different value out of the range between min and max. Why?
+ test(
+ function() {
+ assert_equals(document.getElementById('max_smaller_than_min').value, "2")
+ },
+ "default value when both min and max attributes are given, while min > max",
+ {
+ "help" : "https://html.spec.whatwg.org/multipage/#range-state-(type=range)"
+ }
+ );
+
+ test(
+ function() {
+ assert_equals(document.getElementById('default_step_scale_factor_1').value, "7")
+ },
+ "The default step scale factor is 1, unless min attribute has non-integer value",
+ {
+ "help" : "https://html.spec.whatwg.org/multipage/#range-state-(type=range)"
+ }
+ );
+
+ test(
+ function() {
+ assert_equals(document.getElementById('default_step_scale_factor_2').value, "6.3")
+ },
+ "Step scale factor behavior when min attribute has integer value but max attribute is non-integer ",
+ {
+ "help" : "https://html.spec.whatwg.org/multipage/#range-state-(type=range)" }
+ );
+
+ test(
+ function() {
+ assert_equals(document.getElementById('default_step_scale_factor_3').step, "1")
+ },
+ "The default scale factor is 1 even if step attribute is explicitly set to non-integer value, unless min attribute has non-integer value",
+ {
+ "help" : "https://html.spec.whatwg.org/multipage/#range-state-(type=range)"
+ }
+ );
+
+ test(
+ function() {
+ assert_equals(document.getElementById('float_step_scale_factor').value, "6.8")
+ },
+ "Solving the step mismatch",
+ {
+ "help" : "https://html.spec.whatwg.org/multipage/#range-state-(type=range)"
+ }
+ );
+
+ // Firefox Nightly (24.0a1) would result in the possible maximum value in this range... (i.e. 12)
+ test(
+ function() {
+ var e = document.getElementById('stepup');
+ e.stepUp();
+ assert_equals(e.value, "9")
+ },
+ "Performing stepUp()",
+ {
+ "help" : "https://html.spec.whatwg.org/multipage/#dom-input-stepup"
+ }
+ );
+
+ // Firefox Nightly (24.0a1) would result in the possible minimum value in this range... (i.e. 3)
+ test(
+ function() {
+ var e = document.getElementById('stepdown');
+ e.stepDown();
+ assert_equals(e.value, "6")
+ },
+ "Performing stepDown()",
+ {
+ "help" : "https://html.spec.whatwg.org/multipage/#dom-input-stepdown"
+ }
+ );
+
+ // Chrome and Opera would throw DOM Exception 11 (InvalidStateError)
+ // Firefox Nightly gives the correct result
+ test(
+ function() {
+ var e = document.getElementById('stepup_beyond_max');
+ e.stepUp(2);
+ assert_equals(e.value, "12")
+ },
+ "Performing stepUp() beyond the value of the max attribute",
+ {
+ "help" : "https://html.spec.whatwg.org/multipage/#dom-input-stepup"
+ }
+ );
+
+ // Chrome and Opera would throw DOM Exception 11 (InvalidStateError)
+ // Firefox Nightly gives the correct result
+ test(
+ function() {
+ var e = document.getElementById('stepdown_beyond_min');
+ e.stepDown(2);
+ assert_equals(e.value, "3")
+ }, "Performing stepDown() beyond the value of the min attribute", {
+ "help" : "https://html.spec.whatwg.org/multipage/#dom-input-stepdown"
+ }
+ );
+
+ </script>
+
+ </body>
+
+</html>
diff --git a/testing/web-platform/tests/html/semantics/forms/the-input-element/required_attribute.html b/testing/web-platform/tests/html/semantics/forms/the-input-element/required_attribute.html
new file mode 100644
index 000000000..63488e9f4
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/the-input-element/required_attribute.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<html>
+
+ <head>
+ <title>Required Attribute</title>
+ <meta name=viewport content="width=device-width, maximum-scale=1.0, user-scalable=no" />
+ <link rel="author" title="Fabrice Clari" href="mailto:f.clari@inno-group.com">
+ <link rel="author" title="Dimitri Bocquet" href="mailto:Dimitri.Bocquet@mosquito-fp7.eu">
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#attr-input-required">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+
+ <body>
+
+
+ <h1>Required Attribute</h1>
+ <div style="display: none">
+ <input type="text" required="required" />
+ </div>
+
+ <div id="log">
+ </div>
+
+ <script type="text/javascript">
+
+
+ test(function() {assert_equals(document.getElementsByTagName("input")[0].getAttribute("required"), "required")}, "required attribute support on input element");
+
+ </script>
+
+ </body>
+
+</html>
diff --git a/testing/web-platform/tests/html/semantics/forms/the-input-element/reset.html b/testing/web-platform/tests/html/semantics/forms/the-input-element/reset.html
new file mode 100644
index 000000000..9a9799542
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/the-input-element/reset.html
@@ -0,0 +1,113 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>input type reset</title>
+<link rel="author" title="Denis Ah-Kang" href="mailto:denis@w3.org">
+<link rel=help href="https://html.spec.whatwg.org/multipage/#reset-button-state-(type=reset)">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<form>
+ <input type=text id=input1 value="foobar">
+ <input type=text id=input2>
+ <input type=reset id=r1>
+</form>
+
+<input type=text id=input3 value="barfoo">
+
+<table>
+ <form>
+ <tr>
+ <td>
+ <input type=text id=input4 value="foobar">
+ <input type=reset id=r2>
+ </td>
+ </tr>
+ </form>
+</table>
+
+<div>
+ <form>
+ <input type=text id=input5 value="foobar">
+ </div>
+ <input type=reset id=r3>
+</form>
+
+<div>
+ <form>
+ <input type=reset id=r4>
+ </div>
+ <input type=text id=input6 value="foobar">
+</form>
+
+<form id=form5>
+ <input type=reset id=r5>
+</form>
+<input form=form5 type=text id=input7 value="foobar">
+
+<form id=form6>
+ <input type=text id=input8 value="foobar">
+</form>
+<input type=reset form=form6 id=r6>
+
+<script>
+ var input1 = document.getElementById('input1'),
+ input2 = document.getElementById('input2'),
+ input3 = document.getElementById('input3'),
+ input7 = document.getElementById('input7'),
+ input8 = document.getElementById('input8'),
+ r1 = document.getElementById('r1');
+
+ test(function(){
+ assert_equals(input1.value, "foobar");
+ assert_equals(input2.value, "");
+ assert_equals(input3.value, "barfoo");
+ input1.value = "foobar1";
+ input2.value = "notempty";
+ input3.value = "barfoo1";
+ assert_equals(input1.value, "foobar1");
+ assert_equals(input2.value, "notempty");
+ assert_equals(input3.value, "barfoo1");
+ r1.click();
+ assert_equals(input1.value, "foobar");
+ assert_equals(input2.value, "");
+ assert_equals(input3.value, "barfoo1");
+ }, "reset button only resets the form owner");
+
+ test(function(){
+ assert_false(r1.willValidate);
+ }, "the element is barred from constraint validation");
+
+ test(function(){
+ assert_equals(input1.value, "foobar");
+ assert_equals(input2.value, "");
+ assert_equals(input3.value, "barfoo1");
+ r1.disabled = true;
+ r1.click();
+ assert_equals(input1.value, "foobar");
+ assert_equals(input2.value, "");
+ assert_equals(input3.value, "barfoo1");
+ }, "clicking on a disabled reset does nothing");
+
+ function testReset(inputId, buttonId) {
+ var inp = document.getElementById(inputId);
+ assert_equals(inp.value, "foobar");
+ inp.value = "barfoo";
+ assert_equals(inp.value, "barfoo");
+ document.getElementById(buttonId).click();
+ assert_equals(inp.value, "foobar");
+ }
+
+ test(function(){
+ testReset("input4", "r2");
+ testReset("input5", "r3");
+ testReset("input6", "r4");
+ }, "reset button resets controls associated with their form using the form element pointer");
+
+ test(function(){
+ testReset("input7", "r5");
+ }, "reset button resets controls associated with a form using the form attribute");
+
+ test(function(){
+ testReset("input8", "r6");
+ }, "reset button associated with a form using the form attribute resets all the form's controls");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/forms/the-input-element/search_input.html b/testing/web-platform/tests/html/semantics/forms/the-input-element/search_input.html
new file mode 100644
index 000000000..175cdde99
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/the-input-element/search_input.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<html>
+
+ <head>
+ <title>Search Input</title>
+ <meta name=viewport content="width=device-width, maximum-scale=1.0, user-scalable=no" />
+ <link rel="author" title="Fabrice Clari" href="mailto:f.clari@inno-group.com">
+ <link rel="author" title="Dimitri Bocquet" href="mailto:Dimitri.Bocquet@mosquito-fp7.eu">
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-input-element">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+
+ <body>
+
+
+ <h1>Search Input</h1>
+ <input type="search" style="display:none" placeholder="Search..." />
+
+ <div id="log">
+ </div>
+
+ <script type="text/javascript">
+
+
+ test(function() {assert_equals(document.getElementsByTagName("input")[0].type, "search")}, "search type support on input element", {
+ "help" : "https://html.spec.whatwg.org/multipage/#dom-input-type" });
+ test(function() {assert_equals(document.getElementsByTagName("input")[0].placeholder, "Search...")}, "placeholder attribute support on input element", {
+ "help" : "https://html.spec.whatwg.org/multipage/#dom-input-placeholder" });
+
+ </script>
+
+ </body>
+
+</html>
diff --git a/testing/web-platform/tests/html/semantics/forms/the-input-element/selection.html b/testing/web-platform/tests/html/semantics/forms/the-input-element/selection.html
new file mode 100644
index 000000000..4ed4bc914
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/the-input-element/selection.html
@@ -0,0 +1,135 @@
+<!DOCTYPE HTML>
+<title>Input element programmatic selection support</title>
+<link rel="author" title="yaycmyk" href="mailto:evan@yaycmyk.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/forms.html#dom-textarea/input-select">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<script>
+
+/* all textual, non-hidden inputs support .select() */
+test(function() {
+ var valid = [
+ "text",
+ "search",
+ "url",
+ "tel",
+ "email",
+ "password",
+ "date",
+ "month",
+ "week",
+ "time",
+ "datetime-local",
+ "number",
+ "color",
+ "file",
+ ];
+
+ var invalid = [
+ "hidden",
+ "range",
+ "checkbox",
+ "radio",
+ "submit",
+ "image",
+ "reset",
+ "button"
+ ];
+
+ valid.forEach(function(type) {
+ test(function() {
+ var input = document.createElement("input");
+ var a;
+
+ input.type = type;
+ assert_equals(input.type, type, "the given input type is not supported");
+
+ input.select();
+
+ }, "input type " + type + " should support the select() method");
+ });
+
+ invalid.forEach(function(type) {
+ test(function() {
+ var input = document.createElement("input");
+
+ input.type = type;
+ assert_equals(input.type, type, "the given input type is not supported");
+
+ assert_throws("INVALID_STATE_ERR", function() { input.select(); });
+
+ }, "input type " + type + " should not support the select() method");
+ });
+});
+
+/* only certain input types are allowed to have a variable-length selection */
+test(function() {
+ var valid = [
+ "text",
+ "search",
+ "url",
+ "tel",
+ "password"
+ ];
+
+ var invalid = [
+ "hidden",
+ "email",
+ "date",
+ "month",
+ "week",
+ "time",
+ "datetime-local",
+ "number",
+ "range",
+ "color",
+ "checkbox",
+ "radio",
+ "file",
+ "submit",
+ "image",
+ "reset",
+ "button"
+ ];
+
+ valid.forEach(function(type) {
+ test(function() {
+ var input = document.createElement("input");
+ var a;
+
+ input.type = type;
+ assert_equals(input.type, type, "the given input type is not supported");
+
+ a = input.selectionStart;
+ input.selectionStart = 0;
+ a = input.selectionEnd;
+ input.selectionEnd = 0;
+ a = input.selectionDirection;
+ input.selectionDirection = "none";
+ input.setSelectionRange(0, 0);
+ input.setRangeText('', 0, 0);
+
+ }, "input type " + type + " should support all selection attributes and methods");
+ });
+
+ invalid.forEach(function(type) {
+ test(function() {
+ var input = document.createElement("input");
+
+ input.type = type;
+ assert_equals(input.type, type, "the given input type is not supported");
+
+ assert_equals(input.selectionStart, null, 'getting input.selectionStart');
+ assert_throws("INVALID_STATE_ERR", function() { input.selectionStart = 0; });
+ assert_equals(input.selectionEnd, null, 'getting input.selectionEnd');
+ assert_throws("INVALID_STATE_ERR", function() { input.selectionEnd = 0; });
+ assert_equals(input.selectionDirection, null, 'getting input.selectionDirection');
+ assert_throws("INVALID_STATE_ERR", function() { input.selectionDirection = "none"; });
+ assert_throws("INVALID_STATE_ERR", function() { input.setSelectionRange(0, 0); });
+ assert_throws("INVALID_STATE_ERR", function() { input.setRangeText('', 0, 0); });
+
+ }, "input type " + type + " should not support variable-length selections");
+ });
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/forms/the-input-element/telephone.html b/testing/web-platform/tests/html/semantics/forms/the-input-element/telephone.html
new file mode 100644
index 000000000..974cbaf88
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/the-input-element/telephone.html
@@ -0,0 +1,84 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>Input tel</title>
+ <link rel="author" title="Kazuki Kanamori" href="mailto:yogurito@gmail.com">
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#telephone-state-(type=tel)">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+</head>
+<body>
+ <h1>Input tel</h1>
+ <input type="tel" id="novalue" />
+ <input type="tel" id="value_with_LF" value="0&#x000A;1" />
+ <input type="tel" id="value_with_CR" value="0&#x000D;1" />
+ <input type="tel" id="value_with_CRLF" value="0&#x000A;&#x000D;1" />
+ <div id="log">
+ </div>
+
+ <script type="text/javascript">
+ var element = document.getElementById('novalue');
+ test(function(){
+ assert_equals(element.type, 'tel');
+ }, 'tel type supported on input element');
+ test(function(){
+ element.value = '0\u000A1';
+ assert_equals(element.value, '01');
+ }, 'User agents must not allow users to insert "LF" (U+000A)');
+ test(function(){
+ element.value = '0\u000D1';
+ assert_equals(element.value, '01');
+ }, 'User agents must not allow users to insert "CR" (U+000D)');
+
+ element = document.getElementById('value_with_LF');
+ test(function(){
+ assert_equals(element.value, '01');
+ }, 'The value attribute, if specified, must have a value that contains no "LF" (U+000A)');
+
+ element = document.getElementById('value_with_CR');
+ test(function(){
+ assert_equals(element.value, '01');
+ }, 'The value attribute, if specified, must have a value that contains no "CR" (U+000D)');
+
+ test(function(){
+ element = document.getElementById('novalue');
+ element.value = '0\u000D\u000A1';
+ assert_equals(element.value, '01');
+
+ element = document.getElementById('value_with_CRLF');
+ assert_equals(element.value, '01');
+ }, 'The value sanitization algorithm is as follows: Strip line breaks from the value');
+
+ element = document.getElementById('novalue');
+ test(function(){
+ element.value = '+811234';
+ assert_equals(element.value, '+811234');
+ }, 'Element can accept the phone number with plus sign(country code)');
+ test(function(){
+ element.value = '1234#5678';
+ assert_equals(element.value, '1234#5678');
+ }, 'Element can accept the phone number with hash mark(extension number)');
+ test(function(){
+ element.value = '123-456-789';
+ assert_equals(element.value, '123-456-789');
+ }, 'Element can accept the phone number with hyphen');
+ test(function(){
+ element.value = '123.456.789';
+ assert_equals(element.value, '123.456.789');
+ }, 'Element can accept the phone number with dots');
+ test(function(){
+ element.value = '1 23 4';
+ assert_equals(element.value, '1 23 4');
+ }, 'Element can accept the phone number with whitespace');
+ test(function(){
+ element.value = ' 1234 ';
+ assert_equals(element.value, ' 1234 ');
+ }, 'Element can accept the phone number with leading & following whitespaces');
+ test(function(){
+ element.value = '(03)12345678';
+ assert_equals(element.value, '(03)12345678');
+ }, 'Element can accept the phone number with parentheses(area code)');
+ </script>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/forms/the-input-element/text.html b/testing/web-platform/tests/html/semantics/forms/the-input-element/text.html
new file mode 100644
index 000000000..b6d4ceabf
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/the-input-element/text.html
@@ -0,0 +1,104 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>Text input element</title>
+ <link rel="author" title="Kinuko Yasuda" href="mailto:kinuko@chromium.org">
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#text-(type=text)-state-and-search-state-(type=search)">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+
+ <body>
+ <h1>Text input element</h1>
+ <div style="display: none">
+
+ <input id="text" type="text" />
+ <input id="text_with_value" type="text" value="foo" />
+
+ <input id="search" type="search" />
+ <input id="search_with_value" type="search" value="foo" />
+
+ </div>
+ <div id="log"></div>
+ <script type="text/javascript">
+ var types = [ 'text', 'search' ];
+
+ for (var i = 0; i < types.length; ++i) {
+ test(
+ function() {
+ assert_equals(document.getElementById(types[i]).value, "");
+ assert_equals(document.getElementById(types[i] + "_with_value").value, "foo");
+ }, "Value returns the current value for " + types[i]);
+
+ test(
+ function() {
+ document.getElementById(types[i]).value = "A";
+ assert_equals(document.getElementById(types[i]).value, "A");
+ document.getElementById(types[i]).value = "B";
+ }, "Setting value changes the current value for " + types[i]);
+
+ test(
+ function() {
+ // Any LF (\n) must be stripped.
+ document.getElementById(types[i]).value = "\nAB";
+ assert_equals(document.getElementById(types[i]).value, "AB");
+ document.getElementById(types[i]).value = "A\nB";
+ assert_equals(document.getElementById(types[i]).value, "AB");
+ document.getElementById(types[i]).value = "AB\n";
+ assert_equals(document.getElementById(types[i]).value, "AB");
+
+ // Any CR (\r) must be stripped.
+ document.getElementById(types[i]).value = "\rAB";
+ assert_equals(document.getElementById(types[i]).value, "AB");
+ document.getElementById(types[i]).value = "A\rB";
+ assert_equals(document.getElementById(types[i]).value, "AB");
+ document.getElementById(types[i]).value = "AB\r";
+ assert_equals(document.getElementById(types[i]).value, "AB");
+
+ // Any combinations of LF CR must be stripped.
+ document.getElementById(types[i]).value = "\r\nAB";
+ assert_equals(document.getElementById(types[i]).value, "AB");
+ document.getElementById(types[i]).value = "A\r\nB";
+ assert_equals(document.getElementById(types[i]).value, "AB");
+ document.getElementById(types[i]).value = "AB\r\n";
+ assert_equals(document.getElementById(types[i]).value, "AB");
+ document.getElementById(types[i]).value = "\r\nA\n\rB\r\n";
+ assert_equals(document.getElementById(types[i]).value, "AB");
+ }, "Value sanitization algorithm should strip line breaks for " + types[i]);
+
+ test(
+ function() {
+ assert_equals(document.getElementById(types[i]).files, null);
+ }, "files attribute must return null for " + types[i]);
+
+ test(
+ function() {
+ assert_equals(document.getElementById(types[i]).valueAsDate, null);
+ }, "valueAsDate attribute must return null for " + types[i]);
+
+ test(
+ function() {
+ assert_equals(document.getElementById(types[i]).valueAsNumber, NaN);
+ }, "valueAsNumber attribute must return NaN for " + types[i]);
+
+ test(
+ function() {
+ assert_equals(document.getElementById("text").list, null);
+ }, "list attribute must return null for " + types[i]);
+
+ test(
+ function() {
+ var el = document.getElementById(types[i]);
+ assert_throws("InvalidStateError", function() { el.stepDown(); }, "");
+ }, "stepDown does not apply for " + types[i]);
+
+ test(
+ function() {
+ var el = document.getElementById(types[i]);
+ assert_throws("InvalidStateError", function() { el.stepUp(); }, "");
+ }, "stepUp does not apply for " + types[i]);
+ }
+
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/forms/the-input-element/time-2.html b/testing/web-platform/tests/html/semantics/forms/the-input-element/time-2.html
new file mode 100644
index 000000000..cf0d4cbbe
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/the-input-element/time-2.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Form input type=time</title>
+<link rel="author" title="Denis Ah-Kang" href="mailto:denis@w3.org">
+<link rel=help href="https://html.spec.whatwg.org/multipage/multipage/common-microsyntaxes.html#times">
+<link rel=help href="https://html.spec.whatwg.org/multipage/multipage/states-of-the-type-attribute.html#time-state-(type=time)">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<script>
+ var times = [
+ {value: "", expected: "", testname: "empty value"},
+ {value: "00:00", expected: "00:00", testname: "Valid value: value should be 00:00"},
+ {value: "00:00:00", expected: "00:00:00", testname: "Valid value: value should be 00:00:00"},
+ {value: "00:00:00.0", expected: "00:00:00.0", testname: "Valid value: value should be 00:00:00.0"},
+ {value: "00:00:00.00", expected: "00:00:00.00", testname: "Valid value: value should be 00:00:00.00"},
+ {value: "00:00:00.000", expected: "00:00:00.000", testname: "Valid value: value should be 00:00:00.000"},
+ {value: "00:00:00.0000", expected: "", testname: "Invalid value: fraction should have one, two or three ASCII digits. Value should be empty"},
+ {value: "0:00:00.000", expected: "", testname: "Invalid value: hour should have two ASCII digits. Value should be empty"},
+ {value: "00:0:00.000", expected: "", testname: "Invalid value: minutes should have two ASCII digits. Value should be empty"},
+ {value: "00:00:0.000", expected: "", testname: "Invalid value: seconds should have two ASCII digits. Value should be empty"},
+ {value: "24:00:00.000", expected: "", testname: "Invalid value: hour > 23. Value should be empty"},
+ {value: "00:60:00.000", expected: "", testname: "Invalid value: minute > 59. Value should be empty"},
+ {value: "00:00:60.000", expected: "", testname: "Invalid value: second > 59. Value should be empty"},
+ {value: "12:00:00.001", attributes: { min: "12:00:00.000" }, expected: "12:00:00.001", testname: "Value >= min attribute"},
+ {value: "12:00:00.000", attributes: { min: "12:00:00.001" }, expected: "12:00:00.001", testname: "Value < min attribute"},
+ {value: "12:00:00.000", attributes: { max: "12:00:00.001" }, expected: "12:00:00.000", testname: "Value <= max attribute"},
+ {value: "12:00:00.001", attributes: { max: "12:00:00.000" }, expected: "12:00:00.000", testname: "Value > max attribute"}
+ ];
+ for (var i = 0; i < times.length; i++) {
+ var w = times[i];
+ test(function() {
+ var input = document.createElement("input");
+ input.type = "time";
+ input.value = w.value;
+ for(var attr in w.attributes) {
+ input[attr] = w.attributes[attr];
+ }
+ assert_equals(input.value, w.expected);
+ }, w.testname);
+ }
+</script>
diff --git a/testing/web-platform/tests/html/semantics/forms/the-input-element/time.html b/testing/web-platform/tests/html/semantics/forms/the-input-element/time.html
new file mode 100644
index 000000000..5178d91de
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/the-input-element/time.html
@@ -0,0 +1,207 @@
+<!DOCTYPE html>
+<html>
+
+ <head>
+ <title>Input Time</title>
+ <meta name=viewport content="width=device-width, maximum-scale=1.0, user-scalable=no" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-input-element">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+
+ <body>
+ <h1>Input Time</h1>
+ <div style="display:none;">
+ <input type="time "id="chkDefaultValue" />
+ <input type="time" id="chkStep" />
+ <input type="time" id="chkSetValueTest" />
+ <input type="time" id="chkSupportAttribute" min="01:01:01.001" max="12:12:12.012" step="600" />
+ </div>
+ <div id="log">
+ </div>
+
+ <script type="text/javascript">
+
+/* check default value */
+test(function(){ assert_equals(document.getElementById("chkDefaultValue").value, "");
+}, "time element of default time value");
+test(function(){assert_equals(document.getElementById('chkStep').step, "");
+}, "step attribute on default value check");
+test(function(){assert_equals(document.getElementById('chkDefaultValue').max, "");
+}, "max attribute on default value check")
+test(function(){assert_equals(document.getElementById('chkDefaultValue').max, "");
+}, "min attribute on default value check")
+
+/* simple attribute test*/
+test(function(){assert_equals(document.getElementById("chkSupportAttribute").type,"time");}
+ , "type attribute support on input element");
+test(function(){assert_equals(document.getElementById('chkSupportAttribute').min, "01:01:01.001")}
+ , "max attribute support on input element");
+test(function(){assert_equals(document.getElementById('chkSupportAttribute').max, "12:12:12.012")}
+ , "min attribute support on input element");
+test(function(){assert_equals(document.getElementById("chkSupportAttribute").step, "600")}
+ , "step attribute support on input element");
+
+/* check step up and down */
+var _StepTest = document.getElementById("chkStep");
+test(function(){ assert_true(typeof(_StepTest.stepUp) ==="function" ) } , "stepUp function support on input Element");
+test(function(){ assert_true(typeof(_StepTest.stepDown) ==="function" ) } , "stepDown function support on input Element");
+
+test(function(){
+ _StepTest.value = "12:00";
+ _StepTest.step = "";
+ _StepTest.stepUp();
+ assert_equals(_StepTest.value,"12:01");
+} , "stepUp step value empty on default step value ");
+
+test(function(){
+ _StepTest.value = "12:00";
+ _StepTest.step = "";
+ _StepTest.stepDown();
+ assert_equals(_StepTest.value,"11:59");
+}, "stepDown step value empty default step value");
+
+test(function(){
+ _StepTest.value = "12:00";
+ _StepTest.step = "-600";
+ _StepTest.stepUp();
+ assert_equals(_StepTest.value, "12:01");
+},"stepUp on step value minus");
+test(function(){
+ _StepTest.value = "12:00";
+ _StepTest.step = "-600";
+ _StepTest.stepDown();
+ assert_equals(_StepTest.value, "11:59");
+},"stepDown on step value minus");
+
+test(function(){
+ _StepTest.value = "12:00";
+ _StepTest.step = "0";
+ _StepTest.stepUp();
+ assert_equals(_StepTest.value, "12:01");
+} , "stepUp on step value zero ");
+test(function(){
+ _StepTest.value = "12:00";
+ _StepTest.step = "0";
+ _StepTest.stepDown();
+ assert_equals(_StepTest.value, "11:59");
+} , "stepDown on step value zero ");
+
+test(function(){
+ _StepTest.value = "00:00";
+ _StepTest.step = "86399";
+ _StepTest.stepUp();
+ assert_equals(_StepTest.value, "23:59:59");
+} , "stepUp on step value 24 hour");
+test(function(){
+ _StepTest.value = "23:59:59";
+ _StepTest.step = "86399";
+ _StepTest.stepDown();
+ assert_equals(_StepTest.value, "00:00:00");
+} , "stepDown on step value 24 hour ");
+
+test(function(){
+ _StepTest.value = "12:00";
+ _StepTest.step = "3600";
+ _StepTest.stepUp();
+ assert_equals(_StepTest.value, "13:00");
+} , "stepUp on step value hour ");
+test(function(){
+ _StepTest.value = "12:00";
+ _StepTest.step = "3600";
+ _StepTest.stepDown();
+ assert_equals(_StepTest.value, "11:00");
+} , "stepDown on step value hour ");
+
+test(function(){
+ _StepTest.value = "12:00";
+ _StepTest.step = "1";
+ _StepTest.stepUp();
+ assert_equals(_StepTest.value, "12:00:01");
+} , "stepUp on step value second ");
+test(function(){
+ _StepTest.value = "12:00";
+ _StepTest.step = "1";
+ _StepTest.stepDown();
+ assert_equals(_StepTest.value, "11:59:59");
+} , "stepDown on step value second ");
+
+test(function(){
+ _StepTest.value = "12:00";
+ _StepTest.step = "0.001";
+ _StepTest.stepUp();
+ assert_equals(_StepTest.value, "12:00:00.001");
+} , "stepUp on step value miri second ");
+test(function(){
+ _StepTest.value = "12:00";
+ _StepTest.step = "0.001";
+ _StepTest.stepDown();
+ assert_equals(_StepTest.value, "11:59:59.999");
+} , "stepDown on step value miri second ");
+
+test(function(){
+ _StepTest.value = "13:00:00";
+ _StepTest.step = "1";
+ _StepTest.stepUp(2);
+ assert_equals(_StepTest.value, "13:00:02");
+}, "stepUp argment 2 times");
+test(function(){
+ _StepTest.value = "13:00:00";
+ _StepTest.step = "1";
+ _StepTest.stepDown(2);
+ assert_equals(_StepTest.value, "12:59:58");
+}, "stepDown argment 2 times");
+
+test(function(){
+ _StepTest.max = "15:00";
+ _StepTest.value = "15:00";
+ _StepTest.stepUp();
+ assert_equals(_StepTest.value, "15:00");
+ _StepTest.max = "";
+} , "stepUp stop because it exceeds the maximum value");
+test(function(){
+ _StepTest.min = "13:00";
+ _StepTest.value = "13:00";
+ _StepTest.stepDown();
+ assert_equals(_StepTest.value, "13:00");
+ _StepTest.min="";
+} , "stepDown Stop so lower than the minimum value");
+
+test(function(){
+ _StepTest.max = "15:01";
+ _StepTest.value = "15:00";
+ _StepTest.step = "120";
+ _StepTest.stepUp();
+ assert_equals(_StepTest.value, "15:01");
+ _StepTest.max = "";
+} , "stop at border on stepUp");
+test(function(){
+ _StepTest.min = "12:59";
+ _StepTest.value = "13:00";
+ _StepTest.step = "120";
+ _StepTest.stepDown();
+ assert_equals(_StepTest.value, "12:59");
+ _StepTest.min="";
+} , "stop at border on stepDown");
+
+test(function(){
+ _StepTest.value = "";
+ _StepTest.step = "60";
+ _StepTest.stepUp();
+ assert_equals(_StepTest.value, "00:01");
+} , " empty value of stepUp");
+
+
+/* set value test */
+test(function(){
+ var _time = document.getElementById("chkSetValueTest");
+ _time.value = "12:00:00.000";
+ assert_equals(_time.value, "12:00:00.000");
+ _time.value = "hh:mi:ss.sss";
+ assert_equals(_time.value, "");
+}, "set value on not time format value");
+
+
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/forms/the-input-element/type-change-state.html b/testing/web-platform/tests/html/semantics/forms/the-input-element/type-change-state.html
new file mode 100644
index 000000000..def11da84
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/the-input-element/type-change-state.html
@@ -0,0 +1,62 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Input element's type attribute changes state</title>
+<link rel="author" title="Denis Ah-Kang" href="mailto:denis@w3.org">
+<link rel=help href="https://html.spec.whatwg.org/multipage/#the-input-element">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<script>
+ var types = [
+ { type: "hidden" },
+ { type: "text", sanitizedValue: " foobar " },
+ { type: "search", sanitizedValue: " foobar " },
+ { type: "tel", sanitizedValue: " foobar " },
+ { type: "url", sanitizedValue: "foobar" },
+ { type: "email", sanitizedValue: "foobar" },
+ { type: "password", sanitizedValue: " foobar " },
+ { type: "datetime-local", sanitizedValue: "" },
+ { type: "date", sanitizedValue: "" },
+ { type: "month", sanitizedValue: "" },
+ { type: "week", sanitizedValue: "" },
+ { type: "time", sanitizedValue: "" },
+ { type: "number", sanitizedValue: "" },
+ { type: "range", sanitizedValue: "50" },
+ { type: "color", sanitizedValue: "#000000" },
+ { type: "checkbox" },
+ { type: "radio" },
+ { type: "file" },
+ { type: "submit" },
+ { type: "image" },
+ { type: "reset" },
+ { type: "button" }
+ ];
+ for (var i = 0; i < types.length; i++) {
+ for (var j = 0; j < types.length; j++) {
+ if (types[i] != types[j]) {
+ test(function() {
+ var input = document.createElement("input");
+ input.type = types[i].type;
+ if (types[i].type === "file") {
+ assert_throws("INVALID_STATE_ERR", function() {
+ input.value = " foo\rbar ";
+ });
+ assert_equals(input.value, "");
+ } else if (types[j].type === "file") {
+ input.value = " foo\rbar ";
+ input.type = types[j].type; // change state
+ assert_equals(input.value, "");
+ } else {
+ input.value = " foo\rbar ";
+ input.type = types[j].type; // change state
+ if (types[j].sanitizedValue || types[j].sanitizedValue === "") {
+ assert_equals(input.value, types[j].sanitizedValue, "input.value should be " + types[j].sanitizedValue + " after change of state");
+ } else {
+ assert_equals(input.value, " foo\rbar ", "input.value should be ' foo\\rbar ' after change of state");
+ }
+ }
+ }, "change state from " + types[i].type + " to " + types[j].type);
+ }
+ }
+ }
+</script>
diff --git a/testing/web-platform/tests/html/semantics/forms/the-input-element/url.html b/testing/web-platform/tests/html/semantics/forms/the-input-element/url.html
new file mode 100644
index 000000000..aafa0ced9
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/the-input-element/url.html
@@ -0,0 +1,59 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>Input url</title>
+ <link rel="author" title="Hyeonseok Shin" href="mailto:hyeonseok@gmail.com">
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#url-state-%28type=url%29">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+</head>
+<body>
+ <h1>Input url</h1>
+ <div style="display: none">
+ <input type="url" id="type_support" />
+ <input type="url" id="set_value_LF" />
+ <input type="url" id="set_value_CR" />
+ <input type="url" id="set_value_CRLF" />
+ <input type="url" id="value_with_CRLF" value="a&#x000D;&#x000A;a" />
+ <input type="url" id="value_with_leading_trailing_white_space" value=" aa " />
+ <input type="url" id="value_with_leading_trailing_inner_white_space" value=" a a " />
+ </div>
+ <div id="log">
+ </div>
+
+ <script type="text/javascript">
+ test(function(){
+ var element = document.getElementById('type_support');
+ assert_equals(element.type, 'url');
+ }, 'url type supported on input element');
+
+ test(function(){
+ var element = document.getElementById('set_value_LF');
+ element.value = 'a\u000Aa';
+ assert_equals(element.value, 'aa');
+
+ element = document.getElementById('set_value_CR');
+ element.value = 'a\u000Da';
+ assert_equals(element.value, 'aa');
+
+ element = document.getElementById('set_value_CRLF');
+ element.value = 'a\u000D\u000Aa';
+ assert_equals(element.value, 'aa');
+ }, 'The value must not be set with "LF" (U+000A) or "CR" (U+000D)');
+
+ test(function(){
+ var element = document.getElementById('value_with_CRLF');
+ assert_equals(element.value, 'aa');
+ }, 'The value sanitization algorithm is as follows: Strip line breaks from the value');
+
+ test(function(){
+ var element = document.getElementById('value_with_leading_trailing_white_space');
+ assert_equals(element.value, 'aa');
+
+ element = document.getElementById('value_with_leading_trailing_inner_white_space');
+ assert_equals(element.value, 'a a');
+ }, 'The value sanitization algorithm is as follows: Strip leading and trailing whitespace from the value.');
+ </script>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/forms/the-input-element/valueMode.html b/testing/web-platform/tests/html/semantics/forms/the-input-element/valueMode.html
new file mode 100644
index 000000000..709c176dd
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/the-input-element/valueMode.html
@@ -0,0 +1,72 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Input element value mode</title>
+<link rel="author" title="Denis Ah-Kang" href="mailto:denis@w3.org">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<script>
+ var types = [
+ { type: "hidden", mode: "default" },
+ { type: "text", mode: "value", sanitizedValue: "foo" },
+ { type: "search", mode: "value", sanitizedValue: "foo" },
+ { type: "tel", mode: "value", sanitizedValue: "foo" },
+ { type: "url", mode: "value", sanitizedValue: "foo" },
+ { type: "email", mode: "value", sanitizedValue: "foo" },
+ { type: "password", mode: "value", sanitizedValue: "foo" },
+ { type: "datetime-local", mode: "value", sanitizedValue: "" },
+ { type: "date", mode: "value", sanitizedValue: "" },
+ { type: "month", mode: "value", sanitizedValue: "" },
+ { type: "week", mode: "value", sanitizedValue: "" },
+ { type: "time", mode: "value", sanitizedValue: "" },
+ { type: "number", mode: "value", sanitizedValue: "" },
+ { type: "range", mode: "value", sanitizedValue: "50" },
+ { type: "color", mode: "value", sanitizedValue: "#000000" },
+ { type: "checkbox", mode: "default/on" },
+ { type: "radio", mode: "default/on" },
+ { type: "submit", mode: "default" },
+ { type: "image", mode: "default" },
+ { type: "reset", mode: "default" },
+ { type: "button", mode: "default" }
+ ];
+ for (var i = 0; i < types.length; i++) {
+ test(function() {
+ var input = document.createElement("input"),
+ expected;
+ input.type = types[i].type;
+ input.value = "foo";
+ switch(types[i].mode) {
+ case "default":
+ expected = "";
+ break;
+ case "default/on":
+ expected = "on";
+ break;
+ case "value":
+ expected = types[i].sanitizedValue;
+ break;
+ }
+ assert_equals(input.value, expected);
+ }, "value IDL attribute of input type " + types[i].type + " without value attribute");
+
+ test(function() {
+ var input = document.createElement("input"),
+ expected;
+ input.type = types[i].type;
+ input.setAttribute("value", "bar");
+ input.value = "foo";
+ switch(types[i].mode) {
+ case "default":
+ expected = "bar";
+ break;
+ case "default/on":
+ expected = "bar";
+ break;
+ case "value":
+ expected = types[i].sanitizedValue;
+ break;
+ }
+ assert_equals(input.value, expected);
+ }, "value IDL attribute of input type " + types[i].type + " with value attribute");
+ }
+</script>
diff --git a/testing/web-platform/tests/html/semantics/forms/the-input-element/week.html b/testing/web-platform/tests/html/semantics/forms/the-input-element/week.html
new file mode 100644
index 000000000..e06b67889
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/the-input-element/week.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Form input type=week</title>
+<link rel="author" title="Denis Ah-Kang" href="mailto:denis@w3.org">
+<link rel=help href="https://html.spec.whatwg.org/multipage/#weeks">
+<link rel=help href="https://html.spec.whatwg.org/multipage/#week-state-(type=week)">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<script>
+ var weeks = [
+ {value: "", expected: "", testname: "empty value"},
+ {value: "2014-W52", expected: "2014-W52", testname: "Valid value: Value should be 2014-W52"},
+ {value: "2014-W53", expected: "", testname: "2014 has 52 weeks: Value should be empty"},
+ {value: "2015-W53", expected: "2015-W53", testname: "2015 has 53 weeks: Value should be 2015-W53"},
+ {value: "2014", expected: "", testname: "Invalid value: year only"},
+ {value: "2014W", expected: "", testname: "Invalid value: no week number"},
+ {value: "2014W52", expected: "", testname: "Invalid value: no '-' (U+002D)"},
+ {value: "-W52", expected: "", testname: "Invalid value: yearless week"},
+ {value: "W52", expected: "", testname: "Invalid value: yearless week and no '-' (U+002D)"},
+ {value: "2014-W03", attributes: { min: "2014-W02" }, expected: "2014-W03", testname: "Value >= min attribute"},
+ {value: "2014-W01", attributes: { min: "2014-W02" }, expected: "2014-W02", testname: "Value < min attribute"},
+ {value: "2014-W10", attributes: { max: "2014-W11" }, expected: "2014-W10", testname: "Value <= max attribute"},
+ {value: "2014-W12", attributes: { max: "2014-W11" }, expected: "2014-W11", testname: "Value > max attribute"}
+ ];
+ for (var i = 0; i < weeks.length; i++) {
+ var w = weeks[i];
+ test(function() {
+ var input = document.createElement("input");
+ input.type = "week";
+ input.value = w.value;
+ for(var attr in w.attributes) {
+ input[attr] = w.attributes[attr];
+ }
+ assert_equals(input.value, w.expected);
+ }, w.testname);
+ }
+</script>
diff --git a/testing/web-platform/tests/html/semantics/forms/the-keygen-element/.gitkeep b/testing/web-platform/tests/html/semantics/forms/the-keygen-element/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/the-keygen-element/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/forms/the-label-element/.gitkeep b/testing/web-platform/tests/html/semantics/forms/the-label-element/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/the-label-element/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/forms/the-label-element/label-attributes.html b/testing/web-platform/tests/html/semantics/forms/the-label-element/label-attributes.html
new file mode 100644
index 000000000..826533e0c
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/the-label-element/label-attributes.html
@@ -0,0 +1,137 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>HTML Test: The label element</title>
+<link rel="author" title="Intel" href="http://www.intel.com/">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<form id="fm" style="display:none">
+ <label id="lbl0" for="test0"></label>
+ <b id="test0"></b>
+
+ <input id="test1"></input>
+
+ <label id="lbl1">
+ <a id="test2"></a>
+ <div><input id="test3"></div>
+ <input id="test4">
+ </label>
+
+ <label id="lbl2" for="testx">
+ <input id="test5">
+ </label>
+
+ <label id="lbl3" for="test6">
+ <b id="test6"></b>
+ <input id="test6" class="class1">
+ </label>
+
+ <label id="lbl4" for="">
+ <input id="" class="class2">
+ </label>
+
+ <label id="lbl5" for="test7"></label>
+ <input id="test7">
+</form>
+
+<label id="lbl6" for="test7"></label>
+
+<script>
+
+ //control attribute
+ test(function () {
+ assert_not_equals(document.getElementById("lbl0").control, document.getElementById("test0"),
+ "An element that's not a labelable element can't be a label element's labeled control.");
+ assert_equals(document.getElementById("lbl0").control, null,
+ "A label element whose 'for' attribute doesn't reference any labelable element shouldn't have any labeled control.");
+ }, "A label element with a 'for' attribute should only be associated with a labelable element.");
+
+ test(function () {
+ var label = document.createElement("label");
+ label.htmlFor = "test1";
+ assert_not_equals(label.control, document.getElementById("test1"),
+ "A label element not in a document should not label an element in a document.");
+ document.body.appendChild(label);
+ assert_equals(label.control, document.getElementById("test1"));
+ label.remove();
+ }, "A label element not in a document can not label any element in the document.");
+
+ test(function () {
+ assert_equals(document.getElementById("lbl1").control, document.getElementById("test3"),
+ "The first labelable descendant of a label element should be its labeled control.");
+
+ var input = document.createElement("input");
+ document.getElementById("lbl1").insertBefore(input, document.getElementById("test2"));
+ assert_equals(document.getElementById("lbl1").control, input,
+ "The first labelable descendant of a label element in tree order should be its labeled control.");
+ input.remove();
+ }, "The labeled control for a label element that has no 'for' attribute is the first labelable element which is a descendant of that label element.");
+
+ test(function () {
+ assert_equals(document.getElementById("lbl2").control, null,
+ "The label's 'control' property should return null if its 'for' attribute points to an inexistent element.");
+ }, "The 'for' attribute points to an inexistent id.");
+
+ test(function () {
+ assert_equals(document.getElementById("lbl3").control, null, "The label should have no control associated.");
+ assert_equals(document.querySelector(".class1").labels.length, 0);
+ }, "A non-control follows by a control with same ID.");
+
+ test(function () {
+ assert_equals(document.getElementById("lbl4").control, null,
+ "A label element with an empty 'for' attribute should not associate with anything.");
+ }, "The 'for' attribute is an empty string.");
+
+ //labels attribute
+ test(function () {
+ var labels = document.getElementById("test7").labels;
+ assert_true(labels instanceof NodeList,
+ "A form control's 'labels' property should be an instance of a NodeList.");
+ assert_equals(labels.length, 2,
+ "The number of labels associated with a form control should be the number of label elements for which it is a labeled control.");
+ assert_array_equals(labels, [document.getElementById("lbl5"), document.getElementById("lbl6")],
+ "The labels for a form control should be returned in tree order.");
+
+ var newLabel = document.createElement("label");
+ newLabel.htmlFor = "test7";
+ document.getElementById("fm").insertBefore(newLabel, document.getElementById("lbl0"));
+ assert_array_equals(document.getElementById("test7").labels, [newLabel, document.getElementById("lbl5"), document.getElementById("lbl6")],
+ "The labels for a form control should be returned in tree order.");
+ newLabel.remove();
+ }, "A form control has multiple labels.");
+
+ test(function () {
+ var labels = document.getElementById("test3").labels;
+ assert_true(labels instanceof NodeList, "A form control's 'labels' property should be an instance of a NodeList.");
+ assert_equals(labels.length, 1, "The form control has an ancestor with no explicit associated label, and is the first labelable descendant.");
+ }, "A form control has an implicit label.");
+
+ test(function () {
+ var labels = document.getElementById("test4").labels;
+ assert_true(labels instanceof NodeList, "A form control's 'labels' property should be an instance of a NodeList.");
+ assert_equals(labels.length, 0, "The form control has an ancestor with no explicit associated label, but is *not* the first labelable descendant");
+ }, "A form control has no label 1.");
+
+ test(function () {
+ assert_equals(document.getElementById("test5").labels.length, 0,
+ "The number of labels should be 0 if the form control has an ancestor label element that the for attribute points to another control.");
+ assert_equals(document.getElementById("lbl2").control, null,
+ "The labeled cotrol should be associated with the control whose ID is equal to the value of the 'for' attribute.");
+ }, "A form control has no label 2.");
+
+ // form attribute
+ test(function () {
+ assert_equals(document.getElementById("lbl0").form, null,
+ "The 'form' property for a label should return null if label.control is null.");
+ }, "A label in a form without a control");
+
+ test(function () {
+ assert_equals(document.getElementById("lbl6").form, document.getElementById("fm"),
+ "The 'form' property for a label should return label.control.form.");
+ }, "A label outside a form with a control inside the form");
+
+ // htmlFor attribute
+ test(function () {
+ assert_equals(document.getElementById("lbl2").htmlFor, "testx");
+ }, "A label's htmlFor attribute must reflect the for content attribute");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/forms/the-label-element/labelable-elements.html b/testing/web-platform/tests/html/semantics/forms/the-label-element/labelable-elements.html
new file mode 100644
index 000000000..7bbb0b395
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/the-label-element/labelable-elements.html
@@ -0,0 +1,156 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>HTML Test: labelable elements</title>
+<link rel="author" title="Intel" href="http://www.intel.com/">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<form style="display:none">
+ <output id="testoutput"></output>
+ <label id="lbl0" for="testoutput"></label>
+ <progress id="testprogress"></progress>
+ <label id="lbl1" for="testprogress"></label>
+ <select id="testselect"></select>
+ <label id="lbl2" for="testselect"></label>
+ <textarea id="testarea"></textarea>
+ <label id="lbl3" for="testarea"></label>
+ <button id="testButton"></button>
+ <label id="lbl4" for="testButton"></label>
+ <input type="hidden" id="testHidden">
+ <label id="lbl5" for="testHidden"></label>
+ <input type="radio" id="testRadio">
+ <label id="lbl6" for="testRadio"></label>
+ <keygen id="testkeygen">
+ <label id="lbl7" for="testkeygen"></label>
+ <meter id="testmeter"></meter>
+ <label id="lbl8" for="testmeter"></label>
+
+ <fieldset id="testfieldset"></fieldset>
+ <label id="lbl9" for="testfieldset"></label>
+ <label id="testlabel"></label>
+ <label id="lbl10" for="testlabel"></label>
+ <object id="testobject"></object>
+ <label id="lbl11" for="testobject"></label>
+ <img id="testimg">
+ <label id="lbl12" for="testimg"></label>
+</form>
+
+<script>
+function testLabelsAttr(formElementId, labelElementId, hasLabels) {
+ var elem = document.getElementById(formElementId);
+ if (labelElementId) {
+ assert_equals(elem.labels.length, 1);
+ assert_equals(elem.labels[0].id, labelElementId);
+ } else {
+ assert_equals(elem.labels.length, 0);
+ }
+}
+
+test(function() {
+ assert_equals(document.getElementById("lbl0").control.id, "testoutput", "An output element should be labelable.");
+}, "Check if the output element is a labelable element");
+
+test(function() {
+ testLabelsAttr("testoutput", "lbl0");
+}, "Check if the output element can access 'labels'");
+
+test(function() {
+ assert_equals(document.getElementById("lbl1").control.id, "testprogress", "A progress element should be labelable.");
+}, "Check if the progress element is a labelable element");
+
+test(function() {
+ testLabelsAttr("testprogress", "lbl1");
+}, "Check if the progress element can access 'labels'");
+
+test(function() {
+ assert_equals(document.getElementById("lbl2").control.id, "testselect", "A select element should be labelable.");
+}, "Check if the select element is a labelable element");
+
+test(function() {
+ testLabelsAttr("testselect", "lbl2");
+}, "Check if the select element can access 'labels'");
+
+test(function() {
+ assert_equals(document.getElementById("lbl3").control.id, "testarea", "A textarea element should be labelable.");
+}, "Check if the textarea element is a labelable form-element");
+
+test(function() {
+ testLabelsAttr("testarea", "lbl3");
+}, "Check if the textarea element can access 'labels'");
+
+test(function() {
+ assert_equals(document.getElementById("lbl4").control.id, "testButton", "A button element should be labelable.");
+}, "Check if the button element is a labelable element");
+
+test(function() {
+ testLabelsAttr("testButton", "lbl4");
+}, "Check if the button element can access 'labels'");
+
+test(function() {
+ assert_equals(document.getElementById("lbl5").control, null, "An input element in hidden state should not be labelable.");
+}, "Check if the hidden input element is not a labelable element.");
+
+test(function() {
+ testLabelsAttr("testHidden", null);
+}, "Check if the hidden input element can access 'labels'");
+
+test(function() {
+ assert_equals(document.getElementById("lbl6").control.id, "testRadio", "An input element in radio state should be labelable.");
+}, "Check if the input element in radio state is a labelable element");
+
+test(function() {
+ testLabelsAttr("testRadio", "lbl6");
+}, "Check if the input element in radio state can access 'labels'");
+
+test(function() {
+ assert_equals(document.getElementById("lbl7").control.id, "testkeygen", "A keygen element should be labelable.");
+}, "Check if the keygen element is a labelable element");
+
+test(function() {
+ testLabelsAttr("testkeygen", "lbl7");
+}, "Check if the keygen element can access 'labels'");
+
+test(function() {
+ assert_equals(document.getElementById("lbl8").control.id, "testmeter", "A meter element should be labelable.");
+}, "Check if the meter element is a labelable element");
+
+test(function() {
+ testLabelsAttr("testmeter", "lbl8");
+}, "Check if the meter element can access 'labels'");
+
+test(function() {
+ assert_not_equals(document.getElementById("lbl9").control, document.getElementById("testfieldset"));
+ assert_equals(document.getElementById("lbl9").control, null, "A fieldset element should not be labelable.");
+}, "Check if the fieldset element is not a labelable element");
+
+test(function() {
+ assert_equals(document.getElementById("testfieldset").labels, undefined);
+}, "Check if the fieldset element can access 'labels'");
+
+test(function() {
+ assert_not_equals(document.getElementById("lbl9").control, document.getElementById("testlabel"));
+ assert_equals(document.getElementById("lbl10").control, null, "A label element should not be labelable.");
+}, "Check if the label element is not a labelable element");
+
+test(function() {
+ assert_equals(document.getElementById("testlabel").labels, undefined);
+}, "Check if the label element can access 'labels'");
+
+test(function() {
+ assert_not_equals(document.getElementById("lbl9").control, document.getElementById("testobject"));
+ assert_equals(document.getElementById("lbl11").control, null, "An object element should not be labelable.");
+}, "Check if the object element is not a labelable element");
+
+test(function() {
+ assert_equals(document.getElementById("testobject").labels, undefined);
+}, "Check if the object element can access 'labels'");
+
+test(function() {
+ assert_not_equals(document.getElementById("lbl9").control, document.getElementById("testimg"));
+ assert_equals(document.getElementById("lbl12").control, null, "An img element should not be labelable.");
+}, "Check if the img element is not a labelable element");
+
+test(function() {
+ assert_equals(document.getElementById("lbl9").labels, undefined);
+}, "Check if the img element can access 'labels'");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/forms/the-legend-element/.gitkeep b/testing/web-platform/tests/html/semantics/forms/the-legend-element/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/the-legend-element/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/forms/the-legend-element/legend-form.html b/testing/web-platform/tests/html/semantics/forms/the-legend-element/legend-form.html
new file mode 100644
index 000000000..b127164ae
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/the-legend-element/legend-form.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>HTMLLegendElement Test: form</title>
+<link rel="author" title="Intel" href="http://www.intel.com/">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<div id="log"></div>
+
+<div style="display:none">
+ <form id="testform">
+ <legend id="testlegend">radio</legend>
+ </form>
+</div>
+
+<div style="display:none">
+ <form id="testformWithFieldSet">
+ <fieldset>
+ <legend id="legendWithFieldSet">radio</legend>
+ </fieldset>
+ </form>
+</div>
+<script>
+test(function () {
+ var legendEle = document.getElementById("legendWithFieldSet");
+ assert_not_equals(legendEle.form, null);
+ assert_equals(legendEle.form, document.getElementById("testformWithFieldSet"));
+}, "Check if legend.form returns its parent when it's inside a fieldset");
+test(function () {
+ var legendEle = document.getElementById("testlegend");
+ assert_equals(legendEle.form, null);
+}, "Check if legend.form return null when legend has no fieldset element as its parent");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/forms/the-meter-element/.gitkeep b/testing/web-platform/tests/html/semantics/forms/the-meter-element/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/the-meter-element/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/forms/the-meter-element/meter.html b/testing/web-platform/tests/html/semantics/forms/the-meter-element/meter.html
new file mode 100644
index 000000000..1c1ce4f18
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/the-meter-element/meter.html
@@ -0,0 +1,250 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>The meter element</title>
+ <link rel="author" title="Tomoyuki SHIMIZU" href="mailto:tomoyuki.labs@gmail.com">
+ <link rel="author" title="Denis Ah-Kang" href="mailto:denis@w3.org">
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-meter-element">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+ <body>
+ <h1>Meter Element</h1>
+ <div id="log"></div>
+ <div style="display: none;">
+ <meter id="meter_illegal_value" value="abc"></meter>
+ <meter id="meter_without_min" value="-10"></meter>
+ <meter id="meter_without_max" value="10"></meter>
+ <meter id="meter_min_without_max_1" value="10" min="-3.1"></meter>
+ <meter id="meter_min_without_max_2" value="210" min="12.1"></meter>
+ <meter id="meter_max_without_min_1" value="-10" max="-5342.55"></meter>
+ <meter id="meter_max_without_min_2" value="210" max="-9.9"></meter>
+ <meter id="meter_illegal_min" value="-2" min="hugfe"></meter>
+ <meter id="meter_illegal_max" value="2.4" max="min"></meter>
+ <meter id="meter_illegal_low_with_min" value="-20" min="-10.3" low="ahuge"></meter>
+ <meter id="meter_illegal_high_with_max" value="2.4" high="old" max="1.5"></meter>
+ <meter id="meter_smaller_than_min" value="-10" min="4.5"></meter>
+ <meter id="meter_larger_than_max" value="2345.53" max="52.02"></meter>
+ <meter id="meter_default_low_and_high_1" value="40" min="-12.3" max="3.4"></meter>
+ <meter id="meter_default_low_and_high_2" value="23"></meter>
+ <meter id="meter_low_smaller_than_min" value="-4" min="12.3" low="34"></meter>
+ <meter id="meter_low_larger_than_max" value="-1" min="-50" low="-5" max="-34.5"></meter>
+ <meter id="meter_high_smaller_than_min" value="-4" min="12.3" high="34"></meter>
+ <meter id="meter_high_larger_than_max" value="-1" min="-50" high="-5" max="-34.5"></meter>
+ <meter id="meter_high_smaller_than_low" value="-9" min="-20" low="-10.3" high="-15.2" max="-2"></meter>
+ <meter id="meter_low_without_min" value="-1" low="-5"></meter>
+ <meter id="meter_high_without_max" value="50000" high="4"></meter>
+ <meter id="meter_optimum_smaller_than_min" value="-8" optimum="-4"></meter>
+ <meter id="meter_optimum_larger_than_max" value="324" optimum="4.6"></meter>
+ <meter id="meter_default_optimum" value="10" min="-132.35" max="33.423"></meter>
+ </div>
+ <script>
+ var meters = [
+ {value: 0, expectedValue: 0, expectedMin: 0, expectedMax: 1.0, expectedLow: 0, expectedHigh: 1.0, expectedOptimum: 0.5, testname: "Default values"},
+ {value: 3, expectedValue: 3, min: -10.1, expectedMin: -10.1, max: 10.1, expectedMax: 10.1, low: -9.1, expectedLow: -9.1, high: 9.1, expectedHigh: 9.1, optimum: 3, expectedOptimum: 3, testname: "Setting values to min, max, low, high and optimum"},
+ {value: 0, expectedValue: 0, min: 0, expectedMin: 0, max: -1.0, expectedMax: 0, expectedLow: 0, expectedHigh: 0, expectedOptimum: 0, testname: "max < min"},
+ {value: 0, expectedValue: 10, min: 10, expectedMin: 10, max: 20, expectedMax: 20, expectedLow: 10, expectedHigh: 20, expectedOptimum: 15, testname: "value < min"},
+ {value: 30, expectedValue: 20, min: 10, expectedMin: 10, max: 20, expectedMax: 20, expectedLow: 10, expectedHigh: 20, expectedOptimum: 15, testname: "value > max"},
+ {value: 15, expectedValue: 15, min: 10, expectedMin: 10, max: 20, expectedMax: 20, low: 5, expectedLow: 10, expectedHigh: 20, expectedOptimum: 15, testname: "low < min"},
+ {value: 15, expectedValue: 15, min: 10, expectedMin: 10, max: 20, expectedMax: 20, low: 25, expectedLow: 20, expectedHigh: 20, expectedOptimum: 15, testname: "low > max"},
+ {value: 15, expectedValue: 15, min: 10, expectedMin: 10, max: 20, expectedMax: 20, low: 12, expectedLow: 12, high: 10, expectedHigh: 12, expectedOptimum: 15, testname: "high < low"},
+ {value: 15, expectedValue: 15, min: 10, expectedMin: 10, max: 20, expectedMax: 20, low: 10, expectedLow: 10, high: 22, expectedHigh: 20, expectedOptimum: 15, testname: "high > max"},
+ {value: 15, expectedValue: 15, min: 10, expectedMin: 10, max: 20, expectedMax: 20, expectedLow: 10, expectedHigh: 20, optimum: 9, expectedOptimum: 10, testname: "optimum < min"},
+ {value: 15, expectedValue: 15, min: 10, expectedMin: 10, max: 20, expectedMax: 20, expectedLow: 10, expectedHigh: 20, optimum: 21, expectedOptimum: 20, testname: "optimum > max"}
+ ];
+ for (var i = 0; i < meters.length; i++) {
+ var m = meters[i];
+ test(function() {
+ var meter = document.createElement("meter");
+ meter.value = m.value;
+ if (m.min) meter.min= m.min;
+ if (m.max) meter.max = m.max;
+ if (m.low) meter.low = m.low;
+ if (m.high) meter.high = m.high;
+ if (m.optimum) meter.optimum = m.optimum;
+ assert_equals(meter.value, m.expectedValue, "meter value");
+ assert_equals(meter.min, m.expectedMin, "min value");
+ assert_equals(meter.max, m.expectedMax, "max value");
+ assert_equals(meter.low, m.expectedLow, "low value");
+ assert_equals(meter.high, m.expectedHigh, "high value");
+ assert_equals(meter.optimum, m.expectedOptimum, "optimum value");
+ }, m.testname);
+ }
+ test(function() {
+ var meter = document.createElement("meter");
+ assert_throws(new TypeError(), function() { meter.value = "foobar"; }, "value attribute");
+ assert_throws(new TypeError(), function() { meter.min = "foobar"; }, "min attribute");
+ assert_throws(new TypeError(), function() { meter.max = "foobar"; }, "max attribute");
+ assert_throws(new TypeError(), function() { meter.low = "foobar"; }, "low attribute");
+ assert_throws(new TypeError(), function() { meter.high = "foobar"; }, "high attribute");
+ assert_throws(new TypeError(), function() { meter.optimum = "foobar"; }, "optimum attribute");
+ }, "Invalid floating-point number values");
+
+ </script>
+ <script type="text/javascript">
+ test(function() {
+ assert_equals(document.getElementById('meter_illegal_value').value, 0);
+ }, "value must be 0 when a string is given");
+
+ test(function() {
+ assert_equals(document.getElementById('meter_without_min').min, 0);
+ }, "default value of min is 0");
+
+ test(function() {
+ assert_equals(document.getElementById('meter_without_min').value, 0);
+ }, "If min is not specified and value is smaller than the default value of min (i.e. 0), the actual value must be 0");
+
+ test(function() {
+ assert_equals(document.getElementById('meter_without_max').max, 1.0);
+ }, "default value of max is 1.0");
+
+ test(function() {
+ assert_equals(document.getElementById('meter_without_max').value, 1.0);
+ }, "If max is not specified and value is larger than the default value of max (i.e. 1.0), the actual value must be 1.0");
+
+ test(function() {
+ assert_equals(document.getElementById('meter_min_without_max_1').max, 1.0);
+ }, "If a value smaller than 1.0 is given to min and max is not specified, max must be the same value as its default value (i.e. 1.0)");
+
+ test(function() {
+ assert_equals(document.getElementById('meter_min_without_max_1').value, 1.0);
+ }, "If a value smaller than 1.0 is given to min, max is not specified, and value is larger than the default value of max (i.e. 1.0), the actual value must be 1.0");
+
+ test(function() {
+ assert_equals(document.getElementById('meter_min_without_max_2').max, 12.1);
+ }, "If a value larger than or equal to 1.0 is given to min and max is not specified, max must be the same value as min");
+
+ test(function() {
+ assert_equals(document.getElementById('meter_min_without_max_2').value, 12.1);
+ }, "If a value larger than or equal to 1.0 is given to min and max is not specified, the actual value must be the same value as min");
+
+ test(function() {
+ assert_equals(document.getElementById('meter_max_without_min_1').min, 0);
+ }, "If a value smaller than 0 is given to max and min is not specified, min must be be the same value as its default value (i.e. 0)");
+
+ test(function() {
+ assert_equals(document.getElementById('meter_max_without_min_1').max, 0);
+ }, "If a value smaller than 0 is given to max and min is not specified, max must be be the same value as the default value of min (i.e. 0)");
+
+ test(function() {
+ assert_equals(document.getElementById('meter_max_without_min_1').value, 0);
+ }, "If a value smaller than 0 is given to max and min is not specified, the actual value must be be the same value as the default value of min (i.e. 0)");
+
+ test(function() {
+ assert_equals(document.getElementById('meter_max_without_min_2').max, 0);
+ }, "If a value larger than or equal to 0 is given to max and min is not specified, max must be the same value as the default value of min (i.e. 0)");
+
+ test(function() {
+ assert_equals(document.getElementById('meter_max_without_min_2').min, 0);
+ }, "If a value larger than or equal to 0 is given to max and min is not specified, min must be the same value as its default value (i.e. 0)");
+
+ test(function() {
+ assert_equals(document.getElementById('meter_max_without_min_2').value, 0);
+ }, "If a value larger than or equal to 0 is given to max and min is not specified, the actual value must be the same value as the default value of min (i.e. 0)");
+
+ test(function() {
+ assert_equals(document.getElementById('meter_illegal_min').min, 0);
+ }, "min must be 0 when a string is given");
+
+ test(function() {
+ assert_equals(document.getElementById('meter_illegal_min').value, 0);
+ }, "If a string is given to min and value is smaller than the default value of min (i.e. 0), the actual value must be 0");
+
+ test(function() {
+ assert_equals(document.getElementById('meter_illegal_max').max, 1.0);
+ }, "max must be 1.0 when a string is given");
+
+ test(function() {
+ assert_equals(document.getElementById('meter_illegal_max').value, 1.0);
+ }, "If a string is given to max and value is larger than the default value of min (i.e. 1.0), the actual value must be 1.0");
+
+ test(function() {
+ assert_equals(document.getElementById('meter_illegal_low_with_min').low, -10.3);
+ }, "giving a string to low must not affect the actual value");
+
+ test(function() {
+ assert_equals(document.getElementById('meter_illegal_high_with_max').high, 1.5);
+ }, "high must equal max when a string is given to high");
+
+ test(function() {
+ assert_equals(document.getElementById('meter_illegal_high_with_max').value, 1.5);
+ }, "giving a string to high must not affect the actual value");
+
+ test(function() {
+ assert_equals(document.getElementById('meter_smaller_than_min').value, 4.5);
+ }, "value must not be smaller than min");
+
+ test(function() {
+ assert_equals(document.getElementById('meter_larger_than_max').value, 52.02);
+ }, "value must not be larger than max");
+
+ test(function() {
+ var e = document.getElementById('meter_default_low_and_high_1');
+ assert_array_equals([e.low,e.high], [-12.3,3.4]);
+ }, "default low and high values equal min and max, respectively");
+
+ test(function() {
+ var e = document.getElementById('meter_default_low_and_high_2');
+ assert_array_equals([e.low,e.high], [0,1.0]);
+ }, "default low and high values equal 0 and 1.0 respectively, if both low and high are not specified");
+
+ test(function() {
+ var e = document.getElementById('meter_low_smaller_than_min');
+ assert_array_equals([e.low,e.min,e.value], [12.3,12.3,12.3]);
+ }, "low must not be smaller than min");
+
+ test(function() {
+ var e = document.getElementById('meter_low_larger_than_max');
+ assert_array_equals([e.low,e.max,e.value], [-34.5,-34.5,-34.5]);
+ }, "low must not be larger than max");
+
+ test(function() {
+ var e = document.getElementById('meter_high_smaller_than_min');
+ assert_array_equals([e.high,e.min,e.value], [12.3,12.3,12.3]);
+ }, "high must not be smaller than min");
+
+ test(function() {
+ var e = document.getElementById('meter_high_larger_than_max');
+ assert_array_equals([e.high,e.max,e.value], [-34.5,-34.5,-34.5]);
+ }, "high must not be larger than max");
+
+ test(function() {
+ var e = document.getElementById('meter_low_without_min');
+ assert_array_equals([e.low,e.min,e.value], [0,0,0]);
+ }, "If min is not specified, low must not be smaller than default value of min (i.e. 0)");
+
+ test(function() {
+ var e = document.getElementById('meter_high_smaller_than_low');
+ assert_array_equals([e.low,e.high,e.value], [-10.3,-10.3,-9]);
+ }, "If a value smaller than low is given to high, it must be set to the same value as low");
+
+ test(function() {
+ var e = document.getElementById('meter_high_without_max');
+ assert_array_equals([e.high,e.value], [1.0,1.0]);
+ }, "If max is not specified, high must not be larger than default value of max (i.e. 1.0)");
+
+ test(function() {
+ assert_equals(document.getElementById('meter_optimum_smaller_than_min').optimum, 0);
+ }, "optimum smaller than min");
+
+ test(function() {
+ var e = document.getElementById('meter_optimum_smaller_than_min');
+ assert_array_equals([e.min,e.value], [0,0]);
+ }, "optimum (smaller than min) must not affect min and the actual value");
+
+ test(function() {
+ assert_equals(document.getElementById('meter_optimum_larger_than_max').optimum, 1.0);
+ }, "optimum smaller than max");
+
+ test(function() {
+ var e = document.getElementById('meter_optimum_larger_than_max');
+ assert_array_equals([e.max,e.value], [1.0,1.0]);
+ }, "optimum (larger than max) must not affect max and the actual value");
+
+ test(function() {
+ var e = document.getElementById('meter_default_optimum');
+ assert_equals(e.optimum, (e.max + e.min) / 2);
+ }, "default optimum value is the midpoint between min and max");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/forms/the-optgroup-element/.gitkeep b/testing/web-platform/tests/html/semantics/forms/the-optgroup-element/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/the-optgroup-element/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/forms/the-optgroup-element/optgroup-disabled-manual.html b/testing/web-platform/tests/html/semantics/forms/the-optgroup-element/optgroup-disabled-manual.html
new file mode 100644
index 000000000..ca8c6cda8
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/the-optgroup-element/optgroup-disabled-manual.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>HTMLOptGroupElement Test: disabled</title>
+<meta name="flags" content="interact">
+<link rel="author" title="Intel" href="http://www.intel.com/">
+
+<form>
+ <select>
+ <optgroup label="8.01" disabled>
+ <option value="8.01.1">Lecture 01: Powers of Ten</option>
+ <option value="8.01.2">Lecture 02: 1D Kinematics</option>
+ <option value="8.01.3">Lecture 03: Vectors</option>
+ </optgroup>
+ <optgroup label="8.02">
+ <option value="8.02.1">Lecture 01: What holds our world together?</option>
+ <option value="8.02.2">Lecture 02: Electric Field</option>
+ <option value="8.02.3">Lecture 03: Electric Flux</option>
+ </optgroup>
+ </select>
+</form>
+
+<h2>Description</h2>
+<p>
+ This test validates that an optgroup element is disabled if its disabled attribute is present.
+</p>
+
+<h2>Test steps:</h2>
+<ol>
+ <li>
+ Click the select flag to select section '8.01'
+ </li>
+</ol>
+
+<h2>Result:</h2>
+<p>Click the select flag and try to select section 8.01, test passes if the section 8.01 is disable to be selected</p>
diff --git a/testing/web-platform/tests/html/semantics/forms/the-option-element/.gitkeep b/testing/web-platform/tests/html/semantics/forms/the-option-element/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/the-option-element/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/forms/the-option-element/option-disabled-manual.html b/testing/web-platform/tests/html/semantics/forms/the-option-element/option-disabled-manual.html
new file mode 100644
index 000000000..25dfcc87a
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/the-option-element/option-disabled-manual.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>HTMLOptionElement Test: disabled</title>
+<meta name="flags" content="interact">
+<link rel="author" title="Intel" href="http://www.intel.com/">
+
+<div>
+ <select>
+ <option id="testOption1" text="Option1" >Option1</option>
+ <option id="testOption2" disabled >Option2</option>
+ <option id="testOption3" >Option3</option>
+ </select>
+</div>
+
+<h2>Description</h2>
+<p>
+ This test validates that an option element is disabled if its disabled attribute is present.
+</p>
+
+<h2>Test steps:</h2>
+<ol>
+ <li>
+ Click the select flag to select 'Option2'
+ </li>
+</ol>
+
+<h2>Result:</h2>
+<p>Test passes if not able to select 'Option2'</p>
diff --git a/testing/web-platform/tests/html/semantics/forms/the-option-element/option-form.html b/testing/web-platform/tests/html/semantics/forms/the-option-element/option-form.html
new file mode 100644
index 000000000..1a68b5c1c
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/the-option-element/option-form.html
@@ -0,0 +1,32 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>HTMLOptionElement.form</title>
+<link rel=author title="Sergey Alexandrov" href="mailto:splavgm@gmail.com">
+<link rel=help href="https://html.spec.whatwg.org/multipage/#dom-option-form">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<form id="form">
+ <select id="select">
+ <optgroup id="optgroup"></optgroup>
+ </select>
+</form>
+<div id=log></div>
+
+<script>
+test(function () {
+ var form = document.getElementById("form");
+ var select = document.getElementById("select");
+ var optgroup = document.getElementById("optgroup");
+
+ var o1 = document.createElement("option");
+ assert_equals(o1.form, null);
+
+ select.appendChild(o1);
+ assert_equals(o1.form, select.form);
+
+ var o2 = document.createElement("option");
+ select.appendChild(o2);
+ assert_equals(o2.form, select.form);
+
+}, "form");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/forms/the-option-element/option-label-value.js b/testing/web-platform/tests/html/semantics/forms/the-option-element/option-label-value.js
new file mode 100644
index 000000000..5c453f173
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/the-option-element/option-label-value.js
@@ -0,0 +1,82 @@
+function test_option(member) {
+ test(function() {
+ var option = document.createElement("option");
+ assert_equals(option[member], "");
+ }, "No children, no " + member);
+
+ test(function() {
+ var option = document.createElement("option");
+ option.setAttribute(member, "")
+ assert_equals(option[member], "");
+ }, "No children, empty " + member);
+
+ test(function() {
+ var option = document.createElement("option");
+ option.setAttribute(member, member)
+ assert_equals(option[member], member);
+ }, "No children, " + member);
+
+ test(function() {
+ var option = document.createElement("option");
+ option.setAttributeNS("http://www.example.com/", member, member)
+ assert_equals(option[member], "");
+ }, "No children, namespaced " + member);
+
+ test(function() {
+ var option = document.createElement("option");
+ option.appendChild(document.createTextNode(" child "));
+ assert_equals(option[member], "child");
+ }, "Single child, no " + member);
+
+ test(function() {
+ var option = document.createElement("option");
+ option.appendChild(document.createTextNode(" child "));
+ option.setAttribute(member, "")
+ assert_equals(option[member], "");
+ }, "Single child, empty " + member);
+
+ test(function() {
+ var option = document.createElement("option");
+ option.appendChild(document.createTextNode(" child "));
+ option.setAttribute(member, member)
+ assert_equals(option[member], member);
+ }, "Single child, " + member);
+
+ test(function() {
+ var option = document.createElement("option");
+ option.appendChild(document.createTextNode(" child "));
+ option.setAttributeNS("http://www.example.com/", member, member)
+ assert_equals(option[member], "child");
+ }, "Single child, namespaced " + member);
+
+ test(function() {
+ var option = document.createElement("option");
+ option.appendChild(document.createTextNode(" child "));
+ option.appendChild(document.createTextNode(" node "));
+ assert_equals(option[member], "child node");
+ }, "Two children, no " + member);
+
+ test(function() {
+ var option = document.createElement("option");
+ option.appendChild(document.createTextNode(" child "));
+ option.appendChild(document.createTextNode(" node "));
+ option.setAttribute(member, "")
+ assert_equals(option[member], "");
+ }, "Two children, empty " + member);
+
+ test(function() {
+ var option = document.createElement("option");
+ option.appendChild(document.createTextNode(" child "));
+ option.appendChild(document.createTextNode(" node "));
+ option.setAttribute(member, member)
+ assert_equals(option[member], member);
+ }, "Two children, " + member);
+
+ test(function() {
+ var option = document.createElement("option");
+ option.appendChild(document.createTextNode(" child "));
+ option.appendChild(document.createTextNode(" node "));
+ option.setAttributeNS("http://www.example.com/", member, member)
+ assert_equals(option[member], "child node");
+ }, "Two children, namespaced " + member);
+}
diff --git a/testing/web-platform/tests/html/semantics/forms/the-option-element/option-label.html b/testing/web-platform/tests/html/semantics/forms/the-option-element/option-label.html
new file mode 100644
index 000000000..f931b9622
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/the-option-element/option-label.html
@@ -0,0 +1,12 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>HTMLOptionElement.label</title>
+<link rel=author title=Ms2ger href="mailto:Ms2ger@gmail.com">
+<link rel=help href="https://html.spec.whatwg.org/multipage/#dom-option-label">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src=option-label-value.js></script>
+<div id=log></div>
+<script>
+test_option("label")
+</script>
diff --git a/testing/web-platform/tests/html/semantics/forms/the-option-element/option-selected.html b/testing/web-platform/tests/html/semantics/forms/the-option-element/option-selected.html
new file mode 100644
index 000000000..e18e90b85
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/the-option-element/option-selected.html
@@ -0,0 +1,61 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>HTMLOptionElement.selected</title>
+<link rel=author title="Corey Farwell" href="mailto:coreyf@rwell.org">
+<link rel=help href="https://html.spec.whatwg.org/multipage/#dom-option-selected">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+
+<script>
+test(function () {
+ var elem = document.createElement("option");
+ assert_equals(elem.selected, false);
+
+ elem.setAttribute("selected", "");
+ assert_equals(elem.selected, true);
+
+ elem.removeAttribute("selected");
+ assert_equals(elem.selected, false);
+
+ elem.defaultSelected = true
+ assert_equals(elem.selected, true);
+
+ elem.defaultSelected = false;
+ assert_equals(elem.selected, false);
+}, "not dirty");
+
+test(function () {
+ testDirty(true);
+}, "dirty, selected");
+
+test(function () {
+ testDirty(false);
+}, "dirty, not selected");
+
+function testDirty(isSelected) {
+ var elem = document.createElement("option");
+
+ elem.selected = isSelected; // After this assignment, dirtiness=true
+ assertDirty(elem, isSelected);
+
+ elem.selected = !isSelected; // Change the value, still dirty
+ assertDirty(elem, !isSelected);
+};
+
+function assertDirty(elem, expect) {
+ assert_equals(elem.selected, expect);
+
+ elem.setAttribute("selected", "");
+ assert_equals(elem.selected, expect);
+
+ elem.removeAttribute("selected");
+ assert_equals(elem.selected, expect);
+
+ elem.defaultSelected = true;
+ assert_equals(elem.selected, expect);
+
+ elem.defaultSelected = false;
+ assert_equals(elem.selected, expect);
+}
+</script>
diff --git a/testing/web-platform/tests/html/semantics/forms/the-option-element/option-text-backslash.html b/testing/web-platform/tests/html/semantics/forms/the-option-element/option-text-backslash.html
new file mode 100644
index 000000000..34bd0d368
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/the-option-element/option-text-backslash.html
@@ -0,0 +1,15 @@
+<!doctype html>
+<meta charset=EUC-JP>
+<title>Test for the backslash sign in option.text</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<div id=log></div>
+<select id=test><option>\</option></select>
+<script>
+test(function() {
+ var select = document.getElementById("test");
+ var option = select.firstChild;
+ assert_equals(option.text, "\\");
+ assert_equals(option.textContent, "\\");
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/forms/the-option-element/option-text-label.html b/testing/web-platform/tests/html/semantics/forms/the-option-element/option-text-label.html
new file mode 100644
index 000000000..9259aecf3
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/the-option-element/option-text-label.html
@@ -0,0 +1,23 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>HTMLOptionElement.text</title>
+<link rel=author title=Ms2ger href="mailto:Ms2ger@gmail.com">
+<link rel=help href="https://html.spec.whatwg.org/multipage/#dom-option-text">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+test(function() {
+ var option = document.createElement("option");
+ option.setAttribute("label", "label");
+ option.textContent = "text";
+ assert_equals(option.text, "text");
+}, "Option with non-empty label.");
+
+test(function() {
+ var option = document.createElement("option");
+ option.setAttribute("label", "");
+ option.textContent = "text";
+ assert_equals(option.text, "text");
+}, "Option with empty label.");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/forms/the-option-element/option-text-recurse.html b/testing/web-platform/tests/html/semantics/forms/the-option-element/option-text-recurse.html
new file mode 100644
index 000000000..cf854f526
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/the-option-element/option-text-recurse.html
@@ -0,0 +1,92 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>HTMLOptionElement.text</title>
+<link rel=author title=Ms2ger href="mailto:Ms2ger@gmail.com">
+<link rel=help href="https://html.spec.whatwg.org/multipage/#dom-option-text">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+test(function() {
+ var option = document.createElement("option");
+ option.appendChild(document.createElement("font"))
+ .appendChild(document.createTextNode(" font "));
+ assert_equals(option.text, "font");
+}, "option.text should recurse");
+
+test(function() {
+ var option = document.createElement("option");
+ option.appendChild(document.createTextNode(" before "));
+ option.appendChild(document.createElement("script"))
+ .appendChild(document.createTextNode(" script "));
+ option.appendChild(document.createTextNode(" after "));
+ assert_equals(option.text, "before after");
+}, "option.text should not recurse into HTML script elements");
+test(function() {
+ var option = document.createElement("option");
+ option.appendChild(document.createTextNode(" before "));
+ option.appendChild(document.createElementNS("http://www.w3.org/2000/svg", "script"))
+ .appendChild(document.createTextNode(" script "));
+ option.appendChild(document.createTextNode(" after "));
+ assert_equals(option.text, "before after");
+}, "option.text should not recurse into SVG script elements");
+test(function() {
+ var option = document.createElement("option");
+ option.appendChild(document.createTextNode(" before "));
+ option.appendChild(document.createElementNS("http://www.w3.org/1998/Math/MathML", "script"))
+ .appendChild(document.createTextNode(" script "));
+ option.appendChild(document.createTextNode(" after "));
+ assert_equals(option.text, "before script after");
+}, "option.text should recurse into MathML script elements");
+test(function() {
+ var option = document.createElement("option");
+ option.appendChild(document.createTextNode(" before "));
+ option.appendChild(document.createElementNS(null, "script"))
+ .appendChild(document.createTextNode(" script "));
+ option.appendChild(document.createTextNode(" after "));
+ assert_equals(option.text, "before script after");
+}, "option.text should recurse into null script elements");
+test(function() {
+ var option = document.createElement("option");
+ var span = option.appendChild(document.createElement("span"));
+ span.appendChild(document.createTextNode(" Some "));
+ span.appendChild(document.createElement("script"))
+ .appendChild(document.createTextNode(" script "));
+ option.appendChild(document.createTextNode(" Text "));
+ assert_equals(option.text, "Some Text");
+}, "option.text should work if a child of the option ends with a script");
+
+test(function() {
+ var script = document.createElement("script");
+ var option = script.appendChild(document.createElement("option"));
+ option.appendChild(document.createTextNode("text"));
+ assert_equals(option.text, "text");
+}, "option.text should work if the option is in an HTML script element");
+test(function() {
+ var script = document.createElementNS("http://www.w3.org/2000/svg", "script");
+ var option = script.appendChild(document.createElement("option"));
+ option.appendChild(document.createTextNode("text"));
+ assert_equals(option.text, "text");
+}, "option.text should work if the option is in an SVG script element");
+test(function() {
+ var script = document.createElementNS("http://www.w3.org/1998/Math/MathML", "script");
+ var option = script.appendChild(document.createElement("option"));
+ option.appendChild(document.createTextNode("text"));
+ assert_equals(option.text, "text");
+}, "option.text should work if the option is in a MathML script element");
+
+test(function() {
+ var option = document.createElement("option");
+ option.appendChild(document.createTextNode("te"));
+ option.appendChild(document.createComment("comment"));
+ option.appendChild(document.createTextNode("xt"));
+ assert_equals(option.text, "text");
+}, "option.text should ignore comment children");
+test(function() {
+ var option = document.createElement("option");
+ option.appendChild(document.createTextNode("te"));
+ option.appendChild(document.createProcessingInstruction("target", "data"));
+ option.appendChild(document.createTextNode("xt"));
+ assert_equals(option.text, "text");
+}, "option.text should ignore PI children");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/forms/the-option-element/option-text-spaces.html b/testing/web-platform/tests/html/semantics/forms/the-option-element/option-text-spaces.html
new file mode 100644
index 000000000..2c712655a
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/the-option-element/option-text-spaces.html
@@ -0,0 +1,75 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>HTMLOptionElement.text</title>
+<link rel=author title=Ms2ger href="mailto:Ms2ger@gmail.com">
+<link rel=help href="https://html.spec.whatwg.org/multipage/#dom-option-text">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+test(function() {
+ var spaces = ["\u0020", "\u0009", "\u000A", "\u000C", "\u000D"];
+ spaces.forEach(function(space) {
+ test(function() {
+ var option = document.createElement("option");
+ option.textContent = space + "text";
+ assert_equals(option.text, "text");
+ }, "option.text should strip leading space characters (" +
+ format_value(space) + ")");
+ });
+ spaces.forEach(function(space) {
+ test(function() {
+ var option = document.createElement("option");
+ option.textContent = "text" + space;
+ assert_equals(option.text, "text");
+ }, "option.text should strip trailing space characters (" +
+ format_value(space) + ")");
+ });
+ spaces.forEach(function(space) {
+ test(function() {
+ var option = document.createElement("option");
+ option.textContent = space + "text" + space;
+ assert_equals(option.text, "text");
+ }, "option.text should strip leading and trailing space characters (" +
+ format_value(space) + ")");
+ });
+ spaces.forEach(function(space) {
+ test(function() {
+ var option = document.createElement("option");
+ option.textContent = "before" + space + "after";
+ assert_equals(option.text, "before after");
+ }, "option.text should replace single internal space characters (" +
+ format_value(space) + ")");
+ });
+ spaces.forEach(function(space1) {
+ spaces.forEach(function(space2) {
+ test(function() {
+ var option = document.createElement("option");
+ option.textContent = "before" + space1 + space2 + "after";
+ assert_equals(option.text, "before after");
+ }, "option.text should replace multiple internal space characters (" +
+ format_value(space1) + ", " + format_value(space2) + ")");
+ });
+ });
+ test(function() {
+ var option = document.createElement("option");
+ option.textContent = "\u00a0text";
+ assert_equals(option.text, "\u00a0text");
+ }, "option.text should leave leading NBSP alone.");
+ test(function() {
+ var option = document.createElement("option");
+ option.textContent = "text\u00a0";
+ assert_equals(option.text, "text\u00a0");
+ }, "option.text should leave trailing NBSP alone.");
+ test(function() {
+ var option = document.createElement("option");
+ option.textContent = "before\u00a0after";
+ assert_equals(option.text, "before\u00a0after");
+ }, "option.text should leave a single internal NBSP alone.");
+ test(function() {
+ var option = document.createElement("option");
+ option.textContent = "before\u00a0\u00a0after";
+ assert_equals(option.text, "before\u00a0\u00a0after");
+ }, "option.text should leave two internal NBSPs alone.");
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/forms/the-option-element/option-value.html b/testing/web-platform/tests/html/semantics/forms/the-option-element/option-value.html
new file mode 100644
index 000000000..cccdc3748
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/the-option-element/option-value.html
@@ -0,0 +1,12 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>HTMLOptionElement.value</title>
+<link rel=author title=Ms2ger href="mailto:Ms2ger@gmail.com">
+<link rel=help href="https://html.spec.whatwg.org/multipage/#dom-option-label">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src=option-label-value.js></script>
+<div id=log></div>
+<script>
+test_option("value")
+</script>
diff --git a/testing/web-platform/tests/html/semantics/forms/the-output-element/.gitkeep b/testing/web-platform/tests/html/semantics/forms/the-output-element/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/the-output-element/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/forms/the-output-element/output.html b/testing/web-platform/tests/html/semantics/forms/the-output-element/output.html
new file mode 100644
index 000000000..7682703fa
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/the-output-element/output.html
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>The output element</title>
+<link rel="author" title="Denis Ah-Kang" href="mailto:denis@w3.org">
+<link rel=help href="https://html.spec.whatwg.org/multipage/#the-output-element">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<output id=output></output>
+<script>
+ var output = document.getElementById("output");
+
+ test(function(){
+ assert_equals(output.type, "output", "type must return the string 'output'");
+ assert_equals(output.textContent, "", "textContent is empty");
+ assert_equals(output.value, "", "value should be empty");
+ assert_equals(output.defaultValue, "", "defaultValue should be empty");
+
+ output.textContent="5";
+ assert_equals(output.value, "5", "textContent is set to 5: value is updated");
+ assert_equals(output.textContent, "5", "textContent is set to 5");
+ assert_equals(output.defaultValue, "5", "textContent is set to 5: defaultValue is updated");
+
+ output.defaultValue="10"; // value mode flag is in "default" mode. Setting defaultValue should set textContent as well
+ assert_equals(output.value, "10", "defaultValue is set to 10: value is updated");
+ assert_equals(output.textContent, "10", "defaultValue is set to 10: textContent is updated");
+ assert_equals(output.defaultValue, "10", "defaultValue is set to 10");
+
+ output.value="20"; // set the value mode flag to "value": default value remains unchanged
+ assert_equals(output.value, "20", "value is set to 20");
+ assert_equals(output.textContent, "20", "value is set to 20: textContent is updated");
+ assert_equals(output.defaultValue, "10", "value is set to 20: defaultValue remains unchanged");
+
+ output.defaultValue="15"; // value mode flag is in "value" mode. textContent remains unchanged when setting defaultValue
+ assert_equals(output.value, "20", "defaultValue is set to 15: value remains unchanged");
+ assert_equals(output.textContent, "20", "defaultValue is set to 15: textContent remains unchanged");
+ assert_equals(output.defaultValue, "15", "defaultValue is set to 15");
+ }, "output value and defaultValue");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/forms/the-progress-element/.gitkeep b/testing/web-platform/tests/html/semantics/forms/the-progress-element/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/the-progress-element/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/forms/the-progress-element/progress-2.html b/testing/web-platform/tests/html/semantics/forms/the-progress-element/progress-2.html
new file mode 100644
index 000000000..ebc475062
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/the-progress-element/progress-2.html
@@ -0,0 +1,34 @@
+<!DOCTYPE HTML>
+<html>
+ <head>
+ <title>Progress Element Tests</title>
+ <meta http-equiv="content-type" content="text/html; charset=UTF-8" />
+ <link rel="author" title="Microsoft" href="http://www.microsoft.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-progress-element" />
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+ <body>
+ <div id="log"></div>
+ <progress id="p00" style="display: none"></progress>
+ <progress id="p01" max="5.5" value=".5" style="display: none"></progress>
+ <script>
+ test(function () {
+ assert_equals(document.getElementById('p00').position, -1);
+ }, "progress position equals -1");
+
+ test(function () {
+ assert_equals(document.getElementById('p00').value, 0);
+ }, "progress value equals 0");
+
+ test(function () {
+ assert_equals(document.getElementById('p01').value, .5);
+ }, "progress value equals .5");
+
+ test(function () {
+ document.getElementById('p00').value = document.getElementById('p00').value;
+ assert_equals(document.getElementById('p00').position, 0);
+ }, "progress position equals 0");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/forms/the-progress-element/progress.html b/testing/web-platform/tests/html/semantics/forms/the-progress-element/progress.html
new file mode 100644
index 000000000..0c176d8ea
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/the-progress-element/progress.html
@@ -0,0 +1,74 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>The progress element</title>
+
+ <link rel="author" title="dan smith" href="mailto:XX1011@gmail.com">
+ <link rel="author" title="Tomoyuki SHIMIZU" href="mailto:tomoyuki.labs@gmail.com">
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-progress-element">
+
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+ <body>
+ <div id="log"></div>
+
+ <progress id="indeterminate"></progress>
+ <progress id="removevalue" value="0.5"></progress>
+ <progress id="quarter" value="1" max="4"></progress>
+ <progress id="largerthanmax" value="2"></progress>
+ <progress id="invalidmax" value="1" max="a"></progress>
+ <progress id="negativemax" value="1" max="-1"></progress>
+ <progress id="invalidvalue" value="a"></progress>
+ <progress id="negativevalue" value="-1"></progress>
+
+ <script>
+
+ test(function() {
+ assert_equals(indeterminate.position, -1);
+ }, "Indeterminate progress bar should have position -1");
+
+ test(function() {
+ removevalue.removeAttribute('value');
+ assert_equals(removevalue.position, -1);
+ }, "Revoming the value attribute makes an intermediate progress bar, which should have position -1");
+
+ test(function() {
+ assert_equals(quarter.position, quarter.value / quarter.max);
+ }, "Determinate progress bar should have fractional position");
+
+ test(function() {
+ assert_equals(indeterminate.value, 0);
+ }, "Indeterminate progress bar should have value 0");
+
+ test(function() {
+ assert_array_equals(largerthanmax.value, 1);
+ }, "Value must equal max if the parsed value is larger than max");
+
+ test(function() {
+ assert_equals(indeterminate.max, 1);
+ }, "Max must be 1 by default");
+
+ test(function() {
+ assert_array_equals(largerthanmax.max, 1);
+ }, "Max must be 1 by default, even if value is specified");
+
+ test(function() {
+ assert_equals(invalidmax.max, 1);
+ }, "Max must be 1 if max value is invalid");
+
+ test(function() {
+ assert_equals(negativemax.max, 1);
+ }, "Max must be 1 if the parsed max value is less than or equal to zero");
+
+ test(function() {
+ assert_equals(invalidvalue.value, 0);
+ }, "Value must be 0 if value is invalid");
+
+ test(function() {
+ assert_equals(negativevalue.value, 0);
+ }, "Value must be 0 if the parsed value is less than or equal to zero");
+
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/forms/the-select-element/.gitkeep b/testing/web-platform/tests/html/semantics/forms/the-select-element/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/the-select-element/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/forms/the-select-element/common-HTMLOptionsCollection-namedItem.html b/testing/web-platform/tests/html/semantics/forms/the-select-element/common-HTMLOptionsCollection-namedItem.html
new file mode 100644
index 000000000..c5c8510a4
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/the-select-element/common-HTMLOptionsCollection-namedItem.html
@@ -0,0 +1,54 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title id='title'>HTMLOptionsCollection</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+</head>
+<body>
+<div id="log"></div>
+<select id="selly">
+ <option id="id1" name="name1">1</option>
+ <option id="id2" name="name2">2</option>
+ <option id="id3" name="name3">3</option>
+ <option id="id4" name="name4">4</option>
+ <option name="nameonly">nameonly</option>
+ <option id="id3">duplicate ID</option>
+ <option name="name4">duplicate name</option>
+ <option id="mixed1">mixed ID</option>
+ <option name="mixed1">mixed name</option>
+</select>
+
+<script>
+var selly;
+setup(function() {
+ selly = document.getElementById('selly');
+});
+
+test(function () {
+ assert_equals(selly.namedItem('nameonly')["value"], "nameonly");
+}, "if only one item has a *name* or id value matching the parameter, return that object and stop");
+
+test(function () {
+ assert_equals(selly.namedItem('id2')["value"], "2");
+}, "if only one item has a name or *id* value matching the parameter, return that object and stop");
+
+test(function () {
+ assert_equals(selly.namedItem('thisdoesnotexist'), null);
+}, "if no item has a name or id value matching the parameter, return null and stop");
+
+test(function () {
+ assert_equals(selly.namedItem('id3')["value"], "3");
+}, "if multiple items have a name or *id* value matching the parameter, return the first object and stop");
+
+test(function () {
+ assert_equals(selly.namedItem('name4')["value"], "4");
+}, "if multiple items have a *name* or id value matching the parameter, return the first object and stop");
+
+test(function () {
+ assert_equals(selly.namedItem('mixed1')["value"], "mixed ID");
+}, "if multiple items have a *name* or *id* value matching the parameter, return the first object and stop");
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/forms/the-select-element/common-HTMLOptionsCollection.html b/testing/web-platform/tests/html/semantics/forms/the-select-element/common-HTMLOptionsCollection.html
new file mode 100644
index 000000000..6bae66ccf
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/the-select-element/common-HTMLOptionsCollection.html
@@ -0,0 +1,70 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title id='title'>HTMLOptionsCollection</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<select id="selly">
+ <option>1</option>
+ <option>2</option>
+ <option>3</option>
+ <option>4</option>
+</select>
+
+<script>
+var selly;
+setup(function() {
+ selly = document.getElementById('selly');
+});
+
+test(function () {
+ assert_equals(selly.length, 4);
+}, "On getting, the length attribute must return the number of nodes represented by the collection.");
+
+test(function () {
+ selly.length = 7;
+ assert_equals(selly.length, 7,
+ "Number of nodes in collection should have changed");
+ assert_equals(selly.children.length, 7,
+ "Number of children should have changed");
+ for (var i = 4; i < 7; ++i) {
+ var child = selly.children[i];
+ assert_equals(child.localName, "option",
+ "new child should be an option");
+ assert_equals(child.namespaceURI, "http://www.w3.org/1999/xhtml",
+ "new child should be an HTML element");
+ assert_equals(child.attributes.length, 0,
+ "new child should not have attributes");
+ assert_equals(child.childNodes.length, 0,
+ "new child should not have child nodes");
+ }
+}, "Changing the length adds new nodes; The number of new nodes = new length minus old length");
+
+test(function () {
+ var elarray = [];
+ for (var i = 0; i < selly.length; i++) {
+ elarray.push(selly[i].value);
+ }
+ assert_array_equals(elarray, ["1", "2", "3", "4", "", "", ""]);
+}, "New nodes have no value");
+
+test(function () {
+ selly.length = 7;
+ assert_equals(selly.length, 7,
+ "Number of nodes in collection should not have changed");
+ assert_equals(selly.children.length, 7,
+ "Number of children should not have changed");
+}, "Setting a length equal to existing length changes nothing");
+
+test(function () {
+ selly.length = 4;
+ assert_equals(selly[6], undefined,
+ "previously set node is now undefined");
+ assert_equals(selly.length, 4,
+ "Number of nodes in collection is correctly changed");
+ assert_equals(selly.children.length, 4,
+ "Number of children should have changed");
+}, "Setting a length lower than the old length trims nodes from the end");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/forms/the-select-element/select-ask-for-reset.html b/testing/web-platform/tests/html/semantics/forms/the-select-element/select-ask-for-reset.html
new file mode 100644
index 000000000..822114fb2
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/the-select-element/select-ask-for-reset.html
@@ -0,0 +1,97 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>HTMLSelectElement ask for reset</title>
+<link rel="author" title="Dongie Agnir" href="dongie.agnir@gmail.com">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+test(function() {
+ var select = makeSelect(5);
+
+ select.children[4].selected = true;
+ unselectedExcept(select, 4);
+
+ select.children[4].remove();
+ unselectedExcept(select, 0); // remove selected node, should default to first
+
+ select.children[3].selected = true;
+
+ select.children[0].remove();
+ unselectedExcept(select, 2); // last node still selected
+
+ select.size = 2;
+ select.children[2].remove();
+
+ unselectedExcept(select, null);
+}, "ask for reset on node remove, non multiple.");
+
+test(function() {
+ var select = makeSelect(3);
+ select.children[1].selected = true;
+
+ // insert selected option, should remain selected
+ var opt4 = document.createElement("option");
+ opt4.selected = true;
+ select.appendChild(opt4);
+ unselectedExcept(select, 3);
+
+ // insert unselected, 3 should remain selected
+ var opt5 = document.createElement("option");
+ select.appendChild(opt5);
+ unselectedExcept(select, 3);
+}, "ask for reset on node insert, non multiple.");
+
+test(function() {
+ var select = makeSelect(3);
+
+ var options = select.children;
+
+ // select options from first to last
+ for (var i = 0; i < options.length; ++i) {
+ options[i].selected = true;
+ unselectedExcept(select, i);
+ }
+
+ // select options from last to first
+ for (var i = options.length - 1; i >= 0; --i) {
+ options[i].selected = true;
+ unselectedExcept(select, i);
+ }
+
+ options[2].selected = true;
+ options[2].selected = false; // none selected
+ unselectedExcept(select, 0);
+
+ // disable first so option at index 1 is first eligible
+ options[0].disabled = true;
+ options[2].selected = true;
+ options[2].selected = false; // none selected
+ unselectedExcept(select, 1);
+
+ select.size = 2;
+ options[1].selected = false;
+ unselectedExcept(select, null); // size > 1 so should not default to any
+}, "change selectedness of option, non multiple.");
+
+
+function unselectedExcept(sel, opt) {
+ for (var i = 0; i < sel.children.length; ++i) {
+ if (i != opt) {
+ assert_false(sel.children[i].selected, "option should not be selected.");
+ }
+ if (opt != null) {
+ assert_true(sel.children[opt].selected, "option should be selected.");
+ }
+ }
+}
+
+function makeSelect(n) {
+ var sel = document.createElement("select");
+ for (var i = 0; i < n; ++i) {
+ opt = document.createElement("option");
+ sel.appendChild(opt);
+ }
+ return sel;
+}
+</script>
diff --git a/testing/web-platform/tests/html/semantics/forms/the-select-element/select-named-getter.html b/testing/web-platform/tests/html/semantics/forms/the-select-element/select-named-getter.html
new file mode 100644
index 000000000..da43da9d9
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/the-select-element/select-named-getter.html
@@ -0,0 +1,46 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Absence of a named getter on HTMLSelectElement</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<div id=log></div>
+<select id=select>
+ <option id=op1>A</option>
+ <option name=op2>B</option>
+ <option id=op3 name=op4>C</option>
+ <option id=>D</option>
+ <option name=>D</option>
+</select>
+<script>
+test(function() {
+ var select = document.getElementById("select");
+ assert_equals(select.op1, undefined);
+ assert_false("op1" in select);
+ assert_equals(select.namedItem("op1"), select.children[0]);
+}, "Option with id")
+
+test(function() {
+ var select = document.getElementById("select");
+ assert_equals(select.op2, undefined);
+ assert_false("op2" in select);
+ assert_equals(select.namedItem("op2"), select.children[1]);
+}, "Option with name")
+
+test(function() {
+ var select = document.getElementById("select");
+ assert_equals(select.op3, undefined);
+ assert_false("op3" in select);
+ assert_equals(select.namedItem("op3"), select.children[2]);
+
+ assert_equals(select.op4, undefined);
+ assert_false("op4" in select);
+ assert_equals(select.namedItem("op4"), select.children[2]);
+}, "Option with name and id")
+
+test(function() {
+ var select = document.getElementById("select");
+ assert_equals(select[""], undefined);
+ assert_false("" in select);
+ assert_equals(select.namedItem(""), null);
+}, "Empty string name");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/forms/the-select-element/select-remove.html b/testing/web-platform/tests/html/semantics/forms/the-select-element/select-remove.html
new file mode 100644
index 000000000..cf2128bd1
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/the-select-element/select-remove.html
@@ -0,0 +1,64 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>HTMLSelectElement.remove</title>
+<link rel="author" title="Ms2ger" href="Ms2ger@gmail.com">
+<link rel="help" href="https://dom.spec.whatwg.org/#dom-childnode-remove">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-select-remove">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-htmloptionscollection-remove">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+function testRemove(getter, desc) {
+ test(function() {
+ var div = document.createElement("div");
+ var select = document.createElement("select");
+ div.appendChild(select);
+ assert_equals(select.parentNode, div);
+
+ var options = [];
+ for (var i = 0; i < 3; ++i) {
+ var option = document.createElement("option");
+ option.textContent = String(i);
+ select.appendChild(option);
+ options.push(option);
+ }
+
+ getter(select).remove(-1);
+ assert_array_equals(select.options, options, "After remove(-1)");
+ assert_equals(select.parentNode, div);
+
+ getter(select).remove(3);
+ assert_array_equals(select.options, options, "After remove(3)");
+ assert_equals(select.parentNode, div);
+
+ getter(select).remove(0);
+ assert_array_equals(select.options, [options[1], options[2]], "After remove(0)");
+ assert_equals(select.parentNode, div);
+ }, desc)
+}
+testRemove(function(select) { return select; }, "select.remove(n) should work");
+testRemove(function(select) { return select.options; }, "select.options.remove(n) should work");
+test(function() {
+ var div = document.createElement("div");
+ var select = document.createElement("select");
+ div.appendChild(select);
+ assert_equals(select.parentNode, div);
+ assert_equals(div.firstChild, select);
+
+ select.remove();
+ assert_equals(select.parentNode, null);
+ assert_equals(div.firstChild, null);
+}, "remove() should work on select elements.")
+test(function() {
+ var div = document.createElement("div");
+ var select = document.createElement("select");
+ div.appendChild(select);
+ assert_equals(select.parentNode, div);
+ assert_equals(div.firstChild, select);
+
+ Element.prototype.remove.call(select);
+ assert_equals(select.parentNode, null);
+ assert_equals(div.firstChild, null);
+}, "Element#remove() should work on select elements.")
+</script>
diff --git a/testing/web-platform/tests/html/semantics/forms/the-textarea-element/.gitkeep b/testing/web-platform/tests/html/semantics/forms/the-textarea-element/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/the-textarea-element/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/forms/the-textarea-element/cloning-steps.html b/testing/web-platform/tests/html/semantics/forms/the-textarea-element/cloning-steps.html
new file mode 100644
index 000000000..7a85bd26a
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/the-textarea-element/cloning-steps.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>Cloning of textarea elements</title>
+<link rel="help" href="https://dom.spec.whatwg.org/#dom-node-clonenode">
+<link rel="help" href="https://dom.spec.whatwg.org/#concept-node-clone">
+<link rel="help" href="https://dom.spec.whatwg.org/#concept-node-clone-ext">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/forms.html#the-textarea-element:concept-node-clone-ext">
+<link rel="author" title="Domenic Denicola" href="mailto:d@domenic.me">
+
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<script>
+"use strict";
+
+test(function() {
+ var textarea = document.createElement("textarea");
+ textarea.value = "foo bar";
+
+ var copy = textarea.cloneNode();
+ assert_equals(copy.value, "foo bar");
+}, "textarea element's value should be cloned");
+
+test(function() {
+ var textarea = document.createElement("textarea");
+ textarea.value = "foo bar";
+
+ var copy = textarea.cloneNode();
+ copy.setAttribute("value", "something else");
+
+ assert_equals(copy.value, "foo bar");
+}, "textarea element's dirty value flag should be cloned, so setAttribute doesn't affect the cloned textarea's value");
+
+</script>
diff --git a/testing/web-platform/tests/html/semantics/forms/the-textarea-element/textarea-newline-bidi-ref.html b/testing/web-platform/tests/html/semantics/forms/the-textarea-element/textarea-newline-bidi-ref.html
new file mode 100644
index 000000000..d69195b4f
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/the-textarea-element/textarea-newline-bidi-ref.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>HTML Test reference: newline in &lt;textarea&gt; separates bidi paragraphs</title>
+ <link rel="author" title="Amir E. Aharoni" href="mailto:amir.aharoni@mail.huji.ac.il"/>
+ <link rel="author" title="Eyal Sela" href="mailto:eyal@post.isoc.org.il"/>
+ <link rel="author" title="Aharon Lanin" href="mailto:aharon@google.com"/>
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-textarea-element"/>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the rightmost character in the first line below is a full stop and to the left of it is a Hebrew letter.</p></div>
+ <div class="test">
+ <textarea cols="70" rows="3">
+A Hebrew letter and a full stop: &#x05d0;.&lrm;
+&#x05d0; this line begins with a Hebrew letter.
+ </textarea>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/forms/the-textarea-element/textarea-newline-bidi.html b/testing/web-platform/tests/html/semantics/forms/the-textarea-element/textarea-newline-bidi.html
new file mode 100644
index 000000000..ce1ff944c
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/the-textarea-element/textarea-newline-bidi.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8"/>
+ <title>HTML Test: newline in &lt;textarea&gt; separates bidi paragraphs</title>
+ <link rel="match" href="textarea-newline-bidi-ref.html" />
+ <link rel="author" title="Amir E. Aharoni" href="mailto:amir.aharoni@mail.huji.ac.il"/>
+ <link rel="author" title="Eyal Sela" href="mailto:eyal@post.isoc.org.il"/>
+ <link rel="author" title="Aharon Lanin" href="mailto:aharon@google.com"/>
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-textarea-element"/>
+ <meta name="assert"
+ content="A newline in a textarea element, and in its raw value, should separate paragraphs for the purposes of the Unicode bidirectional algorithm."/>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the rightmost character in the first line below is a full stop and to the left of it is a Hebrew letter.</p></div>
+ <div class="test">
+ <textarea cols="70" rows="3">
+A Hebrew letter and a full stop: &#x05d0;.
+&#x05d0; this line begins with a Hebrew letter.
+ </textarea>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/forms/the-textarea-element/textarea-placeholder-manual.html b/testing/web-platform/tests/html/semantics/forms/the-textarea-element/textarea-placeholder-manual.html
new file mode 100644
index 000000000..d59a25941
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/the-textarea-element/textarea-placeholder-manual.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>HTML Test: textarea - placeholder attribute</title>
+<link rel="author" title="Intel" href="http://www.intel.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#attr-textarea-placeholder">
+<meta name="flags" content="interact">
+<body>
+ <p>
+ Test passes if there is a "Placeholder Text" in the text area,
+ and if the "Placeholder Text" disappears after type in any character.
+ </p>
+ <textarea placeholder="Placeholder Text"></textarea>
+</body>
+
diff --git a/testing/web-platform/tests/html/semantics/forms/the-textarea-element/textarea-select-event-manual.html b/testing/web-platform/tests/html/semantics/forms/the-textarea-element/textarea-select-event-manual.html
new file mode 100644
index 000000000..f1679e280
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/the-textarea-element/textarea-select-event-manual.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>HTMLTextAreaElement Test: select event</title>
+<link rel="author" title="Intel" href="http://www.intel.com/">
+<meta name="flags" content="interact">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<p>Select any numberic characters in the text area below</p>
+
+<form id="testForm" name="testForm">
+ <textarea id="testtextarea">0123456789</textarea>
+</form>
+
+<script>
+
+var textarea = document.getElementById("testtextarea");
+
+setup({explicit_done : true});
+setup({explicit_timeout : true});
+
+on_event(textarea, "select", function(evt) {
+ test(function() {
+ assert_greater_than(textarea.value.substring(textarea.selectionStart, textarea.selectionEnd).length, 0, "Check if select event captured when text selected");
+ });
+ done();
+});
+
+</script>
+
+<div id="log"></div>
diff --git a/testing/web-platform/tests/html/semantics/forms/the-textarea-element/textarea-select-manual.html b/testing/web-platform/tests/html/semantics/forms/the-textarea-element/textarea-select-manual.html
new file mode 100644
index 000000000..4e98ba509
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/the-textarea-element/textarea-select-manual.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>HTMLTextAreaElement Test: select()</title>
+<link rel="author" title="Intel" href="http://www.intel.com/">
+<meta name="flags" content="interact">
+
+<p>Test passes if content of the input area is selected</p>
+
+<textarea id="test_obj">1234567</textarea>
+<script>
+var textarea = document.querySelector("#test_obj");
+textarea.select();
+</script>
diff --git a/testing/web-platform/tests/html/semantics/forms/the-textarea-element/textarea-type.html b/testing/web-platform/tests/html/semantics/forms/the-textarea-element/textarea-type.html
new file mode 100644
index 000000000..ac80f9365
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/the-textarea-element/textarea-type.html
@@ -0,0 +1,16 @@
+<!DOCTYPE HTML>
+<title>The type IDL attribute</title>
+<link rel="author" title="Ms2ger" href="mailto:ms2ger@gmail.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-textarea-type">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="test">
+<textarea></textarea>
+</div>
+<script>
+test(function() {
+ assert_equals(document.getElementById("test")
+ .getElementsByTagName("textarea")[0].type,
+ "textarea");
+}, "Textarea's type attribute should return 'textarea'");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/forms/the-textarea-element/wrap-reflect-1-ref.html b/testing/web-platform/tests/html/semantics/forms/the-textarea-element/wrap-reflect-1-ref.html
new file mode 100644
index 000000000..98a7f8a3a
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/the-textarea-element/wrap-reflect-1-ref.html
@@ -0,0 +1,5 @@
+<!DOCTYPE html>
+<title>Dynamic manipulation of textarea.wrap</title>
+<link rel=help href=https://html.spec.whatwg.org/multipage/#dom-textarea-wrap>
+<link rel=author title=Ms2ger href=mailto:ms2ger@gmail.com>
+<textarea wrap=soft cols=20>01234567890 01234567890 01234567890</textarea>
diff --git a/testing/web-platform/tests/html/semantics/forms/the-textarea-element/wrap-reflect-1a.html b/testing/web-platform/tests/html/semantics/forms/the-textarea-element/wrap-reflect-1a.html
new file mode 100644
index 000000000..b3baa79d7
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/the-textarea-element/wrap-reflect-1a.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<title>Dynamic manipulation of textarea.wrap</title>
+<link rel=match href=wrap-reflect-1-ref.html>
+<link rel=help href=https://html.spec.whatwg.org/multipage/#dom-textarea-wrap>
+<link rel=author title=Ms2ger href=mailto:ms2ger@gmail.com>
+<textarea wrap=off cols=20>01234567890 01234567890 01234567890</textarea>
+<script>
+document.getElementsByTagName("textarea")[0].wrap = "soft";
+</script>
diff --git a/testing/web-platform/tests/html/semantics/forms/the-textarea-element/wrap-reflect-1b.html b/testing/web-platform/tests/html/semantics/forms/the-textarea-element/wrap-reflect-1b.html
new file mode 100644
index 000000000..b0a9b460f
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/the-textarea-element/wrap-reflect-1b.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<title>Dynamic manipulation of textarea.wrap</title>
+<link rel=match href=wrap-reflect-1-ref.html>
+<link rel=help href=https://html.spec.whatwg.org/multipage/#dom-textarea-wrap>
+<link rel=author title=Ms2ger href=mailto:ms2ger@gmail.com>
+<textarea wrap=off cols=20>01234567890 01234567890 01234567890</textarea>
+<script>
+document.getElementsByTagName("textarea")[0].setAttribute("wrap", "soft");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/grouping-content/.gitkeep b/testing/web-platform/tests/html/semantics/grouping-content/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/grouping-content/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/grouping-content/the-blockquote-element/.gitkeep b/testing/web-platform/tests/html/semantics/grouping-content/the-blockquote-element/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/grouping-content/the-blockquote-element/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/grouping-content/the-dd-element/.gitkeep b/testing/web-platform/tests/html/semantics/grouping-content/the-dd-element/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/grouping-content/the-dd-element/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/grouping-content/the-dd-element/grouping-dd.html b/testing/web-platform/tests/html/semantics/grouping-content/the-dd-element/grouping-dd.html
new file mode 100644
index 000000000..022e555bd
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/grouping-content/the-dd-element/grouping-dd.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>the dd element</title>
+ <link rel="author" title="dzenana" href="mailto:dzenana.trenutak@gmail.com">
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-dd-element">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script>
+ "use strict";
+
+ // check that prototype matches spec's DOM interface
+ test(function () {
+ var testElement = document.createElement("dd");
+ assert_equals(Object.getPrototypeOf(testElement), HTMLElement.prototype, "HTMLElement.prototype should be used for dd");
+ }, "The prototype for dd is HTMLElement.prototype");
+
+ </script>
+</head>
+<body>
+ <h1>Description</h1>
+ <p>This test validates the dd element.</p>
+
+ <div id="log"></div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/grouping-content/the-div-element/.gitkeep b/testing/web-platform/tests/html/semantics/grouping-content/the-div-element/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/grouping-content/the-div-element/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/grouping-content/the-div-element/grouping-div.html b/testing/web-platform/tests/html/semantics/grouping-content/the-div-element/grouping-div.html
new file mode 100644
index 000000000..ffde6eb53
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/grouping-content/the-div-element/grouping-div.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>The div element</title>
+ <link rel="author" title="dzenana" href="mailto:dzenana.trenutak@gmail.com">
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-div-element">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script>
+ "use strict";
+
+ // check that prototype matches spec's DOM interface
+ test(function () {
+ var testElement = document.createElement("div");
+ assert_equals(Object.getPrototypeOf(testElement), HTMLDivElement.prototype, "HTMLDivElement.prototype should be used for div");
+ }, "The prototype for div is HTMLDivElement.prototype");
+
+ </script>
+</head>
+<body>
+ <h1>Description</h1>
+ <p>This test validates the div element.</p>
+
+ <div id="log"></div>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/grouping-content/the-dl-element/.gitkeep b/testing/web-platform/tests/html/semantics/grouping-content/the-dl-element/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/grouping-content/the-dl-element/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/grouping-content/the-dl-element/grouping-dl.html b/testing/web-platform/tests/html/semantics/grouping-content/the-dl-element/grouping-dl.html
new file mode 100644
index 000000000..2394d6a92
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/grouping-content/the-dl-element/grouping-dl.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>the dl element</title>
+ <link rel="author" title="dzenana" href="mailto:dzenana.trenutak@gmail.com">
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-dl-element">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script>
+ "use strict";
+
+ // check that prototype matches spec's DOM interface
+ test(function () {
+ var testElement = document.createElement("dl");
+ assert_equals(Object.getPrototypeOf(testElement), HTMLDListElement.prototype, "HTMLDListElement.prototype should be used for dl");
+ }, "The prototype for dl is HTMLDListElement.prototype");
+
+ // Not checking: effects of markup on defining groups and the name-pair values within those groups
+
+ </script>
+</head>
+<body>
+ <h1>Description</h1>
+ <p>This test validates the dl element.</p>
+
+ <div id="log"></div>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/grouping-content/the-dt-element/.gitkeep b/testing/web-platform/tests/html/semantics/grouping-content/the-dt-element/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/grouping-content/the-dt-element/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/grouping-content/the-dt-element/grouping-dt.html b/testing/web-platform/tests/html/semantics/grouping-content/the-dt-element/grouping-dt.html
new file mode 100644
index 000000000..1dbb4384d
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/grouping-content/the-dt-element/grouping-dt.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>the dl element</title>
+ <link rel="author" title="dzenana" href="mailto:dzenana.trenutak@gmail.com">
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-dt-element">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script>
+ "use strict";
+
+ // check that prototype matches spec's DOM interface
+ test(function () {
+ var testElement = document.createElement("dt");
+ assert_equals(Object.getPrototypeOf(testElement), HTMLElement.prototype, "HTMLElement.prototype should be used for dt");
+ }, "The prototype for dt is HTMLElement.prototype");
+
+ </script>
+</head>
+<body>
+ <h1>Description</h1>
+ <p>This test validates the dt element.</p>
+
+ <div id="log"></div>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/grouping-content/the-figcaption-element/.gitkeep b/testing/web-platform/tests/html/semantics/grouping-content/the-figcaption-element/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/grouping-content/the-figcaption-element/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/grouping-content/the-figcaption-element/grouping-figcaption.html b/testing/web-platform/tests/html/semantics/grouping-content/the-figcaption-element/grouping-figcaption.html
new file mode 100644
index 000000000..68e7a516b
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/grouping-content/the-figcaption-element/grouping-figcaption.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>the figcaption element</title>
+ <link rel="author" title="dzenana" href="mailto:dzenana.trenutak@gmail.com">
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-figcaption-element">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script>
+ "use strict";
+
+ // check that prototype matches spec's DOM interface
+ test(function () {
+ var testElement = document.createElement("figcaption");
+ assert_equals(Object.getPrototypeOf(testElement), HTMLElement.prototype, "HTMLElement.prototype should be used for figcaption");
+ }, "The prototype for figcaption is HTMLElement.prototype");
+
+ </script>
+</head>
+<body>
+ <h1>Description</h1>
+ <p>This test validates the figcaption element.</p>
+
+ <div id="log"></div>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/grouping-content/the-figure-element/.gitkeep b/testing/web-platform/tests/html/semantics/grouping-content/the-figure-element/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/grouping-content/the-figure-element/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/grouping-content/the-figure-element/grouping-figure.html b/testing/web-platform/tests/html/semantics/grouping-content/the-figure-element/grouping-figure.html
new file mode 100644
index 000000000..31c156ce3
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/grouping-content/the-figure-element/grouping-figure.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>the figure element</title>
+ <link rel="author" title="dzenana" href="mailto:dzenana.trenutak@gmail.com">
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-figure-element">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script>
+ "use strict";
+
+ // check that prototype matches spec's DOM interface
+ test(function () {
+ var testElement = document.createElement("figure");
+ assert_equals(Object.getPrototypeOf(testElement), HTMLElement.prototype, "HTMLElement.prototype should be used for figure");
+ }, "The prototype for figure is HTMLElement.prototype");
+
+ // Not checking: Sectioning root
+
+ </script>
+</head>
+<body>
+ <h1>Description</h1>
+ <p>This test validates the figure element.</p>
+
+ <div id="log"></div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/grouping-content/the-hr-element/.gitkeep b/testing/web-platform/tests/html/semantics/grouping-content/the-hr-element/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/grouping-content/the-hr-element/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/grouping-content/the-hr-element/grouping-hr.html b/testing/web-platform/tests/html/semantics/grouping-content/the-hr-element/grouping-hr.html
new file mode 100644
index 000000000..eeadd97d4
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/grouping-content/the-hr-element/grouping-hr.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>the hr element</title>
+ <link rel="author" title="dzenana" href="mailto:dzenana.trenutak@gmail.com">
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-hr-element">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script>
+ "use strict";
+
+ // check that prototype matches spec's DOM interface
+ test(function () {
+ var testElement = document.createElement("hr");
+ assert_equals(Object.getPrototypeOf(testElement), HTMLHRElement.prototype, "HTMLHRElement.prototype should be used for hr");
+ }, "The prototype for hr is HTMLHRElement.prototype");
+
+ // Not checking: "The hr element does not affect the document's outline."
+
+ </script>
+</head>
+<body>
+ <h1>Description</h1>
+ <p>This test validates the hr element.</p>
+
+ <div id="log"></div>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/grouping-content/the-li-element/.gitkeep b/testing/web-platform/tests/html/semantics/grouping-content/the-li-element/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/grouping-content/the-li-element/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/grouping-content/the-li-element/grouping-li-novalue-manual.html b/testing/web-platform/tests/html/semantics/grouping-content/the-li-element/grouping-li-novalue-manual.html
new file mode 100644
index 000000000..346ed5662
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/grouping-content/the-li-element/grouping-li-novalue-manual.html
@@ -0,0 +1,148 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>Body Element</title>
+ <link rel="author" title="dzenana" href="mailto:dzenana.trenutak@gmail.com">
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-body-element">
+ <meta name="flags" content="interact" />
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+</head>
+<body>
+ <h1>Validation of li characteristic requiring manual testing</h1>
+
+ <p>The spec states: "If the parent element is an ol element, then the li element has an ordinal value."</p>
+ <p>This manual test is needed to verify that NON-ol element parents do NOT result in an ordinal value.</p>
+ <p>It needs to be manual because the ordinal value assigned to each list element by the user agent is NOT available programmatically. Values which are set either via markup or IDL are available programmatically, but not the calculated values for all the other list items.</p>
+ <p>And, as we cannot be sure how a mistakenly assigned value would be rendered, this test cannot be a reftest.</p>
+ <p>So, please use the buttons to answer the following questions:</p>
+
+ <table>
+ <thead>
+ <tr>
+ <th>HTML Markup</th>
+ <th>Do you see any sort of sequencing information?</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr>
+ <td>
+ <menu>
+ <li>Menu Item</li>
+ <li>Menu Item</li>
+ </menu>
+ </td>
+ <td>
+ <input type="button" id="btnMenuYes" value="Yes" />
+ <input type="button" id="btnMenuNo" value="No" />
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <menu type="toolbar">
+ <li>
+ <menu label="ToolbarLabel">
+ <li><a>Toolbar Menu Item</a></li>
+ <li><a>Toolbar Menu Item</a></li>
+ </menu>
+ </li>
+ <li>
+ <menu label="ToolbarLabel">
+ <li><a>Toolbar Menu Item</a></li>
+ <li><a>Toolbar Menu Item</a></li>
+ </menu>
+ </li>
+ </menu>
+ </td>
+ <td>
+ <input type="button" id="btnToolbarYes" value="Yes" />
+ <input type="button" id="btnToolbarNo" value="No" />
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <ul>
+ <li>list item</li>
+ <li>list item</li>
+ <li>list item</li>
+ </ul>
+ </td>
+ <td>
+ <input type="button" id="btnULYes" value="Yes" />
+ <input type="button" id="btnULNo" value="No" />
+ </td>
+ </tr>
+ </tbody>
+ </table>
+
+ <div id="log"></div>
+
+ <script>
+ "use strict";
+
+ var testMenu = {}, testToolbar = {}, testUL = {};
+
+ // need to be able to wait for user to push button
+ setup(function () {
+ btnMenuYes.disabled = false;
+ btnMenuNo.disabled = false;
+ btnToolbarYes.disabled = false;
+ btnToolbarNo.disabled = false;
+ btnULYes.disabled = false;
+ btnULNo.disabled = false;
+ },
+ { explicit_timeout: true }
+ );
+
+ // register async tests
+ testMenu = async_test("Check that menu element does not result in values for list items.");
+ testToolbar = async_test("Check that toolbar type menu element does not result in values for list items.");
+ testUL = async_test("Check that unordered list element does not result in values for list items.");
+
+ // run async tests after buttons are clicked - MENU test
+ document.getElementById("btnMenuNo").onclick = testMenu.step_func(function (event) {
+ assert_true(true, "No sequencing applied to list elements inside menu.");
+ testMenu.done();
+ btnMenuYes.disabled = true;
+ btnMenuNo.disabled = true;
+ });
+ document.getElementById("btnMenuYes").onclick = testMenu.step_func(function (event) {
+ assert_true(false, "No sequencing applied to list elements inside menu.");
+ testMenu.done();
+ btnMenuYes.disabled = true;
+ btnMenuNo.disabled = true;
+ });
+
+ // run async tests after buttons are clicked -TOOLBAR test
+ document.getElementById("btnToolbarNo").onclick = testToolbar.step_func(function (event) {
+ assert_true(true, "No sequencing applied to list elements inside toolbar menu.");
+ testToolbar.done();
+ btnToolbarYes.disabled = true;
+ btnToolbarNo.disabled = true;
+ });
+ document.getElementById("btnToolbarYes").onclick = testToolbar.step_func(function (event) {
+ assert_true(false, "No sequencing applied to list elements inside toolbar menu.");
+ testToolbar.done();
+ btnToolbarYes.disabled = true;
+ btnToolbarNo.disabled = true;
+ });
+
+ // run async tests after buttons are clicked - UL test
+ document.getElementById("btnULNo").onclick = testUL.step_func(function (event) {
+ assert_true(true, "No sequencing applied to list elements inside UL.");
+ testUL.done();
+ btnULYes.disabled = true;
+ btnULNo.disabled = true;
+ });
+ document.getElementById("btnULYes").onclick = testUL.step_func(function (event) {
+ assert_true(false, "No sequencing applied to list elements inside UL.");
+ testUL.done();
+ btnULYes.disabled = true;
+ btnULNo.disabled = true;
+ });
+
+
+ </script>
+
+</body>
diff --git a/testing/web-platform/tests/html/semantics/grouping-content/the-li-element/grouping-li-reftest-001-ref.html b/testing/web-platform/tests/html/semantics/grouping-content/the-li-element/grouping-li-reftest-001-ref.html
new file mode 100644
index 000000000..5ff5296e2
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/grouping-content/the-li-element/grouping-li-reftest-001-ref.html
@@ -0,0 +1,48 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>li element</title>
+ <link rel="author" title="dzenana" href="mailto:dzenana.trenutak@gmail.com">
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-li-element">
+ <meta name="assert" content="The value attribute has no effect when applied to a li element whose parent is a non-ol element." />
+</head>
+<body>
+ <h1>Description</h1>
+ <p>This test continues to validate the li element.</p>
+
+ <p>The spec states:</p>
+ <blockquote>"If the parent element is an ol element, then the li element has an ordinal value. The value attribute is processed relative to the element's parent ol element (q.v.), if there is one. If there is not, the attribute has no effect."</blockquote>
+ <p>This reftest verifies that the value attribute has no effect when applied to a list item NOT having an ol parent.</p>
+ <p>A reftest is necessary because the values of li elements as calculated by the user agent are NOT available programatically. Only explicitly-set values are then available programatically.</p>
+ <p>This reftest passes if you see NO sequencing information on any of the items below.</p>
+
+ <p>Unordered List</p>
+ <ul>
+ <li>list item</li>
+ <li>list item</li>
+ <li>list item</li>
+ </ul>
+
+ <menu>
+ <li>Menu Item</li>
+ <li>Menu Item</li>
+ </menu>
+
+ <menu type="toolbar">
+ <li>
+ <menu label="ToolbarLabel">
+ <li><a>Toolbar Menu Item</a></li>
+ <li><a>Toolbar Menu Item</a></li>
+ </menu>
+ </li>
+ <li>
+ <menu label="ToolbarLabel">
+ <li><a>Toolbar Menu Item</a></li>
+ <li><a>Toolbar Menu Item</a></li>
+ </menu>
+ </li>
+ </menu>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/grouping-content/the-li-element/grouping-li-reftest-001.html b/testing/web-platform/tests/html/semantics/grouping-content/the-li-element/grouping-li-reftest-001.html
new file mode 100644
index 000000000..71b72c2ce
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/grouping-content/the-li-element/grouping-li-reftest-001.html
@@ -0,0 +1,49 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>li element</title>
+ <link rel="author" title="dzenana" href="mailto:dzenana.trenutak@gmail.com">
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-li-element">
+ <link rel="match" href="grouping-li-reftest-001-ref.html" />
+ <meta name="assert" content="The value attribute has no effect when applied to a li element whose parent is a non-ol element." />
+</head>
+<body>
+ <h1>Description</h1>
+ <p>This test continues to validate the li element.</p>
+
+ <p>The spec states:</p>
+ <blockquote>"If the parent element is an ol element, then the li element has an ordinal value. The value attribute is processed relative to the element's parent ol element (q.v.), if there is one. If there is not, the attribute has no effect."</blockquote>
+ <p>This reftest verifies that the value attribute has no effect when applied to a list item NOT having an ol parent.</p>
+ <p>A reftest is necessary because the values of li elements as calculated by the user agent are NOT available programatically. Only explicitly-set values are then available programatically.</p>
+ <p>This reftest passes if you see NO sequencing information on any of the items below.</p>
+
+ <p>Unordered List</p>
+ <ul>
+ <li value="2">list item</li>
+ <li>list item</li>
+ <li>list item</li>
+ </ul>
+
+ <menu>
+ <li>Menu Item</li>
+ <li value="3">Menu Item</li>
+ </menu>
+
+ <menu type="toolbar">
+ <li value="4">
+ <menu label="ToolbarLabel">
+ <li value="5"><a>Toolbar Menu Item</a></li>
+ <li><a>Toolbar Menu Item</a></li>
+ </menu>
+ </li>
+ <li value="6">
+ <menu label="ToolbarLabel">
+ <li value="10"><a>Toolbar Menu Item</a></li>
+ <li><a>Toolbar Menu Item</a></li>
+ </menu>
+ </li>
+ </menu>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/grouping-content/the-li-element/grouping-li-reftest-002-ref.html b/testing/web-platform/tests/html/semantics/grouping-content/the-li-element/grouping-li-reftest-002-ref.html
new file mode 100644
index 000000000..bdb728faf
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/grouping-content/the-li-element/grouping-li-reftest-002-ref.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>li element</title>
+ <link rel="author" title="dzenana" href="mailto:dzenana.trenutak@gmail.com">
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-li-element">
+ <meta name="assert" content="li elements with ol parents have ordinal values." />
+ <style type="text/css">
+ span p {display:list-item; margin-left: 0; margin-top: 0; margin-bottom: 0; padding-left: 0; padding-top: 0; padding-bottom: 0;}
+ span span p {margin-left: 0; margin-top: 0; margin-bottom: 0; padding-left: 5em; padding-top: 0; padding-bottom: 0; font-family: monospace;}
+ </style>
+</head>
+<body>
+ <h1>Description</h1>
+ <p>This test continues to validate the li element.</p>
+
+ <p>The spec states:</p>
+ <blockquote>"If the parent element is an ol element, then the li element has an ordinal value. The value attribute is processed relative to the element's parent ol element (q.v.), if there is one. If there is not, the attribute has no effect."</blockquote>
+ <p>This reftest verifies that the value attribute has an effect when applied to a list item with an ol parent.</p>
+ <p>A reftest is necessary because the values of li elements as calculated by the user agent are NOT available programatically. Only explicitly-set values are then available programatically.</p>
+ <p>This reftest passes if you see the numbers 1. 2. 3. below the words "Ordered List"</p>
+
+ <span>
+ <p>Ordered List</p>
+ <span>
+ <p>1.</p>
+ <p>2.</p>
+ <p>3.</p>
+ </span>
+ </span>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/grouping-content/the-li-element/grouping-li-reftest-002.html b/testing/web-platform/tests/html/semantics/grouping-content/the-li-element/grouping-li-reftest-002.html
new file mode 100644
index 000000000..ae4eebee1
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/grouping-content/the-li-element/grouping-li-reftest-002.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>li element</title>
+ <link rel="author" title="dzenana" href="mailto:dzenana.trenutak@gmail.com">
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-li-element">
+ <link rel="match" href="grouping-li-reftest-002-ref.html" />
+ <meta name="assert" content="li elements with ol parents have ordinal values." />
+ <style type="text/css">
+ span p {display:list-item; margin-left: 0; margin-top: 0; margin-bottom: 0; padding-left: 0; padding-top: 0; padding-bottom: 0;}
+ span li {margin-left: 0; margin-top: 0; margin-bottom: 0; padding-left: 0; padding-top: 0; padding-bottom: 0; font-family: monospace;}
+ span ol {margin-left: 0; margin-top: 0; margin-bottom: 0; padding-left: 5em; padding-top: 0; padding-bottom: 0; font-family: monospace;
+ list-style-position: inside; list-style-type: decimal; }
+ </style>
+</head>
+<body>
+ <h1>Description</h1>
+ <p>This test continues to validate the li element.</p>
+
+ <p>The spec states:</p>
+ <blockquote>"If the parent element is an ol element, then the li element has an ordinal value. The value attribute is processed relative to the element's parent ol element (q.v.), if there is one. If there is not, the attribute has no effect."</blockquote>
+ <p>This reftest verifies that the value attribute has an effect when applied to a list item with an ol parent.</p>
+ <p>A reftest is necessary because the values of li elements as calculated by the user agent are NOT available programatically. Only explicitly-set values are then available programatically.</p>
+ <p>This reftest passes if you see the numbers 1. 2. 3. below the words "Ordered List"</p>
+
+ <span>
+ <p>Ordered List</p>
+ <ol>
+ <li></li>
+ <li></li>
+ <li></li>
+ </ol>
+ </span>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/grouping-content/the-li-element/grouping-li.html b/testing/web-platform/tests/html/semantics/grouping-content/the-li-element/grouping-li.html
new file mode 100644
index 000000000..fa342b3e2
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/grouping-content/the-li-element/grouping-li.html
@@ -0,0 +1,193 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>li element</title>
+ <link rel="author" title="dzenana" href="mailto:dzenana.trenutak@gmail.com">
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-li-element">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+</head>
+<body>
+ <h1>Description</h1>
+ <p>This test validates the li element.</p>
+
+ <div id="log"></div>
+
+ <span>
+ <menu id="listmenu">
+ <li>Command</li>
+ <li value="3">Command</li>
+ </menu>
+
+ <menu type="toolbar" id="toolbarmenu">
+ <li>
+ <menu label="File">
+ <button type="button">New...</button>
+ <button type="button">Open...</button>
+ </menu>
+ </li>
+ <li value="10">
+ <menu label="Help">
+ <li value = "2"><a href="help.html">Help Me</a></li>
+ <li><a href="about.html">About</a></li>
+ </menu>
+ </li>
+ </menu>
+
+ <p>Unordered List</p>
+ <ul id="unordered">
+ <li>list item</li>
+ <li>list item</li>
+ <li>list item</li>
+ </ul>
+ </span>
+
+ <p>Ordered List</p>
+ <ol id="basic">
+ <li>list item</li>
+ <li>list item</li>
+ <li>list item</li>
+ </ol>
+
+ <p>Ordered List</p>
+ <ol id="start2">
+ <li value="2">list item</li>
+ <li>list item</li>
+ <li>list item</li>
+ </ol>
+
+ <p>Ordered List</p>
+ <ol id="negative">
+ <li value="-10">list item</li>
+ <li>list item</li>
+ <li>list item</li>
+ </ol>
+
+ <p>Ordered List</p>
+ <ol id="posFloatDown">
+ <li value="4.03">list item</li>
+ <li>list item</li>
+ <li>list item</li>
+ </ol>
+
+ <p>Ordered List</p>
+ <ol id="negFloatDown">
+ <li value="-4.03">list item</li>
+ <li>list item</li>
+ <li>list item</li>
+ </ol>
+
+ <p>Ordered List</p>
+ <ol id="posFloatUp">
+ <li value="4.9">list item</li>
+ <li>list item</li>
+ <li>list item</li>
+ </ol>
+
+ <p>Ordered List</p>
+ <ol id="negFloatUp">
+ <li value="-4.9">list item</li>
+ <li>list item</li>
+ <li>list item</li>
+ </ol>
+
+ <p>Ordered List</p>
+ <ol id="exponent">
+ <li value="7e2">list item</li>
+ <li>list item</li>
+ <li>list item</li>
+ </ol>
+
+ <p>Ordered List</p>
+ <ol id="decimal">
+ <li value=".5">list item</li>
+ <li>list item</li>
+ <li>list item</li>
+ </ol>
+
+ <p>Ordered List</p>
+ <ol id="letter">
+ <li value="A">list item</li>
+ <li>list item</li>
+ <li>list item</li>
+ </ol>
+
+ <script>
+ "use strict";
+
+ // "The [value] attribute has no default value" so, per https://html.spec.whatwg.org/multipage/#reflect,
+ // the default when unspecified is 0
+ test(function() {
+ var testList = document.querySelectorAll("#unordered li, #basic li");
+ for (var i = 0; i < testList.length; i++) {
+ assert_equals(testList[i].value, 0, "Default (unspecified) value of value is 0.");
+ }
+ }, "Default (unspecified) value of value is 0.");
+
+ // "If the value attribute is present, user agents must parse it as an integer, in order to determine the attribute's value.
+ // If the attribute's value cannot be converted to a number, the attribute must be treated as if it was absent."
+ // Per https://html.spec.whatwg.org/multipage/#collect-a-sequence-of-characters,
+ // an integer is parsed by collecting as many digits as possible and then aborting at the first
+ // non-digit character after the first digit (otherwise, with no beginning digit, it's just an error)
+ // and: "The value IDL attribute must reflect the value of the value content attribute."
+
+ // start2's first element has value of 2
+ test(function() {
+ var testLI = document.getElementById("start2").children[0];
+ assert_equals(testLI.value, 2, "value of 2 -> value of 2");
+ }, ".value property reflects content attribute - and both parse value of '2' correctly.");
+
+ // negative's first element has value of -10
+ test(function() {
+ var testLI = document.getElementById("negative").children[0];
+ assert_equals(testLI.value, -10, "value of -10 -> value of -10");
+ }, "IDL and content attribute parse value of '-10' correctly.");
+
+ // posFloatDown's first element has value of 4.03 which should return 4
+ test(function() {
+ var testLI = document.getElementById("posFloatDown").children[0];
+ assert_equals(testLI.value, 4, "value of 4.03 -> 4");
+ }, "IDL and content attribute parse value of '4.03' correctly.");
+
+ // negFloatDown's first element has value of -4.03 which should return -4
+ test(function() {
+ var testLI = document.getElementById("negFloatDown").children[0];
+ assert_equals(testLI.value, -4, "value of -4.03 -> -4");
+ }, "IDL and content attribute parse value of '-4.03' correctly.");
+
+ // posFloatUp's first element has value of 4.9 which should return 4
+ test(function() {
+ var testLI = document.getElementById("posFloatUp").children[0];
+ assert_equals(testLI.value, 4, "value of 4.9 -> 4");
+ }, "IDL and content attribute parse value of '4.9' correctly.");
+
+ // negFloatUp's first element has value of -4.9 which should return -4
+ test(function() {
+ var testLI = document.getElementById("negFloatUp").children[0];
+ assert_equals(testLI.value, -4, "value of -4.9 -> -4");
+ }, "IDL and content attribute parse value of '-4.9' correctly.");
+
+ // exponent's first element has value of 7e2 which should return 7
+ test(function() {
+ var testLI = document.getElementById("exponent").children[0];
+ assert_equals(testLI.value, 7, "value of 7e2 -> 7");
+ }, "IDL and content attribute parse value of '7e2' correctly.");
+
+ // decimal's first element has value of .5 which should return 0
+ test(function() {
+ var testLI = document.getElementById("decimal").children[0];
+ assert_equals(testLI.value, 0, "value of .5 -> 0 (default)");
+ }, "IDL and content attribute parse value of '.5' correctly.");
+
+ // letter's first element has value of A which should return 0
+ test(function() {
+ var testLI = document.getElementById("letter").children[0];
+ assert_equals(testLI.value, 0, "value of A -> 0 (default)");
+ }, "IDL and content attribute parse value of 'A' correctly.");
+
+ // SHOULD I TEST MORE NON-ASCII-DIGIT ENTRIES?
+
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/grouping-content/the-ol-element/.gitkeep b/testing/web-platform/tests/html/semantics/grouping-content/the-ol-element/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/grouping-content/the-ol-element/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/grouping-content/the-ol-element/grouping-ol-rev-reftest-001-ref.html b/testing/web-platform/tests/html/semantics/grouping-content/the-ol-element/grouping-ol-rev-reftest-001-ref.html
new file mode 100644
index 000000000..019aef1b6
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/grouping-content/the-ol-element/grouping-ol-rev-reftest-001-ref.html
@@ -0,0 +1,53 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>ol element</title>
+ <link rel="author" title="dzenana" href="mailto:dzenana.trenutak@gmail.com">
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-ol-element">
+ <meta name="assert" content="OL's reversed attribute creates a descending list." />
+ <style type="text/css">
+ span p {display:list-item; margin-left: 0; margin-top: 0; margin-bottom: 0; padding-left: 0; padding-top: 0; padding-bottom: 0;}
+ span span p {margin-left: 0; margin-top: 0; margin-bottom: 0; padding-left: 5em; padding-top: 0; padding-bottom: 0; font-family: monospace;}
+ </style>
+</head>
+<body>
+ <h1>Description</h1>
+ <p>This test continues to validate the ol element.</p>
+
+ <p>These reftests are necessary because the values of the ol's li children as calculated by the user agent are NOT available programatically. Only explicitly-set values are available programatically. Therefore, we need to check actual rendering against expected rendering.</p>
+
+ <p>The spec states:</p>
+ <blockquote>"The reversed attribute is a boolean attribute. If present, it indicates that the list is a descending list (..., 3, 2, 1). If the attribute is omitted, the list is an ascending list (1, 2, 3, ...)."</blockquote>
+
+ <p><strong>This reftest passes if you see an ascending list followed by two descending lists.</strong></p>
+ <p>(Note: each list item has no content; only the sequencing should appear.)</p>
+
+ <span>
+
+ <p>Ordered List</p>
+ <span>
+ <p>1.</p>
+ <p>2.</p>
+ <p>3.</p>
+ </span>
+
+ <p>Ordered List - reversed via content attribute</p>
+ <span>
+ <p>3.</p>
+ <p>2.</p>
+ <p>1.</p>
+ </span>
+
+ <p>Ordered List - reversed via IDL</p>
+ <span>
+ <p>3.</p>
+ <p>2.</p>
+ <p>1.</p>
+ </span>
+
+ </span>
+
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/grouping-content/the-ol-element/grouping-ol-rev-reftest-001.html b/testing/web-platform/tests/html/semantics/grouping-content/the-ol-element/grouping-ol-rev-reftest-001.html
new file mode 100644
index 000000000..32d4f2c86
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/grouping-content/the-ol-element/grouping-ol-rev-reftest-001.html
@@ -0,0 +1,59 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>ol element</title>
+ <link rel="author" title="dzenana" href="mailto:dzenana.trenutak@gmail.com">
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-ol-element">
+ <link rel="match" href="grouping-ol-rev-reftest-001-ref.html" />
+ <meta name="assert" content="OL's reversed attribute creates a descending list." />
+ <style type="text/css">
+ span p {display:list-item; margin-left: 0; margin-top: 0; margin-bottom: 0; padding-left: 0; padding-top: 0; padding-bottom: 0;}
+ span li {margin-left: 0; margin-top: 0; margin-bottom: 0; padding-left: 0; padding-top: 0; padding-bottom: 0; font-family: monospace;}
+ span ol {margin-left: 0; margin-top: 0; margin-bottom: 0; padding-left: 5em; padding-top: 0; padding-bottom: 0; font-family: monospace;
+ list-style-position: inside; list-style-type: decimal; }
+ </style>
+</head>
+<body>
+ <h1>Description</h1>
+ <p>This test continues to validate the ol element.</p>
+
+ <p>These reftests are necessary because the values of the ol's li children as calculated by the user agent are NOT available programatically. Only explicitly-set values are available programatically. Therefore, we need to check actual rendering against expected rendering.</p>
+
+ <p>The spec states:</p>
+ <blockquote>"The reversed attribute is a boolean attribute. If present, it indicates that the list is a descending list (..., 3, 2, 1). If the attribute is omitted, the list is an ascending list (1, 2, 3, ...)."</blockquote>
+
+ <p><strong>This reftest passes if you see an ascending list followed by two descending lists.</strong></p>
+ <p>(Note: each list item has no content; only the sequencing should appear.)</p>
+
+ <span>
+
+ <p>Ordered List</p>
+ <ol>
+ <li></li>
+ <li></li>
+ <li></li>
+ </ol>
+
+ <p>Ordered List - reversed via content attribute</p>
+ <ol reversed="reversed">
+ <li></li>
+ <li></li>
+ <li></li>
+ </ol>
+
+ <p>Ordered List - reversed via IDL</p>
+ <ol id="reverse_me">
+ <li></li>
+ <li></li>
+ <li></li>
+ </ol>
+
+ </span>
+
+ <script>
+ document.getElementById("reverse_me").reversed = true;
+ </script>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/grouping-content/the-ol-element/grouping-ol-start-reftest-001-ref.html b/testing/web-platform/tests/html/semantics/grouping-content/the-ol-element/grouping-ol-start-reftest-001-ref.html
new file mode 100644
index 000000000..f87074899
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/grouping-content/the-ol-element/grouping-ol-start-reftest-001-ref.html
@@ -0,0 +1,57 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>ol element</title>
+ <link rel="author" title="dzenana" href="mailto:dzenana.trenutak@gmail.com">
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-ol-element">
+ <meta name="assert" content="Sequences produced by calculated values for LI elements within OL match spec's expectations. (part one)" />
+ <style type="text/css">
+ span p {display:list-item; margin-left: 0; margin-top: 0; margin-bottom: 0; padding-left: 0; padding-top: 0; padding-bottom: 0;}
+ span span p {margin-left: 0; margin-top: 0; margin-bottom: 0; padding-left: 5em; padding-top: 0; padding-bottom: 0; font-family: monospace;}
+ </style>
+</head>
+<body>
+ <p>This test continues to validate the ol element. This reftest is necessary because the values of the ol's li children as calculated and displayed by the user agent are NOT systematically available programatically. Only explicitly-set values are available programatically. Therefore, we need to check actual rendering against expected rendering.</p>
+
+ <p>The spec states:</p>
+ <blockquote><p>The first item in the list has the ordinal value given by the ol element's start attribute, unless that li element has a value attribute with a value that can be successfully parsed, in which case it has the ordinal value given by that value attribute.</p>
+ <p>Each subsequent item in the list has the ordinal value given by its value attribute, if it has one, or, if it doesn't, the ordinal value of the previous item, plus one if the reversed is absent, or minus one if it is present.</p></blockquote>
+
+ <p><strong>This reftest passes if each list's items are numbered identically to the horizontal sequence immediately above those list items.</strong></p>
+ <p>(Note: each list item has no content; only the sequencing should appear.)</p>
+
+ <span>
+
+ <p>2, 3, 4 (ol has start attribute of 2)</p>
+ <span>
+ <p>2.</p>
+ <p>3.</p>
+ <p>4.</p>
+ </span>
+
+ <p>-9, -8, -7 (ol has start attribute of -9)</p>
+ <span>
+ <p>-9.</p>
+ <p>-8.</p>
+ <p>-7.</p>
+ </span>
+
+ <p>1000, 1001, 1002 (list's start attribute of 1000 provided by JavaScript)</p>
+ <span>
+ <p>1000.</p>
+ <p>1001.</p>
+ <p>1002.</p>
+ </span>
+
+ <p>2, 1, 9 (each list item has a specified value attribute, list has a start attribute of 1000)</p>
+ <span>
+ <p>2.</p>
+ <p>1.</p>
+ <p>9.</p>
+ </span>
+
+ </span>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/grouping-content/the-ol-element/grouping-ol-start-reftest-001.html b/testing/web-platform/tests/html/semantics/grouping-content/the-ol-element/grouping-ol-start-reftest-001.html
new file mode 100644
index 000000000..dc373f910
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/grouping-content/the-ol-element/grouping-ol-start-reftest-001.html
@@ -0,0 +1,64 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>ol element</title>
+ <link rel="author" title="dzenana" href="mailto:dzenana.trenutak@gmail.com">
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-ol-element">
+ <link rel="match" href="grouping-ol-start-reftest-001-ref.html" />
+ <meta name="assert" content="Sequences produced by calculated values for LI elements within OL match spec's expectations (part one)." />
+ <style type="text/css">
+ span p {display:list-item; margin-left: 0; margin-top: 0; margin-bottom: 0; padding-left: 0; padding-top: 0; padding-bottom: 0;}
+ span li {margin-left: 0; margin-top: 0; margin-bottom: 0; padding-left: 0; padding-top: 0; padding-bottom: 0; font-family: monospace;}
+ span ol {margin-left: 0; margin-top: 0; margin-bottom: 0; padding-left: 5em; padding-top: 0; padding-bottom: 0; font-family: monospace;
+ list-style-position: inside; list-style-type: decimal; }
+ </style>
+</head>
+<body>
+ <p>This test continues to validate the ol element. This reftest is necessary because the values of the ol's li children as calculated and displayed by the user agent are NOT systematically available programatically. Only explicitly-set values are available programatically. Therefore, we need to check actual rendering against expected rendering.</p>
+
+ <p>The spec states:</p>
+ <blockquote><p>The first item in the list has the ordinal value given by the ol element's start attribute, unless that li element has a value attribute with a value that can be successfully parsed, in which case it has the ordinal value given by that value attribute.</p>
+ <p>Each subsequent item in the list has the ordinal value given by its value attribute, if it has one, or, if it doesn't, the ordinal value of the previous item, plus one if the reversed is absent, or minus one if it is present.</p></blockquote>
+
+ <p><strong>This reftest passes if each list's items are numbered identically to the horizontal sequence immediately above those list items.</strong></p>
+ <p>(Note: each list item has no content; only the sequencing should appear.)</p>
+
+ <span>
+
+ <p>2, 3, 4 (ol has start attribute of 2)</p>
+ <ol start="2">
+ <li></li>
+ <li></li>
+ <li></li>
+ </ol>
+
+ <p>-9, -8, -7 (ol has start attribute of -9)</p>
+ <ol start="-9">
+ <li></li>
+ <li></li>
+ <li></li>
+ </ol>
+
+ <p>1000, 1001, 1002 (list's start attribute of 1000 provided by JavaScript)</p>
+ <ol id="start_me">
+ <li></li>
+ <li></li>
+ <li></li>
+ </ol>
+
+ <p>2, 1, 9 (each list item has a specified value attribute, list has a start attribute of 1000)</p>
+ <ol istart="1000">
+ <li value="2"></li>
+ <li value="1"></li>
+ <li value="9"></li>
+ </ol>
+
+ </span>
+
+ <script>
+ document.getElementById("start_me").start = 1000;
+ </script>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/grouping-content/the-ol-element/grouping-ol-start-reftest-002-ref.html b/testing/web-platform/tests/html/semantics/grouping-content/the-ol-element/grouping-ol-start-reftest-002-ref.html
new file mode 100644
index 000000000..2ba4af9b1
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/grouping-content/the-ol-element/grouping-ol-start-reftest-002-ref.html
@@ -0,0 +1,57 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>ol element</title>
+ <link rel="author" title="dzenana" href="mailto:dzenana.trenutak@gmail.com">
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-ol-element">
+ <meta name="assert" content="Sequences produced by calculated values for LI elements within OL match spec's expectations. (part two)" />
+ <style type="text/css">
+ span p {display:list-item; margin-left: 0; margin-top: 0; margin-bottom: 0; padding-left: 0; padding-top: 0; padding-bottom: 0;}
+ span span p {margin-left: 0; margin-top: 0; margin-bottom: 0; padding-left: 5em; padding-top: 0; padding-bottom: 0; font-family: monospace;}
+ </style>
+</head>
+<body>
+ <p>This test continues to validate the ol element. This reftest is necessary because the values of the ol's li children as calculated and displayed by the user agent are NOT systematically available programatically. Only explicitly-set values are available programatically. Therefore, we need to check actual rendering against expected rendering.</p>
+
+ <p>The spec states:</p>
+ <blockquote><p>The first item in the list has the ordinal value given by the ol element's start attribute, unless that li element has a value attribute with a value that can be successfully parsed, in which case it has the ordinal value given by that value attribute.</p>
+ <p>Each subsequent item in the list has the ordinal value given by its value attribute, if it has one, or, if it doesn't, the ordinal value of the previous item, plus one if the reversed is absent, or minus one if it is present.</p></blockquote>
+
+ <p><strong>This reftest passes if each list's items are numbered identically to the horizontal sequence immediately above those list items.</strong></p>
+ <p>(Note: each list item has no content; only the sequencing should appear.)</p>
+
+ <span>
+
+ <p>4, 5, 6 (ol has start attribute of 2 which is overridden by first list item's value attribute of 4)</p>
+ <span>
+ <p>4.</p>
+ <p>5.</p>
+ <p>6.</p>
+ </span>
+
+ <p>4, 5, 6 (ol has start attribute of -10 which is overridden by first list item's value attribute of 4)</p>
+ <span>
+ <p>4.</p>
+ <p>5.</p>
+ <p>6.</p>
+ </span>
+
+ <p>1, 5, 6 (2nd list item has value attribute of 5)</p>
+ <span>
+ <p>1.</p>
+ <p>5.</p>
+ <p>6.</p>
+ </span>
+
+ <p>-1, -5, -4 (list has a start attribute of -1, and 2nd list item has value attribute of -5)</p>
+ <span>
+ <p>-1.</p>
+ <p>-5.</p>
+ <p>-4.</p>
+ </span>
+
+ </span>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/grouping-content/the-ol-element/grouping-ol-start-reftest-002.html b/testing/web-platform/tests/html/semantics/grouping-content/the-ol-element/grouping-ol-start-reftest-002.html
new file mode 100644
index 000000000..559e3c219
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/grouping-content/the-ol-element/grouping-ol-start-reftest-002.html
@@ -0,0 +1,61 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>ol element</title>
+ <link rel="author" title="dzenana" href="mailto:dzenana.trenutak@gmail.com">
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-ol-element">
+ <link rel="match" href="grouping-ol-start-reftest-002-ref.html" />
+ <meta name="assert" content="Sequences produced by calculated values for LI elements within OL match spec's expectations. (part two)" />
+ <style type="text/css">
+ span p {display:list-item; margin-left: 0; margin-top: 0; margin-bottom: 0; padding-left: 0; padding-top: 0; padding-bottom: 0;}
+ span li {margin-left: 0; margin-top: 0; margin-bottom: 0; padding-left: 0; padding-top: 0; padding-bottom: 0; font-family: monospace;}
+ span ol {margin-left: 0; margin-top: 0; margin-bottom: 0; padding-left: 5em; padding-top: 0; padding-bottom: 0; font-family: monospace;
+ list-style-position: inside; list-style-type: decimal; }
+ </style>
+</head>
+<body>
+ <p>This test continues to validate the ol element. This reftest is necessary because the values of the ol's li children as calculated and displayed by the user agent are NOT systematically available programatically. Only explicitly-set values are available programatically. Therefore, we need to check actual rendering against expected rendering.</p>
+
+ <p>The spec states:</p>
+ <blockquote><p>The first item in the list has the ordinal value given by the ol element's start attribute, unless that li element has a value attribute with a value that can be successfully parsed, in which case it has the ordinal value given by that value attribute.</p>
+ <p>Each subsequent item in the list has the ordinal value given by its value attribute, if it has one, or, if it doesn't, the ordinal value of the previous item, plus one if the reversed is absent, or minus one if it is present.</p></blockquote>
+
+ <p><strong>This reftest passes if each list's items are numbered identically to the horizontal sequence immediately above those list items.</strong></p>
+ <p>(Note: each list item has no content; only the sequencing should appear.)</p>
+
+ <span>
+
+ <p>4, 5, 6 (ol has start attribute of 2 which is overridden by first list item's value attribute of 4)</p>
+ <ol start="2">
+ <li value="4"></li>
+ <li></li>
+ <li></li>
+ </ol>
+
+ <p>4, 5, 6 (ol has start attribute of -10 which is overridden by first list item's value attribute of 4)</p>
+ <ol start="-10">
+ <li value="4"></li>
+ <li></li>
+ <li></li>
+ </ol>
+
+ <p>1, 5, 6 (2nd list item has value attribute of 5)</p>
+ <ol>
+ <li></li>
+ <li value="5"></li>
+ <li></li>
+ </ol>
+
+ <p>-1, -5, -4 (list has a start attribute of -1, and 2nd list item has value attribute of -5)</p>
+ <ol start="-1">
+ <li></li>
+ <li value="-5"></li>
+ <li></li>
+ </ol>
+
+ </span>
+
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/grouping-content/the-ol-element/grouping-ol-type-reftest-001-ref.html b/testing/web-platform/tests/html/semantics/grouping-content/the-ol-element/grouping-ol-type-reftest-001-ref.html
new file mode 100644
index 000000000..294c9abc2
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/grouping-content/the-ol-element/grouping-ol-type-reftest-001-ref.html
@@ -0,0 +1,55 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>ol element</title>
+ <link rel="author" title="dzenana" href="mailto:dzenana.trenutak@gmail.com">
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-ol-element">
+ <meta name="assert" content="OL's type attribute defaults to decimal state." />
+ <style type="text/css">
+ span p {display:list-item; margin-left: 0; margin-top: 0; margin-bottom: 0; padding-left: 0; padding-top: 0; padding-bottom: 0;}
+ span span p {margin-left: 0; margin-top: 0; margin-bottom: 0; padding-left: 5em; padding-top: 0; padding-bottom: 0; font-family: monospace;}
+ </style>
+</head>
+<body>
+ <p>This test continues to validate the ol element. This reftest is necessary because the values of the ol's li children as calculated and displayed by the user agent are NOT systematically available programatically. Only explicitly-set values are available programatically. Therefore, we need to check actual rendering against expected rendering.</p>
+
+ <p>The spec states:</p>
+ <blockquote><p>The type attribute represents the state given in the cell in the second column of the row whose first cell matches the attribute's value; if none of the cells match, or if the attribute is omitted, then the attribute represents the decimal state.</p></blockquote>
+
+ <p><strong>This reftest passes if each list's items are labelled identically to the horizontal sequence immediately above those list items:</strong></p>
+ <p>(Note: each list item has no content; only the sequencing should appear.)</p>
+
+ <span>
+ <p>1, 2, 3 (default value for unspecified type attribute is 'decimal')</p>
+ <span>
+ <p>1.</p>
+ <p>2.</p>
+ <p>3.</p>
+ </span>
+
+ <p>1, 2, 3 (default value for type attribute not listed in spec table is 'decimal' (type = "!"))</p>
+ <span>
+ <p>1.</p>
+ <p>2.</p>
+ <p>3.</p>
+ </span>
+
+ <p>1, 2, 3 (default value for type attribute not listed in spec table is 'decimal' (type = "2"))</p>
+ <span>
+ <p>1.</p>
+ <p>2.</p>
+ <p>3.</p>
+ </span>
+
+ <p>1, 2, 3 (default value for type attribute not listed in spec table is 'decimal' (type = "b"))</p>
+ <span>
+ <p>1.</p>
+ <p>2.</p>
+ <p>3.</p>
+ </span>
+
+ </span>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/grouping-content/the-ol-element/grouping-ol-type-reftest-001.html b/testing/web-platform/tests/html/semantics/grouping-content/the-ol-element/grouping-ol-type-reftest-001.html
new file mode 100644
index 000000000..32b0e200b
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/grouping-content/the-ol-element/grouping-ol-type-reftest-001.html
@@ -0,0 +1,58 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>ol element</title>
+ <link rel="author" title="dzenana" href="mailto:dzenana.trenutak@gmail.com">
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-ol-element">
+ <link rel="match" href="grouping-ol-type-reftest-001-ref.html" />
+ <meta name="assert" content="OL's type attribute defaults to decimal state." />
+ <style type="text/css">
+ span p {display:list-item; margin-left: 0; margin-top: 0; margin-bottom: 0; padding-left: 0; padding-top: 0; padding-bottom: 0;}
+ span li {margin-left: 0; margin-top: 0; margin-bottom: 0; padding-left: 0; padding-top: 0; padding-bottom: 0; font-family: monospace;}
+ span ol {margin-left: 0; margin-top: 0; margin-bottom: 0; padding-left: 5em; padding-top: 0; padding-bottom: 0; font-family: monospace; list-style-position: inside; }
+ </style>
+</head>
+<body>
+ <p>This test continues to validate the ol element. This reftest is necessary because the values of the ol's li children as calculated and displayed by the user agent are NOT systematically available programatically. Only explicitly-set values are available programatically. Therefore, we need to check actual rendering against expected rendering.</p>
+
+ <p>The spec states:</p>
+ <blockquote><p>The type attribute represents the state given in the cell in the second column of the row whose first cell matches the attribute's value; if none of the cells match, or if the attribute is omitted, then the attribute represents the decimal state.</p></blockquote>
+
+ <p><strong>This reftest passes if each list's items are labelled identically to the horizontal sequence immediately above those list items:</strong></p>
+ <p>(Note: each list item has no content; only the sequencing should appear.)</p>
+
+ <span>
+
+ <p>1, 2, 3 (default value for unspecified type attribute is 'decimal')</p>
+ <ol>
+ <li></li>
+ <li></li>
+ <li></li>
+ </ol>
+
+ <p>1, 2, 3 (default value for type attribute not listed in spec table is 'decimal' (type = "!"))</p>
+ <ol type="!">
+ <li></li>
+ <li></li>
+ <li></li>
+ </ol>
+
+ <p>1, 2, 3 (default value for type attribute not listed in spec table is 'decimal' (type = "2"))</p>
+ <ol type="2">
+ <li></li>
+ <li></li>
+ <li></li>
+ </ol>
+
+ <p>1, 2, 3 (default value for type attribute not listed in spec table is 'decimal' (type = "b"))</p>
+ <ol type="b">
+ <li></li>
+ <li></li>
+ <li></li>
+ </ol>
+
+ </span>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/grouping-content/the-ol-element/grouping-ol-type-reftest-002-ref.html b/testing/web-platform/tests/html/semantics/grouping-content/the-ol-element/grouping-ol-type-reftest-002-ref.html
new file mode 100644
index 000000000..cf31b7a9c
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/grouping-content/the-ol-element/grouping-ol-type-reftest-002-ref.html
@@ -0,0 +1,62 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>ol element</title>
+ <link rel="author" title="dzenana" href="mailto:dzenana.trenutak@gmail.com">
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-ol-element">
+ <meta name="assert" content="List items are rendered consistently with the state of the type attribute." />
+ <style type="text/css">
+ span p {display:list-item; margin-left: 0; margin-top: 0; margin-bottom: 0; padding-left: 0; padding-top: 0; padding-bottom: 0;}
+ span span p {margin-left: 0; margin-top: 0; margin-bottom: 0; padding-left: 5em; padding-top: 0; padding-bottom: 0; font-family: monospace;}
+ </style>
+</head>
+<body>
+ <p>This test continues to validate the ol element. This reftest is necessary because the values of the ol's li children as calculated and displayed by the user agent are NOT systematically available programatically. Only explicitly-set values are available programatically. Therefore, we need to check actual rendering against expected rendering.</p>
+
+ <p>The spec states:</p>
+ <blockquote>User agents should render the items of the list in a manner consistent with the state of the type attribute of the ol element.</blockquote>
+
+ <p><strong>This reftest passes if each list's items are labelled identically to the horizontal sequence immediately above those list items:</strong></p>
+ <p>(Note: each list item has no content; only the sequencing should appear.)</p>
+
+ <span>
+ <p>1, 2, 3 (type attribute of "1" results in decimal type)</p>
+ <span>
+ <p>1.</p>
+ <p>2.</p>
+ <p>3.</p>
+ </span>
+
+ <p>aa, ab, ac (type attribute of "a" results in lower case latin alphabet, start = 27)</p>
+ <span>
+ <p>aa.</p>
+ <p>ab.</p>
+ <p>ac.</p>
+ </span>
+
+ <p>AA, AB, AC (type attribute of "A" results in upper case latin alphabet, start = 27)</p>
+ <span>
+ <p>AA.</p>
+ <p>AB.</p>
+ <p>AC.</p>
+ </span>
+
+ <p>i, v, c (type attribute of "i" results in lower case roman alphabet, list values = 1, 5, 100)</p>
+ <span>
+ <p>i.</p>
+ <p>v.</p>
+ <p>c.</p>
+ </span>
+
+ <p>I, V, C (type attribute of "I" results in upper case roman alphabet, list values = 1, 5, 100)</p>
+ <span>
+ <p>I.</p>
+ <p>V.</p>
+ <p>C.</p>
+ </span>
+
+ </span>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/grouping-content/the-ol-element/grouping-ol-type-reftest-002.html b/testing/web-platform/tests/html/semantics/grouping-content/the-ol-element/grouping-ol-type-reftest-002.html
new file mode 100644
index 000000000..7daea54c0
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/grouping-content/the-ol-element/grouping-ol-type-reftest-002.html
@@ -0,0 +1,65 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>ol element</title>
+ <link rel="author" title="dzenana" href="mailto:dzenana.trenutak@gmail.com">
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-ol-element">
+ <link rel="match" href="grouping-ol-type-reftest-002-ref.html" />
+ <meta name="assert" content="List items are rendered consistently with the state of the type attribute." />
+ <style type="text/css">
+ span p {display:list-item; margin-left: 0; margin-top: 0; margin-bottom: 0; padding-left: 0; padding-top: 0; padding-bottom: 0;}
+ span li {margin-left: 0; margin-top: 0; margin-bottom: 0; padding-left: 0; padding-top: 0; padding-bottom: 0; font-family: monospace;}
+ span ol {margin-left: 0; margin-top: 0; margin-bottom: 0; padding-left: 5em; padding-top: 0; padding-bottom: 0; font-family: monospace; list-style-position: inside;}
+ </style>
+</head>
+<body>
+ <p>This test continues to validate the ol element. This reftest is necessary because the values of the ol's li children as calculated and displayed by the user agent are NOT systematically available programatically. Only explicitly-set values are available programatically. Therefore, we need to check actual rendering against expected rendering.</p>
+
+ <p>The spec states:</p>
+ <blockquote>User agents should render the items of the list in a manner consistent with the state of the type attribute of the ol element.</blockquote>
+
+ <p><strong>This reftest passes if each list's items are labelled identically to the horizontal sequence immediately above those list items:</strong></p>
+ <p>(Note: each list item has no content; only the sequencing should appear.)</p>
+
+ <span>
+
+ <p>1, 2, 3 (type attribute of "1" results in decimal type)</p>
+ <ol type="1">
+ <li></li>
+ <li></li>
+ <li></li>
+ </ol>
+
+ <p>aa, ab, ac (type attribute of "a" results in lower case latin alphabet, start = 27)</p>
+ <ol type="a" start="27">
+ <li></li>
+ <li></li>
+ <li></li>
+ </ol>
+
+ <p>AA, AB, AC (type attribute of "A" results in upper case latin alphabet, start = 27)</p>
+ <ol type="A" start="27">
+ <li></li>
+ <li></li>
+ <li></li>
+ </ol>
+
+ <p>i, v, c (type attribute of "i" results in lower case roman alphabet, list values = 1, 5, 100)</p>
+ <ol type="i">
+ <li value="1"></li>
+ <li value="5"></li>
+ <li value="100"></li>
+ </ol>
+
+ <p>I, V, C (type attribute of "I" results in upper case roman alphabet, list values = 1, 5, 100)</p>
+ <ol type="I">
+ <li value="1"></li>
+ <li value="5"></li>
+ <li value="100"></li>
+ </ol>
+
+ </span>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/grouping-content/the-ol-element/grouping-ol-type-reftest-003-ref.html b/testing/web-platform/tests/html/semantics/grouping-content/the-ol-element/grouping-ol-type-reftest-003-ref.html
new file mode 100644
index 000000000..4906f3ca6
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/grouping-content/the-ol-element/grouping-ol-type-reftest-003-ref.html
@@ -0,0 +1,78 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>ol element</title>
+ <link rel="author" title="dzenana" href="mailto:dzenana.trenutak@gmail.com">
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-ol-element">
+ <meta name="assert" content="OL's type attribute defaults to decimal state." />
+ <style type="text/css">
+ span p {display:list-item; margin-left: 0; margin-top: 0; margin-bottom: 0; padding-left: 0; padding-top: 0; padding-bottom: 0;}
+ span span p {margin-left: 0; margin-top: 0; margin-bottom: 0; padding-left: 5em; padding-top: 0; padding-bottom: 0; font-family: monospace;}
+ </style>
+</head>
+<body>
+ <p>This test continues to validate the ol element. This reftest is necessary because the values of the ol's li children as calculated and displayed by the user agent are NOT systematically available programatically. Only explicitly-set values are available programatically. Therefore, we need to check actual rendering against expected rendering.</p>
+
+ <p>The spec states: Numbers less than or equal to zero should always use the decimal system regardless of the type attribute.</p>
+
+ <p><strong>This reftest passes if each list's items are labelled identically to the horizontal sequence immediately above those list items:</strong></p>
+ <p>(Note: each list item has no content; only the sequencing should appear.)</p>
+
+ <span>
+ <p>-3, -2, -1 (type is "a", start is -3)</p>
+ <span>
+ <p>-3.</p>
+ <p>-2.</p>
+ <p>-1.</p>
+ </span>
+
+ <p>0, a (type is "a", start is 0)</p>
+ <span>
+ <p>0.</p>
+ <p>a.</p>
+ </span>
+
+ <p>-3, -2, -1 (type is "A", start is -3)</p>
+ <span>
+ <p>-3.</p>
+ <p>-2.</p>
+ <p>-1.</p>
+ </span>
+
+ <p>0, A (type is "A", start is 0)</p>
+ <span>
+ <p>0.</p>
+ <p>A.</p>
+ </span>
+
+ <p>-3, -2, -1 (type is "i", start is -3)</p>
+ <span>
+ <p>-3.</p>
+ <p>-2.</p>
+ <p>-1.</p>
+ </span>
+
+ <p>0, i (type is "i", start is 0)</p>
+ <span>
+ <p>0.</p>
+ <p>i.</p>
+ </span>
+
+ <p>-3, -2, -1 (type is "I", start is -3)</p>
+ <span>
+ <p>-3.</p>
+ <p>-2.</p>
+ <p>-1.</p>
+ </span>
+
+ <p>0, I (type is "I", start is 0)</p>
+ <span>
+ <p>0.</p>
+ <p>I.</p>
+ </span>
+
+ </span>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/grouping-content/the-ol-element/grouping-ol-type-reftest-003.html b/testing/web-platform/tests/html/semantics/grouping-content/the-ol-element/grouping-ol-type-reftest-003.html
new file mode 100644
index 000000000..5e4b5a588
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/grouping-content/the-ol-element/grouping-ol-type-reftest-003.html
@@ -0,0 +1,81 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>ol element</title>
+ <link rel="author" title="dzenana" href="mailto:dzenana.trenutak@gmail.com">
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-ol-element">
+ <link rel="match" href="grouping-ol-type-reftest-003-ref.html" />
+ <meta name="assert" content="OL's type attribute defaults to decimal state." />
+ <style type="text/css">
+ span p {display:list-item; margin-left: 0; margin-top: 0; margin-bottom: 0; padding-left: 0; padding-top: 0; padding-bottom: 0;}
+ span li {margin-left: 0; margin-top: 0; margin-bottom: 0; padding-left: 0; padding-top: 0; padding-bottom: 0; font-family: monospace;}
+ span ol {margin-left: 0; margin-top: 0; margin-bottom: 0; padding-left: 5em; padding-top: 0; padding-bottom: 0; font-family: monospace; list-style-position: inside;}
+ </style>
+</head>
+<body>
+ <p>This test continues to validate the ol element. This reftest is necessary because the values of the ol's li children as calculated and displayed by the user agent are NOT systematically available programatically. Only explicitly-set values are available programatically. Therefore, we need to check actual rendering against expected rendering.</p>
+
+ <p>The spec states: Numbers less than or equal to zero should always use the decimal system regardless of the type attribute.</p>
+
+ <p><strong>This reftest passes if each list's items are labelled identically to the horizontal sequence immediately above those list items:</strong></p>
+ <p>(Note: each list item has no content; only the sequencing should appear.)</p>
+
+ <span>
+
+ <p>-3, -2, -1 (type is "a", start is -3)</p>
+ <ol type="a" start="-3">
+ <li></li>
+ <li></li>
+ <li></li>
+ </ol>
+
+ <p>0, a (type is "a", start is 0)</p>
+ <ol type="a" start="0">
+ <li></li>
+ <li></li>
+ </ol>
+
+ <p>-3, -2, -1 (type is "A", start is -3)</p>
+ <ol type="A" start="-3">
+ <li></li>
+ <li></li>
+ <li></li>
+ </ol>
+
+ <p>0, A (type is "A", start is 0)</p>
+ <ol type="A" start="0">
+ <li></li>
+ <li></li>
+ </ol>
+
+ <p>-3, -2, -1 (type is "i", start is -3)</p>
+ <ol type="i" start="-3">
+ <li></li>
+ <li></li>
+ <li></li>
+ </ol>
+
+ <p>0, i (type is "i", start is 0)</p>
+ <ol type="i" start="0">
+ <li></li>
+ <li></li>
+ </ol>
+
+ <p>-3, -2, -1 (type is "I", start is -3)</p>
+ <ol type="I" start="-3">
+ <li></li>
+ <li></li>
+ <li></li>
+ </ol>
+
+ <p>0, I (type is "I", start is 0)</p>
+ <ol type="I" start="0">
+ <li></li>
+ <li></li>
+ </ol>
+
+ </span>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/grouping-content/the-ol-element/grouping-ol.html b/testing/web-platform/tests/html/semantics/grouping-content/the-ol-element/grouping-ol.html
new file mode 100644
index 000000000..0de2a0641
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/grouping-content/the-ol-element/grouping-ol.html
@@ -0,0 +1,314 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>the ol element</title>
+ <link rel="author" title="dzenana" href="mailto:dzenana.trenutak@gmail.com">
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-ol-element">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+</head>
+<body>
+ <h1>Description</h1>
+ <p>This test validates the ol element.</p>
+
+ <div id="log"></div>
+
+ <p>Ordered List</p>
+ <ol id="basic">
+ <li>list item</li>
+ <li>list item</li>
+ <li>list item</li>
+ </ol>
+
+ <p>Ordered List</p>
+ <ol id="allAtts" reversed start="3" type="A">
+ <li>list item</li>
+ <li>list item</li>
+ <li>list item</li>
+ </ol>
+
+ <p>Ordered List</p>
+ <ol id="justRev" reversed>
+ <li>list item</li>
+ <li>list item</li>
+ <li>list item</li>
+ </ol>
+
+ <p>Ordered List</p>
+ <ol id="basicRevGoodName" reversed="reversed">
+ <li>list item</li>
+ <li>list item</li>
+ <li>list item</li>
+ </ol>
+
+ <p>Ordered List</p>
+ <ol id="basicRevNameWithSpace" reversed=" reversed ">
+ <li>list item</li>
+ <li>list item</li>
+ <li>list item</li>
+ </ol>
+
+ <p>Ordered List</p>
+ <ol id="basicRevEmpty" reversed="" start="A">
+ <li>list item</li>
+ <li>list item</li>
+ <li>list item</li>
+ </ol>
+
+ <p>Ordered List</p>
+ <ol id="basicRevTrue" reversed="true">
+ <li>list item</li>
+ <li>list item</li>
+ <li>list item</li>
+ </ol>
+
+ <p>Ordered List</p>
+ <ol id="basicRevFalse" reversed="false">
+ <li>list item</li>
+ <li>list item</li>
+ <li>list item</li>
+ </ol>
+
+ <p>Ordered List</p>
+ <ol id="start2" start="2">
+ <li>list item</li>
+ <li>list item</li>
+ <li>list item</li>
+ </ol>
+
+ <p>Ordered List</p>
+ <ol id="negative" start="-10">
+ <li>list item</li>
+ <li>list item</li>
+ <li>list item</li>
+ </ol>
+
+ <p>Ordered List</p>
+ <ol id="posFloatDown" start="4.03">
+ <li>list item</li>
+ <li>list item</li>
+ <li>list item</li>
+ </ol>
+
+ <p>Ordered List</p>
+ <ol id="negFloatDown" start="-4.03">
+ <li>list item</li>
+ <li>list item</li>
+ <li>list item</li>
+ </ol>
+
+ <p>Ordered List</p>
+ <ol id="posFloatUp" start="4.9">
+ <li>list item</li>
+ <li>list item</li>
+ <li>list item</li>
+ </ol>
+
+ <p>Ordered List</p>
+ <ol id="negFloatUp" start="-4.9">
+ <li>list item</li>
+ <li>list item</li>
+ <li>list item</li>
+ </ol>
+
+ <p>Ordered List</p>
+ <ol id="exponent" start="7e2">
+ <li>list item</li>
+ <li>list item</li>
+ <li>list item</li>
+ </ol>
+
+ <p>Ordered List</p>
+ <ol id="decimal" start=".5">
+ <li>list item</li>
+ <li>list item</li>
+ <li>list item</li>
+ </ol>
+
+ <p>Ordered List</p>
+ <ol id="letter" start="A">
+ <li>list item</li>
+ <li>list item</li>
+ <li>list item</li>
+ </ol>
+
+ <p>Ordered List</p>
+ <ol id="middle50">
+ <li>list item</li>
+ <li value="50">list item</li>
+ <li>list item</li>
+ </ol>
+
+ <p>Ordered List</p>
+ <ol id="middleneg50">
+ <li>list item</li>
+ <li value="-50">list item</li>
+ <li>list item</li>
+ </ol>
+
+ <p>Ordered List</p>
+ <ol id="lots" reversed="reversed">
+ <li value="10">list item</li>
+ <li value="20">list item</li>
+<a></a><abbr></abbr><address></address><area></area><article></article><aside></aside><audio></audio><b></b><base></base><bdi></bdi><bdo></bdo><blockquote></blockquote><body></body><br></br><button></button><canvas></canvas><caption></caption><cite></cite><code></code><col></col><colgroup></colgroup><command></command><datalist></datalist><dd></dd><del></del><details></details><dfn></dfn><dialog></dialog><div></div><dl></dl><dt></dt><em></em><embed></embed><fieldset></fieldset><figcaption></figcaption><figure></figure><footer></footer><form></form><h1></h1><h2></h2><h3></h3><h4></h4><h5></h5><h6></h6><head></head><header></header><hgroup></hgroup><hr></hr><html></html><i></i><iframe></iframe><img></img><input></input><ins></ins><kbd></kbd><keygen></keygen><label></label><legend></legend><link></link><map></map><mark></mark><menu></menu><meta></meta><meter></meter><nav></nav><noscript></noscript><object></object><ol><li></li><li></li></ol><optgroup></optgroup><option></option><output></output><p></p><param></param><pre></pre><progress></progress><q></q><rp></rp><rt></rt><ruby></ruby><s></s><samp></samp><script></script><section></section><select></select><small></small><source></source><span></span><strong></strong><style></style><sub></sub><summary></summary><sup></sup><table></table><tbody></tbody><td></td><textarea></textarea><tfoot></tfoot><th></th><thead></thead><time></time><title></title><tr></tr><track></track><u></u><ul><li></li><li></li></ul><var></var><video></video><wbr></wbr>
+ <li value="-99">list item</li>
+ </ol>
+
+ <script>
+ "use strict";
+
+ var testList;
+
+ // check that prototype matches spec's DOM interface
+ test(function () {
+ testList = document.getElementById("basic");
+ assert_equals(Object.getPrototypeOf(testList), HTMLOListElement.prototype, "HTMLOListElement.prototype should be used for OL");
+ }, "The prototype for OL is HTMLOListElement.prototype");
+
+ // check that "own" properties reversed, start, and type are present
+ test(function () {
+ testList = document.getElementById("basic");
+ assert_idl_attribute(testList, "reversed");
+ }, "'reversed' property should be defined on OL.");
+
+ test(function () {
+ testList = document.getElementById("basic");
+ assert_idl_attribute(testList, "start");
+ }, "'start' property should be defined on OL.");
+
+ test(function () {
+ testList = document.getElementById("basic");
+ assert_idl_attribute(testList, "type");
+ }, "'type' property should be defined on OL.");
+
+ // "The reversed, start, and type IDL attributes must reflect the respective content attributes of the same name."
+ test(function () {
+ testList = document.getElementById("allAtts");
+ assert_true(testList.reversed);
+ }, "OL's 'reversed' IDL property reflects content attribute.");
+
+ test(function () {
+ testList = document.getElementById("allAtts");
+ assert_equals(testList.start, 3);
+ }, "OL's 'start' IDL property reflects content attribute.");
+
+ test(function () {
+ testList = document.getElementById("allAtts");
+ assert_equals(testList.type, "A");
+ }, "OL's 'type' IDL property reflects content attribute.");
+
+
+ // "The reversed attribute is a boolean attribute."
+
+ // check lists for which reversed value should be false
+ test(function() {
+ assert_false(document.getElementById("basic").reversed, "IDL 'reversed' attribute value false when content attribute absent");
+ }, "IDL 'reversed' attribute value false when content attribute absent");
+
+ // check lists for which reversed value should be true
+ test(function() {
+ assert_true(document.getElementById("justRev").reversed);
+ assert_true(document.getElementById("basicRevGoodName").reversed);
+ assert_true(document.getElementById("basicRevNameWithSpace").reversed);
+ assert_true(document.getElementById("basicRevEmpty").reversed);
+ assert_true(document.getElementById("basicRevTrue").reversed);
+ assert_true(document.getElementById("basicRevFalse").reversed);
+ }, "IDL 'reversed' attribute value true when content attribute exists");
+
+ // check that IDL property works to change reversed value
+ test(function() {
+ document.getElementById("justRev").reversed = false;
+ assert_false(document.getElementById("justRev").reversed, "Changing IDL 'reversed' property changes list's reversed property.");
+ }, "Changing IDL 'reversed' property changes list's reversed property.");
+
+
+ // If the start attribute is present, user agents must parse it as an integer, in order to determine the attribute's value.
+ // The default value, used if the attribute is missing or
+ // if the value cannot be converted to a number according to the referenced algorithm,
+ // is 1 if the element has no reversed attribute, and
+ // is the number of child li elements otherwise."
+ // "The start IDL attribute has the same default as its content attribute."
+
+ // basic - default should be 1
+ test(function() {
+ assert_equals(document.getElementById("basic").start, 1, "no start attribute provided -> 1");
+ }, "Default start value for non-reversed list should be 1");
+
+ // decimal's first element has value of .5 which should return 1
+ test(function() {
+ assert_equals(document.getElementById("decimal").start, 1, "start of .5 -> 1 (default)");
+ }, "IDL and content attribute parse start of '.5' correctly.");
+
+ // letter's first element has value of A which should return 1
+ test(function() {
+ assert_equals(document.getElementById("letter").start, 1, "start of A -> 1 (default)");
+ }, "IDL and content attribute parse start of 'A' correctly.");
+
+ // basicRevGoodName - default should be 3
+ test(function() {
+ assert_equals(document.getElementById("basicRevGoodName").start, 3, "no start attribute provided -> 3");
+ }, "Default start value (if none provided) for reversed list = child li elements.");
+
+ // basicRevEmpty - default should be 3
+ test(function() {
+ assert_equals(document.getElementById("basicRevEmpty").start, 3, "start of A -> 3 (default)");
+ }, "Default start value (if failed to parse) for reversed list = child li elements.");
+
+ // lots - default should be 3
+ test(function() {
+ assert_equals(document.getElementById("lots").start, 3, "no start attribute -> 3 (default)");
+ }, "Default start value for reversed list = child li elements (even with tons of other child elements).");
+
+ // adding child element changes default start value for reversed list
+ test(function() {
+ var myList = document.getElementById("basicRevGoodName"), myLI = document.createElement("li");
+ myList.appendChild(myLI);
+ assert_equals(document.getElementById("basicRevGoodName").start, 4, "Adding child element to reversed list adds 1 to start value");
+ }, "Adding child element to reversed list adds 1 to start value");
+
+ // removing child element changes default start value for reversed list
+ test(function() {
+ var myList = document.getElementById("basicRevTrue");
+ myList.removeChild(myList.children[0]);
+ assert_equals(document.getElementById("basicRevTrue").start, 2, "Deleting child element from reversed list reduces start value by 1");
+ }, "Deleting child element from reversed list reduces start value by 1");
+
+ // start2's first element has value of 2
+ test(function() {
+ assert_equals(document.getElementById("start2").start, 2, "start of 2 -> 2");
+ }, "IDL and content attribute parse start of '2' correctly.");
+
+ // negative's first element has value of -10
+ test(function() {
+ assert_equals(document.getElementById("negative").start, -10, "start of -10 -> -10");
+ }, "IDL and content attribute parse start of '-10' correctly.");
+
+ // posFloatDown's first element has value of 4.03 which should return 4
+ test(function() {
+ assert_equals(document.getElementById("posFloatDown").start, 4, "start of 4.03 -> 4");
+ }, "IDL and content attribute parse start of '4.03' correctly.");
+
+ // negFloatDown's first element has value of -4.03 which should return -4
+ test(function() {
+ assert_equals(document.getElementById("negFloatDown").start, -4, "start of -4.03 -> -4");
+ }, "IDL and content attribute parse start of '-4.03' correctly.");
+
+ // posFloatUp's first element has value of 4.9 which should return 4
+ test(function() {
+ assert_equals(document.getElementById("posFloatUp").start, 4, "start of 4.9 -> 4");
+ }, "IDL and content attribute parse start of '4.9' correctly.");
+
+ // negFloatUp's first element has value of -4.9 which should return -4
+ test(function() {
+ assert_equals(document.getElementById("negFloatUp").start, -4, "start of -4.9 -> -4");
+ }, "IDL and content attribute parse start of '-4.9' correctly.");
+
+ // exponent's first element has value of 7e2 which should return 7
+ test(function() {
+ assert_equals(document.getElementById("exponent").start, 7, "start of 7e2 -> 7");
+ }, "IDL and content attribute parse start of '7e2' correctly.");
+
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/grouping-content/the-ol-element/ol.start-reflection-1.html b/testing/web-platform/tests/html/semantics/grouping-content/the-ol-element/ol.start-reflection-1.html
new file mode 100644
index 000000000..7f2a00c70
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/grouping-content/the-ol-element/ol.start-reflection-1.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>ol.start - reflection test</title>
+ <link rel="author" title="Shiki Okasaka" href="http://shiki.esrille.com/">
+ <link rel="author" title="Esrille Inc." href="http://www.esrille.com/">
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-ol-element">
+ <meta name="assert" content="This test checks that the start IDL attribute reflects the respective content attribute of the same name.">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+ <body>
+ <ol id="ol">
+ <li>One</li>
+ <li>Two</li>
+ <li>Three</li>
+ </ol>
+ <div id="log"></div>
+ <script>
+test(function() {
+ assert_equals(document.getElementById('ol').start, 1);
+})
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/grouping-content/the-ol-element/ol.start-reflection-2.html b/testing/web-platform/tests/html/semantics/grouping-content/the-ol-element/ol.start-reflection-2.html
new file mode 100644
index 000000000..f6a260a8b
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/grouping-content/the-ol-element/ol.start-reflection-2.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>ol.start - reflection test</title>
+ <link rel="author" title="Shiki Okasaka" href="http://shiki.esrille.com/">
+ <link rel="author" title="Esrille Inc." href="http://www.esrille.com/">
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-ol-element">
+ <meta name="assert" content="This test checks that the start IDL attribute reflects the respective content attribute of the same name.">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+ <body>
+ <ol id='ol' reversed>
+ <li>Three</li>
+ <li>Two</li>
+ <li>One</li>
+ </ol>
+ <div id='log'></div>
+ <script>
+test(function() {
+ assert_equals(document.getElementById('ol').start, 3);
+})
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/grouping-content/the-ol-element/reversed-1-ref.html b/testing/web-platform/tests/html/semantics/grouping-content/the-ol-element/reversed-1-ref.html
new file mode 100644
index 000000000..f8cac3c70
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/grouping-content/the-ol-element/reversed-1-ref.html
@@ -0,0 +1,6 @@
+<!DOCTYPE html>
+<ol>
+ <li value="3">Three</li>
+ <li value="2">Two</li>
+ <li value="1">One</li>
+</ol>
diff --git a/testing/web-platform/tests/html/semantics/grouping-content/the-ol-element/reversed-1a.html b/testing/web-platform/tests/html/semantics/grouping-content/the-ol-element/reversed-1a.html
new file mode 100644
index 000000000..202315b1c
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/grouping-content/the-ol-element/reversed-1a.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>`reversed` should reverse the numbering correctly</title>
+<link rel=match href="reversed-1-ref.html">
+<link rel=help href="https://html.spec.whatwg.org/#attr-ol-reversed">
+<ol reversed>
+ <li>Three</li>
+ <li>Two</li>
+ <li>One</li>
+</ol>
diff --git a/testing/web-platform/tests/html/semantics/grouping-content/the-ol-element/reversed-1b.html b/testing/web-platform/tests/html/semantics/grouping-content/the-ol-element/reversed-1b.html
new file mode 100644
index 000000000..4d6202943
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/grouping-content/the-ol-element/reversed-1b.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Dynamically setting `reversed` should update the numbering</title>
+<link rel=match href="reversed-1-ref.html">
+<link rel=help href="https://html.spec.whatwg.org/#attr-ol-reversed">
+<ol id="x">
+ <li>Three</li>
+ <li>Two</li>
+ <li>One</li>
+</ol>
+<script>
+ var l = document.getElementById("x");
+ var w = l.offsetWidth;
+ l.setAttribute("reversed", "");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/grouping-content/the-ol-element/reversed-1c.html b/testing/web-platform/tests/html/semantics/grouping-content/the-ol-element/reversed-1c.html
new file mode 100644
index 000000000..6fad13053
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/grouping-content/the-ol-element/reversed-1c.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Reversed numbering should update on dynamic addition of child nodes</title>
+<link rel=match href="reversed-1-ref.html">
+<link rel=help href="https://html.spec.whatwg.org/#attr-ol-reversed">
+<ol id="x" reversed>
+ <li>Three</li>
+ <li>Two</li>
+</ol>
+<script>
+ var l = document.getElementById("x");
+ var w = l.offsetWidth;
+ var li = document.createElement("li");
+ li.textContent = "One"
+ l.appendChild(li);
+</script>
diff --git a/testing/web-platform/tests/html/semantics/grouping-content/the-ol-element/reversed-1d.html b/testing/web-platform/tests/html/semantics/grouping-content/the-ol-element/reversed-1d.html
new file mode 100644
index 000000000..a256b6a42
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/grouping-content/the-ol-element/reversed-1d.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Reverse numbering should not be affected by nested div</title>
+<link rel=match href="reversed-1-ref.html">
+<link rel=help href="https://html.spec.whatwg.org/#attr-ol-reversed">
+<ol reversed>
+ <li>Three</li>
+ <div>
+ <li>Two</li>
+ <li>One</li>
+ </div>
+</ol>
diff --git a/testing/web-platform/tests/html/semantics/grouping-content/the-ol-element/reversed-1e.html b/testing/web-platform/tests/html/semantics/grouping-content/the-ol-element/reversed-1e.html
new file mode 100644
index 000000000..48a279994
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/grouping-content/the-ol-element/reversed-1e.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Reverse numbering should not count display:none elements</title>
+<link rel=match href="reversed-1-ref.html">
+<link rel=help href="https://html.spec.whatwg.org/#attr-ol-reversed">
+<ol reversed>
+ <li>Three</li>
+ <li style="display:none">Three</li>
+ <li>Two</li>
+ <li>One</li>
+</ol>
diff --git a/testing/web-platform/tests/html/semantics/grouping-content/the-ol-element/reversed-2-ref.html b/testing/web-platform/tests/html/semantics/grouping-content/the-ol-element/reversed-2-ref.html
new file mode 100644
index 000000000..4f3ece2be
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/grouping-content/the-ol-element/reversed-2-ref.html
@@ -0,0 +1,6 @@
+<!DOCTYPE html>
+<ol>
+ <li value="5">Five</li>
+ <li value="4">Four</li>
+ <li value="3">Three</li>
+</ol>
diff --git a/testing/web-platform/tests/html/semantics/grouping-content/the-ol-element/reversed-2.html b/testing/web-platform/tests/html/semantics/grouping-content/the-ol-element/reversed-2.html
new file mode 100644
index 000000000..0d4948153
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/grouping-content/the-ol-element/reversed-2.html
@@ -0,0 +1,7 @@
+<!DOCTYPE html>
+<link rel="match" href="reversed-2-ref.html">
+<ol reversed start="5">
+ <li>Five</li>
+ <li>Four</li>
+ <li>Three</li>
+</ol>
diff --git a/testing/web-platform/tests/html/semantics/grouping-content/the-p-element/.gitkeep b/testing/web-platform/tests/html/semantics/grouping-content/the-p-element/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/grouping-content/the-p-element/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/grouping-content/the-p-element/grouping-p.html b/testing/web-platform/tests/html/semantics/grouping-content/the-p-element/grouping-p.html
new file mode 100644
index 000000000..5f15aca31
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/grouping-content/the-p-element/grouping-p.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>the p element</title>
+ <link rel="author" title="dzenana" href="mailto:dzenana.trenutak@gmail.com">
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-p-element">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script>
+ "use strict";
+
+ // check that prototype matches spec's DOM interface
+ test(function () {
+ var testElement = document.createElement("p");
+ assert_equals(Object.getPrototypeOf(testElement), HTMLParagraphElement.prototype, "HTMLParagraphElement.prototype should be used for p");
+ }, "The prototype for p is HTMLParagraphElement.prototype");
+
+ </script>
+</head>
+<body>
+ <h1>Description</h1>
+ <p>This test validates the p element.</p>
+
+ <div id="log"></div>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/grouping-content/the-pre-element/.gitkeep b/testing/web-platform/tests/html/semantics/grouping-content/the-pre-element/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/grouping-content/the-pre-element/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/grouping-content/the-pre-element/grouping-pre-reftest-001-ref.html b/testing/web-platform/tests/html/semantics/grouping-content/the-pre-element/grouping-pre-reftest-001-ref.html
new file mode 100644
index 000000000..75aa91b30
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/grouping-content/the-pre-element/grouping-pre-reftest-001-ref.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>pre element</title>
+ <link rel="author" title="dzenana" href="mailto:dzenana.trenutak@gmail.com">
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-pre-element">
+ <meta name="assert" content="Newlines within pre elements separate paragraphs for the purposes of BIDI." />
+</head>
+<body>
+ <h1>Description</h1>
+ <p>This test continues to validate the pre element.</p>
+
+ <p>The spec states:</p>
+ <blockquote>"A newline in a pre element should separate paragraphs for the purposes of the Unicode bidirectional algorithm. This requirement may be implemented indirectly through the style layer. For example, an HTML+CSS user agent could implement these requirements by implementing the CSS 'unicode-bidi' property."</blockquote>
+
+ <p>This reftest passes if below you see "ABC ABC" repeated on two separate lines below (4 ABCs total):</p>
+
+ <pre>ABC ABC
+ABC ABC</pre>
+
+</html>
diff --git a/testing/web-platform/tests/html/semantics/grouping-content/the-pre-element/grouping-pre-reftest-001.html b/testing/web-platform/tests/html/semantics/grouping-content/the-pre-element/grouping-pre-reftest-001.html
new file mode 100644
index 000000000..29e582edd
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/grouping-content/the-pre-element/grouping-pre-reftest-001.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>pre element</title>
+ <link rel="author" title="dzenana" href="mailto:dzenana.trenutak@gmail.com">
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-pre-element">
+ <link rel="match" href="grouping-pre-reftest-001-ref.html" />
+ <meta name="assert" content="Newlines within pre elements separate paragraphs for the purposes of BIDI." />
+</head>
+<body>
+ <h1>Description</h1>
+ <p>This test continues to validate the pre element.</p>
+
+ <p>The spec states:</p>
+ <blockquote>"A newline in a pre element should separate paragraphs for the purposes of the Unicode bidirectional algorithm. This requirement may be implemented indirectly through the style layer. For example, an HTML+CSS user agent could implement these requirements by implementing the CSS 'unicode-bidi' property."</blockquote>
+
+ <p>This reftest passes if below you see "ABC ABC" repeated on two separate lines below (4 ABCs total):</p>
+
+ <pre>&#x202E CBA CBA
+ABC ABC</pre>
+
+</html>
diff --git a/testing/web-platform/tests/html/semantics/grouping-content/the-pre-element/grouping-pre.html b/testing/web-platform/tests/html/semantics/grouping-content/the-pre-element/grouping-pre.html
new file mode 100644
index 000000000..07fc631b9
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/grouping-content/the-pre-element/grouping-pre.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>the pre element</title>
+ <link rel="author" title="dzenana" href="mailto:dzenana.trenutak@gmail.com">
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-pre-element">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+</head>
+<body>
+ <h1>Description</h1>
+ <p>This test validates the pre element.</p>
+
+ <div id="log"></div>
+
+ <script>
+ "use strict";
+
+ // check that prototype matches spec's DOM interface
+ test(function () {
+ var testElement = document.createElement("pre");
+ assert_equals(Object.getPrototypeOf(testElement), HTMLPreElement.prototype, "HTMLPreElement.prototype should be used for pre");
+ }, "The prototype for pre is HTMLPreElement.prototype");
+
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/grouping-content/the-pre-element/pre-newline-bidi-ref.html b/testing/web-platform/tests/html/semantics/grouping-content/the-pre-element/pre-newline-bidi-ref.html
new file mode 100644
index 000000000..0f302b5d4
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/grouping-content/the-pre-element/pre-newline-bidi-ref.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>HTML Test reference: newline in &lt;pre&gt; separates bidi paragraphs</title>
+ <link rel="author" title="Amir E. Aharoni" href="mailto:amir.aharoni@mail.huji.ac.il"/>
+ <link rel="author" title="Eyal Sela" href="mailto:eyal@post.isoc.org.il"/>
+ <link rel="author" title="Aharon Lanin" href="mailto:aharon@google.com"/>
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-pre-element"/>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the rightmost character in the first line below is a full stop and to the left of it is a Hebrew letter.</p></div>
+ <div class="test">
+ <pre>
+A Hebrew letter and a full stop: &#x05d0;.&lrm;
+&#x05d0; this line begins with a Hebrew letter.
+ </pre>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/grouping-content/the-pre-element/pre-newline-bidi.html b/testing/web-platform/tests/html/semantics/grouping-content/the-pre-element/pre-newline-bidi.html
new file mode 100644
index 000000000..23d442f52
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/grouping-content/the-pre-element/pre-newline-bidi.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8"/>
+ <title>HTML Test: newline in pre separates bidi paragraphs</title>
+ <link rel="match" href="pre-newline-bidi-ref.html" />
+ <link rel="author" title="Amir E. Aharoni" href="mailto:amir.aharoni@mail.huji.ac.il"/>
+ <link rel="author" title="Eyal Sela" href="mailto:eyal@post.isoc.org.il"/>
+ <link rel="author" title="Aharon Lanin" href="mailto:aharon@google.com"/>
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-pre-element"/>
+ <meta name="assert"
+ content="A newline in a pre element should separate paragraphs for the purposes of the Unicode bidirectional algorithm."/>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the rightmost character in the first line below is a full stop and to the left of it is a Hebrew letter.</p></div>
+ <div class="test">
+ <pre>
+A Hebrew letter and a full stop: &#x05d0;.
+&#x05d0; this line begins with a Hebrew letter.
+ </pre>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/grouping-content/the-ul-element/.gitkeep b/testing/web-platform/tests/html/semantics/grouping-content/the-ul-element/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/grouping-content/the-ul-element/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/grouping-content/the-ul-element/grouping-ul.html b/testing/web-platform/tests/html/semantics/grouping-content/the-ul-element/grouping-ul.html
new file mode 100644
index 000000000..6e62343f6
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/grouping-content/the-ul-element/grouping-ul.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <title>the ul element</title>
+ <link rel="author" title="dzenana" href="mailto:dzenana.trenutak@gmail.com">
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-ul-element">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script>
+ "use strict";
+
+ // check that prototype matches spec's DOM interface
+ test(function () {
+ var testElement = document.createElement("ul");
+ assert_equals(Object.getPrototypeOf(testElement), HTMLUListElement.prototype, "HTMLUListElement.prototype should be used for ul");
+ }, "The prototype for ul is HTMLUListElement.prototype");
+
+ </script>
+</head>
+<body>
+ <h1>Description</h1>
+ <p>This test validates the ul element.</p>
+
+ <div id="log"></div>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/interactive-elements/.gitkeep b/testing/web-platform/tests/html/semantics/interactive-elements/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/interactive-elements/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/interactive-elements/commands/.gitkeep b/testing/web-platform/tests/html/semantics/interactive-elements/commands/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/interactive-elements/commands/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/interactive-elements/commands/contains.json b/testing/web-platform/tests/html/semantics/interactive-elements/commands/contains.json
new file mode 100644
index 000000000..b2ca2e771
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/interactive-elements/commands/contains.json
@@ -0,0 +1,38 @@
+[
+ {
+ "id": "using-the-a-element-to-define-a-command",
+ "original_id": "using-the-a-element-to-define-a-command"
+ },
+ {
+ "id": "using-the-button-element-to-define-a-command",
+ "original_id": "using-the-button-element-to-define-a-command"
+ },
+ {
+ "id": "using-the-input-element-to-define-a-command",
+ "original_id": "using-the-input-element-to-define-a-command"
+ },
+ {
+ "id": "using-the-option-element-to-define-a-command",
+ "original_id": "using-the-option-element-to-define-a-command"
+ },
+ {
+ "id": "using-the-command-element-to-define-a-command",
+ "original_id": "using-the-command-element-to-define-a-command"
+ },
+ {
+ "id": "using-the-command-attribute-on-command-elements-to-define-a-command-indirectly",
+ "original_id": "using-the-command-attribute-on-command-elements-to-define-a-command-indirectly"
+ },
+ {
+ "id": "using-the-accesskey-attribute-on-a-label-element-to-define-a-command",
+ "original_id": "using-the-accesskey-attribute-on-a-label-element-to-define-a-command"
+ },
+ {
+ "id": "using-the-accesskey-attribute-on-a-legend-element-to-define-a-command",
+ "original_id": "using-the-accesskey-attribute-on-a-legend-element-to-define-a-command"
+ },
+ {
+ "id": "using-the-accesskey-attribute-to-define-a-command-on-other-elements",
+ "original_id": "using-the-accesskey-attribute-to-define-a-command-on-other-elements"
+ }
+] \ No newline at end of file
diff --git a/testing/web-platform/tests/html/semantics/interactive-elements/the-command-element/.gitkeep b/testing/web-platform/tests/html/semantics/interactive-elements/the-command-element/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/interactive-elements/the-command-element/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/interactive-elements/the-details-element/.gitkeep b/testing/web-platform/tests/html/semantics/interactive-elements/the-details-element/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/interactive-elements/the-details-element/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/interactive-elements/the-details-element/details.html b/testing/web-platform/tests/html/semantics/interactive-elements/the-details-element/details.html
new file mode 100644
index 000000000..5ed14c53a
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/interactive-elements/the-details-element/details.html
@@ -0,0 +1,47 @@
+<!doctype html>
+<html>
+ <head>
+ <title>HTML details element API</title>
+ <style>#one, #two { visibility: hidden; }</style>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+ <body>
+ <div id="log"></div>
+
+ <!-- Used in parsing tests -->
+ <div id='one'><details></details><details></details></div>
+ <div id='two'><p><details></details></div>
+
+ <script type="text/javascript">
+
+function makeDetails () {
+ return document.createElement('details');
+}
+
+
+// <details>
+test(function () {
+ var times = document.getElementById('one').getElementsByTagName('details');
+ assert_equals( times.length, 2 );
+}, 'HTML parsing should locate 2 details elements in this document');
+
+test(function () {
+ assert_equals( document.getElementById('two').getElementsByTagName('p')[0].innerHTML, '' );
+}, 'HTML parsing should close an unclosed <p> before <details>');
+
+test(function () {
+ assert_true( !!window.HTMLDetailsElement );
+}, 'HTMLDetailsElement should be exposed for prototyping');
+
+test(function () {
+ assert_true( makeDetails() instanceof window.HTMLDetailsElement);
+}, 'a dynamically created details element should be instanceof HTMLDetailsElement');
+
+test(function () {
+ assert_true( document.getElementById('one').getElementsByTagName('details')[0] instanceof window.HTMLDetailsElement);
+}, 'a details element from the parser should be instanceof HTMLDetailsElement');
+ </script>
+
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/interactive-elements/the-details-element/toggleEvent.html b/testing/web-platform/tests/html/semantics/interactive-elements/the-details-element/toggleEvent.html
new file mode 100644
index 000000000..da255a384
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/interactive-elements/the-details-element/toggleEvent.html
@@ -0,0 +1,157 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>The details element</title>
+<link rel="author" title="Denis Ah-Kang" href="mailto:denis@w3.org">
+<link rel=help href="https://html.spec.whatwg.org/multipage/#the-details-element">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<details id=details1>
+ <summary>Lorem ipsum</summary>
+ <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
+</details>
+<details id=details2 open>
+ <summary>Lorem ipsum</summary>
+ <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
+</details>
+<details id=details3 style="display:none;">
+ <summary>Lorem ipsum</summary>
+ <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
+</details>
+<details id=details4>
+</details>
+<details id=details6>
+ <summary>Lorem ipsum</summary>
+ <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
+</details>
+<details id=details7>
+ <summary>Lorem ipsum</summary>
+ <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
+</details>
+<details id=details8 open>
+ <summary>Lorem ipsum</summary>
+ <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
+</details>
+<details id=details9 open>
+ <summary>Lorem ipsum</summary>
+ <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
+</details>
+<details id=details10>
+ <summary>Lorem ipsum</summary>
+ <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</p>
+</details>
+<script>
+ var t1 = async_test("Adding open to 'details' should fire a toggle event at the 'details' element"),
+ t2 = async_test("Removing open from 'details' should fire a toggle event at the 'details' element"),
+ t3 = async_test("Adding open to 'details' (display:none) should fire a toggle event at the 'details' element"),
+ t4 = async_test("Adding open from 'details' (no children) should fire a toggle event at the 'details' element"),
+ t6 = async_test("Calling open twice on 'details' fires only one toggle event"),
+ t7 = async_test("Calling setAttribute('open', '') to 'details' should fire a toggle event at the 'details' element"),
+ t8 = async_test("Calling removeAttribute('open') to 'details' should fire a toggle event at the 'details' element"),
+ t9 = async_test("Setting open=true to opened 'details' element should not fire a toggle event at the 'details' element"),
+ t10 = async_test("Setting open=false to closed 'details' element should not fire a toggle event at the 'details' element"),
+
+ details1 = document.getElementById('details1'),
+ details2 = document.getElementById('details2'),
+ details3 = document.getElementById('details3'),
+ details4 = document.getElementById('details4'),
+ details6 = document.getElementById('details6'),
+ details7 = document.getElementById('details7'),
+ details8 = document.getElementById('details8'),
+ details9 = document.getElementById('details9'),
+ details10 = document.getElementById('details10'),
+ loop=false;
+
+ function testEvent(evt) {
+ assert_true(evt.isTrusted, "event is trusted");
+ assert_false(evt.bubbles, "event doesn't bubble");
+ assert_false(evt.cancelable, "event is not cancelable");
+ assert_equals(Object.getPrototypeOf(evt), Event.prototype, "Prototype of toggle event is Event.prototype");
+ }
+
+ details1.ontoggle = t1.step_func_done(function(evt) {
+ assert_true(details1.open);
+ testEvent(evt)
+ });
+ details1.open = true; // opens details1
+
+ details2.ontoggle = t2.step_func_done(function(evt) {
+ assert_false(details2.open);
+ testEvent(evt);
+ });
+ details2.open = false; // closes details2
+
+ details3.ontoggle = t3.step_func_done(function(evt) {
+ assert_true(details3.open);
+ testEvent(evt);
+ });
+ details3.open = true; // opens details3
+
+ details4.ontoggle = t4.step_func_done(function(evt) {
+ assert_true(details4.open);
+ testEvent(evt);
+ });
+ details4.open = true; // opens details4
+
+ async_test(function(t) {
+ var details5 = document.createElement("details");
+ details5.ontoggle = t.step_func_done(function(evt) {
+ assert_true(details5.open);
+ testEvent(evt);
+ })
+ details5.open = true;
+ }, "Adding open to 'details' (not in the document) should fire a toggle event at the 'details' element");
+
+ details6.open = true;
+ details6.open = false;
+ details6.ontoggle = t6.step_func(function() {
+ if (loop) {
+ assert_unreached("toggle event fired twice");
+ } else {
+ loop = true;
+ }
+ });
+ setTimeout(t6.step_func(function() {
+ assert_true(loop);
+ t6.done();
+ }), 0);
+
+ details7.ontoggle = t7.step_func_done(function(evt) {
+ assert_true(details7.open);
+ testEvent(evt)
+ });
+ details7.setAttribute('open', ''); // opens details7
+
+ details8.ontoggle = t8.step_func_done(function(evt) {
+ assert_false(details8.open);
+ testEvent(evt)
+ });
+ details8.removeAttribute('open'); // closes details8
+
+ var toggleFiredOnDetails9 = false;
+ details9.ontoggle = t9.step_func_done(function(evt) {
+ if (toggleFiredOnDetails9) {
+ assert_unreached("toggle event fired twice on opened details element");
+ } else {
+ toggleFiredOnDetails9 = true;
+ }
+ });
+ // The toggle event should be fired once when declaring details9 with open
+ // attribute.
+ details9.open = true; // opens details9
+ setTimeout(t9.step_func(function() {
+ assert_true(details9.open);
+ assert_true(toggleFiredOnDetails9);
+ t9.done();
+ }), 0);
+
+ details10.ontoggle = t10.step_func_done(function(evt) {
+ assert_unreached("toggle event fired on closed details element");
+ });
+ details10.open = false; // closes details10
+ setTimeout(t10.step_func(function() {
+ assert_false(details10.open);
+ t10.done();
+ }), 0);
+
+</script>
diff --git a/testing/web-platform/tests/html/semantics/interactive-elements/the-dialog-element/contains.json b/testing/web-platform/tests/html/semantics/interactive-elements/the-dialog-element/contains.json
new file mode 100644
index 000000000..c865c8588
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/interactive-elements/the-dialog-element/contains.json
@@ -0,0 +1,6 @@
+[
+ {
+ "id": "anchor-points",
+ "original_id": "anchor-points"
+ }
+] \ No newline at end of file
diff --git a/testing/web-platform/tests/html/semantics/interactive-elements/the-dialog-element/dialog-close.html b/testing/web-platform/tests/html/semantics/interactive-elements/the-dialog-element/dialog-close.html
new file mode 100644
index 000000000..9029612b2
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/interactive-elements/the-dialog-element/dialog-close.html
@@ -0,0 +1,77 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>dialog element: close()</title>
+<link rel="author" title="Denis Ah-Kang" href="mailto:denis@w3.org">
+<link rel=help href="https://html.spec.whatwg.org/multipage/#the-dialog-element">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<dialog id="d1">
+ <p>foobar</p>
+ <button>OK</button>
+</dialog>
+<dialog id="d2" open>
+ <p>foobar</p>
+ <button>OK</button>
+</dialog>
+<dialog id="d3" open>
+ <p>foobar</p>
+ <button>OK</button>
+</dialog>
+<dialog id="d4" open>
+ <p>foobar</p>
+ <button>OK</button>
+</dialog>
+<dialog id="d5" open>
+ <p>foobar</p>
+ <button>OK</button>
+</dialog>
+<script>
+ var d1 = document.getElementById('d1'),
+ d2 = document.getElementById('d2'),
+ d3 = document.getElementById('d3'),
+ d4 = document.getElementById('d4'),
+ d5 = document.getElementById('d5'),
+ t = async_test("close() fires a close event"),
+ was_queued = false;
+
+ test(function(){
+ d1.close("closedialog");
+ assert_equals(d1.returnValue, "");
+ }, "close() on a <dialog> that doesn't have an open attribute aborts the steps");
+
+ test(function(){
+ assert_true(d2.open);
+ assert_equals(d2.returnValue, "");
+ d2.close("closedialog");
+ assert_false(d2.hasAttribute("open"));
+ assert_equals(d2.returnValue, "closedialog");
+ }, "close() removes the open attribute and set the returnValue to the first argument");
+
+ test(function(){
+ assert_true(d3.open);
+ assert_equals(d3.returnValue, "");
+ d3.returnValue = "foobar";
+ d3.close();
+ assert_false(d3.hasAttribute("open"));
+ assert_equals(d3.returnValue, "foobar");
+ }, "close() without argument removes the open attribute and there's no returnValue");
+
+ d4.onclose = t.step_func_done(function(e) {
+ assert_true(was_queued, "close event should be queued");
+ assert_true(e.isTrusted, "close event is trusted");
+ assert_false(e.bubbles, "close event doesn't bubble");
+ assert_false(e.cancelable, "close event is not cancelable");
+ });
+
+ t.step(function() {
+ d4.close();
+ was_queued = true;
+ })
+
+ test(function(){
+ Object.defineProperty(HTMLDialogElement.prototype, 'returnValue', { set: function(v) { assert_unreached('JS-defined setter returnValue on the prototype was invoked'); }, configurable:true });
+ Object.defineProperty(d5, 'returnValue', { set: function(v) { assert_unreached('JS-defined setter returnValue on the instance was invoked'); }, configurable:true });
+ d5.close('foo');
+ }, "close() should set the returnValue IDL attribute but not the JS property");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/interactive-elements/the-dialog-element/dialog-open.html b/testing/web-platform/tests/html/semantics/interactive-elements/the-dialog-element/dialog-open.html
new file mode 100644
index 000000000..4719f63b8
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/interactive-elements/the-dialog-element/dialog-open.html
@@ -0,0 +1,30 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>dialog element: open</title>
+<link rel=help href="https://html.spec.whatwg.org/multipage/forms.html#dom-dialog-open">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<dialog id="d1">
+ <p>foobar</p>
+ <button>OK</button>
+</dialog>
+<dialog id="d2" open>
+ <p>foobar</p>
+ <button>OK</button>
+</dialog>
+<script>
+ var d1 = document.getElementById('d1');
+ var d2 = document.getElementById('d2');
+
+ test(function(){
+ assert_false(d1.open);
+ assert_true(d2.open);
+ }, "On getting, the IDL open attribute must return true if the content open attribute is set, and false if it is absent.");
+
+ test(function(){
+ d1.open = true;
+ assert_true(d1.hasAttribute("open"));
+ d2.open = false;
+ assert_false(d2.hasAttribute("open"));
+ }, "On setting, the content open attribute must be removed if the IDL open attribute is set to false, and must be present if the IDL open attribute is set to true.");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/interactive-elements/the-dialog-element/dialog-showModal.html b/testing/web-platform/tests/html/semantics/interactive-elements/the-dialog-element/dialog-showModal.html
new file mode 100644
index 000000000..6ca9189c0
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/interactive-elements/the-dialog-element/dialog-showModal.html
@@ -0,0 +1,125 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>dialog element: showModal()</title>
+<link rel="author" title="Denis Ah-Kang" href="mailto:denis@w3.org">
+<link rel=help href="https://html.spec.whatwg.org/multipage/#the-dialog-element">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<button id="b0">OK</button>
+<dialog id="d1">
+ <p>foobar</p>
+ <button id="b1">OK</button>
+</dialog>
+<dialog id="d2" open>
+ <p>foobar</p>
+ <button>OK</button>
+</dialog>
+<dialog id="d3">
+ <p>foobar</p>
+ <button id="b3">OK</button>
+</dialog>
+<dialog id="d4">
+ <p>foobar</p>
+ <button id="b4">OK</button>
+</dialog>
+<dialog id="d5">
+ <p>foobar</p>
+ <button id="b5">OK</button>
+</dialog>
+<dialog id="d6"></dialog>
+<dialog id="d7">
+ <input id="i71" value="foobar">
+ <input id="i72" value="foobar">
+ <button id="b7">OK</button>
+</dialog>
+<dialog id="d8">
+ <input id="i81" value="foobar">
+ <input id="i82" value="foobar" autofocus>
+ <button id="b8">OK</button>
+</dialog>
+<script>
+ var d1 = document.getElementById('d1'),
+ d2 = document.getElementById('d2'),
+ d3 = document.getElementById('d3'),
+ d4 = document.getElementById('d4'),
+ d5 = document.getElementById('d5'),
+ d6 = document.getElementById('d6'),
+ d7 = document.getElementById('d7'),
+ d8 = document.getElementById('d8'),
+ b0 = document.getElementById('b0'),
+ b1 = document.getElementById('b1'),
+ b3 = document.getElementById('b3'),
+ b4 = document.getElementById('b4'),
+ b5 = document.getElementById('b5');
+
+ test(function(){
+ assert_false(d1.open);
+ assert_false(b0.commandDisabled);
+ d1.showModal();
+ this.add_cleanup(function() { d1.close(); });
+ assert_true(d1.open);
+ assert_true(b0.commandDisabled);
+ assert_equals(document.activeElement, b1);
+ });
+
+ test(function(){
+ assert_throws("INVALID_STATE_ERR", function() {
+ d2.showModal();
+ this.add_cleanup(function() { d2.close(); });
+ });
+ }, "showModal() on a <dialog> that already has an open attribute throws an InvalidStateError exception");
+
+ test(function(){
+ var d = document.createElement("dialog");
+ assert_throws("INVALID_STATE_ERR", function() {
+ d.showModal();
+ this.add_cleanup(function() { d.close(); });
+ });
+ }, "showModal() on a <dialog> not in a Document throws an InvalidStateError exception");
+
+ test(function(){
+ assert_false(d3.open);
+ assert_false(b3.commandDisabled);
+ assert_false(d4.open);
+ assert_false(b4.commandDisabled);
+ assert_false(d5.open);
+ assert_false(b5.commandDisabled);
+ d3.showModal();
+ this.add_cleanup(function() { d3.close(); });
+ d4.showModal();
+ this.add_cleanup(function() { d4.close(); });
+ d5.showModal();
+ this.add_cleanup(function() { d5.close(); });
+ assert_true(d3.open);
+ assert_true(b3.commandDisabled);
+ assert_true(d4.open);
+ assert_true(b4.commandDisabled);
+ assert_true(d5.open);
+ assert_false(b5.commandDisabled);
+ }, "when opening multiple dialogs, only the newest one is non-inert");
+
+ test(function(){
+ assert_false(d6.open);
+ d6.showModal();
+ this.add_cleanup(function() { d6.close(); });
+ assert_true(d6.open);
+ assert_equals(document.activeElement, d6);
+ }, "opening dialog without focusable children");
+
+ test(function(){
+ assert_false(d7.open);
+ d7.showModal();
+ this.add_cleanup(function() { d7.close(); });
+ assert_true(d7.open);
+ assert_equals(document.activeElement, document.getElementById("i71"));
+ }, "opening dialog with multiple focusable children");
+
+ test(function(){
+ assert_false(d8.open);
+ d8.showModal();
+ this.add_cleanup(function() { d8.close(); });
+ assert_true(d8.open);
+ assert_equals(document.activeElement, document.getElementById("i82"));
+ }, "opening dialog with multiple focusable children, one having the autofocus attribute");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/interactive-elements/the-menu-element/.gitkeep b/testing/web-platform/tests/html/semantics/interactive-elements/the-menu-element/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/interactive-elements/the-menu-element/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/interactive-elements/the-menu-element/contains.json b/testing/web-platform/tests/html/semantics/interactive-elements/the-menu-element/contains.json
new file mode 100644
index 000000000..20f2439f6
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/interactive-elements/the-menu-element/contains.json
@@ -0,0 +1,18 @@
+[
+ {
+ "id": "menus-intro",
+ "original_id": "menus-intro"
+ },
+ {
+ "id": "building-menus-and-toolbars",
+ "original_id": "building-menus-and-toolbars"
+ },
+ {
+ "id": "context-menus",
+ "original_id": "context-menus"
+ },
+ {
+ "id": "toolbars",
+ "original_id": "toolbars"
+ }
+] \ No newline at end of file
diff --git a/testing/web-platform/tests/html/semantics/interactive-elements/the-summary-element/.gitkeep b/testing/web-platform/tests/html/semantics/interactive-elements/the-summary-element/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/interactive-elements/the-summary-element/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/interfaces.html b/testing/web-platform/tests/html/semantics/interfaces.html
new file mode 100644
index 000000000..359101dd9
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/interfaces.html
@@ -0,0 +1,47 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>Test of interfaces</title>
+<link rel="author" title="Ms2ger" href="mailto:Ms2ger@gmail.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/">
+<link rel="help" href="https://heycam.github.io/webidl/#host-objects">
+<link rel="help" href="http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-262.pdf#page=96">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src=interfaces.js></script>
+<div id="log"></div>
+<script>
+function do_test(local_name, iface, variant) {
+ test(function() {
+ var e;
+ var i = "HTML" + iface + "Element";
+ if (variant === "useNS") {
+ // Use createElementNS here to preserve the case of local_name.
+ e = document.createElementNS("http://www.w3.org/1999/xhtml", local_name);
+ } else {
+ e = document.createElement(local_name);
+ }
+ assert_class_string(e, i,
+ "Element " + local_name + " should have " + i +
+ " as its primary interface.");
+ assert_true(e instanceof window[i],
+ "Element " + local_name + " should implement " + i + ".");
+ assert_true(e instanceof HTMLElement,
+ "Element " + local_name + " should implement HTMLElement.");
+ assert_true(e instanceof Element,
+ "Element " + local_name + " should implement Element.");
+ assert_true(e instanceof Node,
+ "Element " + local_name + " should implement Node.");
+ }, "Interfaces for " + local_name);
+}
+
+elements.forEach(function(a) {
+ do_test(a[0], a[1], "useNS");
+
+ // Only run the createElement variant if the input is all-lowercase, because createElement
+ // case-folds to lowercase. Custom elements are required to use all-lowercase to implement
+ // HTMLElement, otherwise they use HTMLUnknownElement per spec. Example: "foo-BAR".
+ if (a[0] === a[0].toLowerCase()) {
+ do_test(a[0].toUpperCase(), a[1]);
+ }
+})
+</script>
diff --git a/testing/web-platform/tests/html/semantics/interfaces.js b/testing/web-platform/tests/html/semantics/interfaces.js
new file mode 100644
index 000000000..0280e278c
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/interfaces.js
@@ -0,0 +1,150 @@
+var elements = [
+ ["a", "Anchor"],
+ ["abbr", ""],
+ ["acronym", ""],
+ ["address", ""],
+ ["applet", "Applet"],
+ ["area", "Area"],
+ ["article", ""],
+ ["aside", ""],
+ ["audio", "Audio"],
+ ["b", ""],
+ ["base", "Base"],
+ ["basefont", ""],
+ ["bdi", ""],
+ ["bdo", ""],
+ ["bgsound", "Unknown"],
+ ["big", ""],
+ ["blink", "Unknown"],
+ ["blockquote", "Quote"],
+ ["body", "Body"],
+ ["br", "BR"],
+ ["button", "Button"],
+ ["canvas", "Canvas"],
+ ["caption", "TableCaption"],
+ ["center", ""],
+ ["cite", ""],
+ ["code", ""],
+ ["col", "TableCol"],
+ ["colgroup", "TableCol"],
+ ["command", "Unknown"],
+ ["data", "Data"],
+ ["datalist", "DataList"],
+ ["dd", ""],
+ ["del", "Mod"],
+ ["details", "Details"],
+ ["dfn", ""],
+ ["dialog", "Dialog"],
+ ["dir", "Directory"],
+ ["directory", "Unknown"],
+ ["div", "Div"],
+ ["dl", "DList"],
+ ["dt", ""],
+ ["em", ""],
+ ["embed", "Embed"],
+ ["fieldset", "FieldSet"],
+ ["figcaption", ""],
+ ["figure", ""],
+ ["font", "Font"],
+ ["foo-BAR", "Unknown"], // not a valid custom element name
+ ["foo-bar", ""], // valid custom element name
+ ["foo", "Unknown"],
+ ["footer", ""],
+ ["form", "Form"],
+ ["frame", "Frame"],
+ ["frameset", "FrameSet"],
+ ["h1", "Heading"],
+ ["h2", "Heading"],
+ ["h3", "Heading"],
+ ["h4", "Heading"],
+ ["h5", "Heading"],
+ ["h6", "Heading"],
+ ["head", "Head"],
+ ["header", ""],
+ ["hgroup", ""],
+ ["hr", "HR"],
+ ["html", "Html"],
+ ["i", ""],
+ ["iframe", "IFrame"],
+ ["image", "Unknown"],
+ ["img", "Image"],
+ ["input", "Input"],
+ ["ins", "Mod"],
+ ["isindex", "Unknown"],
+ ["kbd", ""],
+ ["keygen", "Keygen"],
+ ["label", "Label"],
+ ["legend", "Legend"],
+ ["li", "LI"],
+ ["link", "Link"],
+ ["listing", "Pre"],
+ ["main", ""],
+ ["map", "Map"],
+ ["mark", ""],
+ ["marquee", "Marquee"],
+ ["menu", "Menu"],
+ ["menuitem", "MenuItem"],
+ ["meta", "Meta"],
+ ["meter", "Meter"],
+ ["mod", "Unknown"],
+ ["multicol", "Unknown"],
+ ["nav", ""],
+ ["nextid", "Unknown"],
+ ["nobr", ""],
+ ["noembed", ""],
+ ["noframes", ""],
+ ["noscript", ""],
+ ["object", "Object"],
+ ["ol", "OList"],
+ ["optgroup", "OptGroup"],
+ ["option", "Option"],
+ ["output", "Output"],
+ ["p", "Paragraph"],
+ ["param", "Param"],
+ ["picture", "Picture"],
+ ["plaintext", ""],
+ ["pre", "Pre"],
+ ["progress", "Progress"],
+ ["q", "Quote"],
+ ["quasit", "Unknown"],
+ ["rb", ""],
+ ["rp", ""],
+ ["rt", ""],
+ ["rtc", ""],
+ ["ruby", ""],
+ ["s", ""],
+ ["samp", ""],
+ ["script", "Script"],
+ ["section", ""],
+ ["select", "Select"],
+ ["slot", "Slot"],
+ ["small", ""],
+ ["source", "Source"],
+ ["spacer", "Unknown"],
+ ["span", "Span"],
+ ["strike", ""],
+ ["strong", ""],
+ ["style", "Style"],
+ ["sub", ""],
+ ["summary", ""],
+ ["sup", ""],
+ ["table", "Table"],
+ ["tbody", "TableSection"],
+ ["td", "TableCell"],
+ ["textarea", "TextArea"],
+ ["tfoot", "TableSection"],
+ ["th", "TableCell"],
+ ["thead", "TableSection"],
+ ["time", "Time"],
+ ["title", "Title"],
+ ["tr", "TableRow"],
+ ["track", "Track"],
+ ["tt", ""],
+ ["u", ""],
+ ["ul", "UList"],
+ ["var", ""],
+ ["video", "Video"],
+ ["wbr", ""],
+ ["xmp", "Pre"],
+ ["\u00E5-bar", "Unknown"], // not a valid custom element name
+];
diff --git a/testing/web-platform/tests/html/semantics/links/.gitkeep b/testing/web-platform/tests/html/semantics/links/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/links/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/links/downloading-resources/.gitkeep b/testing/web-platform/tests/html/semantics/links/downloading-resources/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/links/downloading-resources/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/links/downloading-resources/contains.json b/testing/web-platform/tests/html/semantics/links/downloading-resources/contains.json
new file mode 100644
index 000000000..b67f855cf
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/links/downloading-resources/contains.json
@@ -0,0 +1,6 @@
+[
+ {
+ "id": "hyperlink-auditing",
+ "original_id": "hyperlink-auditing"
+ }
+] \ No newline at end of file
diff --git a/testing/web-platform/tests/html/semantics/links/following-hyperlinks/.gitkeep b/testing/web-platform/tests/html/semantics/links/following-hyperlinks/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/links/following-hyperlinks/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/links/introduction-3/.gitkeep b/testing/web-platform/tests/html/semantics/links/introduction-3/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/links/introduction-3/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/links/links-created-by-a-and-area-elements/.gitkeep b/testing/web-platform/tests/html/semantics/links/links-created-by-a-and-area-elements/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/links/links-created-by-a-and-area-elements/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/links/links-created-by-a-and-area-elements/htmlanchorelement_attribute-getter-setter.html b/testing/web-platform/tests/html/semantics/links/links-created-by-a-and-area-elements/htmlanchorelement_attribute-getter-setter.html
new file mode 100644
index 000000000..2db3082e2
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/links/links-created-by-a-and-area-elements/htmlanchorelement_attribute-getter-setter.html
@@ -0,0 +1,65 @@
+<!doctype html>
+<meta charset="utf-8">
+<html>
+<head>
+<title>HTMLAnchorElement getters and setters</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<a>anchor</a>
+<script>
+function test_gettersetter(property, oldresult, newval, newresult, oldurl, newurl) {
+ var a = document.querySelector('a');
+ a.href = oldurl;
+ var r1 = a[property];
+ assert_equals(r1, oldresult);
+ a[property] = newval;
+ var r2 = a[property];
+ assert_equals(r2, newresult);
+ var r3 = a.href;
+ assert_equals(r3, newurl);
+}
+
+//Elements for each test: [property, oldresult, newvalue, newresult, oldurl, newurl]
+// [0] [1] [2] [3] [4] [5]
+tests = [
+ ["hash", "#somehash", "someother", "#someother",
+ "http://google.com/index.html#somehash",
+ "http://google.com/index.html#someother"],
+ ["hash", "#somehash", "#someother", "#someother",
+ "http://google.com/index.html#somehash",
+ "http://google.com/index.html#someother"],
+ ["host", "google.com:1234", "github.com:4444", "github.com:4444",
+ "http://google.com:1234/somedir",
+ "http://github.com:4444/somedir"],
+ ["hostname", "google.com", "github.com", "github.com",
+ "http://google.com:1234/somedir",
+ "http://github.com:1234/somedir"],
+ ["href", "http://google.com:1234/somedir", "http://goo-gle.com:1234/other/x.html", "http://goo-gle.com:1234/other/x.html",
+ "http://google.com:1234/somedir",
+ "http://goo-gle.com:1234/other/x.html"],
+ ["password", "flabada", "blubb", "blubb",
+ "https://anonymous:flabada@developer.mozilla.org/en-US/docs/",
+ "https://anonymous:blubb@developer.mozilla.org/en-US/docs/"],
+ ["pathname", "/somedir/someotherdir/index.html", "/newpath/x.txt", "/newpath/x.txt",
+ "http://google.com:1234/somedir/someotherdir/index.html",
+ "http://google.com:1234/newpath/x.txt"],
+ ["port", "1234", "4444", "4444", "http://google.com:1234/somedir", "http://google.com:4444/somedir"],
+ ["protocol", "http:", "ftp:", "ftp:", "http://google.com/somedir", "ftp://google.com/somedir"],
+ ["protocol", "http:", "ftp", "ftp:", "http://google.com/somedir", "ftp://google.com/somedir"],
+ ["search", "?ho", "?hi", "?hi", "http://google.com/q.php?ho", "http://google.com/q.php?hi"],
+ ["search", "?ho", "hi", "?hi", "http://google.com/q.php?ho", "http://google.com/q.php?hi"],
+ ["search", "?ho", "?hi", "?hi", "http://google.com/?ho", "http://google.com/?hi"],
+ ["search", "?ho", "hi", "?hi", "http://google.com/?ho", "http://google.com/?hi"],
+ ["username", "anonymous", "wellknown", "wellknown",
+ "https://anonymous:pwd@developer.mozilla.org:1234/en-US/",
+ "https://wellknown:pwd@developer.mozilla.org:1234/en-US/"]
+];
+
+for (var i = 0; i < tests.length; i++) {
+ test(function() {
+ test_gettersetter(tests[i][0], tests[i][1], tests[i][2], tests[i][3], tests[i][4], tests[i][5])
+ }, "Getter and setter for attribute of anchor element(" + i + "):" + tests[i][0] );
+}
+</script>
+</head>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/links/links-created-by-a-and-area-elements/htmlanchorelement_getter.html b/testing/web-platform/tests/html/semantics/links/links-created-by-a-and-area-elements/htmlanchorelement_getter.html
new file mode 100644
index 000000000..759eada22
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/links/links-created-by-a-and-area-elements/htmlanchorelement_getter.html
@@ -0,0 +1,48 @@
+<!doctype html>
+<meta charset="utf-8">
+<html>
+<head>
+<title>HTMLAnchorElement getters test</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<a id=a1 href="http://google.com?hi">a1</a>
+<a id=a2 href="http://google.com#somehash">a2</a>
+<a id=a3 href="http://google.com:1234/somedir">a3</a>
+<a id=a4 href="http://google.com:1234/somedir">a4</a>
+<a id=a5 href="http://google.com:1234/somedir">a5</a>
+<a id=a6 href="https://anonymous:flabada@developer.mozilla.org/en-US/docs/">a6</a>
+<a id=a7 href="http://google.com:1234/somedir/someotherdir/index.html">a7</a>
+<a id=a8 href="http://google.com:1234/somedir">a8</a>
+<a id=a9 href="http://google.com/somedir">a9</a>
+<a id=a10 href="https://anonymous:pwd@developer.mozilla.org:1234/en-US/">a10</a>
+<script>
+function test_getter(property, result, id) {
+ var a = document.getElementById(id);
+ var r = a[property];
+ assert_equals(r, result);
+}
+
+//Elements for each test: [property, result, id]
+// [0] [1] [2]
+tests = [
+ ["search", "?hi", "a1"],
+ ["hash", "#somehash", "a2"],
+ ["host", "google.com:1234", "a3"],
+ ["hostname", "google.com", "a4"],
+ ["href", "http://google.com:1234/somedir", "a5"],
+ ["password", "flabada", "a6"],
+ ["pathname", "/somedir/someotherdir/index.html", "a7"],
+ ["port", "1234", "a8"],
+ ["protocol", "http:", "a9"],
+ ["username", "anonymous", "a10"]
+];
+
+for (var i = 0; i < tests.length; i++) {
+ test(function() {
+ test_getter(tests[i][0], tests[i][1], tests[i][2])
+ }, "Getter for attribute of anchor element(" + i + "):" + tests[i][0]);
+}
+</script>
+</head>
+</html>
+
diff --git a/testing/web-platform/tests/html/semantics/links/links-created-by-a-and-area-elements/htmlanchorelement_noopener.html b/testing/web-platform/tests/html/semantics/links/links-created-by-a-and-area-elements/htmlanchorelement_noopener.html
new file mode 100644
index 000000000..3d22481d2
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/links/links-created-by-a-and-area-elements/htmlanchorelement_noopener.html
@@ -0,0 +1,78 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Test behavior of rel="noopener" links</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<iframe name="oursubframe"></iframe>
+<a href="support/noopener-target-2.html" rel="noopener" target="ourpopup"></a>
+<a href="support/noopener-target-2.html" rel="noopener" target="oursubframe"></a>
+<script>
+var tests = [];
+// First test the special targets
+function target1Loaded(win) {
+ // Find the relevant test
+ var test = tests.find((t) => t.openedWindow == win);
+ test.step(function() {
+ assert_equals(win.opener, window);
+ win.close();
+ test.done();
+ });
+}
+/**
+ * Test that <a rel="noopener"> targeted at one of _self, _parent, _top does the
+ * load in the appropriate existing browsing context instead of opening a new
+ * one. The test is run in a separate popup window we open and which we can
+ * navigate without causing the test harness going into conniptions.
+ */
+for (var target of ["self", "parent", "top"]) {
+ var t = async_test("Check that rel=noopener with target=_" + target + " does a normal load");
+ tests.push(t);
+ t.openedWindow = window.open("support/noopener-popup.html");
+ t.targetName = target;
+ t.openedWindow.onload = t.step_func(function() {
+ this.openedWindow.findLink(this.targetName).click();
+ });
+}
+
+/**
+ * And now check that a noopener load targeted at something other than one of
+ * the three special targets above in fact ignores existing things with the
+ * given name. We do this in two ways. First, by opening a window named
+ * "ourpopup" and then doing a load via <a rel="noopener" target="ourpopup"> and
+ * verifying that the load happens in a window with a null opener, etc, while
+ * the opener of the thing we opened is not modified. And second, by targeting
+ * <a rel="noopener"> at a name that an existing subframe has, and ensuring that
+ * this subframe is not navigated.
+ */
+var t1 = async_test("Check that targeting of rel=noopener with a given name ignores an existing window with that name");
+var w;
+t1.add_cleanup(function() { w.close(); });
+var channel = new BroadcastChannel("ourpopup");
+channel.onmessage = t1.step_func_done(function(e) {
+ var data = e.data;
+ assert_false(data.hasOpener);
+ assert_false(data.hasParent);
+ assert_equals(data.name, "ourpopup");
+ assert_equals(w.opener, window);
+ assert_equals(w.location.href, "about:blank");
+});
+t1.step(function() {
+ w = window.open("", "ourpopup");
+ assert_equals(w.opener, window);
+ document.querySelectorAll("a")[0].click();
+});
+
+var t2 = async_test("Check that targeting of rel=noopener with a given name ignores an existing subframe with that name");
+var channel = new BroadcastChannel("oursubframe");
+channel.onmessage = t2.step_func_done(function(e) {
+ var data = e.data;
+ assert_false(data.hasOpener);
+ assert_false(data.hasParent);
+ assert_equals(data.name, "oursubframe");
+ assert_equals(document.querySelector("iframe").contentWindow.location.href,
+ "about:blank");
+});
+t2.step(function() {
+ document.querySelectorAll("a")[1].click();
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/links/links-created-by-a-and-area-elements/support/noopener-popup.html b/testing/web-platform/tests/html/semantics/links/links-created-by-a-and-area-elements/support/noopener-popup.html
new file mode 100644
index 000000000..2057dbf0b
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/links/links-created-by-a-and-area-elements/support/noopener-popup.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<script>
+ function findLink(arg) {
+ var doc;
+ if (arg == "self") {
+ doc = document;
+ } else {
+ doc = frames[0].document;
+ }
+ return doc.getElementById(arg + "target");
+ }
+</script>
+<a rel="noopener" target="_self" id="selftarget"
+ href="noopener-target-1.html"></a>
+<iframe srcdoc='
+ <a rel="noopener" target="_parent" id="parenttarget"
+ href="noopener-target-1.html"></a>
+ <a rel="noopener" target="_top" id="toptarget"
+ href="noopener-target-1.html"></a>'></iframe>
diff --git a/testing/web-platform/tests/html/semantics/links/links-created-by-a-and-area-elements/support/noopener-target-1.html b/testing/web-platform/tests/html/semantics/links/links-created-by-a-and-area-elements/support/noopener-target-1.html
new file mode 100644
index 000000000..0dbd14275
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/links/links-created-by-a-and-area-elements/support/noopener-target-1.html
@@ -0,0 +1,4 @@
+<!DOCTYPE html>
+<script>
+ opener.target1Loaded(this);
+</script>
diff --git a/testing/web-platform/tests/html/semantics/links/links-created-by-a-and-area-elements/support/noopener-target-2.html b/testing/web-platform/tests/html/semantics/links/links-created-by-a-and-area-elements/support/noopener-target-2.html
new file mode 100644
index 000000000..dd2d71913
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/links/links-created-by-a-and-area-elements/support/noopener-target-2.html
@@ -0,0 +1,8 @@
+<!DOCTYPE html>
+<script>
+ var channel = new BroadcastChannel(this.name);
+ channel.postMessage({ hasOpener: opener !== null ,
+ hasParent: parent != this,
+ name: window.name });
+ window.close();
+</script>
diff --git a/testing/web-platform/tests/html/semantics/links/linktypes/.gitkeep b/testing/web-platform/tests/html/semantics/links/linktypes/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/links/linktypes/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/links/linktypes/alternate-css-ref.html b/testing/web-platform/tests/html/semantics/links/linktypes/alternate-css-ref.html
new file mode 100644
index 000000000..ec961eac1
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/links/linktypes/alternate-css-ref.html
@@ -0,0 +1,5 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>Reference of Alternate css</title>
+<link rel="stylesheet" href="preferred.css" title="preferred">
+<div>foobar</div>
diff --git a/testing/web-platform/tests/html/semantics/links/linktypes/alternate-css.html b/testing/web-platform/tests/html/semantics/links/linktypes/alternate-css.html
new file mode 100644
index 000000000..366d6c559
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/links/linktypes/alternate-css.html
@@ -0,0 +1,7 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>Alternate css</title>
+<link rel="match" href="alternate-css-ref.html">
+<link rel="stylesheet" href="preferred.css" title="preferred">
+<link rel="alternate stylesheet" href="alternate.css" title="alternate">
+<div>foobar</div>
diff --git a/testing/web-platform/tests/html/semantics/links/linktypes/alternate.css b/testing/web-platform/tests/html/semantics/links/linktypes/alternate.css
new file mode 100644
index 000000000..05920c613
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/links/linktypes/alternate.css
@@ -0,0 +1,3 @@
+div {
+ background-color: red;
+}
diff --git a/testing/web-platform/tests/html/semantics/links/linktypes/contains.json b/testing/web-platform/tests/html/semantics/links/linktypes/contains.json
new file mode 100644
index 000000000..55aa4f677
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/links/linktypes/contains.json
@@ -0,0 +1,68 @@
+[
+ {
+ "id": "rel-alternate",
+ "original_id": "rel-alternate"
+ },
+ {
+ "id": "link-type-author",
+ "original_id": "link-type-author"
+ },
+ {
+ "id": "link-type-bookmark",
+ "original_id": "link-type-bookmark"
+ },
+ {
+ "id": "link-type-help",
+ "original_id": "link-type-help"
+ },
+ {
+ "id": "rel-icon",
+ "original_id": "rel-icon"
+ },
+ {
+ "id": "link-type-license",
+ "original_id": "link-type-license"
+ },
+ {
+ "id": "link-type-nofollow",
+ "original_id": "link-type-nofollow"
+ },
+ {
+ "id": "link-type-noreferrer",
+ "original_id": "link-type-noreferrer"
+ },
+ {
+ "id": "link-type-prefetch",
+ "original_id": "link-type-prefetch"
+ },
+ {
+ "id": "link-type-search",
+ "original_id": "link-type-search"
+ },
+ {
+ "id": "link-type-stylesheet",
+ "original_id": "link-type-stylesheet"
+ },
+ {
+ "id": "link-type-tag",
+ "original_id": "link-type-tag"
+ },
+ {
+ "id": "sequential-link-types",
+ "original_id": "sequential-link-types",
+ "children": [
+ {
+ "id": "link-type-next",
+ "original_id": "link-type-next"
+ },
+ {
+ "id": "link-type-prev",
+ "original_id": "link-type-prev"
+ }
+ ]
+ },
+ {
+ "id": "other-link-types",
+ "original_id": "other-link-types"
+ }
+] \ No newline at end of file
diff --git a/testing/web-platform/tests/html/semantics/links/linktypes/original-id.json b/testing/web-platform/tests/html/semantics/links/linktypes/original-id.json
new file mode 100644
index 000000000..1e5f7b5ed
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/links/linktypes/original-id.json
@@ -0,0 +1 @@
+{"original_id":"linkTypes"} \ No newline at end of file
diff --git a/testing/web-platform/tests/html/semantics/links/linktypes/preferred.css b/testing/web-platform/tests/html/semantics/links/linktypes/preferred.css
new file mode 100644
index 000000000..54b95ac28
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/links/linktypes/preferred.css
@@ -0,0 +1,3 @@
+div {
+ border: 4px solid green;
+}
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/.gitkeep b/testing/web-platform/tests/html/semantics/scripting-1/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-noscript-element/.gitkeep b/testing/web-platform/tests/html/semantics/scripting-1/the-noscript-element/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-noscript-element/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/.gitkeep b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/async_001.htm b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/async_001.htm
new file mode 100644
index 000000000..370152683
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/async_001.htm
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>Async property on a dynamically-created script is true by default</title>
+ <meta http-equiv="content-type" content="text/html; charset=UTF-8" />
+ <meta description="This test checks the Async property on a dynamically-created script element. By default it should be true." />
+ <link rel="author" title="Microsoft" href="http://www.microsoft.com/" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-script-async"/>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+ <body>
+ <div id=log></div>
+ <script type="text/javascript">
+ test(function() {assert_true(document.createElement("script").async)}, "Async property on a dynamically-created script is true by default");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/async_002.htm b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/async_002.htm
new file mode 100644
index 000000000..e1850ff6e
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/async_002.htm
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>Changes to the 'async' attribute are reflected in the async property</title>
+ <meta http-equiv="content-type" content="text/html; charset=UTF-8" />
+ <meta description="This test ensures changes to the 'async' attribute are reflected in the async property." />
+ <link rel="author" title="Microsoft" href="http://www.microsoft.com/" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-script-async"/>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+ <body>
+ <div id=log></div>
+ <script type="text/javascript">
+ test(function() {
+ var s = document.createElement("script");
+ s.async = false;
+ s.setAttribute('async', ''); /*Should change s.async to true*/
+ assert_true(s.async)
+ }, "Test 'async' attribute are reflected in the async property with setAttribute");
+
+ test(function() {
+ var s = document.createElement("script");
+ s.async = false;
+ s.setAttribute('async', ''); /*Should change s.async to true*/
+ s.removeAttribute('async'); /*Should change s.async to false*/
+ assert_false(s.async)
+ }, "Test 'async' attribute are reflected in the async property with removeAttribute");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/async_003.htm b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/async_003.htm
new file mode 100644
index 000000000..b9a854c6b
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/async_003.htm
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>An async script does not block the parser while downloading</title>
+ <meta http-equiv="content-type" content="text/html; charset=UTF-8" />
+ <meta description="This test ensures an async script does not block the parser while downloading." />
+ <link rel="author" title="Microsoft" href="http://www.microsoft.com/" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#attr-script-async"/>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+ <body>
+ <div id=log></div>
+ <script type="text/javascript">
+ var t = async_test("An async script does not block the parser while downloading");
+
+ function timeout()
+ {
+ t.step(function(){ assert_equals(document.getElementById("testresult").innerHTML, "21")});
+ t.done();
+ }
+
+ var timer = setTimeout(timeout, 4000);
+
+ function log(text)
+ {
+ var textNode = document.createTextNode(text);
+ document.getElementById("testresult").appendChild(textNode);
+ }
+ </script>
+
+ <span id="testresult"></span>
+
+ <script src="log.py?sec=3&id=1" async></script>
+ <script>
+ log('2');
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/async_004.htm b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/async_004.htm
new file mode 100644
index 000000000..7908b757a
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/async_004.htm
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>An async script executes as soon as possible after a download is complete</title>
+ <meta http-equiv="content-type" content="text/html; charset=UTF-8" />
+ <meta description="This test ensures an async script executes as soon as possible after a download is complete." />
+ <link rel="author" title="Microsoft" href="http://www.microsoft.com/" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#attr-script-async"/>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+ <body>
+ <div id=log></div>
+ <script type="text/javascript">
+ var t = async_test("async script executes as soon as possible after a download is complete");
+
+ function timeout()
+ {
+ t.step(function(){ assert_equals(document.getElementById("testresult").innerHTML, "21")});
+ t.done();
+ }
+
+ var timer = setTimeout(timeout, 4000);
+
+ function log(text)
+ {
+ var textNode = document.createTextNode(text);
+ document.getElementById("testresult").appendChild(textNode);
+ }
+ </script>
+
+ <span id="testresult"></span>
+
+ <script src="log.py?sec=3&id=1" async></script>
+ <script src="log.py?sec=1&id=2" async></script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/async_005.htm b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/async_005.htm
new file mode 100644
index 000000000..4519d7234
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/async_005.htm
@@ -0,0 +1,39 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>A script element with both async and defer set should execute asynchronously</title>
+ <meta http-equiv="content-type" content="text/html; charset=UTF-8" />
+ <meta description="This test ensures a script element with both async and defer set should execute asynchronously." />
+ <link rel="author" title="Microsoft" href="http://www.microsoft.com/" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#attr-script-async"/>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+ <body>
+ <div id=log></div>
+ <script type="text/javascript">
+ var t = async_test("A script element with both async and defer set should execute asynchronously");
+
+ function timeout()
+ {
+ t.step(function(){ assert_equals(document.getElementById("testresult").innerHTML, "2134")});
+ t.done();
+ }
+
+ var timer = setTimeout(timeout, 5000);
+
+ function log(text)
+ {
+ var textNode = document.createTextNode(text);
+ document.getElementById("testresult").appendChild(textNode);
+ }
+ </script>
+
+ <span id="testresult"></span>
+
+ <script type="text/javascript" src="log.py?sec=1&id=1" defer async></script>
+ <script type="text/javascript">log('2');</script>
+ <script type="text/javascript" src="log.py?sec=3&id=3"></script>
+ <script type="text/javascript">log('4');</script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/async_006.htm b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/async_006.htm
new file mode 100644
index 000000000..86eb99897
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/async_006.htm
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>A dynamically created external script executes asynchronously</title>
+ <meta http-equiv="content-type" content="text/html; charset=UTF-8" />
+ <meta description="This test ensures a dynamically created external script executes asynchronously." />
+ <link rel="author" title="Microsoft" href="http://www.microsoft.com/" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#force-async"/>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+ <body>
+ <div id=log></div>
+ <script type="text/javascript">
+ var t = async_test("dynamically created external script executes asynchronously");
+
+ function timeout()
+ {
+ t.step(function(){ assert_equals(document.getElementById("testresult").innerHTML, "321")});
+ t.done();
+ }
+
+ var timer = setTimeout(timeout, 4000);
+
+ function log(text)
+ {
+ var textNode = document.createTextNode(text);
+ document.getElementById("testresult").appendChild(textNode);
+ }
+ </script>
+
+ <span id="testresult"></span>
+ <script type="text/javascript">
+ var one = document.createElement("script");
+ one.src="log.py?sec=3&id=1";
+ document.head.appendChild(one);
+
+ var two = document.createElement("script");
+ two.src="log.py?sec=1&id=2";
+ document.head.appendChild(two);
+
+ log('3');
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/async_007.htm b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/async_007.htm
new file mode 100644
index 000000000..8df0fba37
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/async_007.htm
@@ -0,0 +1,48 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>Ordered async script execution when script.async == false</title>
+ <meta http-equiv="content-type" content="text/html; charset=UTF-8" />
+ <meta description="This test ensures Ordered async script execution when script.async == false" />
+ <link rel="author" title="Microsoft" href="http://www.microsoft.com/" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#script-processing-src-sync"/>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+ <body>
+ <div id=log></div>
+ <script type="text/javascript">
+ var t = async_test("Ordered async script execution when script.async == false");
+
+ function timeout()
+ {
+ t.step(function(){ assert_equals(document.getElementById("testresult").innerHTML, "312")});
+ t.done();
+ }
+
+ var timer = setTimeout(timeout, 8000);
+
+ function log(text)
+ {
+ var textNode = document.createTextNode(text);
+ document.getElementById("testresult").appendChild(textNode);
+ }
+ </script>
+
+ <span id="testresult"></span>
+ <script type="text/javascript">
+ var one = document.createElement("script");
+ one.src="log.py?sec=3&id=1";
+ one.async = false;
+ document.head.appendChild(one);
+
+ var two = document.createElement("script");
+ two.src="log.py?sec=1&id=2";
+ two.async = false;
+ document.head.appendChild(two);
+ </script>
+ <script type="text/javascript">
+ log('3');
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/async_008.htm b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/async_008.htm
new file mode 100644
index 000000000..73529cc31
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/async_008.htm
@@ -0,0 +1,47 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>Async script element execution delays the window's load event</title>
+ <meta http-equiv="content-type" content="text/html; charset=UTF-8" />
+ <meta description="This test ensures an async script element's execution delays the window's load event." />
+ <link rel="author" title="Microsoft" href="http://www.microsoft.com/" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#delay-the-load-event"/>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+ <body>
+ <div id=log></div>
+ <script type="text/javascript">
+ var t = async_test("Async script element execution delays the window's load event");
+
+ function timeout()
+ {
+ t.step(function(){ assert_equals(document.getElementById("testresult").innerHTML, "213")});
+ t.done();
+ }
+
+ var timer = setTimeout(timeout, 8000);
+
+ function log(text)
+ {
+ var textNode = document.createTextNode(text);
+ document.getElementById("testresult").appendChild(textNode);
+ }
+ </script>
+
+ <span id="testresult"></span>
+ <script type="text/javascript">
+ window.addEventListener("load", function() {
+ log("3");
+ timeout();
+ }, false);
+
+ var s1 = document.createElement("script");
+ s1.src = "log.py?sec=2&id=1";
+ document.head.appendChild(s1);
+ </script>
+ <script type="text/javascript">
+ log('2');
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/async_009.htm b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/async_009.htm
new file mode 100644
index 000000000..501edda06
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/async_009.htm
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>Document.write() silently fails from an Async script</title>
+ <meta http-equiv="content-type" content="text/html; charset=UTF-8" />
+ <meta description="This test ensures Document.write() silently fails from an Async script." />
+ <link rel="author" title="Microsoft" href="http://www.microsoft.com/" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#execute-the-script-block"/>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script type="text/javascript">
+ var t = async_test("Document.write() silently fails from an Async script");
+
+ var log = t.step_func(function() {
+ document.write("<span id='writtenText'/>");
+ assert_equals(null, document.getElementById('writtenText'));
+ t.done();
+ });
+ </script>
+ </head>
+ <body>
+ <div id=log></div>
+ <script type="text/javascript" src="log.py?sec=1&id=1" async></script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/async_010.htm b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/async_010.htm
new file mode 100644
index 000000000..959a8aa27
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/async_010.htm
@@ -0,0 +1,54 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>Removing an async script before execution</title>
+ <meta http-equiv="content-type" content="text/html; charset=UTF-8" />
+ <meta description="This test ensures that an async script still executes if it is removed from a markup before the download is complete. The other two scripts that come after it in insertion order should execute as well." />
+ <link rel="author" title="Microsoft" href="http://www.microsoft.com/" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#execute-the-script-block"/>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script type="text/javascript">
+ var t = async_test("Removing an async script before execution");
+
+ function timeout()
+ {
+ t.step(function(){ assert_equals(document.getElementById("testresult").innerHTML, "4123")});
+ t.done();
+ }
+
+ var timer = setTimeout(timeout, 8000);
+
+ function log(text)
+ {
+ var textNode = document.createTextNode(text);
+ document.getElementById("testresult").appendChild(textNode);
+ }
+ </script>
+ </head>
+ <body>
+ <div id=log></div>
+ <span id="testresult"></span>
+ <script type="text/javascript">
+ var s1 = document.createElement("script");
+ s1.src="log.py?sec=2&id=1";
+ s1.async = false;
+ document.body.appendChild(s1);
+
+ var s2 = document.createElement("script");
+ s2.src="log.py?sec=1&id=2";
+ s2.async = false;
+ document.body.appendChild(s2);
+
+ var s3 = document.createElement("script");
+ s3.id = "s3";
+ s3.src="log.py?sec=0&id=3";
+ s3.async = false;
+ document.body.appendChild(s3);
+
+ //Remove s1 (Should still execute)
+ document.body.removeChild(s1);
+ </script>
+ <script type="text/javascript">log('4');</script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/async_011.htm b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/async_011.htm
new file mode 100644
index 000000000..d80e463ce
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/async_011.htm
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>An empty parser-inserted script element should return async=true</title>
+ <meta http-equiv="content-type" content="text/html; charset=UTF-8" />
+ <meta description="An empty parser-inserted script element should return async=true." />
+ <link rel="author" title="Microsoft" href="http://www.microsoft.com/" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#prepare-a-script"/>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+ <body>
+ <div id=log></div>
+ <script></script>
+ <script type="text/javascript">
+ test(function() { assert_true(document.getElementsByTagName("script")[2].async)}, "An empty parser-inserted script element should return async=true");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/contains.json b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/contains.json
new file mode 100644
index 000000000..e31ce4003
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/contains.json
@@ -0,0 +1,18 @@
+[
+ {
+ "id": "scriptinglanguages",
+ "original_id": "scriptingLanguages"
+ },
+ {
+ "id": "restrictions-for-contents-of-script-elements",
+ "original_id": "restrictions-for-contents-of-script-elements"
+ },
+ {
+ "id": "inline-documentation-for-external-scripts",
+ "original_id": "inline-documentation-for-external-scripts"
+ },
+ {
+ "id": "scripttagxslt",
+ "original_id": "scriptTagXSLT"
+ }
+] \ No newline at end of file
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/external-script-utf8.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/external-script-utf8.js
new file mode 100644
index 000000000..eb442c97b
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/external-script-utf8.js
@@ -0,0 +1,5 @@
+(function() {
+ window.getSomeString = function() {
+ return "śćążź"; //<- these are five Polish letters, similar to scazz. It can be read correctly only with windows 1250 encoding.
+ };
+})();
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/external-script-windows1250.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/external-script-windows1250.js
new file mode 100644
index 000000000..50de6932b
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/external-script-windows1250.js
@@ -0,0 +1,5 @@
+(function() {
+ window.getSomeString = function() {
+ return "œæ¹¿Ÿ"; //<- these are five Polish letters, similar to scazz. It can be read correctly only with windows 1250 encoding.
+ };
+})();
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/fetch-src/alpha/base.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/fetch-src/alpha/base.html
new file mode 100644
index 000000000..dc0fa9dab
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/fetch-src/alpha/base.html
@@ -0,0 +1,15 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Script src with a base URL</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<base href=../beta/>
+<div id=log></div>
+<script>
+function do_test(path) {
+ test(function() {
+ assert_equals(path, "beta");
+ });
+}
+</script>
+<script src=test.js></script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/fetch-src/alpha/test.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/fetch-src/alpha/test.js
new file mode 100644
index 000000000..3cbbb12e2
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/fetch-src/alpha/test.js
@@ -0,0 +1 @@
+do_test("alpha");
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/fetch-src/beta/test.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/fetch-src/beta/test.js
new file mode 100644
index 000000000..4ce0f5338
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/fetch-src/beta/test.js
@@ -0,0 +1 @@
+do_test("beta");
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/fetch-src/empty-with-base.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/fetch-src/empty-with-base.html
new file mode 100644
index 000000000..edc2c3d6f
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/fetch-src/empty-with-base.html
@@ -0,0 +1,27 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Script src with an empty URL</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<base href=unreachable.js>
+<div id=log></div>
+<script>
+async_test(function(t) {
+ window.unreachable = this.unreached_func("Should not load unreachable.js");
+ var queued = false;
+ var script = document.createElement("script");
+ script.onerror = this.step_func_done(function(ev) {
+ assert_equals(ev.type, "error");
+ assert_false(ev.bubbles, "bubbles");
+ assert_false(ev.cancelable, "cancelable");
+ assert_true(ev.isTrusted, "isTrusted");
+ assert_equals(ev.target, script);
+ assert_true(ev instanceof Event, "instanceof Event");
+ assert_class_string(ev, "Event");
+ assert_true(queued, "event should not be dispatched synchronously");
+ });
+ script.setAttribute("src", "");
+ document.body.appendChild(script);
+ queued = true;
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/fetch-src/empty.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/fetch-src/empty.html
new file mode 100644
index 000000000..d127f1eb3
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/fetch-src/empty.html
@@ -0,0 +1,32 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Script src with an empty URL</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<div id=log></div>
+<script>
+// For a better error message in case the UA tries to load "" (which resolves
+// to this document).
+setup({
+ "allow_uncaught_exception": true,
+});
+async_test(function(t) {
+ window.onerror = this.unreached_func("Should not get an error reported to " +
+ "the window before the script");
+ var queued = false;
+ var script = document.createElement("script");
+ script.onerror = this.step_func_done(function(ev) {
+ assert_equals(ev.type, "error");
+ assert_false(ev.bubbles, "bubbles");
+ assert_false(ev.cancelable, "cancelable");
+ assert_true(ev.isTrusted, "isTrusted");
+ assert_equals(ev.target, script);
+ assert_true(ev instanceof Event, "instanceof Event");
+ assert_class_string(ev, "Event");
+ assert_true(queued, "event should not be dispatched synchronously");
+ });
+ script.setAttribute("src", "");
+ document.body.appendChild(script);
+ queued = true;
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/fetch-src/failure.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/fetch-src/failure.html
new file mode 100644
index 000000000..b49e51740
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/fetch-src/failure.html
@@ -0,0 +1,25 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Script src with an invalid URL</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<div id=log></div>
+<script>
+async_test(function(t) {
+ var queued = false;
+ var script = document.createElement("script");
+ script.onerror = this.step_func_done(function(ev) {
+ assert_equals(ev.type, "error");
+ assert_false(ev.bubbles, "bubbles");
+ assert_false(ev.cancelable, "cancelable");
+ assert_true(ev.isTrusted, "isTrusted");
+ assert_equals(ev.target, script);
+ assert_true(ev instanceof Event, "instanceof Event");
+ assert_class_string(ev, "Event");
+ assert_true(queued, "event should not be dispatched synchronously");
+ });
+ script.setAttribute("src", "//[]");
+ document.body.appendChild(script);
+ queued = true;
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/fetch-src/unreachable.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/fetch-src/unreachable.js
new file mode 100644
index 000000000..ca7fdba71
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/fetch-src/unreachable.js
@@ -0,0 +1 @@
+unreachable();
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/historical.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/historical.html
new file mode 100644
index 000000000..1f1a91228
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/historical.html
@@ -0,0 +1,53 @@
+<!doctype html>
+<title>Historical script element features should not be supported</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+function t(property) {
+ test(function() {
+ assert_false(property in document.createElement('script'));
+ }, 'script.' + property + ' should not be supported');
+}
+// added in https://github.com/whatwg/html/commit/69f83cf2eacf4543860ccb7abab0ff5bb1e8b594
+// removed in https://github.com/whatwg/html/commit/1a0b5e8377d59462e05a5cffda4b8592324a2785
+t('onbeforescriptexecute');
+t('onafterscriptexecute');
+
+var t_onbeforescriptexecute_attr = async_test('onbeforescriptexecute content attribute should not be supported');
+var t_onafterscriptexecute_attr = async_test('onafterscriptexecute content attribute should not be supported');
+var t_beforescriptexecute_event = async_test(function() {
+ addEventListener('beforescriptexecute', this.step_func(function() {
+ assert_unreached();
+ }), true);
+}, 'beforescriptexecute event should not be supported');
+var t_afterscriptexecute_event = async_test(function() {
+ addEventListener('afterscriptexecute', this.step_func(function() {
+ assert_unreached();
+ }), true);
+}, 'afterscriptexecute event should not be supported');
+
+var a = false;
+
+onload = function() {
+ t_onbeforescriptexecute_attr.step(function() {
+ assert_true(a);
+ this.done();
+ });
+ t_onafterscriptexecute_attr.step(function() {
+ assert_true(a);
+ this.done();
+ });
+ t_beforescriptexecute_event.step(function() {
+ assert_true(a);
+ this.done();
+ });
+ t_afterscriptexecute_event.step(function() {
+ assert_true(a);
+ this.done();
+ });
+};
+</script>
+<script onbeforescriptexecute="t_onbeforescriptexecute_attr.step(function() { assert_unreached(); });"
+ onafterscriptexecute="t_onafterscriptexecute_attr.step(function() { assert_unreached(); });">
+a = true;
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/load-event.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/load-event.html
new file mode 100644
index 000000000..25c2ddf3e
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/load-event.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#execute-the-script-block">
+<link rel="author" title="Domenic Denicola" href="mailto:d@domenic.me">
+
+<script>
+"use strict";
+
+async_test(function(t) {
+ window.scriptExecuting = function () {
+ setTimeout(t.step_func_done(() => {
+ assert_equals(window.onloadHappened, undefined);
+ }), 0);
+ };
+}, "load events should not be fired for inline scripts");
+</script>
+
+
+<script onload="window.onloadHappened = true;">
+"use strict";
+window.scriptExecuting();
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/log.py b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/log.py
new file mode 100644
index 000000000..6803bb3e4
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/log.py
@@ -0,0 +1,13 @@
+import time
+
+def main(request, response):
+ response.headers.append("Content-Type", "text/javascript")
+ try:
+ script_id = int(request.GET.first("id"))
+ delay = int(request.GET.first("sec"))
+ except:
+ response.set_error(400, "Invalid parameter")
+
+ time.sleep(int(delay))
+
+ return "log('%s')" % script_id
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/resources/cross-origin.py b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/resources/cross-origin.py
new file mode 100644
index 000000000..f8e05d966
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/resources/cross-origin.py
@@ -0,0 +1,10 @@
+def main(request, response):
+ headers = [("Content-Type", "text/javascript")]
+ milk = request.cookies.first("milk", None)
+
+ if milk is None:
+ return headers, "var included = false;"
+ elif milk.value == "yes":
+ return headers, "var included = true;"
+
+ return headers, "var included = false;"
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-charset-01.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-charset-01.html
new file mode 100644
index 000000000..c5ac0d0a6
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-charset-01.html
@@ -0,0 +1,89 @@
+<!DOCTYPE html>
+<head>
+ <meta charset="utf-8">
+ <title>Script @type: unknown parameters</title>
+ <link rel="author" title="askalski" href="github.com/askalski">
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#scriptingLanguages">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <div id="log"></div>
+
+ <!-- "Step1" tests -->
+ <!-- charset is set incorrectly via Content Type "text/javascript;charset=utf-8" in response
+ which has priority before a correct setting in "charset" attribute of script tag.
+ -->
+ <script type="text/javascript"
+ src="serve-with-content-type.py?fn=external-script-windows1250.js&ct=text/javascript%3Bcharset=utf-8" charset="windows-1250">
+ </script>
+ <script>
+ test(function() {
+ //these strings should not match, since the file charset is set incorrectly
+ assert_not_equals(window.getSomeString(), "śćążź");
+ });
+ </script>
+ <!-- charset is set correctly via Content Type "text/javascript;charset=utf-8" in response
+ which has priority before a incorrect setting in "charset" attribute of script tag.
+ -->
+
+ <script type="text/javascript"
+ src="serve-with-content-type.py?fn=external-script-windows1250.js&ct=text/javascript%3Bcharset=windows-1250" charset="utf-8">
+ </script>
+ <script>
+ //the charset is set correctly via Content Type "text/javascript;charset=windows-1250" in respones
+ test(function() {
+ assert_equals(window.getSomeString(), "śćążź");
+ });
+ </script>
+
+ <!-- end of step1 tests, now step2 tests -->
+ <!-- in this case, the response's Content Type does not bring charset information.
+ Second step takes block character encoding if available.-->
+ <script type="text/javascript"
+ src="serve-with-content-type.py?fn=external-script-windows1250.js&ct=text/javascript" charset="utf-8">
+ </script>
+ <script>
+ test(function() {
+ //these strings should not match, since the file charset is set incorrectly in "charset" tag of <script> above
+ assert_not_equals(window.getSomeString(), "śćążź");
+ });
+ </script>
+ <!-- charset is set correctly via Content Type "text/javascript;charset=utf-8" in response
+ which has priority before a incorrect setting in "charset" attribute of script tag.
+ -->
+
+ <script type="text/javascript"
+ src="serve-with-content-type.py?fn=external-script-windows1250.js&ct=text/javascript" charset="windows-1250">
+ </script>
+ <script>
+ //the charset is set correctly via content attribute in <script> above
+ test(function() {
+ assert_equals(window.getSomeString(), "śćążź");
+ });
+ </script>
+
+ <!-- end of step2 tests, now step3 tests -->
+ <!-- in this case, neither response's Content Type nor charset attribute bring correct charset information.
+ Third step takes this document's character encoding (declared correctly as UTF-8).-->
+ <script type="text/javascript"
+ src="serve-with-content-type.py?fn=external-script-windows1250.js&ct=text/javascript">
+ </script>
+ <script>
+ test(function() {
+ //these strings should not match, since the tested file is in windows-1250, and document is utf-8
+ assert_not_equals(window.getSomeString(), "śćążź");
+ });
+ </script>
+
+ <script type="text/javascript"
+ src="serve-with-content-type.py?fn=external-script-utf8.js&ct=text/javascript">
+ </script>
+ <script>
+ //these strings should match, both document and tested file are utf-8
+ test(function() {
+ assert_equals(window.getSomeString(), "śćążź");
+ });
+ </script>
+
+ <!-- the last portion of tests (step4) are in file script-charset-02.html
+
+</head>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-charset-02.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-charset-02.html
new file mode 100644
index 000000000..77a015bb7
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-charset-02.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<head>
+ <!-- TODO:
+ askalski: while this test pass, it does not test anything now.
+ It should test, whether with no document.charset set in any way, the
+ external scripts will get decoded using utf-8 as fallback character encoding.
+ It seems like utf-8 is also a fallback encoding to html (my guess), so
+ the part of the code I was attempting to test is never reached.
+ -->
+ <title>Script @type: unknown parameters</title>
+ <link rel="author" title="askalski" href="github.com/askalski">
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#scriptingLanguages">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <div id="log"></div>
+
+ <!-- test of step4, which is taking utf-8 as fallback -->
+ <!-- in this case, neither response's Content Type nor charset attribute bring correct charset information.
+ Furthermore, document's encoding is not set.-->
+ <script type="text/javascript"
+ src="serve-with-content-type.py?fn=external-script-windows1250.js&ct=text/javascript">
+ </script>
+ <script>
+ test(function() {
+ //these strings should not match, since the tested file is in windows-1250, and fallback is defined as utf-8
+ assert_not_equals(window.getSomeString().length, 5);
+ });
+ </script>
+
+ <script type="text/javascript"
+ src="serve-with-content-type.py?fn=external-script-utf8.js&ct=text/javascript">
+ </script>
+ <script>
+ //these strings should match, since fallback utf-8 is the correct setting.
+ test(function() {
+ assert_equals(window.getSomeString().length, 5);
+ });
+ </script>
+
+</head>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-charset-03.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-charset-03.html
new file mode 100644
index 000000000..4ff4cc6b0
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-charset-03.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<head>
+<meta charset="utf-8">
+<title>Script changing @charset</title>
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#scriptingLanguages">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<script>
+async_test(function() {
+ var s = document.createElement("script");
+ s.src = "external-script-windows1250.js";
+ s.charset = "windows-1250";
+ document.body.appendChild(s);
+ s.charset = "utf-8";
+ window.onload = this.step_func_done(function() {
+ assert_equals(window.getSomeString(), "\u015b\u0107\u0105\u017c\u017a");
+ });
+})
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-crossorigin-network.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-crossorigin-network.html
new file mode 100644
index 000000000..488dd4488
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-crossorigin-network.html
@@ -0,0 +1,49 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>HTMLScriptElement: crossorigin attribute network test</title>
+<link rel="author" title="KiChjang" href="mailto:kungfukeith11@gmail.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#cors-settings-attribute">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<body>
+ <script type="text/javascript">
+ var test1 = async_test(document.title + "1");
+ var test2 = async_test(document.title + "2");
+ var test3 = async_test(document.title + "3");
+
+ var script1 = document.createElement("script");
+ script1.src = "resources/cross-origin.py";
+ script1.crossOrigin = "use-credentials";
+ var script2 = document.createElement("script");
+ script2.src = "resources/cross-origin.py";
+ script2.crossOrigin = "gibberish";
+ var script3 = document.createElement("script");
+ script3.src = "resources/cross-origin.py";
+
+ document.cookie = "milk=yes";
+ document.body.appendChild(script1);
+ script1.onload = function() {
+ test1.step(function() {
+ assert_true(included, "credentials should be included in script request");
+ test1.done();
+ });
+ };
+
+ document.body.appendChild(script2);
+ script2.onload = function() {
+ test2.step(function() {
+ assert_true(included, "invalid values should default to include credentials due to response tainting");
+ test2.done();
+ });
+ };
+
+ document.body.appendChild(script3);
+ script3.onload = function() {
+ test3.step(function() {
+ assert_true(included, "missing value should default to include credentials");
+ test3.done();
+ });
+ };
+ </script>
+</body>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-crossorigin.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-crossorigin.html
new file mode 100644
index 000000000..52857a08e
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-crossorigin.html
@@ -0,0 +1,39 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>HTMLScriptElement: crossOrigin IDL attribute</title>
+<link rel="author" title="KiChjang" href="mailto:kungfukeith11@gmail.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#cors-settings-attribute">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script id="script1"></script>
+<script id="script2" crossorigin=""></script>
+<script id="script3" crossorigin="foo"></script>
+<script id="script4" crossorigin="anonymous"></script>
+<script id="script5" crossorigin="use-credentials"></script>
+<script>
+test(function() {
+ var script1 = document.getElementById("script1");
+ var script2 = document.getElementById("script2");
+ var script3 = document.getElementById("script3");
+ var script4 = document.getElementById("script4");
+ var script5 = document.getElementById("script5");
+
+ assert_equals(script1.crossOrigin, null, "Missing value default should be null");
+ assert_equals(script2.crossOrigin, "anonymous", "Empty string should map to anonymous");
+ assert_equals(script3.crossOrigin, "anonymous", "Invalid value default should be anonymous");
+ assert_equals(script4.crossOrigin, "anonymous", "anonymous should be parsed correctly");
+ assert_equals(script5.crossOrigin, "use-credentials", "use-credentials should be parsed correctly");
+
+ script1.crossOrigin = "bar";
+ assert_equals(script1.crossOrigin, "anonymous", "Setting to invalid value would default to anonymous");
+
+ script2.crossOrigin = null;
+ assert_equals(script2.crossOrigin, null, "Resetting to null should work");
+
+ script4.crossOrigin = "use-credentials";
+ assert_equals(script4.crossOrigin, "use-credentials", "Switching from anonymous to use-credentials should work");
+
+ script5.crossOrigin = "anonymous";
+ assert_equals(script5.crossOrigin, "anonymous", "Switching from use-credentials to anonymous should work");
+}, document.title);
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-for-event-xhtml.xhtml b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-for-event-xhtml.xhtml
new file mode 100644
index 000000000..69c4ef1f8
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-for-event-xhtml.xhtml
@@ -0,0 +1,22 @@
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+ <title>Scripts with for and event attributes</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+</head>
+<body>
+ <div id="log"></div>
+ <script>
+ var run = false;
+ </script>
+ <script for="window" event="bar">
+ // This script should not run, but should not cause a parse error either.
+ run = true;
+ </script>
+ <script>
+ test(function() {
+ assert_false(run, "Script was unexpectedly run.")
+ }, "Scripts with for and event attributes should not run.")
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-for-event.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-for-event.html
new file mode 100644
index 000000000..552ea7041
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-for-event.html
@@ -0,0 +1,93 @@
+<!DOCTYPE html>
+<title>Scripts with for and event attributes</title>
+<link rel="author" title="Matheus Kerschbaum" href="mailto:matjk7@gmail.com">
+<link rel="author" title="Ms2ger" href="mailto:ms2ger@gmail.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#prepare-a-script">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<script>
+var expected = [
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ false,
+ true,
+ true,
+ false,
+ true,
+ true,
+];
+var run = expected.map(function() { return false });
+</script>
+<script for="w&#x130;ndow" event="onload">
+run[0] = true;
+</script>
+<script for="window" event="onload x">
+run[1] = true;
+</script>
+<script for="window" event="onload(x">
+run[2] = true;
+</script>
+<script for="window" event="onload(x)">
+run[3] = true;
+</script>
+<script for="window" event="onclick">
+run[4] = true;
+</script>
+<script for="" event="onload">
+run[5] = true;
+</script>
+<script for="window" event="">
+run[6] = true;
+</script>
+<script for="" event="">
+run[7] = true;
+</script>
+<script for="&#xa0;window" event="onload">
+run[8] = true;
+</script>
+<script for="window&#xa0;" event="onload">
+run[9] = true;
+</script>
+<script for="window" event="&#xa0;onload">
+run[10] = true;
+</script>
+<script for="window" event="onload&#xa0;">
+run[11] = true;
+</script>
+<script for=" window " event=" onload ">
+run[12] = true;
+</script>
+<script for=" window " event=" onload() ">
+run[13] = true;
+</script>
+<script for="object" event="handler">
+run[14] = true;
+</script>
+<script event="handler">
+run[15] = true;
+</script>
+<script for="object">
+run[16] = true;
+</script>
+<script>
+test(function() {
+ for (var i = 0; i < run.length; ++i) {
+ test(function() {
+ var script = document.querySelectorAll("script[for], script[event]")[i];
+ assert_equals(run[i], expected[i],
+ "script for=" + format_value(script.getAttribute("for")) +
+ " event=" + format_value(script.getAttribute("event")));
+ }, "Script " + i);
+ }
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-language-type.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-language-type.html
new file mode 100644
index 000000000..b94834c83
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-language-type.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<title>Script: combinations of @type and @language</title>
+<link rel="author" title="Ms2ger" href="mailto:ms2ger@gmail.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#prepare-a-script">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<script>
+var run = false;
+</script>
+<script type="" language="foo">
+run = true;
+</script>
+<script>
+test(function() {
+ assert_equals(run, true);
+}, "A script with empty type should run");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-languages-01.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-languages-01.html
new file mode 100644
index 000000000..f2f2724df
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-languages-01.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<title>Script @type: unknown parameters</title>
+<link rel="author" title="Ms2ger" href="mailto:ms2ger@gmail.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#scriptingLanguages">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<div id="test">
+<script type="text/javascript;charset=UTF-8">
+test(function() {
+ assert_unreached("'charset' should have prevented this script from executing.");
+})
+</script>
+<script type="text/javascript;x-test=abc">
+test(function() {
+ assert_unreached("'x-test' should have prevented this script from executing.");
+})
+</script>
+</div>
+<script>
+test(function() {
+ assert_true(true)
+})
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-languages-02.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-languages-02.html
new file mode 100644
index 000000000..69613e510
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-languages-02.html
@@ -0,0 +1,98 @@
+<!DOCTYPE html>
+<title>Script @type: JavaScript types</title>
+<link rel="author" title="Ms2ger" href="mailto:ms2ger@gmail.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#scriptingLanguages">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<script>
+function testAttribute(attr, val, shouldRun) {
+ test(function() {
+ assert_false(ran, "ran variable not reset");
+ var script = document.createElement("script");
+ script.setAttribute(attr, val);
+ script.textContent = "ran = true;"
+ document.body.appendChild(script);
+ assert_equals(ran, shouldRun);
+ }, "Script should" + (shouldRun ? "" : "n't") + " run with " + attr + "=" + format_value(val));
+ ran = false
+}
+function testType(type) {
+ testAttribute("type", type, true);
+}
+function testLanguage(lang) {
+ testAttribute("language", lang, true);
+}
+function testTypeIgnored(type) {
+ testAttribute("type", type, false);
+}
+function testLanguageIgnored(lang) {
+ testAttribute("language", lang, false);
+}
+var application = [
+ "ecmascript",
+ "javascript",
+ "x-ecmascript",
+ "x-javascript"
+];
+var text = [
+ "ecmascript",
+ "javascript",
+ "javascript1.0",
+ "javascript1.1",
+ "javascript1.2",
+ "javascript1.3",
+ "javascript1.4",
+ "javascript1.5",
+ "jscript",
+ "livescript",
+ "x-ecmascript",
+ "x-javascript"
+];
+var spaces = [" ", "\t", "\n", "\r", "\f"];
+
+var ran = false;
+
+// Type attribute
+
+testType("");
+testTypeIgnored(" ");
+
+application.map(function(t) { return "application/" + t; }).forEach(testType);
+application.map(function(t) { return ("application/" + t).toUpperCase(); }).forEach(testType);
+
+spaces.forEach(function(s) {
+ application.map(function(t) { return "application/" + t + s; }).forEach(testType);
+ application.map(function(t) { return s + "application/" + t; }).forEach(testType);
+})
+
+application.map(function(t) { return "application/" + t + "\0"; }).forEach(testTypeIgnored);
+application.map(function(t) { return "application/" + t + "\0foo"; }).forEach(testTypeIgnored);
+
+text.map(function(t) { return "text/" + t; }).forEach(testType);
+text.map(function(t) { return ("text/" + t).toUpperCase(); }).forEach(testType);
+
+spaces.forEach(function(s) {
+ text.map(function(t) { return "text/" + t + s; }).forEach(testType);
+ text.map(function(t) { return s + "text/" + t; }).forEach(testType);
+})
+
+text.map(function(t) { return "text/" + t + "\0"; }).forEach(testTypeIgnored);
+text.map(function(t) { return "text/" + t + "\0foo"; }).forEach(testTypeIgnored);
+
+// Language attribute
+
+testLanguage("");
+testLanguageIgnored(" ");
+
+text.forEach(testLanguage);
+text.map(function(t) { return t.toUpperCase(); }).forEach(testLanguage);
+
+text.map(function(t) { return t + " "; }).forEach(testLanguageIgnored);
+text.map(function(t) { return " " + t; }).forEach(testLanguageIgnored);
+text.map(function(t) { return t + "xyz"; }).forEach(testLanguageIgnored);
+text.map(function(t) { return "xyz" + t; }).forEach(testLanguageIgnored);
+
+text.map(function(t) { return t + "\0"; }).forEach(testLanguageIgnored);
+text.map(function(t) { return t + "\0foo"; }).forEach(testLanguageIgnored);
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-noembed-noframes-iframe.xhtml b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-noembed-noframes-iframe.xhtml
new file mode 100644
index 000000000..8dd9ceb9a
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-noembed-noframes-iframe.xhtml
@@ -0,0 +1,36 @@
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title>Script inside noembed, noframes and iframe</title>
+<link rel="author" title="Ms2ger" href="mailto:ms2ger@gmail.com"/>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+</head>
+<body>
+<div id="log"></div>
+<script>
+var run = [];
+</script>
+<div id="test">
+<noembed>
+<script>
+run.push("noembed");
+</script>
+</noembed>
+<noframes>
+<script>
+run.push("noframes");
+</script>
+</noframes>
+<iframe>
+<script>
+run.push("iframe");
+</script>
+</iframe>
+</div>
+<script>
+test(function() {
+ assert_array_equals(run, ["noembed", "noframes", "iframe"], "Haven't run.");
+});
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-not-executed-after-shutdown-child.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-not-executed-after-shutdown-child.html
new file mode 100644
index 000000000..2f3ce2368
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-not-executed-after-shutdown-child.html
@@ -0,0 +1,12 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>Script is not executed after script thread is shutdown</title>
+<script>
+onload = function() {
+ script_executed = parent.script_executed;
+ s = document.createElement('script');
+ s.type = 'text/javascript';
+ s.src = 'script-not-executed-after-shutdown.js?pipe=trickle(d3)';
+ document.body.appendChild(s);
+};
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-not-executed-after-shutdown.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-not-executed-after-shutdown.html
new file mode 100644
index 000000000..704e8ed36
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-not-executed-after-shutdown.html
@@ -0,0 +1,18 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>Script is not executed after script thread is shutdown</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<iframe id="testiframe" src="script-not-executed-after-shutdown-child.html"></iframe>
+<script>
+async_test(function(t) {
+ window.script_executed = t.unreached_func("script executed in removed iframe");
+ let iframe = document.getElementById("testiframe");
+ iframe.onload = function() {
+ iframe.parentNode.removeChild(iframe);
+ };
+ setTimeout(function() {
+ t.done();
+ }, 5000);
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-not-executed-after-shutdown.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-not-executed-after-shutdown.js
new file mode 100644
index 000000000..ccdf14c0c
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-not-executed-after-shutdown.js
@@ -0,0 +1 @@
+script_executed();
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-not-found-not-executed-2.py b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-not-found-not-executed-2.py
new file mode 100644
index 000000000..53caed7c0
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-not-found-not-executed-2.py
@@ -0,0 +1,4 @@
+def main(request, response):
+ headers = [("Content-Type", "text/javascript")]
+ body = "test2_token = \"script executed\";"
+ return 200, headers, body
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-not-found-not-executed.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-not-found-not-executed.html
new file mode 100644
index 000000000..44ad30b01
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-not-found-not-executed.html
@@ -0,0 +1,19 @@
+<!doctype html>
+<meta charset="utf-8">
+<title></title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>var test1_token = "script not executed";</script>
+<script src="script-not-found-not-executed.py"></script>
+<script>
+test(function(){
+ assert_equals(test1_token, "script not executed");
+}, "Script that 404");
+</script>
+<script>var test2_token = "script not executed";</script>
+<script src="script-not-found-not-executed-2.py"></script>
+<script>
+test(function(){
+ assert_equals(test2_token, "script executed");
+}, "Script that does not 404");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-not-found-not-executed.py b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-not-found-not-executed.py
new file mode 100644
index 000000000..7722bd3f2
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-not-found-not-executed.py
@@ -0,0 +1,4 @@
+def main(request, response):
+ headers = [("Content-Type", "text/javascript")]
+ body = "test1_token = \"script executed\";"
+ return 404, headers, body
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-onerror-insertion-point-1.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-onerror-insertion-point-1.html
new file mode 100644
index 000000000..0fe39b11a
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-onerror-insertion-point-1.html
@@ -0,0 +1,12 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Test that the insertion point is defined in the error event of a parser-inserted script that actually started a fetch (but just had it fail).</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script>
+ var t = async_test("");
+ var writeDone = t.step_func_done(function(text) {
+ assert_equals(text, "Some text");
+ });
+</script>
+<iframe src="support/script-onerror-insertion-point-1-helper.html"></iframe>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-onerror-insertion-point-2.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-onerror-insertion-point-2.html
new file mode 100644
index 000000000..6d3f3ef09
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-onerror-insertion-point-2.html
@@ -0,0 +1,13 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Test that the insertion point is not defined in the error event of a
+ parser-inserted script that has an unparseable URL</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script>
+ var t = async_test("");
+ var writeDone = t.step_func_done(function(text) {
+ assert_equals(text, "text");
+ });
+</script>
+<iframe src="support/script-onerror-insertion-point-2-helper.html"></iframe>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-onload-insertion-point.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-onload-insertion-point.html
new file mode 100644
index 000000000..ce3ddeee6
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-onload-insertion-point.html
@@ -0,0 +1,12 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Test that the insertion point is defined in the load event of a parser-inserted script.</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script>
+ var t = async_test("");
+ var writeDone = t.step_func_done(function(text) {
+ assert_equals(text, "Some text");
+ });
+</script>
+<iframe src="support/script-onload-insertion-point-helper.html"></iframe>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-onload-string.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-onload-string.html
new file mode 100644
index 000000000..85f2d4dcf
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-onload-string.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<title>Script: setting onload to a string</title>
+<link rel="author" title="Ms2ger" href="mailto:ms2ger@gmail.com">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+test(function() {
+ var s = document.createElement("script");
+ assert_equals(s.onload, null);
+ var dummy = function() {};
+ s.onload = dummy;
+ assert_equals(s.onload, dummy);
+ s.onload = "w('load DOM appended')";
+ assert_equals(s.onload, null);
+}, "Setting onload to a string should convert to null.");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-text-xhtml.xhtml b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-text-xhtml.xhtml
new file mode 100644
index 000000000..33a4635db
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-text-xhtml.xhtml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<title>HTMLScriptElement.text</title>
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-script-text"/>
+<script src="/resources/testharness.js"/>
+<script src="/resources/testharnessreport.js"/>
+</head>
+<body>
+<div id="log"></div>
+<script>
+<x>7;</x>
+<![CDATA[
+ var x = "y";
+]]>
+</script>
+<script>
+var script;
+setup(function() {
+ script = document.body.getElementsByTagName("script")[0];
+})
+test(function() {
+ assert_equals(script.text, '\n\n\n var x = "y";\n\n')
+ assert_equals(script.textContent, '\n7;\n\n var x = "y";\n\n')
+}, "Getter with CDATA section")
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-text.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-text.html
new file mode 100644
index 000000000..6e8647224
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/script-text.html
@@ -0,0 +1,72 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>HTMLScriptElement.text</title>
+<link rel=help href="https://html.spec.whatwg.org/multipage/#dom-script-text">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<script>
+var script;
+setup(function() {
+ script = document.createElement("script")
+ script.appendChild(document.createComment("COMMENT"))
+ script.appendChild(document.createTextNode(" TEXT "))
+ script.appendChild(document.createProcessingInstruction("P", "I"))
+ script.appendChild(document.createElement("a"))
+ .appendChild(document.createTextNode("ELEMENT"))
+})
+
+test(function() {
+ assert_equals(script.text, " TEXT ")
+ assert_equals(script.textContent, " TEXT ELEMENT")
+}, "Getter")
+
+test(function() {
+ script.text = " text "
+ assert_equals(script.text, " text ")
+ assert_equals(script.textContent, " text ")
+ assert_equals(script.firstChild.nodeType, Node.TEXT_NODE)
+ assert_equals(script.firstChild.data, " text ")
+ assert_equals(script.firstChild, script.lastChild)
+ assert_array_equals(script.childNodes, [script.firstChild])
+}, "Setter (non-empty string)")
+
+test(function() {
+ script.text = ""
+ assert_equals(script.text, "")
+ assert_equals(script.textContent, "")
+ assert_equals(script.firstChild, null)
+}, "Setter (empty string)")
+
+test(function() {
+ script.text = null
+ assert_equals(script.text, "null")
+ assert_equals(script.textContent, "null")
+ assert_equals(script.firstChild.nodeType, Node.TEXT_NODE)
+ assert_equals(script.firstChild.data, "null")
+ assert_equals(script.firstChild, script.lastChild)
+}, "Setter (null)")
+
+test(function() {
+ script.text = undefined
+ assert_equals(script.text, "undefined")
+ assert_equals(script.textContent, "undefined")
+ assert_equals(script.firstChild.nodeType, Node.TEXT_NODE)
+ assert_equals(script.firstChild.data, "undefined")
+ assert_equals(script.firstChild, script.lastChild)
+}, "Setter (undefined)")
+
+test(function() {
+ var s = document.createElement("script");
+ var text = document.createTextNode("one");
+ s.appendChild(text);
+
+ assert_equals(s.firstChild, text);
+ assert_equals(text.nodeValue, "one");
+
+ s.text = "two";
+ assert_not_equals(s.firstChild, text);
+ assert_equals(text.nodeValue, "one");
+ assert_equals(s.firstChild.nodeValue, "two");
+}, "Setter (text node reuse)")
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/scripting-enabled.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/scripting-enabled.html
new file mode 100644
index 000000000..a2671a78f
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/scripting-enabled.html
@@ -0,0 +1,16 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>JS is disabled on documents created without a browsing context</title>
+<link rel="help" href="https://html.spec.whatwg.org/multipage/webappapis.html#concept-n-script">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+test(function(t) {
+ var doc = document.implementation.createHTMLDocument();
+ window.fail_test = t.unreached_func('should not have been called');
+
+ var script = doc.createElement('script');
+ script.textContent = 'fail_test();';
+ doc.documentElement.appendChild(script);
+}, 'script on document returned by createHTMLDocument should not execute');
+</script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/serve-with-content-type.py b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/serve-with-content-type.py
new file mode 100644
index 000000000..7cfe6f4ce
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/serve-with-content-type.py
@@ -0,0 +1,15 @@
+import os
+
+def main(request, response):
+ directory = os.path.dirname(__file__)
+
+ try:
+ file_name = request.GET.first("fn")
+ content_type = request.GET.first("ct")
+ with open(os.path.join(directory, file_name), "rb") as fh:
+ content = fh.read()
+
+ response.headers.set("Content-Type", content_type)
+ response.content = content
+ except:
+ response.set_error(400, "Not enough parameters or file not found")
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/support/script-onerror-insertion-point-1-helper.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/support/script-onerror-insertion-point-1-helper.html
new file mode 100644
index 000000000..d9b0c84ca
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/support/script-onerror-insertion-point-1-helper.html
@@ -0,0 +1,2 @@
+Some <script src="nosuchscripthere.js"
+ onerror="document.write('text'); parent.writeDone(document.documentElement.textContent)"></script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/support/script-onerror-insertion-point-2-helper.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/support/script-onerror-insertion-point-2-helper.html
new file mode 100644
index 000000000..7a1739815
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/support/script-onerror-insertion-point-2-helper.html
@@ -0,0 +1,2 @@
+Some <script src="http://this is not parseable"
+ onerror="document.write('text'); parent.writeDone(document.documentElement.textContent)"></script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/support/script-onload-insertion-point-helper.html b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/support/script-onload-insertion-point-helper.html
new file mode 100644
index 000000000..f0236b4fb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/support/script-onload-insertion-point-helper.html
@@ -0,0 +1,2 @@
+Some <script src="script-onload-insertion-point-helper.js"
+ onload="document.write('xt'); parent.writeDone(document.documentElement.textContent)"></script>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/support/script-onload-insertion-point-helper.js b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/support/script-onload-insertion-point-helper.js
new file mode 100644
index 000000000..8a96a0b78
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-script-element/support/script-onload-insertion-point-helper.js
@@ -0,0 +1 @@
+document.write("te");
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/additions-to-parsing-xhtml-documents/node-document.html b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/additions-to-parsing-xhtml-documents/node-document.html
new file mode 100644
index 000000000..8676319b2
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/additions-to-parsing-xhtml-documents/node-document.html
@@ -0,0 +1,150 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>HTML Templates: Parsing XHTML: Node's node document</title>
+<meta name="author" title="Sergey G. Grekhov" href="mailto:sgrekhov@unipro.ru">
+<meta name="author" title="Aleksei Yu. Semenov" href="mailto:a.semenov@unipro.ru">
+<meta name="assert" content="Parsing XHTML: Node's node document must be set to that of the element to which it will be appended">
+<link rel="help" href="http://www.w3.org/TR/2013/WD-html-templates-20130214/#parsing-xhtml-documents">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src='/html/resources/common.js'></script>
+</head>
+<body>
+<div id="log"></div>
+<script type="text/javascript">
+
+
+
+test(function() {
+ var doc = newXHTMLDocument();
+ doc.body = doc.createElement('body');
+ doc.body.innerHTML = '<template id="tmpl"></template>';
+
+ var template = doc.querySelector('#tmpl');
+
+ assert_not_equals(template, null, 'Template element should not be null');
+ assert_not_equals(template.content, undefined,
+ 'Content attribute of template element should not be undefined');
+ assert_not_equals(template.content, null,
+ 'Content attribute of template element should not be null');
+
+ assert_equals(template.ownerDocument, doc.body.ownerDocument,
+ 'Wrong template node owner document');
+ var ownerDoc = template.content.ownerDocument;
+ assert_not_equals(ownerDoc, doc, 'Wrong template content owner document');
+ assert_not_equals(ownerDoc, document, 'Wrong template content owner document');
+ assert_equals(ownerDoc.defaultView, null,
+ 'Template content owner document should not have a browsing context');
+
+}, 'Parsing XHTML: Node\'s node document must be set to that of the element '
+ + 'to which it will be appended. Test empty template');
+
+
+
+test(function() {
+ var doc = newXHTMLDocument();
+
+ doc.body = doc.createElement('body');
+ doc.body.innerHTML = '<template id="tmpl"><div>Div content</div></template>';
+
+ var template = doc.querySelector('#tmpl');
+
+ assert_equals(template.ownerDocument, doc.body.ownerDocument,
+ 'Wrong template node owner document');
+
+ assert_not_equals(template, null, 'Template element should not be null');
+ assert_not_equals(template.content, undefined,
+ 'Content attribute of template element should not be undefined');
+ assert_not_equals(template.content, null,
+ 'Content attribute of template element should not be null');
+
+ var div = template.content.querySelector('div');
+ assert_equals(template.content.ownerDocument, div.ownerDocument,
+ 'Wrong DIV node owner document');
+
+}, 'Parsing XHTML: Node\'s node document must be set to that of the element '
+ + 'to which it will be appended. Test not empty template');
+
+
+
+test(function() {
+ var doc = newXHTMLDocument();
+ doc.body = doc.createElement('body');
+ doc.body.innerHTML = ''
+ + '<template id="tmpl"><div>Div content</div> And some more text'
+ + '<template id="tmpl2"><div>Template content</div></template>'
+ + '</template>';
+
+ var template = doc.querySelector('#tmpl');
+ assert_not_equals(template, null, 'Template element should not be null');
+ assert_equals(template.ownerDocument, doc, 'Wrong template node owner document');
+ assert_not_equals(template.content, undefined,
+ 'Content attribute of template element should not be undefined');
+ assert_not_equals(template.content, null,
+ 'Content attribute of template element should not be null');
+
+ var nestedTemplate = template.content.querySelector('#tmpl2');
+ assert_not_equals(nestedTemplate, null, 'Nested template element should not be null');
+ assert_not_equals(nestedTemplate.content, undefined,
+ 'Content attribute of nested template element should not be undefined');
+ assert_not_equals(nestedTemplate.content, null,
+ 'Content attribute of nested template element should not be null');
+
+ assert_equals(nestedTemplate.ownerDocument, template.content.ownerDocument,
+ 'Wrong nested template node owner document');
+
+
+ var div = nestedTemplate.content.querySelector('div');
+ assert_equals(nestedTemplate.content.ownerDocument, div.ownerDocument,
+ 'Wrong DIV node owner document');
+
+}, 'Parsing XHTML: Node\'s node document must be set to that of the element '
+ + 'to which it will be appended. Test nested templates');
+
+
+
+testInIFrame('../resources/template-child-nodes-div.xhtml', function(context) {
+ var doc = context.iframes[0].contentDocument;
+
+ var template = doc.querySelector('template');
+
+ assert_equals(template.ownerDocument, doc, 'Wrong template node owner document');
+
+ assert_not_equals(template.content, undefined,
+ 'Content attribute of template element should not be undefined');
+ assert_not_equals(template.content, null,
+ 'Content attribute of template element should not be null');
+
+ var div = template.content.querySelector('div');
+ assert_equals(template.content.ownerDocument, div.ownerDocument,
+ 'Wrong DIV node owner document');
+
+}, 'Parsing XHTML: Node\'s node document must be set to that of the element '
+ + 'to which it will be appended. Test loading XHTML document from a file');
+
+
+
+testInIFrame('../resources/template-child-nodes-nested.xhtml', function(context) {
+ var doc = context.iframes[0].contentDocument;
+
+ var template = doc.querySelector('template');
+
+ assert_equals(template.ownerDocument, doc, 'Wrong template node owner document');
+
+ var nestedTemplate = template.content.querySelector('template');
+
+ assert_equals(nestedTemplate.ownerDocument, template.content.ownerDocument,
+ 'Wrong template node owner document');
+
+ var div = nestedTemplate.content.querySelector('div');
+ assert_equals(nestedTemplate.content.ownerDocument, div.ownerDocument,
+ 'Wrong DIV node owner document');
+
+}, 'Parsing XHTML: Node\'s node document must be set to that of the element '
+ + 'to which it will be appended. Test loading of XHTML document '
+ + 'with nested templates from a file');
+
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/additions-to-parsing-xhtml-documents/template-child-nodes.html b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/additions-to-parsing-xhtml-documents/template-child-nodes.html
new file mode 100644
index 000000000..40abda568
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/additions-to-parsing-xhtml-documents/template-child-nodes.html
@@ -0,0 +1,102 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>HTML Templates: Child nodes of template element in XHTML documents</title>
+<meta name="author" title="Sergey G. Grekhov" href="mailto:sgrekhov@unipro.ru">
+<meta name="author" title="Aleksei Yu. Semenov" href="a.semenov@unipro.ru">
+<meta name="assert" content="Child nodes of template element in XHTML documents are always appended to the template content (instead of template itself)">
+<link rel="help" href="http://www.w3.org/TR/2013/WD-html-templates-20130214/#parsing-xhtml-documents">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src='/html/resources/common.js'></script>
+</head>
+<body>
+<div id="log"></div>
+<script type="text/javascript">
+
+
+test(function() {
+ var doc = newXHTMLDocument();
+
+ doc.body = doc.createElement('body');
+ doc.body.innerHTML = '<template id="tmpl1">'
+ + '<div id="div1">This is div inside template</div>'
+ + '<div id="div2">This is another div inside template</div>'
+ + '</template>';
+
+ var template = doc.querySelector('#tmpl1');
+
+ assert_equals(template.childNodes.length, 0,
+ 'Wrong number of template child nodes');
+ assert_equals(template.content.childNodes.length, 2,
+ 'Wrong number of template content child nodes');
+
+}, 'Child nodes of template element in XHTML documents must be appended to template content');
+
+
+
+test(function() {
+ var doc = newXHTMLDocument();
+ doc.body = doc.createElement('body');
+ doc.body.innerHTML = '<template id="tmpl1">'
+ + '<div id="div1">This is div inside template</div>'
+ + '<div id="div2">This is another div inside template</div>'
+ + '<template id="tmpl2">'
+ + '<div id="div3">This is div inside nested template</div>'
+ + '<div id="div4">This is another div inside nested template</div>'
+ + '</template>' + '</template>';
+
+ var template = doc.querySelector('#tmpl1');
+
+ assert_equals(template.childNodes.length, 0,
+ 'Wrong number of template child nodes');
+ assert_equals(template.content.childNodes.length, 3,
+ 'Wrong number of template content child nodes');
+
+ var nestedTemplate = template.content.querySelector('#tmpl2');
+
+ assert_equals(nestedTemplate.childNodes.length, 0,
+ 'Wrong number of template child nodes');
+ assert_equals(nestedTemplate.content.childNodes.length, 2,
+ 'Wrong number of nested template content child nodes');
+
+}, 'Child nodes of nested template element in XHTML documents must be appended to template content');
+
+
+
+testInIFrame('../resources/template-child-nodes-div.xhtml', function(context) {
+ var doc = context.iframes[0].contentDocument;
+
+ var template = doc.querySelector('template');
+
+ assert_equals(template.childNodes.length, 0,
+ 'Wrong number of template child nodes');
+ assert_equals(template.content.querySelectorAll('div').length, 2,
+ 'Wrong number of template content child nodes');
+
+}, 'Child nodes of template element in XHTML documents must be appended to template content. '
+ + 'Test loading XHTML document from a file');
+
+
+testInIFrame('../resources/template-child-nodes-nested.xhtml', function(context) {
+ var doc = context.iframes[0].contentDocument;
+
+ var template = doc.querySelector('template');
+
+ assert_equals(template.childNodes.length, 0,
+ 'Wrong number of template child nodes');
+
+ var nestedTemplate = template.content.querySelector('template');
+
+ assert_equals(nestedTemplate.childNodes.length, 0,
+ 'Wrong number of template child nodes');
+
+ assert_equals(nestedTemplate.content.querySelectorAll('div').length, 2,
+ 'Wrong number of template content child nodes');
+
+}, 'Child nodes of nested template element in XHTML documents must be appended to template content. '
+ + 'Test loading XHTML document from a file');
+
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/additions-to-serializing-xhtml-documents/outerhtml.html b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/additions-to-serializing-xhtml-documents/outerhtml.html
new file mode 100644
index 000000000..416a3bc61
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/additions-to-serializing-xhtml-documents/outerhtml.html
@@ -0,0 +1,71 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>HTML Templates: serialize template contents instead of template element</title>
+<meta name="author" title="Aleksei Yu. Semenov" href="a.semenov@unipro.ru">
+<meta name="assert" content="Template contents should be serialized instead of template element if serializing template element in XHTML document">
+<link rel="help" href="http://www.w3.org/TR/2013/WD-html-templates-20130214/#serializing-xhtml-documents">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src='/html/resources/common.js'></script>
+</head>
+<body>
+<div id="log"></div>
+<script type="text/javascript">
+
+test(function () {
+ var doc = newXHTMLDocument();
+ var template = doc.createElement('template');
+
+ var div = doc.createElement('div');
+ div.setAttribute('id', 'div1');
+ div.innerHTML = 'some text';
+ template.content.appendChild(div);
+
+ assert_equals(template.outerHTML, '<template xmlns="http://www.w3.org/1999/xhtml"><div id="div1">some text</div></template>',
+ 'template element is serialized incorrectly');
+
+}, 'Template contents should be serialized instead of template element if serializing template element');
+
+
+
+test(function () {
+ var doc = newXHTMLDocument();
+ var template = doc.createElement('template');
+ var nestedTemplate = doc.createElement('template');
+
+ template.content.appendChild(nestedTemplate);
+
+ var div = doc.createElement('div');
+ div.setAttribute('id', 'div1');
+ div.innerHTML = 'some text';
+ nestedTemplate.content.appendChild(div);
+
+ assert_equals(template.outerHTML, '<template xmlns="http://www.w3.org/1999/xhtml"><template><div id="div1">some text</div></template></template>',
+ 'template element is serialized incorrectly');
+
+
+}, 'Template contents should be serialized instead of template element if serializing template element. '
+ + 'Test nested template');
+
+
+test(function () {
+ var doc = newXHTMLDocument();
+ var template = doc.createElement('template');
+
+ var div = doc.createElement('div');
+ div.setAttribute('id', 'div1');
+ div.innerHTML = 'some text';
+ template.content.appendChild(div);
+ doc.body = doc.createElement('body');
+ doc.body.appendChild(template);
+
+ assert_equals(doc.documentElement.outerHTML, '<html xmlns="http://www.w3.org/1999/xhtml"><body><template><div id="div1">some text</div></template></body></html>',
+ 'template element is serialized incorrectly');
+
+}, 'Template contents should be serialized instead of template element if serializing template element. '
+ + 'Test serializing whole document');
+
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/additions-to-the-css-user-agent-style-sheet/css-user-agent-style-sheet-test-001-ref.html b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/additions-to-the-css-user-agent-style-sheet/css-user-agent-style-sheet-test-001-ref.html
new file mode 100644
index 000000000..55c8b2e30
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/additions-to-the-css-user-agent-style-sheet/css-user-agent-style-sheet-test-001-ref.html
@@ -0,0 +1,6 @@
+<!DOCTYPE html>
+<title>Template Reftest Reference</title>
+<link rel="author" title="Sergey G. Grekhov" href="mailto:sgrekhov@unipro.ru"/>
+<body>
+ <p>Test passes if there's no anything below this line.</p>
+</body>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/additions-to-the-css-user-agent-style-sheet/css-user-agent-style-sheet-test-001.html b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/additions-to-the-css-user-agent-style-sheet/css-user-agent-style-sheet-test-001.html
new file mode 100644
index 000000000..fc310f47c
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/additions-to-the-css-user-agent-style-sheet/css-user-agent-style-sheet-test-001.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+ <title>Template Test: check that template content is invisible by default</title>
+ <link rel="author" title="Sergey G. Grekhov" href="mailto:sgrekhov@unipro.ru">
+ <link rel="help" href="http://www.w3.org/TR/2013/WD-html-templates-20130214/#css-additions">
+ <meta name="assert" content="Test checks that the template contents are hidden implicitly">
+ <link rel="match" href="css-user-agent-style-sheet-test-001-ref.html">
+<body>
+ <p>Test passes if there's no anything below this line.</p>
+ <template>
+ <span style="color:red">Test fails if you can see this text</span>
+ </template>
+</body>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/additions-to-the-css-user-agent-style-sheet/css-user-agent-style-sheet-test-002.html b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/additions-to-the-css-user-agent-style-sheet/css-user-agent-style-sheet-test-002.html
new file mode 100644
index 000000000..92f3d81ea
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/additions-to-the-css-user-agent-style-sheet/css-user-agent-style-sheet-test-002.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+ <title>Template Test: check that template content is invisible by default</title>
+ <link rel="author" title="Sergey G. Grekhov" href="mailto:sgrekhov@unipro.ru">
+ <link rel="help" href="http://www.w3.org/TR/2013/WD-html-templates-20130214/#css-additions">
+ <meta name="assert" content="The template element itself must be hidden by default">
+ <link rel="match" href="css-user-agent-style-sheet-test-001-ref.html">
+<body>
+ <p>Test passes if there's no anything below this line.</p>
+ <template style="border: 1px solid; width: 100px; height: 100px">
+ <span style="color:red">Test fails if you can see this text or border around it</span>
+ </template>
+</body>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/additions-to-the-css-user-agent-style-sheet/css-user-agent-style-sheet-test-003.html b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/additions-to-the-css-user-agent-style-sheet/css-user-agent-style-sheet-test-003.html
new file mode 100644
index 000000000..4c477fde7
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/additions-to-the-css-user-agent-style-sheet/css-user-agent-style-sheet-test-003.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+ <title>HTML Templates: template content is invisible by default</title>
+ <link rel="author" title="Sergey G. Grekhov" href="mailto:sgrekhov@unipro.ru">
+ <link rel="help" href="http://www.w3.org/TR/2013/WD-html-templates-20130214/#css-additions">
+ <meta name="assert" content="The template element itself must be hidden by default">
+ <link rel="match" href="css-user-agent-style-sheet-test-001-ref.html">
+ <style>
+ template {
+ border: 1px solid;
+ width: 100px;
+ height: 100px;
+ }
+ </style>
+<body>
+ <p>Test passes if there's no anything below this line.</p>
+ <template>
+ <span style="color:red">Test fails if you can see this text or border around it</span>
+ </template>
+</body>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/additions-to-the-steps-to-clone-a-node/template-clone-children.html b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/additions-to-the-steps-to-clone-a-node/template-clone-children.html
new file mode 100644
index 000000000..c668d9095
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/additions-to-the-steps-to-clone-a-node/template-clone-children.html
@@ -0,0 +1,82 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>HTML Templates: Clone template node: All the children of template content are copied if 'copy children flag' set to true</title>
+<meta name="author" title="Sergey G. Grekhov" href="mailto:sgrekhov@unipro.ru">
+<meta name="assert" content="Clone template node: all the children of template content are copied if 'copy children flag' set to true">
+<link rel="help" href="http://www.w3.org/TR/2013/WD-html-templates-20130214/#node-clone-additions">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src='/html/resources/common.js'></script>
+</head>
+<body>
+<div id="log"></div>
+<script type="text/javascript">
+
+test(function () {
+ var doc = newHTMLDocument();
+ doc.body.innerHTML = '<template id="tmpl1">' +
+ '<div id="div1">This is div inside template</div>' +
+ '<div id="div2">This is another div inside template</div>' +
+ '</template>';
+
+ var template = doc.querySelector('#tmpl1');
+ var copy = template.cloneNode(true);
+
+ assert_not_equals(copy.content, undefined, 'Template clone content attribute should not be undefined');
+ assert_not_equals(copy.content, null, 'Template clone content attribute should not be null');
+
+ assert_equals(copy.content.childNodes.length, 2,
+ 'Wrong number of template content\'s copy child nodes');
+ assert_not_equals(copy.content.querySelector('#div1'), null,
+ 'Template child node should be copied');
+ assert_not_equals(copy.content.querySelector('#div2'), null,
+ 'Template child node should be copied');
+
+}, 'Clone template node. Test call to cloneNode(true)');
+
+
+
+test(function () {
+ var doc = newHTMLDocument();
+ doc.body.innerHTML = '<template id="tmpl1">' +
+ '<div id="div1">This is div inside template</div>' +
+ '<div id="div2">This is another div inside template</div>' +
+ '</template>';
+
+ var template = doc.querySelector('#tmpl1');
+ var copy = template.cloneNode();
+
+ assert_not_equals(copy.content, undefined, 'Template clone content attribute should not be undefined');
+ assert_not_equals(copy.content, null, 'Template clone content attribute should not be null');
+
+ assert_equals(copy.content.childNodes.length, 0,
+ 'Wrong number of template content\'s copy child nodes');
+
+}, 'Clone template node. Test call to cloneNode() with the default parameter '
+ + '(false by default)');
+
+
+
+test(function () {
+ var doc = newHTMLDocument();
+ doc.body.innerHTML = '<template id="tmpl1">' +
+ '<div id="div1">This is div inside template</div>' +
+ '<div id="div2">This is another div inside template</div>' +
+ '</template>';
+
+ var template = doc.querySelector('#tmpl1');
+ var copy = template.cloneNode(false);
+
+ assert_not_equals(copy.content, undefined, 'Template clone content attribute is undefined');
+ assert_not_equals(copy.content, null, 'Template clone content attribute is null');
+
+ assert_equals(copy.content.childNodes.length, 0,
+ 'Wrong number of template content\'s copy child nodes');
+
+}, 'Clone template node. Test call to cloneNode(false)');
+
+
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/additions-to-the-steps-to-clone-a-node/templates-copy-document-owner.html b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/additions-to-the-steps-to-clone-a-node/templates-copy-document-owner.html
new file mode 100644
index 000000000..a2afc2304
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/additions-to-the-steps-to-clone-a-node/templates-copy-document-owner.html
@@ -0,0 +1,126 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>HTML Templates: ownerDocument of cloned template content is set to template content owner</title>
+<meta name="author" title="Sergey G. Grekhov" href="mailto:sgrekhov@unipro.ru">
+<meta name="author" title="Aleksei Yu. Semenov" href="a.semenov@unipro.ru">
+<meta name="assert" content="ownerDocument of cloned template content is set to template content owner">
+<link rel="help" href="http://www.w3.org/TR/2013/WD-html-templates-20130214/#node-clone-additions">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src='/html/resources/common.js'></script>
+</head>
+<body>
+<div id="log"></div>
+<script type="text/javascript">
+
+function checkOwnerDocument(node, doc) {
+ if ((node !== null) && (node !== undefined)) {
+ assert_equals(node.ownerDocument, doc,
+ 'Wrong ownerDocument of the template copy\'s node ' + node.nodeName);
+ for (var i = 0; i < node.childNodes.length; i++) {
+ if (node.childNodes[i].nodeType === Node.ELEMENT_NODE) {
+ checkOwnerDocument(node.childNodes[i], doc);
+ if (node.childNodes[i].nodeName === 'TEMPLATE') {
+ checkOwnerDocument(node.childNodes[i].content, doc);
+ }
+ }
+ }
+ }
+}
+
+
+test(function () {
+ var doc = newHTMLDocument();
+ doc.body.innerHTML = '<template id="tmpl1">' +
+ '<div id="div1">This is div inside template</div>' +
+ '<div id="div2">This is another div inside template</div>' +
+ '</template>';
+
+ var template = doc.querySelector('#tmpl1');
+ var copy = template.cloneNode(true);
+
+ assert_equals(copy.content.childNodes.length, 2,
+ 'Wrong number of template content\'s copy child nodes');
+ checkOwnerDocument(copy.content, template.content.ownerDocument);
+
+}, 'ownerDocument of cloned template content is set to template content owner. '
+ + 'Test cloning with children');
+
+
+
+test(function () {
+ var doc = newHTMLDocument();
+ doc.body.innerHTML = '<template id="tmpl1">' +
+ '<div id="div1">This is div inside template</div>' +
+ '<div id="div2">This is another div inside template</div>' +
+ '</template>';
+
+ var template = doc.querySelector('#tmpl1');
+ var copy = template.cloneNode(false);
+
+ assert_equals(copy.content.childNodes.length, 0,
+ 'Wrong number of template content\'s copy child nodes');
+ checkOwnerDocument(copy.content, template.content.ownerDocument);
+
+}, 'ownerDocument of cloned template content is set to template content owner. '
+ + 'Test cloning without children');
+
+
+
+test(function () {
+ var doc = newHTMLDocument();
+ doc.body.innerHTML = '<template id="tmpl1">' +
+ '<div id="div1">This is div inside template</div>' +
+ '<div id="div2">This is another div inside template</div>' +
+ '</template>';
+
+ var template = doc.querySelector('#tmpl1');
+ var copy = template.cloneNode();
+
+ assert_equals(copy.content.childNodes.length, 0,
+ 'Wrong number of template content\'s copy child nodes');
+ checkOwnerDocument(copy.content, template.content.ownerDocument);
+
+}, 'ownerDocument of cloned template content is set to template content owner. '
+ + 'Test cloneNode() with no arguments (false by default)');
+
+
+
+test(function () {
+ var doc = newHTMLDocument();
+ doc.body.innerHTML = '<template id="tmpl1">' +
+ '<div id="div1">This is div inside template</div>' +
+ '<div id="div2">This is another div inside template</div>' +
+ '<template id="tmpl2">' +
+ '<div id="div3">This is div inside nested template</div>' +
+ '<div id="div4">This is another div inside nested template</div>' +
+ '</template>' +
+ '</template>';
+
+ var template = doc.querySelector('#tmpl1');
+ var copy = template.cloneNode(true);
+
+ assert_equals(copy.content.childNodes.length, 3,
+ 'Wrong number of template content\'s copy child nodes');
+ checkOwnerDocument(copy.content, template.content.ownerDocument);
+
+}, 'ownerDocument of cloned template content is set to template content owner. '
+ + 'Test cloning nested template');
+
+
+
+testInIFrame('../resources/template-contents.html', function(context) {
+ var doc = context.iframes[0].contentDocument;
+
+ var template = doc.body.querySelector('template');
+ var copy = template.cloneNode(true);
+
+ checkOwnerDocument(copy.content, template.content.ownerDocument);
+
+}, 'ownerDocument of cloned template content is set to template content owner. '
+ + 'Test loading HTML document from file');
+
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/definitions/template-contents-owner-document-type.html b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/definitions/template-contents-owner-document-type.html
new file mode 100644
index 000000000..d063acded
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/definitions/template-contents-owner-document-type.html
@@ -0,0 +1,83 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>HTML Templates: The template contents owner document type is HTML document</title>
+<meta name="author" title="Sergey G. Grekhov" href="mailto:sgrekhov@unipro.ru">
+<meta name="assert" content="The template contents owner document type is HTML document, if template is declared in HTML document">
+<link rel="help" href="http://www.w3.org/TR/2013/WD-html-templates-20130214/#definitions">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src='/html/resources/common.js'></script>
+</head>
+<body>
+<div id="log"></div>
+<script type="text/javascript">
+
+testInIFrame('../resources/template-contents.html', function(context) {
+ var doc = context.iframes[0].contentDocument;
+ var template = doc.querySelector('template');
+ var content_owner = template.content.ownerDocument;
+
+ assert_class_string(content_owner, 'Document',
+ 'Template content owner should be a document');
+ assert_equals(content_owner.createElement('DIV').localName, 'div',
+ 'Template content owner should be an HTML document');
+
+}, 'The template contents owner document type is HTML document ' +
+ '(case when document has browsing context and the template ' +
+ 'is created by HTML parser)');
+
+
+testInIFrame('../resources/template-contents.html', function(context) {
+ var doc = context.iframes[0].contentDocument;
+ var template = doc.createElement('template');
+ var content_owner = template.content.ownerDocument;
+ var div = doc.createElement('DIV');
+ template.appendChild(div);
+
+ doc.body.appendChild(template);
+
+ assert_class_string(content_owner, 'Document',
+ 'Template content owner should be a document');
+ assert_equals(div.localName, 'div',
+ 'Template content owner should be an HTML document');
+
+}, 'The template contents owner document type is HTML document ' +
+ '(case when document has browsing context and the template ' +
+ 'is created by createElement())');
+
+
+test(function() {
+ var doc = newHTMLDocument();
+ var template = doc.createElement('template');
+ var content_owner = template.content.ownerDocument;
+ var div = doc.createElement('DIV');
+ template.appendChild(div);
+
+ doc.body.appendChild(template);
+
+ assert_class_string(content_owner, 'Document',
+ 'Template content owner should be a document');
+ assert_equals(div.localName, 'div',
+ 'Template content owner should be an HTML document');
+
+}, 'The template contents owner document type is HTML document ' +
+ '(case when document has no browsing context and the template is created ' +
+ 'by createElement())');
+
+test(function() {
+ var doc = newHTMLDocument();
+ doc.body.innerHTML = '<template><div>Hello!</div></template>';
+ var template = doc.querySelector('template');
+ var content_owner = template.content.ownerDocument;
+
+ assert_class_string(content_owner, 'Document',
+ 'Template content owner should be a document');
+ assert_equals(content_owner.createElement('DIV').localName, 'div',
+ 'Template content owner should be an HTML document');
+
+}, 'The template contents owner document type is HTML document ' +
+ '(case when document has no browsing context and the template is created via innerHTML)');
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/definitions/template-contents-owner-test-001.html b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/definitions/template-contents-owner-test-001.html
new file mode 100644
index 000000000..a087f788e
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/definitions/template-contents-owner-test-001.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>HTML Templates: The template contents owner document (no browsing context)</title>
+<meta name="author" title="Sergey G. Grekhov" href="mailto:sgrekhov@unipro.ru">
+<meta name="assert" content="Even if template's enclosing document has no browsing context, it gets its own template contents owner">
+<link rel="help" href="http://www.w3.org/TR/2013/WD-html-templates-20130214/#definitions">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src='/html/resources/common.js'></script>
+</head>
+<body>
+<div id="log"></div>
+<script type="text/javascript">
+
+
+test(function() {
+ var doc = newHTMLDocument();
+ var template = doc.createElement('template');
+
+ doc.body.appendChild(template);
+
+ assert_not_equals(template.content.ownerDocument, doc, 'Wrong template content owner');
+
+}, 'Test the template contents owner document when enclosing document has '
+ + 'no browsing content. Template element is created by createElement()');
+
+
+
+test(function() {
+ var doc = newHTMLDocument();
+
+ doc.body.innerHTML = '<template><div>some text</div></template>';
+
+ var template = doc.querySelector('template');
+
+ assert_not_equals(template.content.ownerDocument, doc, 'Wrong template content owner');
+
+}, 'Test the template contents owner document when enclosing document has '
+ + 'no browsing content. Template element is created by innerHTML');
+
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/definitions/template-contents-owner-test-002.html b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/definitions/template-contents-owner-test-002.html
new file mode 100644
index 000000000..cf2e30b64
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/definitions/template-contents-owner-test-002.html
@@ -0,0 +1,67 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>HTML Templates: The template contents owner document (there's browsing context)</title>
+<meta name="author" title="Sergey G. Grekhov" href="mailto:sgrekhov@unipro.ru">
+<meta name="assert" content="If template's enclosing document has browsing context, then templates content owner must be a new Document node without browsing context">
+<link rel="help" href="http://www.w3.org/TR/2013/WD-html-templates-20130214/#definitions">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src='/html/resources/common.js'></script>
+</head>
+<body>
+<div id="log"></div>
+<script type="text/javascript">
+
+
+testInIFrame(null, function(context) {
+ var doc = context.iframes[0].contentDocument;
+ var template = doc.createElement('template');
+
+ var div = doc.createElement('div');
+ div.setAttribute('id', 'div1');
+
+ template.appendChild(div);
+
+ doc.body.appendChild(template);
+
+ // doc has browsing context. There should be another document as a template
+ // content owner
+ assert_not_equals(template.content.ownerDocument, doc, 'Wrong template owner document');
+
+}, 'The template contents owner document must be different from template owner document,' +
+ ' which has browsing context. Template element is created by createElement()');
+
+
+
+testInIFrame(null, function(context) {
+ var doc = context.iframes[0].contentDocument;
+
+ doc.body.innerHTML = '<template><div>some text</div></template>';
+
+ var template = doc.querySelector('template');
+
+ // doc has browsing context. There should be another document as a template
+ // content owner
+ assert_not_equals(template.content.ownerDocument, doc, 'Wrong template owner document');
+
+}, 'The template contents owner document must be different from template owner document,' +
+ ' which has browsing context. Template element is created via innerHTML');
+
+
+
+testInIFrame('../resources/template-contents.html', function(context) {
+ var doc = context.iframes[0].contentDocument;
+
+ var template = doc.querySelector('template');
+
+ // doc has browsing context. There should be another document as a template
+ // content owner
+ assert_not_equals(template.content.ownerDocument, doc, 'Wrong template owner document');
+
+}, 'The template contents owner document must be different from template owner document,' +
+ ' which has browsing context. Template element is created by HTML parser');
+
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/definitions/template-contents.html b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/definitions/template-contents.html
new file mode 100644
index 000000000..4a61dc8d3
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/definitions/template-contents.html
@@ -0,0 +1,172 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>HTML Templates: The template contents is a DocumentFragment</title>
+<meta name="author" title="Sergey G. Grekhov" href="mailto:sgrekhov@unipro.ru">
+<meta name="assert" content="The template contents must be a DocumentFragment">
+<link rel="help" href="http://www.w3.org/TR/2013/WD-html-templates-20130214/#definitions">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src='/html/resources/common.js'></script>
+</head>
+<body>
+<div id="log"></div>
+<script type="text/javascript">
+
+
+test(function() {
+ var doc = newHTMLDocument();
+ var template = doc.createElement('template');
+
+ doc.body.appendChild(template);
+
+ assert_equals(template.content.nodeType, Node.DOCUMENT_FRAGMENT_NODE,
+ 'Template content should be a DocumentFragment');
+
+ assert_class_string(template.content, 'DocumentFragment',
+ 'Template content class should be a DocumentFragment');
+
+}, 'The template contents must be a DocumentFragment (empty template)');
+
+
+test(function() {
+ var doc = newHTMLDocument();
+ var template = doc.createElement('template');
+
+ template.innerHTML = '<div>This is a div</div><span>This is a span</span>';
+
+ doc.body.appendChild(template);
+
+ assert_equals(template.content.nodeType, Node.DOCUMENT_FRAGMENT_NODE,
+ 'Template content should be a DocumentFragment');
+
+ assert_class_string(template.content, 'DocumentFragment',
+ 'Template content class should be a DocumentFragment');
+
+}, 'The template contents must be a DocumentFragment (non empty template)');
+
+
+
+test(function() {
+ var doc = newHTMLDocument();
+ var template = doc.createElement('template');
+
+ template.innerHTML = '<div>This is a div</div>';
+
+ doc.body.appendChild(template);
+
+ assert_equals(template.content.nodeType, Node.DOCUMENT_FRAGMENT_NODE,
+ 'Template content should be a documentFragment');
+
+}, 'The template contents must be a DocumentFragment (non empty template '
+ + 'containing div which is an Element instance)');
+
+
+test(function() {
+ var doc = newHTMLDocument();
+ var template = doc.createElement('template');
+
+ template.innerHTML = 'Some text';
+
+ doc.body.appendChild(template);
+
+ assert_equals(template.content.nodeType, Node.DOCUMENT_FRAGMENT_NODE,
+ 'Template content should be a documentFragment');
+
+ assert_class_string(template.content, 'DocumentFragment',
+ 'Template content class should be a DocumentFragment');
+
+}, 'The template contents must be a DocumentFragment (not empty template '
+ + 'containing text node)');
+
+
+test(function() {
+ var doc = newHTMLDocument();
+ var template = doc.createElement('template');
+
+ template.innerHTML = '<template id="t2">Some text</template>';
+
+ doc.body.appendChild(template);
+
+ assert_equals(template.content.nodeType, Node.DOCUMENT_FRAGMENT_NODE,
+ 'Template content should be a documentFragment');
+ assert_class_string(template.content, 'DocumentFragment',
+ 'Template content class should be a DocumentFragment');
+
+ var nestedTemplate = template.content.querySelector("#t2");
+ assert_equals(nestedTemplate.content.nodeType, Node.DOCUMENT_FRAGMENT_NODE,
+ 'Nested template content should be a documentFragment');
+
+ assert_class_string(nestedTemplate.content, 'DocumentFragment',
+ 'Nested template content class should be a DocumentFragment');
+
+
+}, 'The template contents must be a DocumentFragment (nested template '
+ + 'containing a text node)');
+
+
+testInIFrame('../resources/template-contents-empty.html', function(context) {
+ var doc = context.iframes[0].contentDocument;
+
+ var template = doc.querySelector('template');
+
+ assert_equals(template.content.nodeType, Node.DOCUMENT_FRAGMENT_NODE,
+ 'Template content should be a documentFragment');
+ assert_class_string(template.content, 'DocumentFragment',
+ 'Template content class should be a DocumentFragment');
+
+
+}, 'The template contents must be a DocumentFragment (the empty template tag '
+ + 'inside HTML file loaded in iframe)');
+
+
+testInIFrame('../resources/template-contents.html', function(context) {
+ var doc = context.iframes[0].contentDocument;
+
+ var template = doc.querySelector('template');
+
+ assert_equals(template.content.nodeType, Node.DOCUMENT_FRAGMENT_NODE,
+ 'Template content should be a documentFragment');
+ assert_class_string(template.content, 'DocumentFragment',
+ 'Template content class should be a DocumentFragment');
+
+}, 'The template contents must be a DocumentFragment (non empty template '
+ + 'tag inside HTML file loaded in iframe)');
+
+
+testInIFrame('../resources/template-contents-text.html', function(context) {
+ var doc = context.iframes[0].contentDocument;
+
+ var template = doc.querySelector('template');
+
+ assert_equals(template.content.nodeType, Node.DOCUMENT_FRAGMENT_NODE,
+ 'Template content should be a documentFragment');
+ assert_class_string(template.content, 'DocumentFragment',
+ 'Template content class should be a DocumentFragment');
+
+}, 'The template contents must be a DocumentFragment (the template tag '
+ + 'with some text inside HTML file loaded in iframe)');
+
+
+testInIFrame('../resources/template-contents-nested.html', function(context) {
+ var doc = context.iframes[0].contentDocument;
+
+ var template = doc.querySelector('template');
+
+ assert_equals(template.content.nodeType, Node.DOCUMENT_FRAGMENT_NODE,
+ 'Template content should be a documentFragment');
+ assert_class_string(template.content, 'DocumentFragment',
+ 'Template content class should be a DocumentFragment');
+
+ var nestedTemplate = template.content.querySelector("template");
+
+ assert_equals(nestedTemplate.content.nodeType, Node.DOCUMENT_FRAGMENT_NODE,
+ 'Nested template content should be a documentFragment');
+ assert_class_string(nestedTemplate.content, 'DocumentFragment',
+ 'Nested template content class should be a DocumentFragment');
+
+}, 'The template contents must be a DocumentFragment (the template tag '
+ + 'with nested template tag inside HTML file loaded in iframe)');
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/innerhtml-on-templates/innerhtml.html b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/innerhtml-on-templates/innerhtml.html
new file mode 100644
index 000000000..0b7ad1e46
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/innerhtml-on-templates/innerhtml.html
@@ -0,0 +1,86 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>HTML Templates: innerHTML of template element replaces all referenced by the content attribute</title>
+<meta name="author" title="Sergey G. Grekhov" href="mailto:sgrekhov@unipro.ru">
+<meta name="author" title="Aleksei Yu. Semenov" href="a.semenov@unipro.ru">
+<meta name="assert" content="innerHTML of template element replaces all referenced by the content attribute">
+<link rel="help" href="http://www.w3.org/TR/2013/WD-html-templates-20130214/#innerhtml-on-templates">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src='/html/resources/common.js'></script>
+</head>
+<body>
+<div id="log"></div>
+<script type="text/javascript">
+
+test(function () {
+ var doc = newHTMLDocument();
+ var template = doc.createElement('template');
+
+ var div1 = doc.createElement('div');
+ div1.setAttribute('id', 'div1');
+ template.content.appendChild(div1);
+
+ assert_not_equals(template.content.querySelector('#div1'), null,
+ 'Element should present in template content');
+
+ template.innerHTML = '<div id="div2"></div>';
+
+ assert_equals(template.content.querySelector('#div1'), null,
+ 'Template content should be replaced by innerHTML');
+ assert_not_equals(template.content.querySelector('#div2'), null,
+ 'Element should present in template content');
+
+}, 'innerHTML of template element replaces all referenced by the content attribute');
+
+
+
+test(function () {
+ var doc = newHTMLDocument();
+ var template = doc.createElement('template');
+ var nestedTemplate = doc.createElement('template');
+
+ template.content.appendChild(nestedTemplate);
+
+ var div1 = doc.createElement('div');
+ div1.setAttribute('id', 'div1');
+ nestedTemplate.content.appendChild(div1);
+
+ assert_not_equals(nestedTemplate.content.querySelector('#div1'), null,
+ 'Element should present in template content');
+
+ nestedTemplate.innerHTML = '<div id="div2"></div>';
+
+ assert_equals(nestedTemplate.content.querySelector('#div1'), null,
+ 'Template content should be replaced by innerHTML');
+ assert_not_equals(nestedTemplate.content.querySelector('#div2'), null,
+ 'Element should present in template content');
+
+}, 'innerHTML of template element replaces all referenced by the content attribute. '
+ + 'Test nested template');
+
+
+testInIFrame('../resources/template-contents.html', function(context) {
+ var doc = context.iframes[0].contentDocument;
+
+ var template = doc.querySelector('template');
+ assert_not_equals(template.content.querySelector('div'), null,
+ 'Div element should present in template content');
+
+ template.innerHTML = '<span>span internals</span>';
+
+ assert_equals(template.content.querySelector('div'), null,
+ 'div element should be replaced by span in template content');
+
+ assert_not_equals(template.content.querySelector('span'), null,
+ 'span element should present in template content');
+
+
+}, 'innerHTML of template element replaces all referenced by the content attribute. '
+ + 'Test loading of HTML document from a file');
+
+
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/end-template-tag-in-body.html b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/end-template-tag-in-body.html
new file mode 100644
index 000000000..2cb149853
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/end-template-tag-in-body.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>The file contains several &lt;/template&gt; tag in HTML body without start one</title>
+ <link rel="author" title="Aleksei Yu. Semenov" href="mailto:a.semenov@unipro.ru">
+</head>
+<body>
+ </template>
+ <div>The file contains several &lt;/template&gt; tag in HTML body without start one</div>
+ </template></template>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/end-template-tag-in-head.html b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/end-template-tag-in-head.html
new file mode 100644
index 000000000..02d0c7be6
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/end-template-tag-in-head.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<html>
+<head>
+ </template>
+ <title>The file contains several &lt;/template&gt; tag in HTML head without start one</title>
+ </template></template>
+ <link rel="author" title="Aleksei Yu. Semenov" href="mailto:a.semenov@unipro.ru">
+ </template>
+</head>
+<body>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/frameset-end-tag.html b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/frameset-end-tag.html
new file mode 100644
index 000000000..b84d55595
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/frameset-end-tag.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>The file contains frameset with the template and frameset end tag in it</title>
+ <link rel="author" title="Sergey G. Grekhov" href="mailto:sgrekhov@unipro.ru">
+</head>
+<frameset>
+ <template></frameset></template>
+</frameset>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/head-template-contents-div-no-end-tag.html b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/head-template-contents-div-no-end-tag.html
new file mode 100644
index 000000000..e4e45bcea
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/head-template-contents-div-no-end-tag.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>The file contains template element with open div tag, but without end div tag, in the head</title>
+ <link rel="author" title="Aleksei Yu. Semenov" href="mailto:a.semenov@unipro.ru">
+ <template>
+ <div>Hello, template
+ </template>
+</head>
+<body>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/head-template-contents-table-no-end-tag.html b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/head-template-contents-table-no-end-tag.html
new file mode 100644
index 000000000..9db2b4af0
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/head-template-contents-table-no-end-tag.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>The file contains template element with open table, tr, td tags, but without end td, tr, table tags, in the head</title>
+ <link rel="author" title="Aleksei Yu. Semenov" href="mailto:a.semenov@unipro.ru">
+ <template>
+ <table>
+ <tr>
+ <td>Hello, cell one!
+ </template>
+</head>
+<body>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/html-start-tag.html b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/html-start-tag.html
new file mode 100644
index 000000000..0de652cf3
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/html-start-tag.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<html tabindex="5">
+<head>
+ <title>The file contains html root element with attributes and some in the body</title>
+ <link rel="author" title="Sergey G. Grekhovv" href="mailto:sgrekhov@unipro.ru">
+</head>
+<body>
+<template id="tmpl"><html class="htmlClass"></html></template><html id="htmlId" tabindex="5">
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-child-nodes-div.xhtml b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-child-nodes-div.xhtml
new file mode 100644
index 000000000..14db5004d
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-child-nodes-div.xhtml
@@ -0,0 +1,14 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+ <title>Template tag with children div tags inside</title>
+ <link rel="author" title="Aleksei Yu. Semenov" href="mailto:a.semenov@unipro.ru"/>
+</head>
+<body>
+ <p>Template tag with div tags inside</p>
+ <template>
+ <div>This is div inside template</div>
+ <div>This is another div inside template</div>
+ </template>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-child-nodes-nested.xhtml b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-child-nodes-nested.xhtml
new file mode 100644
index 000000000..406fa6c3d
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-child-nodes-nested.xhtml
@@ -0,0 +1,16 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+ <title>Template tag with children div tags inside another template tag</title>
+ <link rel="author" title="Aleksei Yu. Semenov" href="mailto:a.semenov@unipro.ru"/>
+</head>
+<body>
+ <p>Template tag with children div tags inside another template tag</p>
+ <template>
+ <template>
+ <div>This is div inside template</div>
+ <div>This is another div inside template</div>
+ </template>
+ </template>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-contents-attribute.html b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-contents-attribute.html
new file mode 100644
index 000000000..b9dd5f47a
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-contents-attribute.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>Empty template tag with attribute content</title>
+ <link rel="author" title="Aleksei Yu. Semenov" href="mailto:a.semenov@unipro.ru">
+<head>
+<body>
+ <template content='some text'></template>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-contents-body.html b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-contents-body.html
new file mode 100644
index 000000000..a1f246fd6
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-contents-body.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>BODY tag inside template</title>
+ <link rel="author" title="Aleksei Yu. Semenov" href="mailto:a.semenov@unipro.ru">
+<head>
+<body>
+ <template><body></body></template>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-contents-div-no-end-tag.html b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-contents-div-no-end-tag.html
new file mode 100644
index 000000000..304acf302
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-contents-div-no-end-tag.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>Div tag inside template tag</title>
+ <link rel="author" title="Aleksei Yu. Semenov" href="mailto:a.semenov@unipro.ru">
+</head>
+<body>
+ <template>
+ <div>Hello, template
+ </template>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-contents-empty.html b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-contents-empty.html
new file mode 100644
index 000000000..f1a539cc0
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-contents-empty.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>Empty template tag</title>
+ <link rel="author" title="Aleksei Yu. Semenov" href="mailto:a.semenov@unipro.ru">
+<head>
+<body>
+ <template>
+ </template>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-contents-frameset.html b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-contents-frameset.html
new file mode 100644
index 000000000..4331367df
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-contents-frameset.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>FRAMESET tag inside template</title>
+ <link rel="author" title="Aleksei Yu. Semenov" href="mailto:a.semenov@unipro.ru">
+<head>
+<body>
+ <template><frameset></frameset></template>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-contents-head.html b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-contents-head.html
new file mode 100644
index 000000000..1e3a337e8
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-contents-head.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>HEAD tag inside template</title>
+ <link rel="author" title="Aleksei Yu. Semenov" href="mailto:a.semenov@unipro.ru">
+<head>
+<body>
+ <template><head></head></template>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-contents-html.html b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-contents-html.html
new file mode 100644
index 000000000..5dd3a28e6
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-contents-html.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>HTML tag inside template</title>
+ <link rel="author" title="Aleksei Yu. Semenov" href="mailto:a.semenov@unipro.ru">
+<head>
+<body>
+ <template><html></html></template>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-contents-nested.html b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-contents-nested.html
new file mode 100644
index 000000000..dc2dc6f15
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-contents-nested.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+ <title>Contains second template tag inside template tag</title>
+ <link rel="author" title="Aleksei Yu. Semenov" href="mailto:a.semenov@unipro.ru">
+<body>
+ <template>
+ <template>
+ <div>Inside nested template</div>
+ </template>
+ </template>
+</body>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-contents-table-no-end-tag.html b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-contents-table-no-end-tag.html
new file mode 100644
index 000000000..4639b4dc8
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-contents-table-no-end-tag.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>The file contains template element with open table, tr, td tags, without end td, tr, table tags</title>
+ <link rel="author" title="Aleksei Yu. Semenov" href="mailto:a.semenov@unipro.ru">
+</head>
+<body>
+ <template>
+ <table>
+ <tr>
+ <td>Hello, cell one!
+ </template>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-contents-text.html b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-contents-text.html
new file mode 100644
index 000000000..a401848ef
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-contents-text.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>Some text inside template tag</title>
+ <link rel="author" title="Aleksei Yu. Semenov" href="mailto:a.semenov@unipro.ru">
+</head>
+<body>
+ <template>Some text</template>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-contents.html b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-contents.html
new file mode 100644
index 000000000..07256c06a
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-contents.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>Div tag inside template tag</title>
+ <link rel="author" title="Aleksei Yu. Semenov" href="mailto:a.semenov@unipro.ru">
+</head>
+<body>
+ <template>
+ <div>Hello, template</div>
+ </template>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-descendant-body.html b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-descendant-body.html
new file mode 100644
index 000000000..d64848c8d
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-descendant-body.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>Div tag inside template tag</title>
+ <link rel="author" title="Sergey G. Grekhov" href="mailto:sgrekhov@unipro.ru">
+</head>
+<body>
+ <template>
+ <div>Hello, template</div>
+ </template>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-descendant-frameset.html b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-descendant-frameset.html
new file mode 100644
index 000000000..480117845
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-descendant-frameset.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>Template tag inside frameset</title>
+ <link rel="author" title="Aleksei Yu. Semenov" href="mailto:a.semenov@unipro.ru">
+</head>
+<frameset>
+ <template>
+ <div>Hello, template</div>
+ </template>
+</frameset>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-descendant-head.html b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-descendant-head.html
new file mode 100644
index 000000000..6bab00ea9
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/template-descendant-head.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>Template tag inside head</title>
+ <link rel="author" title="Aleksei Yu. Semenov" href="mailto:a.semenov@unipro.ru">
+ <template>
+ <div>Hello, template</div>
+ </template>
+</head>
+<body>
+ Nothing interesting here
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/two-templates.html b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/two-templates.html
new file mode 100644
index 000000000..f6e9ab58e
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/resources/two-templates.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>The file contains two template elements</title>
+ <link rel="author" title="Aleksei Yu. Semenov" href="mailto:a.semenov@unipro.ru">
+</head>
+<body>
+ <template id="template1">
+ <div>Hello, template</div>
+ </template>
+
+ <template id="template2">
+ <div>Hello, from second template</div>
+ </template>
+
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/serializing-html-templates/outerhtml.html b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/serializing-html-templates/outerhtml.html
new file mode 100644
index 000000000..1539afbe1
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/serializing-html-templates/outerhtml.html
@@ -0,0 +1,70 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>HTML Templates: serialize template contents instead of template element</title>
+<meta name="author" title="Aleksei Yu. Semenov" href="a.semenov@unipro.ru">
+<meta name="assert" content="template contents should be serialized instead of template element if serializing template element">
+<link rel="help" href="http://www.w3.org/TR/2013/WD-html-templates-20130214/#serializing-html-templates">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src='/html/resources/common.js'></script>
+</head>
+<body>
+<div id="log"></div>
+<script type="text/javascript">
+
+test(function () {
+ var doc = newHTMLDocument();
+ var template = doc.createElement('template');
+
+ var div = doc.createElement('div');
+ div.setAttribute('id', 'div1');
+ div.innerHTML = 'some text';
+ template.content.appendChild(div);
+
+ assert_equals(template.outerHTML, '<template><div id="div1">some text</div></template>',
+ 'template element is serialized incorrectly');
+
+}, 'Template contents should be serialized instead of template element if serializing template element');
+
+
+
+test(function () {
+ var doc = newHTMLDocument();
+ var template = doc.createElement('template');
+ var nestedTemplate = doc.createElement('template');
+
+ template.content.appendChild(nestedTemplate);
+
+ var div = doc.createElement('div');
+ div.setAttribute('id', 'div1');
+ div.innerHTML = 'some text';
+ nestedTemplate.content.appendChild(div);
+
+ assert_equals(template.outerHTML, '<template><template><div id="div1">some text</div></template></template>',
+ 'template element is serialized incorrectly');
+
+
+}, 'Template contents should be serialized instead of template element if serializing template element. '
+ + 'Test nested template');
+
+
+test(function () {
+ var doc = newHTMLDocument();
+ var template = doc.createElement('template');
+
+ var div = doc.createElement('div');
+ div.setAttribute('id', 'div1');
+ div.innerHTML = 'some text';
+ template.content.appendChild(div);
+ doc.body.appendChild(template);
+
+ assert_equals(doc.documentElement.outerHTML, '<html><head><title>Test Document</title></head><body><template><div id="div1">some text</div></template></body></html>',
+ 'template element is serialized incorrectly');
+
+}, 'Template contents should be serialized instead of template element if serializing template element. '
+ + 'Test serializing whole document');
+
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/template-element/content-attribute.html b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/template-element/content-attribute.html
new file mode 100644
index 000000000..b4c11b841
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/template-element/content-attribute.html
@@ -0,0 +1,114 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>HTML Templates: Content attribute of template element is read-only</title>
+<meta name="author" title="Sergey G. Grekhov" href="mailto:sgrekhov@unipro.ru">
+<meta name="author" title="Aleksei Yu. Semenov" href="mailto:a.semenov@unipro.ru">
+<meta name="assert" content="Content attribute of template element is read-only">
+<link rel="help" href="http://www.w3.org/TR/2013/WD-html-templates-20130214/#template-element">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src='/html/resources/common.js'></script>
+</head>
+<body>
+<div id="log"></div>
+<script type="text/javascript">
+
+test(function() {
+ var doc = newHTMLDocument();
+ var template = doc.createElement('template');
+
+ assert_readonly(template, 'content',
+ 'Content attribute of template element should be read-only');
+
+}, 'Content attribute of template element is read-only. ' +
+ 'Test empty template');
+
+
+test(function() {
+ var doc = newHTMLDocument();
+ var template = doc.createElement('template');
+ var el1 = doc.createElement('div');
+ var el2 = doc.createElement('span');
+ el1.appendChild(el2);
+
+ template.content.appendChild(el1);
+
+ assert_readonly(template, 'content',
+ 'Content attribute of template element should be read-only');
+
+}, 'Content attribute of template element is read-only. ' +
+ 'Test not empty template populated by appendchild()');
+
+
+test(function() {
+ var doc = newHTMLDocument();
+ doc.body.innerHTML = '<template>Text<div>DIV</div></template>';
+
+ var template = doc.querySelector('template');
+
+ assert_readonly(template, 'content',
+ 'Content attribute of template element should be read-only');
+
+}, 'Content attribute of template element is read-only. ' +
+ 'Test not empty template populated by innerHTML');
+
+
+test(function() {
+ var doc = newHTMLDocument();
+ doc.body.innerHTML = '<template id="template1" content="Some text as a content"></template>';
+
+ var template = doc.querySelector('#template1');
+
+ assert_readonly(template, 'content',
+ 'Content attribute of template element should be read-only');
+
+}, 'Content attribute of template element is read-only. ' +
+ 'Test that custom content attribute named \'content\' doesn\'t ' +
+ 'make content IDL attribute writable');
+
+
+test(function() {
+ var doc = newHTMLDocument();
+ doc.body.innerHTML = '<template id="template1" content="<div id=div1>Div content</div>"></template>';
+
+ var template = doc.querySelector('#template1');
+
+ assert_readonly(template, 'content',
+ 'Content attribute of template element should be read-only');
+
+ assert_equals(template.content.childNodes.length, 0,
+ 'Content attribute of template element should be read-only');
+
+}, 'Content attribute of template element is read-only. ' +
+ 'Test that custom content attribute named \'content\' doesn\'t ' +
+ 'affect content IDL attribute');
+
+
+testInIFrame('../resources/template-contents-attribute.html', function(context) {
+ var doc = context.iframes[0].contentDocument;
+
+ var template = doc.body.querySelector('template');
+
+ assert_readonly(template, 'content',
+ 'Content attribute of template element should be read-only');
+
+}, 'Content attribute of template element is read-only. '
+ + 'Text value of content attribute of template tag should be ignored, '
+ + 'when loading document from a file');
+
+
+testInIFrame('../resources/template-contents.html', function(context) {
+ var doc = context.iframes[0].contentDocument;
+
+ var template = doc.body.querySelector('template');
+
+ assert_readonly(template, 'content',
+ 'Content attribute of template element should be read-only');
+
+}, 'Content attribute of template element is read-only. '
+ + 'Test content attribute of a document loaded from a file');
+
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/template-element/node-document-changes.html b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/template-element/node-document-changes.html
new file mode 100644
index 000000000..8027fbb91
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/template-element/node-document-changes.html
@@ -0,0 +1,199 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>HTML Templates: When node's document changes its owner document should be changed</title>
+<meta name="author" title="Sergey G. Grekhov" href="mailto:sgrekhov@unipro.ru">
+<meta name="author" title="Aleksei Yu. Semenov" href="mailto:a.semenov@unipro.ru">
+<meta name="assert" content="When a template element's node document changes, the template element's content DocumentFragment must be adopted into the new node document's template contents owner document">
+<link rel="help" href="http://www.w3.org/TR/2013/WD-html-templates-20130214/#template-element">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src='/html/resources/common.js'></script>
+</head>
+<body>
+<div id="log"></div>
+<script type="text/javascript">
+
+
+test(function() {
+ var doc1 = newHTMLDocument();
+ var template = doc1.createElement('template');
+
+ assert_equals(template.ownerDocument, doc1, 'Wrong template node owner document');
+ assert_not_equals(template.content.ownerDocument, doc1,
+ 'Wrong template content owner document');
+
+ var doc2 = newHTMLDocument();
+ var template2 = doc2.createElement('template');
+ doc2.body.appendChild(template);
+
+ assert_equals(template.ownerDocument, template2.ownerDocument,
+ 'Template node owner document should be changed');
+ assert_equals(template.content.ownerDocument, template2.content.ownerDocument,
+ 'Template content owner document should be changed');
+
+}, 'Changing of template element\'s node document. ' +
+ 'Test that ownerDocument of an empty template and its content changes');
+
+
+test(function() {
+ var doc1 = newHTMLDocument();
+ doc1.body.innerHTML = '<template id="tmpl"><div>Div content</div> And some more text</template>';
+
+ var template = doc1.querySelector('#tmpl');
+
+ assert_equals(template.ownerDocument, doc1,
+ 'Wrong template node owner document');
+ assert_not_equals(template.content.ownerDocument, doc1,
+ 'Wrong template content owner document');
+
+ var doc2 = newHTMLDocument();
+ var template2 = doc2.createElement('template');
+ doc2.body.appendChild(template);
+
+ assert_equals(template.ownerDocument, template2.ownerDocument,
+ 'Template node owner document should be changed');
+ assert_equals(template.content.ownerDocument, template2.content.ownerDocument,
+ 'Template content owner document should be changed');
+
+ assert_equals(template.content.querySelector('div').ownerDocument,
+ template2.content.ownerDocument,
+ 'Template content descendants owner document should be changed');
+
+}, 'Changing of template element\'s node document. ' +
+ 'Test that ownerDocument of a not empty template and its content changes');
+
+
+test(function() {
+ var doc1 = newHTMLDocument();
+ doc1.body.innerHTML = ''
+ + '<template id="tmpl"><div>Div content</div> And some more text'
+ + '<template id="tmpl2"><div>Template content</div></template>'
+ + '</template>';
+
+ var template = doc1.querySelector('#tmpl');
+
+ assert_equals(template.ownerDocument, doc1, 'Wrong template node owner document');
+ assert_not_equals(template.content.ownerDocument, doc1,
+ 'Wrong template content owner document');
+
+ var nestedTemplate = template.content.querySelector('#tmpl2');
+
+ assert_equals(nestedTemplate.ownerDocument, template.content.ownerDocument,
+ 'Wrong nested template node owner document');
+ assert_equals(nestedTemplate.content.ownerDocument, template.content.ownerDocument,
+ 'Wrong nested template content owner document');
+
+ var doc2 = newHTMLDocument();
+ var template2 = doc2.createElement('template');
+ doc2.body.appendChild(template);
+
+ assert_equals(template.ownerDocument, template2.ownerDocument,
+ 'Template node owner document should be changed');
+ assert_equals(template.content.ownerDocument, template2.content.ownerDocument,
+ 'Template content owner document should be changed');
+ assert_equals(template.content.querySelector('div').ownerDocument,
+ template2.content.ownerDocument,
+ 'Template content descendants owner document should be changed');
+
+ assert_equals(nestedTemplate.ownerDocument,
+ template2.content.ownerDocument,
+ 'Nested template node owner document should be changed');
+ assert_equals(nestedTemplate.content.ownerDocument,
+ template2.content.ownerDocument,
+ 'Nested template content owner document should be changed');
+ assert_equals(nestedTemplate.content.querySelector('div').ownerDocument,
+ template2.content.ownerDocument,
+ 'Owner document of the nested template content descendants should be changed');
+
+}, 'Changing of template element\'s node document. ' +
+ 'Test that ownerDocument of nested template and its content changes');
+
+
+testInIFrame('../resources/template-contents.html', function(context) {
+ var doc1 = context.iframes[0].contentDocument;
+
+ var template = doc1.body.querySelector('template');
+
+ var doc2 = newHTMLDocument();
+ var template2 = doc2.createElement('template');
+ doc2.body.appendChild(template);
+
+ assert_equals(template.ownerDocument, template2.ownerDocument,
+ 'Template node owner document should be changed');
+ assert_equals(template.content.ownerDocument,
+ template2.content.ownerDocument,
+ 'Template content owner document should be changed');
+ assert_equals(template.content.querySelector('div').ownerDocument,
+ template2.content.ownerDocument,
+ 'Template content descendants owner document should be changed');
+
+}, 'Changing of template element\'s node document. ' +
+ 'Test document loaded from a file');
+
+
+testInIFrame('../resources/template-contents.html', function(context) {
+ var doc1 = context.iframes[0].contentDocument;
+
+ var doc2 = newHTMLDocument();
+ var template = doc2.createElement('template');
+ var div = doc2.createElement('div');
+ template.content.appendChild(div);
+
+ doc1.body.appendChild(template);
+
+ assert_not_equals(template.ownerDocument, doc2,
+ 'Template node owner document should be changed');
+ assert_not_equals(template.content.ownerDocument, doc2,
+ 'Template content owner document should be changed');
+ assert_not_equals(div.ownerDocument, doc2,
+ 'Template content descendants owner document should be changed');
+
+ assert_equals(template.ownerDocument, doc1,
+ 'Template node owner document should be changed');
+ // doc1 has browsing context so it cannot be template.content.ownerDocument
+ assert_not_equals(template.content.ownerDocument, doc1,
+ 'Template content owner document should be a new document');
+ assert_equals(div.ownerDocument, template.content.ownerDocument,
+ 'Template content descendants owner document should be ' +
+ 'template content document owner');
+
+}, 'Changing of template element\'s node document. ' +
+ 'Adobt template element into a document that has a browsing context');
+
+
+testInIFrame('../resources/template-contents.html', function(context) {
+ var doc1 = context.iframes[0].contentDocument;
+
+ var template = doc1.querySelector('template');
+ var div = template.content.querySelector('div');
+ var templateContentOwner = template.content.ownerDocument;
+
+ var doc2 = document;
+
+ doc2.body.appendChild(template);
+
+
+ assert_not_equals(template.ownerDocument, doc1,
+ 'Template node owner document should be changed');
+ assert_not_equals(template.content.ownerDocument, templateContentOwner,
+ 'Template content owner document should be changed');
+ assert_not_equals(div.ownerDocument, templateContentOwner,
+ 'Template content descendants owner document should be changed');
+
+ assert_equals(template.ownerDocument, doc2,
+ 'Template node owner document should be changed');
+ // doc2 has browsing context, so it cannot be template.content.ownerDocument
+ assert_not_equals(template.content.ownerDocument, doc2,
+ 'Template content owner document should be a new document');
+ assert_equals(div.ownerDocument, template.content.ownerDocument,
+ 'Template content descendants owner document should be ' +
+ 'template content document owner');
+
+}, 'Changing of template element\'s node document. ' +
+ 'Test the case when both old and new owner documents of template element ' +
+ 'have browsing context');
+
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/template-element/template-as-a-descendant.html b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/template-element/template-as-a-descendant.html
new file mode 100644
index 000000000..6a6482daa
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/template-element/template-as-a-descendant.html
@@ -0,0 +1,135 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>HTML Templates: Template element as a descendant of the body element.</title>
+<meta name="author" title="Sergey G. Grekhov" href="mailto:sgrekhov@unipro.ru">
+<meta name="author" title="Aleksei Yu. Semenov" href="mailto:a.semenov@unipro.ru">
+<meta name="assert" content="Template element can be a descendant of the body element">
+<link rel="help" href="http://www.w3.org/TR/2013/WD-html-templates-20130214/#template-element">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src='/html/resources/common.js'></script>
+</head>
+<body>
+<div id="log"></div>
+<script type="text/javascript">
+
+function templateIsAChild(element) {
+ element.innerHTML = '<template>some text</template>';
+
+ assert_not_equals(element.querySelector('template'), null,
+ 'Template element should be a descendant of the ' + element.tagName + ' element');
+}
+
+function templateIsDisallowedAsAChild(element) {
+ element.innerHTML = '<template>some text</template>';
+
+ assert_equals(element.querySelector('template'), null,
+ 'Template element should not be allowed as a descendant of the ' + element.tagName + ' element');
+}
+
+function templateIsAnIndirectChild(element) {
+ element.innerHTML = '<div><template>some text</template></div>';
+
+ assert_not_equals(element.querySelector('template'), null,
+ 'Template element should be a descendant of the ' + element.tagName + ' element');
+}
+
+function templateIsDisallowedAsAnIndirectChild(element) {
+ element.innerHTML = '<div><template>some text</template></div>';
+
+ assert_equals(element.querySelector('template'), null,
+ 'Template element should not be allowed as indirect descendant of the ' + element.tagName + ' element');
+}
+
+function templateIsAnAppendedChild(doc, element) {
+ var template = doc.createElement('template');
+
+ element.appendChild(template);
+
+ assert_not_equals(element.querySelector('template'), null,
+ 'Template element should be a descendant of the ' + element.tagName + ' element');
+}
+
+function templateIsAnAppendedIndirectChild(doc, element) {
+ var template = doc.createElement('template');
+ var div = doc.createElement('div');
+ div.appendChild(template);
+
+ element.appendChild(div);
+
+ assert_not_equals(element.querySelector('template'), null,
+ 'Template element should be a descendant of the ' + element.tagName + ' element');
+}
+
+var doc = newHTMLDocument();
+var frameset = doc.createElement('frameset');
+
+var parameters = [['Template element as a descendant of the BODY element. ' +
+ 'Template element is created by innerHTML',
+ doc.body],
+ ['Template element as a descendant of the HEAD element. ' +
+ 'Template element is created by innerHTML',
+ doc.head],
+ ];
+generate_tests(templateIsAChild, parameters,
+ 'Template element as a descendant of the HEAD and BODY elements');
+
+parameters = [['Template element as a descendant of the FRAMESET element. ' +
+ 'Template element is created by innerHTML',
+ frameset],
+ ];
+generate_tests(templateIsDisallowedAsAChild, parameters,
+ 'Template element should be disallowed as a descendant of the FRAMESET elements');
+
+
+parameters = [['Template element as an indirect descendant of the BODY element. ' +
+ 'Template element is created by innerHTML',
+ doc.body],
+ ['Template element as an indirect descendant of the HEAD element. ' +
+ 'Template element is created by innerHTML',
+ doc.head],
+ ];
+generate_tests(templateIsAnIndirectChild, parameters,
+ 'Template element as an indirect descendant of the HEAD, BODY and FRAMESET elements');
+
+parameters = [['Template element as a descendant of the FRAMESET element. ' +
+ 'Template element is created by innerHTML',
+ frameset],
+ ];
+generate_tests(templateIsDisallowedAsAnIndirectChild, parameters,
+ 'Template element should be disallowed as an indirect descendant of the FRAMESET elements');
+
+
+
+parameters = [['Template element as a descendant of the BODY element. ' +
+ 'Template element is appended by appendChild()',
+ doc, doc.body],
+ ['Template element as a descendant of the HEAD element. ' +
+ 'Template element is appended by appendChild()',
+ doc, doc.head],
+ ['Template element as a descendant of the FRAMESET element. ' +
+ 'Template element is appended by appendChild()',
+ doc, frameset]
+ ];
+generate_tests(templateIsAnAppendedChild, parameters,
+ 'Template element as a descendant of the HEAD, BODY and FRAMESET elements');
+
+
+
+parameters = [['Template element as an indirect descendant of the BODY element. ' +
+ 'Template element is appended by appendChild()',
+ doc, doc.body],
+ ['Template element as an indirect descendant of the HEAD element. ' +
+ 'Template element is appended by appendChild()',
+ doc, doc.head],
+ ['Template element as an indirect descendant of the FRAMESET element. ' +
+ 'Template element is appended by appendChild()',
+ doc, frameset]
+ ];
+generate_tests(templateIsAnAppendedIndirectChild, parameters,
+ 'Template element as a descendant of the HEAD, BODY and FRAMESET elements');
+
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/template-element/template-content-node-document.html b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/template-element/template-content-node-document.html
new file mode 100644
index 000000000..da76c6b04
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/template-element/template-content-node-document.html
@@ -0,0 +1,59 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>HTML Templates: Node document of the template content attribute must be template contents owner</title>
+<meta name="author" title="Sergey G. Grekhov" href="mailto:sgrekhov@unipro.ru">
+<meta name="author" title="Aleksei Yu. Semenov" href="mailto:a.semenov@unipro.ru">
+<meta name="assert" content="Node document of the template content attribute must be template contents owner">
+<link rel="help" href="http://www.w3.org/TR/2013/WD-html-templates-20130214/#template-element">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src='/html/resources/common.js'></script>
+</head>
+<body>
+<div id="log"></div>
+<script type="text/javascript">
+
+test(function() {
+ var doc = newHTMLDocument();
+ var template = doc.createElement('template');
+ var nestedTemplate = doc.createElement('template');
+ template.appendChild(nestedTemplate);
+
+ assert_equals(nestedTemplate.content.ownerDocument, template.content.ownerDocument,
+ 'Wrong node document of the template content attribute');
+
+}, 'Node document of the template content attribute must be template contents owner. ' +
+ 'Nested template element created by createElement');
+
+
+test(function() {
+ var doc = newHTMLDocument();
+ doc.body.innerHTML = '<template><template></template></template>';
+ var template = doc.querySelector('template');
+ var nestedTemplate = template.content.querySelector('template');
+
+ assert_equals(nestedTemplate.content.ownerDocument, template.content.ownerDocument,
+ 'Wrong node document of the template content attribute');
+
+}, 'Node document of the template content attribute must be template contents owner. ' +
+ 'Nested template element created by innerHTML');
+
+testInIFrame('../resources/two-templates.html', function(context) {
+ var doc = context.iframes[0].contentDocument;
+
+ var template1 = doc.querySelector('#template1');
+ var template2 = doc.querySelector('#template2');
+
+ // when there is a browsing context, template contents owner is only accessible via template.content.ownerDocument
+ // because template contents owner is bounded to document
+ // verify that multiple templates share the same instance of template contents owner
+
+ assert_equals(template1.content.ownerDocument, template2.content.ownerDocument,
+ 'Wrong node document of the template content attribute');
+}, 'Node document of the template content attribute must be template contents owner. ' +
+ 'Load HTML file with multiple template elements');
+
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/template-element/template-content.html b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/template-element/template-content.html
new file mode 100644
index 000000000..8ed55d0d2
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/template-element/template-content.html
@@ -0,0 +1,77 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>HTML Templates: HTML elements in template content</title>
+<meta name="author" title="Sergey G. Grekhov" href="mailto:sgrekhov@unipro.ru">
+<meta name="author" title="Aleksei Yu. Semenov" href="a.semenov@unipro.ru">
+<meta name="assert" content="Template may contain any element, except the html element, the head element, the body element, or the frameset element">
+<link rel="help" href="http://www.w3.org/TR/2013/WD-html-templates-20130214/#template-element">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src='/html/resources/common.js'></script>
+</head>
+<body>
+<div id="log"></div>
+<script type="text/javascript">
+
+var parameters = [];
+
+HTML5_ELEMENTS.forEach(function(value) {
+ if (value !== 'body' && value !== 'html' && value !== 'head' && value !== 'frameset') {
+
+ var doc = newHTMLDocument();
+ var template = doc.createElement('template');
+ var element = doc.createElement(value);
+ template.content.appendChild(element);
+ var valueToTest = template.content.querySelector(value);
+
+ doc.body.appendChild(template);
+
+ parameters.push([
+ 'Template may contain ' + value + ' element',
+ valueToTest,
+ null
+ ]);
+ }
+});
+
+generate_tests(assert_not_equals, parameters,
+ 'Template may contain any element, except the html element, '
+ + 'the head element, the body element, or the frameset element');
+
+
+
+
+var parameters = [];
+
+HTML5_ELEMENTS.forEach(function(value) {
+ if (value !== 'body' && value !== 'html' && value !== 'head' && value !== 'frameset') {
+
+ var doc = newHTMLDocument();
+
+ if (isVoidElement(value)) {
+ doc.body.innerHTML = '<template><' + value + '/></template>';
+ } else {
+ doc.body.innerHTML = '<template><' + value + '></' + value + '></template>';
+ }
+
+ var template = doc.querySelector('template');
+ var element = template.content.querySelector(value);
+
+ parameters.push([
+ 'Template may contain ' + value + ' element. '
+ +'The template element and contents are added via body.innerHTML',
+ element,
+ null
+ ]);
+ }
+});
+
+generate_tests(assert_not_equals, parameters,
+ 'Template may contain any element, except the html element, '
+ + 'the head element, the body element, or the frameset element. '
+ +'The template element and contents are added via body.innerHTML');
+
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/template-element/template-descendant-body.html b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/template-element/template-descendant-body.html
new file mode 100644
index 000000000..70028c5ec
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/template-element/template-descendant-body.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>HTML Templates: Template element as a descendant of the body element.</title>
+<meta name="author" title="Aleksei Yu. Semenov" href="mailto:a.semenov@unipro.ru">
+<meta name="assert" content="Template element can be a descendant of the body element">
+<link rel="help" href="http://www.w3.org/TR/2013/WD-html-templates-20130214/#template-element">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src='/html/resources/common.js'></script>
+</head>
+<body>
+<div id="log"></div>
+<script type="text/javascript">
+
+testInIFrame('../resources/template-contents.html', function(ctx) {
+ var doc = ctx.iframes[0].contentDocument;
+
+ assert_not_equals(doc.body.querySelector('template'), null,
+ 'Template element should be a descendant of the body element');
+
+}, 'Template element as a descendant of the body element. Test loading from a file');
+
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/template-element/template-descendant-frameset.html b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/template-element/template-descendant-frameset.html
new file mode 100644
index 000000000..ce20a7413
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/template-element/template-descendant-frameset.html
@@ -0,0 +1,62 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>HTML Templates: Template element as a descendant of the frameset element.</title>
+<meta name="author" title="Aleksei Yu. Semenov" href="mailto:a.semenov@unipro.ru">
+<meta name="assert" content="Template element can not be a descendant of the frameset element">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#parsing-main-inframeset">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src='/html/resources/common.js'></script>
+</head>
+<body>
+<div id="log"></div>
+<script type="text/javascript">
+
+testInIFrame('../resources/template-descendant-frameset.html', function(context) {
+ var doc = context.iframes[0].contentDocument;
+
+ var frameset = doc.querySelector('frameset');
+
+ assert_equals(frameset.querySelector('template'), null,
+ 'Template element should not be a descendant of the frameset element');
+
+}, 'Template element as a descendant of the frameset element. Test loading from a file');
+
+
+testInIFrame('../resources/template-descendant-frameset.html', function(context) {
+ var doc = context.iframes[0].contentDocument;
+
+ var frameset = doc.querySelector('frameset');
+
+ frameset.innerHTML = '';
+ assert_equals(doc.querySelector('template'), null,
+ 'Initial conditions are not satisfied');
+
+ frameset.innerHTML = '<template>some text</template>';
+
+ assert_equals(frameset.querySelector('template'), null,
+ 'Template element should not be a descendant of the frameset element');
+
+}, 'Template element as a descendant of the frameset element. '
+ + 'Test template element is assigned to frameset\'s innerHTML)');
+
+
+testInIFrame('../resources/template-descendant-frameset.html', function(context) {
+ var doc = context.iframes[0].contentDocument;
+
+ var frameset = doc.querySelector('frameset');
+
+ var template = doc.createElement('template');
+ frameset.appendChild(template);
+
+ assert_equals(frameset.querySelectorAll('template').length, 1,
+ 'Template element should be a descendant of the frameset element');
+
+}, 'Template element as a descendant of the frameset element. '
+ + 'Test template element appended to frameset by appendChild()');
+
+
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/template-element/template-descendant-head.html b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/template-element/template-descendant-head.html
new file mode 100644
index 000000000..611ec50bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/scripting-1/the-template-element/template-element/template-descendant-head.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>HTML Templates: Template element as a descendant of the head element.</title>
+<meta name="author" title="Aleksei Yu. Semenov" href="mailto:a.semenov@unipro.ru">
+<meta name="assert" content="Template element can be a descendant of the head element">
+<link rel="help" href="http://www.w3.org/TR/2013/WD-html-templates-20130214/#template-element">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src='/html/resources/common.js'></script>
+</head>
+<body>
+<div id="log"></div>
+<script type="text/javascript">
+
+testInIFrame('../resources/template-descendant-head.html', function(context) {
+ var doc = context.iframes[0].contentDocument;
+
+ assert_not_equals(doc.head.querySelector('template'), null,
+ 'Template element should be a descendant of the head element');
+
+}, 'Template element as a descendant of the head element. Test loading from a file');
+
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/sections/.gitkeep b/testing/web-platform/tests/html/semantics/sections/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/sections/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/sections/headings-and-sections/.gitkeep b/testing/web-platform/tests/html/semantics/sections/headings-and-sections/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/sections/headings-and-sections/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/sections/headings-and-sections/contains.json b/testing/web-platform/tests/html/semantics/sections/headings-and-sections/contains.json
new file mode 100644
index 000000000..a9fecf65b
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/sections/headings-and-sections/contains.json
@@ -0,0 +1,6 @@
+[
+ {
+ "id": "outlines",
+ "original_id": "outlines"
+ }
+] \ No newline at end of file
diff --git a/testing/web-platform/tests/html/semantics/sections/the-address-element/.gitkeep b/testing/web-platform/tests/html/semantics/sections/the-address-element/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/sections/the-address-element/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/sections/the-article-element/.gitkeep b/testing/web-platform/tests/html/semantics/sections/the-article-element/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/sections/the-article-element/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/sections/the-aside-element/.gitkeep b/testing/web-platform/tests/html/semantics/sections/the-aside-element/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/sections/the-aside-element/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/sections/the-body-element/.gitkeep b/testing/web-platform/tests/html/semantics/sections/the-body-element/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/sections/the-body-element/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/sections/the-footer-element/.gitkeep b/testing/web-platform/tests/html/semantics/sections/the-footer-element/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/sections/the-footer-element/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/sections/the-h1-h2-h3-h4-h5-and-h6-elements/.gitkeep b/testing/web-platform/tests/html/semantics/sections/the-h1-h2-h3-h4-h5-and-h6-elements/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/sections/the-h1-h2-h3-h4-h5-and-h6-elements/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/sections/the-h1-h2-h3-h4-h5-and-h6-elements/original-id.json b/testing/web-platform/tests/html/semantics/sections/the-h1-h2-h3-h4-h5-and-h6-elements/original-id.json
new file mode 100644
index 000000000..748a548ca
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/sections/the-h1-h2-h3-h4-h5-and-h6-elements/original-id.json
@@ -0,0 +1 @@
+{"original_id":"the-h1,-h2,-h3,-h4,-h5,-and-h6-elements"} \ No newline at end of file
diff --git a/testing/web-platform/tests/html/semantics/sections/the-header-element/.gitkeep b/testing/web-platform/tests/html/semantics/sections/the-header-element/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/sections/the-header-element/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/sections/the-hgroup-element/.gitkeep b/testing/web-platform/tests/html/semantics/sections/the-hgroup-element/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/sections/the-hgroup-element/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/sections/the-nav-element/.gitkeep b/testing/web-platform/tests/html/semantics/sections/the-nav-element/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/sections/the-nav-element/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/sections/the-section-element/.gitkeep b/testing/web-platform/tests/html/semantics/sections/the-section-element/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/sections/the-section-element/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/sections/usage-summary-0/.gitkeep b/testing/web-platform/tests/html/semantics/sections/usage-summary-0/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/sections/usage-summary-0/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/selectors/.gitkeep b/testing/web-platform/tests/html/semantics/selectors/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/selectors/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/selectors/case-sensitivity/.gitkeep b/testing/web-platform/tests/html/semantics/selectors/case-sensitivity/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/selectors/case-sensitivity/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/checked-001-manual.html b/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/checked-001-manual.html
new file mode 100644
index 000000000..76a963a60
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/checked-001-manual.html
@@ -0,0 +1,18 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
+<html>
+ <head>
+ <title>CSS Selectors (:checked)</title>
+ <link rel="author" title="Ian Hickson" href="mailto:ian@hixie.ch"/>
+ <link rel="alternate" href="http://www.hixie.ch/tests/adhoc/css/selectors/checked/001.html"/>
+ <style type="text/css">
+ :checked, :checked + span { border: solid blue; color: blue; background: navy; }
+ </style>
+ </head>
+ <body>
+ <p>Anything that is checked below should be blue.</p>
+ <p><input checked type="checkbox"> <span>X</span></p>
+ <p><input checked type="radio" name="x"> <span>X</span> <input checked type="radio" name="x"> <span>X</span></p>
+ <p><select><option selected>X</option></select></p>
+ <p><select size="2"><option selected>X</option></select></p>
+ </body>
+</html> \ No newline at end of file
diff --git a/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/checked.html b/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/checked.html
new file mode 100644
index 000000000..bf5981293
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/checked.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Selector: pseudo-classes (:checked)</title>
+<link rel="author" title="Denis Ah-Kang" href="mailto:denis@w3.org" id=link1>
+<link rel=help href="https://html.spec.whatwg.org/multipage/#pseudo-classes" id=link2>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="utils.js"></script>
+<div id="log"></div>
+<select id=select1>
+ <optgroup label="options" id=optgroup1>
+ <option value="option1" id=option1 selected>option1
+ <option value="option2" id=option2>option2
+ <option value="option2" id=option3 checked>option3
+</select>
+<input type=checkbox id=checkbox1 checked>
+<input type=checkbox id=checkbox2>
+<input type=checkbox id=checkbox3 selected>
+<input type=radio id=radio1 checked>
+<input type=radio id=radio2>
+<form>
+ <p><input type=submit contextmenu=formmenu id="submitbutton"></p>
+ <menu type=popup id=formmenu>
+ <menuitem type=checkbox checked default id=menuitem1>
+ <menuitem type=checkbox default id=menuitem2>
+ <menuitem type=checkbox id=menuitem3>
+ <menuitem type=radio checked id=menuitem4>
+ <menuitem type=radio id=menuitem5>
+ </menu>
+</form>
+
+<script>
+ testSelectorIdsMatch(":checked", ["option1", "checkbox1", "radio1", "menuitem1", "menuitem4"], "':checked' matches checked <input>/<menuitem> in checkbox and radio button states, selected <option>s");
+
+ document.getElementById("checkbox1").removeAttribute("type"); // change type of input
+ document.getElementById("radio1").removeAttribute("type"); // change type of input
+ testSelectorIdsMatch(":checked", ["option1", "menuitem1", "menuitem4"], "':checked' should no longer match <input>s whose type checkbox/radio has been removed");
+
+ document.getElementById("option2").selected = "selected"; // select option2
+ document.getElementById("checkbox2").click(); // check chekbox2
+ document.getElementById("radio2").click(); // check radio2
+ testSelectorIdsMatch(":checked", ["option2", "checkbox2", "radio2", "menuitem1", "menuitem4"], "':checked' matches clicked checkbox and radio buttons");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/default.html b/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/default.html
new file mode 100644
index 000000000..3187801f6
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/default.html
@@ -0,0 +1,64 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Selector: pseudo-classes (:default)</title>
+<link rel="author" title="Denis Ah-Kang" href="mailto:denis@w3.org" id=link1>
+<link rel=help href="https://html.spec.whatwg.org/multipage/#pseudo-classes" id=link2>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="utils.js"></script>
+<div id="log"></div>
+<form>
+ <button id=button1 type=button>button1</button>
+ <button id=button2 type=submit>button2</button>
+</form>
+<form>
+ <button id=button3 type=reset>button3</button>
+ <button id=button4>button4</button>
+</form>
+<button id=button5 type=submit>button5</button>
+<form id=form1>
+ <input type=text id=input1>
+</form>
+<input type=text id=input2 form=form1>
+<form>
+ <input type=submit id=input3>
+ <input type=submit id=input4>
+</form>
+<form>
+ <input type=image id=input5>
+ <input type=image id=input6>
+</form>
+<form>
+ <input type=submit id=input7>
+</form>
+<input type=checkbox id=checkbox1 checked>
+<input type=checkbox id=checkbox2>
+<input type=checkbox id=checkbox3 default>
+<input type=radio name=radios id=radio1 checked>
+<input type=radio name=radios id=radio2>
+<input type=radio name=radios id=radio3 default>
+<select id=select1>
+ <optgroup label="options" id=optgroup1>
+ <option value="option1" id=option1>option1
+ <option value="option2" id=option2 selected>option2
+</select>
+<dialog id="dialog">
+ <input type=submit id=input8>
+</dialog>
+<form>
+ <button id=button6 type='invalid'>button6</button>
+ <button id=button7>button7</button>
+</form>
+<form>
+ <button id=button8>button8</button>
+ <button id=button9>button9</button>
+</form>
+
+
+<script>
+ testSelectorIdsMatch(":default", ["button2", "button4", "input3", "input5", "input7", "checkbox1", "radio1", "option2", "button6", "button8"], "':default' matches <button>s that are their form's default button, <input>s of type submit/image that are their form's default button, checked <input>s and selected <option>s");
+
+ document.getElementById("button1").type = "submit"; // change the form's default button
+ testSelectorIdsMatch(":default", ["button1", "button4", "input3", "input5", "input7", "checkbox1", "radio1", "option2", "button6", "button8"], "':default' matches dynamically changed form's default buttons");
+
+</script>
diff --git a/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/dir.html b/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/dir.html
new file mode 100644
index 000000000..8edd9b8ab
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/dir.html
@@ -0,0 +1,46 @@
+<!DOCTYPE html>
+<html id=html>
+ <head id=head>
+ <meta charset=utf-8 id=meta>
+ <title id=title>Selector: pseudo-classes (:dir(ltr), :dir(rtl))</title>
+ <link rel="author" title="Denis Ah-Kang" href="mailto:denis@w3.org" id=link1>
+ <link rel=help href="https://html.spec.whatwg.org/multipage/#pseudo-classes" id=link2>
+ <script src="/resources/testharness.js" id=script1></script>
+ <script src="/resources/testharnessreport.js" id=script2></script>
+ <script src="utils.js" id=script3></script>
+ <style id=style>
+ #span1 {direction: rtl;}
+ #span5, #span6 {display: none;}
+ </style>
+ </head>
+ <body id=body>
+ <div id="log"></div>
+ <bdo dir="rtl" id=bdo1>WERBEH</bdo>
+ <bdo dir="ltr" id=bdo2>HEBREW</bdo>
+ <bdi id=bdi1>HEBREW</bdi>
+ <bdi dir="rtl" id=bdi2>WERBEH</bdi>
+ <bdi dir="ltr" id=bdi3>HEBREW</bdi>
+ <bdi id=bdi4>إيان</bdi>
+ <span id=span1>WERBEH</span>
+ <span dir="rtl" id=span2>WERBEH</span>
+ <span dir="ltr" id=span3>HEBREW</span>
+ &#x202E;<span id=span4>WERBEH</span>&#x202C;
+ <span dir="rtl" id=span5>WERBEH</span>
+ <span dir="ltr" id=span6>HEBREW</span>
+ <bdo dir="auto" id=bdo3>HEBREW</bdo>
+ <bdo dir="auto" id=bdo4>إيان</bdo>
+ <bdo dir="ltr" id=bdo5>עברית</bdo>
+
+ <script id=script4>
+ testSelectorIdsMatch(":dir(rtl)", ["bdo1", "bdi2", "bdi4", "span2", "span5", "bdo4"], "':dir(rtl)' matches all elements whose directionality is 'rtl'.");
+
+ var ltrElements = ["html", "head", "meta", "title", "link1", "link2", "script1", "script2", "script3", "style", "body", "log", "bdo2", "bdi1", "bdi3", "span1", "span3", "span4", "span6", "bdo3", "bdo5", "script4"];
+
+ testSelectorIdsMatch(":dir(ltr)", ltrElements, "':dir(ltr)' matches all elements whose directionality is 'ltr'.");
+
+ var bdo = document.createElement("bdo");
+ bdo.setAttribute("dir", "ltr");
+ testSelectorIdsMatch(":dir(ltr)", ltrElements, "':dir(ltr)' doesn't match elements not in the document.");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/dir01.html b/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/dir01.html
new file mode 100644
index 000000000..61bbd574a
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/dir01.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<meta charset=iso-8859-8 id=meta>
+<title id=title>Selector: pseudo-classes (:dir(ltr), :dir(rtl)) in iso-8859-8 documents</title>
+<link rel="author" title="Denis Ah-Kang" href="mailto:denis@w3.org" id=link1>
+<link rel=help href="https://html.spec.whatwg.org/multipage/#pseudo-classes" id=link2>
+<script src="/resources/testharness.js" id=script1></script>
+<script src="/resources/testharnessreport.js" id=script2></script>
+<script src="utils.js" id=script3></script>
+<div id="log"></div>
+<div>This text is left to right<div id=div1 style="direction:rtl">this is right to left</div></div>
+<div>This text is left to right<span id=div2 style="direction:rtl">this is left to right</span></div>
+
+<script>
+ var ltr = new Array(),
+ all = document.querySelectorAll('*');
+ for(var i = all.length; i--; ltr.unshift(all[i]));
+ testSelectorElementsMatch(":dir(ltr)", ltr, "direction doesn't affect :dir()");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/disabled.html b/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/disabled.html
new file mode 100644
index 000000000..8808675eb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/disabled.html
@@ -0,0 +1,60 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Selector: pseudo-classes (:disabled)</title>
+<link rel="author" title="Denis Ah-Kang" href="mailto:denis@w3.org" id=link1>
+<link rel=help href="https://html.spec.whatwg.org/multipage/#pseudo-classes" id=link2>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="utils.js"></script>
+<style>
+ #input4 {display:none;}
+</style>
+<div id="log"></div>
+<button id=button1 type=submit>button1</button>
+<button id=button2 disabled>button2</button>
+<input id=input1>
+<input id=input2 disabled>
+<input id=input3 readonly>
+<input id=input4>
+<select id=select1>
+ <optgroup label="options" id=optgroup1>
+ <option value="option1" id=option1 selected>option1
+</select>
+<select disabled id=select2>
+ <optgroup label="options" disabled id=optgroup2>
+ <option value="option2" disabled id=option2>option2
+</select>
+<textarea id=textarea1>textarea1</textarea>
+<textarea disabled id=textarea2>textarea2</textarea>
+<fieldset id=fieldset1></fieldset>
+<fieldset disabled id=fieldset2>
+ <legend><input type=checkbox id=club></legend>
+ <p><label>Name on card: <input id=clubname required></label></p>
+ <p><label>Card number: <input id=clubnum required pattern="[-0-9]+"></label></p>
+</fieldset>
+<label disabled></label>
+<object disabled></object>
+<output disabled></output>
+<img disabled/>
+<meter disabled></meter>
+<progress disabled></progress>
+
+<script>
+ testSelectorIdsMatch(":disabled", ["button2", "input2", "select2", "optgroup2", "option2", "textarea2", "fieldset2", "clubname", "clubnum"], "':disabled' should match only disabled elements");
+
+ document.getElementById("button2").removeAttribute("disabled");
+ testSelectorIdsMatch(":disabled", ["input2", "select2", "optgroup2", "option2", "textarea2", "fieldset2", "clubname", "clubnum"], "':disabled' should not match elements whose disabled attribute has been removed");
+
+ document.getElementById("button1").setAttribute("disabled", "disabled");
+ testSelectorIdsMatch(":disabled", ["button1", "input2", "select2", "optgroup2", "option2", "textarea2", "fieldset2", "clubname", "clubnum"], "':disabled' should also match elements whose disabled attribute has been set");
+
+ document.getElementById("button1").setAttribute("disabled", "disabled");
+ testSelectorIdsMatch(":disabled", ["button1", "input2", "select2", "optgroup2", "option2", "textarea2", "fieldset2", "clubname", "clubnum"], "':disabled' should also match elements whose disabled attribute has been set twice");
+
+ document.getElementById("input2").setAttribute("type", "submit"); // change input type to submit
+ testSelectorIdsMatch(":disabled", ["button1", "input2", "select2", "optgroup2", "option2", "textarea2", "fieldset2", "clubname", "clubnum"], "':disabled' should also match disabled elements whose type has changed");
+
+ var input = document.createElement("input");
+ input.setAttribute("disabled", "disabled");
+ testSelectorIdsMatch(":disabled", ["button1", "input2", "select2", "optgroup2", "option2", "textarea2", "fieldset2", "clubname", "clubnum"], "':disabled' should not match elements not in the document");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/enabled.html b/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/enabled.html
new file mode 100644
index 000000000..98d81297e
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/enabled.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Selector: pseudo-classes (:enabled)</title>
+<link rel="author" title="Denis Ah-Kang" href="mailto:denis@w3.org" id=link1>
+<link rel=help href="https://html.spec.whatwg.org/multipage/#pseudo-classes" id=link2>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="utils.js"></script>
+<div id="log"></div>
+<a id=link3></a>
+<area id=link4></area>
+<link id=link5></link>
+<a href="http://www.w3.org" id=link6></a>
+<area href="http://www.w3.org" id=link7></area>
+<link href="http://www.w3.org" id=link8></link>
+<button id=button1>button1</button>
+<button id=button2 disabled>button2</button>
+<input id=input1>
+<input id=input2 disabled>
+<select id=select1>
+ <optgroup label="options" id=optgroup1>
+ <option value="option1" id=option1 selected>option1
+</select>
+<select disabled id=select2>
+ <optgroup label="options" disabled id=optgroup2>
+ <option value="option2" disabled id=option2>option2
+</select>
+<textarea id=textarea1>textarea1</textarea>
+<textarea disabled id=textarea2>textarea2</textarea>
+<form>
+ <p><input type=submit contextmenu=formmenu id=submitbutton></p>
+ <menu type=popup id=formmenu>
+ <menuitem command="submitbutton" default id=menuitem1>
+ <menuitem command="resetbutton" disabled id=menuitem2>
+ </menu>
+</form>
+<fieldset id=fieldset1></fieldset>
+<fieldset disabled id=fieldset2></fieldset>
+
+<script>
+ testSelectorIdsMatch(":enabled", ["button1", "input1", "select1", "optgroup1", "option1", "textarea1", "submitbutton", "menuitem1", "fieldset1"], "':enabled' elements that are not disabled");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/focus-autofocus.html b/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/focus-autofocus.html
new file mode 100644
index 000000000..80a75bb99
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/focus-autofocus.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Selector: pseudo-classes (:focus for autofocus)</title>
+<link rel="author" title="Kent Tamura" href="mailto:tkent@chromium.org">
+<link rel=help href="https://html.spec.whatwg.org/multipage/#pseudo-classes">
+<link rel=help href="https://html.spec.whatwg.org/multipage/forms.html#autofocusing-a-form-control:-the-autofocus-attribute">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<body>
+<script>
+// This test can't be merged to focus.html because element.focus() may affect
+// autofocus behavior.
+var autofocusTest = async_test(":focus selector should work with an autofocused element.");
+var input = document.createElement("input");
+input.autofocus = true;
+input.addEventListener("focus", function() {
+ autofocusTest.step(function() {
+ assert_array_equals(document.querySelectorAll(":focus"), [input])
+ autofocusTest.done();
+ });
+}, false);
+document.body.appendChild(input);
+</script>
+</body>
diff --git a/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/focus-iframe.html b/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/focus-iframe.html
new file mode 100644
index 000000000..a269f1c67
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/focus-iframe.html
@@ -0,0 +1,5 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Selector: pseudo-classes (:focus)</title>
+<link rel="author" title="Denis Ah-Kang" href="mailto:denis@w3.org">
+<input id="inputiframe" type=text value="foobar" />
diff --git a/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/focus.html b/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/focus.html
new file mode 100644
index 000000000..a319b24ef
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/focus.html
@@ -0,0 +1,51 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Selector: pseudo-classes (:focus)</title>
+<link rel="author" title="Denis Ah-Kang" href="mailto:denis@w3.org" id=link1>
+<link rel=help href="https://html.spec.whatwg.org/multipage/#pseudo-classes" id=link2>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="utils.js"></script>
+<body id=body tabindex=0>
+ <div id="log"></div>
+ <button id=button1 type=submit>button1</button>
+ <input id=input1>
+ <input id=input2 disabled>
+ <textarea id=textarea1>textarea1</textarea>
+ <input type=checkbox id=checkbox1 checked>
+ <input type=radio id=radio1 checked>
+ <div tabindex=0 id=div1>hello</div>
+ <div contenteditable id=div2>content</div>
+ <iframe src="focus-iframe.html" id=iframe></iframe>
+
+ <script>
+ setup({explicit_done: true});
+
+ onload = function() {
+ if (document.hasFocus() || frames[0].document.hasFocus()) {
+ run_test()
+ } else {
+ window.onfocus = run_test;
+ }
+ }
+
+ function run_test() {
+ document.getElementById("input1").focus(); // set the focus on input1
+ testSelectorIdsMatch(":focus", ["input1"], "input1 has the focus");
+
+ document.getElementById("div1").focus();
+ testSelectorIdsMatch(":focus", ["div1"], "tabindex attribute makes the element focusable");
+
+ document.getElementById("div2").focus();
+ testSelectorIdsMatch(":focus", ["div2"], "editable elements are focusable");
+
+ document.body.focus();
+ testSelectorIdsMatch(":focus", ["body"], "':focus' matches focussed body with tabindex");
+
+ document.getElementById("iframe").contentDocument.getElementById("inputiframe").focus();
+ testSelectorIdsMatch(":focus", [], "':focus' doesn't match focused elements in iframe");
+
+ done();
+ }
+ </script>
+</body>
diff --git a/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/indeterminate-radio.html b/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/indeterminate-radio.html
new file mode 100644
index 000000000..4a7b2d6ec
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/indeterminate-radio.html
@@ -0,0 +1,26 @@
+<!DOCTYPE HTML>
+<meta charset="utf-8">
+<title>:indeterminate and input type=radio</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<style type="text/css">
+#test {
+ color: green;
+}
+input:indeterminate + #test {
+ color: red;
+}
+</style>
+<input type="radio" name="radios">
+<div id="test"></div>
+<input type="radio" name="radios" checked>
+<script type="text/javascript">
+test(function() {
+ document.getElementsByTagName("input")[0].indeterminate = true;
+ var target = document.getElementById("test");
+ var val = getComputedStyle(target, null).getPropertyValue("color");
+ assert_equals(val, "rgb(0, 128, 0)",
+ "The indeterminate IDL attribute should not cause the " +
+ ":indeterminate pseudo-class to match on input type=radio");
+})
+</script>
diff --git a/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/indeterminate.html b/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/indeterminate.html
new file mode 100644
index 000000000..df0484667
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/indeterminate.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Selector: pseudo-classes (:indeterminate)</title>
+<link rel="author" title="Denis Ah-Kang" href="mailto:denis@w3.org" id=link1>
+<link rel=help href="https://html.spec.whatwg.org/multipage/#pseudo-classes" id=link2>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="utils.js"></script>
+<div id="log"></div>
+<input type=checkbox id=checkbox1>
+<input type=checkbox id=checkbox2>
+<input type=radio id=radio1 checked>
+<input type=radio name=radiogroup id=radio2>
+<input type=radio name=radiogroup id=radio3>
+<input type=radio name=group2 id=radio4>
+<input type=radio name=group2 id=radio5>
+<progress id="progress1"></progress>
+<progress id="progress2" value=10></progress>
+
+<script>
+ testSelectorIdsMatch(":indeterminate", ["radio2", "radio3", "radio4", "radio5", "progress1"], "':progress' matches <input>s radio buttons whose radio button group contains no checked input and <progress> elements without value attribute");
+
+ document.getElementById("radio2").setAttribute("checked", "checked");
+ testSelectorIdsMatch(":indeterminate", ["radio4", "radio5", "progress1"], "dynamically check a radio input in a radio button group");
+
+ document.getElementById("radio4").click();
+ testSelectorIdsMatch(":indeterminate", ["progress1"], "click on radio4 which is in the indeterminate state");
+
+ document.getElementById("progress1").setAttribute("value", "20");
+ testSelectorIdsMatch(":indeterminate", [], "adding a value to progress1 should put it in a determinate state");
+
+ document.getElementById("progress2").removeAttribute("value");
+ testSelectorIdsMatch(":indeterminate", ["progress2"], "removing progress2's value should put it in an indeterminate state");
+
+ document.getElementById("checkbox1").indeterminate = true; // set checkbox1 in the indeterminate state
+ testSelectorIdsMatch(":indeterminate", ["checkbox1", "progress2"], "':progress' also matches <input> checkbox whose indeterminate IDL is set to true");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/inrange-outofrange.html b/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/inrange-outofrange.html
new file mode 100644
index 000000000..e9acbb374
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/inrange-outofrange.html
@@ -0,0 +1,84 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Selector: pseudo-classes (:in-range, :out-of-range)</title>
+<link rel="author" title="Denis Ah-Kang" href="mailto:denis@w3.org" id="link1">
+<link rel="author" title="Chris Rebert" href="http://chrisrebert.com" id="link2">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#selector-in-range" id="link3">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#selector-out-of-range" id="link4">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="utils.js"></script>
+<div id="log"></div>
+<input type=number value=0 min=0 max=10 id=number1>
+<input type=number value=0 min=0 max=10 id=number2 disabled>
+<input type=number value=0 min=1 max=10 id=number3>
+<input type=number value=11 min=0 max=10 id=number4>
+<input type=number value=0 min=0 max=10 id=number5 readonly>
+
+<input type="date" min="2005-10-10" max="2020-10-10" value="2010-10-10" id="datein">
+<input type="date" min="2010-10-10" max="2020-10-10" value="2005-10-10" id="dateunder">
+<input type="date" min="2010-10-10" max="2020-10-10" value="2030-10-10" id="dateover">
+
+<input type="time" min="01:00:00" max="05:00:00" value="02:00:00" id="timein">
+<input type="time" min="02:00:00" max="05:00:00" value="01:00:00" id="timeunder">
+<input type="time" min="02:00:00" max="05:00:00" value="07:00:00" id="timeover">
+
+<input type="week" min="2016-W05" max="2016-W10" value="2016-W07" id="weekin">
+<input type="week" min="2016-W05" max="2016-W10" value="2016-W02" id="weekunder">
+<input type="week" min="2016-W05" max="2016-W10" value="2016-W26" id="weekover">
+
+<input type="month" min="2000-04" max="2000-09" value="2000-06" id="monthin">
+<input type="month" min="2000-04" max="2000-09" value="2000-02" id="monthunder">
+<input type="month" min="2000-04" max="2000-09" value="2000-11" id="monthover">
+
+<input type="datetime-local" min="2008-03-12T23:59:59" max="2015-02-13T23:59:59" value="2012-11-28T23:59:59" id="datetimelocalin">
+<input type="datetime-local" min="2008-03-12T23:59:59" max="2015-02-13T23:59:59" value="2008-03-01T23:59:59" id="datetimelocalunder">
+<input type="datetime-local" min="2008-03-12T23:59:59" max="2015-02-13T23:59:59" value="2016-01-01T23:59:59" id="datetimelocalover">
+
+<!-- None of the following have range limitations since they have neither min nor max attributes -->
+<input type="number" value="0" id="numbernolimit">
+<input type="date" value="2010-10-10" id="datenolimit">
+<input type="time" value="02:00:00" id="timenolimit">
+<input type="week" value="2016-W07" id="weeknolimit">
+<input type="month" value="2000-06" id="monthnolimit">
+<input type="datetime-local" value="2012-11-28T23:59:59" id="datetimelocalnolimit">
+
+<!-- range inputs have default minimum of 0 and default maximum of 100 -->
+<input type="range" value="50" id="range0">
+
+<!-- range input's value gets immediately clamped to the nearest boundary point -->
+<input type="range" min="2" max="7" value="5" id="range1">
+<input type="range" min="2" max="7" value="1" id="range2">
+<input type="range" min="2" max="7" value="9" id="range3">
+
+<!-- None of the following input types can have range limitations -->
+<input min="1" value="0" type="text">
+<input min="1" value="0" type="search">
+<input min="1" value="0" type="url">
+<input min="1" value="0" type="tel">
+<input min="1" value="0" type="email">
+<input min="1" value="0" type="password">
+<input min="1" value="#000000" type="color">
+<input min="1" value="0" type="checkbox">
+<input min="1" value="0" type="radio">
+<input min="1" value="0" type="file">
+<input min="1" value="0" type="submit">
+<input min="1" value="0" type="image">
+<!-- The following types are also barred from constraint validation -->
+<input min="1" value="0" type="hidden">
+<input min="1" value="0" type="button">
+<input min="1" value="0" type="reset">
+
+<script>
+ testSelectorIdsMatch(":in-range", ["number1", "datein", "timein", "weekin", "monthin", "datetimelocalin", "range0", "range1", "range2", "range3"], "':in-range' matches all elements that are candidates for constraint validation, have range limitations, and that are neither suffering from an underflow nor suffering from an overflow");
+
+ testSelectorIdsMatch(":out-of-range", ["number3", "number4", "dateunder", "dateover", "timeunder", "timeover", "weekunder", "weekover", "monthunder", "monthover", "datetimelocalunder", "datetimelocalover"], "':out-of-range' matches all elements that are candidates for constraint validation, have range limitations, and that are either suffering from an underflow or suffering from an overflow");
+
+ document.getElementById("number1").value = -10;
+ testSelectorIdsMatch(":in-range", ["datein", "timein", "weekin", "monthin", "datetimelocalin", "range0", "range1", "range2", "range3"], "':in-range' update number1's value < min");
+ testSelectorIdsMatch(":out-of-range", ["number1", "number3", "number4", "dateunder", "dateover", "timeunder", "timeover", "weekunder", "weekover", "monthunder", "monthover", "datetimelocalunder", "datetimelocalover"], "':out-of-range' update number1's value < min");
+
+ document.getElementById("number3").min = 0;
+ testSelectorIdsMatch(":in-range", ["number3", "datein", "timein", "weekin", "monthin", "datetimelocalin", "range0", "range1", "range2", "range3"], "':in-range' update number3's min < value");
+ testSelectorIdsMatch(":out-of-range", ["number1", "number4", "dateunder", "dateover", "timeunder", "timeover", "weekunder", "weekover", "monthunder", "monthover", "datetimelocalunder", "datetimelocalover"], "':out-of-range' update number3's min < value");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/link.html b/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/link.html
new file mode 100644
index 000000000..fd485b83e
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/link.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Selector: pseudo-classes (:link)</title>
+<link rel="author" title="Denis Ah-Kang" href="mailto:denis@w3.org" id=link1>
+<link rel=help href="https://html.spec.whatwg.org/multipage/#pseudo-classes" id=link2>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="utils.js"></script>
+<div id="log"></div>
+<a id=link4></a>
+<area id=link5></area>
+<link id=link6></link>
+<a href="http://www.w3.org" id=link7></a>
+<area href="http://www.w3.org" id=link8></area>
+<link href="http://www.w3.org" id=link9></link>
+<a href="http://[" id=link10></a>
+
+<script>
+ testSelectorIdsMatch(":link", ["link1", "link2", "link3", "link7", "link8", "link9", "link10"], "Only <a>s, <area>s and <link>s that have a href attribute match ':link'");
+
+ document.getElementById("link9").removeAttribute("href");
+ testSelectorIdsMatch(":link", ["link1", "link2", "link3", "link7", "link8", "link10"], "':link' doesn't match elements whos href attribute has been removed");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/readwrite-readonly.html b/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/readwrite-readonly.html
new file mode 100644
index 000000000..d9bbadbe6
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/readwrite-readonly.html
@@ -0,0 +1,89 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Selector: pseudo-classes (:read-write, :read-only)</title>
+<link rel=help href="https://html.spec.whatwg.org/multipage/#pseudo-classes" id=link2>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="utils.js"></script>
+<div id="log"></div>
+
+<div id=set0>
+<!-- The readonly attribute does not apply to the following input types -->
+<input id=checkbox1 type=checkbox>
+<input id=hidden1 type=hidden value=abc>
+<input id=range1 type=range>
+<input id=color1 type=color>
+<input id=radio1 type=radio>
+<input id=file1 type=file>
+<input id=submit1 type=submit>
+<input id=image1 type=image>
+<input id=button1 type=button value="Button">
+<input id=reset1 type=reset>
+</div>
+
+<div id=set1>
+<input id=input1>
+<input id=input2 readonly>
+<input id=input3 disabled>
+<input id=input4 type=checkbox>
+<input id=input5 type=checkbox readonly>
+</div>
+
+<div id=set2>
+<textarea id=textarea1>textarea1</textarea>
+<textarea readonly id=textarea2>textarea2</textarea>
+</div>
+
+<div id=set3>
+<textarea id=textarea3>textarea3</textarea>
+<textarea disabled id=textarea4>textarea4</textarea>
+</div>
+
+<div id=set4>
+<p id=p1>paragraph1.</p>
+<p id=p2 contenteditable>paragraph2.</p>
+</div>
+
+<script>
+ testSelectorIdsMatch("#set0 :read-write", [], "The :read-write pseudo-class must not match input elements to which the readonly attribute does not apply");
+
+ testSelectorIdsMatch("#set0 :read-only", ["checkbox1", "hidden1", "range1", "color1", "radio1", "file1", "submit1", "image1", "button1", "reset1"], "The :read-only pseudo-class must match input elements to which the readonly attribute does not apply");
+
+ testSelectorIdsMatch("#set1 :read-write", ["input1"], "The :read-write pseudo-class must match input elements to which the readonly attribute applies, and that are mutable");
+
+ testSelectorIdsMatch("#set1 :read-only", ["input2"], "The :read-only pseudo-class must not match input elements to which the readonly attribute applies, and that are mutable");
+
+ document.getElementById("input1").setAttribute("readonly", "readonly");
+ testSelectorIdsMatch("#set1 :read-write", [], "The :read-write pseudo-class must not match input elements after the readonly attribute has been added");
+
+ testSelectorIdsMatch("#set1 :read-only", ["input1", "input2"], "The :read-only pseudo-class must match input elements after the readonly attribute has been added");
+
+ document.getElementById("input1").removeAttribute("readonly");
+ testSelectorIdsMatch("#set1 :read-write", ["input1"], "The :read-write pseudo-class must not match input elements after the readonly attribute has been removed");
+
+ testSelectorIdsMatch("#set1 :read-only", ["input2"], "The :read-only pseudo-class must match input elements after the readonly attribute has been removed");
+
+ testSelectorIdsMatch("#set2 :read-write", ["textarea1"], "The :read-write pseudo-class must match textarea elements that do not have a readonly attribute, and that are not disabled");
+
+ testSelectorIdsMatch("#set2 :read-only", ["textarea2"], "The :read-only pseudo-class must match textarea elements that have a readonly attribute, or that are disabled");
+
+ document.getElementById("textarea1").setAttribute("readonly", "readonly");
+ testSelectorIdsMatch("#set2 :read-write", [], "The :read-write pseudo-class must match textarea elements after the readonly attribute has been added");
+
+ testSelectorIdsMatch("#set2 :read-only", ["textarea1", "textarea2"], "The :read-only pseudo-class must match textarea elements after the readonly attribute has been added");
+
+ testSelectorIdsMatch("#set3 :read-write", ["textarea3"], "The :read-write pseudo-class must not match textarea elements that are disabled");
+
+ testSelectorIdsMatch("#set3 :read-only", ["textarea4"], "The :read-only pseudo-class must match textarea elements that are disabled");
+
+ testSelectorIdsMatch("#set4 :read-write", ["p2"], "The :read-write pseudo-class must match elements that are editable");
+
+ testSelectorIdsMatch("#set4 :read-only", ["p1"], "The :read-only pseudo-class must not match elements that are editable");
+
+ document.designMode = "on";
+
+ testSelectorIdsMatch("#set4 :read-write", ["p1", "p2"], "The :read-write pseudo-class must match elements that are editing hosts");
+
+ testSelectorIdsMatch("#set4 :read-only", [], "The :read-only pseudo-class must not match elements that are editing hosts");
+
+</script>
diff --git a/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/required-optional.html b/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/required-optional.html
new file mode 100644
index 000000000..f06fdfa1e
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/required-optional.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>Selector: pseudo-classes (:required, :optional)</title>
+<link rel="author" title="Denis Ah-Kang" href="mailto:denis@w3.org" id=link1>
+<link rel=help href="https://html.spec.whatwg.org/multipage/#pseudo-classes" id=link2>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="utils.js"></script>
+<div id="log"></div>
+<input type=text id=text1 value="foobar" required>
+<input type=text id=text2 required>
+<input type=text id=text3>
+<select id=select1 required>
+ <optgroup label="options" id=optgroup1>
+ <option value="option1" id=option1>option1
+</select>
+<select id=select2>
+ <optgroup label="options" id=optgroup2>
+ <option value="option2" id=option2>option2
+</select>
+<textarea required id=textarea1>textarea1</textarea>
+<textarea id=textarea2>textarea2</textarea>
+
+<script>
+ testSelectorIdsMatch(":required", ["text1", "text2", "select1", "textarea1"], "':required' matches required <input>s, <select>s and <textarea>s");
+ testSelectorIdsMatch(":optional", ["text3", "select2", "textarea2"], "':optional' matches elements <input>s, <select>s and <textarea>s that are not required");
+
+ document.getElementById("text1").removeAttribute("required");
+ testSelectorIdsMatch(":required", ["text2", "select1", "textarea1"], "':required' doesn't match elements whose required attribute has been removed");
+ testSelectorIdsMatch(":optional", ["text1", "text3", "select2", "textarea2"], "':optional' matches elements whose required attribute has been removed");
+
+ document.getElementById("select2").setAttribute("required", "required");
+ testSelectorIdsMatch(":required", ["text2", "select1", "select2", "textarea1"], "':required' matches elements whose required attribute has been added");
+ testSelectorIdsMatch(":optional", ["text1", "text3", "textarea2"], "':optional' doesn't match elements whose required attribute has been added");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/utils.js b/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/utils.js
new file mode 100644
index 000000000..a8b1cd62a
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/utils.js
@@ -0,0 +1,20 @@
+function getElementsByIds(ids) {
+ var result = [];
+ ids.forEach(function(id) {
+ result.push(document.getElementById(id));
+ });
+ return result;
+}
+
+function testSelectorIdsMatch(selector, ids, testName) {
+ test(function(){
+ var elements = document.querySelectorAll(selector);
+ assert_array_equals(elements, getElementsByIds(ids));
+ }, testName);
+}
+
+function testSelectorElementsMatch(selector, elements, testName) {
+ test(function(){
+ assert_array_equals(document.querySelectorAll(selector), elements);
+ }, testName);
+}
diff --git a/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/valid-invalid.html b/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/valid-invalid.html
new file mode 100644
index 000000000..d93407707
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/selectors/pseudo-classes/valid-invalid.html
@@ -0,0 +1,146 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset=utf-8>
+<title>Selector: pseudo-classes (:valid, :invalid)</title>
+<link rel="author" title="Denis Ah-Kang" href="mailto:denis@w3.org" id=link1>
+<link rel=help href="https://html.spec.whatwg.org/multipage/#pseudo-classes" id=link2>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="utils.js"></script>
+<style>
+ #styleTests form, #styleTests fieldset, #failExample { background-color:red; }
+ #styleTests > :valid, #validExample { background-color:green; }
+ #styleTests > :invalid, #invalidExample { background-color:lime; }
+</style>
+</head>
+<body>
+<div id="log"></div>
+<div id='simpleConstraints'>
+ <input type=text id=text1 value="foobar" required>
+ <input type=text id=text2 required>
+</div>
+<div id='FormSelection'>
+ <form id=form1>
+ <input type=text id=text3 value="foobar" required>
+ </form>
+ <form id=form2>
+ <input type=text id=text4 required>
+ </form>
+</div>
+<div id='FieldSetSelection'>
+ <fieldset id=fieldset1>
+ <input type=text id=text5 value="foobar" required>
+ </fieldset>
+ <fieldset id=fieldset2>
+ <input type=text id=text6 required>
+ </fieldset>
+</div>
+<div id='patternConstraints'>
+ <input type=text id=text7 value="AAA" pattern="[0-9][A-Z]{3}">
+ <input type=text id=text8 value="0AAA" pattern="[0-9][A-Z]{3}">
+</div>
+<div id='numberConstraints'>
+ <input type=number id=number1 value=0 min=1>
+ <input type=number id=number2 value=1 min=1>
+</div>
+<div id='styleTests'>
+ <form>
+ </form>
+ <form>
+ <input type=text min=8 value=4>
+ </form>
+ <form>
+ <input type=number min=8 value=4>
+ </form>
+ <fieldset>
+ </fieldset>
+ <fieldset>
+ <input type=text min=8 value=4>
+ </fieldset>
+ <fieldset>
+ <input type=number min=8 value=4>
+ </fieldset>
+ <div id='validExample'></div>
+ <div id='invalidExample'></div>
+ <div id='failExample'></div>
+</div>
+<script>
+ testSelectorIdsMatch("#simpleConstraints :valid", ["text1"], "':valid' matches elements that satisfy their constraints");
+
+ testSelectorIdsMatch("#FormSelection :valid", ["form1", "text3"], "':valid' matches form elements that are not the form owner of any elements that themselves are candidates for constraint validation but do not satisfy their constraints");
+
+ testSelectorIdsMatch("#FieldSetSelection :valid", ["fieldset1", "text5"], "':valid' matches fieldset elements that have no descendant elements that themselves are candidates for constraint validation but do not satisfy their constraints");
+
+ testSelectorIdsMatch("#patternConstraints :valid", [ "text8" ], "':valid' matches elements that satisfy their pattern constraints");
+
+ testSelectorIdsMatch("#numberConstraints :valid", [ "number2" ], "':valid' matches elements that satisfy their number constraints");
+
+
+ testSelectorIdsMatch("#simpleConstraints :invalid", ["text2"], "':invalid' matches elements that do not satisfy their simple text constraints");
+
+ testSelectorIdsMatch("#FormSelection :invalid", ["form2", "text4"], "':invalid' matches form elements that are the form owner of one or more elements that themselves are candidates for constraint validation but do not satisfy their constraints");
+
+ testSelectorIdsMatch("#FieldSetSelection :invalid", ["fieldset2", "text6"], "':invalid' matches fieldset elements that have of one or more descendant elements that themselves are candidates for constraint validation but do not satisfy their constraints");
+
+ testSelectorIdsMatch("#patternConstraints :invalid", ["text7"], "':invalid' matches elements that do not satisfy their pattern constraints");
+
+ testSelectorIdsMatch("#numberConstraints :invalid", ["number1"], "':invalid' matches elements that do not satisfy their number constraints");
+
+ document.getElementById("text7").value="0BBB";
+ testSelectorIdsMatch("#patternConstraints :valid", [ "text7", "text8" ], "':valid' matches new elements that satisfy their constraints");
+ testSelectorIdsMatch("#patternConstraints :invalid", [], "':invalid' doesn't match new elements that satisfy their constraints");
+
+ document.getElementById("text8").value="BBB";
+ testSelectorIdsMatch("#patternConstraints :valid", ["text7"], "':valid' doesn't match new elements that do not satisfy their constraints");
+ testSelectorIdsMatch("#patternConstraints :invalid", ["text8"], "':invalid' matches new elements that do not satisfy their constraints");
+
+ function getBGColor(elem) {
+ return getComputedStyle(elem).backgroundColor;
+ }
+
+ function testStyles(type) {
+ var elems = document.querySelectorAll("#styleTests " + type),
+ empty = elems[0],
+ valid = elems[1],
+ invalid = elems[2],
+ validInput = valid.querySelector("input"),
+ invalidInput = invalid.querySelector("input"),
+ expectedValidBGColor = getBGColor(document.getElementById("validExample")),
+ expectedInvalidBGColor = getBGColor(document.getElementById("invalidExample")),
+ expectedFailBGColor = getBGColor(document.getElementById("failExample"));
+
+ test(function() {
+ assert_equals(getBGColor(empty), expectedValidBGColor, "wrong background-color");
+ }, 'empty ' + type + ' correctly styled on page-load');
+
+ test(function() {
+ assert_equals(getBGColor(valid), expectedValidBGColor, "wrong background-color");
+ }, 'valid ' + type + ' correctly styled on page-load');
+ test(function() {
+ assert_equals(getBGColor(invalid), expectedInvalidBGColor, "wrong background-color");
+ }, 'invalid ' + type + ' correctly styled on page-load');
+
+ test(function() {
+ empty.appendChild(validInput.cloneNode());
+ assert_equals(getBGColor(empty), expectedValidBGColor, "wrong background-color");
+ }, 'programmatically adding valid to empty ' + type + ' results in correct style');
+ test(function() {
+ empty.appendChild(invalidInput.cloneNode());
+ assert_equals(getBGColor(empty), expectedInvalidBGColor, "wrong background-color");
+ }, 'programmatically adding invalid to empty ' + type + ' results in correct style');
+
+ validInput.type = "number";
+ invalidInput.type = "text";
+ test(function() {
+ assert_equals(getBGColor(valid), expectedInvalidBGColor, "wrong background-color");
+ }, 'programmatically-invalidated ' + type + ' correctly styled');
+ test(function() {
+ assert_equals(getBGColor(invalid), expectedValidBGColor, "wrong background-color");
+ }, 'programmatically-validated ' + type + ' correctly styled');
+ }
+ test(testStyles.bind(undefined, "form"), ":valid/:invalid styling for <form>");
+ test(testStyles.bind(undefined, "fieldset"), ":valid/:invalid styling for <fieldset>");
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/tabular-data/.gitkeep b/testing/web-platform/tests/html/semantics/tabular-data/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/tabular-data/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/tabular-data/attributes-common-to-td-and-th-elements/.gitkeep b/testing/web-platform/tests/html/semantics/tabular-data/attributes-common-to-td-and-th-elements/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/tabular-data/attributes-common-to-td-and-th-elements/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/tabular-data/attributes-common-to-td-and-th-elements/cellIndex.html b/testing/web-platform/tests/html/semantics/tabular-data/attributes-common-to-td-and-th-elements/cellIndex.html
new file mode 100644
index 000000000..b8449229d
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/tabular-data/attributes-common-to-td-and-th-elements/cellIndex.html
@@ -0,0 +1,50 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>HTMLTableCellElement.cellIndex</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<script>
+test(function() {
+ var th = document.createElement("th");
+ assert_true("cellIndex" in th, '"cellIndex" in th');
+ var td = document.createElement("td");
+ assert_true("cellIndex" in td, '"cellIndex" in td');
+}, "cellIndex should exist.")
+test(function() {
+ var th = document.createElement("th");
+ assert_equals(th.cellIndex, -1);
+ var td = document.createElement("td");
+ assert_equals(td.cellIndex, -1);
+}, "For cells without a parent, cellIndex should be -1.")
+test(function() {
+ var table = document.createElement("table");
+ var th = table.appendChild(document.createElement("th"));
+ assert_equals(th.cellIndex, -1);
+ var td = table.appendChild(document.createElement("td"));
+ assert_equals(td.cellIndex, -1);
+}, "For cells whose parent is not a tr, cellIndex should be -1.")
+test(function() {
+ var tr = document.createElementNS("", "tr");
+ var th = tr.appendChild(document.createElement("th"));
+ assert_equals(th.cellIndex, -1);
+ var td = tr.appendChild(document.createElement("td"));
+ assert_equals(td.cellIndex, -1);
+}, "For cells whose parent is not a HTML tr, cellIndex should be -1.")
+test(function() {
+ var tr = document.createElement("tr");
+ var th = tr.appendChild(document.createElement("th"));
+ assert_equals(th.cellIndex, 0);
+ var td = tr.appendChild(document.createElement("td"));
+ assert_equals(td.cellIndex, 1);
+}, "For cells whose parent is a tr, cellIndex should be the index.")
+test(function() {
+ var tr = document.createElement("tr");
+ var th = tr.appendChild(document.createElement("th"));
+ assert_equals(th.cellIndex, 0);
+ tr.appendChild(document.createElement("div"));
+ tr.appendChild(document.createTextNode("Hello World"));
+ var td = tr.appendChild(document.createElement("td"));
+ assert_equals(td.cellIndex, 1)
+}, "For cells whose parent is a tr with non td/th sibling, cellIndex should skip those non td/th siblings.")
+</script>
diff --git a/testing/web-platform/tests/html/semantics/tabular-data/examples/.gitkeep b/testing/web-platform/tests/html/semantics/tabular-data/examples/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/tabular-data/examples/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/tabular-data/historical.html b/testing/web-platform/tests/html/semantics/tabular-data/historical.html
new file mode 100644
index 000000000..a6be56e13
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/tabular-data/historical.html
@@ -0,0 +1,25 @@
+<!doctype html>
+<title>Historical table features should not be supported</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+function t(property, tagNames) {
+ if (typeof tagNames === "string") {
+ tagNames = [tagNames];
+ }
+ tagNames.forEach(function(tagName) {
+ test(function() {
+ assert_false(property in document.createElement(tagName));
+ }, tagName + '.' + property + ' should not be supported');
+ });
+}
+
+// added in https://github.com/whatwg/html/commit/6db0d8d4e3456140de958c963afe9bb9ec7b6a25
+// removed in https://github.com/whatwg/html/commit/59b7e2466c2b7c5c408a4963b05b13fd808aa07a
+t('onsort', 'table');
+t('sortable', 'table');
+t('stopSorting', 'table');
+t('sorted', 'th');
+t('sort', 'th');
+</script>
diff --git a/testing/web-platform/tests/html/semantics/tabular-data/html-table-section-element.js b/testing/web-platform/tests/html/semantics/tabular-data/html-table-section-element.js
new file mode 100644
index 000000000..68b68ceed
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/tabular-data/html-table-section-element.js
@@ -0,0 +1,22 @@
+// https://html.spec.whatwg.org/multipage/#dom-tbody-rows
+function testRowsAttribute(localName) {
+ var elem = document.createElement(localName);
+ assert_equals(elem.rows.length, 0);
+
+ // Child <p> should *not* count as a row
+ elem.appendChild(document.createElement("p"));
+ assert_equals(elem.rows.length, 0);
+
+ // Child <tr> should count as a row
+ var childTr = document.createElement("tr");
+ elem.appendChild(childTr);
+ assert_equals(elem.rows.length, 1);
+
+ // Nested table with child <tr> should *not* count as a row
+ var nested = document.createElement(localName);
+ nested.appendChild(document.createElement("tr"));
+ var nestedTable = document.createElement("table");
+ nestedTable.appendChild(nested);
+ childTr.appendChild(nestedTable);
+ assert_equals(elem.rows.length, 1);
+}
diff --git a/testing/web-platform/tests/html/semantics/tabular-data/processing-model-1/.gitkeep b/testing/web-platform/tests/html/semantics/tabular-data/processing-model-1/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/tabular-data/processing-model-1/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/tabular-data/processing-model-1/contains.json b/testing/web-platform/tests/html/semantics/tabular-data/processing-model-1/contains.json
new file mode 100644
index 000000000..be5a8fdfd
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/tabular-data/processing-model-1/contains.json
@@ -0,0 +1,10 @@
+[
+ {
+ "id": "forming-a-table",
+ "original_id": "forming-a-table"
+ },
+ {
+ "id": "header-and-data-cell-semantics",
+ "original_id": "header-and-data-cell-semantics"
+ }
+] \ No newline at end of file
diff --git a/testing/web-platform/tests/html/semantics/tabular-data/the-caption-element/.gitkeep b/testing/web-platform/tests/html/semantics/tabular-data/the-caption-element/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/tabular-data/the-caption-element/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/tabular-data/the-caption-element/caption_001.html b/testing/web-platform/tests/html/semantics/tabular-data/the-caption-element/caption_001.html
new file mode 100644
index 000000000..ecb1bef85
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/tabular-data/the-caption-element/caption_001.html
@@ -0,0 +1,70 @@
+<!DOCTYPE HTML>
+<html>
+ <head>
+ <title>HTML5 Table API Tests</title>
+ <meta content="text/html; charset=UTF-8" http-equiv="Content-Type">
+ <link rel="author" title="Microsoft" href="http://www.microsoft.com/" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-caption-element" />
+ </head>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <body>
+ <div id="log"></div>
+ <table id="table1" style="display:none">
+ <tr><td></td></tr>
+ <caption>first caption</caption>
+ <caption>second caption</caption>
+ </table>
+ <table id="table2" style="display:none">
+ <tr><td></td></tr>
+ </table>
+ <table id="table3" style="display:none">
+ <tr><td></td></tr>
+ </table>
+ <table id="table4" style="display:none">
+ <tr><td></td></tr>
+ <caption>first caption</caption>
+ </table>
+ <script>
+ test(function () {
+ assert_equals(document.getElementById('table1').caption.innerHTML, "first caption");
+ }, "first caption element child of the first table element");
+
+ test(function () {
+ var caption = document.createElement("caption");
+ caption.innerHTML = "new caption";
+ var table = document.getElementById('table1');
+ table.caption = caption;
+
+ assert_equals(caption.parentNode, table);
+ assert_equals(table.firstChild, caption);
+ assert_equals(table.caption.innerHTML, "new caption");
+
+ captions = table.getElementsByTagName('caption');
+ assert_equals(captions.length, 2);
+ assert_equals(captions[0].innerHTML, "new caption");
+ assert_equals(captions[1].innerHTML, "second caption");
+ }, "setting caption on a table");
+
+ test(function () {
+ assert_equals(document.getElementById('table2').caption, null);
+ }, "caption IDL attribute is null");
+
+ test(function () {
+ var table = document.getElementById('table3');
+ var caption = document.createElement("caption")
+ table.rows[0].appendChild(caption);
+ assert_equals(table.caption, null);
+ }, "caption of the third table element should be null");
+
+ test(function () {
+ assert_not_equals(document.getElementById('table4').caption, null);
+
+ var parent = document.getElementById('table4').caption.parentNode;
+ parent.removeChild(document.getElementById('table4').caption);
+
+ assert_equals(document.getElementById('table4').caption, null);
+ }, "dynamically removing caption on a table");
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/tabular-data/the-col-element/.gitkeep b/testing/web-platform/tests/html/semantics/tabular-data/the-col-element/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/tabular-data/the-col-element/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/tabular-data/the-colgroup-element/.gitkeep b/testing/web-platform/tests/html/semantics/tabular-data/the-colgroup-element/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/tabular-data/the-colgroup-element/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/tabular-data/the-table-element/.gitkeep b/testing/web-platform/tests/html/semantics/tabular-data/the-table-element/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/tabular-data/the-table-element/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/tabular-data/the-table-element/caption-methods.html b/testing/web-platform/tests/html/semantics/tabular-data/the-table-element/caption-methods.html
new file mode 100644
index 000000000..35ee9f445
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/tabular-data/the-table-element/caption-methods.html
@@ -0,0 +1,100 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>Creating and deleting captions</title>
+ <link rel="author" title="Erika Navara" href="mailto:edoyle@microsoft.com">
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-table-element" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-table-createcaption" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-table-deletecaption" />
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+</head>
+<body>
+ <div id="log"></div>
+ <table id="table0" style="display:none">
+ </table>
+ <table id="table1" style="display:none">
+ <caption id="caption1">caption</caption>
+ <tr>
+ <td>cell</td>
+ <td>cell</td>
+ </tr>
+ </table>
+ <table id="table2" style="display:none">
+ <foo:caption>caption</foo:caption>
+ <tr>
+ <td>cell</td>
+ <td>cell</td>
+ </tr>
+ </table>
+ <table id="table3" style="display:none">
+ <caption id="caption3">caption 3</caption>
+ <tr>
+ <td>cell</td>
+ <td>cell</td>
+ </tr>
+ </table>
+ <table id="table4" style="display:none">
+ </table>
+ <table id="table5" style="display:none">
+ </table>
+ <script>
+ test(function () {
+ var table0 = document.getElementById('table0');
+ var caption = document.createElementNS("foo", "caption");
+ table0.appendChild(caption);
+ var table0FirstNode = table0.firstChild;
+ var testCaption = table0.createCaption();
+ assert_not_equals(testCaption, table0FirstNode);
+ assert_equals(testCaption, table0.firstChild);
+ }, "createCaption method creates new caption if existing caption is not in html namespace")
+ test(function () {
+ var table1 = document.getElementById('table1');
+ var testCaption = table1.createCaption();
+ var table1FirstCaption = table1.caption;
+ assert_equals(testCaption, table1FirstCaption);
+ }, "createCaption method returns the first caption element child of the table")
+ test(function () {
+ var table2 = document.getElementById('table2');
+ var test2Caption = table2.createCaption();
+ var table2FirstNode = table2.firstChild;
+ assert_true(test2Caption instanceof HTMLTableCaptionElement);
+ assert_equals(table2FirstNode, test2Caption);
+ }, "createCaption method creates a new caption and inserts it as the first node of the table element")
+ test(function () {
+ var table = document.createElement('table');
+ assert_equals(table.createCaption(), table.createCaption());
+ }, "createCaption will not create new caption if one exists")
+ test(function () {
+ var table = document.createElementNS("http://www.w3.org/1999/xhtml", "foo:table")
+ var caption = table.createCaption();
+ assert_equals(caption.prefix, null);
+ }, "createCaption will not copy table's prefix")
+ test(function () {
+ var table3 = document.getElementById('table3');
+ assert_equals(table3.caption.textContent, "caption 3");
+ table3.deleteCaption();
+ assert_equals(table3.caption, null);
+ }, "deleteCaption method removes the first caption element child of the table element")
+ test(function () {
+ var table4 = document.getElementById('table4');
+ var caption = document.createElementNS("foo", "caption");
+ table4.appendChild(caption);
+ table4.deleteCaption();
+ assert_equals(caption.parentNode, table4);
+ }, "deleteCaption method not remove caption that is not in html namespace")
+ test(function() {
+ var table5 = document.getElementById('table5');
+ var caption = document.createElement('caption');
+ caption.appendChild(table5)
+
+ // Node cannot be inserted at the specified point in the hierarchy
+ assert_throws("HierarchyRequestError", function() {
+ table5.caption = caption;
+ });
+
+ assert_not_equals(table5.caption, caption);
+ }, "Setting caption rethrows exception");
+ </script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/tabular-data/the-table-element/contains.json b/testing/web-platform/tests/html/semantics/tabular-data/the-table-element/contains.json
new file mode 100644
index 000000000..ee89be21d
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/tabular-data/the-table-element/contains.json
@@ -0,0 +1,10 @@
+[
+ {
+ "id": "table-descriptions-techniques",
+ "original_id": "table-descriptions-techniques"
+ },
+ {
+ "id": "table-layout-techniques",
+ "original_id": "table-layout-techniques"
+ }
+] \ No newline at end of file
diff --git a/testing/web-platform/tests/html/semantics/tabular-data/the-table-element/createTBody.html b/testing/web-platform/tests/html/semantics/tabular-data/the-table-element/createTBody.html
new file mode 100644
index 000000000..6100aedfd
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/tabular-data/the-table-element/createTBody.html
@@ -0,0 +1,173 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>HTMLTableElement.createTBody</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<div id=log></div>
+<script>
+function assert_tbody(tbody) {
+ assert_equals(tbody.localName, "tbody");
+ assert_equals(tbody.namespaceURI, htmlNS);
+ assert_equals(tbody.prefix, null);
+}
+var htmlNS = "http://www.w3.org/1999/xhtml";
+test(function() {
+ var table = document.createElement("table");
+ var tbody = table.createTBody();
+ assert_equals(table.firstChild, tbody);
+ assert_tbody(tbody);
+}, "No child nodes");
+
+test(function() {
+ var table = document.createElement("table");
+ var before = table.appendChild(document.createElement("tbody"));
+ assert_array_equals(table.childNodes, [before]);
+
+ var tbody = table.createTBody();
+ assert_array_equals(table.childNodes, [before, tbody]);
+ assert_tbody(tbody);
+}, "One tbody child node");
+
+test(function() {
+ var table = document.createElement("table");
+ var before1 = table.appendChild(document.createElement("tbody"));
+ var before2 = table.appendChild(document.createElement("tbody"));
+ assert_array_equals(table.childNodes, [before1, before2]);
+
+ var tbody = table.createTBody();
+ assert_array_equals(table.childNodes, [before1, before2, tbody]);
+ assert_tbody(tbody);
+}, "Two tbody child nodes");
+
+test(function() {
+ var table = document.createElement("table");
+ var before1 = table.appendChild(document.createElement("thead"));
+ var before2 = table.appendChild(document.createElement("tbody"));
+ assert_array_equals(table.childNodes, [before1, before2]);
+
+ var tbody = table.createTBody();
+ assert_array_equals(table.childNodes, [before1, before2, tbody]);
+ assert_tbody(tbody);
+}, "A thead and a tbody child node");
+
+test(function() {
+ var table = document.createElement("table");
+ var before1 = table.appendChild(document.createElement("tfoot"));
+ var before2 = table.appendChild(document.createElement("tbody"));
+ assert_array_equals(table.childNodes, [before1, before2]);
+
+ var tbody = table.createTBody();
+ assert_array_equals(table.childNodes, [before1, before2, tbody]);
+ assert_tbody(tbody);
+}, "A tfoot and a tbody child node");
+
+test(function() {
+ var table = document.createElement("table");
+ var before = table.appendChild(document.createElement("tbody"));
+ var after = table.appendChild(document.createElement("thead"));
+ assert_array_equals(table.childNodes, [before, after]);
+
+ var tbody = table.createTBody();
+ assert_array_equals(table.childNodes, [before, tbody, after]);
+ assert_tbody(tbody);
+}, "A tbody and a thead child node");
+
+test(function() {
+ var table = document.createElement("table");
+ var before = table.appendChild(document.createElement("tbody"));
+ var after = table.appendChild(document.createElement("tfoot"));
+ assert_array_equals(table.childNodes, [before, after]);
+
+ var tbody = table.createTBody();
+ assert_array_equals(table.childNodes, [before, tbody, after]);
+ assert_tbody(tbody);
+}, "A tbody and a tfoot child node");
+
+test(function() {
+ var table = document.createElement("table");
+ var before1 = table.appendChild(document.createElement("tbody"));
+ var before2 = table.appendChild(document.createElement("tbody"));
+ var after = table.appendChild(document.createElement("div"));
+ assert_array_equals(table.childNodes, [before1, before2, after]);
+
+ var tbody = table.createTBody();
+ assert_array_equals(table.childNodes, [before1, before2, tbody, after]);
+ assert_tbody(tbody);
+}, "Two tbody child nodes and a div");
+
+test(function() {
+ var table = document.createElement("table");
+ var before = table.appendChild(document.createElement("tbody"));
+ var after = table.appendChild(document.createElementNS("x", "tbody"));
+ assert_array_equals(table.childNodes, [before, after]);
+
+ var tbody = table.createTBody();
+ assert_array_equals(table.childNodes, [before, tbody, after]);
+ assert_tbody(tbody);
+}, "One HTML and one namespaced tbody child node");
+
+test(function() {
+ var table = document.createElement("table");
+ var before1 = table.appendChild(document.createElement("tbody"));
+ var before2 = before1.appendChild(document.createElement("tbody"));
+ assert_array_equals(table.childNodes, [before1]);
+
+ var tbody = table.createTBody();
+ assert_array_equals(table.childNodes, [before1, tbody]);
+ assert_tbody(tbody);
+}, "Two nested tbody child nodes");
+
+test(function() {
+ var table = document.createElement("table");
+ var before1 = table.appendChild(document.createElement("thead"));
+ var before2 = before1.appendChild(document.createElement("tbody"));
+ assert_array_equals(table.childNodes, [before1]);
+
+ var tbody = table.createTBody();
+ assert_array_equals(table.childNodes, [before1, tbody]);
+ assert_tbody(tbody);
+}, "A tbody node inside a thead child node");
+
+test(function() {
+ var table = document.createElement("table");
+ var before1 = table.appendChild(document.createElement("tfoot"));
+ var before2 = before1.appendChild(document.createElement("tbody"));
+ assert_array_equals(table.childNodes, [before1]);
+
+ var tbody = table.createTBody();
+ assert_array_equals(table.childNodes, [before1, tbody]);
+ assert_tbody(tbody);
+}, "A tbody node inside a tfoot child node");
+
+test(function() {
+ var table = document.createElement("table");
+ var before = table.appendChild(document.createElement("tbody"));
+ var after1 = table.appendChild(document.createElement("thead"));
+ var after2 = after1.appendChild(document.createElement("tbody"));
+ assert_array_equals(table.childNodes, [before, after1]);
+
+ var tbody = table.createTBody();
+ assert_array_equals(table.childNodes, [before, tbody, after1]);
+ assert_tbody(tbody);
+}, "A tbody node inside a thead child node after a tbody child node");
+
+test(function() {
+ var table = document.createElement("table");
+ var before = table.appendChild(document.createElement("tbody"));
+ var after1 = table.appendChild(document.createElement("tfoot"));
+ var after2 = after1.appendChild(document.createElement("tbody"));
+ assert_array_equals(table.childNodes, [before, after1]);
+
+ var tbody = table.createTBody();
+ assert_array_equals(table.childNodes, [before, tbody, after1]);
+ assert_tbody(tbody);
+}, "A tbody node inside a tfoot child node after a tbody child node");
+
+test(function() {
+ var table = document.createElementNS(htmlNS, "foo:table");
+ var tbody = table.createTBody();
+
+ assert_equals(tbody.prefix, null);
+}, "A prefixed table creates tbody without prefix");
+
+</script>
diff --git a/testing/web-platform/tests/html/semantics/tabular-data/the-table-element/delete-caption.html b/testing/web-platform/tests/html/semantics/tabular-data/the-table-element/delete-caption.html
new file mode 100644
index 000000000..6183fa98b
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/tabular-data/the-table-element/delete-caption.html
@@ -0,0 +1,94 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>deleteCaption()</title>
+ <link rel="author" title="Ben Boyle" href="mailto:benjamins.boyle@gmail.com">
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-table-deletecaption" />
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+</head>
+<body>
+ <table id="one-caption">
+ <caption>Fixture table caption</caption>
+ </table>
+
+ <table id="two-captions">
+ <caption>Fixture table caption</caption>
+ <caption>A second caption element</caption>
+ </table>
+
+ <table id="zero-captions"></table>
+
+ <table id="descendent-caption">
+ <tr>
+ <td>
+ <table>
+ <caption>Nested caption</caption>
+ </table>
+ </td>
+ </tr>
+ </table>
+
+ <script>
+ // The deleteCaption() method must remove the first caption element child of the table element, if any.
+ // https://html.spec.whatwgorg/multipage/tables.html#dom-table-deletecaption
+ test(function() {
+ var table = document.getElementById('one-caption');
+
+ table.deleteCaption();
+ assert_equals(table.getElementsByTagName('caption').length, 0, 'caption was removed');
+
+ }, 'deleteCaption() delete only caption on table');
+
+ test(function() {
+ var table = document.getElementById('one-caption');
+ var result;
+
+ result = table.deleteCaption();
+ // does .deleteCaption() have a return value?
+ assert_equals(result, undefined, '.deleteCaption() returns undefined');
+ }, 'deleteCaption() returns undefined');
+
+ test(function() {
+ var table = document.getElementById('two-captions');
+
+ table.deleteCaption();
+ assert_equals(table.getElementsByTagName('caption').length, 1, '1 caption (of 2) was removed');
+ assert_equals(table.getElementsByTagName('caption')[0].textContent, 'A second caption element', 'The first caption was removed');
+
+ // removing the only caption
+ table.deleteCaption();
+ assert_equals(table.getElementsByTagName('caption').length, 0, 'last caption was removed');
+ }, 'deleteCaption()');
+
+ test(function() {
+ var table = document.getElementById('zero-captions');
+ // removing a caption when none exists
+ table.deleteCaption();
+
+ assert_equals(table.getElementsByTagName('caption').length, 0, 'no exceptions using .deleteCaption() on a table without any captions');
+
+ }, 'deleteCaption() does not throw any exceptions when called on a table without a caption');
+
+ test(function() {
+ var table = document.getElementById( 'descendent-caption' );
+ table.deleteCaption();
+
+ assert_equals(table.getElementsByTagName('caption').length, 1, 'descendent caption was not deleted');
+ }, 'deleteCaption() does not delete captions in descendent tables');
+
+ test(function() {
+ var table = document.getElementById('zero-captions');
+ var caption;
+
+ caption = document.createElementNS('http://www.w3.org/2000/svg', 'caption');
+ table.insertBefore(caption, table.firstChild);
+ assert_equals(table.getElementsByTagName('caption').length, 1, 'SVG:caption is created');
+
+ table.deleteCaption();
+ assert_equals(table.getElementsByTagName('caption').length, 1, 'SVG:caption is not deleted');
+
+ }, 'deleteCaption() handles captions from different namespaces');
+</script>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/tabular-data/the-table-element/insertRow-method-01.html b/testing/web-platform/tests/html/semantics/tabular-data/the-table-element/insertRow-method-01.html
new file mode 100644
index 000000000..4e379a1cc
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/tabular-data/the-table-element/insertRow-method-01.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<title>insertRow(): INDEX_SIZE_ERR</title>
+<link rel="author" title="Ms2ger" href="mailto:ms2ger@gmail.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-table-insertrow">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<div id="test">
+<table>
+<tr>
+<td>
+</table>
+</div>
+<script>
+test(function() {
+ var table = document.getElementById("test").getElementsByTagName("table")[0];
+ assert_throws("INDEX_SIZE_ERR", function() {
+ table.insertRow(-2);
+ })
+ assert_throws("INDEX_SIZE_ERR", function() {
+ table.insertRow(2);
+ })
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/tabular-data/the-table-element/insertRow-method-02.html b/testing/web-platform/tests/html/semantics/tabular-data/the-table-element/insertRow-method-02.html
new file mode 100644
index 000000000..410425fb1
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/tabular-data/the-table-element/insertRow-method-02.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<title>insertRow(): Empty table</title>
+<link rel="author" title="Ms2ger" href="mailto:ms2ger@gmail.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-table-insertrow">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<div id="test">
+<table></table>
+</div>
+<script>
+var HTML = "http://www.w3.org/1999/xhtml";
+test(function() {
+ var table = document.getElementById("test").getElementsByTagName("table")[0];
+ test(function() {
+ assert_equals(table.childNodes.length, 0);
+ assert_equals(table.rows.length, 0);
+ }, "table should start out empty")
+
+ var tr;
+ test(function() {
+ tr = table.insertRow(0);
+ assert_equals(tr.localName, "tr");
+ assert_equals(tr.namespaceURI, HTML);
+ }, "insertRow should insert a tr element")
+
+ var tbody = tr.parentNode;
+ test(function() {
+ assert_equals(tbody.localName, "tbody");
+ assert_equals(tbody.namespaceURI, HTML);
+ assert_equals(tbody.parentNode, table);
+ }, "insertRow should insert a tbody element")
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/tabular-data/the-table-element/insertRow-method-03.html b/testing/web-platform/tests/html/semantics/tabular-data/the-table-element/insertRow-method-03.html
new file mode 100644
index 000000000..19c3ceb3c
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/tabular-data/the-table-element/insertRow-method-03.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<title>insertRow(): non-empty table</title>
+<link rel="author" title="g-k" href="mailto:greg.guthe@gmail.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-table-insertrow">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<div id="test">
+ <table>
+ <tbody><tr id="first"></tr><tr id="second"></tr></tbody>
+ </table>
+</div>
+<script>
+var HTML = "http://www.w3.org/1999/xhtml";
+test(function() {
+ var table = document.getElementById("test").getElementsByTagName("table")[0];
+ test(function() {
+ assert_equals(table.childNodes.length, 3);
+ assert_equals(table.rows.length, 2);
+ }, "table should start out with two rows")
+
+ var tr;
+ test(function() {
+ tr = table.insertRow(1);
+ assert_equals(tr.localName, "tr");
+ assert_equals(tr.namespaceURI, HTML);
+ assert_equals(table.getElementsByTagName("tr")[0].id, "first");
+ assert_equals(table.getElementsByTagName("tr")[1].id, "");
+ assert_equals(table.getElementsByTagName("tr")[2].id, "second");
+ }, "insertRow should insert a tr element before the second row")
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/tabular-data/the-table-element/remove-row.html b/testing/web-platform/tests/html/semantics/tabular-data/the-table-element/remove-row.html
new file mode 100644
index 000000000..b0e529f91
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/tabular-data/the-table-element/remove-row.html
@@ -0,0 +1,50 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>Delete Row tests</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<table id="element">
+ <thead>
+ <th>First column</th>
+ <th>Second column</th>
+ </thead>
+ <tbody>
+ <tr>
+ <td>1.1</td>
+ <td>1.2</td>
+ </tr>
+ <tr>
+ <td>2.1</td>
+ <td>2.2</td>
+ </tr>
+ </tbody>
+</table>
+
+<script>
+var el = document.getElementById('element');
+
+test(function() {
+ assert_throws("IndexSizeError", function() {
+ el.deleteRow(-2)
+ })
+}, 'deleteRow function invalid argument');
+test(function() {
+ assert_throws("IndexSizeError", function() {
+ el.deleteRow(el.rows.length)
+ })
+}, 'deleteRow function invalid argument bis');
+
+test(function() {
+ var old_length = el.rows.length;
+ el.insertRow(-1);
+ el.deleteRow(-1);
+ assert_equals(old_length, el.rows.length);
+}, "check normal deleteRow");
+test(function() {
+ while (el.rows.length > 1) {
+ el.deleteRow(-1);
+ }
+ assert_equals(1, el.rows.length);
+}, "check normal deleteRow bis");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/tabular-data/the-table-element/tBodies.html b/testing/web-platform/tests/html/semantics/tabular-data/the-table-element/tBodies.html
new file mode 100644
index 000000000..128dbc9f7
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/tabular-data/the-table-element/tBodies.html
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<title>HTMLTableElement.tBodies</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<script>
+test(function() {
+ var text =
+ '<html xmlns="http://www.w3.org/1999/xhtml">' +
+ ' <head>' +
+ ' <title>Virtual Library</title>' +
+ ' </head>' +
+ ' <body>' +
+ ' <table id="mytable" border="1">' +
+ ' <tbody>' +
+ ' <tr><td>Cell 1</td><td>Cell 2</td></tr>' +
+ ' <tr><td>Cell 3</td><td>Cell 4</td></tr>' +
+ ' </tbody>' +
+ ' </table>' +
+ ' </body>' +
+ '</html>';
+
+ var parser = new DOMParser();
+ var doc = parser.parseFromString(text, "text/xml");
+
+ // import <table>
+ var table = doc.documentElement.getElementsByTagName('table')[0];
+ var mytable = document.body.appendChild(document.importNode(table, true));
+
+ assert_equals(mytable.tBodies.length, 1);
+ var tbody = document.createElement('tbody');
+ mytable.appendChild(tbody);
+ var tr = tbody.insertRow(-1);
+ tr.insertCell(-1).appendChild(document.createTextNode('Cell 5'));
+ tr.insertCell(-1).appendChild(document.createTextNode('Cell 6'));
+ assert_equals(mytable.tBodies.length, 2);
+ assert_equals(mytable.rows.length, 3);
+ assert_equals(tr.rowIndex, 2);
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/tabular-data/the-table-element/tFoot.html b/testing/web-platform/tests/html/semantics/tabular-data/the-table-element/tFoot.html
new file mode 100644
index 000000000..d06e16f20
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/tabular-data/the-table-element/tFoot.html
@@ -0,0 +1,57 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>tFoot tests</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<table id="t">
+<caption id="tcaption"></caption><thead id="thead"></thead><tbody id="tbody1"></tbody><tbody id="tbody2"></tbody><tfoot id="tfoot1"></tfoot><tfoot id="tfoot2"></tfoot><tfoot id="tfoot3"></tfoot></table>
+<script>
+test(function() {
+ var t = document.getElementById("t");
+ var tfoot1 = document.getElementById("tfoot1");
+
+ assert_equals(t.tFoot, tfoot1);
+
+ var tfoot2 = document.getElementById("tfoot2");
+ t.tFoot = null;
+
+ assert_equals(t.tFoot, tfoot2);
+
+ var tfoot3 = document.getElementById("tfoot3");
+ t.deleteTFoot();
+
+ assert_equals(t.tFoot, tfoot3);
+
+ var tfoot = t.createTFoot();
+ assert_equals(t.tFoot, tfoot);
+ assert_equals(tfoot, tfoot3);
+
+ t.deleteTFoot();
+ assert_equals(t.tFoot, null);
+
+ var tbody2 = document.getElementById("tbody2");
+
+ tfoot = t.createTFoot();
+ assert_equals(t.tFoot, tfoot);
+
+ assert_equals(t.tFoot.previousSibling, tbody2);
+ assert_equals(t.tFoot.nextSibling, null);
+
+ t.deleteTFoot();
+ assert_equals(t.tFoot, null);
+
+ t.tFoot = tfoot;
+ assert_equals(t.tFoot, tfoot);
+
+ assert_equals(t.tFoot.previousSibling, tbody2);
+ assert_equals(t.tFoot.nextSibling, null);
+
+ assert_throws(new TypeError(), function(){
+ t.tFoot = document.createElement("div");
+ });
+
+ assert_throws("HierarchyRequestError", function(){
+ t.tFoot = document.createElement("thead");
+ });
+})
+</script>
diff --git a/testing/web-platform/tests/html/semantics/tabular-data/the-table-element/tHead.html b/testing/web-platform/tests/html/semantics/tabular-data/the-table-element/tHead.html
new file mode 100644
index 000000000..ea2ebf128
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/tabular-data/the-table-element/tHead.html
@@ -0,0 +1,66 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>tHead tests</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<table id="t">
+<caption id="tcaption"></caption><thead id="thead1"></thead><thead id="thead2"></thead><thead id="thead3"></thead><tbody id="tbody1"></tbody><tbody id="tbody2"></tbody><tfoot id="tfoot"></tfoot>
+</table>
+<table>
+<thead id="t2thead">
+<td>
+<table id="t2">
+</table>
+</table>
+<script>
+test(function() {
+ var t = document.getElementById("t");
+ var thead1 = document.getElementById("thead1");
+
+ assert_equals(t.tHead, thead1);
+
+ var thead2 = document.getElementById("thead2");
+ t.tHead = null;
+
+ assert_equals(t.tHead, thead2);
+
+ var thead3 = document.getElementById("thead3");
+ t.deleteTHead();
+
+ assert_equals(t.tHead, thead3);
+
+ var thead = t.createTHead();
+ assert_equals(t.tHead, thead);
+ assert_equals(thead, thead3);
+
+ t.deleteTHead();
+ assert_equals(t.tHead, null);
+
+ var tcaption = document.getElementById("tcaption");
+ var tbody1 = document.getElementById("tbody1");
+
+ thead = t.createTHead();
+ assert_equals(t.tHead, thead);
+
+ assert_equals(t.tHead.previousSibling, tcaption);
+ assert_equals(t.tHead.nextSibling, tbody1);
+
+ assert_throws(new TypeError(), function(){
+ t.tHead = document.createElement("div");
+ });
+
+ assert_throws("HierarchyRequestError", function(){
+ t.tHead = document.createElement("tbody");
+ });
+
+});
+
+test(function() {
+ var t2 = document.getElementById("t2");
+ var t2thead = document.getElementById("t2thead");
+
+ assert_throws("HierarchyRequestError", function() {
+ t2.tHead = t2thead;
+ });
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/tabular-data/the-table-element/table-insertRow.html b/testing/web-platform/tests/html/semantics/tabular-data/the-table-element/table-insertRow.html
new file mode 100644
index 000000000..8a9574ecd
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/tabular-data/the-table-element/table-insertRow.html
@@ -0,0 +1,56 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>HTMLTableElement.insertRow</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<script>
+test(function() {
+ var HTMLNS = "http://www.w3.org/1999/xhtml"
+ var parentEl = document.createElementNS(HTMLNS, "html:table")
+ assert_equals(parentEl.namespaceURI, HTMLNS, "Parent should be in the HTML namespace")
+ assert_equals(parentEl.prefix, "html", "Parent prefix should be html")
+ assert_equals(parentEl.localName, "table", "Parent local name should be table")
+ assert_equals(parentEl.tagName, "HTML:TABLE", "Parent tag name should be HTML:TABLE")
+
+ var row = parentEl.insertRow(-1)
+ assert_equals(row.namespaceURI, HTMLNS, "Row should be in the HTML namespace")
+ assert_equals(row.prefix, null, "Row prefix should be null")
+ assert_equals(row.localName, "tr", "Row local name should be tr")
+ assert_equals(row.tagName, "TR", "Row tag name should be TR")
+
+ var body = row.parentNode
+ assert_equals(body.namespaceURI, HTMLNS, "Body should be in the HTML namespace")
+ assert_equals(body.prefix, null, "Body prefix should be null")
+ assert_equals(body.localName, "tbody", "Body local name should be tr")
+ assert_equals(body.tagName, "TBODY", "Body tag name should be TR")
+
+ assert_array_equals(parentEl.childNodes, [body])
+ assert_array_equals(body.childNodes, [row])
+ assert_array_equals(parentEl.rows, [row])
+}, "insertRow should not copy prefixes")
+test(function() {
+ var table = document.createElement("table")
+ var head = table.appendChild(document.createElement("thead"))
+ assert_array_equals(table.rows, [])
+
+ var row = table.insertRow(-1)
+ var body = row.parentNode
+ assert_array_equals(table.childNodes, [head, body])
+ assert_array_equals(head.childNodes, [])
+ assert_array_equals(body.childNodes, [row])
+ assert_array_equals(table.rows, [row])
+}, "insertRow should insert into a tbody, not into a thead, if table.rows is empty")
+test(function() {
+ var table = document.createElement("table")
+ var foot = table.appendChild(document.createElement("tfoot"))
+ assert_array_equals(table.rows, [])
+
+ var row = table.insertRow(-1)
+ var body = row.parentNode
+ assert_array_equals(table.childNodes, [foot, body])
+ assert_array_equals(foot.childNodes, [])
+ assert_array_equals(body.childNodes, [row])
+ assert_array_equals(table.rows, [row])
+}, "insertRow should insert into a tbody, not into a tfoot, if table.rows is empty")
+</script>
diff --git a/testing/web-platform/tests/html/semantics/tabular-data/the-table-element/table-rows.html b/testing/web-platform/tests/html/semantics/tabular-data/the-table-element/table-rows.html
new file mode 100644
index 000000000..8bc23d5a7
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/tabular-data/the-table-element/table-rows.html
@@ -0,0 +1,234 @@
+<!DOCTYPE html>
+<title>HTMLTableElement.rows</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<script>
+function assert_nodelist_equals(actual, expected) {
+ assert_equals(actual.length, expected.length);
+
+ for (var i = 0; i < actual.length; ++i) {
+ assert_true(i in actual);
+ assert_true(actual.hasOwnProperty(i),
+ "property " + i + " expected to be present on the object");
+ assert_equals(actual.item(i), expected[i]);
+ assert_equals(actual[i], expected[i]);
+ }
+}
+
+function test_table_simple(group, table) {
+ var foo1 = group.appendChild(document.createElement("tr"));
+ foo1.id = "foo";
+ var bar1 = group.appendChild(document.createElement("tr"));
+ bar1.id = "bar";
+ var foo2 = group.appendChild(document.createElement("tr"));
+ foo2.id = "foo";
+ var bar2 = group.appendChild(document.createElement("tr"));
+ bar2.id = "bar";
+
+ assert_true(table.rows instanceof HTMLCollection, "table.rows should be a HTMLCollection.");
+ assert_nodelist_equals(table.rows, [foo1, bar1, foo2, bar2]);
+ assert_equals(table.rows.foo, foo1);
+ assert_equals(table.rows["foo"], foo1);
+ assert_equals(table.rows.namedItem("foo"), foo1);
+ assert_equals(table.rows.bar, bar1);
+ assert_equals(table.rows["bar"], bar1);
+ assert_equals(table.rows.namedItem("bar"), bar1);
+ assert_array_equals(Object.getOwnPropertyNames(table.rows), [
+ "0",
+ "1",
+ "2",
+ "3",
+ "foo",
+ "bar"
+ ]);
+}
+test(function() {
+ var table = document.createElement("table");
+ test_table_simple(table, table);
+}, "Children of table");
+test(function() {
+ var table = document.createElement("table");
+ var group = table.appendChild(document.createElement("thead"));
+ test_table_simple(group, table);
+}, "Children of thead");
+test(function() {
+ var table = document.createElement("table");
+ var group = table.appendChild(document.createElement("tbody"));
+ test_table_simple(group, table);
+}, "Children of tbody");
+test(function() {
+ var table = document.createElement("table");
+ var group = table.appendChild(document.createElement("tfoot"));
+ test_table_simple(group, table);
+}, "Children of tfoot");
+test(function() {
+ var table = document.createElement("table");
+ var orphan1 = table.appendChild(document.createElement("tr"));
+ orphan1.id = "orphan1";
+ var foot1 = table.appendChild(document.createElement("tfoot"));
+ var orphan2 = table.appendChild(document.createElement("tr"));
+ orphan2.id = "orphan2";
+ var foot2 = table.appendChild(document.createElement("tfoot"));
+ var orphan3 = table.appendChild(document.createElement("tr"));
+ orphan3.id = "orphan3";
+ var body1 = table.appendChild(document.createElement("tbody"));
+ var orphan4 = table.appendChild(document.createElement("tr"));
+ orphan4.id = "orphan4";
+ var body2 = table.appendChild(document.createElement("tbody"));
+ var orphan5 = table.appendChild(document.createElement("tr"));
+ orphan5.id = "orphan5";
+ var head1 = table.appendChild(document.createElement("thead"));
+ var orphan6 = table.appendChild(document.createElement("tr"));
+ orphan6.id = "orphan6";
+ var head2 = table.appendChild(document.createElement("thead"));
+ var orphan7 = table.appendChild(document.createElement("tr"));
+ orphan7.id = "orphan7";
+
+ var foot1row1 = foot1.appendChild(document.createElement("tr"));
+ foot1row1.id = "foot1row1";
+ var foot1row2 = foot1.appendChild(document.createElement("tr"));
+ foot1row2.id = "foot1row2";
+ var foot2row1 = foot2.appendChild(document.createElement("tr"));
+ foot2row1.id = "foot2row1";
+ var foot2row2 = foot2.appendChild(document.createElement("tr"));
+ foot2row2.id = "foot2row2";
+
+ var body1row1 = body1.appendChild(document.createElement("tr"));
+ body1row1.id = "body1row1";
+ var body1row2 = body1.appendChild(document.createElement("tr"));
+ body1row2.id = "body1row2";
+ var body2row1 = body2.appendChild(document.createElement("tr"));
+ body2row1.id = "body2row1";
+ var body2row2 = body2.appendChild(document.createElement("tr"));
+ body2row2.id = "body2row2";
+
+ var head1row1 = head1.appendChild(document.createElement("tr"));
+ head1row1.id = "head1row1";
+ var head1row2 = head1.appendChild(document.createElement("tr"));
+ head1row2.id = "head1row2";
+ var head2row1 = head2.appendChild(document.createElement("tr"));
+ head2row1.id = "head2row1";
+ var head2row2 = head2.appendChild(document.createElement("tr"));
+ head2row2.id = "head2row2";
+
+ // These elements should not end up in any collection.
+ table.appendChild(document.createElement("div"))
+ .appendChild(document.createElement("tr"));
+ foot1.appendChild(document.createElement("div"))
+ .appendChild(document.createElement("tr"));
+ body1.appendChild(document.createElement("div"))
+ .appendChild(document.createElement("tr"));
+ head1.appendChild(document.createElement("div"))
+ .appendChild(document.createElement("tr"));
+ table.appendChild(document.createElementNS("http://example.com/test", "tr"));
+ foot1.appendChild(document.createElementNS("http://example.com/test", "tr"));
+ body1.appendChild(document.createElementNS("http://example.com/test", "tr"));
+ head1.appendChild(document.createElementNS("http://example.com/test", "tr"));
+
+ assert_true(table.rows instanceof HTMLCollection, "table.rows should be a HTMLCollection.");
+ assert_nodelist_equals(table.rows, [
+ // thead
+ head1row1,
+ head1row2,
+ head2row1,
+ head2row2,
+
+ // tbody + table
+ orphan1,
+ orphan2,
+ orphan3,
+ body1row1,
+ body1row2,
+ orphan4,
+ body2row1,
+ body2row2,
+ orphan5,
+ orphan6,
+ orphan7,
+
+ // tfoot
+ foot1row1,
+ foot1row2,
+ foot2row1,
+ foot2row2
+ ]);
+ assert_array_equals(Object.getOwnPropertyNames(table.rows), [
+ "0",
+ "1",
+ "2",
+ "3",
+ "4",
+ "5",
+ "6",
+ "7",
+ "8",
+ "9",
+ "10",
+ "11",
+ "12",
+ "13",
+ "14",
+ "15",
+ "16",
+ "17",
+ "18",
+ "head1row1",
+ "head1row2",
+ "head2row1",
+ "head2row2",
+ "orphan1",
+ "orphan2",
+ "orphan3",
+ "body1row1",
+ "body1row2",
+ "orphan4",
+ "body2row1",
+ "body2row2",
+ "orphan5",
+ "orphan6",
+ "orphan7",
+ "foot1row1",
+ "foot1row2",
+ "foot2row1",
+ "foot2row2"
+ ]);
+
+ var ids = [
+ "orphan1",
+ "orphan2",
+ "orphan3",
+ "orphan4",
+ "orphan5",
+ "orphan6",
+ "orphan7",
+ "foot1row1",
+ "foot1row2",
+ "foot2row1",
+ "foot2row2",
+ "body1row1",
+ "body1row2",
+ "body2row1",
+ "body2row2",
+ "head1row1",
+ "head1row2",
+ "head2row1",
+ "head2row2"
+ ];
+ ids.forEach(function(id) {
+ assert_equals(table.rows.namedItem(id).id, id);
+ assert_true(id in table.rows);
+ assert_equals(table.rows[id].id, id);
+ assert_true(id in table.rows);
+ });
+ while (table.firstChild) {
+ table.removeChild(table.firstChild);
+ }
+ ids.forEach(function(id) {
+ assert_equals(table.rows.namedItem(id), null);
+ assert_false(id in table.rows);
+ assert_equals(table.rows[id], undefined);
+ assert_false(id in table.rows);
+ });
+}, "Complicated case");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/tabular-data/the-tbody-element/.gitkeep b/testing/web-platform/tests/html/semantics/tabular-data/the-tbody-element/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/tabular-data/the-tbody-element/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/tabular-data/the-tbody-element/deleteRow.html b/testing/web-platform/tests/html/semantics/tabular-data/the-tbody-element/deleteRow.html
new file mode 100644
index 000000000..c81abd826
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/tabular-data/the-tbody-element/deleteRow.html
@@ -0,0 +1,54 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>HTMLTableSectionElement#deleteRow</title>
+<link rel="author" title="Intel" href="http://www.intel.com/">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<div id ="log"></div>
+
+<table>
+ <tbody id="testBody">
+ <tr><td>ABCDEF</td></tr>
+ <tr><td>12345</td></tr>
+ <tr><td>ABC12345DEF</td></tr>
+ </tbody>
+</table>
+
+<script>
+
+var tbody = document.getElementById("testBody");
+
+test(function () {
+ tbody.deleteRow(0);
+ assert_equals(tbody.rows.length, 2);
+ assert_equals(tbody.rows[0].childNodes[0].innerHTML, "12345");
+}, "HTMLTableSectionElement deleteRow(0)");
+
+test(function () {
+ tbody.deleteRow(-1);
+ assert_equals(tbody.rows.length, 1);
+ assert_equals(tbody.rows[0].childNodes[0].innerHTML, "12345");
+}, "HTMLTableSectionElement deleteRow(-1)");
+
+test(function () {
+ assert_throws("IndexSizeError", function () {
+ tbody.deleteRow(tbody.rows.length);
+ });
+}, "HTMLTableSectionElement deleteRow(rows.length)");
+
+test(function () {
+ assert_throws("IndexSizeError", function () {
+ tbody.deleteRow(-2);
+ });
+}, "HTMLTableSectionElement deleteRow(-2)");
+
+test(function () {
+ assert_equals(tbody.rows.length, 1);
+ tbody.deleteRow(-1);
+ assert_equals(tbody.rows.length, 0);
+ tbody.deleteRow(-1);
+ assert_equals(tbody.rows.length, 0);
+}, "HTMLTableSectionElement deleteRow(-1) with no rows");
+
+</script>
diff --git a/testing/web-platform/tests/html/semantics/tabular-data/the-tbody-element/insertRow.html b/testing/web-platform/tests/html/semantics/tabular-data/the-tbody-element/insertRow.html
new file mode 100644
index 000000000..4c13db7aa
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/tabular-data/the-tbody-element/insertRow.html
@@ -0,0 +1,56 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>HTMLTableSectionElement#insertRow</title>
+<link rel="author" title="Intel" href="http://www.intel.com/">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<div id ="log"></div>
+
+<table>
+ <tbody id="testBody">
+ <tr><td>ABCDEF</td></tr>
+ </tbody>
+</table>
+
+<script>
+
+var tbody = document.getElementById("testBody");
+
+test(function () {
+ var trEle = tbody.insertRow(0);
+ assert_equals(tbody.rows[0], trEle);
+ assert_equals(tbody.rows.length, 2);
+}, "HTMLTableSectionElement insertRow(0)");
+
+test(function () {
+ var trEle = tbody.insertRow(-1);
+ assert_equals(tbody.rows[tbody.rows.length - 1], trEle);
+ assert_equals(tbody.rows.length, 3);
+}, "HTMLTableSectionElement insertRow(-1)");
+
+test(function () {
+ var trEle = tbody.insertRow();
+ assert_equals(tbody.rows[tbody.rows.length - 1], trEle);
+ assert_equals(tbody.rows.length, 4);
+}, "HTMLTableSectionElement insertRow()");
+
+test(function () {
+ var trEle = tbody.insertRow(tbody.rows.length);
+ assert_equals(tbody.rows[tbody.rows.length - 1], trEle);
+ assert_equals(tbody.rows.length, 5);
+}, "HTMLTableSectionElement insertRow(rows.length)");
+
+test(function () {
+ assert_throws("IndexSizeError", function () {
+ tbody.insertRow(-2);
+ });
+}, "HTMLTableSectionElement insertRow(-2)");
+
+test(function () {
+ assert_throws("IndexSizeError", function () {
+ tbody.insertRow(tbody.rows.length + 1);
+ });
+}, "HTMLTableSectionElement insertRow(rows.length + 1)");
+
+</script>
diff --git a/testing/web-platform/tests/html/semantics/tabular-data/the-tbody-element/rows.html b/testing/web-platform/tests/html/semantics/tabular-data/the-tbody-element/rows.html
new file mode 100644
index 000000000..eb155de77
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/tabular-data/the-tbody-element/rows.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>'tbody' element, 'rows' attribute</title>
+<link rel="author" title="Corey Farwell" href="mailto:coreyf@rwell.org">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/semantics/tabular-data/html-table-section-element.js"></script>
+
+<div id ="log"></div>
+
+<script>
+test(function () {
+ testRowsAttribute('tbody');
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/tabular-data/the-td-element/.gitkeep b/testing/web-platform/tests/html/semantics/tabular-data/the-td-element/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/tabular-data/the-td-element/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/tabular-data/the-tfoot-element/.gitkeep b/testing/web-platform/tests/html/semantics/tabular-data/the-tfoot-element/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/tabular-data/the-tfoot-element/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/tabular-data/the-tfoot-element/rows.html b/testing/web-platform/tests/html/semantics/tabular-data/the-tfoot-element/rows.html
new file mode 100644
index 000000000..fe70d6f28
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/tabular-data/the-tfoot-element/rows.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>'tfoot' element, 'rows' attribute</title>
+<link rel="author" title="Corey Farwell" href="mailto:coreyf@rwell.org">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/semantics/tabular-data/html-table-section-element.js"></script>
+
+<div id ="log"></div>
+
+<script>
+test(function () {
+ testRowsAttribute('tfoot');
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/tabular-data/the-th-element/.gitkeep b/testing/web-platform/tests/html/semantics/tabular-data/the-th-element/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/tabular-data/the-th-element/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/tabular-data/the-thead-element/.gitkeep b/testing/web-platform/tests/html/semantics/tabular-data/the-thead-element/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/tabular-data/the-thead-element/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/tabular-data/the-thead-element/rows.html b/testing/web-platform/tests/html/semantics/tabular-data/the-thead-element/rows.html
new file mode 100644
index 000000000..7830281a0
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/tabular-data/the-thead-element/rows.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>'thead' element, 'rows' attribute</title>
+<link rel="author" title="Corey Farwell" href="mailto:coreyf@rwell.org">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/html/semantics/tabular-data/html-table-section-element.js"></script>
+
+<div id ="log"></div>
+
+<script>
+test(function () {
+ testRowsAttribute('thead');
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/tabular-data/the-tr-element/.gitkeep b/testing/web-platform/tests/html/semantics/tabular-data/the-tr-element/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/tabular-data/the-tr-element/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/tabular-data/the-tr-element/cells.html b/testing/web-platform/tests/html/semantics/tabular-data/the-tr-element/cells.html
new file mode 100644
index 000000000..2678d3b1c
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/tabular-data/the-tr-element/cells.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>HTMLTableRowElement#cells</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<div id="log"></div>
+
+<table>
+ <tr id="testTr">
+ <td>First</td>
+ <div><td>Second</td></div>
+ <td>Third
+ <table>
+ <tr><td>Nested first</td></tr>
+ </table>
+ </td>
+ <img>
+ </tr>
+</table>
+<script>
+var tr = document.getElementById("testTr");
+
+test(function () {
+ tr.insertBefore(document.createElementNS("foo", "td"), tr.children[1]);
+ assert_array_equals(tr.cells, [tr.children[0], tr.children[2], tr.children[3]]);
+}, "HTMLTableRowElement cells ignores nested tables and non-HTML elements");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/tabular-data/the-tr-element/deleteCell.html b/testing/web-platform/tests/html/semantics/tabular-data/the-tr-element/deleteCell.html
new file mode 100644
index 000000000..1400d32e1
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/tabular-data/the-tr-element/deleteCell.html
@@ -0,0 +1,54 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>HTMLTableRowElement#deleteCell</title>
+<link rel="author" title="Intel" href="http://www.intel.com/">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<div id="log"></div>
+
+<table>
+ <tr id="testTr">
+ <td>ABCDE</td>
+ <td>12345</td>
+ <td>ABC12</td>
+ </tr>
+</table>
+
+<script>
+
+var tr = document.getElementById("testTr");
+
+test(function () {
+ tr.deleteCell(0);
+ assert_equals(tr.cells[0].innerHTML, "12345");
+ assert_equals(tr.cells.length, 2);
+}, "HTMLTableRowElement deleteCell(0)");
+
+test(function () {
+ tr.deleteCell(-1);
+ assert_equals(tr.cells[tr.cells.length - 1].innerHTML, "12345");
+ assert_equals(tr.cells.length, 1);
+}, "HTMLTableRowElement deleteCell(-1)");
+
+test(function () {
+ assert_throws("IndexSizeError", function () {
+ tr.deleteCell(-2);
+ });
+}, "HTMLTableRowElement deleteCell(-2)");
+
+test(function () {
+ assert_throws("IndexSizeError", function () {
+ tr.deleteCell(tr.cells.length);
+ });
+}, "HTMLTableRowElement deleteCell(cells.length)");
+
+test(function () {
+ assert_equals(tr.cells.length, 1);
+ tr.deleteCell(-1);
+ assert_equals(tr.cells.length, 0);
+ tr.deleteCell(-1);
+ assert_equals(tr.cells.length, 0);
+}, "HTMLTableRowElement deleteCell(-1) with no cells");
+
+</script>
diff --git a/testing/web-platform/tests/html/semantics/tabular-data/the-tr-element/insertCell.html b/testing/web-platform/tests/html/semantics/tabular-data/the-tr-element/insertCell.html
new file mode 100644
index 000000000..07eac1efb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/tabular-data/the-tr-element/insertCell.html
@@ -0,0 +1,55 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>HTMLTableRowElement#insertCell</title>
+<link rel="author" title="Intel" href="http://www.intel.com/">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<div id="log"></div>
+
+<table>
+ <tr id="testTr"></tr>
+</table>
+
+<script>
+
+var tr = document.getElementById("testTr");
+
+test(function () {
+ var tdEle = tr.insertCell(0);
+ assert_equals(tr.cells[0], tdEle);
+ assert_equals(tr.cells.length, 1);
+}, "HTMLTableRowElement insertCell(0)");
+
+test(function () {
+ var tdEle = tr.insertCell(-1);
+ assert_equals(tr.cells[tr.cells.length - 1], tdEle);
+ assert_equals(tr.cells.length, 2);
+}, "HTMLTableRowElement insertCell(-1)");
+
+
+test(function () {
+ var tdEle = tr.insertCell(tr.cells.length);
+ assert_equals(tr.cells[tr.cells.length - 1], tdEle);
+ assert_equals(tr.cells.length, 3);
+}, "HTMLTableRowElement insertCell(cells.length)");
+
+test(function () {
+ var tdEle = tr.insertCell();
+ assert_equals(tr.cells[tr.cells.length - 1], tdEle);
+ assert_equals(tr.cells.length, 4);
+}, "HTMLTableRowElement insertCell()");
+
+test(function () {
+ assert_throws("IndexSizeError", function () {
+ tr.insertCell(-2);
+ });
+}, "HTMLTableRowElement insertCell(-2)");
+
+test(function () {
+ assert_throws("IndexSizeError", function () {
+ tr.insertCell(tr.cells.length + 1);
+ });
+}, "HTMLTableRowElement insertCell(cells.length + 1)");
+
+</script>
diff --git a/testing/web-platform/tests/html/semantics/tabular-data/the-tr-element/rowIndex.html b/testing/web-platform/tests/html/semantics/tabular-data/the-tr-element/rowIndex.html
new file mode 100644
index 000000000..117712563
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/tabular-data/the-tr-element/rowIndex.html
@@ -0,0 +1,77 @@
+<!DOCTYPE html>
+<title>HTMLTableRowElement.rowIndex</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<script>
+test(function() {
+ var row = document.createElement("table")
+ .appendChild(document.createElement("div"))
+ .appendChild(document.createElement("tr"));
+ assert_equals(row.rowIndex, -1);
+});
+test(function() {
+ var row = document.createElement("table")
+ .appendChild(document.createElement("thead"))
+ .appendChild(document.createElement("tr"));
+ assert_equals(row.rowIndex, 0);
+});
+test(function() {
+ var row = document.createElement("table")
+ .appendChild(document.createElement("tbody"))
+ .appendChild(document.createElement("tr"));
+ assert_equals(row.rowIndex, 0);
+});
+test(function() {
+ var row = document.createElement("table")
+ .appendChild(document.createElement("tfoot"))
+ .appendChild(document.createElement("tr"));
+ assert_equals(row.rowIndex, 0);
+});
+test(function() {
+ var row = document.createElement("table")
+ .appendChild(document.createElement("tr"));
+ assert_equals(row.rowIndex, 0);
+});
+test(function() {
+ var row = document.createElementNS("", "table")
+ .appendChild(document.createElement("thead"))
+ .appendChild(document.createElement("tr"));
+ assert_equals(row.rowIndex, -1);
+});
+test(function() {
+ var row = document.createElementNS("", "table")
+ .appendChild(document.createElement("tbody"))
+ .appendChild(document.createElement("tr"));
+ assert_equals(row.rowIndex, -1);
+});
+test(function() {
+ var row = document.createElementNS("", "table")
+ .appendChild(document.createElement("tfoot"))
+ .appendChild(document.createElement("tr"));
+ assert_equals(row.rowIndex, -1);
+});
+test(function() {
+ var row = document.createElementNS("", "table")
+ .appendChild(document.createElement("tr"));
+ assert_equals(row.rowIndex, -1);
+});
+test(function() {
+ var row = document.createElement("table")
+ .appendChild(document.createElementNS("", "thead"))
+ .appendChild(document.createElement("tr"));
+ assert_equals(row.rowIndex, -1);
+});
+test(function() {
+ var row = document.createElement("table")
+ .appendChild(document.createElementNS("", "tbody"))
+ .appendChild(document.createElement("tr"));
+ assert_equals(row.rowIndex, -1);
+});
+test(function() {
+ var row = document.createElement("table")
+ .appendChild(document.createElementNS("", "tfoot"))
+ .appendChild(document.createElement("tr"));
+ assert_equals(row.rowIndex, -1);
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/tabular-data/the-tr-element/sectionRowIndex.html b/testing/web-platform/tests/html/semantics/tabular-data/the-tr-element/sectionRowIndex.html
new file mode 100644
index 000000000..ef5366739
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/tabular-data/the-tr-element/sectionRowIndex.html
@@ -0,0 +1,130 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>HTMLTableRowElement.sectionRowIndex</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id="log"></div>
+<table>
+ <thead>
+ <tr id="ht1"></tr>
+ </thead>
+ <tr id="t1"></tr>
+ <tr id="t2">
+ <td>
+ <table>
+ <thead>
+ <tr id="nht1"></tr>
+ </thead>
+ <tr></tr>
+ <tr id="nt1"></tr>
+ <tbody>
+ <tr id="nbt1"></tr>
+ </tbody>
+ </table>
+ </td>
+ </tr>
+ <tbody>
+ <tr></tr>
+ <tr id="bt1"></tr>
+ </tbody>
+ <tfoot>
+ <tr></tr>
+ <tr></tr>
+ <tr id="ft1"></tr>
+ </tfoot>
+</table>
+
+<script>
+test(function() {
+ var tHeadRow = document.getElementById('ht1');
+ assert_equals(tHeadRow.sectionRowIndex, 0);
+}, "Row in thead in HTML");
+
+test(function() {
+ var tRow1 = document.getElementById('t1');
+ assert_equals(tRow1.sectionRowIndex, 0);
+}, "Row in implicit tbody in HTML");
+
+test(function() {
+ var tRow2 = document.getElementById('t2');
+ assert_equals(tRow2.sectionRowIndex, 1);
+}, "Other row in implicit tbody in HTML");
+
+test(function() {
+ var tBodyRow = document.getElementById('bt1');
+ assert_equals(tBodyRow.sectionRowIndex, 1);
+}, "Row in explicit tbody in HTML");
+
+test(function() {
+ var tFootRow = document.getElementById('ft1');
+ assert_equals(tFootRow.sectionRowIndex, 2);
+}, "Row in tfoot in HTML");
+
+test(function() {
+ var childHeadRow = document.getElementById('nht1');
+ assert_equals(childHeadRow.sectionRowIndex, 0);
+}, "Row in thead in nested table in HTML");
+
+test(function() {
+ var childRow = document.getElementById('nt1');
+ assert_equals(childRow.sectionRowIndex, 1);
+}, "Row in implicit tbody in nested table in HTML");
+
+test(function() {
+ var childBodyRow = document.getElementById('nbt1');
+ assert_equals(childBodyRow.sectionRowIndex, 0);
+}, "Row in explicit tbody in nested table in HTML");
+
+/* script create element test */
+var mkTrElm = function (elst) {
+ var elm = document.createElement("table");
+ elst.forEach(function(item) {
+ elm = elm.appendChild(document.createElement(item));
+ });
+ return elm.appendChild(document.createElement("tr"));
+};
+
+test(function() {
+ assert_equals(mkTrElm([]).sectionRowIndex, 0);
+}, "Row in script-created table");
+
+test(function() {
+ assert_equals(mkTrElm(["div"]).sectionRowIndex, -1);
+}, "Row in script-created div in table");
+
+test(function() {
+ assert_equals(mkTrElm(["thead"]).sectionRowIndex, 0);
+}, "Row in script-created thead in table");
+
+test(function() {
+ assert_equals(mkTrElm(["tbody"]).sectionRowIndex, 0);
+}, "Row in script-created tbody in table");
+
+test(function() {
+ assert_equals(mkTrElm(["tfoot"]).sectionRowIndex, 0);
+}, "Row in script-created tfoot in table");
+
+test(function() {
+ assert_equals(mkTrElm(["tbody", "tr"]).sectionRowIndex, -1);
+}, "Row in script-created tr in tbody in table");
+
+test(function() {
+ assert_equals(mkTrElm(["tbody", "tr", "td"]).sectionRowIndex, -1);
+}, "Row in script-created td in tr in tbody in table");
+
+test(function() {
+ assert_equals(mkTrElm(["tbody", "tr", "td", "table"]).sectionRowIndex, 0);
+}, "Row in script-created nested table");
+
+test(function() {
+ assert_equals(mkTrElm(["tbody", "tr", "td", "table", "thead"]).sectionRowIndex, 0);
+}, "Row in script-created thead in nested table");
+
+test(function() {
+ assert_equals(mkTrElm(["tbody", "tr", "td", "table", "tbody"]).sectionRowIndex, 0);
+}, "Row in script-created tbody in nested table");
+
+test(function() {
+ assert_equals(mkTrElm(["tbody", "tr", "td", "table", "tfoot"]).sectionRowIndex, 0);
+}, "Row in script-created tfoot in nested table");
+</script>
diff --git a/testing/web-platform/tests/html/semantics/text-level-semantics/.gitkeep b/testing/web-platform/tests/html/semantics/text-level-semantics/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/text-level-semantics/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/text-level-semantics/historical.html b/testing/web-platform/tests/html/semantics/text-level-semantics/historical.html
new file mode 100644
index 000000000..9de09fe5b
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/text-level-semantics/historical.html
@@ -0,0 +1,32 @@
+<!doctype html>
+<title>Historical text-level element features should not be supported</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<script>
+function t(property, tagNames) {
+ if (typeof tagNames === "string") {
+ tagNames = [tagNames];
+ }
+ tagNames.forEach(function(tagName) {
+ test(function() {
+ assert_false(property in document.createElement(tagName));
+ }, tagName + '.' + property + ' should not be supported');
+ });
+}
+
+// <area> and <link> are in other sections in the spec, but we'll test them here together with <a>
+
+// removed in https://github.com/whatwg/html/commit/790479ab1ba143efc27d1f92cd0465627df48fb0
+t('hreflang', 'area');
+t('type', 'area');
+
+// renamed to dateTime in https://github.com/whatwg/html/commit/8b6732237c7021cd61e3c3463146234ca8ce5bad
+t('datetime', 'time');
+
+// removed in https://github.com/whatwg/html/commit/66fcb2357f205448fe2f40d7834a1e8ea2ed283b
+t('media', ['a', 'area']);
+
+// renamed to noreferrer in https://github.com/whatwg/html/commit/6a34274e99593e767ae99744a6c38a19489915c6
+t('noreferer', ['link', 'a', 'area']);
+</script>
diff --git a/testing/web-platform/tests/html/semantics/text-level-semantics/the-a-element/.gitkeep b/testing/web-platform/tests/html/semantics/text-level-semantics/the-a-element/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/text-level-semantics/the-a-element/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/text-level-semantics/the-a-element/a-stringifier.html b/testing/web-platform/tests/html/semantics/text-level-semantics/the-a-element/a-stringifier.html
new file mode 100644
index 000000000..fb0780dee
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/text-level-semantics/the-a-element/a-stringifier.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<title>HTMLAnchorElement stringifier</title>
+<link rel="author" title="Ms2ger" href="mailto:ms2ger@gmail.com">
+<link rel="help" href="https://heycam.github.io/webidl/#es-stringifier">
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script src=/common/stringifiers.js></script>
+<div id=log></div>
+<script>
+test(function() {
+ test_stringifier_attribute(document.createElement("a"), "href", false);
+ var a = document.createElement("a");
+ a.setAttribute("href", "foo");
+ test_stringifier_attribute(a, "href", false);
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/text-level-semantics/the-a-element/a.text-getter-01.html b/testing/web-platform/tests/html/semantics/text-level-semantics/the-a-element/a.text-getter-01.html
new file mode 100644
index 000000000..e0bb73be0
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/text-level-semantics/the-a-element/a.text-getter-01.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<title>HTMLAnchorElement.text getting</title>
+<link rel="author" title="Ms2ger" href="mailto:ms2ger@gmail.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-a-text">
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<div id=log></div>
+<script>var b</script>
+<div id="test">
+<a href="a">a b c </a>
+<a href="b">a <!--b-->b c </a>
+<a href="c">a <b>b</b> c </a>
+<a href="d">a <script>b</script> c </a>
+<script>
+var e = document.getElementById("test")
+ .appendChild(document.createElement("a"));
+e.href = "d";
+e.appendChild(document.createTextNode("a "));
+e.appendChild(document.createTextNode("b "));
+e.appendChild(document.createTextNode("c "));
+</script>
+</div>
+<script>
+test(function() {
+ var list = document.getElementById("test")
+ .getElementsByTagName("a");
+ for (var i = 0, il = list.length; i < il; ++i) {
+ test(function() {
+ assert_equals(list[i].text, list[i].textContent);
+ assert_equals(list[i].text, "a b c ");
+ }, "Test for anchor " + i);
+ }
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/text-level-semantics/the-a-element/a.text-setter-01.html b/testing/web-platform/tests/html/semantics/text-level-semantics/the-a-element/a.text-setter-01.html
new file mode 100644
index 000000000..879a9e3d0
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/text-level-semantics/the-a-element/a.text-setter-01.html
@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<title>HTMLAnchorElement.text setting</title>
+<link rel="author" title="Ms2ger" href="mailto:ms2ger@gmail.com">
+<link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-a-text">
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<div id=log></div>
+<div id="test">
+<a href="a">a b c</a>
+<a href="b">a <!--b--> c</a>
+<a href="c">a <b>b</b> c</a>
+<script>
+var d = document.getElementById("test")
+ .appendChild(document.createElement("a"));
+d.href = "d";
+d.appendChild(document.createTextNode("a "));
+d.appendChild(document.createTextNode("b "));
+d.appendChild(document.createTextNode("c "));
+</script>
+</div>
+<script>
+test(function() {
+ var list = document.getElementById("test")
+ .getElementsByTagName("a");
+ for (var i = 0, il = list.length; i < il; ++i) {
+ test(function() {
+ list[i].text = "x";
+ assert_equals(list[i].text, "x");
+ assert_equals(list[i].textContent, "x");
+ assert_equals(list[i].firstChild.data, "x");
+ assert_equals(list[i].childNodes.length, 1);
+
+ list[i].textContent = "y";
+ assert_equals(list[i].text, "y");
+ assert_equals(list[i].textContent, "y");
+ assert_equals(list[i].firstChild.data, "y");
+ assert_equals(list[i].childNodes.length, 1);
+ }, "Test for anchor " + i);
+ }
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/text-level-semantics/the-abbr-element/.gitkeep b/testing/web-platform/tests/html/semantics/text-level-semantics/the-abbr-element/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/text-level-semantics/the-abbr-element/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/text-level-semantics/the-b-element/.gitkeep b/testing/web-platform/tests/html/semantics/text-level-semantics/the-b-element/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/text-level-semantics/the-b-element/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/.gitkeep b/testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-auto-dir-default-ref.html b/testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-auto-dir-default-ref.html
new file mode 100644
index 000000000..eff61bb41
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-auto-dir-default-ref.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <link rel="author" title="Aharon Lanin" href="mailto:aharon@google.com">
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com">
+ <style>
+ body{
+ font-size:2em;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 500px;
+ margin: 20px;
+ }
+ .comments { display: none; }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="comments">
+ Key to entities used below:
+ &#x05D0; ... &#x05D5; - The first six Hebrew letters (strongly RTL).
+ &#x202D; - The LRO (left-to-right override) formatting character.
+ &#x202C; - The PDF (pop directional formatting) formatting character; closes LRO.
+ </div>
+ <div class="test">
+ <div dir="ltr">&#x202D;[:)], [+- a &#x05D1;], [d &#x05D2; 1]...&#x202C;</div>
+ <div dir="rtl">&#x202D;...[d &#x05D2; 1] ,[+- a &#x05D1;] ,[:)]&#x202C;</div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">&#x202D;[:)], [+- a &#x05D1;], [d &#x05D2; 1]...&#x202C;</div>
+ <div dir="rtl">&#x202D;...[d &#x05D2; 1] ,[+- a &#x05D1;] ,[:)]&#x202C;</div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-auto-dir-default.html b/testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-auto-dir-default.html
new file mode 100644
index 000000000..e658500a4
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-auto-dir-default.html
@@ -0,0 +1,46 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8"/>
+ <title>HTML Test: BDI: has dir=auto by default</title>
+ <link rel="match" href="bdi-auto-dir-default-ref.html"/>
+ <link rel="author" title="Aharon Lanin" href="mailto:aharon@google.com"/>
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com"/>
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-bdi-element"/>
+ <meta name="assert" content="
+ 'The dir global attribute defaults to auto on this element (it never inherits from the parent
+ element like with other elements).'"/>
+ <style>
+ body{
+ font-size:2em;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 500px;
+ margin: 20px;
+ }
+ .comments { display: none; }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="comments">
+ Key to entities used below:
+ &#x05D0; ... &#x05D5; - The first six Hebrew letters (strongly RTL).
+ &#x202D; - The LRO (left-to-right override) formatting character.
+ &#x202C; - The PDF (pop directional formatting) formatting character; closes LRO.
+ In each DIV of the test:
+ - the first BDI, having no characters with strong direction, should be LTR by default;
+ - the second BDI, having an LTR character first, should be LTR by default;
+ - the third BDI, having an RTL character first, should be RTL by default.
+ </div>
+ <div class="test">
+ <div dir="ltr"><bdi>[:)]</bdi>, <bdi>[+- a &#x05D1;]</bdi>, <bdi>[1 &#x05D2; d]</bdi>...</div>
+ <div dir="rtl"><bdi>[:)]</bdi>, <bdi>[+- a &#x05D1;]</bdi>, <bdi>[1 &#x05D2; d]</bdi>...</div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">&#x202D;[:)], [+- a &#x05D1;], [d &#x05D2; 1]...&#x202C;</div>
+ <div dir="rtl">&#x202D;...[d &#x05D2; 1] ,[+- a &#x05D1;] ,[:)]&#x202C;</div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-missing-pdf-ref.html b/testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-missing-pdf-ref.html
new file mode 100644
index 000000000..b4d44c510
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-missing-pdf-ref.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <link rel="author" title="Aharon Lanin" href="mailto:aharon@google.com">
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com">
+ <style>
+ body{
+ font-size:2em;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments { display: none; }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="comments">
+ Key to entities used below:
+ &#x05D0; ... &#x05D5; - The first six Hebrew letters (strongly RTL).
+ &#x202D; - The LRO (left-to-right override) formatting character.
+ &#x202C; - The PDF (pop directional formatting) formatting character; closes LRO.
+ </div>
+ <div class="test">
+ <div dir="ltr">&#x202D;cb&#x05D0;de...&#x202C;</div>
+ <div dir="ltr">&#x202D;cb&#x05D0;de...&#x202C;</div>
+ <div dir="ltr">&#x202D;cb&#x05D0;de...&#x202C;</div>
+ <div dir="rtl">&#x202D;...&#x05D4;&#x05D3;a&#x05D1;&#x05D2;&#x202C;</div>
+ <div dir="rtl">&#x202D;...&#x05D4;&#x05D3;a&#x05D1;&#x05D2;&#x202C;</div>
+ <div dir="rtl">&#x202D;...&#x05D4;&#x05D3;a&#x05D1;&#x05D2;&#x202C;</div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">&#x202D;cb&#x05D0;de...&#x202C;</div>
+ <div dir="ltr">&#x202D;cb&#x05D0;de...&#x202C;</div>
+ <div dir="ltr">&#x202D;cb&#x05D0;de...&#x202C;</div>
+ <div dir="rtl">&#x202D;...&#x05D4;&#x05D3;a&#x05D1;&#x05D2;&#x202C;</div>
+ <div dir="rtl">&#x202D;...&#x05D4;&#x05D3;a&#x05D1;&#x05D2;&#x202C;</div>
+ <div dir="rtl">&#x202D;...&#x05D4;&#x05D3;a&#x05D1;&#x05D2;&#x202C;</div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-missing-pdf.html b/testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-missing-pdf.html
new file mode 100644
index 000000000..1ce9da6b7
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-missing-pdf.html
@@ -0,0 +1,56 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8"/>
+ <title>HTML Test: BDI: neutral when contains LRO or RLO without PDF</title>
+ <link rel="match" href="bdi-neutral-missing-pdf-ref.html"/>
+ <link rel="author" title="Aharon Lanin" href="mailto:aharon@google.com"/>
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com"/>
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-bdi-element"/>
+ <meta name="assert" content="
+ 'For the purposes of applying the bidirectional algorithm to the paragraph-level
+ container that a bdi element finds itself within, the bdi element must be treated
+ like a U+FFFC OBJECT REPLACEMENT CHARACTER.'
+ Thus, if a BDI contains LRO or RLO characters lacking a matching PDF, these must not affect
+ the visual ordering of the content outside the BDI."/>
+ <style>
+ body{
+ font-size:2em;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments { display: none; }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="comments">
+ Key to entities used below:
+ &#x05D0; ... &#x05D5; - The first six Hebrew letters (strongly RTL).
+ &#x202D; - The LRO (left-to-right override) formatting character.
+ &#x202E; - the RLO (right-to-left-override) formatting character.
+ &#x202C; - The PDF (pop directional formatting) formatting character; closes LRO and RLO.
+ If the BDI in the test's first DIV were a SPAN, the RLO it contains, not being closed by a
+ PDF, would visually reorder the de into ed.
+ </div>
+ <div class="test">
+ <div dir="ltr"><bdi>&#x05D0;&#x202E;bc</bdi>de...</div>
+ <div dir="ltr"><bdi dir="ltr">&#x05D0;&#x202E;bc</bdi>de...</div>
+ <div dir="ltr"><bdi dir="rtl">&#x05D0;&#x202E;bc</bdi>de...</div>
+ <div dir="rtl"><bdi>a&#x202D;&#x05D1;&#x05D2;</bdi>&#x05D3;&#x05D4;...</div>
+ <div dir="rtl"><bdi dir="ltr">a&#x202D;&#x05D1;&#x05D2;</bdi>&#x05D3;&#x05D4;...</div>
+ <div dir="rtl"><bdi dir="rtl">a&#x202D;&#x05D1;&#x05D2;</bdi>&#x05D3;&#x05D4;...</div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">&#x202D;cb&#x05D0;de...&#x202C;</div>
+ <div dir="ltr">&#x202D;cb&#x05D0;de...&#x202C;</div>
+ <div dir="ltr">&#x202D;cb&#x05D0;de...&#x202C;</div>
+ <div dir="rtl">&#x202D;...&#x05D4;&#x05D3;a&#x05D1;&#x05D2;&#x202C;</div>
+ <div dir="rtl">&#x202D;...&#x05D4;&#x05D3;a&#x05D1;&#x05D2;&#x202C;</div>
+ <div dir="rtl">&#x202D;...&#x05D4;&#x05D3;a&#x05D1;&#x05D2;&#x202C;</div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-nested-ref.html b/testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-nested-ref.html
new file mode 100644
index 000000000..d5d7674a4
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-nested-ref.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <link rel="author" title="Aharon Lanin" href="mailto:aharon@google.com">
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com">
+ <style>
+ body{
+ font-size:2em;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 500px;
+ margin: 20px;
+ }
+ .comments { display: none; }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="comments">
+ Key to entities used below:
+ &#x05D0; ... &#x05D5; - The first six Hebrew letters (strongly RTL).
+ &#x202D; - The LRO (left-to-right override) formatting character.
+ &#x202C; - The PDF (pop directional formatting) formatting character; closes LRO.
+ </div>
+ <div class="test">
+ <div dir="ltr">&#x202D;1 + [a + [3 + [b + 4] + &#x05D1;] + 2] + &#x05D0;&#x202C;</div>
+ <div dir="ltr">&#x202D;1 + [a + [3 + [b + 4] + &#x05D1;] + 2] + &#x05D0;&#x202C;</div>
+ <div dir="ltr">&#x202D;1 + [a + [3 + [b + 4] + &#x05D1;] + 2] + &#x05D0;&#x202C;</div>
+ <div dir="rtl">&#x202D;a + [1 + [b + [3 + &#x05D1;] + 2] + &#x05D0;] + 0&#x202C;</div>
+ <div dir="rtl">&#x202D;a + [1 + [b + [3 + &#x05D1;] + 2] + &#x05D0;] + 0&#x202C;</div>
+ <div dir="rtl">&#x202D;a + [1 + [b + [3 + &#x05D1;] + 2] + &#x05D0;] + 0&#x202C;</div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">&#x202D;1 + [a + [3 + [b + 4] + &#x05D1;] + 2] + &#x05D0;&#x202C;</div>
+ <div dir="ltr">&#x202D;1 + [a + [3 + [b + 4] + &#x05D1;] + 2] + &#x05D0;&#x202C;</div>
+ <div dir="ltr">&#x202D;1 + [a + [3 + [b + 4] + &#x05D1;] + 2] + &#x05D0;&#x202C;</div>
+ <div dir="rtl">&#x202D;a + [1 + [b + [3 + &#x05D1;] + 2] + &#x05D0;] + 0&#x202C;</div>
+ <div dir="rtl">&#x202D;a + [1 + [b + [3 + &#x05D1;] + 2] + &#x05D0;] + 0&#x202C;</div>
+ <div dir="rtl">&#x202D;a + [1 + [b + [3 + &#x05D1;] + 2] + &#x05D0;] + 0&#x202C;</div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-nested.html b/testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-nested.html
new file mode 100644
index 000000000..158576885
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-nested.html
@@ -0,0 +1,52 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8"/>
+ <title>HTML Test: BDI: neutral when nested</title>
+ <link rel="match" href="bdi-neutral-nested-ref.html"/>
+ <link rel="author" title="Aharon Lanin" href="mailto:aharon@google.com"/>
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com"/>
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-bdi-element"/>
+ <meta name="assert" content="
+ 'For the purposes of applying the bidirectional algorithm to the paragraph-level
+ container that a bdi element finds itself within, the bdi element must be treated
+ like a U+FFFC OBJECT REPLACEMENT CHARACTER.'
+ This must apply when a BDI is nested within a BDI."/>
+ <style>
+ body{
+ font-size:2em;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 500px;
+ margin: 20px;
+ }
+ .comments { display: none; }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="comments">
+ Key to entities used below:
+ &#x05D0; ... &#x05D5; - The first six Hebrew letters (strongly RTL).
+ &#x202D; - The LRO (left-to-right override) formatting character.
+ &#x202C; - The PDF (pop directional formatting) formatting character; closes LRO.
+ </div>
+ <div class="test">
+ <div dir="ltr">&#x05D0; + <bdi>[a + <bdi>[&#x05D1; + <bdi>[b + 4]</bdi> + 3]</bdi> + 2]</bdi> + 1</div>
+ <div dir="ltr">&#x05D0; + <bdi dir="rtl">[a + <bdi dir="ltr">[&#x05D1; + <bdi dir="rtl">[b + 4]</bdi> + 3]</bdi> + 2]</bdi> + 1</div>
+ <div dir="ltr">&#x05D0; + <bdi dir="ltr">[a + <bdi dir="rtl">[&#x05D1; + <bdi dir="ltr">[b + 4]</bdi> + 3]</bdi> + 2]</bdi> + 1</div>
+ <div dir="rtl">a + <bdi>[&#x05D0; + <bdi>[b + <bdi>[&#x05D1; + 3]</bdi> + 2]</bdi> + 1]</bdi> + 0</div>
+ <div dir="rtl">a + <bdi dir="ltr">[&#x05D0; + <bdi dir="rtl">[b + <bdi dir="ltr">[&#x05D1; + 3]</bdi> + 2]</bdi> + 1]</bdi> + 0</div>
+ <div dir="rtl">a + <bdi dir="rtl">[&#x05D0; + <bdi dir="ltr">[b + <bdi dir="rtl">[&#x05D1; + 3]</bdi> + 2]</bdi> + 1]</bdi> + 0</div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">&#x202D;1 + [a + [3 + [b + 4] + &#x05D1;] + 2] + &#x05D0;&#x202C;</div>
+ <div dir="ltr">&#x202D;1 + [a + [3 + [b + 4] + &#x05D1;] + 2] + &#x05D0;&#x202C;</div>
+ <div dir="ltr">&#x202D;1 + [a + [3 + [b + 4] + &#x05D1;] + 2] + &#x05D0;&#x202C;</div>
+ <div dir="rtl">&#x202D;a + [1 + [b + [3 + &#x05D1;] + 2] + &#x05D0;] + 0&#x202C;</div>
+ <div dir="rtl">&#x202D;a + [1 + [b + [3 + &#x05D1;] + 2] + &#x05D0;] + 0&#x202C;</div>
+ <div dir="rtl">&#x202D;a + [1 + [b + [3 + &#x05D1;] + 2] + &#x05D0;] + 0&#x202C;</div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-number-ref.html b/testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-number-ref.html
new file mode 100644
index 000000000..df7af7778
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-number-ref.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <link rel="author" title="Aharon Lanin" href="mailto:aharon@google.com">
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com">
+ <style>
+ body{
+ font-size:2em;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments { display: none; }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="comments">
+ Key to entities used below:
+ &#x05D0; ... &#x05D5; - The first six Hebrew letters (strongly RTL).
+ &#x202D; - The LRO (left-to-right override) formatting character.
+ &#x202C; - The PDF (pop directional formatting) formatting character; closes LRO.
+ </div>
+ <div class="test">
+ <div dir="ltr">&#x202D;&#x05D0; - [1]...&#x202C;</div>
+ <div dir="ltr">&#x202D;&#x05D0; - [1]...&#x202C;</div>
+ <div dir="ltr">&#x202D;&#x05D0; - [1]...&#x202C;</div>
+ <div dir="rtl">&#x202D;...[1] - a&#x202C;</div>
+ <div dir="rtl">&#x202D;...[1] - a&#x202C;</div>
+ <div dir="rtl">&#x202D;...[1] - a&#x202C;</div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">&#x202D;&#x05D0; - [1]...&#x202C;</div>
+ <div dir="ltr">&#x202D;&#x05D0; - [1]...&#x202C;</div>
+ <div dir="ltr">&#x202D;&#x05D0; - [1]...&#x202C;</div>
+ <div dir="rtl">&#x202D;...[1] - a&#x202C;</div>
+ <div dir="rtl">&#x202D;...[1] - a&#x202C;</div>
+ <div dir="rtl">&#x202D;...[1] - a&#x202C;</div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-number.html b/testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-number.html
new file mode 100644
index 000000000..37e467c17
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-number.html
@@ -0,0 +1,53 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8"/>
+ <title>HTML Test: BDI: neutral when number</title>
+ <link rel="match" href="bdi-neutral-number-ref.html"/>
+ <link rel="author" title="Aharon Lanin" href="mailto:aharon@google.com"/>
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com"/>
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-bdi-element"/>
+ <meta name="assert" content="
+ 'For the purposes of applying the bidirectional algorithm to the paragraph-level
+ container that a bdi element finds itself within, the bdi element must be treated
+ like a U+FFFC OBJECT REPLACEMENT CHARACTER.'"/>
+ <style>
+ body{
+ font-size:2em;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments { display: none; }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="comments">
+ Key to entities used below:
+ &#x05D0; ... &#x05D5; - The first six Hebrew letters (strongly RTL).
+ &#x202D; - The LRO (left-to-right override) formatting character.
+ &#x202C; - The PDF (pop directional formatting) formatting character; closes LRO.
+ If the BDI in the test's first DIV were a SPAN, the 1 inside it would be visually ordered
+ to the left of the &#x05D0;.
+ </div>
+ <div class="test">
+ <div dir="ltr">&#x05D0; - <bdi>[1]</bdi>...</div>
+ <div dir="ltr">&#x05D0; - <bdi dir="ltr">[1]</bdi>...</div>
+ <div dir="ltr">&#x05D0; - <bdi dir="rtl">[1]</bdi>...</div>
+ <div dir="rtl">a - <bdi>[1]</bdi>...</div>
+ <div dir="rtl">a - <bdi dir="ltr">[1]</bdi>...</div>
+ <div dir="rtl">a - <bdi dir="rtl">[1]</bdi>...</div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">&#x202D;&#x05D0; - [1]...&#x202C;</div>
+ <div dir="ltr">&#x202D;&#x05D0; - [1]...&#x202C;</div>
+ <div dir="ltr">&#x202D;&#x05D0; - [1]...&#x202C;</div>
+ <div dir="rtl">&#x202D;...[1] - a&#x202C;</div>
+ <div dir="rtl">&#x202D;...[1] - a&#x202C;</div>
+ <div dir="rtl">&#x202D;...[1] - a&#x202C;</div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-separate-ref.html b/testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-separate-ref.html
new file mode 100644
index 000000000..ec8e34627
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-separate-ref.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <link rel="author" title="Aharon Lanin" href="mailto:aharon@google.com">
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com">
+ <style>
+ body{
+ font-size:2em;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 500px;
+ margin: 20px;
+ }
+ .comments { display: none; }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="comments">
+ Key to entities used below:
+ &#x05D0; ... &#x05D5; - The first six Hebrew letters (strongly RTL).
+ &#x202D; - The LRO (left-to-right override) formatting character.
+ &#x202C; - The PDF (pop directional formatting) formatting character; closes LRO.
+ </div>
+ <div class="test">
+ <div dir="ltr">&#x202D;&#x05D0; [1 b] c [d &#x05D4;] &#x05D5;...&#x202C;</div>
+ <div dir="rtl">&#x202D;...f [e &#x05D3;] &#x05D2; [&#x05D1; 1] a&#x202C;</div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">&#x202D;&#x05D0; [1 b] c [d &#x05D4;] &#x05D5;...&#x202C;</div>
+ <div dir="rtl">&#x202D;...f [e &#x05D3;] &#x05D2; [&#x05D1; 1] a&#x202C;</div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-separate.html b/testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-separate.html
new file mode 100644
index 000000000..7bb8a2081
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-separate.html
@@ -0,0 +1,47 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8"/>
+ <title>HTML Test: BDI: paragraph-level container</title>
+ <link rel="match" href="bdi-neutral-separate-ref.html"/>
+ <link rel="author" title="Aharon Lanin" href="mailto:aharon@google.com"/>
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com"/>
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-bdi-element"/>
+ <meta name="assert" content="
+ 'For the purposes of applying the bidirectional algorithm to the paragraph-level
+ container that a bdi element finds itself within, the bdi element must be treated
+ like a U+FFFC OBJECT REPLACEMENT CHARACTER.'
+ Thus, under no circumstances should any part of the content outside a BDI be visually
+ reordered inside the BDI's content."/>
+ <style>
+ body{
+ font-size:2em;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 500px;
+ margin: 20px;
+ }
+ .comments { display: none; }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="comments">
+ Key to entities used below:
+ &#x05D0; ... &#x05D5; - The first six Hebrew letters (strongly RTL).
+ &#x202D; - The LRO (left-to-right override) formatting character.
+ &#x202C; - The PDF (pop directional formatting) formatting character; closes LRO.
+ If the BDIs in the test's first DIV were just SPANs, the &#x05D0; would appear between the 1
+ and the b, and the &#x05D5; between the d and the &#x05D4;.
+ </div>
+ <div class="test">
+ <div dir="ltr">&#x05D0; <bdi>[1 b]</bdi> c <bdi>[d &#x05D4;]</bdi> &#x05D5;...</div>
+ <div dir="rtl">a <bdi>[1 &#x05D1;]</bdi> &#x05D2; <bdi>[&#x05D3; e]</bdi> f...</div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">&#x202D;&#x05D0; [1 b] c [d &#x05D4;] &#x05D5;...&#x202C;</div>
+ <div dir="rtl">&#x202D;...f [e &#x05D3;] &#x05D2; [&#x05D1; 1] a&#x202C;</div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-to-another-bdi-1-ref.html b/testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-to-another-bdi-1-ref.html
new file mode 100644
index 000000000..c0f323ea2
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-to-another-bdi-1-ref.html
@@ -0,0 +1,47 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <link rel="author" title="Aharon Lanin" href="mailto:aharon@google.com" />
+ <link rel="author" title="Shai Berger" href="mailto:shai@platonix.com" />
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com" />
+ <style>
+ body{
+ font-size:2em;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments {
+ display: none;
+ }
+ </style>
+ </head>
+ <body>
+ <div class="instructions">Test passes if the two boxes below look exactly the same.</div>
+ <div class="comments">
+ Key to entities used below:
+ &#x05D0; ... &#x05D5; - The first six Hebrew letters (strongly RTL).
+ &#x202D; - The LRO (left-to-right override) formatting character.
+ &#x202C; - The PDF (pop directional formatting) formatting character; closes LRO.
+ </div>
+ <div class="test">
+ <div dir="ltr">&#x202D;[&#x05D0;] &gt; [&#x05D1;]...&#x202C;</div>
+ <div dir="ltr">&#x202D;[&#x05D0;] &gt; [&#x05D1;]...&#x202C;</div>
+ <div dir="ltr">&#x202D;[&#x05D0;] &gt; [&#x05D1;]...&#x202C;</div>
+ <div dir="rtl">&#x202D;...[b] &lt; [a]&#x202C;</div>
+ <div dir="rtl">&#x202D;...[b] &lt; [a]&#x202C;</div>
+ <div dir="rtl">&#x202D;...[b] &lt; [a]&#x202C;</div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">&#x202D;[&#x05D0;] &gt; [&#x05D1;]...&#x202C;</div>
+ <div dir="ltr">&#x202D;[&#x05D0;] &gt; [&#x05D1;]...&#x202C;</div>
+ <div dir="ltr">&#x202D;[&#x05D0;] &gt; [&#x05D1;]...&#x202C;</div>
+ <div dir="rtl">&#x202D;...[b] &lt; [a]&#x202C;</div>
+ <div dir="rtl">&#x202D;...[b] &lt; [a]&#x202C;</div>
+ <div dir="rtl">&#x202D;...[b] &lt; [a]&#x202C;</div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-to-another-bdi-1.html b/testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-to-another-bdi-1.html
new file mode 100644
index 000000000..822120721
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-to-another-bdi-1.html
@@ -0,0 +1,58 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>HTML Test: BDI: neutral to another BDI</title>
+ <link rel="match" href="bdi-neutral-to-another-bdi-1-ref.html" />
+ <link rel="author" title="Aharon Lanin" href="mailto:aharon@google.com" />
+ <link rel="author" title="Shai Berger" href="mailto:shai@platonix.com" />
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-bdi-element" />
+ <meta name="assert" content="
+ 'For the purposes of applying the bidirectional algorithm to the paragraph-level
+ container that a bdi element finds itself within, the bdi element must be treated
+ like a U+FFFC OBJECT REPLACEMENT CHARACTER.'
+ Thus, when a BDI contains text of the same strong direction as another BDI following it, the
+ two must not form a directional run as would be the case if the BDIs were just SPANs." />
+ <style>
+ body{
+ font-size:2em;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments {
+ display: none;
+ }
+ </style>
+ </head>
+ <body>
+ <div class="instructions">Test passes if the two boxes below look exactly the same.</div>
+ <div class="comments">
+ Key to entities used below:
+ &#x05D0; ... &#x05D5; - The first six Hebrew letters (strongly RTL).
+ &#x202D; - The LRO (left-to-right override) formatting character.
+ &#x202C; - The PDF (pop directional formatting) formatting character; closes LRO.
+ If the BDIs in the test's first DIV were SPANs, the &#x05D1; would be rendered to the left
+ of the &#x05D0;.
+ </div>
+ <div class="test">
+ <div dir="ltr"><bdi>[&#x05D0;]</bdi> &gt; <bdi>[&#x05D1;]</bdi>...</div>
+ <div dir="ltr"><bdi dir="rtl">[&#x05D0;]</bdi> &gt; <bdi dir="rtl">[&#x05D1;]</bdi>...</div>
+ <div dir="ltr"><bdi dir="ltr">[&#x05D0;]</bdi> &gt; <bdi dir="ltr">[&#x05D1;]</bdi>...</div>
+ <div dir="rtl"><bdi>[a]</bdi> &gt; <bdi>[b]</bdi>...</div>
+ <div dir="rtl"><bdi dir="ltr">[a]</bdi> &gt; <bdi dir="ltr">[b]</bdi>...</div>
+ <div dir="rtl"><bdi dir="rtl">[a]</bdi> &gt; <bdi dir="rtl">[b]</bdi>...</div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">&#x202D;[&#x05D0;] &gt; [&#x05D1;]...&#x202C;</div>
+ <div dir="ltr">&#x202D;[&#x05D0;] &gt; [&#x05D1;]...&#x202C;</div>
+ <div dir="ltr">&#x202D;[&#x05D0;] &gt; [&#x05D1;]...&#x202C;</div>
+ <div dir="rtl">&#x202D;...[b] &lt; [a]&#x202C;</div>
+ <div dir="rtl">&#x202D;...[b] &lt; [a]&#x202C;</div>
+ <div dir="rtl">&#x202D;...[b] &lt; [a]&#x202C;</div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-to-another-bdi-2-ref.html b/testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-to-another-bdi-2-ref.html
new file mode 100644
index 000000000..9aef97c0e
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-to-another-bdi-2-ref.html
@@ -0,0 +1,47 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <link rel="author" title="Aharon Lanin" href="mailto:aharon@google.com" />
+ <link rel="author" title="Shai Berger" href="mailto:shai@platonix.com" />
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com" />
+ <style>
+ body{
+ font-size:2em;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments {
+ display: none;
+ }
+ </style>
+ </head>
+ <body>
+ <div class="instructions">Test passes if the two boxes below look exactly the same.</div>
+ <div class="comments">
+ Key to entities used below:
+ &#x05D0; ... &#x05D5; - The first six Hebrew letters (strongly RTL).
+ &#x202D; - The LRO (left-to-right override) formatting character.
+ &#x202C; - The PDF (pop directional formatting) formatting character; closes LRO.
+ </div>
+ <div class="test">
+ <div dir="ltr">&#x202D;&#x05D0;&#x05D1;...&#x202C;</div>
+ <div dir="ltr">&#x202D;&#x05D0;&#x05D1;...&#x202C;</div>
+ <div dir="ltr">&#x202D;&#x05D0;&#x05D1;...&#x202C;</div>
+ <div dir="rtl">&#x202D;...ba&#x202C;</div>
+ <div dir="rtl">&#x202D;...ba&#x202C;</div>
+ <div dir="rtl">&#x202D;...ba&#x202C;</div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">&#x202D;&#x05D0;&#x05D1;...&#x202C;</div>
+ <div dir="ltr">&#x202D;&#x05D0;&#x05D1;...&#x202C;</div>
+ <div dir="ltr">&#x202D;&#x05D0;&#x05D1;...&#x202C;</div>
+ <div dir="rtl">&#x202D;...ba&#x202C;</div>
+ <div dir="rtl">&#x202D;...ba&#x202C;</div>
+ <div dir="rtl">&#x202D;...ba&#x202C;</div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-to-another-bdi-2.html b/testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-to-another-bdi-2.html
new file mode 100644
index 000000000..85aec4668
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-to-another-bdi-2.html
@@ -0,0 +1,59 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>HTML Test: BDI: neutral to another immediately following BDI</title>
+ <link rel="match" href="bdi-neutral-to-another-bdi-2-ref.html">
+ <link rel="author" title="Aharon Lanin" href="mailto:aharon@google.com" />
+ <link rel="author" title="Shai Berger" href="mailto:shai@platonix.com" />
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-bdi-element" />
+ <meta name="assert" content="
+ 'For the purposes of applying the bidirectional algorithm to the paragraph-level
+ container that a bdi element finds itself within, the bdi element must be treated
+ like a U+FFFC OBJECT REPLACEMENT CHARACTER.'
+ Thus, when a BDI contains text of the same strong direction as another BDI following it, the
+ two must not form a directional run as would be the case if the BDIs were just SPANs, even if
+ the two BDIs are not separated by anything at all." />
+ <style>
+ body{
+ font-size:2em;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments {
+ display: none;
+ }
+ </style>
+ </head>
+ <body>
+ <div class="instructions">Test passes if the two boxes below look exactly the same.</div>
+ <div class="comments">
+ Key to entities used below:
+ &#x05D0; ... &#x05D5; - The first six Hebrew letters (strongly RTL).
+ &#x202D; - The LRO (left-to-right override) formatting character.
+ &#x202C; - The PDF (pop directional formatting) formatting character; closes LRO.
+ If the BDIs in the test's first DIV were SPANs, the &#x05D1; would be rendered to the left of
+ the &#x05D0;.
+ </div>
+ <div class="test">
+ <div dir="ltr"><bdi>&#x05D0;</bdi><bdi>&#x05D1;</bdi>...</div>
+ <div dir="ltr"><bdi dir="rtl">&#x05D0;</bdi><bdi dir="rtl">&#x05D1;</bdi>...</div>
+ <div dir="ltr"><bdi dir="ltr">&#x05D0;</bdi><bdi dir="ltr">&#x05D1;</bdi>...</div>
+ <div dir="rtl"><bdi>a</bdi><bdi>b</bdi>...</div>
+ <div dir="rtl"><bdi dir="ltr">a</bdi><bdi dir="ltr">b</bdi>...</div>
+ <div dir="rtl"><bdi dir="rtl">a</bdi><bdi dir="rtl">b</bdi>...</div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">&#x202D;&#x05D0;&#x05D1;...&#x202C;</div>
+ <div dir="ltr">&#x202D;&#x05D0;&#x05D1;...&#x202C;</div>
+ <div dir="ltr">&#x202D;&#x05D0;&#x05D1;...&#x202C;</div>
+ <div dir="rtl">&#x202D;...ba&#x202C;</div>
+ <div dir="rtl">&#x202D;...ba&#x202C;</div>
+ <div dir="rtl">&#x202D;...ba&#x202C;</div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-to-letter-following-1-ref.html b/testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-to-letter-following-1-ref.html
new file mode 100644
index 000000000..a34d09bd2
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-to-letter-following-1-ref.html
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <link rel="author" title="Aharon Lanin" href="mailto:aharon@google.com">
+ <link rel="author" title="Shai Berger" href="mailto:shai@platonix.com">
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com">
+ <style>
+ body{
+ font-size:2em;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments { display: none; }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="comments">
+ Key to entities used below:
+ &#x05D0; ... &#x05D5; - The first six Hebrew letters (strongly RTL).
+ &#x202D; - The LRO (left-to-right override) formatting character.
+ &#x202C; - The PDF (pop directional formatting) formatting character; closes LRO.
+ </div>
+ <div class="test">
+ <div dir="ltr">&#x202D;[&#x05D0;] &gt; &#x05D1;...&#x202C;</div>
+ <div dir="ltr">&#x202D;[&#x05D0;] &gt; &#x05D1;...&#x202C;</div>
+ <div dir="ltr">&#x202D;[&#x05D0;] &gt; &#x05D1;...&#x202C;</div>
+ <div dir="rtl">&#x202D;...b &lt; [a]&#x202C;</div>
+ <div dir="rtl">&#x202D;...b &lt; [a]&#x202C;</div>
+ <div dir="rtl">&#x202D;...b &lt; [a]&#x202C;</div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">&#x202D;[&#x05D0;] &gt; &#x05D1;...&#x202C;</div>
+ <div dir="ltr">&#x202D;[&#x05D0;] &gt; &#x05D1;...&#x202C;</div>
+ <div dir="ltr">&#x202D;[&#x05D0;] &gt; &#x05D1;...&#x202C;</div>
+ <div dir="rtl">&#x202D;...b &lt; [a]&#x202C;</div>
+ <div dir="rtl">&#x202D;...b &lt; [a]&#x202C;</div>
+ <div dir="rtl">&#x202D;...b &lt; [a]&#x202C;</div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-to-letter-following-1.html b/testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-to-letter-following-1.html
new file mode 100644
index 000000000..76da57c2b
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-to-letter-following-1.html
@@ -0,0 +1,54 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8"/>
+ <title>HTML Test: BDI: neutral to following letter</title>
+ <link rel="match" href="bdi-neutral-to-letter-following-1-ref.html"/>
+ <link rel="author" title="Aharon Lanin" href="mailto:aharon@google.com"/>
+ <link rel="author" title="Shai Berger" href="mailto:shai@platonix.com"/>
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com"/>
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-bdi-element"/>
+ <meta name="assert" content="
+ 'For the purposes of applying the bidirectional algorithm to the paragraph-level
+ container that a bdi element finds itself within, the bdi element must be treated
+ like a U+FFFC OBJECT REPLACEMENT CHARACTER.'"/>
+ <style>
+ body{
+ font-size:2em;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments { display: none; }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="comments">
+ Key to entities used below:
+ &#x05D0; ... &#x05D5; - The first six Hebrew letters (strongly RTL).
+ &#x202D; - The LRO (left-to-right override) formatting character.
+ &#x202C; - The PDF (pop directional formatting) formatting character; closes LRO.
+ If the BDI in the test's first DIV were a SPAN, the &#x05D1; would be rendered to the left
+ of the &#x05D0;
+ </div>
+ <div class="test">
+ <div dir="ltr"><bdi>[&#x05D0;]</bdi> &gt; &#x05D1;...</div>
+ <div dir="ltr"><bdi dir="rtl">[&#x05D0;]</bdi> &gt; &#x05D1;...</div>
+ <div dir="ltr"><bdi dir="ltr">[&#x05D0;]</bdi> &gt; &#x05D1;...</div>
+ <div dir="rtl"><bdi>[a]</bdi> &gt; b...</div>
+ <div dir="rtl"><bdi dir="ltr">[a]</bdi> &gt; b...</div>
+ <div dir="rtl"><bdi dir="rtl">[a]</bdi> &gt; b...</div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">&#x202D;[&#x05D0;] &gt; &#x05D1;...&#x202C;</div>
+ <div dir="ltr">&#x202D;[&#x05D0;] &gt; &#x05D1;...&#x202C;</div>
+ <div dir="ltr">&#x202D;[&#x05D0;] &gt; &#x05D1;...&#x202C;</div>
+ <div dir="rtl">&#x202D;...b &lt; [a]&#x202C;</div>
+ <div dir="rtl">&#x202D;...b &lt; [a]&#x202C;</div>
+ <div dir="rtl">&#x202D;...b &lt; [a]&#x202C;</div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-to-letter-following-2-ref.html b/testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-to-letter-following-2-ref.html
new file mode 100644
index 000000000..80f36183b
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-to-letter-following-2-ref.html
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <link rel="author" title="Aharon Lanin" href="mailto:aharon@google.com">
+ <link rel="author" title="Shai Berger" href="mailto:shai@platonix.com">
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com">
+ <style>
+ body{
+ font-size:2em;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments { display: none; }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="comments">
+ Key to entities used below:
+ &#x05D0; ... &#x05D5; - The first six Hebrew letters (strongly RTL).
+ &#x202D; - The LRO (left-to-right override) formatting character.
+ &#x202C; - The PDF (pop directional formatting) formatting character; closes LRO.
+ </div>
+ <div class="test">
+ <div dir="ltr">&#x202D;&#x05D0;&#x05D1;...&#x202C;</div>
+ <div dir="ltr">&#x202D;&#x05D0;&#x05D1;...&#x202C;</div>
+ <div dir="ltr">&#x202D;&#x05D0;&#x05D1;...&#x202C;</div>
+ <div dir="rtl">&#x202D;...ba&#x202C;</div>
+ <div dir="rtl">&#x202D;...ba&#x202C;</div>
+ <div dir="rtl">&#x202D;...ba&#x202C;</div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">&#x202D;&#x05D0;&#x05D1;...&#x202C;</div>
+ <div dir="ltr">&#x202D;&#x05D0;&#x05D1;...&#x202C;</div>
+ <div dir="ltr">&#x202D;&#x05D0;&#x05D1;...&#x202C;</div>
+ <div dir="rtl">&#x202D;...ba&#x202C;</div>
+ <div dir="rtl">&#x202D;...ba&#x202C;</div>
+ <div dir="rtl">&#x202D;...ba&#x202C;</div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-to-letter-following-2.html b/testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-to-letter-following-2.html
new file mode 100644
index 000000000..ce41983f0
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-to-letter-following-2.html
@@ -0,0 +1,54 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8"/>
+ <title>HTML Test: BDI: neutral to immediately following letter</title>
+ <link rel="match" href="bdi-neutral-to-letter-following-2-ref.html">
+ <link rel="author" title="Aharon Lanin" href="mailto:aharon@google.com"/>
+ <link rel="author" title="Shai Berger" href="mailto:shai@platonix.com"/>
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com"/>
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-bdi-element"/>
+ <meta name="assert" content="
+ 'For the purposes of applying the bidirectional algorithm to the paragraph-level
+ container that a bdi element finds itself within, the bdi element must be treated
+ like a U+FFFC OBJECT REPLACEMENT CHARACTER.'"/>
+ <style>
+ body{
+ font-size:2em;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments { display: none; }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="comments">
+ Key to entities used below:
+ &#x05D0; ... &#x05D5; - The first six Hebrew letters (strongly RTL).
+ &#x202D; - The LRO (left-to-right override) formatting character.
+ &#x202C; - The PDF (pop directional formatting) formatting character; closes LRO.
+ If the BDI in the following DIV were a SPAN, the &#x05D1; would be rendered to the left
+ of the &#x05D0;
+ </div>
+ <div class="test">
+ <div dir="ltr"><bdi>&#x05D0;</bdi>&#x05D1;...</div>
+ <div dir="ltr"><bdi dir="rtl">&#x05D0;</bdi>&#x05D1;...</div>
+ <div dir="ltr"><bdi dir="ltr">&#x05D0;</bdi>&#x05D1;...</div>
+ <div dir="rtl"><bdi>a</bdi>b...</div>
+ <div dir="rtl"><bdi dir="ltr">a</bdi>b...</div>
+ <div dir="rtl"><bdi dir="rtl">a</bdi>b...</div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">&#x202D;&#x05D0;&#x05D1;...&#x202C;</div>
+ <div dir="ltr">&#x202D;&#x05D0;&#x05D1;...&#x202C;</div>
+ <div dir="ltr">&#x202D;&#x05D0;&#x05D1;...&#x202C;</div>
+ <div dir="rtl">&#x202D;...ba&#x202C;</div>
+ <div dir="rtl">&#x202D;...ba&#x202C;</div>
+ <div dir="rtl">&#x202D;...ba&#x202C;</div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-to-letter-preceding-1-ref.html b/testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-to-letter-preceding-1-ref.html
new file mode 100644
index 000000000..5e39eabd2
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-to-letter-preceding-1-ref.html
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <link rel="author" title="Aharon Lanin" href="mailto:aharon@google.com">
+ <link rel="author" title="Shai Berger" href="mailto:shai@platonix.com">
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com">
+ <style>
+ body{
+ font-size:2em;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments { display: none; }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="comments">
+ Key to entities used below:
+ &#x05D0; ... &#x05D5; - The first six Hebrew letters (strongly RTL).
+ &#x202D; - The LRO (left-to-right override) formatting character.
+ &#x202C; - The PDF (pop directional formatting) formatting character; closes LRO.
+ </div>
+ <div class="test">
+ <div dir="ltr">&#x202D;&#x05D0; &gt; [&#x05D1;]...&#x202C;</div>
+ <div dir="ltr">&#x202D;&#x05D0; &gt; [&#x05D1;]...&#x202C;</div>
+ <div dir="ltr">&#x202D;&#x05D0; &gt; [&#x05D1;]...&#x202C;</div>
+ <div dir="rtl">&#x202D;...[b] &lt; a&#x202C;</div>
+ <div dir="rtl">&#x202D;...[b] &lt; a&#x202C;</div>
+ <div dir="rtl">&#x202D;...[b] &lt; a&#x202C;</div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">&#x202D;&#x05D0; &gt; [&#x05D1;]...&#x202C;</div>
+ <div dir="ltr">&#x202D;&#x05D0; &gt; [&#x05D1;]...&#x202C;</div>
+ <div dir="ltr">&#x202D;&#x05D0; &gt; [&#x05D1;]...&#x202C;</div>
+ <div dir="rtl">&#x202D;...[b] &lt; a&#x202C;</div>
+ <div dir="rtl">&#x202D;...[b] &lt; a&#x202C;</div>
+ <div dir="rtl">&#x202D;...[b] &lt; a&#x202C;</div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-to-letter-preceding-1.html b/testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-to-letter-preceding-1.html
new file mode 100644
index 000000000..46772de64
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-to-letter-preceding-1.html
@@ -0,0 +1,54 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8"/>
+ <title>HTML Test: BDI: neutral to preceding letter</title>
+ <link rel="match" href="bdi-neutral-to-letter-preceding-1-ref.html">
+ <link rel="author" title="Aharon Lanin" href="mailto:aharon@google.com"/>
+ <link rel="author" title="Shai Berger" href="mailto:shai@platonix.com"/>
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com"/>
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-bdi-element"/>
+ <meta name="assert" content="
+ 'For the purposes of applying the bidirectional algorithm to the paragraph-level
+ container that a bdi element finds itself within, the bdi element must be treated
+ like a U+FFFC OBJECT REPLACEMENT CHARACTER.'"/>
+ <style>
+ body{
+ font-size:2em;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments { display: none; }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="comments">
+ Key to entities used below:
+ &#x05D0; ... &#x05D5; - The first six Hebrew letters (strongly RTL).
+ &#x202D; - The LRO (left-to-right override) formatting character.
+ &#x202C; - The PDF (pop directional formatting) formatting character; closes LRO.
+ If the BDI in the test's first DIV were a SPAN, the &#x05D1; would be rendered to the left
+ of the &#x05D0;
+ </div>
+ <div class="test">
+ <div dir="ltr">&#x05D0; &gt; <bdi>[&#x05D1;]</bdi>...</div>
+ <div dir="ltr">&#x05D0; &gt; <bdi dir="rtl">[&#x05D1;]</bdi>...</div>
+ <div dir="ltr">&#x05D0; &gt; <bdi dir="ltr">[&#x05D1;]</bdi>...</div>
+ <div dir="rtl">a &gt; <bdi>[b]</bdi>...</div>
+ <div dir="rtl">a &gt; <bdi dir="ltr">[b]</bdi>...</div>
+ <div dir="rtl">a &gt; <bdi dir="rtl">[b]</bdi>...</div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">&#x202D;&#x05D0; &gt; [&#x05D1;]...&#x202C;</div>
+ <div dir="ltr">&#x202D;&#x05D0; &gt; [&#x05D1;]...&#x202C;</div>
+ <div dir="ltr">&#x202D;&#x05D0; &gt; [&#x05D1;]...&#x202C;</div>
+ <div dir="rtl">&#x202D;...[b] &lt; a&#x202C;</div>
+ <div dir="rtl">&#x202D;...[b] &lt; a&#x202C;</div>
+ <div dir="rtl">&#x202D;...[b] &lt; a&#x202C;</div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-to-letter-preceding-2-ref.html b/testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-to-letter-preceding-2-ref.html
new file mode 100644
index 000000000..80f36183b
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-to-letter-preceding-2-ref.html
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <link rel="author" title="Aharon Lanin" href="mailto:aharon@google.com">
+ <link rel="author" title="Shai Berger" href="mailto:shai@platonix.com">
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com">
+ <style>
+ body{
+ font-size:2em;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments { display: none; }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="comments">
+ Key to entities used below:
+ &#x05D0; ... &#x05D5; - The first six Hebrew letters (strongly RTL).
+ &#x202D; - The LRO (left-to-right override) formatting character.
+ &#x202C; - The PDF (pop directional formatting) formatting character; closes LRO.
+ </div>
+ <div class="test">
+ <div dir="ltr">&#x202D;&#x05D0;&#x05D1;...&#x202C;</div>
+ <div dir="ltr">&#x202D;&#x05D0;&#x05D1;...&#x202C;</div>
+ <div dir="ltr">&#x202D;&#x05D0;&#x05D1;...&#x202C;</div>
+ <div dir="rtl">&#x202D;...ba&#x202C;</div>
+ <div dir="rtl">&#x202D;...ba&#x202C;</div>
+ <div dir="rtl">&#x202D;...ba&#x202C;</div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">&#x202D;&#x05D0;&#x05D1;...&#x202C;</div>
+ <div dir="ltr">&#x202D;&#x05D0;&#x05D1;...&#x202C;</div>
+ <div dir="ltr">&#x202D;&#x05D0;&#x05D1;...&#x202C;</div>
+ <div dir="rtl">&#x202D;...ba&#x202C;</div>
+ <div dir="rtl">&#x202D;...ba&#x202C;</div>
+ <div dir="rtl">&#x202D;...ba&#x202C;</div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-to-letter-preceding-2.html b/testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-to-letter-preceding-2.html
new file mode 100644
index 000000000..192115775
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-to-letter-preceding-2.html
@@ -0,0 +1,54 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8"/>
+ <title>HTML Test: BDI: neutral to immediately preceding letter</title>
+ <link rel="match" href="bdi-neutral-to-letter-preceding-2-ref.html"/>
+ <link rel="author" title="Aharon Lanin" href="mailto:aharon@google.com"/>
+ <link rel="author" title="Shai Berger" href="mailto:shai@platonix.com"/>
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com"/>
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-bdi-element"/>
+ <meta name="assert" content="
+ 'For the purposes of applying the bidirectional algorithm to the paragraph-level
+ container that a bdi element finds itself within, the bdi element must be treated
+ like a U+FFFC OBJECT REPLACEMENT CHARACTER.'"/>
+ <style>
+ body{
+ font-size:2em;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments { display: none; }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="comments">
+ Key to entities used below:
+ &#x05D0; ... &#x05D5; - The first six Hebrew letters (strongly RTL).
+ &#x202D; - The LRO (left-to-right override) formatting character.
+ &#x202C; - The PDF (pop directional formatting) formatting character; closes LRO.
+ If the BDI in the test's first DIV were a SPAN, the &#x05D1; would be rendered to the left
+ of the &#x05D0;
+ </div>
+ <div class="test">
+ <div dir="ltr">&#x05D0;<bdi>&#x05D1;</bdi>...</div>
+ <div dir="ltr">&#x05D0;<bdi dir="rtl">&#x05D1;</bdi>...</div>
+ <div dir="ltr">&#x05D0;<bdi dir="ltr">&#x05D1;</bdi>...</div>
+ <div dir="rtl">a<bdi>b</bdi>...</div>
+ <div dir="rtl">a<bdi dir="ltr">b</bdi>...</div>
+ <div dir="rtl">a<bdi dir="rtl">b</bdi>...</div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">&#x202D;&#x05D0;&#x05D1;...&#x202C;</div>
+ <div dir="ltr">&#x202D;&#x05D0;&#x05D1;...&#x202C;</div>
+ <div dir="ltr">&#x202D;&#x05D0;&#x05D1;...&#x202C;</div>
+ <div dir="rtl">&#x202D;...ba&#x202C;</div>
+ <div dir="rtl">&#x202D;...ba&#x202C;</div>
+ <div dir="rtl">&#x202D;...ba&#x202C;</div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-to-number-following-1-ref.html b/testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-to-number-following-1-ref.html
new file mode 100644
index 000000000..ad15d468b
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-to-number-following-1-ref.html
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <link rel="author" title="Aharon Lanin" href="mailto:aharon@google.com">
+ <link rel="author" title="Shai Berger" href="mailto:shai@platonix.com">
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com">
+ <style>
+ body{
+ font-size:2em;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments { display: none; }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="comments">
+ Key to entities used below:
+ &#x05D0; ... &#x05D5; - The first six Hebrew letters (strongly RTL).
+ &#x202D; - The LRO (left-to-right override) formatting character.
+ &#x202C; - The PDF (pop directional formatting) formatting character; closes LRO.
+ </div>
+ <div class="test">
+ <div dir="ltr">&#x202D;[&#x05D0;] (3 reviews)...&#x202C;</div>
+ <div dir="ltr">&#x202D;[&#x05D0;] (3 reviews)...&#x202C;</div>
+ <div dir="ltr">&#x202D;[&#x05D0;] (3 reviews)...&#x202C;</div>
+ <div dir="rtl">&#x202D;...(3) [a]&#x202C;</div>
+ <div dir="rtl">&#x202D;...(3) [a]&#x202C;</div>
+ <div dir="rtl">&#x202D;...(3) [a]&#x202C;</div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">&#x202D;[&#x05D0;] (3 reviews)...&#x202C;</div>
+ <div dir="ltr">&#x202D;[&#x05D0;] (3 reviews)...&#x202C;</div>
+ <div dir="ltr">&#x202D;[&#x05D0;] (3 reviews)...&#x202C;</div>
+ <div dir="rtl">&#x202D;...(3) [a]&#x202C;</div>
+ <div dir="rtl">&#x202D;...(3) [a]&#x202C;</div>
+ <div dir="rtl">&#x202D;...(3) [a]&#x202C;</div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-to-number-following-1.html b/testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-to-number-following-1.html
new file mode 100644
index 000000000..ff566737f
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-to-number-following-1.html
@@ -0,0 +1,54 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8"/>
+ <title>HTML Test: BDI: neutral to following number</title>
+ <link rel="match" href="bdi-neutral-to-number-following-1-ref.html"/>
+ <link rel="author" title="Aharon Lanin" href="mailto:aharon@google.com"/>
+ <link rel="author" title="Shai Berger" href="mailto:shai@platonix.com"/>
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com"/>
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-bdi-element"/>
+ <meta name="assert" content="
+ 'For the purposes of applying the bidirectional algorithm to the paragraph-level
+ container that a bdi element finds itself within, the bdi element must be treated
+ like a U+FFFC OBJECT REPLACEMENT CHARACTER.'"/>
+ <style>
+ body{
+ font-size:2em;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments { display: none; }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="comments">
+ Key to entities used below:
+ &#x05D0; ... &#x05D5; - The first six Hebrew letters (strongly RTL).
+ &#x202D; - The LRO (left-to-right override) formatting character.
+ &#x202C; - The PDF (pop directional formatting) formatting character; closes LRO.
+ If the BDI in the test's first DIV were a SPAN, the 3 would be rendered to the left
+ of the &#x05D0;
+ </div>
+ <div class="test">
+ <div dir="ltr"><bdi>[&#x05D0;]</bdi> (3 reviews)...</div>
+ <div dir="ltr"><bdi dir="rtl">[&#x05D0;]</bdi> (3 reviews)...</div>
+ <div dir="ltr"><bdi dir="ltr">[&#x05D0;]</bdi> (3 reviews)...</div>
+ <div dir="rtl"><bdi>[a]</bdi> (3)...</div>
+ <div dir="rtl"><bdi dir="ltr">[a]</bdi> (3)...</div>
+ <div dir="rtl"><bdi dir="rtl">[a]</bdi> (3)...</div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">&#x202D;[&#x05D0;] (3 reviews)...&#x202C;</div>
+ <div dir="ltr">&#x202D;[&#x05D0;] (3 reviews)...&#x202C;</div>
+ <div dir="ltr">&#x202D;[&#x05D0;] (3 reviews)...&#x202C;</div>
+ <div dir="rtl">&#x202D;...(3) [a]&#x202C;</div>
+ <div dir="rtl">&#x202D;...(3) [a]&#x202C;</div>
+ <div dir="rtl">&#x202D;...(3) [a]&#x202C;</div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-to-number-following-2-ref.html b/testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-to-number-following-2-ref.html
new file mode 100644
index 000000000..d0f1097ad
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-to-number-following-2-ref.html
@@ -0,0 +1,45 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <link rel="author" title="Aharon Lanin" href="mailto:aharon@google.com">
+ <link rel="author" title="Shai Berger" href="mailto:shai@platonix.com">
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com">
+ <style>
+ body{
+ font-size:2em;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments { display: none; }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="comments">
+ Key to entities used below:
+ &#x05D0; ... &#x05D5; - The first six Hebrew letters (strongly RTL).
+ &#x202D; - The LRO (left-to-right override) formatting character.
+ &#x202C; - The PDF (pop directional formatting) formatting character; closes LRO.
+ </div>
+ <div class="test">
+ <div dir="ltr">&#x202D;&#x05D0;1...&#x202C;</div>
+ <div dir="ltr">&#x202D;&#x05D0;1...&#x202C;</div>
+ <div dir="ltr">&#x202D;&#x05D0;1...&#x202C;</div>
+ <div dir="rtl">&#x202D;...1a&#x202C;</div>
+ <div dir="rtl">&#x202D;...1a&#x202C;</div>
+ <div dir="rtl">&#x202D;...1a&#x202C;</div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">&#x202D;&#x05D0;1...&#x202C;</div>
+ <div dir="ltr">&#x202D;&#x05D0;1...&#x202C;</div>
+ <div dir="ltr">&#x202D;&#x05D0;1...&#x202C;</div>
+ <div dir="rtl">&#x202D;...1a&#x202C;</div>
+ <div dir="rtl">&#x202D;...1a&#x202C;</div>
+ <div dir="rtl">&#x202D;...1a&#x202C;</div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-to-number-following-2.html b/testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-to-number-following-2.html
new file mode 100644
index 000000000..62a3b50ff
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-to-number-following-2.html
@@ -0,0 +1,53 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8"/>
+ <title>HTML Test: BDI: neutral to immediately following number</title>
+ <link rel="match" href="bdi-neutral-to-number-following-2-ref.html"/>
+ <link rel="author" title="Aharon Lanin" href="mailto:aharon@google.com"/>
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com"/>
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-bdi-element"/>
+ <meta name="assert" content="
+ 'For the purposes of applying the bidirectional algorithm to the paragraph-level
+ container that a bdi element finds itself within, the bdi element must be treated
+ like a U+FFFC OBJECT REPLACEMENT CHARACTER.'"/>
+ <style>
+ body{
+ font-size:2em;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments { display: none; }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="comments">
+ Key to entities used below:
+ &#x05D0; ... &#x05D5; - The first six Hebrew letters (strongly RTL).
+ &#x202D; - The LRO (left-to-right override) formatting character.
+ &#x202C; - The PDF (pop directional formatting) formatting character; closes LRO.
+ If the BDI in the test's first DIV were a SPAN, the 1 would be rendered to the left
+ of the &#x05D0;
+ </div>
+ <div class="test">
+ <div dir="ltr"><bdi>&#x05D0;</bdi>1...</div>
+ <div dir="ltr"><bdi dir="rtl">&#x05D0;</bdi>1...</div>
+ <div dir="ltr"><bdi dir="ltr">&#x05D0;</bdi>1...</div>
+ <div dir="rtl"><bdi>a</bdi>1...</div>
+ <div dir="rtl"><bdi dir="ltr">a</bdi>1...</div>
+ <div dir="rtl"><bdi dir="rtl">a</bdi>1...</div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">&#x202D;&#x05D0;1...&#x202C;</div>
+ <div dir="ltr">&#x202D;&#x05D0;1...&#x202C;</div>
+ <div dir="ltr">&#x202D;&#x05D0;1...&#x202C;</div>
+ <div dir="rtl">&#x202D;...1a&#x202C;</div>
+ <div dir="rtl">&#x202D;...1a&#x202C;</div>
+ <div dir="rtl">&#x202D;...1a&#x202C;</div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-to-surrounding-run-ref.html b/testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-to-surrounding-run-ref.html
new file mode 100644
index 000000000..d7967c77f
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-to-surrounding-run-ref.html
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <link rel="author" title="Aharon Lanin" href="mailto:aharon@google.com">
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com">
+ <style>
+ body{
+ font-size:2em;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments { display: none; }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="comments">
+ Key to entities used below:
+ &#x05D0; ... &#x05D5; - The first six Hebrew letters (strongly RTL).
+ &#x202D; - The LRO (left-to-right override) formatting character.
+ &#x202C; - The PDF (pop directional formatting) formatting character; closes LRO.
+ </div>
+ <div class="test">
+ <div dir="ltr">&#x202D;&#x05D2; &lt; [b] &lt; &#x05D0;...&#x202C;</div>
+ <div dir="ltr">&#x202D;&#x05D2; &lt; [b] &lt; &#x05D0;...&#x202C;</div>
+ <div dir="ltr">&#x202D;&#x05D2; &lt; [b] &lt; &#x05D0;...&#x202C;</div>
+ <div dir="rtl">&#x202D;...a &gt; [&#x05D1;] &gt; c&#x202C;</div>
+ <div dir="rtl">&#x202D;...a &gt; [&#x05D1;] &gt; c&#x202C;</div>
+ <div dir="rtl">&#x202D;...a &gt; [&#x05D1;] &gt; c&#x202C;</div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">&#x202D;&#x05D2; &lt; [b] &lt; &#x05D0;...&#x202C;</div>
+ <div dir="ltr">&#x202D;&#x05D2; &lt; [b] &lt; &#x05D0;...&#x202C;</div>
+ <div dir="ltr">&#x202D;&#x05D2; &lt; [b] &lt; &#x05D0;...&#x202C;</div>
+ <div dir="rtl">&#x202D;...a &gt; [&#x05D1;] &gt; c&#x202C;</div>
+ <div dir="rtl">&#x202D;...a &gt; [&#x05D1;] &gt; c&#x202C;</div>
+ <div dir="rtl">&#x202D;...a &gt; [&#x05D1;] &gt; c&#x202C;</div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-to-surrounding-run.html b/testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-to-surrounding-run.html
new file mode 100644
index 000000000..bff339ec3
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-to-surrounding-run.html
@@ -0,0 +1,56 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8"/>
+ <title>HTML Test: BDI: neutral to surrounding letters</title>
+ <link rel="match" href="bdi-neutral-to-surrounding-run-ref.html">
+ <link rel="author" title="Aharon Lanin" href="mailto:aharon@google.com"/>
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com"/>
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-bdi-element"/>
+ <meta name="assert" content="
+ 'For the purposes of applying the bidirectional algorithm to the paragraph-level
+ container that a bdi element finds itself within, the bdi element must be treated
+ like a U+FFFC OBJECT REPLACEMENT CHARACTER.'
+ Thus, regardless of its content and its dir attribute (if any), a BDI will not prevent
+ a strongly RTL (or LTR) character preceding it from forming a single directional run with
+ another strongly RTL (LTR) character following it."/>
+ <style>
+ body{
+ font-size:2em;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments { display: none; }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="comments">
+ Key to entities used below:
+ &#x05D0; ... &#x05D5; - The first six Hebrew letters (strongly RTL).
+ &#x202D; - The LRO (left-to-right override) formatting character.
+ &#x202C; - The PDF (pop directional formatting) formatting character; closes LRO.
+ If the BDI in the test's first DIV were a SPAN, its b would prevent the &#x05D0; and the &#x05D1;
+ from forming a single RTL run and thus keep the &gt;s between from being mirrored into &lt;s.
+ </div>
+ <div class="test">
+ <div dir="ltr">&#x05D0; &gt; <bdi>[b]</bdi> &gt; &#x05D2;...</div>
+ <div dir="ltr">&#x05D0; &gt; <bdi dir="ltr">[b]</bdi> &gt; &#x05D2;...</div>
+ <div dir="ltr">&#x05D0; &gt; <bdi dir="rtl">[b]</bdi> &gt; &#x05D2;...</div>
+ <div dir="rtl">a &gt; <bdi>[&#x05D1;]</bdi> &gt; c...</div>
+ <div dir="rtl">a &gt; <bdi dir="ltr">[&#x05D1;]</bdi> &gt; c...</div>
+ <div dir="rtl">a &gt; <bdi dir="rtl">[&#x05D1;]</bdi> &gt; c...</div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">&#x202D;&#x05D2; &lt; [b] &lt; &#x05D0;...&#x202C;</div>
+ <div dir="ltr">&#x202D;&#x05D2; &lt; [b] &lt; &#x05D0;...&#x202C;</div>
+ <div dir="ltr">&#x202D;&#x05D2; &lt; [b] &lt; &#x05D0;...&#x202C;</div>
+ <div dir="rtl">&#x202D;...a &gt; [&#x05D1;] &gt; c&#x202C;</div>
+ <div dir="rtl">&#x202D;...a &gt; [&#x05D1;] &gt; c&#x202C;</div>
+ <div dir="rtl">&#x202D;...a &gt; [&#x05D1;] &gt; c&#x202C;</div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-wrapped-ref.html b/testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-wrapped-ref.html
new file mode 100644
index 000000000..9859de474
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-wrapped-ref.html
@@ -0,0 +1,52 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <link rel="author" title="Aharon Lanin" href="mailto:aharon@google.com">
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com">
+ <style>
+ body{
+ font-size:2em;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments { display: none; }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="comments">
+ Key to entities used below:
+ &#x05D0; ... &#x05D5; - The first six Hebrew letters (strongly RTL).
+ &#x202D; - The LRO (left-to-right override) formatting character.
+ &#x202C; - The PDF (pop directional formatting) formatting character; closes LRO.
+ </div>
+ <div class="test">
+ <div dir="ltr">
+ &#x202D;b &lt; &#x05D0;&#x202C;<br/>
+ &#x202D;&gt;&gt;&gt;&#x202C;<br/>
+ &#x202D;&#x05D3; &lt; c...&#x202C;
+ </div>
+ <div dir="rtl">
+ &#x202D;a &gt; &#x05D1;&#x202C;<br/>
+ &#x202D;&lt;&lt;&lt;&#x202C;<br/>
+ &#x202D;...&#x05D2; &gt; d&#x202C;
+ </div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">
+ &#x202D;b &lt; &#x05D0;&#x202C;<br/>
+ &#x202D;&gt;&gt;&gt;&#x202C;<br/>
+ &#x202D;&#x05D3; &lt; c...&#x202C;
+ </div>
+ <div dir="rtl">
+ &#x202D;a &gt; &#x05D1;&#x202C;<br/>
+ &#x202D;&lt;&lt;&lt;&#x202C;<br/>
+ &#x202D;...&#x05D2; &gt; d&#x202C;
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-wrapped.html b/testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-wrapped.html
new file mode 100644
index 000000000..3e21fcb0f
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-wrapped.html
@@ -0,0 +1,73 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8"/>
+ <title>HTML Test: BDI: neutral when wrapped</title>
+ <link rel="match" href="bdi-neutral-wrapped-ref.html">
+ <link rel="author" title="Aharon Lanin" href="mailto:aharon@google.com"/>
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com"/>
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-bdi-element"/>
+ <meta name="assert" content="
+ 'For the purposes of applying the bidirectional algorithm to the paragraph-level
+ container that a bdi element finds itself within, the bdi element must be treated
+ like a U+FFFC OBJECT REPLACEMENT CHARACTER.'
+ This should hold even if the BDI's content is wrapped over more than one line."/>
+ <style>
+ body{
+ font-size:2em;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments { display: none; }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="comments">
+ Key to entities used below:
+ &#xA0; - Non-breaking space.
+ &#x05D0; ... &#x05D5; - The first six Hebrew letters (strongly RTL).
+ &#x202D; - The LRO (left-to-right override) formatting character.
+ &#x202C; - The PDF (pop directional formatting) formatting character; closes LRO.
+ In the test below, the non-breaking spaces in the BDI's middle "word" make it so long that it
+ must be displayed on a line of its own, with the BDI wrapped before and after it. At the same
+ time, the content surrounding the BDI is supposed to form a single directional run, despite
+ the containing element and the BDI both having the opposite direction, because the BDI must be
+ treated as a neutral. Thus, on the line containing the first part of the BDI, the BDI's
+ content must appear after the content preceding it, and on the line containing the last part
+ of the BDI, the BDI content must appear before the content following it, where both 'before'
+ and 'after' are defined relative to the surrounding directional run.
+ </div>
+ <div class="test">
+ <div dir="ltr">
+ &#x05D0; &gt;
+ <bdi>b
+&gt;&gt;&gt;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;
+ c</bdi>
+ &gt; &#x05D3;...
+ </div>
+ <div dir="rtl">
+ a &gt;
+ <bdi>&#x05D1;
+&gt;&gt;&gt;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;
+ &#x05D2;</bdi>
+ &gt; d...
+ </div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">
+ &#x202D;b &lt; &#x05D0;&#x202C;<br/>
+ &#x202D;&gt;&gt;&gt;&#x202C;<br/>
+ &#x202D;&#x05D3; &lt; c...&#x202C;
+ </div>
+ <div dir="rtl">
+ &#x202D;a &gt; &#x05D1;&#x202C;<br/>
+ &#x202D;&lt;&lt;&lt;&#x202C;<br/>
+ &#x202D;...&#x05D2; &gt; d&#x202C;
+ </div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-paragraph-level-container-ref.html b/testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-paragraph-level-container-ref.html
new file mode 100644
index 000000000..0c74ecf68
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-paragraph-level-container-ref.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <link rel="author" title="Aharon Lanin" href="mailto:aharon@google.com">
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com">
+ <style>
+ body{
+ font-size:2em;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 500px;
+ margin: 20px;
+ }
+ .comments { display: none; }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="comments">
+ Key to entities used below:
+ &#x05D0; ... &#x05D5; - The first six Hebrew letters (strongly RTL).
+ &#x202D; - The LRO (left-to-right override) formatting character.
+ &#x202C; - The PDF (pop directional formatting) formatting character; closes LRO.
+ </div>
+ <div class="test">
+ <div dir="ltr">&#x202D;&#x05D0; [1 2 3 b] c [d &#x05D4;?!] &#x05D5;...&#x202C;</div>
+ <div dir="rtl">&#x202D;...f [!?e &#x05D3;] &#x05D2; [&#x05D1; 3 2 1] a&#x202C;</div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">&#x202D;&#x05D0; [1 2 3 b] c [d &#x05D4;?!] &#x05D5;...&#x202C;</div>
+ <div dir="rtl">&#x202D;...f [!?e &#x05D3;] &#x05D2; [&#x05D1; 3 2 1] a&#x202C;</div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-paragraph-level-container.html b/testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-paragraph-level-container.html
new file mode 100644
index 000000000..f133a9577
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/text-level-semantics/the-bdi-element/bdi-paragraph-level-container.html
@@ -0,0 +1,46 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8"/>
+ <title>HTML Test: BDI: paragraph-level container</title>
+ <link rel="match" href="bdi-paragraph-level-container-ref.html"/>
+ <link rel="author" title="Aharon Lanin" href="mailto:aharon@google.com"/>
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com"/>
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-bdi-element"/>
+ <meta name="assert" content="
+ 'For the purposes of applying the bidirectional algorithm to the contents of a bdi element,
+ user agents must treat the element as a paragraph-level container.'
+ Thus, under no circumstances should the content outside a BDI affect the visual
+ ordering of the BDI's content."/>
+ <style>
+ body{
+ font-size:2em;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 500px;
+ margin: 20px;
+ }
+ .comments { display: none; }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="comments">
+ Key to entities used below:
+ &#x05D0; ... &#x05D5; - The first six Hebrew letters (strongly RTL).
+ &#x202D; - The LRO (left-to-right override) formatting character.
+ &#x202C; - The PDF (pop directional formatting) formatting character; closes LRO.
+ If the BDIs in the test's first DIV were just SPANs, the &#x05D0; would order the 1 2 3 as
+ 3 2 1, and the &#x05D5; would (with the &#x05D4;) order the ?! as !?.
+ </div>
+ <div class="test">
+ <div dir="ltr">&#x05D0; <bdi>[1 2 3 b]</bdi> c <bdi>[d &#x05D4;?!]</bdi> &#x05D5;...</div>
+ <div dir="rtl">a <bdi>[1 2 3 &#x05D1;]</bdi> &#x05D2; <bdi>[&#x05D3; e?!]</bdi> f...</div>
+ </div>
+ <div class="ref">
+ <div dir="ltr">&#x202D;&#x05D0; [1 2 3 b] c [d &#x05D4;?!] &#x05D5;...&#x202C;</div>
+ <div dir="rtl">&#x202D;...f [!?e &#x05D3;] &#x05D2; [&#x05D1; 3 2 1] a&#x202C;</div>
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/text-level-semantics/the-bdo-element/.gitkeep b/testing/web-platform/tests/html/semantics/text-level-semantics/the-bdo-element/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/text-level-semantics/the-bdo-element/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/text-level-semantics/the-bdo-element/bdo-child.html b/testing/web-platform/tests/html/semantics/text-level-semantics/the-bdo-element/bdo-child.html
new file mode 100644
index 000000000..feadc26d7
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/text-level-semantics/the-bdo-element/bdo-child.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>HTML Test: bdo - text directionality formatting control for its children</title>
+ <link rel="author" title="Intel" href="http://www.intel.com/">
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-bdo-element">
+ <link rel="match" href="bidi-001-ref.html">
+ <meta name="assert" content="Check if the bdo element represents explicit text directionality formatting control for its children.">
+ </head>
+ <body>
+ <p>Test passes if there is text 'WERBEH'.</p>
+ <bdo dir="rtl">
+ <span>HEBREW</span>
+ </bdo>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/text-level-semantics/the-bdo-element/bdo-ltr.html b/testing/web-platform/tests/html/semantics/text-level-semantics/the-bdo-element/bdo-ltr.html
new file mode 100644
index 000000000..8a7861086
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/text-level-semantics/the-bdo-element/bdo-ltr.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>HTML Test: The value 'ltr' of dir attribute specifies a left-to-right override</title>
+ <link rel="author" title="Intel" href="http://www.intel.com/">
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-bdo-element">
+ <link rel="match" href="bidi-001-ref.html">
+ <meta name="assert" content="Check if the value ltr of dir attribute specifies a left-to-right override">
+ </head>
+ <body>
+ <p>Test passes if there is text 'WERBEH'.</p>
+ <bdo dir="ltr">WERBEH</bdo>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/text-level-semantics/the-bdo-element/bdo-override.html b/testing/web-platform/tests/html/semantics/text-level-semantics/the-bdo-element/bdo-override.html
new file mode 100644
index 000000000..75a45e198
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/text-level-semantics/the-bdo-element/bdo-override.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <title>HTML Test: bdo - override the Unicode bidirectional algorithm</title>
+ <link rel="author" title="Intel" href="http://www.intel.com/">
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-bdo-element">
+ <link rel="match" href="bidi-001-ref.html">
+ <meta name="assert" content="Check if authors could override the Unicode bidirectional algorithm
+ by explicitly specifying a direction override of bdo element">
+ </head>
+ <body>
+ <p>Test passes if there is text 'WERBEH'.</p>
+ <p>
+ &#x202E;<bdo dir="ltr">WERBEH</bdo>&#x202C;
+ </p>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/text-level-semantics/the-bdo-element/bidi-001-ref.html b/testing/web-platform/tests/html/semantics/text-level-semantics/the-bdo-element/bidi-001-ref.html
new file mode 100644
index 000000000..83d2dc4a1
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/text-level-semantics/the-bdo-element/bidi-001-ref.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="UTF-8">
+<title>directional type reference</title>
+</head>
+<body>
+<p>Test passes if there is text 'WERBEH'.</p>
+<div>WERBEH</div>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/text-level-semantics/the-bdo-element/bidi-001.html b/testing/web-platform/tests/html/semantics/text-level-semantics/the-bdo-element/bidi-001.html
new file mode 100644
index 000000000..772dcf43b
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/text-level-semantics/the-bdo-element/bidi-001.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="UTF-8">
+<title>directional type</title>
+<meta content="W3C" name="author">
+<link rel="match" href="bidi-001-ref.html">
+<meta name="assert" content="Test text bidirectionality using the bdo element">
+</head>
+<body dir='ltr'>
+<p>Test passes if there is text 'WERBEH'.</p>
+<bdo dir="rtl">HEBREW</bdo>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/text-level-semantics/the-br-element/.gitkeep b/testing/web-platform/tests/html/semantics/text-level-semantics/the-br-element/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/text-level-semantics/the-br-element/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/text-level-semantics/the-br-element/br-bidi-in-inline-ancestors-ref.html b/testing/web-platform/tests/html/semantics/text-level-semantics/the-br-element/br-bidi-in-inline-ancestors-ref.html
new file mode 100644
index 000000000..c2dd4daa7
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/text-level-semantics/the-br-element/br-bidi-in-inline-ancestors-ref.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <link rel="author" title="Aharon Lanin" href="mailto:aharon@google.com"/>
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com" />
+ <style>
+ body{
+ font-size:2em;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments { display: none; }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="comments">
+ Key to entities used below:
+ &#x05D0; ... &#x05D8; - The first nine Hebrew letters (strongly RTL).
+ &#x202D; - The LRO (left-to-right override) formatting character.
+ &#x202C; - The PDF (pop directional formatting) formatting character; closes LRO.
+ </div>
+ <div class="test">
+ &#x202D;&#x05D0;&#x05D1; &#x05D2;&#x05D3; 1. I like &#x05D4;. fg hi&#x202C;
+ <br/>
+ &#x202D;ab cd 2. &#x05D4; is great! &#x05D5;&#x05D6; &#x05D7;&#x05D8;&#x202C;
+ </div>
+ <div class="ref">
+ &#x202D;&#x05D0;&#x05D1; &#x05D2;&#x05D3; 1. I like &#x05D4;. fg hi&#x202C;
+ <br/>
+ &#x202D;ab cd 2. &#x05D4; is great! &#x05D5;&#x05D6; &#x05D7;&#x05D8;&#x202C;
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/text-level-semantics/the-br-element/br-bidi-in-inline-ancestors.html b/testing/web-platform/tests/html/semantics/text-level-semantics/the-br-element/br-bidi-in-inline-ancestors.html
new file mode 100644
index 000000000..89e7f2f1a
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/text-level-semantics/the-br-element/br-bidi-in-inline-ancestors.html
@@ -0,0 +1,59 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>HTML Test: BR in inline ancestors</title>
+ <link rel="match" href="br-bidi-in-inline-ancestors-ref.html">
+ <link rel="author" title="Aharon Lanin" href="mailto:aharon@google.com"/>
+ <link rel="author" title="HTML5 bidi test WG" href="mailto:html5bidi@googlegroups.com" />
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-br-element"/>
+ <link rel="help" href="http://www.w3.org/TR/css3-writing-modes/#unicode-bidi" />
+ <meta name="assert" content="
+ 'A br element should separate paragraphs for the purposes of the Unicode bidirectional
+ algorithm.'
+ 'If an inline element is broken around a bidi paragraph boundary (e.g. if split by a block or
+ forced paragraph break), then the bidi control codes corresponding to the end of the element
+ are added before the interruption and the codes corresponding to the start of the element are
+ added after it. (In other words, any embedding levels or overrides started by the element are
+ closed at the paragraph break and reopened on the other side of it.)'" />
+ <style>
+ body{
+ font-size:2em;
+ }
+ .test, .ref {
+ border: medium solid gray;
+ width: 400px;
+ margin: 20px;
+ }
+ .comments { display: none; }
+ </style>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the two boxes below look exactly the same.</p></div>
+ <div class="comments">
+ Key to entities used below:
+ &#x05D0; ... &#x05D8; - The first nine Hebrew letters (strongly RTL).
+ &#x200E; - The LRM (left-to-right mark) formatting character (invisible, stronly LTR).
+ &#x200F; - The RLM (right-to-left mark) formatting character (invisible, stronly RTL).
+ &#x202D; - The LRO (left-to-right override) formatting character.
+ &#x202C; - The PDF (pop directional formatting) formatting character; closes LRO.
+ </div>
+ <div class="test">
+ &#x05D1;&#x05D0;&#x200E;
+ <bdo dir="rtl">ih
+ <bdo dir="ltr">&#x05D2;&#x05D3;
+ <span dir="rtl">fg&#x200F;
+ <span dir="ltr">1. I like &#x05D4;.<br/>
+ 2. &#x05D4; is great!</span>
+ &#x200F;cd</span>
+ &#x05D5;&#x05D6;</bdo>
+ ba</bdo>
+ &#x200E;&#x05D8;&#x05D7;
+ </div>
+ <div class="ref">
+ &#x202D;&#x05D0;&#x05D1; &#x05D2;&#x05D3; 1. I like &#x05D4;. fg hi&#x202C;
+ <br/>
+ &#x202D;ab cd 2. &#x05D4; is great! &#x05D5;&#x05D6; &#x05D7;&#x05D8;&#x202C;
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/text-level-semantics/the-br-element/br-bidi-ref.html b/testing/web-platform/tests/html/semantics/text-level-semantics/the-br-element/br-bidi-ref.html
new file mode 100644
index 000000000..f07c07791
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/text-level-semantics/the-br-element/br-bidi-ref.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>HTML Test reference: BR separates bidi paragraph</title>
+ <link rel="author" title="Amir E. Aharoni" href="mailto:amir.aharoni@mail.huji.ac.il"/>
+ <link rel="author" title="Eyal Sela" href="mailto:eyal@post.isoc.org.il"/>
+ <link rel="author" title="Aharon Lanin" href="mailto:aharon@google.com"/>
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-br-element"/>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the rightmost character in the first line below is a full stop and to the left of it is a Hebrew letter.</p></div>
+ <div class="test">
+ A Hebrew letter and a full stop: &#x05d0;.&lrm;
+ <br />
+ &#x05d0; this line begins with a Hebrew letter.
+ </div>
+</p>
+</body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/text-level-semantics/the-br-element/br-bidi.html b/testing/web-platform/tests/html/semantics/text-level-semantics/the-br-element/br-bidi.html
new file mode 100644
index 000000000..1dfa6836f
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/text-level-semantics/the-br-element/br-bidi.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8"/>
+ <title>HTML Test: BR separates bidi paragraph</title>
+ <link rel="match" href="br-bidi-ref.html">
+ <link rel="author" title="Amir E. Aharoni" href="mailto:amir.aharoni@mail.huji.ac.il"/>
+ <link rel="author" title="Eyal Sela" href="mailto:eyal@post.isoc.org.il"/>
+ <link rel="author" title="Aharon Lanin" href="mailto:aharon@google.com"/>
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-br-element"/>
+ <meta name="assert"
+ content="A br element should separate paragraphs for the purposes of the Unicode bidirectional algorithm."/>
+ </head>
+ <body>
+ <div class="instructions"><p>Test passes if the rightmost character in the first line below is a full stop and to the left of it is a Hebrew letter.</p></div>
+ <div class="test">
+ A Hebrew letter and a full stop: &#x05d0;.
+ <br />
+ &#x05d0; this line begins with a Hebrew letter.
+ </div>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/text-level-semantics/the-cite-element/.gitkeep b/testing/web-platform/tests/html/semantics/text-level-semantics/the-cite-element/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/text-level-semantics/the-cite-element/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/text-level-semantics/the-code-element/.gitkeep b/testing/web-platform/tests/html/semantics/text-level-semantics/the-code-element/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/text-level-semantics/the-code-element/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/text-level-semantics/the-data-element/data.value-001.html b/testing/web-platform/tests/html/semantics/text-level-semantics/the-data-element/data.value-001.html
new file mode 100644
index 000000000..9fc827b9b
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/text-level-semantics/the-data-element/data.value-001.html
@@ -0,0 +1,66 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>HTMLDataElement.value getting</title>
+ <link rel="author" title="ofekd" href="mailto:ofek@outlook.com">
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/semantics.html#dom-data-value">
+ <script src=/resources/testharness.js></script>
+ <script src=/resources/testharnessreport.js></script>
+ </head>
+ <body>
+ <div id="log"></div>
+ <div id="container">
+ <data value=""></data>
+ <data value="40">Forty</data>
+ </div>
+ <script>
+ var newData, datasArr, container;
+
+ container = document.getElementById('container')
+
+ newData = document.createElement('data');
+ newData.textContent = 'Five';
+ newData.setAttribute('value', '5');
+ container.appendChild(newData);
+
+ datasArr = container.getElementsByTagName('data');
+
+ test(function () {
+ test(function() {
+ assert_equals(datasArr[0].value, '');
+ }, 'data[value] #0 getter test');
+
+ test(function() {
+ assert_equals(datasArr[1].value, '40');
+ }, 'data[value] #1 getter test');
+
+ test(function() {
+ assert_equals(datasArr[2].value, '5');
+ }, 'data[value] #2 getter test');
+ }, 'Getter tests');
+
+ test(function () {
+ var i;
+
+ for (i = 0; i < datasArr.length; i++) {
+ datasArr[i].textContent = 'Twenty';
+ datasArr[i].value = 20;
+
+ test(function() {
+ assert_equals(datasArr[i].getAttribute('value'), '20');
+ }, 'data[value] #' + i + ' setter test');
+ }
+
+ newData = document.createElement('data');
+ newData.textContent = 'Twenty';
+ newData.value = '20';
+ container.appendChild(newData);
+
+ test(function() {
+ assert_equals(datasArr[3].getAttribute('value'), '20');
+ }, 'data[value] #3 setter test');
+
+ }, 'Setter tests');
+ </script>
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/text-level-semantics/the-dfn-element/.gitkeep b/testing/web-platform/tests/html/semantics/text-level-semantics/the-dfn-element/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/text-level-semantics/the-dfn-element/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/text-level-semantics/the-em-element/.gitkeep b/testing/web-platform/tests/html/semantics/text-level-semantics/the-em-element/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/text-level-semantics/the-em-element/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/text-level-semantics/the-i-element/.gitkeep b/testing/web-platform/tests/html/semantics/text-level-semantics/the-i-element/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/text-level-semantics/the-i-element/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/text-level-semantics/the-kbd-element/.gitkeep b/testing/web-platform/tests/html/semantics/text-level-semantics/the-kbd-element/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/text-level-semantics/the-kbd-element/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/text-level-semantics/the-mark-element/.gitkeep b/testing/web-platform/tests/html/semantics/text-level-semantics/the-mark-element/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/text-level-semantics/the-mark-element/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/text-level-semantics/the-q-element/.gitkeep b/testing/web-platform/tests/html/semantics/text-level-semantics/the-q-element/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/text-level-semantics/the-q-element/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/text-level-semantics/the-rp-element/.gitkeep b/testing/web-platform/tests/html/semantics/text-level-semantics/the-rp-element/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/text-level-semantics/the-rp-element/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/text-level-semantics/the-rt-element/.gitkeep b/testing/web-platform/tests/html/semantics/text-level-semantics/the-rt-element/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/text-level-semantics/the-rt-element/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/text-level-semantics/the-ruby-element/.gitkeep b/testing/web-platform/tests/html/semantics/text-level-semantics/the-ruby-element/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/text-level-semantics/the-ruby-element/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/text-level-semantics/the-s-element/.gitkeep b/testing/web-platform/tests/html/semantics/text-level-semantics/the-s-element/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/text-level-semantics/the-s-element/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/text-level-semantics/the-samp-element/.gitkeep b/testing/web-platform/tests/html/semantics/text-level-semantics/the-samp-element/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/text-level-semantics/the-samp-element/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/text-level-semantics/the-small-element/.gitkeep b/testing/web-platform/tests/html/semantics/text-level-semantics/the-small-element/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/text-level-semantics/the-small-element/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/text-level-semantics/the-span-element/.gitkeep b/testing/web-platform/tests/html/semantics/text-level-semantics/the-span-element/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/text-level-semantics/the-span-element/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/text-level-semantics/the-strong-element/.gitkeep b/testing/web-platform/tests/html/semantics/text-level-semantics/the-strong-element/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/text-level-semantics/the-strong-element/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/text-level-semantics/the-sub-and-sup-elements/.gitkeep b/testing/web-platform/tests/html/semantics/text-level-semantics/the-sub-and-sup-elements/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/text-level-semantics/the-sub-and-sup-elements/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/text-level-semantics/the-time-element/.gitkeep b/testing/web-platform/tests/html/semantics/text-level-semantics/the-time-element/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/text-level-semantics/the-time-element/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/text-level-semantics/the-time-element/001.html b/testing/web-platform/tests/html/semantics/text-level-semantics/the-time-element/001.html
new file mode 100644
index 000000000..e1cd0480a
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/text-level-semantics/the-time-element/001.html
@@ -0,0 +1,68 @@
+<!doctype html>
+<html>
+ <head>
+ <meta charset=utf-8>
+ <title>HTML time element API</title>
+ <style>
+#time { visibility: hidden; }
+ </style>
+ <link rel="help" href="https://html.spec.whatwg.org/multipage/#the-time-element">
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ </head>
+ <body>
+ <div id="log"></div>
+ <!-- intentionally nested to test parsing rules -->
+ <p id="time"><time pubdate datetime="2000-02-01T03:04:05Z">Dummy text <time>2001-06-07T<time>08:09<time></time></time>Z</time></time></p>
+ <script type="text/javascript">
+function makeTime(dateTime,contents,dateTimeProp) {
+ var timeEl = document.createElement('time');
+ if( dateTime ) {
+ timeEl.setAttribute('datetime',dateTime);
+ }
+ if( contents ) {
+ timeEl.innerHTML = contents;
+ }
+ if( dateTimeProp ) {
+ timeEl.dateTime = dateTimeProp;
+ }
+ return timeEl;
+}
+
+var timep = document.getElementById('time');
+var times = timep.getElementsByTagName('time');
+
+//TIME elements
+test(function () {
+ assert_equals( times.length, 4 );
+}, 'HTML parsing should locate 4 time elements in this document');
+test(function () {
+ assert_true( !!window.HTMLTimeElement );
+}, 'HTMLTimeElement should be exposed for prototyping');
+test(function () {
+ assert_true( makeTime() instanceof window.HTMLTimeElement, 'createElement variant' );
+ assert_true( times[0] instanceof window.HTMLTimeElement, 'HTML parsing variant' );
+}, 'the time elements should be instanceof HTMLTimeElement');
+
+//dateTime
+test(function () {
+ assert_equals( makeTime('2000-02-01T03:04:05Z','2001-02-01T03:04:05Z').dateTime, '2000-02-01T03:04:05Z' );
+}, 'the datetime attribute should be reflected by the .dateTime property');
+test(function () {
+ assert_equals( typeof makeTime().dateTime, 'string', 'typeof test' );
+ assert_equals( makeTime().dateTime, '', 'value test' );
+}, 'the dateTime IDL property should default to an empty string');
+test(function () {
+ assert_equals( makeTime(false,false,'2000-02-01T03:04:05Z').dateTime, '2000-02-01T03:04:05Z' );
+}, 'the dateTime property should be read/write');
+test(function () {
+ assert_equals( makeTime('go fish').dateTime, 'go fish' );
+}, 'the datetime attribute should be reflected by the .dateTime property even if it is invalid');
+test(function () {
+ assert_equals( makeTime(false,'2000-02-01T03:04:05Z').dateTime, '' );
+}, 'the datetime attribute should not reflect the textContent');
+
+ </script>
+
+ </body>
+</html>
diff --git a/testing/web-platform/tests/html/semantics/text-level-semantics/the-u-element/.gitkeep b/testing/web-platform/tests/html/semantics/text-level-semantics/the-u-element/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/text-level-semantics/the-u-element/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/text-level-semantics/the-var-element/.gitkeep b/testing/web-platform/tests/html/semantics/text-level-semantics/the-var-element/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/text-level-semantics/the-var-element/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/text-level-semantics/the-wbr-element/wbr-element-ref.html b/testing/web-platform/tests/html/semantics/text-level-semantics/the-wbr-element/wbr-element-ref.html
new file mode 100644
index 000000000..f167ea719
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/text-level-semantics/the-wbr-element/wbr-element-ref.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>The wbr element</title>
+<link rel="author" title="Denis Ah-Kang" href="mailto:denis@w3.org">
+<meta name="flags" content="ahem">
+<style>
+ p {font:15px/1 Ahem;}
+</style>
+<p>Loremipsumdolorsit<br>amet,consectetur<br>adipisicingelit,sed<br>doeiusmodtempor<br>incididuntutlaboreet<br>doloremagnaaliqua.Ut<br>enimadminimveniam,<br>quisnostrud<br>exercitationullamco<br>laborisnisiutaliquip<br>exeacommodo<br>consequat.Duisaute<br>iruredolorin<br>reprehenderitin<br>voluptatevelitesse<br>cillumdoloreeufugiat<br>nullapariatur.<br>Excepteursint<br>occaecatcupidatatnon<br>proident,suntinculpa<br>quiofficiadeserunt<br>mollitanimidest<br>laborum.</p>
diff --git a/testing/web-platform/tests/html/semantics/text-level-semantics/the-wbr-element/wbr-element.html b/testing/web-platform/tests/html/semantics/text-level-semantics/the-wbr-element/wbr-element.html
new file mode 100644
index 000000000..63f271615
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/text-level-semantics/the-wbr-element/wbr-element.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<title>The wbr element</title>
+<link rel="author" title="Denis Ah-Kang" href="mailto:denis@w3.org">
+<link rel=help href="https://html.spec.whatwg.org/multipage/#rendering">
+<link rel="match" href="wbr-element-ref.html">
+<meta name="flags" content="ahem">
+<style>
+ p {max-width: 300px; font:15px/1 Ahem;}
+</style>
+<p>AHEM_<wbr>ipsum<wbr>dolor<wbr>sit<wbr>amet,<wbr>consectetur<wbr>adipisicing<wbr>elit,<wbr>sed<wbr>do<wbr>eiusmod<wbr>tempor<wbr>incididunt<wbr>ut<wbr>labore<wbr>et<wbr>dolore<wbr>magna<wbr>aliqua.<wbr>Ut<wbr>enim<wbr>ad<wbr>minim<wbr>veniam,<wbr>quis<wbr>nostrud<wbr>exercitation<wbr>ullamco<wbr>laboris<wbr>nisi<wbr>ut<wbr>aliquip<wbr>ex<wbr>ea<wbr>commodo<wbr>consequat.<wbr>Duis<wbr>aute<wbr>irure<wbr>dolor<wbr>in<wbr>reprehenderit<wbr>in<wbr>voluptate<wbr>velit<wbr>esse<wbr>cillum<wbr>dolore<wbr>eu<wbr>fugiat<wbr>nulla<wbr>pariatur.<wbr>Excepteur<wbr>sint<wbr>occaecat<wbr>cupidatat<wbr>non<wbr>proident,<wbr>sunt<wbr>in<wbr>culpa<wbr>qui<wbr>officia<wbr>deserunt<wbr>mollit<wbr>anim<wbr>id<wbr>est<wbr>laborum.</p>
diff --git a/testing/web-platform/tests/html/semantics/text-level-semantics/usage-summary/.gitkeep b/testing/web-platform/tests/html/semantics/text-level-semantics/usage-summary/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/text-level-semantics/usage-summary/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/the-root-element/.gitkeep b/testing/web-platform/tests/html/semantics/the-root-element/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/the-root-element/.gitkeep
diff --git a/testing/web-platform/tests/html/semantics/the-root-element/the-html-element/.gitkeep b/testing/web-platform/tests/html/semantics/the-root-element/the-html-element/.gitkeep
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/the-root-element/the-html-element/.gitkeep