aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/pull-request-wpt-export.yml4
-rw-r--r--Cargo.lock94
-rw-r--r--Cargo.toml2
-rw-r--r--components/canvas/backend.rs5
-rw-r--r--components/canvas/canvas_data.rs25
-rw-r--r--components/canvas/raqote_backend.rs19
-rw-r--r--components/compositing/compositor.rs68
-rw-r--r--components/compositing/webview_renderer.rs117
-rw-r--r--components/devtools/actors/breakpoint.rs55
-rw-r--r--components/devtools/actors/browsing_context.rs9
-rw-r--r--components/devtools/actors/watcher.rs7
-rw-r--r--components/devtools/lib.rs1
-rw-r--r--components/net/fetch/methods.rs115
-rw-r--r--components/net/websocket_loader.rs19
-rw-r--r--components/script/body.rs5
-rw-r--r--components/script/devtools.rs2
-rw-r--r--components/script/dom/abortcontroller.rs33
-rw-r--r--components/script/dom/abortsignal.rs108
-rw-r--r--components/script/dom/element.rs66
-rw-r--r--components/script/dom/event.rs8
-rw-r--r--components/script/dom/eventsource.rs47
-rw-r--r--components/script/dom/eventtarget.rs10
-rw-r--r--components/script/dom/htmlhrelement.rs58
-rw-r--r--components/script/dom/htmlmediaelement.rs1001
-rw-r--r--components/script/dom/htmlselectelement.rs63
-rw-r--r--components/script/dom/node.rs66
-rw-r--r--components/script/dom/range.rs87
-rw-r--r--components/script/dom/readablestream.rs2
-rw-r--r--components/script/dom/xmlhttprequest.rs3
-rw-r--r--components/script/dom/xpathresult.rs2
-rw-r--r--components/script/script_thread.rs51
-rw-r--r--components/script/timers.rs16
-rw-r--r--components/script/webdriver_handlers.rs113
-rw-r--r--components/script/xpath/context.rs12
-rw-r--r--components/script/xpath/eval.rs88
-rw-r--r--components/script/xpath/eval_function.rs65
-rw-r--r--components/script/xpath/eval_value.rs14
-rw-r--r--components/script/xpath/parser.rs199
-rw-r--r--components/script_bindings/codegen/Bindings.conf4
-rw-r--r--components/script_bindings/webidls/AbortController.webidl2
-rw-r--r--components/script_bindings/webidls/HTMLHRElement.webidl15
-rw-r--r--components/shared/embedder/input_events.rs6
-rw-r--r--components/shared/embedder/webdriver.rs3
-rw-r--r--components/webdriver_server/actions.rs471
-rw-r--r--components/webdriver_server/lib.rs45
-rw-r--r--ports/servoshell/Cargo.toml4
-rw-r--r--ports/servoshell/desktop/app.rs6
-rw-r--r--ports/servoshell/desktop/egui_glue.rs4
-rw-r--r--ports/servoshell/desktop/headed_window.rs6
-rw-r--r--ports/servoshell/egl/ohos.rs8
-rw-r--r--python/servo/build_commands.py25
-rw-r--r--python/servo/command_base.py8
-rw-r--r--python/servo/package_commands.py3
-rw-r--r--python/servo/platform/build_target.py48
-rw-r--r--support/hitrace-bencher/runs.json45
-rw-r--r--tests/wpt/meta/MANIFEST.json1777
-rw-r--r--tests/wpt/meta/content-security-policy/connect-src/connect-src-syncxmlhttprequest-redirect-to-blocked.sub.html.ini3
-rw-r--r--tests/wpt/meta/content-security-policy/connect-src/connect-src-xmlhttprequest-redirect-to-blocked.sub.html.ini3
-rw-r--r--tests/wpt/meta/content-security-policy/gen/top.http-rp/script-src-self/script-tag.http.html.ini3
-rw-r--r--tests/wpt/meta/content-security-policy/gen/top.http-rp/script-src-self/script-tag.https.html.ini3
-rw-r--r--tests/wpt/meta/content-security-policy/gen/top.meta/script-src-self/script-tag.http.html.ini3
-rw-r--r--tests/wpt/meta/content-security-policy/gen/top.meta/script-src-self/script-tag.https.html.ini3
-rw-r--r--tests/wpt/meta/content-security-policy/generic/wildcard-host-part.sub.window.js.ini2
-rw-r--r--tests/wpt/meta/content-security-policy/inside-worker/dedicatedworker-connect-src.html.ini3
-rw-r--r--tests/wpt/meta/content-security-policy/reporting/report-original-url.sub.html.ini7
-rw-r--r--tests/wpt/meta/content-security-policy/securitypolicyviolation/img-src-redirect.sub.html.ini3
-rw-r--r--tests/wpt/meta/css/css-borders/tentative/corner-shape/corner-shape-render-fuzzy.html.ini3
-rw-r--r--tests/wpt/meta/css/css-borders/tentative/corner-shape/corner-shape-render-precise.html.ini6
-rw-r--r--tests/wpt/meta/css/css-conditional/container-queries/style-query-registered-custom-rem-change.html.ini3
-rw-r--r--tests/wpt/meta/css/css-gaps/grid/grid-gap-decorations-040.html.ini2
-rw-r--r--tests/wpt/meta/css/css-masking/clip-path/clip-path-shape-011.html.ini2
-rw-r--r--tests/wpt/meta/css/css-overflow/overflow-video.html.ini2
-rw-r--r--tests/wpt/meta/css/css-sizing/responsive-iframe-cross-origin.sub.tentative.html.ini2
-rw-r--r--tests/wpt/meta/css/css-sizing/responsive-iframe.tentative.html.ini2
-rw-r--r--tests/wpt/meta/css/css-tables/table-cell-overflow-auto-scrolled.html.ini2
-rw-r--r--tests/wpt/meta/css/css-text/text-autospace/text-autospace-vs-001.html.ini2
-rw-r--r--tests/wpt/meta/css/css-text/word-break/word-break-keep-all-u002d.html.ini2
-rw-r--r--tests/wpt/meta/css/css-values/if-conditionals.html.ini123
-rw-r--r--tests/wpt/meta/css/css-values/tree-counting/sibling-function-container-query-invalidation.html.ini12
-rw-r--r--tests/wpt/meta/css/css-values/tree-counting/sibling-index-keyframe-registered-properties-dynamic.html.ini6
-rw-r--r--tests/wpt/meta/custom-elements/registries/idlharness.window.js.ini39
-rw-r--r--tests/wpt/meta/dom/ranges/Range-in-shadow-after-the-shadow-removed.html.ini14
-rw-r--r--tests/wpt/meta/domxpath/fn-lang.html.ini21
-rw-r--r--tests/wpt/meta/domxpath/node-sets.html.ini3
-rw-r--r--tests/wpt/meta/domxpath/text-html-attributes.html.ini9
-rw-r--r--tests/wpt/meta/domxpath/xml_xpath_runner.html.ini3072
-rw-r--r--tests/wpt/meta/fetch/content-encoding/br/bad-br-body.https.any.js.ini12
-rw-r--r--tests/wpt/meta/fetch/content-encoding/gzip/bad-gzip-body.any.js.ini6
-rw-r--r--tests/wpt/meta/fetch/content-encoding/zstd/bad-zstd-body.https.any.js.ini6
-rw-r--r--tests/wpt/meta/fetch/metadata/redirect/multiple-redirect-https-downgrade-upgrade.sub.html.ini3
-rw-r--r--tests/wpt/meta/fetch/nosniff/importscripts.html.ini4
-rw-r--r--tests/wpt/meta/fetch/private-network-access/mixed-content-fetch.tentative.https.window.js.ini156
-rw-r--r--tests/wpt/meta/fetch/private-network-access/window-open-existing.tentative.https.window.js.ini72
-rw-r--r--tests/wpt/meta/focus/focus-contenteditable-element-in-iframe-scroll-into-view.html.ini3
-rw-r--r--tests/wpt/meta/html/browsers/browsing-the-web/navigating-across-documents/008.html.ini3
-rw-r--r--tests/wpt/meta/html/browsers/browsing-the-web/navigating-across-documents/009.html.ini3
-rw-r--r--tests/wpt/meta/html/browsers/history/the-history-interface/001.html.ini (renamed from tests/wpt/meta/webdriver/tests/classic/set_timeouts/set.py.ini)2
-rw-r--r--tests/wpt/meta/html/browsers/history/the-history-interface/traverse_the_history_3.html.ini3
-rw-r--r--tests/wpt/meta/html/canvas/element/manual/imagebitmap/createImageBitmap-origin.sub.html.ini1
-rw-r--r--tests/wpt/meta/html/canvas/element/manual/imagebitmap/createImageBitmap-transfer.html.ini1
-rw-r--r--tests/wpt/meta/html/dom/idlharness.https.html.ini12
-rw-r--r--tests/wpt/meta/html/dom/reflection-grouping.html.ini228
-rw-r--r--tests/wpt/meta/html/semantics/embedded-content/media-elements/media_fragment_seek.html.ini2
-rw-r--r--tests/wpt/meta/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_escaping-1.html.ini2
-rw-r--r--tests/wpt/meta/html/semantics/permission-element/negative-offset-and-margin.tentative.html.ini12
-rw-r--r--tests/wpt/meta/html/semantics/permission-element/negative-offset.tentative.html.ini9
-rw-r--r--tests/wpt/meta/html/semantics/permission-element/permission-icon/icon-hidden-reftest.html.ini2
-rw-r--r--tests/wpt/meta/html/semantics/permission-element/permission-icon/icon-unique-per-type-reftest.html.ini2
-rw-r--r--tests/wpt/meta/html/semantics/scripting-1/the-script-element/execution-timing/042.html.ini3
-rw-r--r--tests/wpt/meta/html/semantics/scripting-1/the-script-element/execution-timing/043.html.ini3
-rw-r--r--tests/wpt/meta/html/semantics/scripting-1/the-script-element/execution-timing/044.html.ini3
-rw-r--r--tests/wpt/meta/html/semantics/scripting-1/the-script-element/execution-timing/045.html.ini3
-rw-r--r--tests/wpt/meta/html/semantics/scripting-1/the-script-element/execution-timing/054.html.ini3
-rw-r--r--tests/wpt/meta/html/semantics/scripting-1/the-script-element/execution-timing/055.html.ini3
-rw-r--r--tests/wpt/meta/html/semantics/the-button-element/command-and-commandfor/source-attribute-retargeting.tentative.html.ini9
-rw-r--r--tests/wpt/meta/navigation-timing/test-navigation-type-reload.html.ini12
-rw-r--r--tests/wpt/meta/preload/preload-error.sub.html.ini15
-rw-r--r--tests/wpt/meta/resize-observer/change-layout-in-error.html.ini3
-rw-r--r--tests/wpt/meta/resize-observer/zoom.html.ini3
-rw-r--r--tests/wpt/meta/trusted-types/block-text-node-insertion-into-script-element.html.ini9
-rw-r--r--tests/wpt/meta/trusted-types/block-text-node-insertion-into-svg-script-element.html.ini3
-rw-r--r--tests/wpt/meta/uievents/legacy-domevents-tests/approved/ProcessingInstruction.DOMCharacterDataModified.html.ini3
-rw-r--r--tests/wpt/meta/uievents/legacy-domevents-tests/approved/domnodeinserted.html.ini4
-rw-r--r--tests/wpt/meta/urlpattern/urlpattern-generate.tentative.any.js.ini63
-rw-r--r--tests/wpt/meta/webaudio/the-audio-api/the-audiobuffersourcenode-interface/sub-sample-buffer-stitching.html.ini9
-rw-r--r--tests/wpt/meta/webdriver/tests/classic/accept_alert/accept.py.ini1
-rw-r--r--tests/wpt/meta/webdriver/tests/classic/dismiss_alert/dismiss.py.ini1
-rw-r--r--tests/wpt/meta/webdriver/tests/classic/element_clear/clear.py.ini210
-rw-r--r--tests/wpt/meta/webdriver/tests/classic/element_clear/disabled.py.ini1
-rw-r--r--tests/wpt/meta/webdriver/tests/classic/element_click/bubbling.py.ini6
-rw-r--r--tests/wpt/meta/webdriver/tests/classic/element_click/center_point.py.ini1
-rw-r--r--tests/wpt/meta/webdriver/tests/classic/element_click/click.py.ini6
-rw-r--r--tests/wpt/meta/webdriver/tests/classic/element_click/events.py.ini3
-rw-r--r--tests/wpt/meta/webdriver/tests/classic/element_click/interactability.py.ini1
-rw-r--r--tests/wpt/meta/webdriver/tests/classic/element_click/shadow_dom.py.ini6
-rw-r--r--tests/wpt/meta/webdriver/tests/classic/element_send_keys/events.py.ini3
-rw-r--r--tests/wpt/meta/webdriver/tests/classic/element_send_keys/file_upload.py.ini31
-rw-r--r--tests/wpt/meta/webdriver/tests/classic/element_send_keys/send_keys.py.ini6
-rw-r--r--tests/wpt/meta/webdriver/tests/classic/execute_async_script/arguments.py.ini78
-rw-r--r--tests/wpt/meta/webdriver/tests/classic/execute_async_script/execute_async.py.ini1
-rw-r--r--tests/wpt/meta/webdriver/tests/classic/execute_script/arguments.py.ini4
-rw-r--r--tests/wpt/meta/webdriver/tests/classic/execute_script/execute.py.ini1
-rw-r--r--tests/wpt/meta/webdriver/tests/classic/find_element/find.py.ini15
-rw-r--r--tests/wpt/meta/webdriver/tests/classic/find_element_from_shadow_root/find.py.ini3
-rw-r--r--tests/wpt/meta/webdriver/tests/classic/find_elements/find.py.ini52
-rw-r--r--tests/wpt/meta/webdriver/tests/classic/find_elements_from_element/find.py.ini51
-rw-r--r--tests/wpt/meta/webdriver/tests/classic/find_elements_from_shadow_root/find.py.ini3
-rw-r--r--tests/wpt/meta/webdriver/tests/classic/get_computed_role/get.py.ini6
-rw-r--r--tests/wpt/meta/webdriver/tests/classic/get_element_attribute/get.py.ini30
-rw-r--r--tests/wpt/meta/webdriver/tests/classic/get_element_css_value/get.py.ini6
-rw-r--r--tests/wpt/meta/webdriver/tests/classic/get_element_property/get.py.ini84
-rw-r--r--tests/wpt/meta/webdriver/tests/classic/get_element_rect/get.py.ini6
-rw-r--r--tests/wpt/meta/webdriver/tests/classic/get_element_tag_name/get.py.ini6
-rw-r--r--tests/wpt/meta/webdriver/tests/classic/get_element_text/get.py.ini6
-rw-r--r--tests/wpt/meta/webdriver/tests/classic/is_element_enabled/enabled.py.ini18
-rw-r--r--tests/wpt/meta/webdriver/tests/classic/is_element_selected/selected.py.ini5
-rw-r--r--tests/wpt/meta/webdriver/tests/classic/new_session/unhandled_prompt_behavior.py.ini1
-rw-r--r--tests/wpt/meta/webdriver/tests/classic/perform_actions/key.py.ini13
-rw-r--r--tests/wpt/meta/webdriver/tests/classic/perform_actions/key_events.py.ini261
-rw-r--r--tests/wpt/meta/webdriver/tests/classic/perform_actions/key_modifiers.py.ini6
-rw-r--r--tests/wpt/meta/webdriver/tests/classic/perform_actions/key_shortcuts.py.ini3
-rw-r--r--tests/wpt/meta/webdriver/tests/classic/perform_actions/key_special_keys.py.ini3
-rw-r--r--tests/wpt/meta/webdriver/tests/classic/perform_actions/navigation.py.ini1
-rw-r--r--tests/wpt/meta/webdriver/tests/classic/perform_actions/pointer_contextmenu.py.ini6
-rw-r--r--tests/wpt/meta/webdriver/tests/classic/perform_actions/pointer_dblclick.py.ini9
-rw-r--r--tests/wpt/meta/webdriver/tests/classic/perform_actions/pointer_modifier_click.py.ini14
-rw-r--r--tests/wpt/meta/webdriver/tests/classic/perform_actions/pointer_mouse.py.ini1
-rw-r--r--tests/wpt/meta/webdriver/tests/classic/perform_actions/pointer_pen.py.ini1
-rw-r--r--tests/wpt/meta/webdriver/tests/classic/perform_actions/pointer_touch.py.ini1
-rw-r--r--tests/wpt/meta/webdriver/tests/classic/release_actions/sequence_tentative.py.ini1
-rw-r--r--tests/wpt/meta/webdriver/tests/classic/set_window_rect/set.py.ini20
-rw-r--r--tests/wpt/meta/webdriver/tests/classic/switch_to_frame/switch.py.ini3
-rw-r--r--tests/wpt/meta/webdriver/tests/classic/switch_to_parent_frame/switch.py.ini3
-rw-r--r--tests/wpt/meta/webdriver/tests/classic/switch_to_window/alerts.py.ini1
-rw-r--r--tests/wpt/meta/webdriver/tests/classic/switch_to_window/switch.py.ini1
-rw-r--r--tests/wpt/meta/webdriver/tests/classic/take_element_screenshot/iframe.py.ini6
-rw-r--r--tests/wpt/meta/webdriver/tests/classic/take_screenshot/iframe.py.ini9
-rw-r--r--tests/wpt/meta/webdriver/tests/classic/take_screenshot/screenshot.py.ini3
-rw-r--r--tests/wpt/meta/websockets/stream/tentative/write.any.js.ini118
-rw-r--r--tests/wpt/meta/workers/constructors/Worker/Worker-constructor.html.ini2
-rw-r--r--tests/wpt/meta/workers/tentative/SharedWorker-extendedLifetime.html.ini3
-rw-r--r--tests/wpt/meta/xhr/abort-during-done.window.js.ini9
-rw-r--r--tests/wpt/meta/xhr/abort-during-headers-received.window.js.ini3
-rw-r--r--tests/wpt/meta/xhr/abort-during-loading.window.js.ini3
-rw-r--r--tests/wpt/tests/client-hints/permissions-policy/WEB_FEATURES.yml6
-rw-r--r--tests/wpt/tests/container-timing/resources/container-timing-helpers.js16
-rw-r--r--tests/wpt/tests/container-timing/tentative/containertiming-with-child-ignore-and-child-img.html46
-rw-r--r--tests/wpt/tests/container-timing/tentative/containertiming-with-ignore-and-child-img.html45
-rw-r--r--tests/wpt/tests/container-timing/tentative/ignore-with-containertiming-and-child-img.html49
-rw-r--r--tests/wpt/tests/content-security-policy/default-src/default-src-sri_hash.sub.html5
-rw-r--r--tests/wpt/tests/content-security-policy/script-src/script-src-sri_hash.sub.html5
-rw-r--r--tests/wpt/tests/content-security-policy/script-src/script-src-strict_dynamic_parser_inserted.html5
-rw-r--r--tests/wpt/tests/content-security-policy/script-src/script-src-strict_dynamic_parser_inserted.html.headers2
-rw-r--r--tests/wpt/tests/cookie-store/META.yml3
-rw-r--r--tests/wpt/tests/cookie-store/cookieStore_special_names.https.any.js36
-rw-r--r--tests/wpt/tests/cookie-store/encoding.https.any.js10
-rw-r--r--tests/wpt/tests/cookie-store/httponly_cookies.https.window.js13
-rw-r--r--tests/wpt/tests/cookie-store/resources/cookie-test-helpers.js10
-rw-r--r--tests/wpt/tests/css/css-anchor-position/anchor-scope-basic.html12
-rw-r--r--tests/wpt/tests/css/css-anchor-position/chrome-420329041-crash.html13
-rw-r--r--tests/wpt/tests/css/css-borders/tentative/corner-shape/corner-shape-img-ref.html12
-rw-r--r--tests/wpt/tests/css/css-borders/tentative/corner-shape/corner-shape-img.html13
-rw-r--r--tests/wpt/tests/css/css-borders/tentative/corner-shape/corner-shape-render-fuzzy.html2
-rw-r--r--tests/wpt/tests/css/css-borders/tentative/corner-shape/corner-shape-render-precise.html5
-rw-r--r--tests/wpt/tests/css/css-borders/tentative/corner-shape/resources/corner-shape.js115
-rw-r--r--tests/wpt/tests/css/css-borders/tentative/corner-shape/resources/corner-utils.js18
-rw-r--r--tests/wpt/tests/css/css-color-hdr/parsing.html2
-rw-r--r--tests/wpt/tests/css/css-conditional/container-queries/style-query-registered-custom-rem-change.html34
-rw-r--r--tests/wpt/tests/css/css-flexbox/flexbox_columns-ref.html10
-rw-r--r--tests/wpt/tests/css/css-flexbox/flexbox_columns.html27
-rw-r--r--tests/wpt/tests/css/css-forms/datetime-stacking-context-ref.html12
-rw-r--r--tests/wpt/tests/css/css-forms/datetime-stacking-context.html16
-rw-r--r--tests/wpt/tests/css/css-gaps/grid/grid-gap-decorations-040-ref.html88
-rw-r--r--tests/wpt/tests/css/css-gaps/grid/grid-gap-decorations-040.html35
-rw-r--r--tests/wpt/tests/css/css-gaps/grid/grid-gap-decorations-041-crash.html16
-rw-r--r--tests/wpt/tests/css/css-gaps/grid/grid-gap-decorations-042-ref.html28
-rw-r--r--tests/wpt/tests/css/css-gaps/grid/grid-gap-decorations-042.html36
-rw-r--r--tests/wpt/tests/css/css-grid/grid-items/grid-item-inline-contribution-004.html34
-rw-r--r--tests/wpt/tests/css/css-highlight-api/HighlightRegistry-highlightsFromPoint-ranges.html109
-rw-r--r--tests/wpt/tests/css/css-highlight-api/HighlightRegistry-highlightsFromPoint.html35
-rw-r--r--tests/wpt/tests/css/css-masking/animations/clip-path-interpolation-shape-arc-direction-agnostic-radius-ref.html26
-rw-r--r--tests/wpt/tests/css/css-masking/animations/clip-path-interpolation-shape-arc-direction-agnostic-radius.html29
-rw-r--r--tests/wpt/tests/css/css-masking/animations/clip-path-interpolation-shape.html49
-rw-r--r--tests/wpt/tests/css/css-masking/clip-path/clip-path-shape-011.html27
-rw-r--r--tests/wpt/tests/css/css-masking/clip-path/reference/clip-path-shape-arc-ref.html25
-rw-r--r--tests/wpt/tests/css/css-masking/parsing/clip-path-shape-parsing.html6
-rw-r--r--tests/wpt/tests/css/css-multicol/column-height-009-ref.html2
-rw-r--r--tests/wpt/tests/css/css-multicol/crashtests/repeated-table-column.html17
-rw-r--r--tests/wpt/tests/css/css-multicol/parsing/column-rule-color-invalid.html1
-rw-r--r--tests/wpt/tests/css/css-multicol/parsing/column-rule-style-invalid.html1
-rw-r--r--tests/wpt/tests/css/css-multicol/parsing/column-rule-width-invalid.html1
-rw-r--r--tests/wpt/tests/css/css-position/overlay/WEB_FEATURES.yml3
-rw-r--r--tests/wpt/tests/css/css-sizing/contain-intrinsic-size/parsing/from-element.tentative.html18
-rw-r--r--tests/wpt/tests/css/css-sizing/image-max-width-and-height-behaves-as-auto.html25
-rw-r--r--tests/wpt/tests/css/css-sizing/resources/iframe-contents-unsized.html7
-rw-r--r--tests/wpt/tests/css/css-sizing/resources/iframe-contents.html8
-rw-r--r--tests/wpt/tests/css/css-sizing/responsive-iframe-cross-origin-no-match-element.sub.tentative.html12
-rw-r--r--tests/wpt/tests/css/css-sizing/responsive-iframe-cross-origin-not-embedded-sized.sub.tentative.html13
-rw-r--r--tests/wpt/tests/css/css-sizing/responsive-iframe-cross-origin.sub.tentative.html13
-rw-r--r--tests/wpt/tests/css/css-sizing/responsive-iframe-no-match-element.html12
-rw-r--r--tests/wpt/tests/css/css-sizing/responsive-iframe-not-embedded-sized.tentative.html13
-rw-r--r--tests/wpt/tests/css/css-sizing/responsive-iframe-ref.html10
-rw-r--r--tests/wpt/tests/css/css-sizing/responsive-iframe-unsized-ref.html10
-rw-r--r--tests/wpt/tests/css/css-sizing/responsive-iframe.tentative.html13
-rw-r--r--tests/wpt/tests/css/css-text/text-autospace/text-autospace-edit-001-ref.html15
-rw-r--r--tests/wpt/tests/css/css-text/text-autospace/text-autospace-edit-001.html35
-rw-r--r--tests/wpt/tests/css/css-text/text-autospace/text-autospace-vs-001-ref.html23
-rw-r--r--tests/wpt/tests/css/css-text/text-autospace/text-autospace-vs-001.html19
-rw-r--r--tests/wpt/tests/css/css-text/word-break/reference/word-break-keep-all-u002d-ref.html11
-rw-r--r--tests/wpt/tests/css/css-text/word-break/word-break-keep-all-u002d.html14
-rw-r--r--tests/wpt/tests/css/css-typed-om/the-stylepropertymap/properties/column-rule-style.html40
-rw-r--r--tests/wpt/tests/css/css-typed-om/the-stylepropertymap/properties/column-rule-width.html19
-rw-r--r--tests/wpt/tests/css/css-values/if-conditionals.html131
-rw-r--r--tests/wpt/tests/css/css-values/tree-counting/sibling-function-container-query-invalidation.html92
-rw-r--r--tests/wpt/tests/css/css-values/tree-counting/sibling-index-keyframe-registered-properties-dynamic.html9
-rw-r--r--tests/wpt/tests/css/css-view-transitions/auto-name-from-id.html6
-rw-r--r--tests/wpt/tests/css/css-view-transitions/auto-name-get-animations.html18
-rw-r--r--tests/wpt/tests/css/css-view-transitions/inline-child-with-composited-filter-ref.html31
-rw-r--r--tests/wpt/tests/css/css-view-transitions/inline-child-with-composited-filter.html57
-rw-r--r--tests/wpt/tests/css/css-view-transitions/inline-with-offset-from-containing-block.html2
-rw-r--r--tests/wpt/tests/css/css-view-transitions/navigation/resources/auto-name-from-id.html5
-rw-r--r--tests/wpt/tests/css/css-view-transitions/nested/nested-exit.tentative.html4
-rw-r--r--tests/wpt/tests/css/css-view-transitions/nested/resources/compute-common.css3
-rw-r--r--tests/wpt/tests/css/css-view-transitions/nested/rounded-border-clipper.html3
-rw-r--r--tests/wpt/tests/css/css-view-transitions/new-content-captures-different-size.html2
-rw-r--r--tests/wpt/tests/css/css-view-transitions/pseudo-with-classes-view-transition-group.html5
-rw-r--r--tests/wpt/tests/css/css-view-transitions/scoped/crashtests/participating-scope.html25
-rw-r--r--tests/wpt/tests/css/css-view-transitions/scoped/nested-scope-ref.html2
-rw-r--r--tests/wpt/tests/css/css-view-transitions/scoped/nested-scope.html13
-rw-r--r--tests/wpt/tests/css/css-viewport/zoom/height.html12
-rw-r--r--tests/wpt/tests/css/css-viewport/zoom/inherited-length.html4
-rw-r--r--tests/wpt/tests/css/css-viewport/zoom/length-implicit-and-explicit-inheritance.html38
-rw-r--r--tests/wpt/tests/css/css-viewport/zoom/max-height.html12
-rw-r--r--tests/wpt/tests/css/css-viewport/zoom/max-width.html12
-rw-r--r--tests/wpt/tests/css/css-viewport/zoom/min-height.html12
-rw-r--r--tests/wpt/tests/css/css-viewport/zoom/min-width.html12
-rw-r--r--tests/wpt/tests/css/css-writing-modes/orthogonal-cell-001-ref.html32
-rw-r--r--tests/wpt/tests/css/css-writing-modes/orthogonal-cell-001.html38
-rw-r--r--tests/wpt/tests/css/motion/animation/offset-path-interpolation-008.html38
-rw-r--r--tests/wpt/tests/css/motion/parsing/offset-path-shape-computed.html4
-rw-r--r--tests/wpt/tests/css/motion/parsing/offset-path-shape-parsing.html4
-rw-r--r--tests/wpt/tests/css/selectors/visited-nested-ref.html (renamed from tests/wpt/tests/css/visited-nested-ref.html)0
-rw-r--r--tests/wpt/tests/css/selectors/visited-nested.html (renamed from tests/wpt/tests/css/visited-nested.html)0
-rw-r--r--tests/wpt/tests/domxpath/fn-id.html47
-rw-r--r--tests/wpt/tests/editing/crashtests/indent-outdent-after-closing-editable-dialog-element.html31
-rw-r--r--tests/wpt/tests/editing/other/move-inserted-node-from-DOMNodeInserted-during-exec-command-insertHTML.html27
-rw-r--r--tests/wpt/tests/fetch/content-encoding/br/bad-br-body.https.any.js5
-rw-r--r--tests/wpt/tests/fetch/content-encoding/gzip/bad-gzip-body.any.js1
-rw-r--r--tests/wpt/tests/fetch/content-encoding/zstd/bad-zstd-body.https.any.js1
-rw-r--r--tests/wpt/tests/fetch/local-network-access/resources/fetch-private-http.html3
-rw-r--r--tests/wpt/tests/fetch/local-network-access/resources/fetch-public-http-wrong-address-space.html3
-rw-r--r--tests/wpt/tests/fetch/private-network-access/mixed-content-fetch.tentative.https.window.js278
-rw-r--r--tests/wpt/tests/fetch/private-network-access/window-open-existing.tentative.https.window.js209
-rw-r--r--tests/wpt/tests/focus/focus-contenteditable-element-in-iframe-scroll-into-view.html74
-rw-r--r--tests/wpt/tests/html/editing/dnd/events/ua-shadow-contents-manual.html22
-rw-r--r--tests/wpt/tests/html/rendering/non-replaced-elements/the-hr-element-0/size-ref.html20
-rw-r--r--tests/wpt/tests/html/rendering/non-replaced-elements/the-hr-element-0/size-with-color-or-noshade-ref.html17
-rw-r--r--tests/wpt/tests/html/rendering/non-replaced-elements/the-hr-element-0/size-with-color-or-noshade.html15
-rw-r--r--tests/wpt/tests/html/rendering/non-replaced-elements/the-hr-element-0/size.html13
-rw-r--r--tests/wpt/tests/html/semantics/embedded-content/the-img-element/decode/image-decode-path-changes-svg.tentative.html24
-rw-r--r--tests/wpt/tests/html/semantics/embedded-content/the-img-element/decode/image-decode-with-quick-attach-svg.tentative.html4
-rw-r--r--tests/wpt/tests/html/semantics/embedded-content/the-img-element/naturalWidth-naturalHeight-unavailable.tentative.html52
-rw-r--r--tests/wpt/tests/html/semantics/forms/the-select-element/customizable-select/select-highlight-crash.html15
-rw-r--r--tests/wpt/tests/html/semantics/permission-element/negative-offset-and-margin.tentative.html68
-rw-r--r--tests/wpt/tests/html/semantics/permission-element/negative-offset.tentative.html79
-rw-r--r--tests/wpt/tests/html/semantics/permission-element/no-focus.tentative.html37
-rw-r--r--tests/wpt/tests/html/semantics/permission-element/permission-icon/icon-hidden-reftest.html11
-rw-r--r--tests/wpt/tests/html/semantics/permission-element/permission-icon/icon-unique-per-type-reftest.html6
-rw-r--r--tests/wpt/tests/html/semantics/permission-element/permission-icon/standard-location-permission-element-ref.html4
-rw-r--r--tests/wpt/tests/html/semantics/popovers/popover-root-crash.html7
-rw-r--r--tests/wpt/tests/html/semantics/scripting-1/the-script-element/execution-timing/042.html29
-rw-r--r--tests/wpt/tests/html/semantics/scripting-1/the-script-element/execution-timing/043.html31
-rw-r--r--tests/wpt/tests/html/semantics/scripting-1/the-script-element/execution-timing/044.html28
-rw-r--r--tests/wpt/tests/html/semantics/scripting-1/the-script-element/execution-timing/045.html28
-rw-r--r--tests/wpt/tests/html/semantics/scripting-1/the-script-element/execution-timing/054.html33
-rw-r--r--tests/wpt/tests/html/semantics/scripting-1/the-script-element/execution-timing/055.html32
-rw-r--r--tests/wpt/tests/html/semantics/scripting-1/the-script-element/json-module/invalid-content-type.any.js6
-rw-r--r--tests/wpt/tests/html/semantics/scripting-1/the-script-element/json-module/valid-content-type.html10
-rw-r--r--tests/wpt/tests/html/semantics/the-button-element/command-and-commandfor/source-attribute-retargeting.tentative.html132
-rw-r--r--tests/wpt/tests/html/webappapis/system-state-and-capabilities/the-navigator-object/WEB_FEATURES.yml4
-rw-r--r--tests/wpt/tests/interfaces/scoped-custom-elements-registry.idl38
-rw-r--r--tests/wpt/tests/layout-instability/WEB_FEATURES.yml3
-rw-r--r--tests/wpt/tests/lint.ignore1
-rw-r--r--tests/wpt/tests/network-error-logging/support/nel.sub.js19
-rw-r--r--tests/wpt/tests/pointerevents/persistentDeviceId/get-persistendeviceid-from-pointer-mouse-event.tentative.html42
-rw-r--r--tests/wpt/tests/resize-observer/zoom.html55
-rw-r--r--tests/wpt/tests/resource-timing/content-encoding.https.html8
-rw-r--r--tests/wpt/tests/resources/testdriver-actions.js.headers2
-rw-r--r--tests/wpt/tests/scroll-animations/animation-trigger/animation-trigger-repeat.tentative.html20
-rw-r--r--tests/wpt/tests/shadow-dom/HighlightRegistry-highlightsFromPoint.html57
-rw-r--r--tests/wpt/tests/soft-navigation-heuristics/first-interaction-not-softnav.tentative.html69
-rw-r--r--tests/wpt/tests/soft-navigation-heuristics/innertext.tentative.html37
-rw-r--r--tests/wpt/tests/soft-navigation-heuristics/resources/soft-navigation-helper.js4
-rw-r--r--tests/wpt/tests/soft-navigation-heuristics/smoke/tentative/dom.html30
-rw-r--r--tests/wpt/tests/soft-navigation-heuristics/smoke/tentative/resources/other_window.html19
-rw-r--r--tests/wpt/tests/soft-navigation-heuristics/smoke/tentative/window-open-cross-scheduling.html45
-rw-r--r--tests/wpt/tests/speculation-rules/prefetch/no-prefetch-for-post.https.html25
-rw-r--r--tests/wpt/tests/speculation-rules/prefetch/resources/executor.sub.html7
-rw-r--r--tests/wpt/tests/speculation-rules/prefetch/resources/post-navigation-handler.py10
-rw-r--r--tests/wpt/tests/speculation-rules/prerender/headers.https.html159
-rw-r--r--tests/wpt/tests/speculation-rules/prerender/resources/image-with-headers-stash.py45
-rw-r--r--tests/wpt/tests/svg/embedded/image-modify-href-4.svg30
-rw-r--r--tests/wpt/tests/tools/third_party_modified/mozlog/mozlog/handlers/base.py2
-rw-r--r--tests/wpt/tests/tools/wptrunner/wptrunner/browsers/firefox_android.py3
-rw-r--r--tests/wpt/tests/tools/wptrunner/wptrunner/browsers/headless_shell.py8
-rw-r--r--tests/wpt/tests/tools/wptrunner/wptrunner/browsers/servo.py5
-rw-r--r--tests/wpt/tests/tools/wptrunner/wptrunner/browsers/servodriver.py5
-rw-r--r--tests/wpt/tests/tools/wptrunner/wptrunner/executors/executorchrome.py4
-rw-r--r--tests/wpt/tests/tools/wptrunner/wptrunner/testrunner.py8
-rw-r--r--tests/wpt/tests/trusted-types/block-text-node-insertion-into-script-element.html28
-rw-r--r--tests/wpt/tests/trusted-types/block-text-node-insertion-into-svg-script-element.html24
-rw-r--r--tests/wpt/tests/trusted-types/resources/block-text-node-insertion.js7
-rw-r--r--tests/wpt/tests/ua-client-hints/WEB_FEATURES.yml3
-rw-r--r--tests/wpt/tests/uievents/legacy-domevents-tests/approved/ProcessingInstruction.DOMCharacterDataModified.html32
-rw-r--r--tests/wpt/tests/uievents/legacy-domevents-tests/approved/domnodeinserted.html26
-rw-r--r--tests/wpt/tests/urlpattern/resources/urlpattern-generate-test-data.json116
-rw-r--r--tests/wpt/tests/urlpattern/urlpattern-generate.tentative.any.js26
-rw-r--r--tests/wpt/tests/webnn/conformance_tests/cumulative_sum.https.any.js145
-rw-r--r--tests/wpt/tests/webnn/conformance_tests/linear.https.any.js469
-rw-r--r--tests/wpt/tests/webnn/conformance_tests/qdq_subgraph.https.any.js694
-rw-r--r--tests/wpt/tests/webnn/conformance_tests/subgraph.https.any.js39
-rw-r--r--tests/wpt/tests/webrtc-encoded-transform/tentative/RTCEncodedAudioFrame-metadata.https.html53
-rw-r--r--tests/wpt/tests/webrtc/RTCConfiguration-iceServers.html26
-rw-r--r--tests/wpt/tests/websockets/stream/tentative/remote-close.any.js3
-rw-r--r--tests/wpt/tests/websockets/stream/tentative/write.any.js96
-rw-r--r--tests/wpt/tests/workers/WEB_FEATURES.yml6
-rw-r--r--tests/wpt/tests/workers/tentative/SharedWorker-extendedLifetime.html61
-rw-r--r--tests/wpt/tests/workers/tentative/resources/shared-worker-memory.js30
-rw-r--r--tests/wpt/webgl/meta/conformance/textures/misc/tex-video-using-tex-unit-non-zero.html.ini6
-rw-r--r--tests/wpt/webgl/meta/conformance/textures/misc/texture-upload-size.html.ini72
370 files changed, 9309 insertions, 7235 deletions
diff --git a/.github/workflows/pull-request-wpt-export.yml b/.github/workflows/pull-request-wpt-export.yml
index aaab9d47907..2ac564dc12f 100644
--- a/.github/workflows/pull-request-wpt-export.yml
+++ b/.github/workflows/pull-request-wpt-export.yml
@@ -4,6 +4,10 @@ on:
types: ['opened', 'synchronize', 'reopened', 'edited', 'closed']
branches: ['main']
+concurrency:
+ group: ${{ github.head_ref }}
+ cancel-in-progress: false
+
jobs:
upstream:
# Run job only on servo/servo
diff --git a/Cargo.lock b/Cargo.lock
index 1590681f08a..7ff8a8ec2e6 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -199,9 +199,9 @@ checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299"
[[package]]
name = "anstream"
-version = "0.6.18"
+version = "0.6.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b"
+checksum = "301af1932e46185686725e0fad2f8f2aa7da69dd70bf6ecc44d6b703844a3933"
dependencies = [
"anstyle",
"anstyle-parse",
@@ -214,33 +214,33 @@ dependencies = [
[[package]]
name = "anstyle"
-version = "1.0.10"
+version = "1.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9"
+checksum = "862ed96ca487e809f1c8e5a8447f6ee2cf102f846893800b20cebdf541fc6bbd"
[[package]]
name = "anstyle-parse"
-version = "0.2.6"
+version = "0.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9"
+checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2"
dependencies = [
"utf8parse",
]
[[package]]
name = "anstyle-query"
-version = "1.1.2"
+version = "1.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c"
+checksum = "6c8bdeb6047d8983be085bab0ba1472e6dc604e7041dbf6fcd5e71523014fae9"
dependencies = [
"windows-sys 0.59.0",
]
[[package]]
name = "anstyle-wincon"
-version = "3.0.8"
+version = "3.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6680de5231bd6ee4c6191b8a1325daa282b415391ec9d3a37bd34f2060dc73fa"
+checksum = "403f75924867bb1033c59fbf0797484329750cfbe3c4325cd33127941fabc882"
dependencies = [
"anstyle",
"once_cell_polyfill",
@@ -1059,9 +1059,9 @@ checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b"
[[package]]
name = "colorchoice"
-version = "1.0.3"
+version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990"
+checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75"
[[package]]
name = "colored"
@@ -1070,7 +1070,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "117725a109d387c937a1533ce01b450cbde6b88abceea8473c4d7a85853cda3c"
dependencies = [
"lazy_static",
- "windows-sys 0.59.0",
+ "windows-sys 0.48.0",
]
[[package]]
@@ -1228,7 +1228,7 @@ dependencies = [
[[package]]
name = "content-security-policy"
version = "0.5.4"
-source = "git+https://github.com/servo/rust-content-security-policy/?branch=servo-csp#58a09ee320fd6fbb828748ae04255e4c8d3f9c9e"
+source = "git+https://github.com/servo/rust-content-security-policy/?branch=servo-csp#dc1fd32b2b32b704a43f4ae170bb2cbb80a7cf59"
dependencies = [
"base64 0.22.1",
"bitflags 2.9.1",
@@ -1595,7 +1595,7 @@ dependencies = [
"crossbeam-channel",
"devtools_traits",
"embedder_traits",
- "headers 0.4.0",
+ "headers 0.4.1",
"http 1.3.1",
"ipc-channel",
"log",
@@ -2025,7 +2025,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cea14ef9355e3beab063703aa9dab15afd25f0667c341310c1e5274bb1d0da18"
dependencies = [
"libc",
- "windows-sys 0.59.0",
+ "windows-sys 0.52.0",
]
[[package]]
@@ -2587,7 +2587,7 @@ dependencies = [
"gobject-sys",
"libc",
"system-deps",
- "windows-sys 0.59.0",
+ "windows-sys 0.52.0",
]
[[package]]
@@ -3158,11 +3158,11 @@ dependencies = [
[[package]]
name = "headers"
-version = "0.4.0"
+version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "322106e6bd0cba2d5ead589ddb8150a13d7c4217cf80d7c4f682ca994ccc6aa9"
+checksum = "b3314d5adb5d94bcdf56771f2e50dbbc80bb4bdf88967526706205ac9eff24eb"
dependencies = [
- "base64 0.21.7",
+ "base64 0.22.1",
"bytes",
"headers-core 0.3.0",
"http 1.3.1",
@@ -3197,12 +3197,6 @@ checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
[[package]]
name = "hermit-abi"
-version = "0.3.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024"
-
-[[package]]
-name = "hermit-abi"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc"
@@ -3416,9 +3410,9 @@ dependencies = [
[[package]]
name = "hyper-util"
-version = "0.1.13"
+version = "0.1.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b1c293b6b3d21eca78250dc7dbebd6b9210ec5530e038cbfe0661b5c47ab06e8"
+checksum = "dc2fdfdbff08affe55bb779f33b053aa1fe5dd5b54c257343c17edfa55711bdb"
dependencies = [
"bytes",
"futures-channel",
@@ -3440,7 +3434,7 @@ name = "hyper_serde"
version = "0.13.2"
dependencies = [
"cookie 0.18.1",
- "headers 0.4.0",
+ "headers 0.4.1",
"http 1.3.1",
"hyper 1.6.0",
"mime",
@@ -4046,7 +4040,7 @@ checksum = "e04d7f318608d35d4b61ddd75cbdaee86b023ebe2bd5a66ee0915f0bf93095a9"
dependencies = [
"hermit-abi 0.5.0",
"libc",
- "windows-sys 0.59.0",
+ "windows-sys 0.52.0",
]
[[package]]
@@ -4865,7 +4859,7 @@ dependencies = [
"futures-core",
"futures-util",
"generic-array",
- "headers 0.4.0",
+ "headers 0.4.1",
"http 1.3.1",
"http-body-util",
"hyper 1.6.0",
@@ -4918,7 +4912,7 @@ dependencies = [
"crossbeam-channel",
"data-url",
"embedder_traits",
- "headers 0.4.0",
+ "headers 0.4.1",
"http 1.3.1",
"hyper-util",
"hyper_serde",
@@ -5054,11 +5048,11 @@ dependencies = [
[[package]]
name = "num_cpus"
-version = "1.16.0"
+version = "1.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43"
+checksum = "91df4bbde75afed763b708b7eee1e8e7651e02d97f6d5dd763e89367e957b23b"
dependencies = [
- "hermit-abi 0.3.9",
+ "hermit-abi 0.5.0",
"libc",
]
@@ -5396,9 +5390,9 @@ dependencies = [
[[package]]
name = "ohos-ime"
-version = "0.3.0"
+version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ee3ea454e31a3372cd9c4ed903db4fae861e92f57cf51852a3cd80f9d3945dcd"
+checksum = "c28c803dbc0fa52e888c62c0a3573ea7559e5283ac10d1d3a75f064dba032575"
dependencies = [
"log",
"ohos-ime-sys",
@@ -5406,9 +5400,9 @@ dependencies = [
[[package]]
name = "ohos-ime-sys"
-version = "0.1.4"
+version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "58f68e03eb5b698781a69dc4918a17fe040a30be87de7014c12e4a2a3cb8a00f"
+checksum = "89d326ae2b2e71f95ca756b7d418c0adcb0018889e73f7eabed59671cb179608"
[[package]]
name = "ohos-sys-opaque-types"
@@ -5532,9 +5526,9 @@ dependencies = [
[[package]]
name = "parking_lot"
-version = "0.12.3"
+version = "0.12.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27"
+checksum = "70d58bf43669b5795d1576d0641cfb6fbb2057bf629506267a92807158584a13"
dependencies = [
"lock_api",
"parking_lot_core",
@@ -5848,9 +5842,9 @@ checksum = "e8cf8e6a8aa66ce33f63993ffc4ea4271eb5b0530a9002db8455ea6050c77bfa"
[[package]]
name = "prettyplease"
-version = "0.2.32"
+version = "0.2.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "664ec5419c51e34154eec046ebcba56312d5a2fc3b09a06da188e1ad21afadf6"
+checksum = "9dee91521343f4c5c6a63edd65e54f31f5c92fe8978c40a4282f8372194c6a7d"
dependencies = [
"proc-macro2",
"syn",
@@ -6268,7 +6262,7 @@ dependencies = [
"errno",
"libc",
"linux-raw-sys",
- "windows-sys 0.59.0",
+ "windows-sys 0.52.0",
]
[[package]]
@@ -6410,7 +6404,7 @@ dependencies = [
"fonts_traits",
"fxhash",
"glow",
- "headers 0.4.0",
+ "headers 0.4.1",
"html5ever",
"http 1.3.1",
"hyper_serde",
@@ -7027,7 +7021,7 @@ dependencies = [
"getopts",
"gilrs",
"glow",
- "headers 0.4.0",
+ "headers 0.4.1",
"hilog",
"hitrace",
"image",
@@ -7658,7 +7652,7 @@ dependencies = [
"getrandom",
"once_cell",
"rustix",
- "windows-sys 0.59.0",
+ "windows-sys 0.52.0",
]
[[package]]
@@ -9075,7 +9069,7 @@ version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb"
dependencies = [
- "windows-sys 0.59.0",
+ "windows-sys 0.48.0",
]
[[package]]
@@ -9800,9 +9794,9 @@ dependencies = [
[[package]]
name = "zune-jpeg"
-version = "0.4.14"
+version = "0.4.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "99a5bab8d7dedf81405c4bb1f2b83ea057643d9cb28778cea9eecddeedd2e028"
+checksum = "3e4a518c0ea2576f4da876349d7f67a7be489297cd77c2cf9e04c2e05fcd3974"
dependencies = [
"zune-core",
]
diff --git a/Cargo.toml b/Cargo.toml
index c290a21f1fc..0fc9d90bf14 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -100,7 +100,7 @@ mozangle = "0.5.3"
net_traits = { path = "components/shared/net" }
nix = "0.29"
num-traits = "0.2"
-num_cpus = "1.1.0"
+num_cpus = "1.17.0"
openxr = "0.19"
parking_lot = "0.12"
percent-encoding = "2.3"
diff --git a/components/canvas/backend.rs b/components/canvas/backend.rs
index 7e348fbc9b9..b7296b81ba3 100644
--- a/components/canvas/backend.rs
+++ b/components/canvas/backend.rs
@@ -2,6 +2,8 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
+use std::borrow::Cow;
+
use canvas_traits::canvas::{
CompositionOrBlending, FillOrStrokeStyle, LineCapStyle, LineJoinStyle,
};
@@ -21,7 +23,6 @@ pub(crate) trait Backend: Clone + Sized {
type DrawTarget: GenericDrawTarget<Self>;
type PathBuilder: GenericPathBuilder<Self>;
type SourceSurface;
- type Bytes<'a>: AsRef<[u8]>;
type Path: PathHelpers<Self> + Clone;
type GradientStop;
type GradientStops;
@@ -122,7 +123,7 @@ pub(crate) trait GenericDrawTarget<B: Backend> {
draw_options: &B::DrawOptions,
);
fn surface(&self) -> B::SourceSurface;
- fn bytes(&'_ self) -> B::Bytes<'_>;
+ fn bytes(&self) -> Cow<[u8]>;
}
/// A generic PathBuilder that abstracts the interface for azure's and raqote's PathBuilder.
diff --git a/components/canvas/canvas_data.rs b/components/canvas/canvas_data.rs
index ea30589d0af..0dff6744418 100644
--- a/components/canvas/canvas_data.rs
+++ b/components/canvas/canvas_data.rs
@@ -154,7 +154,18 @@ struct PathBuilderRef<'a, B: Backend> {
}
impl<B: Backend> PathBuilderRef<'_, B> {
+ /// <https://html.spec.whatwg.org/multipage#ensure-there-is-a-subpath>
+ fn ensure_there_is_a_subpath(&mut self, point: &Point2D<f32>) {
+ if self.builder.get_current_point().is_none() {
+ self.builder.move_to(*point);
+ }
+ }
+
+ /// <https://html.spec.whatwg.org/multipage#dom-context-2d-lineto>
fn line_to(&mut self, pt: &Point2D<f32>) {
+ // 2. If the object's path has no subpaths, then ensure there is a subpath for (x, y).
+ self.ensure_there_is_a_subpath(pt);
+
let pt = self.transform.transform_point(*pt);
self.builder.line_to(pt);
}
@@ -182,14 +193,22 @@ impl<B: Backend> PathBuilderRef<'_, B> {
self.move_to(&first);
}
+ /// <https://html.spec.whatwg.org/multipage#dom-context-2d-quadraticcurveto>
fn quadratic_curve_to(&mut self, cp: &Point2D<f32>, endpoint: &Point2D<f32>) {
+ // 2. Ensure there is a subpath for (cpx, cpy).
+ self.ensure_there_is_a_subpath(cp);
+
self.builder.quadratic_curve_to(
&self.transform.transform_point(*cp),
&self.transform.transform_point(*endpoint),
)
}
+ /// <https://html.spec.whatwg.org/multipage#dom-context-2d-beziercurveto>
fn bezier_curve_to(&mut self, cp1: &Point2D<f32>, cp2: &Point2D<f32>, endpoint: &Point2D<f32>) {
+ // 2. Ensure there is a subpath for (cp1x, cp1y).
+ self.ensure_there_is_a_subpath(cp1);
+
self.builder.bezier_curve_to(
&self.transform.transform_point(*cp1),
&self.transform.transform_point(*cp2),
@@ -210,6 +229,7 @@ impl<B: Backend> PathBuilderRef<'_, B> {
.arc(center, radius, start_angle, end_angle, ccw);
}
+ /// <https://html.spec.whatwg.org/multipage#dom-context-2d-arcto>
fn arc_to(&mut self, cp1: &Point2D<f32>, cp2: &Point2D<f32>, radius: f32) {
let cp0 = if let (Some(inverse), Some(point)) =
(self.transform.inverse(), self.builder.get_current_point())
@@ -218,6 +238,9 @@ impl<B: Backend> PathBuilderRef<'_, B> {
} else {
*cp1
};
+
+ // 2. Ensure there is a subpath for (x1, y1) is done by one of self.line_to calls
+
if (cp0.x == cp1.x && cp0.y == cp1.y) || cp1 == cp2 || radius == 0.0 {
self.line_to(cp1);
return;
@@ -1327,7 +1350,7 @@ impl<'a, B: Backend> CanvasData<'a, B> {
.to_vec()
}
} else {
- self.drawtarget.bytes().as_ref().to_vec()
+ self.drawtarget.bytes().into_owned()
};
Snapshot::from_vec(
diff --git a/components/canvas/raqote_backend.rs b/components/canvas/raqote_backend.rs
index ecf780c36d5..02d87dfcd54 100644
--- a/components/canvas/raqote_backend.rs
+++ b/components/canvas/raqote_backend.rs
@@ -2,6 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
+use std::borrow::Cow;
use std::cell::RefCell;
use std::collections::HashMap;
@@ -41,7 +42,6 @@ impl Backend for RaqoteBackend {
type DrawTarget = raqote::DrawTarget;
type PathBuilder = PathBuilder;
type SourceSurface = Vec<u8>; // TODO: See if we can avoid the alloc (probably?)
- type Bytes<'a> = &'a [u8];
type Path = raqote::Path;
type GradientStop = raqote::GradientStop;
type GradientStops = Vec<raqote::GradientStop>;
@@ -656,9 +656,11 @@ impl GenericDrawTarget<RaqoteBackend> for raqote::DrawTarget {
);
}
#[allow(unsafe_code)]
- fn bytes(&self) -> &[u8] {
+ fn bytes(&self) -> Cow<[u8]> {
let v = self.get_data();
- unsafe { std::slice::from_raw_parts(v.as_ptr() as *const u8, std::mem::size_of_val(v)) }
+ Cow::Borrowed(unsafe {
+ std::slice::from_raw_parts(v.as_ptr() as *const u8, std::mem::size_of_val(v))
+ })
}
}
@@ -708,7 +710,7 @@ impl GenericPathBuilder<RaqoteBackend> for PathBuilder {
PathOp::MoveTo(point) | PathOp::LineTo(point) => Some(Point2D::new(point.x, point.y)),
PathOp::CubicTo(_, _, point) => Some(Point2D::new(point.x, point.y)),
PathOp::QuadTo(_, point) => Some(Point2D::new(point.x, point.y)),
- PathOp::Close => None,
+ PathOp::Close => path.ops.first().and_then(get_first_point),
})
}
@@ -731,6 +733,15 @@ impl GenericPathBuilder<RaqoteBackend> for PathBuilder {
}
}
+fn get_first_point(op: &PathOp) -> Option<euclid::Point2D<f32, euclid::UnknownUnit>> {
+ match op {
+ PathOp::MoveTo(point) | PathOp::LineTo(point) => Some(Point2D::new(point.x, point.y)),
+ PathOp::CubicTo(point, _, _) => Some(Point2D::new(point.x, point.y)),
+ PathOp::QuadTo(point, _) => Some(Point2D::new(point.x, point.y)),
+ PathOp::Close => None,
+ }
+}
+
pub trait ToRaqoteStyle {
type Target;
diff --git a/components/compositing/compositor.rs b/components/compositing/compositor.rs
index a76b0022122..0acbbec977a 100644
--- a/components/compositing/compositor.rs
+++ b/components/compositing/compositor.rs
@@ -281,6 +281,11 @@ impl PipelineDetails {
}
}
+pub enum HitTestError {
+ EpochMismatch,
+ Others,
+}
+
impl ServoRenderer {
pub fn shutdown_state(&self) -> ShutdownState {
self.shutdown_state.get()
@@ -290,15 +295,19 @@ impl ServoRenderer {
&self,
point: DevicePoint,
details_for_pipeline: impl Fn(PipelineId) -> Option<&'a PipelineDetails>,
- ) -> Option<CompositorHitTestResult> {
- self.hit_test_at_point_with_flags_and_pipeline(
+ ) -> Result<CompositorHitTestResult, HitTestError> {
+ match self.hit_test_at_point_with_flags_and_pipeline(
point,
HitTestFlags::empty(),
None,
details_for_pipeline,
- )
- .first()
- .cloned()
+ ) {
+ Ok(hit_test_results) => hit_test_results
+ .first()
+ .cloned()
+ .ok_or(HitTestError::Others),
+ Err(error) => Err(error),
+ }
}
// TODO: split this into first half (global) and second half (one for whole compositor, one for webview)
@@ -308,14 +317,15 @@ impl ServoRenderer {
flags: HitTestFlags,
pipeline_id: Option<WebRenderPipelineId>,
details_for_pipeline: impl Fn(PipelineId) -> Option<&'a PipelineDetails>,
- ) -> Vec<CompositorHitTestResult> {
+ ) -> Result<Vec<CompositorHitTestResult>, HitTestError> {
// DevicePoint and WorldPoint are the same for us.
let world_point = WorldPoint::from_untyped(point.to_untyped());
let results =
self.webrender_api
.hit_test(self.webrender_document, pipeline_id, world_point, flags);
- results
+ let mut epoch_mismatch = false;
+ let results = results
.items
.iter()
.filter_map(|item| {
@@ -323,10 +333,16 @@ impl ServoRenderer {
let details = details_for_pipeline(pipeline_id)?;
// If the epoch in the tag does not match the current epoch of the pipeline,
- // then the hit test is against an old version of the display list and we
- // should ignore this hit test for now.
+ // then the hit test is against an old version of the display list.
match details.most_recent_display_list_epoch {
- Some(epoch) if epoch.as_u16() == item.tag.1 => {},
+ Some(epoch) => {
+ if epoch.as_u16() != item.tag.1 {
+ // It's too early to hit test for now.
+ // New scene building is in progress.
+ epoch_mismatch = true;
+ return None;
+ }
+ },
_ => return None,
}
@@ -340,7 +356,13 @@ impl ServoRenderer {
scroll_tree_node: info.scroll_tree_node,
})
})
- .collect()
+ .collect();
+
+ if epoch_mismatch {
+ return Err(HitTestError::EpochMismatch);
+ }
+
+ Ok(results)
}
pub(crate) fn send_transaction(&mut self, transaction: Transaction) {
@@ -619,7 +641,7 @@ impl IOCompositor {
.global
.borrow()
.hit_test_at_point(point, details_for_pipeline);
- if let Some(result) = result {
+ if let Ok(result) = result {
self.global.borrow_mut().update_cursor(point, &result);
}
}
@@ -649,7 +671,7 @@ impl IOCompositor {
};
let dppx = webview_renderer.device_pixels_per_page_pixel();
let point = dppx.transform_point(Point2D::new(x, y));
- webview_renderer.dispatch_input_event(
+ webview_renderer.dispatch_point_input_event(
InputEvent::MouseButton(MouseButtonEvent::new(action, button, point))
.with_webdriver_message_id(Some(message_id)),
);
@@ -662,7 +684,7 @@ impl IOCompositor {
};
let dppx = webview_renderer.device_pixels_per_page_pixel();
let point = dppx.transform_point(Point2D::new(x, y));
- webview_renderer.dispatch_input_event(
+ webview_renderer.dispatch_point_input_event(
InputEvent::MouseMove(MouseMoveEvent::new(point))
.with_webdriver_message_id(Some(message_id)),
);
@@ -684,7 +706,7 @@ impl IOCompositor {
let scroll_delta =
dppx.transform_vector(Vector2D::new(delta_x as f32, delta_y as f32));
webview_renderer
- .dispatch_input_event(InputEvent::Wheel(WheelEvent { delta, point }));
+ .dispatch_point_input_event(InputEvent::Wheel(WheelEvent { delta, point }));
webview_renderer.on_webdriver_wheel_action(scroll_delta, point);
},
@@ -792,6 +814,8 @@ impl IOCompositor {
let Some(webview_renderer) = self.webview_renderers.get_mut(webview_id) else {
return warn!("Could not find WebView for incoming display list");
};
+ // WebRender is not ready until we receive "NewWebRenderFrameReady"
+ webview_renderer.webrender_frame_ready.set(false);
let pipeline_id = display_list_info.pipeline_id;
let details = webview_renderer.ensure_pipeline_details(pipeline_id.into());
@@ -841,7 +865,8 @@ impl IOCompositor {
flags,
pipeline,
details_for_pipeline,
- );
+ )
+ .unwrap_or_default();
let _ = sender.send(result);
},
@@ -1629,11 +1654,20 @@ impl IOCompositor {
},
CompositorMsg::NewWebRenderFrameReady(..) => {
found_recomposite_msg = true;
- compositor_messages.push(msg)
+ compositor_messages.push(msg);
},
_ => compositor_messages.push(msg),
}
}
+
+ if found_recomposite_msg {
+ // Process all pending events
+ self.webview_renderers.iter().for_each(|webview| {
+ webview.dispatch_pending_point_input_events();
+ webview.webrender_frame_ready.set(true);
+ });
+ }
+
for msg in compositor_messages {
self.handle_browser_message(msg);
diff --git a/components/compositing/webview_renderer.rs b/components/compositing/webview_renderer.rs
index b0e91ccb02e..84d5fd877e6 100644
--- a/components/compositing/webview_renderer.rs
+++ b/components/compositing/webview_renderer.rs
@@ -2,9 +2,9 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
-use std::cell::RefCell;
-use std::collections::HashMap;
+use std::cell::{Cell, RefCell};
use std::collections::hash_map::Keys;
+use std::collections::{HashMap, VecDeque};
use std::rc::Rc;
use base::id::{PipelineId, WebViewId};
@@ -25,7 +25,7 @@ use webrender_api::units::{
};
use webrender_api::{ExternalScrollId, HitTestFlags, ScrollLocation};
-use crate::compositor::{PipelineDetails, ServoRenderer};
+use crate::compositor::{HitTestError, PipelineDetails, ServoRenderer};
use crate::touch::{TouchHandler, TouchMoveAction, TouchMoveAllowed, TouchSequenceState};
// Default viewport constraints
@@ -98,6 +98,10 @@ pub(crate) struct WebViewRenderer {
/// Whether or not this [`WebViewRenderer`] isn't throttled and has a pipeline with
/// active animations or animation frame callbacks.
animating: bool,
+ /// Pending input events queue. Priavte and only this thread pushes events to it.
+ pending_point_input_events: RefCell<VecDeque<InputEvent>>,
+ /// WebRender is not ready between `SendDisplayList` and `WebRenderFrameReady` messages.
+ pub webrender_frame_ready: Cell<bool>,
}
impl Drop for WebViewRenderer {
@@ -132,6 +136,8 @@ impl WebViewRenderer {
max_viewport_zoom: None,
hidpi_scale_factor: Scale::new(hidpi_scale_factor.0),
animating: false,
+ pending_point_input_events: Default::default(),
+ webrender_frame_ready: Cell::default(),
}
}
@@ -309,29 +315,89 @@ impl WebViewRenderer {
}
}
- pub(crate) fn dispatch_input_event(&mut self, event: InputEvent) {
+ pub(crate) fn dispatch_point_input_event(&mut self, mut event: InputEvent) -> bool {
// Events that do not need to do hit testing are sent directly to the
// constellation to filter down.
let Some(point) = event.point() else {
- return;
+ return false;
};
+ // Delay the event if the epoch is not synchronized yet (new frame is not ready),
+ // or hit test result would fail and the event is rejected anyway.
+ if !self.webrender_frame_ready.get() || !self.pending_point_input_events.borrow().is_empty()
+ {
+ self.pending_point_input_events
+ .borrow_mut()
+ .push_back(event);
+ return false;
+ }
+
// If we can't find a pipeline to send this event to, we cannot continue.
let get_pipeline_details = |pipeline_id| self.pipelines.get(&pipeline_id);
- let Some(result) = self
+ let result = match self
.global
.borrow()
.hit_test_at_point(point, get_pipeline_details)
- else {
- return;
+ {
+ Ok(hit_test_results) => hit_test_results,
+ Err(HitTestError::EpochMismatch) => {
+ self.pending_point_input_events
+ .borrow_mut()
+ .push_back(event);
+ return false;
+ },
+ _ => {
+ return false;
+ },
};
- self.global.borrow_mut().update_cursor(point, &result);
+ match event {
+ InputEvent::Touch(ref mut touch_event) => {
+ touch_event.init_sequence_id(self.touch_handler.current_sequence_id);
+ },
+ InputEvent::MouseButton(_) | InputEvent::MouseMove(_) | InputEvent::Wheel(_) => {
+ self.global.borrow_mut().update_cursor(point, &result);
+ },
+ _ => unreachable!("Unexpected input event type: {event:?}"),
+ }
if let Err(error) = self.global.borrow().constellation_sender.send(
EmbedderToConstellationMessage::ForwardInputEvent(self.id, event, Some(result)),
) {
warn!("Sending event to constellation failed ({error:?}).");
+ false
+ } else {
+ true
+ }
+ }
+
+ pub(crate) fn dispatch_pending_point_input_events(&self) {
+ while let Some(event) = self.pending_point_input_events.borrow_mut().pop_front() {
+ // Events that do not need to do hit testing are sent directly to the
+ // constellation to filter down.
+ let Some(point) = event.point() else {
+ continue;
+ };
+
+ // If we can't find a pipeline to send this event to, we cannot continue.
+ let get_pipeline_details = |pipeline_id| self.pipelines.get(&pipeline_id);
+ let Ok(result) = self
+ .global
+ .borrow()
+ .hit_test_at_point(point, get_pipeline_details)
+ else {
+ // Don't need to process pending input events in this frame any more.
+ // TODO: Add multiple retry later if needed.
+ return;
+ };
+
+ self.global.borrow_mut().update_cursor(point, &result);
+
+ if let Err(error) = self.global.borrow().constellation_sender.send(
+ EmbedderToConstellationMessage::ForwardInputEvent(self.id, event, Some(result)),
+ ) {
+ warn!("Sending event to constellation failed ({error:?}).");
+ }
}
}
@@ -401,29 +467,11 @@ impl WebViewRenderer {
}
}
- self.dispatch_input_event(event);
+ self.dispatch_point_input_event(event);
}
- fn send_touch_event(&self, mut event: TouchEvent) -> bool {
- let get_pipeline_details = |pipeline_id| self.pipelines.get(&pipeline_id);
- let Some(result) = self
- .global
- .borrow()
- .hit_test_at_point(event.point, get_pipeline_details)
- else {
- return false;
- };
-
- event.init_sequence_id(self.touch_handler.current_sequence_id);
- let event = InputEvent::Touch(event);
- if let Err(e) = self.global.borrow().constellation_sender.send(
- EmbedderToConstellationMessage::ForwardInputEvent(self.id, event, Some(result)),
- ) {
- warn!("Sending event to constellation failed ({:?}).", e);
- false
- } else {
- true
- }
+ fn send_touch_event(&mut self, event: TouchEvent) -> bool {
+ self.dispatch_point_input_event(InputEvent::Touch(event))
}
pub(crate) fn on_touch_event(&mut self, event: TouchEvent) {
@@ -687,13 +735,13 @@ impl WebViewRenderer {
/// <http://w3c.github.io/touch-events/#mouse-events>
fn simulate_mouse_click(&mut self, point: DevicePoint) {
let button = MouseButton::Left;
- self.dispatch_input_event(InputEvent::MouseMove(MouseMoveEvent::new(point)));
- self.dispatch_input_event(InputEvent::MouseButton(MouseButtonEvent::new(
+ self.dispatch_point_input_event(InputEvent::MouseMove(MouseMoveEvent::new(point)));
+ self.dispatch_point_input_event(InputEvent::MouseButton(MouseButtonEvent::new(
MouseButtonAction::Down,
button,
point,
)));
- self.dispatch_input_event(InputEvent::MouseButton(MouseButtonEvent::new(
+ self.dispatch_point_input_event(InputEvent::MouseButton(MouseButtonEvent::new(
MouseButtonAction::Up,
button,
point,
@@ -858,7 +906,8 @@ impl WebViewRenderer {
HitTestFlags::FIND_ALL,
None,
get_pipeline_details,
- );
+ )
+ .unwrap_or_default();
// Iterate through all hit test results, processing only the first node of each pipeline.
// This is needed to propagate the scroll events from a pipeline representing an iframe to
diff --git a/components/devtools/actors/breakpoint.rs b/components/devtools/actors/breakpoint.rs
new file mode 100644
index 00000000000..04f2de140b4
--- /dev/null
+++ b/components/devtools/actors/breakpoint.rs
@@ -0,0 +1,55 @@
+/* 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 https://mozilla.org/MPL/2.0/. */
+
+use serde::Serialize;
+
+use crate::EmptyReplyMsg;
+use crate::actor::{Actor, ActorMessageStatus};
+use crate::protocol::JsonPacketStream;
+
+#[derive(Serialize)]
+pub struct BreakpointListActorMsg {
+ actor: String,
+}
+
+pub struct BreakpointListActor {
+ name: String,
+}
+
+impl Actor for BreakpointListActor {
+ fn name(&self) -> String {
+ self.name.clone()
+ }
+
+ fn handle_message(
+ &self,
+ _registry: &crate::actor::ActorRegistry,
+ msg_type: &str,
+ _msg: &serde_json::Map<String, serde_json::Value>,
+ stream: &mut std::net::TcpStream,
+ _stream_id: crate::StreamId,
+ ) -> Result<crate::actor::ActorMessageStatus, ()> {
+ Ok(match msg_type {
+ "setBreakpoint" => {
+ let msg = EmptyReplyMsg { from: self.name() };
+ let _ = stream.write_json_packet(&msg);
+
+ ActorMessageStatus::Processed
+ },
+ "setActiveEventBreakpoints" => {
+ let msg = EmptyReplyMsg { from: self.name() };
+ let _ = stream.write_json_packet(&msg);
+
+ ActorMessageStatus::Processed
+ },
+ _ => ActorMessageStatus::Ignored,
+ })
+ }
+}
+
+impl BreakpointListActor {
+ pub fn new(name: String) -> Self {
+ Self { name }
+ }
+}
diff --git a/components/devtools/actors/browsing_context.rs b/components/devtools/actors/browsing_context.rs
index 81a00e82d47..fc5116131a0 100644
--- a/components/devtools/actors/browsing_context.rs
+++ b/components/devtools/actors/browsing_context.rs
@@ -82,6 +82,13 @@ struct BrowsingContextTraits {
}
#[derive(Serialize)]
+#[serde(rename_all = "lowercase")]
+enum TargetType {
+ Frame,
+ // Other target types not implemented yet.
+}
+
+#[derive(Serialize)]
#[serde(rename_all = "camelCase")]
pub struct BrowsingContextActorMsg {
actor: String,
@@ -104,6 +111,7 @@ pub struct BrowsingContextActorMsg {
reflow_actor: String,
style_sheets_actor: String,
thread_actor: String,
+ target_type: TargetType,
// Part of the official protocol, but not yet implemented.
// animations_actor: String,
// changes_actor: String,
@@ -302,6 +310,7 @@ impl BrowsingContextActor {
reflow_actor: self.reflow.clone(),
style_sheets_actor: self.style_sheets.clone(),
thread_actor: self.thread.clone(),
+ target_type: TargetType::Frame,
}
}
diff --git a/components/devtools/actors/watcher.rs b/components/devtools/actors/watcher.rs
index 061ffc92336..7720daf070d 100644
--- a/components/devtools/actors/watcher.rs
+++ b/components/devtools/actors/watcher.rs
@@ -19,6 +19,7 @@ use serde::Serialize;
use serde_json::{Map, Value};
use self::network_parent::{NetworkParentActor, NetworkParentActorMsg};
+use super::breakpoint::BreakpointListActor;
use super::thread::ThreadActor;
use super::worker::WorkerMsg;
use crate::actor::{Actor, ActorMessageStatus, ActorRegistry};
@@ -362,10 +363,14 @@ impl Actor for WatcherActor {
ActorMessageStatus::Processed
},
"getBreakpointListActor" => {
+ let breakpoint_list_name = registry.new_name("breakpoint-list");
+ let breakpoint_list = BreakpointListActor::new(breakpoint_list_name.clone());
+ registry.register_later(Box::new(breakpoint_list));
+
let _ = stream.write_json_packet(&GetBreakpointListActorReply {
from: self.name(),
breakpoint_list: GetBreakpointListActorReplyInner {
- actor: registry.new_name("breakpoint-list"),
+ actor: breakpoint_list_name,
},
});
ActorMessageStatus::Processed
diff --git a/components/devtools/lib.rs b/components/devtools/lib.rs
index d097cb25e9d..74a45eaf866 100644
--- a/components/devtools/lib.rs
+++ b/components/devtools/lib.rs
@@ -53,6 +53,7 @@ use crate::protocol::JsonPacketStream;
mod actor;
/// <https://searchfox.org/mozilla-central/source/devtools/server/actors>
mod actors {
+ pub mod breakpoint;
pub mod browsing_context;
pub mod console;
pub mod device;
diff --git a/components/net/fetch/methods.rs b/components/net/fetch/methods.rs
index 33d0da952fb..e99776be350 100644
--- a/components/net/fetch/methods.rs
+++ b/components/net/fetch/methods.rs
@@ -170,8 +170,12 @@ pub async fn fetch_with_cors_cache(
// TODO: We don't implement fetchParams as defined in the spec
}
-fn convert_request_to_csp_request(request: &Request, origin: &ImmutableOrigin) -> csp::Request {
- csp::Request {
+pub(crate) fn convert_request_to_csp_request(request: &Request) -> Option<csp::Request> {
+ let origin = match &request.origin {
+ Origin::Client => return None,
+ Origin::Origin(origin) => origin,
+ };
+ let csp_request = csp::Request {
url: request.url().into_url(),
origin: origin.clone().into_url_origin(),
redirect_count: request.redirect_count,
@@ -190,45 +194,58 @@ fn convert_request_to_csp_request(request: &Request, origin: &ImmutableOrigin) -
ParserMetadata::NotParserInserted => csp::ParserMetadata::NotParserInserted,
ParserMetadata::Default => csp::ParserMetadata::None,
},
- }
+ };
+ Some(csp_request)
}
/// <https://www.w3.org/TR/CSP/#should-block-request>
pub fn should_request_be_blocked_by_csp(
- request: &Request,
+ csp_request: &csp::Request,
policy_container: &PolicyContainer,
) -> (csp::CheckResult, Vec<csp::Violation>) {
- let origin = match &request.origin {
- Origin::Client => return (csp::CheckResult::Allowed, Vec::new()),
- Origin::Origin(origin) => origin,
- };
- let csp_request = convert_request_to_csp_request(request, origin);
-
policy_container
.csp_list
.as_ref()
- .map(|c| c.should_request_be_blocked(&csp_request))
+ .map(|c| c.should_request_be_blocked(csp_request))
.unwrap_or((csp::CheckResult::Allowed, Vec::new()))
}
/// <https://www.w3.org/TR/CSP/#report-for-request>
pub fn report_violations_for_request_by_csp(
- request: &Request,
+ csp_request: &csp::Request,
policy_container: &PolicyContainer,
) -> Vec<csp::Violation> {
- let origin = match &request.origin {
- Origin::Client => return Vec::new(),
- Origin::Origin(origin) => origin,
- };
- let csp_request = convert_request_to_csp_request(request, origin);
-
policy_container
.csp_list
.as_ref()
- .map(|c| c.report_violations_for_request(&csp_request))
+ .map(|c| c.report_violations_for_request(csp_request))
.unwrap_or_default()
}
+fn should_response_be_blocked_by_csp(
+ csp_request: &csp::Request,
+ response: &Response,
+ policy_container: &PolicyContainer,
+) -> (csp::CheckResult, Vec<csp::Violation>) {
+ if response.is_network_error() {
+ return (csp::CheckResult::Allowed, Vec::new());
+ }
+ let csp_response = csp::Response {
+ url: response
+ .actual_response()
+ .url()
+ .cloned()
+ .expect("response must have a url")
+ .into_url(),
+ redirect_count: csp_request.redirect_count,
+ };
+ policy_container
+ .csp_list
+ .as_ref()
+ .map(|c| c.should_response_to_request_be_blocked(csp_request, &csp_response))
+ .unwrap_or((csp::CheckResult::Allowed, Vec::new()))
+}
+
/// [Main fetch](https://fetch.spec.whatwg.org/#concept-main-fetch)
pub async fn main_fetch(
fetch_params: &mut FetchParams,
@@ -270,13 +287,15 @@ pub async fn main_fetch(
RequestPolicyContainer::Client => PolicyContainer::default(),
RequestPolicyContainer::PolicyContainer(container) => container.to_owned(),
};
+ let csp_request = convert_request_to_csp_request(request);
+ if let Some(csp_request) = csp_request.as_ref() {
+ // Step 2.2.
+ let violations = report_violations_for_request_by_csp(csp_request, &policy_container);
- // Step 2.2.
- let violations = report_violations_for_request_by_csp(request, &policy_container);
-
- if !violations.is_empty() {
- target.process_csp_violations(request, violations);
- }
+ if !violations.is_empty() {
+ target.process_csp_violations(request, violations);
+ }
+ };
// Step 3.
// TODO: handle request abort.
@@ -309,22 +328,24 @@ pub async fn main_fetch(
request.insecure_requests_policy
);
}
+ if let Some(csp_request) = csp_request.as_ref() {
+ // Step 7. If should request be blocked due to a bad port, should fetching request be blocked
+ // as mixed content, or should request be blocked by Content Security Policy returns blocked,
+ // then set response to a network error.
+ let (check_result, violations) =
+ should_request_be_blocked_by_csp(csp_request, &policy_container);
+
+ if !violations.is_empty() {
+ target.process_csp_violations(request, violations);
+ }
- // Step 7. If should request be blocked due to a bad port, should fetching request be blocked
- // as mixed content, or should request be blocked by Content Security Policy returns blocked,
- // then set response to a network error.
- let (check_result, violations) = should_request_be_blocked_by_csp(request, &policy_container);
-
- if !violations.is_empty() {
- target.process_csp_violations(request, violations);
- }
-
- if check_result == csp::CheckResult::Blocked {
- warn!("Request blocked by CSP");
- response = Some(Response::network_error(NetworkError::Internal(
- "Blocked by Content-Security-Policy".into(),
- )))
- }
+ if check_result == csp::CheckResult::Blocked {
+ warn!("Request blocked by CSP");
+ response = Some(Response::network_error(NetworkError::Internal(
+ "Blocked by Content-Security-Policy".into(),
+ )))
+ }
+ };
if should_request_be_blocked_due_to_a_bad_port(&request.current_url()) {
response = Some(Response::network_error(NetworkError::Internal(
"Request attempted on bad port".into(),
@@ -530,6 +551,14 @@ pub async fn main_fetch(
should_be_blocked_due_to_mime_type(request.destination, &response.headers);
let should_replace_with_mixed_content = !response_is_network_error &&
should_response_be_blocked_as_mixed_content(request, &response, &context.protocols);
+ let should_replace_with_csp_error = csp_request.is_some_and(|csp_request| {
+ let (check_result, violations) =
+ should_response_be_blocked_by_csp(&csp_request, &response, &policy_container);
+ if !violations.is_empty() {
+ target.process_csp_violations(request, violations);
+ }
+ check_result == csp::CheckResult::Blocked
+ });
// Step 15.
let mut network_error_response = response
@@ -553,7 +582,7 @@ pub async fn main_fetch(
// Step 19. If response is not a network error and any of the following returns blocked
// * should internalResponse to request be blocked as mixed content
- // TODO: * should internalResponse to request be blocked by Content Security Policy
+ // * should internalResponse to request be blocked by Content Security Policy
// * should internalResponse to request be blocked due to its MIME type
// * should internalResponse to request be blocked due to nosniff
let mut blocked_error_response;
@@ -572,6 +601,10 @@ pub async fn main_fetch(
blocked_error_response =
Response::network_error(NetworkError::Internal("Blocked as mixed content".into()));
&blocked_error_response
+ } else if should_replace_with_csp_error {
+ blocked_error_response =
+ Response::network_error(NetworkError::Internal("Blocked due to CSP".into()));
+ &blocked_error_response
} else {
internal_response
};
diff --git a/components/net/websocket_loader.rs b/components/net/websocket_loader.rs
index 128436ac47c..8ad7df5d376 100644
--- a/components/net/websocket_loader.rs
+++ b/components/net/websocket_loader.rs
@@ -43,7 +43,8 @@ use crate::async_runtime::HANDLE;
use crate::connector::{CACertificates, TlsConfig, create_tls_config};
use crate::cookie::ServoCookie;
use crate::fetch::methods::{
- should_request_be_blocked_by_csp, should_request_be_blocked_due_to_a_bad_port,
+ convert_request_to_csp_request, should_request_be_blocked_by_csp,
+ should_request_be_blocked_due_to_a_bad_port,
};
use crate::hosts::replace_host;
use crate::http_loader::HttpState;
@@ -390,14 +391,18 @@ fn connect(
RequestPolicyContainer::PolicyContainer(container) => container.to_owned(),
};
- let (check_result, violations) = should_request_be_blocked_by_csp(&request, &policy_container);
+ if let Some(csp_request) = convert_request_to_csp_request(&request) {
+ let (check_result, violations) =
+ should_request_be_blocked_by_csp(&csp_request, &policy_container);
- if !violations.is_empty() {
- let _ = resource_event_sender.send(WebSocketNetworkEvent::ReportCSPViolations(violations));
- }
+ if !violations.is_empty() {
+ let _ =
+ resource_event_sender.send(WebSocketNetworkEvent::ReportCSPViolations(violations));
+ }
- if check_result == csp::CheckResult::Blocked {
- return Err("Blocked by Content-Security-Policy".to_string());
+ if check_result == csp::CheckResult::Blocked {
+ return Err("Blocked by Content-Security-Policy".to_string());
+ }
}
let client = match create_request(
diff --git a/components/script/body.rs b/components/script/body.rs
index cc7870a0845..ee269fd430a 100644
--- a/components/script/body.rs
+++ b/components/script/body.rs
@@ -249,7 +249,7 @@ impl TransmitBodyConnectHandler {
let rejection_handler = Box::new(TransmitBodyPromiseRejectionHandler {
bytes_sender,
- stream: rooted_stream,
+ stream: Dom::from_ref(&rooted_stream.clone()),
control_sender,
});
@@ -321,11 +321,12 @@ impl Callback for TransmitBodyPromiseHandler {
/// The handler of read promises rejection of body streams used in
/// <https://fetch.spec.whatwg.org/#concept-request-transmit-body>.
#[derive(Clone, JSTraceable, MallocSizeOf)]
+#[cfg_attr(crown, crown::unrooted_must_root_lint::must_root)]
struct TransmitBodyPromiseRejectionHandler {
#[ignore_malloc_size_of = "Channels are hard"]
#[no_trace]
bytes_sender: IpcSender<BodyChunkResponse>,
- stream: DomRoot<ReadableStream>,
+ stream: Dom<ReadableStream>,
#[ignore_malloc_size_of = "Channels are hard"]
#[no_trace]
control_sender: IpcSender<BodyChunkRequest>,
diff --git a/components/script/devtools.rs b/components/script/devtools.rs
index 93212887dc8..945470194e2 100644
--- a/components/script/devtools.rs
+++ b/components/script/devtools.rs
@@ -132,7 +132,7 @@ fn find_node_by_unique_id(
document
.upcast::<Node>()
.traverse_preorder(ShadowIncluding::Yes)
- .find(|candidate| candidate.unique_id() == node_id)
+ .find(|candidate| candidate.unique_id(pipeline) == node_id)
})
}
diff --git a/components/script/dom/abortcontroller.rs b/components/script/dom/abortcontroller.rs
index 3813cfdd51a..3a7ca17220d 100644
--- a/components/script/dom/abortcontroller.rs
+++ b/components/script/dom/abortcontroller.rs
@@ -3,24 +3,33 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
use dom_struct::dom_struct;
-use js::jsapi::Value;
-use js::rust::{Handle, HandleObject};
+use js::rust::{HandleObject, HandleValue};
+use crate::dom::abortsignal::AbortSignal;
use crate::dom::bindings::codegen::Bindings::AbortControllerBinding::AbortControllerMethods;
use crate::dom::bindings::reflector::{Reflector, reflect_dom_object_with_proto};
-use crate::dom::bindings::root::DomRoot;
+use crate::dom::bindings::root::{Dom, DomRoot};
use crate::dom::globalscope::GlobalScope;
use crate::script_runtime::{CanGc, JSContext};
+/// <https://dom.spec.whatwg.org/#abortcontroller>
#[dom_struct]
pub(crate) struct AbortController {
reflector_: Reflector,
+
+ /// An AbortController object has an associated signal (an AbortSignal object).
+ signal: Dom<AbortSignal>,
}
impl AbortController {
+ /// <https://dom.spec.whatwg.org/#dom-abortcontroller-abortcontroller>
fn new_inherited() -> AbortController {
+ // The new AbortController() constructor steps are:
+ // Let signal be a new AbortSignal object.
+ // Set this’s signal to signal.
AbortController {
reflector_: Reflector::new(),
+ signal: Dom::from_ref(&AbortSignal::new_inherited()),
}
}
@@ -36,6 +45,12 @@ impl AbortController {
can_gc,
)
}
+
+ /// <https://dom.spec.whatwg.org/#abortcontroller-signal-abort>
+ fn signal_abort(&self, cx: JSContext, reason: HandleValue, can_gc: CanGc) {
+ // signal abort on controller’s signal with reason if it is given.
+ self.signal.signal_abort(cx, reason, can_gc);
+ }
}
impl AbortControllerMethods<crate::DomTypeHolder> for AbortController {
@@ -49,5 +64,15 @@ impl AbortControllerMethods<crate::DomTypeHolder> for AbortController {
}
/// <https://dom.spec.whatwg.org/#dom-abortcontroller-abort>
- fn Abort(&self, _cx: JSContext, _reason: Handle<'_, Value>) {}
+ fn Abort(&self, cx: JSContext, reason: HandleValue, can_gc: CanGc) {
+ // The abort(reason) method steps are
+ // to signal abort on this with reason if it is given.
+ self.signal_abort(cx, reason, can_gc);
+ }
+
+ /// <https://dom.spec.whatwg.org/#dom-abortcontroller-signal>
+ fn Signal(&self) -> DomRoot<AbortSignal> {
+ // The signal getter steps are to return this’s signal.
+ self.signal.as_rooted()
+ }
}
diff --git a/components/script/dom/abortsignal.rs b/components/script/dom/abortsignal.rs
index 57c6e9cd67e..e93a7b64e90 100644
--- a/components/script/dom/abortsignal.rs
+++ b/components/script/dom/abortsignal.rs
@@ -2,18 +2,37 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
+use std::cell::RefCell;
+use std::mem;
+
use dom_struct::dom_struct;
-use js::jsapi::Heap;
-use js::jsval::JSVal;
-use js::rust::{HandleObject, MutableHandleValue};
+use js::jsapi::{ExceptionStackBehavior, Heap, JS_SetPendingException};
+use js::jsval::{JSVal, UndefinedValue};
+use js::rust::{HandleObject, HandleValue, MutableHandleValue};
+use script_bindings::inheritance::Castable;
use crate::dom::bindings::codegen::Bindings::AbortSignalBinding::AbortSignalMethods;
-use crate::dom::bindings::reflector::reflect_dom_object_with_proto;
+use crate::dom::bindings::error::{Error, ErrorToJsval};
+use crate::dom::bindings::reflector::{DomGlobal, reflect_dom_object_with_proto};
use crate::dom::bindings::root::DomRoot;
use crate::dom::eventtarget::EventTarget;
use crate::dom::globalscope::GlobalScope;
use crate::script_runtime::{CanGc, JSContext};
+/// <https://dom.spec.whatwg.org/#abortcontroller-api-integration>
+/// TODO: implement algorithms at call point,
+/// in order to integrate the abort signal with its various use cases.
+#[derive(JSTraceable, MallocSizeOf)]
+#[allow(dead_code)]
+enum AbortAlgorithm {
+ /// <https://dom.spec.whatwg.org/#add-an-event-listener>
+ DomEventLister,
+ /// <https://streams.spec.whatwg.org/#readable-stream-pipe-to>
+ StreamPiping,
+ /// <https://fetch.spec.whatwg.org/#dom-global-fetch>
+ Fetch,
+}
+
/// <https://dom.spec.whatwg.org/#abortsignal>
#[dom_struct]
pub(crate) struct AbortSignal {
@@ -22,14 +41,17 @@ pub(crate) struct AbortSignal {
/// <https://dom.spec.whatwg.org/#abortsignal-abort-reason>
#[ignore_malloc_size_of = "mozjs"]
abort_reason: Heap<JSVal>,
+
+ /// <https://dom.spec.whatwg.org/#abortsignal-abort-algorithms>
+ abort_algorithms: RefCell<Vec<AbortAlgorithm>>,
}
impl AbortSignal {
- #[allow(dead_code)]
- fn new_inherited() -> AbortSignal {
+ pub(crate) fn new_inherited() -> AbortSignal {
AbortSignal {
eventtarget: EventTarget::new_inherited(),
abort_reason: Default::default(),
+ abort_algorithms: Default::default(),
}
}
@@ -46,24 +68,88 @@ impl AbortSignal {
can_gc,
)
}
+
+ /// <https://dom.spec.whatwg.org/#abortsignal-signal-abort>
+ pub(crate) fn signal_abort(&self, cx: JSContext, reason: HandleValue, can_gc: CanGc) {
+ // If signal is aborted, then return.
+ if self.Aborted() {
+ return;
+ }
+
+ let abort_reason = reason.get();
+
+ // Set signal’s abort reason to reason if it is given;
+ if !abort_reason.is_undefined() {
+ self.abort_reason.set(abort_reason);
+ } else {
+ // otherwise to a new "AbortError" DOMException.
+ rooted!(in(*cx) let mut rooted_error = UndefinedValue());
+ Error::Abort.to_jsval(cx, &self.global(), rooted_error.handle_mut(), can_gc);
+ self.abort_reason.set(rooted_error.get())
+ }
+
+ // Let dependentSignalsToAbort be a new list.
+ // For each dependentSignal of signal’s dependent signals:
+ // TODO: #36936
+
+ // Run the abort steps for signal.
+ self.run_the_abort_steps(can_gc);
+
+ // For each dependentSignal of dependentSignalsToAbort, run the abort steps for dependentSignal.
+ // TODO: #36936
+ }
+
+ /// <https://dom.spec.whatwg.org/#run-the-abort-steps>
+ fn run_the_abort_steps(&self, can_gc: CanGc) {
+ // For each algorithm of signal’s abort algorithms: run algorithm.
+ let algos = mem::take(&mut *self.abort_algorithms.borrow_mut());
+ for _algo in algos {
+ // TODO: match on variant and implement algo steps.
+ // See the various items of #34866
+ }
+
+ // Empty signal’s abort algorithms.
+ // Done above with `take`.
+
+ // Fire an event named abort at signal.
+ self.upcast::<EventTarget>()
+ .fire_event(atom!("abort"), can_gc);
+ }
+
+ /// <https://dom.spec.whatwg.org/#abortsignal-aborted>
+ fn aborted(&self) -> bool {
+ // An AbortSignal object is aborted when its abort reason is not undefined.
+ !self.abort_reason.get().is_undefined()
+ }
}
impl AbortSignalMethods<crate::DomTypeHolder> for AbortSignal {
/// <https://dom.spec.whatwg.org/#dom-abortsignal-aborted>
fn Aborted(&self) -> bool {
- // TODO
- false
+ // The aborted getter steps are to return true if this is aborted; otherwise false.
+ self.aborted()
}
/// <https://dom.spec.whatwg.org/#dom-abortsignal-reason>
- fn Reason(&self, _: JSContext, _rval: MutableHandleValue) {
- // TODO
+ fn Reason(&self, _cx: JSContext, mut rval: MutableHandleValue) {
+ // The reason getter steps are to return this’s abort reason.
+ rval.set(self.abort_reason.get());
}
/// <https://dom.spec.whatwg.org/#dom-abortsignal-throwifaborted>
#[allow(unsafe_code)]
fn ThrowIfAborted(&self) {
- // TODO
+ // The throwIfAborted() method steps are to throw this’s abort reason, if this is aborted.
+ if self.aborted() {
+ let cx = GlobalScope::get_cx();
+ unsafe {
+ JS_SetPendingException(
+ *cx,
+ self.abort_reason.handle(),
+ ExceptionStackBehavior::Capture,
+ )
+ };
+ }
}
// <https://dom.spec.whatwg.org/#dom-abortsignal-onabort>
diff --git a/components/script/dom/element.rs b/components/script/dom/element.rs
index 311991804e9..ed4c37c4378 100644
--- a/components/script/dom/element.rs
+++ b/components/script/dom/element.rs
@@ -121,7 +121,7 @@ use crate::dom::htmlelement::HTMLElement;
use crate::dom::htmlfieldsetelement::HTMLFieldSetElement;
use crate::dom::htmlfontelement::{HTMLFontElement, HTMLFontElementLayoutHelpers};
use crate::dom::htmlformelement::FormControlElementHelpers;
-use crate::dom::htmlhrelement::{HTMLHRElement, HTMLHRLayoutHelpers};
+use crate::dom::htmlhrelement::{HTMLHRElement, HTMLHRLayoutHelpers, SizePresentationalHint};
use crate::dom::htmliframeelement::{HTMLIFrameElement, HTMLIFrameElementLayoutMethods};
use crate::dom::htmlimageelement::{HTMLImageElement, LayoutHTMLImageElementHelpers};
use crate::dom::htmlinputelement::{HTMLInputElement, LayoutHTMLInputElementHelpers};
@@ -1306,6 +1306,47 @@ impl<'dom> LayoutElementHelpers<'dom> for LayoutDom<'dom, Element> {
PropertyDeclaration::PaddingRight(cellpadding),
));
}
+
+ // https://html.spec.whatwg.org/multipage/#the-hr-element-2
+ if let Some(size_info) = self
+ .downcast::<HTMLHRElement>()
+ .and_then(|hr_element| hr_element.get_size_info())
+ {
+ match size_info {
+ SizePresentationalHint::SetHeightTo(height) => {
+ hints.push(from_declaration(
+ shared_lock,
+ PropertyDeclaration::Height(height),
+ ));
+ },
+ SizePresentationalHint::SetAllBorderWidthValuesTo(border_width) => {
+ hints.push(from_declaration(
+ shared_lock,
+ PropertyDeclaration::BorderLeftWidth(border_width.clone()),
+ ));
+ hints.push(from_declaration(
+ shared_lock,
+ PropertyDeclaration::BorderRightWidth(border_width.clone()),
+ ));
+ hints.push(from_declaration(
+ shared_lock,
+ PropertyDeclaration::BorderTopWidth(border_width.clone()),
+ ));
+ hints.push(from_declaration(
+ shared_lock,
+ PropertyDeclaration::BorderBottomWidth(border_width),
+ ));
+ },
+ SizePresentationalHint::SetBottomBorderWidthToZero => {
+ hints.push(from_declaration(
+ shared_lock,
+ PropertyDeclaration::BorderBottomWidth(
+ specified::border::BorderSideWidth::from_px(0.),
+ ),
+ ));
+ },
+ }
+ }
}
fn get_span(self) -> Option<u32> {
@@ -4481,7 +4522,9 @@ impl SelectorsElement for SelectorWrapper<'_> {
// a string containing commas (separating each language tag in
// a list) but the pseudo-class instead should be parsing and
// storing separate <ident> or <string>s for each language tag.
- NonTSPseudoClass::Lang(ref lang) => extended_filtering(&self.get_lang(), lang),
+ NonTSPseudoClass::Lang(ref lang) => {
+ extended_filtering(&self.upcast::<Node>().get_lang().unwrap_or_default(), lang)
+ },
NonTSPseudoClass::ReadOnly => {
!Element::state(self).contains(NonTSPseudoClass::ReadWrite.state_flag())
@@ -4821,24 +4864,7 @@ impl Element {
}
}
- // https://html.spec.whatwg.org/multipage/#language
- pub(crate) fn get_lang(&self) -> String {
- self.upcast::<Node>()
- .inclusive_ancestors(ShadowIncluding::Yes)
- .filter_map(|node| {
- node.downcast::<Element>().and_then(|el| {
- el.get_attribute(&ns!(xml), &local_name!("lang"))
- .or_else(|| el.get_attribute(&ns!(), &local_name!("lang")))
- .map(|attr| String::from(attr.Value()))
- })
- // TODO: Check meta tags for a pragma-set default language
- // TODO: Check HTTP Content-Language header
- })
- .next()
- .unwrap_or(String::new())
- }
-
- pub(crate) fn state(&self) -> ElementState {
+ pub fn state(&self) -> ElementState {
self.state.get()
}
diff --git a/components/script/dom/event.rs b/components/script/dom/event.rs
index 743ced42a4b..345038a08da 100644
--- a/components/script/dom/event.rs
+++ b/components/script/dom/event.rs
@@ -1124,7 +1124,13 @@ impl TaskOnce for EventTask {
let target = self.target.root();
let bubbles = self.bubbles;
let cancelable = self.cancelable;
- target.fire_event_with_params(self.name, bubbles, cancelable, CanGc::note());
+ target.fire_event_with_params(
+ self.name,
+ bubbles,
+ cancelable,
+ EventComposed::NotComposed,
+ CanGc::note(),
+ );
}
}
diff --git a/components/script/dom/eventsource.rs b/components/script/dom/eventsource.rs
index 7cf7bd6106f..3e0070f91d7 100644
--- a/components/script/dom/eventsource.rs
+++ b/components/script/dom/eventsource.rs
@@ -61,6 +61,34 @@ enum ReadyState {
Closed = 2,
}
+#[derive(JSTraceable, MallocSizeOf)]
+struct DroppableEventSource {
+ canceller: DomRefCell<FetchCanceller>,
+}
+
+impl DroppableEventSource {
+ pub(crate) fn new(canceller: DomRefCell<FetchCanceller>) -> Self {
+ DroppableEventSource { canceller }
+ }
+
+ pub(crate) fn cancel(&self) {
+ self.canceller.borrow_mut().cancel();
+ }
+
+ pub(crate) fn set_canceller(&self, data: FetchCanceller) {
+ *self.canceller.borrow_mut() = data;
+ }
+}
+
+// https://html.spec.whatwg.org/multipage/#garbage-collection-2
+impl Drop for DroppableEventSource {
+ fn drop(&mut self) {
+ // If an EventSource object is garbage collected while its connection is still open,
+ // the user agent must abort any instance of the fetch algorithm opened by this EventSource.
+ self.cancel();
+ }
+}
+
#[dom_struct]
pub(crate) struct EventSource {
eventtarget: EventTarget,
@@ -74,7 +102,7 @@ pub(crate) struct EventSource {
ready_state: Cell<ReadyState>,
with_credentials: bool,
- canceller: DomRefCell<FetchCanceller>,
+ droppable: DroppableEventSource,
}
enum ParserState {
@@ -480,7 +508,7 @@ impl EventSource {
ready_state: Cell::new(ReadyState::Connecting),
with_credentials,
- canceller: DomRefCell::new(Default::default()),
+ droppable: DroppableEventSource::new(DomRefCell::new(Default::default())),
}
}
@@ -501,7 +529,7 @@ impl EventSource {
// https://html.spec.whatwg.org/multipage/#sse-processing-model:fail-the-connection-3
pub(crate) fn cancel(&self) {
- self.canceller.borrow_mut().cancel();
+ self.droppable.cancel();
self.fail_the_connection();
}
@@ -529,15 +557,6 @@ impl EventSource {
}
}
-// https://html.spec.whatwg.org/multipage/#garbage-collection-2
-impl Drop for EventSource {
- fn drop(&mut self) {
- // If an EventSource object is garbage collected while its connection is still open,
- // the user agent must abort any instance of the fetch algorithm opened by this EventSource.
- self.canceller.borrow_mut().cancel();
- }
-}
-
impl EventSourceMethods<crate::DomTypeHolder> for EventSource {
// https://html.spec.whatwg.org/multipage/#dom-eventsource
fn Constructor(
@@ -632,7 +651,7 @@ impl EventSourceMethods<crate::DomTypeHolder> for EventSource {
listener.notify_fetch(message.unwrap());
}),
);
- *ev.canceller.borrow_mut() = FetchCanceller::new(request.id);
+ ev.droppable.set_canceller(FetchCanceller::new(request.id));
global
.core_resource_thread()
.send(CoreResourceMsg::Fetch(
@@ -672,7 +691,7 @@ impl EventSourceMethods<crate::DomTypeHolder> for EventSource {
fn Close(&self) {
let GenerationId(prev_id) = self.generation_id.get();
self.generation_id.set(GenerationId(prev_id + 1));
- self.canceller.borrow_mut().cancel();
+ self.droppable.cancel();
self.ready_state.set(ReadyState::Closed);
}
}
diff --git a/components/script/dom/eventtarget.rs b/components/script/dom/eventtarget.rs
index 1a5aafb0ae7..15f77f5fcd5 100644
--- a/components/script/dom/eventtarget.rs
+++ b/components/script/dom/eventtarget.rs
@@ -59,7 +59,7 @@ use crate::dom::bindings::trace::HashMapTracedValues;
use crate::dom::document::Document;
use crate::dom::element::Element;
use crate::dom::errorevent::ErrorEvent;
-use crate::dom::event::{Event, EventBubbles, EventCancelable, EventStatus};
+use crate::dom::event::{Event, EventBubbles, EventCancelable, EventComposed, EventStatus};
use crate::dom::globalscope::GlobalScope;
use crate::dom::htmlformelement::FormControlElementHelpers;
use crate::dom::node::{Node, NodeTraits};
@@ -767,6 +767,7 @@ impl EventTarget {
name,
EventBubbles::DoesNotBubble,
EventCancelable::NotCancelable,
+ EventComposed::NotComposed,
can_gc,
)
}
@@ -777,6 +778,7 @@ impl EventTarget {
name,
EventBubbles::Bubbles,
EventCancelable::NotCancelable,
+ EventComposed::NotComposed,
can_gc,
)
}
@@ -787,6 +789,7 @@ impl EventTarget {
name,
EventBubbles::DoesNotBubble,
EventCancelable::Cancelable,
+ EventComposed::NotComposed,
can_gc,
)
}
@@ -801,19 +804,22 @@ impl EventTarget {
name,
EventBubbles::Bubbles,
EventCancelable::Cancelable,
+ EventComposed::NotComposed,
can_gc,
)
}
- // https://dom.spec.whatwg.org/#concept-event-fire
+ /// <https://dom.spec.whatwg.org/#concept-event-fire>
pub(crate) fn fire_event_with_params(
&self,
name: Atom,
bubbles: EventBubbles,
cancelable: EventCancelable,
+ composed: EventComposed,
can_gc: CanGc,
) -> DomRoot<Event> {
let event = Event::new(&self.global(), name, bubbles, cancelable, can_gc);
+ event.set_composed(composed.into());
event.fire(self, can_gc);
event
}
diff --git a/components/script/dom/htmlhrelement.rs b/components/script/dom/htmlhrelement.rs
index c88a0fcf184..8dc11e4e848 100644
--- a/components/script/dom/htmlhrelement.rs
+++ b/components/script/dom/htmlhrelement.rs
@@ -2,11 +2,17 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
+use std::str::FromStr;
+
use dom_struct::dom_struct;
use html5ever::{LocalName, Prefix, local_name, ns};
use js::rust::HandleObject;
use style::attr::{AttrValue, LengthOrPercentageOrAuto};
use style::color::AbsoluteColor;
+use style::values::generics::NonNegative;
+use style::values::specified::border::BorderSideWidth;
+use style::values::specified::length::Size;
+use style::values::specified::{LengthPercentage, NoCalcLength};
use crate::dom::bindings::codegen::Bindings::HTMLHRElementBinding::HTMLHRElementMethods;
use crate::dom::bindings::inheritance::Castable;
@@ -65,6 +71,18 @@ impl HTMLHRElementMethods<crate::DomTypeHolder> for HTMLHRElement {
// https://html.spec.whatwg.org/multipage/#dom-hr-color
make_legacy_color_setter!(SetColor, "color");
+ // https://html.spec.whatwg.org/multipage/#dom-hr-noshade
+ make_bool_getter!(NoShade, "noshade");
+
+ // https://html.spec.whatwg.org/multipage/#dom-hr-noshade
+ make_bool_setter!(SetNoShade, "noshade");
+
+ // https://html.spec.whatwg.org/multipage/#dom-hr-size
+ make_getter!(Size, "size");
+
+ // https://html.spec.whatwg.org/multipage/#dom-hr-size
+ make_dimension_setter!(SetSize, "size");
+
// https://html.spec.whatwg.org/multipage/#dom-hr-width
make_getter!(Width, "width");
@@ -72,9 +90,20 @@ impl HTMLHRElementMethods<crate::DomTypeHolder> for HTMLHRElement {
make_dimension_setter!(SetWidth, "width");
}
+/// The result of applying the the presentational hint for the `size` attribute.
+///
+/// (This attribute can mean different things depending on its value and other attributes)
+#[allow(clippy::enum_variant_names)]
+pub(crate) enum SizePresentationalHint {
+ SetHeightTo(Size),
+ SetAllBorderWidthValuesTo(BorderSideWidth),
+ SetBottomBorderWidthToZero,
+}
+
pub(crate) trait HTMLHRLayoutHelpers {
fn get_color(self) -> Option<AbsoluteColor>;
fn get_width(self) -> LengthOrPercentageOrAuto;
+ fn get_size_info(self) -> Option<SizePresentationalHint>;
}
impl HTMLHRLayoutHelpers for LayoutDom<'_, HTMLHRElement> {
@@ -92,6 +121,35 @@ impl HTMLHRLayoutHelpers for LayoutDom<'_, HTMLHRElement> {
.cloned()
.unwrap_or(LengthOrPercentageOrAuto::Auto)
}
+
+ fn get_size_info(self) -> Option<SizePresentationalHint> {
+ // https://html.spec.whatwg.org/multipage/#the-hr-element-2
+ let element = self.upcast::<Element>();
+ let size_value = element
+ .get_attr_val_for_layout(&ns!(), &local_name!("size"))
+ .and_then(|value| usize::from_str(value).ok())
+ .filter(|value| *value != 0)?;
+
+ let hint = if element
+ .get_attr_for_layout(&ns!(), &local_name!("color"))
+ .is_some() ||
+ element
+ .get_attr_for_layout(&ns!(), &local_name!("noshade"))
+ .is_some()
+ {
+ SizePresentationalHint::SetAllBorderWidthValuesTo(BorderSideWidth::from_px(
+ size_value as f32 / 2.0,
+ ))
+ } else if size_value == 1 {
+ SizePresentationalHint::SetBottomBorderWidthToZero
+ } else {
+ SizePresentationalHint::SetHeightTo(Size::LengthPercentage(NonNegative(
+ LengthPercentage::Length(NoCalcLength::from_px((size_value - 2) as f32)),
+ )))
+ };
+
+ Some(hint)
+ }
}
impl VirtualMethods for HTMLHRElement {
diff --git a/components/script/dom/htmlmediaelement.rs b/components/script/dom/htmlmediaelement.rs
index e2b31e918de..aa1323cdc5f 100644
--- a/components/script/dom/htmlmediaelement.rs
+++ b/components/script/dom/htmlmediaelement.rs
@@ -878,6 +878,9 @@ impl HTMLMediaElement {
fn fetch_request(&self, offset: Option<u64>, seek_lock: Option<SeekLock>) {
if self.resource_url.borrow().is_none() && self.blob_url.borrow().is_none() {
eprintln!("Missing request url");
+ if let Some(seek_lock) = seek_lock {
+ seek_lock.unlock(/* successful seek */ false);
+ }
self.queue_dedicated_media_source_failure_steps();
return;
}
@@ -923,9 +926,17 @@ impl HTMLMediaElement {
*current_fetch_context = Some(HTMLMediaElementFetchContext::new(request.id));
let listener =
- HTMLMediaElementFetchListener::new(self, url.clone(), offset.unwrap_or(0), seek_lock);
+ HTMLMediaElementFetchListener::new(self, request.id, url.clone(), offset.unwrap_or(0));
self.owner_document().fetch_background(request, listener);
+
+ // Since we cancelled the previous fetch, from now on the media element
+ // will only receive response data from the new fetch that's been
+ // initiated. This means the player can resume operation, since all subsequent data
+ // pushes will originate from the new seek offset.
+ if let Some(seek_lock) = seek_lock {
+ seek_lock.unlock(/* successful seek */ true);
+ }
}
// https://html.spec.whatwg.org/multipage/#concept-media-load-resource
@@ -1414,6 +1425,7 @@ impl HTMLMediaElement {
audio_renderer,
Box::new(window.get_player_context()),
);
+ let player_id = player.lock().unwrap().get_id();
*self.player.borrow_mut() = Some(player);
@@ -1430,7 +1442,7 @@ impl HTMLMediaElement {
trace!("Player event {:?}", event);
let this = trusted_node.clone();
task_source.queue(task!(handle_player_event: move || {
- this.root().handle_player_event(&event, CanGc::note());
+ this.root().handle_player_event(player_id, &event, CanGc::note());
}));
}),
);
@@ -1514,406 +1526,458 @@ impl HTMLMediaElement {
}
}
- fn handle_player_event(&self, event: &PlayerEvent, can_gc: CanGc) {
- match *event {
- PlayerEvent::EndOfStream => {
- // https://html.spec.whatwg.org/multipage/#media-data-processing-steps-list
- // => "If the media data can be fetched but is found by inspection to be in
- // an unsupported format, or can otherwise not be rendered at all"
- if self.ready_state.get() < ReadyState::HaveMetadata {
- self.queue_dedicated_media_source_failure_steps();
- } else {
- // https://html.spec.whatwg.org/multipage/#reaches-the-end
- match self.direction_of_playback() {
- PlaybackDirection::Forwards => {
- // Step 1.
- if self.Loop() {
- self.seek(
- self.earliest_possible_position(),
- /* approximate_for_speed*/ false,
- );
- } else {
- // Step 2.
- // The **ended playback** condition is implemented inside of
- // the HTMLMediaElementMethods::Ended method
-
- // Step 3.
- let this = Trusted::new(self);
-
- self.owner_global().task_manager().media_element_task_source().queue(
- task!(reaches_the_end_steps: move || {
- let this = this.root();
- // Step 3.1.
- this.upcast::<EventTarget>().fire_event(atom!("timeupdate"), CanGc::note());
-
- // Step 3.2.
- if this.Ended() && !this.Paused() {
- // Step 3.2.1.
- this.paused.set(true);
-
- // Step 3.2.2.
- this.upcast::<EventTarget>().fire_event(atom!("pause"), CanGc::note());
-
- // Step 3.2.3.
- this.take_pending_play_promises(Err(Error::Abort));
- this.fulfill_in_flight_play_promises(|| ());
- }
-
- // Step 3.3.
- this.upcast::<EventTarget>().fire_event(atom!("ended"), CanGc::note());
- })
- );
-
- // https://html.spec.whatwg.org/multipage/#dom-media-have_current_data
- self.change_ready_state(ReadyState::HaveCurrentData);
- }
- },
+ fn end_of_playback_in_forwards_direction(&self) {
+ // Step 1. If the media element has a loop attribute specified, then seek to the earliest
+ // posible position of the media resource and return.
+ if self.Loop() {
+ self.seek(
+ self.earliest_possible_position(),
+ /* approximate_for_speed*/ false,
+ );
+ return;
+ }
+ // Step 2. The ended IDL attribute starts returning true once the event loop returns to
+ // step 1.
+ // The **ended playback** condition is implemented inside of
+ // the HTMLMediaElementMethods::Ended method
- PlaybackDirection::Backwards => {
- if self.playback_position.get() <= self.earliest_possible_position() {
- self.owner_global()
- .task_manager()
- .media_element_task_source()
- .queue_simple_event(self.upcast(), atom!("ended"));
- }
- },
- }
- }
- },
- PlayerEvent::Error(ref error) => {
- error!("Player error: {:?}", error);
+ // Step 3. Queue a media element task given the media element and the following steps:
+ let this = Trusted::new(self);
- // If we have already flagged an error condition while processing
- // the network response, we should silently skip any observable
- // errors originating while decoding the erroneous response.
- if self.in_error_state() {
- return;
+ self.owner_global()
+ .task_manager()
+ .media_element_task_source()
+ .queue(task!(reaches_the_end_steps: move || {
+ let this = this.root();
+ // Step 3.1. Fire an event named timeupdate at the media element
+ this.upcast::<EventTarget>().fire_event(atom!("timeupdate"), CanGc::note());
+
+ // Step 3.2. If the media element has ended playback, the direction of playback is
+ // forwards, and paused is false, then:
+ if this.Ended() && !this.Paused() {
+ // Step 3.2.1. Set the paused attribute to true
+ this.paused.set(true);
+
+ // Step 3.2.2. Fire an event named pause at the media element
+ this.upcast::<EventTarget>().fire_event(atom!("pause"), CanGc::note());
+
+ // Step 3.2.3. Take pending play promises and reject pending play promises with
+ // the result and an "AbortError" DOMException
+ this.take_pending_play_promises(Err(Error::Abort));
+ this.fulfill_in_flight_play_promises(|| ());
}
- // https://html.spec.whatwg.org/multipage/#loading-the-media-resource:media-data-13
- // 1. The user agent should cancel the fetching process.
- if let Some(ref mut current_fetch_context) =
- *self.current_fetch_context.borrow_mut()
- {
- current_fetch_context.cancel(CancelReason::Error);
- }
- // 2. Set the error attribute to the result of creating a MediaError with MEDIA_ERR_DECODE.
- self.error.set(Some(&*MediaError::new(
- &self.owner_window(),
- MEDIA_ERR_DECODE,
- can_gc,
- )));
+ // Step 3.3. Fire an event named ended at the media element.
+ this.upcast::<EventTarget>().fire_event(atom!("ended"), CanGc::note());
+ }));
- // 3. Set the element's networkState attribute to the NETWORK_IDLE value.
- self.network_state.set(NetworkState::Idle);
+ // https://html.spec.whatwg.org/multipage/#dom-media-have_current_data
+ self.change_ready_state(ReadyState::HaveCurrentData);
+ }
- // 4. Set the element's delaying-the-load-event flag to false. This stops delaying the load event.
- self.delay_load_event(false, can_gc);
+ fn playback_end(&self) {
+ // https://html.spec.whatwg.org/multipage/#media-data-processing-steps-list
+ // => "If the media data can be fetched but is found by inspection to be in
+ // an unsupported format, or can otherwise not be rendered at all"
+ if self.ready_state.get() < ReadyState::HaveMetadata {
+ self.queue_dedicated_media_source_failure_steps();
+ return;
+ }
- // 5. Fire an event named error at the media element.
- self.upcast::<EventTarget>()
- .fire_event(atom!("error"), can_gc);
+ // https://html.spec.whatwg.org/multipage/#reaches-the-end
+ match self.direction_of_playback() {
+ PlaybackDirection::Forwards => self.end_of_playback_in_forwards_direction(),
- // TODO: 6. Abort the overall resource selection algorithm.
- },
- PlayerEvent::VideoFrameUpdated => {
- // Check if the frame was resized
- if let Some(frame) = self.video_renderer.lock().unwrap().current_frame {
- self.handle_resize(Some(frame.width as u32), Some(frame.height as u32));
+ PlaybackDirection::Backwards => {
+ if self.playback_position.get() <= self.earliest_possible_position() {
+ self.owner_global()
+ .task_manager()
+ .media_element_task_source()
+ .queue_simple_event(self.upcast(), atom!("ended"));
}
},
- PlayerEvent::MetadataUpdated(ref metadata) => {
- // https://html.spec.whatwg.org/multipage/#media-data-processing-steps-list
- // => If the media resource is found to have an audio track
- if !metadata.audio_tracks.is_empty() {
- for (i, _track) in metadata.audio_tracks.iter().enumerate() {
- // Step 1.
- let kind = match i {
- 0 => DOMString::from("main"),
- _ => DOMString::new(),
- };
- let window = self.owner_window();
- let audio_track = AudioTrack::new(
- &window,
- DOMString::new(),
- kind,
- DOMString::new(),
- DOMString::new(),
- Some(&*self.AudioTracks()),
- can_gc,
- );
-
- // Steps 2. & 3.
- self.AudioTracks().add(&audio_track);
-
- // Step 4
- if let Some(servo_url) = self.resource_url.borrow().as_ref() {
- let fragment = MediaFragmentParser::from(servo_url);
- if let Some(id) = fragment.id() {
- if audio_track.id() == DOMString::from(id) {
- self.AudioTracks()
- .set_enabled(self.AudioTracks().len() - 1, true);
- }
- }
+ }
+ }
- if fragment.tracks().contains(&audio_track.kind().into()) {
- self.AudioTracks()
- .set_enabled(self.AudioTracks().len() - 1, true);
- }
- }
+ fn playback_error(&self, error: &str, can_gc: CanGc) {
+ error!("Player error: {:?}", error);
+
+ // If we have already flagged an error condition while processing
+ // the network response, we should silently skip any observable
+ // errors originating while decoding the erroneous response.
+ if self.in_error_state() {
+ return;
+ }
+
+ // https://html.spec.whatwg.org/multipage/#loading-the-media-resource:media-data-13
+ // 1. The user agent should cancel the fetching process.
+ if let Some(ref mut current_fetch_context) = *self.current_fetch_context.borrow_mut() {
+ current_fetch_context.cancel(CancelReason::Error);
+ }
+ // 2. Set the error attribute to the result of creating a MediaError with MEDIA_ERR_DECODE.
+ self.error.set(Some(&*MediaError::new(
+ &self.owner_window(),
+ MEDIA_ERR_DECODE,
+ can_gc,
+ )));
+
+ // 3. Set the element's networkState attribute to the NETWORK_IDLE value.
+ self.network_state.set(NetworkState::Idle);
+
+ // 4. Set the element's delaying-the-load-event flag to false. This stops delaying the load event.
+ self.delay_load_event(false, can_gc);
+
+ // 5. Fire an event named error at the media element.
+ self.upcast::<EventTarget>()
+ .fire_event(atom!("error"), can_gc);
- // Step 5. & 6,
- if self.AudioTracks().enabled_index().is_none() {
+ // TODO: 6. Abort the overall resource selection algorithm.
+ }
+
+ fn playback_metadata_updated(
+ &self,
+ metadata: &servo_media::player::metadata::Metadata,
+ can_gc: CanGc,
+ ) {
+ // https://html.spec.whatwg.org/multipage/#media-data-processing-steps-list
+ // => If the media resource is found to have an audio track
+ if !metadata.audio_tracks.is_empty() {
+ for (i, _track) in metadata.audio_tracks.iter().enumerate() {
+ // Step 1.
+ let kind = match i {
+ 0 => DOMString::from("main"),
+ _ => DOMString::new(),
+ };
+ let window = self.owner_window();
+ let audio_track = AudioTrack::new(
+ &window,
+ DOMString::new(),
+ kind,
+ DOMString::new(),
+ DOMString::new(),
+ Some(&*self.AudioTracks()),
+ can_gc,
+ );
+
+ // Steps 2. & 3.
+ self.AudioTracks().add(&audio_track);
+
+ // Step 4
+ if let Some(servo_url) = self.resource_url.borrow().as_ref() {
+ let fragment = MediaFragmentParser::from(servo_url);
+ if let Some(id) = fragment.id() {
+ if audio_track.id() == DOMString::from(id) {
self.AudioTracks()
.set_enabled(self.AudioTracks().len() - 1, true);
}
+ }
- // Steps 7.
- let event = TrackEvent::new(
- self.global().as_window(),
- atom!("addtrack"),
- false,
- false,
- &Some(VideoTrackOrAudioTrackOrTextTrack::AudioTrack(audio_track)),
- can_gc,
- );
-
- event
- .upcast::<Event>()
- .fire(self.upcast::<EventTarget>(), can_gc);
+ if fragment.tracks().contains(&audio_track.kind().into()) {
+ self.AudioTracks()
+ .set_enabled(self.AudioTracks().len() - 1, true);
}
}
- // => If the media resource is found to have a video track
- if !metadata.video_tracks.is_empty() {
- for (i, _track) in metadata.video_tracks.iter().enumerate() {
- // Step 1.
- let kind = match i {
- 0 => DOMString::from("main"),
- _ => DOMString::new(),
- };
- let window = self.owner_window();
- let video_track = VideoTrack::new(
- &window,
- DOMString::new(),
- kind,
- DOMString::new(),
- DOMString::new(),
- Some(&*self.VideoTracks()),
- can_gc,
- );
-
- // Steps 2. & 3.
- self.VideoTracks().add(&video_track);
-
- // Step 4.
- if let Some(track) = self.VideoTracks().item(0) {
- if let Some(servo_url) = self.resource_url.borrow().as_ref() {
- let fragment = MediaFragmentParser::from(servo_url);
- if let Some(id) = fragment.id() {
- if track.id() == DOMString::from(id) {
- self.VideoTracks().set_selected(0, true);
- }
- } else if fragment.tracks().contains(&track.kind().into()) {
- self.VideoTracks().set_selected(0, true);
- }
- }
- }
+ // Step 5. & 6,
+ if self.AudioTracks().enabled_index().is_none() {
+ self.AudioTracks()
+ .set_enabled(self.AudioTracks().len() - 1, true);
+ }
- // Step 5. & 6.
- if self.VideoTracks().selected_index().is_none() {
- self.VideoTracks()
- .set_selected(self.VideoTracks().len() - 1, true);
- }
+ // Steps 7.
+ let event = TrackEvent::new(
+ self.global().as_window(),
+ atom!("addtrack"),
+ false,
+ false,
+ &Some(VideoTrackOrAudioTrackOrTextTrack::AudioTrack(audio_track)),
+ can_gc,
+ );
- // Steps 7.
- let event = TrackEvent::new(
- self.global().as_window(),
- atom!("addtrack"),
- false,
- false,
- &Some(VideoTrackOrAudioTrackOrTextTrack::VideoTrack(video_track)),
- can_gc,
- );
-
- event
- .upcast::<Event>()
- .fire(self.upcast::<EventTarget>(), can_gc);
- }
- }
+ event
+ .upcast::<Event>()
+ .fire(self.upcast::<EventTarget>(), can_gc);
+ }
+ }
- // => "Once enough of the media data has been fetched to determine the duration..."
+ // => If the media resource is found to have a video track
+ if !metadata.video_tracks.is_empty() {
+ for (i, _track) in metadata.video_tracks.iter().enumerate() {
// Step 1.
- // servo-media owns the media timeline.
-
- // Step 2.
- // XXX(ferjm) Update the timeline offset.
+ let kind = match i {
+ 0 => DOMString::from("main"),
+ _ => DOMString::new(),
+ };
+ let window = self.owner_window();
+ let video_track = VideoTrack::new(
+ &window,
+ DOMString::new(),
+ kind,
+ DOMString::new(),
+ DOMString::new(),
+ Some(&*self.VideoTracks()),
+ can_gc,
+ );
- // Step 3.
- self.playback_position.set(0.);
+ // Steps 2. & 3.
+ self.VideoTracks().add(&video_track);
// Step 4.
- let previous_duration = self.duration.get();
- if let Some(duration) = metadata.duration {
- self.duration.set(duration.as_secs() as f64);
- } else {
- self.duration.set(f64::INFINITY);
+ if let Some(track) = self.VideoTracks().item(0) {
+ if let Some(servo_url) = self.resource_url.borrow().as_ref() {
+ let fragment = MediaFragmentParser::from(servo_url);
+ if let Some(id) = fragment.id() {
+ if track.id() == DOMString::from(id) {
+ self.VideoTracks().set_selected(0, true);
+ }
+ } else if fragment.tracks().contains(&track.kind().into()) {
+ self.VideoTracks().set_selected(0, true);
+ }
+ }
}
- if previous_duration != self.duration.get() {
- self.owner_global()
- .task_manager()
- .media_element_task_source()
- .queue_simple_event(self.upcast(), atom!("durationchange"));
+
+ // Step 5. & 6.
+ if self.VideoTracks().selected_index().is_none() {
+ self.VideoTracks()
+ .set_selected(self.VideoTracks().len() - 1, true);
}
- // Step 5.
- self.handle_resize(Some(metadata.width), Some(metadata.height));
+ // Steps 7.
+ let event = TrackEvent::new(
+ self.global().as_window(),
+ atom!("addtrack"),
+ false,
+ false,
+ &Some(VideoTrackOrAudioTrackOrTextTrack::VideoTrack(video_track)),
+ can_gc,
+ );
- // Step 6.
- self.change_ready_state(ReadyState::HaveMetadata);
+ event
+ .upcast::<Event>()
+ .fire(self.upcast::<EventTarget>(), can_gc);
+ }
+ }
- // Step 7.
- let mut jumped = false;
-
- // Step 8.
- if self.default_playback_start_position.get() > 0. {
- self.seek(
- self.default_playback_start_position.get(),
- /* approximate_for_speed*/ false,
- );
- jumped = true;
- }
+ // => "Once enough of the media data has been fetched to determine the duration..."
+ // Step 1.
+ // servo-media owns the media timeline.
- // Step 9.
- self.default_playback_start_position.set(0.);
+ // Step 2.
+ // XXX(ferjm) Update the timeline offset.
- // Steps 10 and 11.
- if let Some(servo_url) = self.resource_url.borrow().as_ref() {
- let fragment = MediaFragmentParser::from(servo_url);
- if let Some(start) = fragment.start() {
- if start > 0. && start < self.duration.get() {
- self.playback_position.set(start);
- if !jumped {
- self.seek(self.playback_position.get(), false)
- }
- }
+ // Step 3.
+ self.playback_position.set(0.);
+
+ // Step 4.
+ let previous_duration = self.duration.get();
+ if let Some(duration) = metadata.duration {
+ self.duration.set(duration.as_secs() as f64);
+ } else {
+ self.duration.set(f64::INFINITY);
+ }
+ if previous_duration != self.duration.get() {
+ self.owner_global()
+ .task_manager()
+ .media_element_task_source()
+ .queue_simple_event(self.upcast(), atom!("durationchange"));
+ }
+
+ // Step 5.
+ self.handle_resize(Some(metadata.width), Some(metadata.height));
+
+ // Step 6.
+ self.change_ready_state(ReadyState::HaveMetadata);
+
+ // Step 7.
+ let mut jumped = false;
+
+ // Step 8.
+ if self.default_playback_start_position.get() > 0. {
+ self.seek(
+ self.default_playback_start_position.get(),
+ /* approximate_for_speed*/ false,
+ );
+ jumped = true;
+ }
+
+ // Step 9.
+ self.default_playback_start_position.set(0.);
+
+ // Steps 10 and 11.
+ if let Some(servo_url) = self.resource_url.borrow().as_ref() {
+ let fragment = MediaFragmentParser::from(servo_url);
+ if let Some(start) = fragment.start() {
+ if start > 0. && start < self.duration.get() {
+ self.playback_position.set(start);
+ if !jumped {
+ self.seek(self.playback_position.get(), false)
}
}
+ }
+ }
- // Step 12 & 13 are already handled by the earlier media track processing.
+ // Step 12 & 13 are already handled by the earlier media track processing.
- // We wait until we have metadata to render the controls, so we render them
- // with the appropriate size.
- if self.Controls() {
- self.render_controls(can_gc);
- }
+ // We wait until we have metadata to render the controls, so we render them
+ // with the appropriate size.
+ if self.Controls() {
+ self.render_controls(can_gc);
+ }
- let global = self.global();
- let window = global.as_window();
+ let global = self.global();
+ let window = global.as_window();
+
+ // Update the media session metadata title with the obtained metadata.
+ window.Navigator().MediaSession().update_title(
+ metadata
+ .title
+ .clone()
+ .unwrap_or(window.get_url().into_string()),
+ );
+ }
- // Update the media session metadata title with the obtained metadata.
- window.Navigator().MediaSession().update_title(
- metadata
- .title
- .clone()
- .unwrap_or(window.get_url().into_string()),
- );
- },
- PlayerEvent::NeedData => {
- // The player needs more data.
- // If we already have a valid fetch request, we do nothing.
- // Otherwise, if we have no request and the previous request was
- // cancelled because we got an EnoughData event, we restart
- // fetching where we left.
- if let Some(ref current_fetch_context) = *self.current_fetch_context.borrow() {
- match current_fetch_context.cancel_reason() {
- Some(reason) if *reason == CancelReason::Backoff => {
- // XXX(ferjm) Ideally we should just create a fetch request from
- // where we left. But keeping track of the exact next byte that the
- // media backend expects is not the easiest task, so I'm simply
- // seeking to the current playback position for now which will create
- // a new fetch request for the last rendered frame.
- self.seek(self.playback_position.get(), false)
- },
- _ => (),
- }
+ fn playback_video_frame_updated(&self) {
+ // Check if the frame was resized
+ if let Some(frame) = self.video_renderer.lock().unwrap().current_frame {
+ self.handle_resize(Some(frame.width as u32), Some(frame.height as u32));
+ }
+ }
+
+ fn playback_need_data(&self) {
+ // The player needs more data.
+ // If we already have a valid fetch request, we do nothing.
+ // Otherwise, if we have no request and the previous request was
+ // cancelled because we got an EnoughData event, we restart
+ // fetching where we left.
+ if let Some(ref current_fetch_context) = *self.current_fetch_context.borrow() {
+ if let Some(reason) = current_fetch_context.cancel_reason() {
+ // XXX(ferjm) Ideally we should just create a fetch request from
+ // where we left. But keeping track of the exact next byte that the
+ // media backend expects is not the easiest task, so I'm simply
+ // seeking to the current playback position for now which will create
+ // a new fetch request for the last rendered frame.
+ if *reason == CancelReason::Backoff {
+ self.seek(self.playback_position.get(), false);
}
- },
- PlayerEvent::EnoughData => {
- self.change_ready_state(ReadyState::HaveEnoughData);
-
- // The player has enough data and it is asking us to stop pushing
- // bytes, so we cancel the ongoing fetch request iff we are able
- // to restart it from where we left. Otherwise, we continue the
- // current fetch request, assuming that some frames will be dropped.
- if let Some(ref mut current_fetch_context) =
- *self.current_fetch_context.borrow_mut()
- {
- if current_fetch_context.is_seekable() {
- current_fetch_context.cancel(CancelReason::Backoff);
- }
+ return;
+ }
+ }
+
+ if let Some(ref mut current_fetch_context) = *self.current_fetch_context.borrow_mut() {
+ if let Err(e) = {
+ let mut data_source = current_fetch_context.data_source().borrow_mut();
+ data_source.set_locked(false);
+ data_source.process_into_player_from_queue(self.player.borrow().as_ref().unwrap())
+ } {
+ // If we are pushing too much data and we know that we can
+ // restart the download later from where we left, we cancel
+ // the current request. Otherwise, we continue the request
+ // assuming that we may drop some frames.
+ if e == PlayerError::EnoughData {
+ current_fetch_context.cancel(CancelReason::Backoff);
+ }
+ }
+ }
+ }
+
+ fn playback_enough_data(&self) {
+ self.change_ready_state(ReadyState::HaveEnoughData);
+
+ // The player has enough data and it is asking us to stop pushing
+ // bytes, so we cancel the ongoing fetch request iff we are able
+ // to restart it from where we left. Otherwise, we continue the
+ // current fetch request, assuming that some frames will be dropped.
+ if let Some(ref mut current_fetch_context) = *self.current_fetch_context.borrow_mut() {
+ if current_fetch_context.is_seekable() {
+ current_fetch_context.cancel(CancelReason::Backoff);
+ }
+ }
+ }
+
+ fn playback_position_changed(&self, position: u64) {
+ let position = position as f64;
+ let _ = self
+ .played
+ .borrow_mut()
+ .add(self.playback_position.get(), position);
+ self.playback_position.set(position);
+ self.time_marches_on();
+ let media_position_state =
+ MediaPositionState::new(self.duration.get(), self.playbackRate.get(), position);
+ debug!(
+ "Sending media session event set position state {:?}",
+ media_position_state
+ );
+ self.send_media_session_event(MediaSessionEvent::SetPositionState(media_position_state));
+ }
+
+ fn playback_seek_done(&self) {
+ // Continuation of
+ // https://html.spec.whatwg.org/multipage/#dom-media-seek
+
+ // Step 13.
+ let task = MediaElementMicrotask::Seeked {
+ elem: DomRoot::from_ref(self),
+ generation_id: self.generation_id.get(),
+ };
+ ScriptThread::await_stable_state(Microtask::MediaElement(task));
+ }
+
+ fn playback_state_changed(&self, state: &PlaybackState) {
+ let mut media_session_playback_state = MediaSessionPlaybackState::None_;
+ match *state {
+ PlaybackState::Paused => {
+ media_session_playback_state = MediaSessionPlaybackState::Paused;
+ if self.ready_state.get() == ReadyState::HaveMetadata {
+ self.change_ready_state(ReadyState::HaveEnoughData);
}
},
- PlayerEvent::PositionChanged(position) => {
- let position = position as f64;
- let _ = self
- .played
- .borrow_mut()
- .add(self.playback_position.get(), position);
- self.playback_position.set(position);
- self.time_marches_on();
- let media_position_state =
- MediaPositionState::new(self.duration.get(), self.playbackRate.get(), position);
- debug!(
- "Sending media session event set position state {:?}",
- media_position_state
- );
- self.send_media_session_event(MediaSessionEvent::SetPositionState(
- media_position_state,
- ));
+ PlaybackState::Playing => {
+ media_session_playback_state = MediaSessionPlaybackState::Playing;
},
- PlayerEvent::SeekData(p, ref seek_lock) => {
- self.fetch_request(Some(p), Some(seek_lock.clone()));
+ PlaybackState::Buffering => {
+ // Do not send the media session playback state change event
+ // in this case as a None_ state is expected to clean up the
+ // session.
+ return;
},
- PlayerEvent::SeekDone(_) => {
- // Continuation of
- // https://html.spec.whatwg.org/multipage/#dom-media-seek
-
- // Step 13.
- let task = MediaElementMicrotask::Seeked {
- elem: DomRoot::from_ref(self),
- generation_id: self.generation_id.get(),
- };
- ScriptThread::await_stable_state(Microtask::MediaElement(task));
+ _ => {},
+ };
+ debug!(
+ "Sending media session event playback state changed to {:?}",
+ media_session_playback_state
+ );
+ self.send_media_session_event(MediaSessionEvent::PlaybackStateChange(
+ media_session_playback_state,
+ ));
+ }
+
+ fn handle_player_event(&self, player_id: usize, event: &PlayerEvent, can_gc: CanGc) {
+ // Ignore the asynchronous event from previous player.
+ if self
+ .player
+ .borrow()
+ .as_ref()
+ .is_none_or(|player| player.lock().unwrap().get_id() != player_id)
+ {
+ return;
+ }
+
+ match *event {
+ PlayerEvent::EndOfStream => self.playback_end(),
+ PlayerEvent::Error(ref error) => self.playback_error(error, can_gc),
+ PlayerEvent::VideoFrameUpdated => self.playback_video_frame_updated(),
+ PlayerEvent::MetadataUpdated(ref metadata) => {
+ self.playback_metadata_updated(metadata, can_gc)
},
- PlayerEvent::StateChanged(ref state) => {
- let mut media_session_playback_state = MediaSessionPlaybackState::None_;
- match *state {
- PlaybackState::Paused => {
- media_session_playback_state = MediaSessionPlaybackState::Paused;
- if self.ready_state.get() == ReadyState::HaveMetadata {
- self.change_ready_state(ReadyState::HaveEnoughData);
- }
- },
- PlaybackState::Playing => {
- media_session_playback_state = MediaSessionPlaybackState::Playing;
- },
- PlaybackState::Buffering => {
- // Do not send the media session playback state change event
- // in this case as a None_ state is expected to clean up the
- // session.
- return;
- },
- _ => {},
- };
- debug!(
- "Sending media session event playback state changed to {:?}",
- media_session_playback_state
- );
- self.send_media_session_event(MediaSessionEvent::PlaybackStateChange(
- media_session_playback_state,
- ));
+ PlayerEvent::NeedData => self.playback_need_data(),
+ PlayerEvent::EnoughData => self.playback_enough_data(),
+ PlayerEvent::PositionChanged(position) => self.playback_position_changed(position),
+ PlayerEvent::SeekData(p, ref seek_lock) => {
+ self.fetch_request(Some(p), Some(seek_lock.clone()))
},
+ PlayerEvent::SeekDone(_) => self.playback_seek_done(),
+ PlayerEvent::StateChanged(ref state) => self.playback_state_changed(state),
}
}
@@ -2659,6 +2723,80 @@ enum Resource {
Url(ServoUrl),
}
+#[derive(Debug, MallocSizeOf, PartialEq)]
+enum DataBuffer {
+ Payload(Vec<u8>),
+ EndOfStream,
+}
+
+#[derive(MallocSizeOf)]
+struct BufferedDataSource {
+ /// During initial setup and seeking (including clearing the buffer queue
+ /// and resetting the end-of-stream state), the data source should be locked and
+ /// any request for processing should be ignored until the media player informs us
+ /// via the NeedData event that it is ready to accept incoming data.
+ locked: Cell<bool>,
+ /// Temporary storage for incoming data.
+ buffers: VecDeque<DataBuffer>,
+}
+
+impl BufferedDataSource {
+ fn new() -> BufferedDataSource {
+ BufferedDataSource {
+ locked: Cell::new(true),
+ buffers: VecDeque::default(),
+ }
+ }
+
+ fn set_locked(&self, locked: bool) {
+ self.locked.set(locked)
+ }
+
+ fn add_buffer_to_queue(&mut self, buffer: DataBuffer) {
+ debug_assert_ne!(
+ self.buffers.back(),
+ Some(&DataBuffer::EndOfStream),
+ "The media backend not expects any further data after end of stream"
+ );
+
+ self.buffers.push_back(buffer);
+ }
+
+ fn process_into_player_from_queue(
+ &mut self,
+ player: &Arc<Mutex<dyn Player>>,
+ ) -> Result<(), PlayerError> {
+ // Early out if any request for processing should be ignored.
+ if self.locked.get() {
+ return Ok(());
+ }
+
+ while let Some(buffer) = self.buffers.pop_front() {
+ match buffer {
+ DataBuffer::Payload(payload) => {
+ if let Err(e) = player.lock().unwrap().push_data(payload) {
+ warn!("Could not push input data to player {:?}", e);
+ return Err(e);
+ }
+ },
+ DataBuffer::EndOfStream => {
+ if let Err(e) = player.lock().unwrap().end_of_stream() {
+ warn!("Could not signal EOS to player {:?}", e);
+ return Err(e);
+ }
+ },
+ }
+ }
+
+ Ok(())
+ }
+
+ fn reset(&mut self) {
+ self.locked.set(true);
+ self.buffers.clear();
+ }
+}
+
/// Indicates the reason why a fetch request was cancelled.
#[derive(Debug, MallocSizeOf, PartialEq)]
enum CancelReason {
@@ -2672,12 +2810,16 @@ enum CancelReason {
#[derive(MallocSizeOf)]
pub(crate) struct HTMLMediaElementFetchContext {
+ /// The fetch request id.
+ request_id: RequestId,
/// Some if the request has been cancelled.
cancel_reason: Option<CancelReason>,
/// Indicates whether the fetched stream is seekable.
is_seekable: bool,
/// Indicates whether the fetched stream is origin clean.
origin_clean: bool,
+ /// The buffered data source which to be processed by media backend.
+ data_source: DomRefCell<BufferedDataSource>,
/// Fetch canceller. Allows cancelling the current fetch request by
/// manually calling its .cancel() method or automatically on Drop.
fetch_canceller: FetchCanceller,
@@ -2686,13 +2828,19 @@ pub(crate) struct HTMLMediaElementFetchContext {
impl HTMLMediaElementFetchContext {
fn new(request_id: RequestId) -> HTMLMediaElementFetchContext {
HTMLMediaElementFetchContext {
+ request_id,
cancel_reason: None,
is_seekable: false,
origin_clean: true,
+ data_source: DomRefCell::new(BufferedDataSource::new()),
fetch_canceller: FetchCanceller::new(request_id),
}
}
+ fn request_id(&self) -> RequestId {
+ self.request_id
+ }
+
fn is_seekable(&self) -> bool {
self.is_seekable
}
@@ -2709,11 +2857,16 @@ impl HTMLMediaElementFetchContext {
self.origin_clean = false;
}
+ fn data_source(&self) -> &DomRefCell<BufferedDataSource> {
+ &self.data_source
+ }
+
fn cancel(&mut self, reason: CancelReason) {
if self.cancel_reason.is_some() {
return;
}
self.cancel_reason = Some(reason);
+ self.data_source.borrow_mut().reset();
self.fetch_canceller.cancel();
}
@@ -2729,6 +2882,8 @@ struct HTMLMediaElementFetchListener {
metadata: Option<Metadata>,
/// The generation of the media element when this fetch started.
generation_id: u32,
+ /// The fetch request id.
+ request_id: RequestId,
/// Time of last progress notification.
next_progress_event: Instant,
/// Timing data for this resource.
@@ -2743,10 +2898,6 @@ struct HTMLMediaElementFetchListener {
/// EnoughData event uses this value to restart the download from
/// the last fetched position.
latest_fetched_content: u64,
- /// The media player discards all data pushes until the seek block
- /// is released right before pushing the data from the offset requested
- /// by a seek request.
- seek_lock: Option<SeekLock>,
}
// https://html.spec.whatwg.org/multipage/#media-data-processing-steps-list
@@ -2758,11 +2909,6 @@ impl FetchResponseListener for HTMLMediaElementFetchListener {
fn process_response(&mut self, _: RequestId, metadata: Result<FetchMetadata, NetworkError>) {
let elem = self.elem.root();
- if elem.generation_id.get() != self.generation_id || elem.player.borrow().is_none() {
- // A new fetch request was triggered, so we ignore this response.
- return;
- }
-
if let Ok(FetchMetadata::Filtered {
filtered: FilteredMetadata::Opaque | FilteredMetadata::OpaqueRedirect(_),
..
@@ -2794,24 +2940,25 @@ impl FetchResponseListener for HTMLMediaElementFetchListener {
// We only set the expected input size if it changes.
if content_length != self.expected_content_length {
if let Some(content_length) = content_length {
- if let Err(e) = elem
- .player
- .borrow()
- .as_ref()
- .unwrap()
- .lock()
- .unwrap()
- .set_input_size(content_length)
- {
- warn!("Could not set player input size {:?}", e);
- } else {
- self.expected_content_length = Some(content_length);
- }
+ self.expected_content_length = Some(content_length);
}
}
}
}
+ // Explicit media player initialization with live/seekable source.
+ if let Err(e) = elem
+ .player
+ .borrow()
+ .as_ref()
+ .unwrap()
+ .lock()
+ .unwrap()
+ .set_input_size(self.expected_content_length.unwrap_or_default())
+ {
+ warn!("Could not set player input size {:?}", e);
+ }
+
let (status_is_ok, is_seekable) = self.metadata.as_ref().map_or((true, false), |s| {
let status = &s.status;
(
@@ -2841,46 +2988,29 @@ impl FetchResponseListener for HTMLMediaElementFetchListener {
fn process_response_chunk(&mut self, _: RequestId, payload: Vec<u8>) {
let elem = self.elem.root();
- // If an error was received previously or if we triggered a new fetch request,
- // we skip processing the payload.
- if elem.generation_id.get() != self.generation_id || elem.player.borrow().is_none() {
- return;
- }
- if let Some(ref current_fetch_context) = *elem.current_fetch_context.borrow() {
- if current_fetch_context.cancel_reason().is_some() {
- return;
- }
- }
let payload_len = payload.len() as u64;
- if let Some(seek_lock) = self.seek_lock.take() {
- seek_lock.unlock(/* successful seek */ true);
- }
+ // If an error was received previously, we skip processing the payload.
+ if let Some(ref mut current_fetch_context) = *elem.current_fetch_context.borrow_mut() {
+ if current_fetch_context.cancel_reason().is_some() {
+ return;
+ }
- // Push input data into the player.
- if let Err(e) = elem
- .player
- .borrow()
- .as_ref()
- .unwrap()
- .lock()
- .unwrap()
- .push_data(payload)
- {
- // If we are pushing too much data and we know that we can
- // restart the download later from where we left, we cancel
- // the current request. Otherwise, we continue the request
- // assuming that we may drop some frames.
- if e == PlayerError::EnoughData {
- if let Some(ref mut current_fetch_context) =
- *elem.current_fetch_context.borrow_mut()
- {
+ if let Err(e) = {
+ let mut data_source = current_fetch_context.data_source().borrow_mut();
+ data_source.add_buffer_to_queue(DataBuffer::Payload(payload));
+ data_source.process_into_player_from_queue(elem.player.borrow().as_ref().unwrap())
+ } {
+ // If we are pushing too much data and we know that we can
+ // restart the download later from where we left, we cancel
+ // the current request. Otherwise, we continue the request
+ // assuming that we may drop some frames.
+ if e == PlayerError::EnoughData {
current_fetch_context.cancel(CancelReason::Backoff);
}
+ return;
}
- warn!("Could not push input data to player {:?}", e);
- return;
}
self.latest_fetched_content += payload_len;
@@ -2903,32 +3033,19 @@ impl FetchResponseListener for HTMLMediaElementFetchListener {
status: Result<ResourceFetchTiming, NetworkError>,
) {
trace!("process response eof");
- if let Some(seek_lock) = self.seek_lock.take() {
- seek_lock.unlock(/* successful seek */ false);
- }
let elem = self.elem.root();
- if elem.generation_id.get() != self.generation_id || elem.player.borrow().is_none() {
- return;
- }
-
// There are no more chunks of the response body forthcoming, so we can
// go ahead and notify the media backend not to expect any further data.
- if let Err(e) = elem
- .player
- .borrow()
- .as_ref()
- .unwrap()
- .lock()
- .unwrap()
- .end_of_stream()
- {
- warn!("Could not signal EOS to player {:?}", e);
- }
+ if let Some(ref mut current_fetch_context) = *elem.current_fetch_context.borrow_mut() {
+ let mut data_source = current_fetch_context.data_source().borrow_mut();
+
+ data_source.add_buffer_to_queue(DataBuffer::EndOfStream);
+ let _ =
+ data_source.process_into_player_from_queue(elem.player.borrow().as_ref().unwrap());
- // If an error was previously received we skip processing the payload.
- if let Some(ref current_fetch_context) = *elem.current_fetch_context.borrow() {
+ // If an error was previously received we skip processing the payload.
if let Some(CancelReason::Error) = current_fetch_context.cancel_reason() {
return;
}
@@ -3015,28 +3132,32 @@ impl ResourceTimingListener for HTMLMediaElementFetchListener {
impl PreInvoke for HTMLMediaElementFetchListener {
fn should_invoke(&self) -> bool {
- //TODO: finish_load needs to run at some point if the generation changes.
- self.elem.root().generation_id.get() == self.generation_id
+ let elem = self.elem.root();
+
+ if elem.generation_id.get() != self.generation_id || elem.player.borrow().is_none() {
+ return false;
+ }
+
+ // A new fetch request was triggered, so we skip processing previous request.
+ elem.current_fetch_context
+ .borrow()
+ .as_ref()
+ .is_some_and(|context| context.request_id() == self.request_id)
}
}
impl HTMLMediaElementFetchListener {
- fn new(
- elem: &HTMLMediaElement,
- url: ServoUrl,
- offset: u64,
- seek_lock: Option<SeekLock>,
- ) -> Self {
+ fn new(elem: &HTMLMediaElement, request_id: RequestId, url: ServoUrl, offset: u64) -> Self {
Self {
elem: Trusted::new(elem),
metadata: None,
generation_id: elem.generation_id.get(),
+ request_id,
next_progress_event: Instant::now() + Duration::from_millis(350),
resource_timing: ResourceFetchTiming::new(ResourceTimingType::Resource),
url,
expected_content_length: None,
latest_fetched_content: offset,
- seek_lock,
}
}
}
diff --git a/components/script/dom/htmlselectelement.rs b/components/script/dom/htmlselectelement.rs
index 0f48c8e923f..2fd8f35c4d8 100644
--- a/components/script/dom/htmlselectelement.rs
+++ b/components/script/dom/htmlselectelement.rs
@@ -16,6 +16,8 @@ use embedder_traits::{SelectElementOptionOrOptgroup, SelectElementOption};
use euclid::{Size2D, Point2D, Rect};
use embedder_traits::{FormControl as EmbedderFormControl, EmbedderMsg};
+use crate::dom::bindings::refcounted::Trusted;
+use crate::dom::event::{EventBubbles, EventCancelable, EventComposed};
use crate::dom::bindings::codegen::GenericBindings::HTMLOptGroupElementBinding::HTMLOptGroupElement_Binding::HTMLOptGroupElementMethods;
use crate::dom::activation::Activatable;
use crate::dom::attr::Attr;
@@ -346,13 +348,6 @@ impl HTMLSelectElement {
.SetData(displayed_text.trim().into());
}
- pub(crate) fn selection_changed(&self, can_gc: CanGc) {
- self.update_shadow_tree(can_gc);
-
- self.upcast::<EventTarget>()
- .fire_bubbling_event(atom!("change"), can_gc);
- }
-
pub(crate) fn selected_option(&self) -> Option<DomRoot<HTMLOptionElement>> {
self.list_of_options()
.find(|opt_elem| opt_elem.Selected())
@@ -417,12 +412,39 @@ impl HTMLSelectElement {
return None;
};
- if response.is_some() && response != selected_index {
- self.selection_changed(can_gc);
- }
-
response
}
+
+ /// <https://html.spec.whatwg.org/multipage/#send-select-update-notifications>
+ fn send_update_notifications(&self) {
+ // > When the user agent is to send select update notifications, queue an element task on the
+ // > user interaction task source given the select element to run these steps:
+ let this = Trusted::new(self);
+ self.owner_global()
+ .task_manager()
+ .user_interaction_task_source()
+ .queue(task!(send_select_update_notification: move || {
+ let this = this.root();
+
+ // TODO: Step 1. Set the select element's user validity to true.
+
+ // Step 2. Fire an event named input at the select element, with the bubbles and composed
+ // attributes initialized to true.
+ this.upcast::<EventTarget>()
+ .fire_event_with_params(
+ atom!("input"),
+ EventBubbles::Bubbles,
+ EventCancelable::NotCancelable,
+ EventComposed::Composed,
+ CanGc::note(),
+ );
+
+ // Step 3. Fire an event named change at the select element, with the bubbles attribute initialized
+ // to true.
+ this.upcast::<EventTarget>()
+ .fire_bubbling_event(atom!("change"), CanGc::note());
+ }));
+ }
}
impl HTMLSelectElementMethods<crate::DomTypeHolder> for HTMLSelectElement {
@@ -578,21 +600,28 @@ impl HTMLSelectElementMethods<crate::DomTypeHolder> for HTMLSelectElement {
/// <https://html.spec.whatwg.org/multipage/#dom-select-selectedindex>
fn SetSelectedIndex(&self, index: i32, can_gc: CanGc) {
+ let mut selection_did_change = false;
+
let mut opt_iter = self.list_of_options();
for opt in opt_iter.by_ref().take(index as usize) {
+ selection_did_change |= opt.Selected();
opt.set_selectedness(false);
}
- if let Some(opt) = opt_iter.next() {
- opt.set_selectedness(true);
- opt.set_dirtiness(true);
+ if let Some(selected_option) = opt_iter.next() {
+ selection_did_change |= !selected_option.Selected();
+ selected_option.set_selectedness(true);
+ selected_option.set_dirtiness(true);
+
// Reset remaining <option> elements
for opt in opt_iter {
+ selection_did_change |= opt.Selected();
opt.set_selectedness(false);
}
}
- // TODO: Track whether the selected element actually changed
- self.update_shadow_tree(can_gc);
+ if selection_did_change {
+ self.update_shadow_tree(can_gc);
+ }
}
/// <https://html.spec.whatwg.org/multipage/#dom-cva-willvalidate>
@@ -767,7 +796,6 @@ impl Activatable for HTMLSelectElement {
true
}
- /// <https://html.spec.whatwg.org/multipage/#input-activation-behavior>
fn activation_behavior(&self, _event: &Event, _target: &EventTarget, can_gc: CanGc) {
let Some(selected_value) = self.show_menu(can_gc) else {
// The user did not select a value
@@ -775,6 +803,7 @@ impl Activatable for HTMLSelectElement {
};
self.SetSelectedIndex(selected_value as i32, can_gc);
+ self.send_update_notifications();
}
}
diff --git a/components/script/dom/node.rs b/components/script/dom/node.rs
index cd0a41ab9f6..4a0aec45024 100644
--- a/components/script/dom/node.rs
+++ b/components/script/dom/node.rs
@@ -48,7 +48,7 @@ use style::properties::ComputedValues;
use style::selector_parser::{SelectorImpl, SelectorParser};
use style::stylesheets::{Stylesheet, UrlExtraData};
use uuid::Uuid;
-use xml5ever::serialize as xml_serialize;
+use xml5ever::{local_name, serialize as xml_serialize};
use crate::conversions::Convert;
use crate::document_loader::DocumentLoader;
@@ -752,10 +752,9 @@ impl Node {
}
pub(crate) fn ranges_is_empty(&self) -> bool {
- match self.rare_data().as_ref() {
- Some(data) => data.ranges.is_empty(),
- None => false,
- }
+ self.rare_data()
+ .as_ref()
+ .is_none_or(|data| data.ranges.is_empty())
}
#[inline]
@@ -1261,13 +1260,13 @@ impl Node {
}
}
- pub(crate) fn unique_id(&self) -> String {
+ pub(crate) fn unique_id(&self, pipeline: PipelineId) -> String {
let mut rare_data = self.ensure_rare_data();
if rare_data.unique_id.is_none() {
- let id = UniqueId::new();
- ScriptThread::save_node_id(id.borrow().simple().to_string());
- rare_data.unique_id = Some(id);
+ let node_id = UniqueId::new();
+ ScriptThread::save_node_id(pipeline, node_id.borrow().simple().to_string());
+ rare_data.unique_id = Some(node_id);
}
rare_data
.unique_id
@@ -1281,6 +1280,7 @@ impl Node {
pub(crate) fn summarize(&self, can_gc: CanGc) -> NodeInfo {
let USVString(base_uri) = self.BaseURI();
let node_type = self.NodeType();
+ let pipeline = self.owner_document().window().pipeline_id();
let maybe_shadow_root = self.downcast::<ShadowRoot>();
let shadow_root_mode = maybe_shadow_root
@@ -1288,7 +1288,7 @@ impl Node {
.map(ShadowRootMode::convert);
let host = maybe_shadow_root
.map(ShadowRoot::Host)
- .map(|host| host.upcast::<Node>().unique_id());
+ .map(|host| host.upcast::<Node>().unique_id(pipeline));
let is_shadow_host = self.downcast::<Element>().is_some_and(|potential_host| {
let Some(root) = potential_host.shadow_root() else {
return false;
@@ -1310,12 +1310,12 @@ impl Node {
.map(|style| style.Display().into());
NodeInfo {
- unique_id: self.unique_id(),
+ unique_id: self.unique_id(pipeline),
host,
base_uri,
parent: self
.GetParentNode()
- .map_or("".to_owned(), |node| node.unique_id()),
+ .map_or("".to_owned(), |node| node.unique_id(pipeline)),
node_type,
is_top_level_document: node_type == NodeConstants::DOCUMENT_NODE,
node_name: String::from(self.NodeName()),
@@ -1469,6 +1469,21 @@ impl Node {
.map(|data| data.element_data.borrow().styles.primary().clone())
}
+ /// <https://html.spec.whatwg.org/multipage/#language>
+ pub(crate) fn get_lang(&self) -> Option<String> {
+ self.inclusive_ancestors(ShadowIncluding::Yes)
+ .filter_map(|node| {
+ node.downcast::<Element>().and_then(|el| {
+ el.get_attribute(&ns!(xml), &local_name!("lang"))
+ .or_else(|| el.get_attribute(&ns!(), &local_name!("lang")))
+ .map(|attr| String::from(attr.Value()))
+ })
+ // TODO: Check meta tags for a pragma-set default language
+ // TODO: Check HTTP Content-Language header
+ })
+ .next()
+ }
+
/// <https://dom.spec.whatwg.org/#assign-slotables-for-a-tree>
pub(crate) fn assign_slottables_for_a_tree(&self) {
// NOTE: This method traverses all descendants of the node and is potentially very
@@ -2649,7 +2664,9 @@ impl Node {
fn remove(node: &Node, parent: &Node, suppress_observers: SuppressObserver, can_gc: CanGc) {
parent.owner_doc().add_script_and_layout_blocker();
- // Step 2.
+ // Step 1. Let parent be node’s parent.
+ // Step 2. Assert: parent is non-null.
+ // NOTE: We get parent as an argument instead
assert!(
node.GetParentNode()
.is_some_and(|node_parent| &*node_parent == parent)
@@ -2661,11 +2678,21 @@ impl Node {
if parent.ranges_is_empty() {
None
} else {
- // Step 1.
+ // Step 1. Let parent be node’s parent.
+ // Step 2. Assert: parent is not null.
+ // NOTE: We already have the parent.
+
+ // Step 3. Let index be node’s index.
let index = node.index();
- // Steps 2-3 are handled in Node::unbind_from_tree.
- // Steps 4-5.
+
+ // Steps 4-5 are handled in Node::unbind_from_tree.
+
+ // Step 6. For each live range whose start node is parent and start offset is greater than index,
+ // decrease its start offset by 1.
+ // Step 7. For each live range whose end node is parent and end offset is greater than index,
+ // decrease its end offset by 1.
parent.ranges().decrease_above(parent, index, 1);
+
// Parent had ranges, we needed the index, let's keep track of
// it to avoid computing it for other ranges when calling
// unbind_from_tree recursively.
@@ -3909,7 +3936,12 @@ impl VirtualMethods for Node {
/// <https://dom.spec.whatwg.org/#concept-node-remove>
fn unbind_from_tree(&self, context: &UnbindContext, can_gc: CanGc) {
self.super_type().unwrap().unbind_from_tree(context, can_gc);
- if !self.ranges_is_empty() {
+
+ // Ranges should only drain to the parent from inclusive non-shadow
+ // including descendants. If we're in a shadow tree at this point then the
+ // unbind operation happened further up in the tree and we should not
+ // drain any ranges.
+ if !self.is_in_a_shadow_tree() && !self.ranges_is_empty() {
self.ranges().drain_to_parent(context, self);
}
}
diff --git a/components/script/dom/range.rs b/components/script/dom/range.rs
index 4bf3b7fb72a..a47b060e0f2 100644
--- a/components/script/dom/range.rs
+++ b/components/script/dom/range.rs
@@ -344,6 +344,58 @@ impl Range {
.chain(iter::once(end_clone))
.flat_map(move |node| node.content_boxes(can_gc))
}
+
+ /// <https://dom.spec.whatwg.org/#concept-range-bp-set>
+ #[allow(clippy::neg_cmp_op_on_partial_ord)]
+ fn set_the_start_or_end(
+ &self,
+ node: &Node,
+ offset: u32,
+ start_or_end: StartOrEnd,
+ ) -> ErrorResult {
+ // Step 1. If node is a doctype, then throw an "InvalidNodeTypeError" DOMException.
+ if node.is_doctype() {
+ return Err(Error::InvalidNodeType);
+ }
+
+ // Step 2. If offset is greater than node’s length, then throw an "IndexSizeError" DOMException.
+ if offset > node.len() {
+ return Err(Error::IndexSize);
+ }
+
+ // Step 3. Let bp be the boundary point (node, offset).
+ // NOTE: We don't need this part.
+
+ match start_or_end {
+ // If these steps were invoked as "set the start"
+ StartOrEnd::Start => {
+ // Step 4.1 If range’s root is not equal to node’s root, or if bp is after the range’s end,
+ // set range’s end to bp.
+ // Step 4.2 Set range’s start to bp.
+ self.set_start(node, offset);
+ if !(self.start() <= self.end()) {
+ self.set_end(node, offset);
+ }
+ },
+ // If these steps were invoked as "set the end"
+ StartOrEnd::End => {
+ // Step 4.1 If range’s root is not equal to node’s root, or if bp is before the range’s start,
+ // set range’s start to bp.
+ // Step 4.2 Set range’s end to bp.
+ self.set_end(node, offset);
+ if !(self.end() >= self.start()) {
+ self.set_start(node, offset);
+ }
+ },
+ }
+
+ Ok(())
+ }
+}
+
+enum StartOrEnd {
+ Start,
+ End,
}
impl RangeMethods<crate::DomTypeHolder> for Range {
@@ -365,43 +417,13 @@ impl RangeMethods<crate::DomTypeHolder> for Range {
}
/// <https://dom.spec.whatwg.org/#dom-range-setstart>
- #[allow(clippy::neg_cmp_op_on_partial_ord)]
fn SetStart(&self, node: &Node, offset: u32) -> ErrorResult {
- if node.is_doctype() {
- // Step 1.
- Err(Error::InvalidNodeType)
- } else if offset > node.len() {
- // Step 2.
- Err(Error::IndexSize)
- } else {
- // Step 3.
- self.set_start(node, offset);
- if !(self.start() <= self.end()) {
- // Step 4.
- self.set_end(node, offset);
- }
- Ok(())
- }
+ self.set_the_start_or_end(node, offset, StartOrEnd::Start)
}
/// <https://dom.spec.whatwg.org/#dom-range-setend>
- #[allow(clippy::neg_cmp_op_on_partial_ord)]
fn SetEnd(&self, node: &Node, offset: u32) -> ErrorResult {
- if node.is_doctype() {
- // Step 1.
- Err(Error::InvalidNodeType)
- } else if offset > node.len() {
- // Step 2.
- Err(Error::IndexSize)
- } else {
- // Step 3.
- self.set_end(node, offset);
- if !(self.end() >= self.start()) {
- // Step 4.
- self.set_start(node, offset);
- }
- Ok(())
- }
+ self.set_the_start_or_end(node, offset, StartOrEnd::End)
}
/// <https://dom.spec.whatwg.org/#dom-range-setstartbefore>
@@ -1204,6 +1226,7 @@ impl WeakRangeVec {
}
/// Used for steps 2-3. when removing a node.
+ ///
/// <https://dom.spec.whatwg.org/#concept-node-remove>
pub(crate) fn drain_to_parent(&self, context: &UnbindContext, child: &Node) {
if self.is_empty() {
diff --git a/components/script/dom/readablestream.rs b/components/script/dom/readablestream.rs
index d2c1d853f86..5203a5f0a83 100644
--- a/components/script/dom/readablestream.rs
+++ b/components/script/dom/readablestream.rs
@@ -1926,7 +1926,7 @@ impl ReadableStreamMethods<crate::DomTypeHolder> for ReadableStream {
// If ! IsReadableStreamLocked(this) is true,
// return a promise rejected with a TypeError exception.
let promise = Promise::new(&global, can_gc);
- promise.reject_error(Error::Type("stream is not locked".to_owned()), can_gc);
+ promise.reject_error(Error::Type("stream is locked".to_owned()), can_gc);
promise
} else {
// Return ! ReadableStreamCancel(this, reason).
diff --git a/components/script/dom/xmlhttprequest.rs b/components/script/dom/xmlhttprequest.rs
index 4e7c136f42b..858cd24d45d 100644
--- a/components/script/dom/xmlhttprequest.rs
+++ b/components/script/dom/xmlhttprequest.rs
@@ -797,6 +797,7 @@ impl XMLHttpRequestMethods<crate::DomTypeHolder> for XMLHttpRequest {
if self.ready_state.get() == XMLHttpRequestState::Done {
self.change_ready_state(XMLHttpRequestState::Unsent, can_gc);
self.response_status.set(Err(()));
+ *self.status.borrow_mut() = HttpStatus::new_error();
self.response.borrow_mut().clear();
self.response_headers.borrow_mut().clear();
}
@@ -1188,6 +1189,8 @@ impl XMLHttpRequest {
self.discard_subsequent_responses();
self.send_flag.set(false);
+ *self.status.borrow_mut() = HttpStatus::new_error();
+ self.response_headers.borrow_mut().clear();
// XXXManishearth set response to NetworkError
self.change_ready_state(XMLHttpRequestState::Done, can_gc);
return_if_fetch_was_terminated!();
diff --git a/components/script/dom/xpathresult.rs b/components/script/dom/xpathresult.rs
index f4a9ae7a31b..890e559ba97 100644
--- a/components/script/dom/xpathresult.rs
+++ b/components/script/dom/xpathresult.rs
@@ -54,7 +54,7 @@ impl TryFrom<u16> for XPathResultType {
}
}
-#[derive(JSTraceable, MallocSizeOf)]
+#[derive(Debug, JSTraceable, MallocSizeOf)]
pub(crate) enum XPathResultValue {
Boolean(bool),
/// A IEEE-754 double-precision floating point number
diff --git a/components/script/script_thread.rs b/components/script/script_thread.rs
index e138e7114d3..e7f60e23772 100644
--- a/components/script/script_thread.rs
+++ b/components/script/script_thread.rs
@@ -194,6 +194,8 @@ pub(crate) struct IncompleteParserContexts(RefCell<Vec<(PipelineId, ParserContex
unsafe_no_jsmanaged_fields!(TaskQueue<MainThreadScriptMsg>);
+type NodeIdSet = HashSet<String>;
+
#[derive(JSTraceable)]
// ScriptThread instances are rooted on creation, so this is okay
#[cfg_attr(crown, allow(crown::unrooted_must_root))]
@@ -315,8 +317,9 @@ pub struct ScriptThread {
#[no_trace]
player_context: WindowGLContext,
- /// A set of all nodes ever created in this script thread
- node_ids: DomRefCell<HashSet<String>>,
+ /// A map from pipelines to all owned nodes ever created in this script thread
+ #[no_trace]
+ pipeline_to_node_ids: DomRefCell<HashMap<PipelineId, NodeIdSet>>,
/// Code is running as a consequence of a user interaction
is_user_interacting: Cell<bool>,
@@ -818,14 +821,25 @@ impl ScriptThread {
})
}
- pub(crate) fn save_node_id(node_id: String) {
+ pub(crate) fn save_node_id(pipeline: PipelineId, node_id: String) {
with_script_thread(|script_thread| {
- script_thread.node_ids.borrow_mut().insert(node_id);
+ script_thread
+ .pipeline_to_node_ids
+ .borrow_mut()
+ .entry(pipeline)
+ .or_default()
+ .insert(node_id);
})
}
- pub(crate) fn has_node_id(node_id: &str) -> bool {
- with_script_thread(|script_thread| script_thread.node_ids.borrow().contains(node_id))
+ pub(crate) fn has_node_id(pipeline: PipelineId, node_id: &str) -> bool {
+ with_script_thread(|script_thread| {
+ script_thread
+ .pipeline_to_node_ids
+ .borrow()
+ .get(&pipeline)
+ .is_some_and(|node_ids| node_ids.contains(node_id))
+ })
}
/// Creates a new script thread.
@@ -945,7 +959,7 @@ impl ScriptThread {
unminify_css: opts.unminify_css,
user_content_manager: state.user_content_manager,
player_context: state.player_context,
- node_ids: Default::default(),
+ pipeline_to_node_ids: Default::default(),
is_user_interacting: Cell::new(false),
#[cfg(feature = "webgpu")]
gpu_id_hub: Arc::new(IdentityHub::default()),
@@ -2266,15 +2280,6 @@ impl ScriptThread {
can_gc,
)
},
- WebDriverScriptCommand::FocusElement(element_id, reply) => {
- webdriver_handlers::handle_focus_element(
- &documents,
- pipeline_id,
- element_id,
- reply,
- can_gc,
- )
- },
WebDriverScriptCommand::ElementClick(element_id, reply) => {
webdriver_handlers::handle_element_click(
&documents,
@@ -2380,6 +2385,20 @@ impl ScriptThread {
WebDriverScriptCommand::GetTitle(reply) => {
webdriver_handlers::handle_get_title(&documents, pipeline_id, reply)
},
+ WebDriverScriptCommand::WillSendKeys(
+ element_id,
+ text,
+ strict_file_interactability,
+ reply,
+ ) => webdriver_handlers::handle_will_send_keys(
+ &documents,
+ pipeline_id,
+ element_id,
+ text,
+ strict_file_interactability,
+ reply,
+ can_gc,
+ ),
_ => (),
}
}
diff --git a/components/script/timers.rs b/components/script/timers.rs
index 0dc1397fbdd..fe542c09a56 100644
--- a/components/script/timers.rs
+++ b/components/script/timers.rs
@@ -4,7 +4,7 @@
use std::cell::Cell;
use std::cmp::{Ord, Ordering};
-use std::collections::HashMap;
+use std::collections::{HashMap, VecDeque};
use std::default::Default;
use std::rc::Rc;
use std::time::{Duration, Instant};
@@ -47,7 +47,7 @@ pub(crate) struct OneshotTimers {
global_scope: Dom<GlobalScope>,
js_timers: JsTimers,
next_timer_handle: Cell<OneshotTimerHandle>,
- timers: DomRefCell<Vec<OneshotTimer>>,
+ timers: DomRefCell<VecDeque<OneshotTimer>>,
suspended_since: Cell<Option<Instant>>,
/// Initially 0, increased whenever the associated document is reactivated
/// by the amount of ms the document was inactive. The current time can be
@@ -131,7 +131,7 @@ impl OneshotTimers {
global_scope: Dom::from_ref(global_scope),
js_timers: JsTimers::default(),
next_timer_handle: Cell::new(OneshotTimerHandle(1)),
- timers: DomRefCell::new(Vec::new()),
+ timers: DomRefCell::new(VecDeque::new()),
suspended_since: Cell::new(None),
suspension_offset: Cell::new(Duration::ZERO),
expected_event_id: Cell::new(TimerEventId(0)),
@@ -180,7 +180,7 @@ impl OneshotTimers {
}
fn is_next_timer(&self, handle: OneshotTimerHandle) -> bool {
- match self.timers.borrow().last() {
+ match self.timers.borrow().back() {
None => false,
Some(max_timer) => max_timer.handle == handle,
}
@@ -201,7 +201,7 @@ impl OneshotTimers {
let base_time = self.base_time();
// Since the event id was the expected one, at least one timer should be due.
- if base_time < self.timers.borrow().last().unwrap().scheduled_for {
+ if base_time < self.timers.borrow().back().unwrap().scheduled_for {
warn!("Unexpected timing!");
return;
}
@@ -213,11 +213,11 @@ impl OneshotTimers {
loop {
let mut timers = self.timers.borrow_mut();
- if timers.is_empty() || timers.last().unwrap().scheduled_for > base_time {
+ if timers.is_empty() || timers.back().unwrap().scheduled_for > base_time {
break;
}
- timers_to_run.push(timers.pop().unwrap());
+ timers_to_run.push(timers.pop_back().unwrap());
}
for timer in timers_to_run {
@@ -286,7 +286,7 @@ impl OneshotTimers {
}
let timers = self.timers.borrow();
- let Some(timer) = timers.last() else {
+ let Some(timer) = timers.back() else {
return;
};
diff --git a/components/script/webdriver_handlers.rs b/components/script/webdriver_handlers.rs
index 6b4264d945e..c81dcbd85fd 100644
--- a/components/script/webdriver_handlers.rs
+++ b/components/script/webdriver_handlers.rs
@@ -81,7 +81,7 @@ fn find_node_by_unique_id(
match documents.find_document(pipeline) {
Some(doc) => find_node_by_unique_id_in_document(&doc, node_id),
None => {
- if ScriptThread::has_node_id(&node_id) {
+ if ScriptThread::has_node_id(pipeline, &node_id) {
Err(ErrorStatus::StaleElementReference)
} else {
Err(ErrorStatus::NoSuchElement)
@@ -94,14 +94,15 @@ pub(crate) fn find_node_by_unique_id_in_document(
document: &Document,
node_id: String,
) -> Result<DomRoot<Node>, ErrorStatus> {
+ let pipeline = document.window().pipeline_id();
match document
.upcast::<Node>()
.traverse_preorder(ShadowIncluding::Yes)
- .find(|node| node.unique_id() == node_id)
+ .find(|node| node.unique_id(pipeline) == node_id)
{
Some(node) => Ok(node),
None => {
- if ScriptThread::has_node_id(&node_id) {
+ if ScriptThread::has_node_id(pipeline, &node_id) {
Err(ErrorStatus::StaleElementReference)
} else {
Err(ErrorStatus::NoSuchElement)
@@ -129,7 +130,10 @@ fn matching_links(
content == link_text
}
})
- .map(|node| node.upcast::<Node>().unique_id())
+ .map(|node| {
+ node.upcast::<Node>()
+ .unique_id(node.owner_doc().window().pipeline_id())
+ })
}
fn all_matching_links(
@@ -329,20 +333,25 @@ unsafe fn jsval_to_webdriver_inner(
Ok(WebDriverJSValue::ArrayLike(result))
} else if let Ok(element) = root_from_object::<Element>(*object, cx) {
Ok(WebDriverJSValue::Element(WebElement(
- element.upcast::<Node>().unique_id(),
+ element
+ .upcast::<Node>()
+ .unique_id(element.owner_document().window().pipeline_id()),
)))
} else if let Ok(window) = root_from_object::<Window>(*object, cx) {
let window_proxy = window.window_proxy();
if window_proxy.is_browsing_context_discarded() {
return Err(WebDriverJSError::StaleElementReference);
- } else if window_proxy.browsing_context_id() == window_proxy.webview_id() {
- Ok(WebDriverJSValue::Window(WebWindow(
- window.Document().upcast::<Node>().unique_id(),
- )))
} else {
- Ok(WebDriverJSValue::Frame(WebFrame(
- window.Document().upcast::<Node>().unique_id(),
- )))
+ let pipeline = window.pipeline_id();
+ if window_proxy.browsing_context_id() == window_proxy.webview_id() {
+ Ok(WebDriverJSValue::Window(WebWindow(
+ window.Document().upcast::<Node>().unique_id(pipeline),
+ )))
+ } else {
+ Ok(WebDriverJSValue::Frame(WebFrame(
+ window.Document().upcast::<Node>().unique_id(pipeline),
+ )))
+ }
}
} else if object_has_to_json_property(cx, global_scope, object.handle()) {
let name = CString::new("toJSON").unwrap();
@@ -598,7 +607,7 @@ pub(crate) fn handle_find_element_css(
.QuerySelector(DOMString::from(selector))
.map_err(|_| ErrorStatus::InvalidSelector)
})
- .map(|node| node.map(|x| x.upcast::<Node>().unique_id())),
+ .map(|node| node.map(|x| x.upcast::<Node>().unique_id(pipeline))),
)
.unwrap();
}
@@ -640,7 +649,7 @@ pub(crate) fn handle_find_element_tag_name(
.elements_iter()
.next()
})
- .map(|node| node.map(|x| x.upcast::<Node>().unique_id())),
+ .map(|node| node.map(|x| x.upcast::<Node>().unique_id(pipeline))),
)
.unwrap();
}
@@ -664,7 +673,7 @@ pub(crate) fn handle_find_elements_css(
.map(|nodes| {
nodes
.iter()
- .map(|x| x.upcast::<Node>().unique_id())
+ .map(|x| x.upcast::<Node>().unique_id(pipeline))
.collect()
}),
)
@@ -706,7 +715,7 @@ pub(crate) fn handle_find_elements_tag_name(
.map(|nodes| {
nodes
.elements_iter()
- .map(|x| x.upcast::<Node>().unique_id())
+ .map(|x| x.upcast::<Node>().unique_id(pipeline))
.collect::<Vec<String>>()
}),
)
@@ -725,7 +734,7 @@ pub(crate) fn handle_find_element_element_css(
find_node_by_unique_id(documents, pipeline, element_id).and_then(|node| {
node.query_selector(DOMString::from(selector))
.map_err(|_| ErrorStatus::InvalidSelector)
- .map(|node| node.map(|x| x.upcast::<Node>().unique_id()))
+ .map(|node| node.map(|x| x.upcast::<Node>().unique_id(pipeline)))
}),
)
.unwrap();
@@ -764,7 +773,7 @@ pub(crate) fn handle_find_element_element_tag_name(
.GetElementsByTagName(DOMString::from(selector), can_gc)
.elements_iter()
.next()
- .map(|x| x.upcast::<Node>().unique_id())),
+ .map(|x| x.upcast::<Node>().unique_id(pipeline))),
None => Err(ErrorStatus::UnknownError),
}),
)
@@ -786,7 +795,7 @@ pub(crate) fn handle_find_element_elements_css(
.map(|nodes| {
nodes
.iter()
- .map(|x| x.upcast::<Node>().unique_id())
+ .map(|x| x.upcast::<Node>().unique_id(pipeline))
.collect()
})
}),
@@ -826,7 +835,7 @@ pub(crate) fn handle_find_element_elements_tag_name(
Some(element) => Ok(element
.GetElementsByTagName(DOMString::from(selector), can_gc)
.elements_iter()
- .map(|x| x.upcast::<Node>().unique_id())
+ .map(|x| x.upcast::<Node>().unique_id(pipeline))
.collect::<Vec<String>>()),
None => Err(ErrorStatus::UnknownError),
}),
@@ -834,24 +843,66 @@ pub(crate) fn handle_find_element_elements_tag_name(
.unwrap();
}
-pub(crate) fn handle_focus_element(
+pub(crate) fn handle_will_send_keys(
documents: &DocumentCollection,
pipeline: PipelineId,
element_id: String,
- reply: IpcSender<Result<(), ErrorStatus>>,
+ text: String,
+ strict_file_interactability: bool,
+ reply: IpcSender<Result<bool, ErrorStatus>>,
can_gc: CanGc,
) {
reply
.send(
find_node_by_unique_id(documents, pipeline, element_id).and_then(|node| {
- match node.downcast::<HTMLElement>() {
- Some(element) => {
- // Need a way to find if this actually succeeded
- element.Focus(can_gc);
- Ok(())
- },
- None => Err(ErrorStatus::UnknownError),
+ // Step 6: Let file be true if element is input element
+ // in the file upload state, or false otherwise
+ let file_input = node
+ .downcast::<HTMLInputElement>()
+ .filter(|&input_element| input_element.input_type() == InputType::File);
+
+ // Step 7: If file is false or the session's strict file interactability
+ if file_input.is_none() || strict_file_interactability {
+ match node.downcast::<HTMLElement>() {
+ Some(element) => {
+ // Need a way to find if this actually succeeded
+ element.Focus(can_gc);
+ },
+ None => return Err(ErrorStatus::UnknownError),
+ }
}
+
+ // Step 8 (file input)
+ if let Some(file_input) = file_input {
+ // Step 8.1: Let files be the result of splitting text
+ // on the newline (\n) character.
+ let files: Vec<DOMString> = text.split("\n").map(|s| s.into()).collect();
+
+ // Step 8.2
+ if files.is_empty() {
+ return Err(ErrorStatus::InvalidArgument);
+ }
+
+ // Step 8.3 - 8.4
+ if !file_input.Multiple() && files.len() > 1 {
+ return Err(ErrorStatus::InvalidArgument);
+ }
+
+ // Step 8.5
+ // TODO: Should return invalid argument error if file doesn't exist
+
+ // Step 8.6 - 8.7
+ // Input and change event already fired in `htmlinputelement.rs`.
+ file_input.SelectFiles(files, can_gc);
+
+ // Step 8.8
+ return Ok(false);
+ }
+
+ // TODO: Check non-typeable form control
+ // TODO: Check content editable
+
+ Ok(true)
}),
)
.unwrap();
@@ -867,7 +918,7 @@ pub(crate) fn handle_get_active_element(
documents
.find_document(pipeline)
.and_then(|document| document.GetActiveElement())
- .map(|element| element.upcast::<Node>().unique_id()),
+ .map(|element| element.upcast::<Node>().unique_id(pipeline)),
)
.unwrap();
}
@@ -1395,7 +1446,7 @@ pub(crate) fn handle_element_click(
Ok(None)
},
- None => Ok(Some(node.unique_id())),
+ None => Ok(Some(node.unique_id(pipeline))),
}
}),
)
diff --git a/components/script/xpath/context.rs b/components/script/xpath/context.rs
index df78a9a7bec..ff51c92521d 100644
--- a/components/script/xpath/context.rs
+++ b/components/script/xpath/context.rs
@@ -5,10 +5,14 @@
use std::iter::Enumerate;
use std::vec::IntoIter;
+use script_bindings::str::DOMString;
+
use super::Node;
+use crate::dom::bindings::codegen::Bindings::NodeBinding::NodeMethods;
use crate::dom::bindings::root::DomRoot;
/// The context during evaluation of an XPath expression.
+#[derive(Debug)]
pub(crate) struct EvaluationCtx {
/// Where we started at
pub(crate) starting_node: DomRoot<Node>,
@@ -20,7 +24,7 @@ pub(crate) struct EvaluationCtx {
pub(crate) predicate_nodes: Option<Vec<DomRoot<Node>>>,
}
-#[derive(Clone, Copy)]
+#[derive(Clone, Copy, Debug)]
pub(crate) struct PredicateCtx {
pub(crate) index: usize,
pub(crate) size: usize,
@@ -68,6 +72,12 @@ impl EvaluationCtx {
size,
}
}
+
+ /// Resolve a namespace prefix using the context node's document
+ pub(crate) fn resolve_namespace(&self, prefix: Option<&str>) -> Option<DOMString> {
+ self.context_node
+ .LookupNamespaceURI(prefix.map(DOMString::from))
+ }
}
/// When evaluating predicates, we need to keep track of the current node being evaluated and
diff --git a/components/script/xpath/eval.rs b/components/script/xpath/eval.rs
index 75d7ac5849c..38d8c2fee90 100644
--- a/components/script/xpath/eval.rs
+++ b/components/script/xpath/eval.rs
@@ -12,6 +12,7 @@ use super::parser::{
QName as ParserQualName, RelationalOp, StepExpr, UnaryOp,
};
use super::{EvaluationCtx, Value};
+use crate::dom::attr::Attr;
use crate::dom::bindings::codegen::Bindings::NodeBinding::NodeMethods;
use crate::dom::bindings::inheritance::{Castable, CharacterDataTypeId, NodeTypeId};
use crate::dom::bindings::root::DomRoot;
@@ -83,6 +84,22 @@ where
}
}
+impl<T> Evaluatable for Option<T>
+where
+ T: Evaluatable,
+{
+ fn evaluate(&self, context: &EvaluationCtx) -> Result<Value, Error> {
+ match self {
+ Some(expr) => expr.evaluate(context),
+ None => Ok(Value::Nodeset(vec![])),
+ }
+ }
+
+ fn is_primitive(&self) -> bool {
+ self.as_ref().is_some_and(|t| T::is_primitive(t))
+ }
+}
+
impl Evaluatable for Expr {
fn evaluate(&self, context: &EvaluationCtx) -> Result<Value, Error> {
match self {
@@ -230,21 +247,31 @@ impl Evaluatable for PathExpr {
}
}
-impl TryFrom<&ParserQualName> for QualName {
+pub(crate) struct QualNameConverter<'a> {
+ qname: &'a ParserQualName,
+ context: &'a EvaluationCtx,
+}
+
+impl<'a> TryFrom<QualNameConverter<'a>> for QualName {
type Error = Error;
- fn try_from(qname: &ParserQualName) -> Result<Self, Self::Error> {
- let qname_as_str = qname.to_string();
- if let Ok((ns, prefix, local)) = validate_and_extract(None, &qname_as_str) {
+ fn try_from(converter: QualNameConverter<'a>) -> Result<Self, Self::Error> {
+ let qname_as_str = converter.qname.to_string();
+ let namespace = converter
+ .context
+ .resolve_namespace(converter.qname.prefix.as_deref());
+
+ if let Ok((ns, prefix, local)) = validate_and_extract(namespace, &qname_as_str) {
Ok(QualName { prefix, ns, local })
} else {
Err(Error::InvalidQName {
- qname: qname.clone(),
+ qname: converter.qname.clone(),
})
}
}
}
+#[derive(Debug)]
pub(crate) enum NameTestComparisonMode {
/// Namespaces must match exactly
XHtml,
@@ -294,29 +321,41 @@ pub(crate) fn element_name_test(
}
}
-fn apply_node_test(test: &NodeTest, node: &Node) -> Result<bool, Error> {
+fn apply_node_test(context: &EvaluationCtx, test: &NodeTest, node: &Node) -> Result<bool, Error> {
let result = match test {
NodeTest::Name(qname) => {
// Convert the unvalidated "parser QualName" into the proper QualName structure
- let wanted_name: QualName = qname.try_into()?;
- if matches!(node.type_id(), NodeTypeId::Element(_)) {
- let element = node.downcast::<Element>().unwrap();
- let comparison_mode = if node.owner_doc().is_xhtml_document() {
- NameTestComparisonMode::XHtml
- } else {
- NameTestComparisonMode::Html
- };
- let element_qualname = QualName::new(
- element.prefix().as_ref().cloned(),
- element.namespace().clone(),
- element.local_name().clone(),
- );
- element_name_test(wanted_name, element_qualname, comparison_mode)
- } else {
- false
+ let wanted_name: QualName = QualNameConverter { qname, context }.try_into()?;
+ match node.type_id() {
+ NodeTypeId::Element(_) => {
+ let element = node.downcast::<Element>().unwrap();
+ let comparison_mode = if node.owner_doc().is_html_document() {
+ NameTestComparisonMode::Html
+ } else {
+ NameTestComparisonMode::XHtml
+ };
+ let element_qualname = QualName::new(
+ element.prefix().as_ref().cloned(),
+ element.namespace().clone(),
+ element.local_name().clone(),
+ );
+ element_name_test(wanted_name, element_qualname, comparison_mode)
+ },
+ NodeTypeId::Attr => {
+ let attr = node.downcast::<Attr>().unwrap();
+ let attr_qualname = QualName::new(
+ attr.prefix().cloned(),
+ attr.namespace().clone(),
+ attr.local_name().clone(),
+ );
+ // attributes are always compared with strict namespace matching
+ let comparison_mode = NameTestComparisonMode::XHtml;
+ element_name_test(wanted_name, attr_qualname, comparison_mode)
+ },
+ _ => false,
}
},
- NodeTest::Wildcard => true,
+ NodeTest::Wildcard => matches!(node.type_id(), NodeTypeId::Element(_)),
NodeTest::Kind(kind) => match kind {
KindTest::PI(target) => {
if NodeTypeId::CharacterData(CharacterDataTypeId::ProcessingInstruction) ==
@@ -411,7 +450,7 @@ impl Evaluatable for StepExpr {
let filtered_nodes: Vec<DomRoot<Node>> = nodes
.into_iter()
.map(|node| {
- apply_node_test(&axis_step.node_test, &node)
+ apply_node_test(context, &axis_step.node_test, &node)
.map(|matches| matches.then_some(node))
})
.collect::<Result<Vec<_>, _>>()?
@@ -489,6 +528,7 @@ impl Evaluatable for PredicateExpr {
let v = match eval_result {
Ok(Value::Number(v)) => Ok(predicate_ctx.index == v as usize),
+ Ok(Value::Boolean(v)) => Ok(v),
Ok(v) => Ok(v.boolean()),
Err(e) => Err(e),
};
diff --git a/components/script/xpath/eval_function.rs b/components/script/xpath/eval_function.rs
index caf0782c07b..53c14944474 100644
--- a/components/script/xpath/eval_function.rs
+++ b/components/script/xpath/eval_function.rs
@@ -2,12 +2,15 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
+use style::Atom;
+
use super::Value;
use super::context::EvaluationCtx;
use super::eval::{Error, Evaluatable, try_extract_nodeset};
use super::parser::CoreFunction;
use crate::dom::bindings::codegen::Bindings::NodeBinding::NodeMethods;
use crate::dom::bindings::inheritance::{Castable, NodeTypeId};
+use crate::dom::bindings::root::DomRoot;
use crate::dom::element::Element;
use crate::dom::node::Node;
@@ -101,6 +104,31 @@ pub(crate) fn normalize_space(s: &str) -> String {
result
}
+/// <https://www.w3.org/TR/1999/REC-xpath-19991116/#function-lang>
+fn lang_matches(context_lang: Option<&str>, target_lang: &str) -> bool {
+ let Some(context_lang) = context_lang else {
+ return false;
+ };
+
+ let context_lower = context_lang.to_ascii_lowercase();
+ let target_lower = target_lang.to_ascii_lowercase();
+
+ if context_lower == target_lower {
+ return true;
+ }
+
+ // Check if context is target with additional suffix
+ if context_lower.starts_with(&target_lower) {
+ // Make sure the next character is a hyphen to avoid matching
+ // e.g. "england" when target is "en"
+ if let Some(next_char) = context_lower.chars().nth(target_lower.len()) {
+ return next_char == '-';
+ }
+ }
+
+ false
+}
+
impl Evaluatable for CoreFunction {
fn evaluate(&self, context: &EvaluationCtx) -> Result<Value, Error> {
match self {
@@ -131,7 +159,20 @@ impl Evaluatable for CoreFunction {
.collect();
Ok(Value::String(strings?.join("")))
},
- CoreFunction::Id(_expr) => todo!(),
+ CoreFunction::Id(expr) => {
+ let args_str = expr.evaluate(context)?.string();
+ let args_normalized = normalize_space(&args_str);
+ let args = args_normalized.split(' ');
+
+ let document = context.context_node.owner_doc();
+ let mut result = Vec::new();
+ for arg in args {
+ for element in document.get_elements_with_id(&Atom::from(arg)).iter() {
+ result.push(DomRoot::from_ref(element.upcast::<Node>()));
+ }
+ }
+ Ok(Value::Nodeset(result))
+ },
CoreFunction::LocalName(expr_opt) => {
let node = match expr_opt {
Some(expr) => expr
@@ -256,7 +297,11 @@ impl Evaluatable for CoreFunction {
CoreFunction::Not(expr) => Ok(Value::Boolean(!expr.evaluate(context)?.boolean())),
CoreFunction::True => Ok(Value::Boolean(true)),
CoreFunction::False => Ok(Value::Boolean(false)),
- CoreFunction::Lang(_) => Ok(Value::Nodeset(vec![])), // Not commonly used in the DOM, short-circuit it
+ CoreFunction::Lang(expr) => {
+ let context_lang = context.context_node.get_lang();
+ let lang = expr.evaluate(context)?.string();
+ Ok(Value::Boolean(lang_matches(context_lang.as_deref(), &lang)))
+ },
}
}
@@ -319,7 +364,7 @@ impl Evaluatable for CoreFunction {
}
#[cfg(test)]
mod tests {
- use super::{substring, substring_after, substring_before};
+ use super::{lang_matches, substring, substring_after, substring_before};
#[test]
fn test_substring_before() {
@@ -354,4 +399,18 @@ mod tests {
assert_eq!(substring("hello", 0, Some(0)), "");
assert_eq!(substring("hello", 0, Some(-5)), "");
}
+
+ #[test]
+ fn test_lang_matches() {
+ assert!(lang_matches(Some("en"), "en"));
+ assert!(lang_matches(Some("EN"), "en"));
+ assert!(lang_matches(Some("en"), "EN"));
+ assert!(lang_matches(Some("en-US"), "en"));
+ assert!(lang_matches(Some("en-GB"), "en"));
+
+ assert!(!lang_matches(Some("eng"), "en"));
+ assert!(!lang_matches(Some("fr"), "en"));
+ assert!(!lang_matches(Some("fr-en"), "en"));
+ assert!(!lang_matches(None, "en"));
+ }
}
diff --git a/components/script/xpath/eval_value.rs b/components/script/xpath/eval_value.rs
index de6c13e3454..66f1b92c6d4 100644
--- a/components/script/xpath/eval_value.rs
+++ b/components/script/xpath/eval_value.rs
@@ -8,7 +8,6 @@ use std::{fmt, string};
use crate::dom::bindings::codegen::Bindings::NodeBinding::Node_Binding::NodeMethods;
use crate::dom::bindings::root::DomRoot;
-use crate::dom::bindings::utils::AsVoidPtr;
use crate::dom::node::Node;
/// The primary types of values that an XPath expression returns as a result.
@@ -216,7 +215,7 @@ impl NodesetHelpers for Vec<DomRoot<Node>> {
}
fn document_order(&self) -> Vec<DomRoot<Node>> {
let mut nodes: Vec<DomRoot<Node>> = self.clone();
- if nodes.len() == 1 {
+ if nodes.len() <= 1 {
return nodes;
}
@@ -233,10 +232,13 @@ impl NodesetHelpers for Vec<DomRoot<Node>> {
nodes
}
fn document_order_unique(&self) -> Vec<DomRoot<Node>> {
- let mut nodes: Vec<DomRoot<Node>> = self.document_order();
-
- nodes.dedup_by_key(|n| n.as_void_ptr());
+ let mut seen = HashSet::new();
+ let unique_nodes: Vec<DomRoot<Node>> = self
+ .iter()
+ .filter(|node| seen.insert(node.to_opaque()))
+ .cloned()
+ .collect();
- nodes
+ unique_nodes.document_order()
}
}
diff --git a/components/script/xpath/parser.rs b/components/script/xpath/parser.rs
index b1a4bfcc42d..272fa41dcdf 100644
--- a/components/script/xpath/parser.rs
+++ b/components/script/xpath/parser.rs
@@ -510,40 +510,45 @@ fn union_expr(input: &str) -> IResult<&str, Expr> {
fn path_expr(input: &str) -> IResult<&str, Expr> {
alt((
// "//" RelativePathExpr
- map(pair(tag("//"), relative_path_expr), |(_, rel_path)| {
- Expr::Path(PathExpr {
- is_absolute: true,
- is_descendant: true,
- steps: match rel_path {
- Expr::Path(p) => p.steps,
- _ => unreachable!(),
- },
- })
- }),
- // "/" RelativePathExpr?
- map(pair(char('/'), opt(relative_path_expr)), |(_, rel_path)| {
- Expr::Path(PathExpr {
- is_absolute: true,
- is_descendant: false,
- steps: rel_path
- .map(|p| match p {
+ map(
+ pair(tag("//"), move |i| relative_path_expr(true, i)),
+ |(_, rel_path)| {
+ Expr::Path(PathExpr {
+ is_absolute: true,
+ is_descendant: true,
+ steps: match rel_path {
Expr::Path(p) => p.steps,
_ => unreachable!(),
- })
- .unwrap_or_default(),
- })
- }),
+ },
+ })
+ },
+ ),
+ // "/" RelativePathExpr?
+ map(
+ pair(char('/'), opt(move |i| relative_path_expr(false, i))),
+ |(_, rel_path)| {
+ Expr::Path(PathExpr {
+ is_absolute: true,
+ is_descendant: false,
+ steps: rel_path
+ .map(|p| match p {
+ Expr::Path(p) => p.steps,
+ _ => unreachable!(),
+ })
+ .unwrap_or_default(),
+ })
+ },
+ ),
// RelativePathExpr
- relative_path_expr,
+ move |i| relative_path_expr(false, i),
))(input)
}
-fn relative_path_expr(input: &str) -> IResult<&str, Expr> {
- let (input, first) = step_expr(input)?;
+fn relative_path_expr(is_descendant: bool, input: &str) -> IResult<&str, Expr> {
+ let (input, first) = step_expr(is_descendant, input)?;
let (input, steps) = many0(pair(
- // ("/" | "//")
- ws(alt((value(false, char('/')), value(true, tag("//"))))),
- step_expr,
+ ws(alt((value(true, tag("//")), value(false, char('/'))))),
+ move |i| step_expr(is_descendant, i),
))(input)?;
let mut all_steps = vec![first];
@@ -569,16 +574,18 @@ fn relative_path_expr(input: &str) -> IResult<&str, Expr> {
))
}
-fn step_expr(input: &str) -> IResult<&str, StepExpr> {
+fn step_expr(is_descendant: bool, input: &str) -> IResult<&str, StepExpr> {
alt((
map(filter_expr, StepExpr::Filter),
- map(axis_step, StepExpr::Axis),
+ map(|i| axis_step(is_descendant, i), StepExpr::Axis),
))(input)
}
-fn axis_step(input: &str) -> IResult<&str, AxisStep> {
- let (input, (step, predicates)) =
- pair(alt((forward_step, reverse_step)), predicate_list)(input)?;
+fn axis_step(is_descendant: bool, input: &str) -> IResult<&str, AxisStep> {
+ let (input, (step, predicates)) = pair(
+ alt((move |i| forward_step(is_descendant, i), reverse_step)),
+ predicate_list,
+ )(input)?;
let (axis, node_test) = step;
Ok((
@@ -591,13 +598,10 @@ fn axis_step(input: &str) -> IResult<&str, AxisStep> {
))
}
-fn forward_step(input: &str) -> IResult<&str, (Axis, NodeTest)> {
- alt((
- // ForwardAxis NodeTest
- pair(forward_axis, node_test),
- // AbbrevForwardStep
- abbrev_forward_step,
- ))(input)
+fn forward_step(is_descendant: bool, input: &str) -> IResult<&str, (Axis, NodeTest)> {
+ alt((pair(forward_axis, node_test), move |i| {
+ abbrev_forward_step(is_descendant, i)
+ }))(input)
}
fn forward_axis(input: &str) -> IResult<&str, Axis> {
@@ -615,7 +619,7 @@ fn forward_axis(input: &str) -> IResult<&str, Axis> {
Ok((input, axis))
}
-fn abbrev_forward_step(input: &str) -> IResult<&str, (Axis, NodeTest)> {
+fn abbrev_forward_step(is_descendant: bool, input: &str) -> IResult<&str, (Axis, NodeTest)> {
let (input, attr) = opt(char('@'))(input)?;
let (input, test) = node_test(input)?;
@@ -624,6 +628,8 @@ fn abbrev_forward_step(input: &str) -> IResult<&str, (Axis, NodeTest)> {
(
if attr.is_some() {
Axis::Attribute
+ } else if is_descendant {
+ Axis::DescendantOrSelf
} else {
Axis::Child
},
@@ -704,6 +710,7 @@ fn filter_expr(input: &str) -> IResult<&str, FilterExpr> {
fn predicate_list(input: &str) -> IResult<&str, PredicateListExpr> {
let (input, predicates) = many0(predicate)(input)?;
+
Ok((input, PredicateListExpr { predicates }))
}
@@ -1195,6 +1202,118 @@ mod tests {
],
}),
),
+ (
+ "//mu[@xml:id=\"id1\"]//rho[@title][@xml:lang=\"en-GB\"]",
+ Expr::Path(PathExpr {
+ is_absolute: true,
+ is_descendant: true,
+ steps: vec![
+ StepExpr::Axis(AxisStep {
+ axis: Axis::Child,
+ node_test: NodeTest::Name(QName {
+ prefix: None,
+ local_part: "mu".to_string(),
+ }),
+ predicates: PredicateListExpr {
+ predicates: vec![PredicateExpr {
+ expr: Expr::Equality(
+ Box::new(Expr::Path(PathExpr {
+ is_absolute: false,
+ is_descendant: false,
+ steps: vec![StepExpr::Axis(AxisStep {
+ axis: Axis::Attribute,
+ node_test: NodeTest::Name(QName {
+ prefix: Some("xml".to_string()),
+ local_part: "id".to_string(),
+ }),
+ predicates: PredicateListExpr {
+ predicates: vec![],
+ },
+ })],
+ })),
+ EqualityOp::Eq,
+ Box::new(Expr::Path(PathExpr {
+ is_absolute: false,
+ is_descendant: false,
+ steps: vec![StepExpr::Filter(FilterExpr {
+ primary: PrimaryExpr::Literal(Literal::String(
+ "id1".to_string(),
+ )),
+ predicates: PredicateListExpr {
+ predicates: vec![],
+ },
+ })],
+ })),
+ ),
+ }],
+ },
+ }),
+ StepExpr::Axis(AxisStep {
+ axis: Axis::DescendantOrSelf, // Represents the second '//'
+ node_test: NodeTest::Kind(KindTest::Node),
+ predicates: PredicateListExpr { predicates: vec![] },
+ }),
+ StepExpr::Axis(AxisStep {
+ axis: Axis::Child,
+ node_test: NodeTest::Name(QName {
+ prefix: None,
+ local_part: "rho".to_string(),
+ }),
+ predicates: PredicateListExpr {
+ predicates: vec![
+ PredicateExpr {
+ expr: Expr::Path(PathExpr {
+ is_absolute: false,
+ is_descendant: false,
+ steps: vec![StepExpr::Axis(AxisStep {
+ axis: Axis::Attribute,
+ node_test: NodeTest::Name(QName {
+ prefix: None,
+ local_part: "title".to_string(),
+ }),
+ predicates: PredicateListExpr {
+ predicates: vec![],
+ },
+ })],
+ }),
+ },
+ PredicateExpr {
+ expr: Expr::Equality(
+ Box::new(Expr::Path(PathExpr {
+ is_absolute: false,
+ is_descendant: false,
+ steps: vec![StepExpr::Axis(AxisStep {
+ axis: Axis::Attribute,
+ node_test: NodeTest::Name(QName {
+ prefix: Some("xml".to_string()),
+ local_part: "lang".to_string(),
+ }),
+ predicates: PredicateListExpr {
+ predicates: vec![],
+ },
+ })],
+ })),
+ EqualityOp::Eq,
+ Box::new(Expr::Path(PathExpr {
+ is_absolute: false,
+ is_descendant: false,
+ steps: vec![StepExpr::Filter(FilterExpr {
+ primary: PrimaryExpr::Literal(Literal::String(
+ "en-GB".to_string(),
+ )),
+ predicates: PredicateListExpr {
+ predicates: vec![],
+ },
+ })],
+ })),
+ ),
+ },
+ ],
+ },
+ }),
+ ],
+ }),
+ ),
];
for (input, expected) in cases {
diff --git a/components/script_bindings/codegen/Bindings.conf b/components/script_bindings/codegen/Bindings.conf
index 7cc092e574e..dd034654974 100644
--- a/components/script_bindings/codegen/Bindings.conf
+++ b/components/script_bindings/codegen/Bindings.conf
@@ -14,6 +14,10 @@
DOMInterfaces = {
+'AbortController': {
+ 'canGc':['Abort'],
+},
+
'AbstractRange': {
'weakReferenceable': True,
},
diff --git a/components/script_bindings/webidls/AbortController.webidl b/components/script_bindings/webidls/AbortController.webidl
index cef49010d3c..bb20ec24955 100644
--- a/components/script_bindings/webidls/AbortController.webidl
+++ b/components/script_bindings/webidls/AbortController.webidl
@@ -7,7 +7,7 @@
interface AbortController {
constructor();
- //[SameObject] readonly attribute AbortSignal signal;
+ [SameObject] readonly attribute AbortSignal signal;
undefined abort(optional any reason);
};
diff --git a/components/script_bindings/webidls/HTMLHRElement.webidl b/components/script_bindings/webidls/HTMLHRElement.webidl
index 8963d5e8901..45828d4da76 100644
--- a/components/script_bindings/webidls/HTMLHRElement.webidl
+++ b/components/script_bindings/webidls/HTMLHRElement.webidl
@@ -12,14 +12,9 @@ interface HTMLHRElement : HTMLElement {
// https://html.spec.whatwg.org/multipage/#HTMLHRElement-partial
partial interface HTMLHRElement {
- [CEReactions]
- attribute DOMString align;
- [CEReactions]
- attribute DOMString color;
- // [CEReactions]
- // attribute boolean noShade;
- // [CEReactions]
- // attribute DOMString size;
- [CEReactions]
- attribute DOMString width;
+ [CEReactions] attribute DOMString align;
+ [CEReactions] attribute DOMString color;
+ [CEReactions] attribute boolean noShade;
+ [CEReactions] attribute DOMString size;
+ [CEReactions] attribute DOMString width;
};
diff --git a/components/shared/embedder/input_events.rs b/components/shared/embedder/input_events.rs
index 869c4eee004..ff48bd7b7d8 100644
--- a/components/shared/embedder/input_events.rs
+++ b/components/shared/embedder/input_events.rs
@@ -58,16 +58,16 @@ impl InputEvent {
}
}
- pub fn with_webdriver_message_id(self, webdriver_id: Option<WebDriverMessageId>) -> Self {
+ pub fn with_webdriver_message_id(mut self, webdriver_id: Option<WebDriverMessageId>) -> Self {
match self {
InputEvent::EditingAction(..) => {},
InputEvent::Gamepad(..) => {},
InputEvent::Ime(..) => {},
InputEvent::Keyboard(..) => {},
- InputEvent::MouseButton(mut event) => {
+ InputEvent::MouseButton(ref mut event) => {
event.webdriver_id = webdriver_id;
},
- InputEvent::MouseMove(mut event) => {
+ InputEvent::MouseMove(ref mut event) => {
event.webdriver_id = webdriver_id;
},
InputEvent::Touch(..) => {},
diff --git a/components/shared/embedder/webdriver.rs b/components/shared/embedder/webdriver.rs
index 7b0f02bc26a..ad1271a045c 100644
--- a/components/shared/embedder/webdriver.rs
+++ b/components/shared/embedder/webdriver.rs
@@ -130,7 +130,6 @@ pub enum WebDriverScriptCommand {
IpcSender<Result<Vec<String>, ErrorStatus>>,
),
FindElementElementsTagName(String, String, IpcSender<Result<Vec<String>, ErrorStatus>>),
- FocusElement(String, IpcSender<Result<(), ErrorStatus>>),
ElementClick(String, IpcSender<Result<Option<String>, ErrorStatus>>),
GetActiveElement(IpcSender<Option<String>>),
GetComputedRole(String, IpcSender<Result<Option<String>, ErrorStatus>>),
@@ -161,6 +160,8 @@ pub enum WebDriverScriptCommand {
IsEnabled(String, IpcSender<Result<bool, ErrorStatus>>),
IsSelected(String, IpcSender<Result<bool, ErrorStatus>>),
GetTitle(IpcSender<String>),
+ /// Match the element type before sending the event for webdriver `element send keys`.
+ WillSendKeys(String, String, bool, IpcSender<Result<bool, ErrorStatus>>),
}
#[derive(Debug, Deserialize, Serialize)]
diff --git a/components/webdriver_server/actions.rs b/components/webdriver_server/actions.rs
index f33310ac001..b84cbb4c2f8 100644
--- a/components/webdriver_server/actions.rs
+++ b/components/webdriver_server/actions.rs
@@ -2,9 +2,9 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
-use std::collections::HashSet;
+use std::collections::{HashMap, HashSet};
+use std::thread;
use std::time::{Duration, Instant};
-use std::{cmp, thread};
use constellation_traits::EmbedderToConstellationMessage;
use embedder_traits::{MouseButtonAction, WebDriverCommandMsg, WebDriverScriptCommand};
@@ -12,10 +12,11 @@ use ipc_channel::ipc;
use keyboard_types::webdriver::KeyInputState;
use webdriver::actions::{
ActionSequence, ActionsType, GeneralAction, KeyAction, KeyActionItem, KeyDownAction,
- KeyUpAction, NullActionItem, PointerAction, PointerActionItem, PointerActionParameters,
- PointerDownAction, PointerMoveAction, PointerOrigin, PointerType, PointerUpAction, WheelAction,
- WheelActionItem, WheelScrollAction,
+ KeyUpAction, NullActionItem, PointerAction, PointerActionItem, PointerDownAction,
+ PointerMoveAction, PointerOrigin, PointerType, PointerUpAction, WheelAction, WheelActionItem,
+ WheelScrollAction,
};
+use webdriver::command::ActionsParameters;
use webdriver::error::{ErrorStatus, WebDriverError};
use crate::{Handler, WebElement, wait_for_script_response};
@@ -24,11 +25,32 @@ use crate::{Handler, WebElement, wait_for_script_response};
static POINTERMOVE_INTERVAL: u64 = 17;
static WHEELSCROLL_INTERVAL: u64 = 17;
-// https://w3c.github.io/webdriver/#dfn-input-source-state
+// A single action, corresponding to an `action object` in the spec.
+// In the spec, `action item` refers to a plain JSON object.
+// However, we use the name ActionItem here
+// to be consistent with type names from webdriver crate.
+pub(crate) enum ActionItem {
+ Null(NullActionItem),
+ Key(KeyActionItem),
+ Pointer(PointerActionItem),
+ Wheel(WheelActionItem),
+}
+
+// A set of actions with multiple sources executed within a single tick.
+// The order in which they are performed is not guaranteed.
+// The `id` is used to identify the source of the actions.
+pub(crate) type TickActions = HashMap<String, ActionItem>;
+
+// Consumed by the `dispatch_actions` method.
+pub(crate) type ActionsByTick = Vec<TickActions>;
+
+/// <https://w3c.github.io/webdriver/#dfn-input-source-state>
pub(crate) enum InputSourceState {
Null,
+ #[allow(dead_code)]
Key(KeyInputState),
Pointer(PointerInputState),
+ #[allow(dead_code)]
Wheel,
}
@@ -44,13 +66,9 @@ pub(crate) struct PointerInputState {
}
impl PointerInputState {
- pub fn new(subtype: &PointerType) -> PointerInputState {
+ pub fn new(subtype: PointerType) -> PointerInputState {
PointerInputState {
- subtype: match subtype {
- PointerType::Mouse => PointerType::Mouse,
- PointerType::Pen => PointerType::Pen,
- PointerType::Touch => PointerType::Touch,
- },
+ subtype,
pressed: HashSet::new(),
x: 0.0,
y: 0.0,
@@ -58,48 +76,44 @@ impl PointerInputState {
}
}
-// https://w3c.github.io/webdriver/#dfn-computing-the-tick-duration
-fn compute_tick_duration(tick_actions: &ActionSequence) -> u64 {
- let mut duration = 0;
- match &tick_actions.actions {
- ActionsType::Null { actions } => {
- for action in actions.iter() {
- let NullActionItem::General(GeneralAction::Pause(pause_action)) = action;
- duration = cmp::max(duration, pause_action.duration.unwrap_or(0));
- }
- },
- ActionsType::Pointer {
- parameters: _,
- actions,
- } => {
- for action in actions.iter() {
- let action_duration = match action {
- PointerActionItem::General(GeneralAction::Pause(action)) => action.duration,
- PointerActionItem::Pointer(PointerAction::Move(action)) => action.duration,
- _ => None,
- };
- duration = cmp::max(duration, action_duration.unwrap_or(0));
- }
- },
- ActionsType::Key { actions: _ } => (),
- ActionsType::Wheel { actions } => {
- for action in actions.iter() {
- let action_duration = match action {
- WheelActionItem::General(GeneralAction::Pause(action)) => action.duration,
- WheelActionItem::Wheel(WheelAction::Scroll(action)) => action.duration,
- };
- duration = cmp::max(duration, action_duration.unwrap_or(0));
+/// <https://w3c.github.io/webdriver/#dfn-computing-the-tick-duration>
+fn compute_tick_duration(tick_actions: &TickActions) -> u64 {
+ // Step 1. Let max duration be 0.
+ // Step 2. For each action in tick actions:
+ tick_actions
+ .iter()
+ .filter_map(|(_, action_item)| {
+ // If action object has subtype property set to "pause" or
+ // action object has type property set to "pointer" and subtype property set to "pointerMove",
+ // or action object has type property set to "wheel" and subtype property set to "scroll",
+ // let duration be equal to the duration property of action object.
+ match action_item {
+ ActionItem::Null(NullActionItem::General(GeneralAction::Pause(pause_action))) |
+ ActionItem::Key(KeyActionItem::General(GeneralAction::Pause(pause_action))) |
+ ActionItem::Pointer(PointerActionItem::General(GeneralAction::Pause(
+ pause_action,
+ ))) |
+ ActionItem::Wheel(WheelActionItem::General(GeneralAction::Pause(pause_action))) => {
+ pause_action.duration
+ },
+ ActionItem::Pointer(PointerActionItem::Pointer(PointerAction::Move(action))) => {
+ action.duration
+ },
+ ActionItem::Wheel(WheelActionItem::Wheel(WheelAction::Scroll(action))) => {
+ action.duration
+ },
+ _ => None,
}
- },
- }
- duration
+ })
+ .max()
+ .unwrap_or(0)
}
impl Handler {
- // https://w3c.github.io/webdriver/#dfn-dispatch-actions
+ /// <https://w3c.github.io/webdriver/#dfn-dispatch-actions>
pub(crate) fn dispatch_actions(
&self,
- actions_by_tick: &[ActionSequence],
+ actions_by_tick: ActionsByTick,
) -> Result<(), ErrorStatus> {
// Step 1. Wait for an action queue token with input state.
let new_token = self.id_generator.next();
@@ -116,11 +130,8 @@ impl Handler {
res
}
- // https://w3c.github.io/webdriver/#dfn-dispatch-actions-inner
- fn dispatch_actions_inner(
- &self,
- actions_by_tick: &[ActionSequence],
- ) -> Result<(), ErrorStatus> {
+ /// <https://w3c.github.io/webdriver/#dfn-dispatch-actions-inner>
+ fn dispatch_actions_inner(&self, actions_by_tick: ActionsByTick) -> Result<(), ErrorStatus> {
// Step 1. For each item tick actions in actions by tick
for tick_actions in actions_by_tick.iter() {
// Step 1.2. Let tick duration be the result of
@@ -133,19 +144,33 @@ impl Handler {
// Step 1.4. Wait for
// The user agent event loop has spun enough times to process the DOM events
// generated by the last invocation of the dispatch tick actions steps.
- //
- // To ensure we wait for all events to be processed, only the last event in
- // this tick action step holds the message id.
- // Whenever a new event is generated, the message id is passed to it.
- //
- // TO-DO: remove the first match after webdriver_id is implemented in all commands
- match tick_actions.actions {
- ActionsType::Key { .. } | ActionsType::Wheel { .. } | ActionsType::Null { .. } => {
- return Ok(());
- },
- _ => {},
- }
+ self.wait_for_user_agent_handling_complete(tick_actions)?;
+ }
+ // Step 2. Return success with data null.
+ dbg!("Dispatch actions completed successfully");
+ Ok(())
+ }
+
+ fn wait_for_user_agent_handling_complete(
+ &self,
+ tick_actions: &TickActions,
+ ) -> Result<(), ErrorStatus> {
+ // TODO: Add matches! for wheel and key actions
+ // after implmenting webdriver id for wheel and key events.
+ let count_non_null_actions_in_tick = tick_actions
+ .iter()
+ .filter(|(_, action)| {
+ matches!(action, ActionItem::Pointer(PointerActionItem::Pointer(_)))
+ })
+ .count();
+
+ // To ensure we wait for all events to be processed, only the last event
+ // in each tick action step holds the message id.
+ // Whenever a new event is generated, the message id is passed to it.
+ //
+ // Wait for count_non_null_actions_in_tick number of responses
+ for _ in 0..count_non_null_actions_in_tick {
match self.constellation_receiver.recv() {
Ok(response) => {
let current_waiting_id = self
@@ -165,8 +190,86 @@ impl Handler {
};
}
- // Step 2. Return success with data null.
- dbg!("Dispatch actions completed successfully");
+ Ok(())
+ }
+
+ /// <https://w3c.github.io/webdriver/#dfn-dispatch-tick-actions>
+ fn dispatch_tick_actions(
+ &self,
+ tick_actions: &TickActions,
+ tick_duration: u64,
+ ) -> Result<(), ErrorStatus> {
+ // Step 1. For each action object in tick actions:
+ // Step 1.1. Let input_id be the value of the id property of action object.
+ for (input_id, action) in tick_actions.iter() {
+ // Step 6. Let subtype be action object's subtype.
+ // Steps 7, 8. Try to run specific algorithm based on the action type.
+ match action {
+ ActionItem::Null(NullActionItem::General(_)) => {
+ self.dispatch_general_action(input_id);
+ },
+ ActionItem::Key(KeyActionItem::General(_)) => {
+ self.dispatch_general_action(input_id);
+ },
+ ActionItem::Key(KeyActionItem::Key(KeyAction::Down(keydown_action))) => {
+ self.dispatch_keydown_action(input_id, keydown_action);
+
+ // Step 9. If subtype is "keyDown", append a copy of action
+ // object with the subtype property changed to "keyUp" to
+ // input state's input cancel list.
+ self.session()
+ .unwrap()
+ .input_cancel_list
+ .borrow_mut()
+ .push(ActionItem::Key(KeyActionItem::Key(KeyAction::Up(
+ KeyUpAction {
+ value: keydown_action.value.clone(),
+ },
+ ))));
+ },
+ ActionItem::Key(KeyActionItem::Key(KeyAction::Up(keyup_action))) => {
+ self.dispatch_keyup_action(input_id, keyup_action);
+ },
+ ActionItem::Pointer(PointerActionItem::General(_)) => {
+ self.dispatch_general_action(input_id);
+ },
+ ActionItem::Pointer(PointerActionItem::Pointer(PointerAction::Down(
+ pointer_down_action,
+ ))) => {
+ self.dispatch_pointerdown_action(input_id, pointer_down_action);
+
+ // Step 10. If subtype is "pointerDown", append a copy of action
+ // object with the subtype property changed to "pointerUp" to
+ // input state's input cancel list.
+ self.session().unwrap().input_cancel_list.borrow_mut().push(
+ ActionItem::Pointer(PointerActionItem::Pointer(PointerAction::Up(
+ PointerUpAction {
+ button: pointer_down_action.button,
+ ..Default::default()
+ },
+ ))),
+ );
+ },
+ ActionItem::Pointer(PointerActionItem::Pointer(PointerAction::Move(
+ pointer_move_action,
+ ))) => {
+ self.dispatch_pointermove_action(input_id, pointer_move_action, tick_duration)?;
+ },
+ ActionItem::Pointer(PointerActionItem::Pointer(PointerAction::Up(
+ pointer_up_action,
+ ))) => {
+ self.dispatch_pointerup_action(input_id, pointer_up_action);
+ },
+ ActionItem::Wheel(WheelActionItem::General(_)) => {
+ self.dispatch_general_action(input_id);
+ },
+ ActionItem::Wheel(WheelActionItem::Wheel(WheelAction::Scroll(scroll_action))) => {
+ self.dispatch_scroll_action(scroll_action, tick_duration)?;
+ },
+ _ => {},
+ }
+ }
+
Ok(())
}
@@ -181,143 +284,7 @@ impl Handler {
// Nothing to be done
}
- // https://w3c.github.io/webdriver/#dfn-dispatch-tick-actions
- fn dispatch_tick_actions(
- &self,
- tick_actions: &ActionSequence,
- tick_duration: u64,
- ) -> Result<(), ErrorStatus> {
- let source_id = &tick_actions.id;
- match &tick_actions.actions {
- ActionsType::Null { actions } => {
- for _action in actions.iter() {
- self.dispatch_general_action(source_id);
- }
- },
- ActionsType::Key { actions } => {
- for action in actions.iter() {
- match action {
- KeyActionItem::General(_action) => {
- self.dispatch_general_action(source_id);
- },
- KeyActionItem::Key(action) => {
- self.session()
- .unwrap()
- .input_state_table
- .borrow_mut()
- .entry(source_id.to_string())
- .or_insert(InputSourceState::Key(KeyInputState::new()));
- match action {
- KeyAction::Down(action) => {
- self.dispatch_keydown_action(source_id, action);
- // Step 9. If subtype is "keyDown", append a copy of action
- // object with the subtype property changed to "keyUp" to
- // input state's input cancel list.
- self.session().unwrap().input_cancel_list.borrow_mut().push(
- ActionSequence {
- id: source_id.into(),
- actions: ActionsType::Key {
- actions: vec![KeyActionItem::Key(KeyAction::Up(
- KeyUpAction {
- value: action.value.clone(),
- },
- ))],
- },
- },
- );
- },
- KeyAction::Up(action) => {
- self.dispatch_keyup_action(source_id, action)
- },
- };
- },
- }
- }
- },
- ActionsType::Pointer {
- parameters,
- actions,
- } => {
- for action in actions.iter() {
- match action {
- PointerActionItem::General(_action) => {
- self.dispatch_general_action(source_id);
- },
- PointerActionItem::Pointer(action) => {
- self.session()
- .unwrap()
- .input_state_table
- .borrow_mut()
- .entry(source_id.to_string())
- .or_insert(InputSourceState::Pointer(PointerInputState::new(
- &parameters.pointer_type,
- )));
- match action {
- PointerAction::Cancel => (),
- PointerAction::Down(action) => {
- self.dispatch_pointerdown_action(source_id, action);
-
- // Step 10. If subtype is "pointerDown", append a copy of action
- // object with the subtype property changed to "pointerUp" to
- // input state's input cancel list.
- self.session().unwrap().input_cancel_list.borrow_mut().push(
- ActionSequence {
- id: source_id.into(),
- actions: ActionsType::Pointer {
- parameters: PointerActionParameters {
- pointer_type: parameters.pointer_type,
- },
- actions: vec![PointerActionItem::Pointer(
- PointerAction::Up(PointerUpAction {
- button: action.button,
- ..Default::default()
- }),
- )],
- },
- },
- );
- },
- PointerAction::Move(action) => self.dispatch_pointermove_action(
- source_id,
- action,
- tick_duration,
- )?,
- PointerAction::Up(action) => {
- self.dispatch_pointerup_action(source_id, action)
- },
- }
- },
- }
- }
- },
- ActionsType::Wheel { actions } => {
- for action in actions.iter() {
- match action {
- WheelActionItem::General(_action) => {
- self.dispatch_general_action(source_id)
- },
- WheelActionItem::Wheel(action) => {
- self.session()
- .unwrap()
- .input_state_table
- .borrow_mut()
- .entry(source_id.to_string())
- .or_insert(InputSourceState::Wheel);
- match action {
- WheelAction::Scroll(action) => {
- self.dispatch_scroll_action(action, tick_duration)?
- },
- }
- },
- }
- }
- },
- }
-
- Ok(())
- }
-
- // https://w3c.github.io/webdriver/#dfn-dispatch-a-keydown-action
+ /// <https://w3c.github.io/webdriver/#dfn-dispatch-a-keydown-action>
fn dispatch_keydown_action(&self, source_id: &str, action: &KeyDownAction) {
let session = self.session().unwrap();
@@ -340,7 +307,7 @@ impl Handler {
.unwrap();
}
- // https://w3c.github.io/webdriver/#dfn-dispatch-a-keyup-action
+ /// <https://w3c.github.io/webdriver/#dfn-dispatch-a-keyup-action>
fn dispatch_keyup_action(&self, source_id: &str, action: &KeyUpAction) {
let session = self.session().unwrap();
@@ -393,7 +360,7 @@ impl Handler {
.unwrap();
}
- // https://w3c.github.io/webdriver/#dfn-dispatch-a-pointerup-action
+ /// <https://w3c.github.io/webdriver/#dfn-dispatch-a-pointerup-action>
pub(crate) fn dispatch_pointerup_action(&self, source_id: &str, action: &PointerUpAction) {
let session = self.session().unwrap();
@@ -423,7 +390,7 @@ impl Handler {
.unwrap();
}
- // https://w3c.github.io/webdriver/#dfn-dispatch-a-pointermove-action
+ /// <https://w3c.github.io/webdriver/#dfn-dispatch-a-pointermove-action>
pub(crate) fn dispatch_pointermove_action(
&self,
source_id: &str,
@@ -738,4 +705,94 @@ impl Handler {
None => Err(ErrorStatus::UnknownError),
}
}
+
+ /// <https://w3c.github.io/webdriver/#dfn-extract-an-action-sequence>
+ pub(crate) fn extract_an_action_sequence(&self, params: ActionsParameters) -> ActionsByTick {
+ // Step 1. Let actions be the result of getting a property named "actions" from parameters.
+ // Step 2 (ignored because params is already validated earlier). If actions is not a list,
+ // return an error with status InvalidArgument.
+ let actions = params.actions;
+
+ self.actions_by_tick_from_sequence(actions)
+ }
+
+ pub(crate) fn actions_by_tick_from_sequence(
+ &self,
+ actions: Vec<ActionSequence>,
+ ) -> ActionsByTick {
+ // Step 3. Let actions by tick be an empty list.
+ let mut actions_by_tick: ActionsByTick = Vec::new();
+
+ // Step 4. For each value action sequence corresponding to an indexed property in actions
+ for action_sequence in actions {
+ // Store id before moving action_sequence
+ let id = action_sequence.id.clone();
+ // Step 4.1. Let source actions be the result of trying to process an input source action sequence
+ let source_actions = self.process_an_input_source_action_sequence(action_sequence);
+
+ // Step 4.2.2. Ensure we have enough ticks to hold all actions
+ while actions_by_tick.len() < source_actions.len() {
+ actions_by_tick.push(HashMap::new());
+ }
+
+ // Step 4.2.3.
+ for (tick_index, action_item) in source_actions.into_iter().enumerate() {
+ actions_by_tick[tick_index].insert(id.clone(), action_item);
+ }
+ }
+
+ actions_by_tick
+ }
+
+ /// <https://w3c.github.io/webdriver/#dfn-process-an-input-source-action-sequence>
+ pub(crate) fn process_an_input_source_action_sequence(
+ &self,
+ action_sequence: ActionSequence,
+ ) -> Vec<ActionItem> {
+ // Step 2. Let id be the value of the id property of action sequence.
+ let id = action_sequence.id.clone();
+
+ let mut input_state_table = self.session().unwrap().input_state_table.borrow_mut();
+
+ match action_sequence.actions {
+ ActionsType::Null {
+ actions: null_actions,
+ } => {
+ input_state_table
+ .entry(id)
+ .or_insert(InputSourceState::Null);
+ null_actions.into_iter().map(ActionItem::Null).collect()
+ },
+ ActionsType::Key {
+ actions: key_actions,
+ } => {
+ input_state_table
+ .entry(id)
+ .or_insert(InputSourceState::Key(KeyInputState::new()));
+ key_actions.into_iter().map(ActionItem::Key).collect()
+ },
+ ActionsType::Pointer {
+ parameters: _,
+ actions: pointer_actions,
+ } => {
+ input_state_table
+ .entry(id)
+ .or_insert(InputSourceState::Pointer(PointerInputState::new(
+ PointerType::Mouse,
+ )));
+ pointer_actions
+ .into_iter()
+ .map(ActionItem::Pointer)
+ .collect()
+ },
+ ActionsType::Wheel {
+ actions: wheel_actions,
+ } => {
+ input_state_table
+ .entry(id)
+ .or_insert(InputSourceState::Wheel);
+ wheel_actions.into_iter().map(ActionItem::Wheel).collect()
+ },
+ }
+ }
}
diff --git a/components/webdriver_server/lib.rs b/components/webdriver_server/lib.rs
index eb3e7bf17ec..1b585319703 100644
--- a/components/webdriver_server/lib.rs
+++ b/components/webdriver_server/lib.rs
@@ -64,7 +64,7 @@ use webdriver::response::{
};
use webdriver::server::{self, Session, SessionTeardownKind, WebDriverHandler};
-use crate::actions::{InputSourceState, PointerInputState};
+use crate::actions::{ActionItem, InputSourceState, PointerInputState};
#[derive(Default)]
pub struct WebDriverMessageIdGenerator {
@@ -171,7 +171,7 @@ pub struct WebDriverSession {
input_state_table: RefCell<HashMap<String, InputSourceState>>,
/// <https://w3c.github.io/webdriver/#dfn-input-cancel-list>
- input_cancel_list: RefCell<Vec<ActionSequence>>,
+ input_cancel_list: RefCell<Vec<ActionItem>>,
}
impl WebDriverSession {
@@ -1480,20 +1480,22 @@ impl Handler {
fn handle_perform_actions(
&mut self,
- parameters: &ActionsParameters,
+ parameters: ActionsParameters,
) -> WebDriverResult<WebDriverResponse> {
- match self.dispatch_actions(&parameters.actions) {
+ // Step 5. Let actions by tick be the result of trying to extract an action sequence
+ let actions_by_tick = self.extract_an_action_sequence(parameters);
+
+ // Step 6. Dispatch actions
+ match self.dispatch_actions(actions_by_tick) {
Ok(_) => Ok(WebDriverResponse::Void),
Err(error) => Err(WebDriverError::new(error, "")),
}
}
+ /// <https://w3c.github.io/webdriver/#dfn-release-actions>
fn handle_release_actions(&mut self) -> WebDriverResult<WebDriverResponse> {
- let input_cancel_list = self.session().unwrap().input_cancel_list.borrow();
- if let Err(error) = self.dispatch_actions(&input_cancel_list) {
- return Err(WebDriverError::new(error, ""));
- }
-
+ // TODO: The previous implementation of this function was different from the spec.
+ // Need to re-implement this to match the spec.
let session = self.session()?;
session.input_state_table.borrow_mut().clear();
@@ -1617,14 +1619,23 @@ impl Handler {
let (sender, receiver) = ipc::channel().unwrap();
- let cmd = WebDriverScriptCommand::FocusElement(element.to_string(), sender);
+ let cmd = WebDriverScriptCommand::WillSendKeys(
+ element.to_string(),
+ keys.text.to_string(),
+ self.session()?.strict_file_interactability,
+ sender,
+ );
let cmd_msg = WebDriverCommandMsg::ScriptCommand(browsing_context_id, cmd);
self.constellation_chan
.send(EmbedderToConstellationMessage::WebDriverCommand(cmd_msg))
.unwrap();
// TODO: distinguish the not found and not focusable cases
- wait_for_script_response(receiver)?.map_err(|error| WebDriverError::new(error, ""))?;
+ // File input and non-typeable form control should have
+ // been handled in `webdriver_handler.rs`.
+ if !wait_for_script_response(receiver)?.map_err(|error| WebDriverError::new(error, ""))? {
+ return Ok(WebDriverResponse::Void);
+ }
let input_events = send_keys(&keys.text);
@@ -1655,7 +1666,7 @@ impl Handler {
// Step 8.1
self.session_mut()?.input_state_table.borrow_mut().insert(
id.clone(),
- InputSourceState::Pointer(PointerInputState::new(&PointerType::Mouse)),
+ InputSourceState::Pointer(PointerInputState::new(PointerType::Mouse)),
);
// Step 8.7. Construct a pointer move action.
@@ -1702,7 +1713,11 @@ impl Handler {
},
};
- let _ = self.dispatch_actions(&[action_sequence]);
+ let actions_by_tick = self.actions_by_tick_from_sequence(vec![action_sequence]);
+
+ if let Err(e) = self.dispatch_actions(actions_by_tick) {
+ log::error!("handle_element_click: dispatch_actions failed: {:?}", e);
+ }
// Step 8.17 Remove an input source with input state and input id.
self.session_mut()?
@@ -1940,7 +1955,9 @@ impl WebDriverHandler<ServoExtensionRoute> for Handler {
self.handle_element_css(element, name)
},
WebDriverCommand::GetPageSource => self.handle_get_page_source(),
- WebDriverCommand::PerformActions(ref x) => self.handle_perform_actions(x),
+ WebDriverCommand::PerformActions(actions_parameters) => {
+ self.handle_perform_actions(actions_parameters)
+ },
WebDriverCommand::ReleaseActions => self.handle_release_actions(),
WebDriverCommand::ExecuteScript(ref x) => self.handle_execute_script(x),
WebDriverCommand::ExecuteAsyncScript(ref x) => self.handle_execute_async_script(x),
diff --git a/ports/servoshell/Cargo.toml b/ports/servoshell/Cargo.toml
index edeaef5408f..034e383c7f0 100644
--- a/ports/servoshell/Cargo.toml
+++ b/ports/servoshell/Cargo.toml
@@ -90,8 +90,8 @@ hilog = "0.2.0"
ipc-channel = { workspace = true, features = ["force-inprocess"] }
napi-derive-ohos = "1.0.4"
napi-ohos = "1.0.4"
-ohos-ime = "0.3.0"
-ohos-ime-sys = "0.1.4"
+ohos-ime = "0.4.0"
+ohos-ime-sys = "0.2.0"
ohos-vsync = "0.1.3"
xcomponent-sys = { version = "0.3.1", features = ["api-12", "keyboard-types"] }
diff --git a/ports/servoshell/desktop/app.rs b/ports/servoshell/desktop/app.rs
index 7bbac47cda3..4f3ce2266c5 100644
--- a/ports/servoshell/desktop/app.rs
+++ b/ports/servoshell/desktop/app.rs
@@ -42,13 +42,17 @@ pub struct App {
preferences: Preferences,
servoshell_preferences: ServoShellPreferences,
suspended: Cell<bool>,
- windows: HashMap<WindowId, Rc<dyn WindowPortsMethods>>,
minibrowser: Option<Minibrowser>,
waker: Box<dyn EventLoopWaker>,
initial_url: ServoUrl,
t_start: Instant,
t: Instant,
state: AppState,
+
+ // This is the last field of the struct to ensure that windows are dropped *after* all other
+ // references to the relevant rendering contexts have been destroyed.
+ // (https://github.com/servo/servo/issues/36711)
+ windows: HashMap<WindowId, Rc<dyn WindowPortsMethods>>,
}
/// Action to be taken by the caller of [`App::handle_events`].
diff --git a/ports/servoshell/desktop/egui_glue.rs b/ports/servoshell/desktop/egui_glue.rs
index 09ef3735cf8..e27a659dd24 100644
--- a/ports/servoshell/desktop/egui_glue.rs
+++ b/ports/servoshell/desktop/egui_glue.rs
@@ -39,6 +39,7 @@ pub use egui_winit;
pub use egui_winit::EventResponse;
use egui_winit::winit;
use winit::event_loop::ActiveEventLoop;
+use winit::window::Theme;
/// Use [`egui`] from a [`glow`] app based on [`winit`].
pub struct EguiGlow {
@@ -63,6 +64,7 @@ impl EguiGlow {
})
.unwrap();
+ let theme = event_loop.system_theme().unwrap_or(Theme::Light);
let egui_ctx = egui::Context::default();
Self {
egui_winit: egui_winit::State::new(
@@ -70,7 +72,7 @@ impl EguiGlow {
ViewportId::ROOT,
event_loop,
None,
- event_loop.system_theme(),
+ Some(theme),
None,
),
egui_ctx,
diff --git a/ports/servoshell/desktop/headed_window.rs b/ports/servoshell/desktop/headed_window.rs
index 6095b5c02e7..a1c7576a8c9 100644
--- a/ports/servoshell/desktop/headed_window.rs
+++ b/ports/servoshell/desktop/headed_window.rs
@@ -49,7 +49,6 @@ use crate::desktop::keyutils::CMD_OR_CONTROL;
use crate::prefs::ServoShellPreferences;
pub struct Window {
- winit_window: winit::window::Window,
screen_size: Size2D<u32, DeviceIndependentPixel>,
inner_size: Cell<PhysicalSize<u32>>,
toolbar_height: Cell<Length<f32, DeviceIndependentPixel>>,
@@ -72,6 +71,11 @@ pub struct Window {
/// The `RenderingContext` of Servo itself. This is used to render Servo results
/// temporarily until they can be blitted into the egui scene.
rendering_context: Rc<OffscreenRenderingContext>,
+
+ // Keep this as the last field of the struct to ensure that the rendering context is
+ // dropped first.
+ // (https://github.com/servo/servo/issues/36711)
+ winit_window: winit::window::Window,
}
impl Window {
diff --git a/ports/servoshell/egl/ohos.rs b/ports/servoshell/egl/ohos.rs
index b9587771a50..a1b76758a9a 100644
--- a/ports/servoshell/egl/ohos.rs
+++ b/ports/servoshell/egl/ohos.rs
@@ -867,14 +867,14 @@ impl HostTrait for HostCallbacks {
let mut ime_proxy = self.ime_proxy.borrow_mut();
let ime = ime_proxy.get_or_insert_with(|| {
let attach_options = AttachOptions::new(true);
- let configbuilder = ohos_ime::TextConfigBuilder::new();
let options = convert_ime_options(input_type, multiline);
- let text_config = configbuilder
+ let text_config = ohos_ime::TextConfigBuilder::new()
.input_type(options.input_type)
.enterkey_type(options.enterkey_type)
.build();
- let editor = RawTextEditorProxy::new(Box::new(ServoIme { text_config }));
- ImeProxy::new(editor, attach_options)
+ let editor = RawTextEditorProxy::new(Box::new(ServoIme { text_config }))
+ .expect("Failed to create RawTextEditorProxy");
+ ImeProxy::new(editor, attach_options).expect("Failed to create IME proxy")
});
match ime.show_keyboard() {
Ok(()) => debug!("IME show keyboard - success"),
diff --git a/python/servo/build_commands.py b/python/servo/build_commands.py
index e2a5ffc6a1a..e34fa2a2687 100644
--- a/python/servo/build_commands.py
+++ b/python/servo/build_commands.py
@@ -40,6 +40,7 @@ from servo.platform.build_target import BuildTarget
SUPPORTED_ASAN_TARGETS = [
"aarch64-apple-darwin",
"aarch64-unknown-linux-gnu",
+ "aarch64-unknown-linux-ohos",
"x86_64-apple-darwin",
"x86_64-unknown-linux-gnu",
]
@@ -109,6 +110,8 @@ class MachCommands(CommandBase):
opts += ["-v"]
if very_verbose:
opts += ["-vv"]
+ if with_asan:
+ self.config["build"]["with_asan"] = True
env = self.build_env()
self.ensure_bootstrapped()
@@ -136,6 +139,10 @@ class MachCommands(CommandBase):
opts += ["-Zbuild-std"]
kwargs["target_override"] = target_triple
+ # With asan we also want frame pointers
+ if "force-frame-pointers" not in env["RUSTFLAGS"]:
+ env["RUSTFLAGS"] += " -C force-frame-pointers=yes"
+
# Note: We want to use the same clang/LLVM version as rustc.
rustc_llvm_version = get_rustc_llvm_version()
if rustc_llvm_version is None:
@@ -144,11 +151,14 @@ class MachCommands(CommandBase):
target_clang = f"clang-{llvm_major}"
target_cxx = f"clang++-{llvm_major}"
if shutil.which(target_clang) is None or shutil.which(target_cxx) is None:
- raise RuntimeError(f"--with-asan requires `{target_clang}` and `{target_cxx}` to be in PATH")
- env.setdefault("TARGET_CC", target_clang)
- env.setdefault("TARGET_CXX", target_cxx)
- # TODO: We should also parse the LLVM version from the clang compiler we chose.
- # It's unclear if the major version being the same is sufficient.
+ env.setdefault("TARGET_CC", target_clang)
+ env.setdefault("TARGET_CXX", target_cxx)
+ else:
+ # libasan can be compatible across multiple compiler versions and has a
+ # runtime check, which would fail if we used incompatible compilers, so
+ # we can try and fallback to the default clang.
+ env.setdefault("TARGET_CC", "clang")
+ env.setdefault("TARGET_CXX", "clang++")
# We need to use `TARGET_CFLAGS`, since we don't want to compile host dependencies with ASAN,
# since that causes issues when building build-scripts / proc macros.
@@ -156,7 +166,6 @@ class MachCommands(CommandBase):
env.setdefault("TARGET_CXXFLAGS", "")
env["TARGET_CFLAGS"] += " -fsanitize=address"
env["TARGET_CXXFLAGS"] += " -fsanitize=address"
- env["TARGET_LDFLAGS"] = "-static-libasan"
# By default build mozjs from source to enable ASAN with mozjs.
env.setdefault("MOZJS_FROM_SOURCE", "1")
@@ -190,7 +199,9 @@ class MachCommands(CommandBase):
built_binary = self.get_binary_path(build_type, asan=with_asan)
if not no_package and self.target.needs_packaging():
- rv = Registrar.dispatch("package", context=self.context, build_type=build_type, flavor=flavor)
+ rv = Registrar.dispatch(
+ "package", context=self.context, build_type=build_type, flavor=flavor, with_asan=with_asan
+ )
if rv:
return rv
diff --git a/python/servo/command_base.py b/python/servo/command_base.py
index abd193eda49..f0f28e5488e 100644
--- a/python/servo/command_base.py
+++ b/python/servo/command_base.py
@@ -305,6 +305,7 @@ class CommandBase(object):
self.config["build"].setdefault("incremental", None)
self.config["build"].setdefault("webgl-backtrace", False)
self.config["build"].setdefault("dom-backtrace", False)
+ self.config["build"].setdefault("with_asan", False)
self.config.setdefault("android", {})
self.config["android"].setdefault("sdk", "")
@@ -803,15 +804,16 @@ class CommandBase(object):
"--manifest-path",
path.join(self.context.topdir, "ports", "servoshell", "Cargo.toml"),
]
- if target_override:
- args += ["--target", target_override]
- elif self.target.is_cross_build():
+
+ if self.target.is_cross_build():
args += ["--target", self.target.triple()]
if type(self.target) in [AndroidTarget, OpenHarmonyTarget]:
# Note: in practice `cargo rustc` should just be used unconditionally.
assert command != "build", "For Android / OpenHarmony `cargo rustc` must be used instead of cargo build"
if command == "rustc":
args += ["--lib", "--crate-type=cdylib"]
+ elif target_override:
+ args += ["--target", target_override]
features = []
diff --git a/python/servo/package_commands.py b/python/servo/package_commands.py
index 5e63e6549c0..9bc4d70232d 100644
--- a/python/servo/package_commands.py
+++ b/python/servo/package_commands.py
@@ -184,6 +184,9 @@ class PackageCommands(CommandBase):
"-p",
f"buildMode={build_mode}",
]
+ if with_asan:
+ hvigor_command.extend(["-p", "ohos-debug-asan=true"])
+
# Detect if PATH already has hvigor, or else fallback to npm installation
# provided via HVIGOR_PATH
if "HVIGOR_PATH" not in env:
diff --git a/python/servo/platform/build_target.py b/python/servo/platform/build_target.py
index 5f0f500ad58..536b10a8d3d 100644
--- a/python/servo/platform/build_target.py
+++ b/python/servo/platform/build_target.py
@@ -350,9 +350,8 @@ class OpenHarmonyTarget(CrossBuildTarget):
env[f"CXX_{clang_target_triple_underscore}"] = ndk_clangxx
# rustc linker
env[f"CARGO_TARGET_{rust_target_triple.upper()}_LINKER"] = ndk_clang
- # We could also use a cross-compile wrapper
- env["RUSTFLAGS"] += f" -Clink-arg=--target={clang_target_triple}"
- env["RUSTFLAGS"] += f" -Clink-arg=--sysroot={ohos_sysroot_posix}"
+
+ link_args = ["-fuse-ld=lld", f"--target={clang_target_triple}", f"--sysroot={ohos_sysroot_posix}"]
env["HOST_CFLAGS"] = ""
env["HOST_CXXFLAGS"] = ""
@@ -398,6 +397,49 @@ class OpenHarmonyTarget(CrossBuildTarget):
bindgen_extra_clangs_args = bindgen_extra_clangs_args + " " + ohos_cflags_str
env[bindgen_extra_clangs_args_var] = bindgen_extra_clangs_args
+ # On OpenHarmony we add some additional flags when asan is enabled
+ if config["build"]["with_asan"]:
+ # Lookup `<sdk>/native/llvm/lib/clang/15.0.4/lib/aarch64-linux-ohos/libclang_rt.asan.so`
+ lib_clang = llvm_toolchain.joinpath("lib", "clang")
+ children = [f.path for f in os.scandir(lib_clang) if f.is_dir()]
+ if len(children) != 1:
+ raise RuntimeError(f"Expected exactly 1 libclang version: `{children}`")
+ lib_clang_version_dir = pathlib.Path(children[0])
+ libclang_arch = lib_clang_version_dir.joinpath("lib", clang_target_triple).resolve()
+ libasan_so_path = libclang_arch.joinpath("libclang_rt.asan.so")
+ libasan_preinit_path = libclang_arch.joinpath("libclang_rt.asan-preinit.a")
+ if not libasan_so_path.exists():
+ raise RuntimeError(f"Couldn't find ASAN runtime library at {libasan_so_path}")
+ link_args.extend(
+ [
+ "-fsanitize=address",
+ "--rtlib=compiler-rt",
+ "-shared-libasan",
+ str(libasan_so_path),
+ "-Wl,--whole-archive",
+ "-Wl," + str(libasan_preinit_path),
+ "-Wl,--no-whole-archive",
+ ]
+ )
+
+ # Use the clangrt from the NDK to use the same library for both C++ and Rust.
+ env["RUSTFLAGS"] += " -Zexternal-clangrt"
+
+ asan_compile_flags = (
+ " -fsanitize=address -shared-libasan -fno-omit-frame-pointer -fsanitize-recover=address"
+ )
+
+ arch_asan_ignore_list = lib_clang_version_dir.joinpath("share", "asan_ignorelist.txt")
+ if arch_asan_ignore_list.exists():
+ asan_compile_flags += " -fsanitize-system-ignorelist=" + str(arch_asan_ignore_list)
+ else:
+ print(f"Warning: Couldn't find system ASAN ignorelist at `{arch_asan_ignore_list}`")
+ env["TARGET_CFLAGS"] += asan_compile_flags
+ env["TARGET_CXXFLAGS"] += asan_compile_flags
+
+ link_args = [f"-Clink-arg={arg}" for arg in link_args]
+ env["RUSTFLAGS"] += " " + " ".join(link_args)
+
def binary_name(self) -> str:
return "libservoshell.so"
diff --git a/support/hitrace-bencher/runs.json b/support/hitrace-bencher/runs.json
index 2513e3f57d1..63c64f41a66 100644
--- a/support/hitrace-bencher/runs.json
+++ b/support/hitrace-bencher/runs.json
@@ -25,6 +25,28 @@
"start_fn_partial": "on_surface_created_cb",
"end_fn_partial": "PageLoadEndedPrompt"
}
+ ],
+ "point_filters": [
+ {
+ "name": "Explicit",
+ "match_str": "explicit"
+ },
+ {
+ "name": "Resident",
+ "match_str": "resident"
+ },
+ {
+ "name": "LayoutThread",
+ "match_str": "layout-thread"
+ },
+ {
+ "name": "image-cache",
+ "match_str": "image-cache"
+ },
+ {
+ "name": "JS",
+ "match_str": "js"
+ }
]
},
{
@@ -39,7 +61,28 @@
"start_fn_partial": "on_surface_created_cb",
"end_fn_partial": "PageLoadEndedPrompt"
}
+ ],
+ "point_filters": [
+ {
+ "name": "Explicit",
+ "match_str": "explicit"
+ },
+ {
+ "name": "Resident",
+ "match_str": "resident"
+ },
+ {
+ "name": "LayoutThread",
+ "match_str": "layout-thread"
+ },
+ {
+ "name": "image-cache",
+ "match_str": "image-cache"
+ },
+ {
+ "name": "JS",
+ "match_str": "js"
+ }
]
}
]
-
diff --git a/tests/wpt/meta/MANIFEST.json b/tests/wpt/meta/MANIFEST.json
index 3a7faebb345..7efcfa22eb2 100644
--- a/tests/wpt/meta/MANIFEST.json
+++ b/tests/wpt/meta/MANIFEST.json
@@ -761,6 +761,13 @@
{}
]
],
+ "chrome-420329041-crash.html": [
+ "2b236a371e524da0ac5669ad7fc5f45259c089c5",
+ [
+ null,
+ {}
+ ]
+ ],
"grid-anchor-center-crash.html": [
"bab4eed6b66dfb846ef451f14ced6eb2a0867cc1",
[
@@ -2841,6 +2848,17 @@
]
]
},
+ "css-gaps": {
+ "grid": {
+ "grid-gap-decorations-041-crash.html": [
+ "be3e2280b5f52dcc60a4fe418ae67af3ec23da6b",
+ [
+ null,
+ {}
+ ]
+ ]
+ }
+ },
"css-grid": {
"abspos": {
"abspos-in-flexbox-in-grid-crash.html": [
@@ -3899,6 +3917,13 @@
{}
]
],
+ "repeated-table-column.html": [
+ "0d6a1accfd122c38180f8d20904a7e16a131dd41",
+ [
+ null,
+ {}
+ ]
+ ],
"repeated-table-footer-in-caption-nested-multicol.html": [
"d630abe8bbb1e752d3a7c559e4c49864233c44f9",
[
@@ -5953,6 +5978,13 @@
],
"scoped": {
"crashtests": {
+ "participating-scope.html": [
+ "26979e58458d0a27679f6aa079f38f71eddc03df",
+ [
+ null,
+ {}
+ ]
+ ],
"shadow-dom.html": [
"a2faafc1694e15f5c513655e57e320325bd4f45a",
[
@@ -6975,13 +7007,6 @@
{}
]
],
- "indent-outdent-after-closing-editable-dialog-element.html": [
- "7f73de048d714c99ce47ae4da61d7128e53216e8",
- [
- null,
- {}
- ]
- ],
"insert-image-with-joining-header-element-and-body.html": [
"cf5b2df225be06c833fea6d3bf2ceab6b1231018",
[
@@ -8178,6 +8203,13 @@
{}
]
],
+ "select-highlight-crash.html": [
+ "a45120a245984408b65b1e99f1cfba265dad78fc",
+ [
+ null,
+ {}
+ ]
+ ],
"select-listitems-crash.html": [
"cdda243877f1e3c699410dd67e25548880b868b9",
[
@@ -8462,6 +8494,13 @@
{}
]
],
+ "popover-root-crash.html": [
+ "86498607730f883920419ac4815dce128196d9f5",
+ [
+ null,
+ {}
+ ]
+ ],
"popover-undefined-remove-crash.html": [
"3c273ea6f344d179a3d010d20f0779b3721abb40",
[
@@ -23715,6 +23754,13 @@
null,
{}
]
+ ],
+ "ua-shadow-contents-manual.html": [
+ "23908ca927426be40895156d26b94fdbc40b090d",
+ [
+ null,
+ {}
+ ]
]
},
"images": {
@@ -136900,6 +136946,35 @@
}
]
],
+ "corner-shape-img.html": [
+ "82662d255623d387080bcc8be2e33570f0ed4c62",
+ [
+ null,
+ [
+ [
+ "/css/css-borders/tentative/corner-shape/corner-shape-img-ref.html",
+ "=="
+ ]
+ ],
+ {
+ "fuzzy": [
+ [
+ null,
+ [
+ [
+ 0,
+ 64
+ ],
+ [
+ 0,
+ 100
+ ]
+ ]
+ ]
+ ]
+ }
+ ]
+ ],
"corner-shape-inset-shadow.html": [
"7a83caff70c08b74d5d6c2540684c49f8e893f72",
[
@@ -136988,7 +137063,7 @@
]
],
"corner-shape-render-fuzzy.html": [
- "12cd2546bf484282a8cab7163c610b5b88d0b9f8",
+ "2d4b56f831b91eb70fd44abc02000213664a480b",
[
"css/css-borders/tentative/corner-shape/corner-shape-render-fuzzy.html?border-radius=30%&corner-shape=superellipse(-1.5)&box-shadow=10px%2010px%200%2010px%20black",
[
@@ -137250,10 +137325,10 @@
}
],
[
- "css/css-borders/tentative/corner-shape/corner-shape-render-fuzzy.html?corner-shape=superellipse(0.8)&border-radius=40px&border-width=10px&border-left-color=purple",
+ "css/css-borders/tentative/corner-shape/corner-shape-render-fuzzy.html?corner-shape=superellipse(0.8)&border-radius=40px&border-width=10px",
[
[
- "/css/css-borders/tentative/corner-shape/corner-shape-any-ref.html?corner-shape=superellipse(0.8)&border-radius=40px&border-width=10px&border-left-color=purple",
+ "/css/css-borders/tentative/corner-shape/corner-shape-any-ref.html?corner-shape=superellipse(0.8)&border-radius=40px&border-width=10px",
"=="
]
],
@@ -137485,7 +137560,7 @@
]
],
"corner-shape-render-precise.html": [
- "5293589222a3f2d918bdbfeecd11280f667578c2",
+ "4a0c575b3b7cef4cbfb1dea4efc53ec40e01ef13",
[
"css/css-borders/tentative/corner-shape/corner-shape-render-precise.html?border-radius=50%&corner-shape=bevel&box-shadow=10px%2010px%200%2010px%20black",
[
@@ -137669,6 +137744,32 @@
}
],
[
+ "css/css-borders/tentative/corner-shape/corner-shape-render-precise.html?corner-shape=notch&border-radius=30px&border-width=30px",
+ [
+ [
+ "/css/css-borders/tentative/corner-shape/corner-shape-any-ref.html?corner-shape=notch&border-radius=30px&border-width=30px",
+ "=="
+ ]
+ ],
+ {
+ "fuzzy": [
+ [
+ null,
+ [
+ [
+ 0,
+ 180
+ ],
+ [
+ 0,
+ 350
+ ]
+ ]
+ ]
+ ]
+ }
+ ],
+ [
"css/css-borders/tentative/corner-shape/corner-shape-render-precise.html?corner-shape=square&border-bottom-left-radius=5px",
[
[
@@ -137877,10 +137978,10 @@
}
],
[
- "css/css-borders/tentative/corner-shape/corner-shape-render-precise.html?corner-top-left-shape=bevel&border-width=10px&border-color=black",
+ "css/css-borders/tentative/corner-shape/corner-shape-render-precise.html?corner-top-left-shape=bevel&border-width=10px",
[
[
- "/css/css-borders/tentative/corner-shape/corner-shape-any-ref.html?corner-top-left-shape=bevel&border-width=10px&border-color=black",
+ "/css/css-borders/tentative/corner-shape/corner-shape-any-ref.html?corner-top-left-shape=bevel&border-width=10px",
"=="
]
],
@@ -138007,10 +138108,10 @@
}
],
[
- "css/css-borders/tentative/corner-shape/corner-shape-render-precise.html?corner-top-right-shape=bevel&border-width=10px&border-color=black",
+ "css/css-borders/tentative/corner-shape/corner-shape-render-precise.html?corner-top-right-shape=bevel&border-width=10px",
[
[
- "/css/css-borders/tentative/corner-shape/corner-shape-any-ref.html?corner-top-right-shape=bevel&border-width=10px&border-color=black",
+ "/css/css-borders/tentative/corner-shape/corner-shape-any-ref.html?corner-top-right-shape=bevel&border-width=10px",
"=="
]
],
@@ -176879,19 +176980,6 @@
{}
]
],
- "flexbox_columns.html": [
- "d39c2db55f2a144e5ab9efa713572bd27da72c07",
- [
- null,
- [
- [
- "/css/css-flexbox/flexbox_columns-ref.html",
- "=="
- ]
- ],
- {}
- ]
- ],
"flexbox_direction-column-reverse.html": [
"8d2cd330e4c65c46a4ff2c8e36811c88c7bdc4e6",
[
@@ -186558,6 +186646,21 @@
]
]
},
+ "css-forms": {
+ "datetime-stacking-context.html": [
+ "4754cacf09d6cc1c9aaccbb760e32ca8991e6502",
+ [
+ null,
+ [
+ [
+ "/css/css-forms/datetime-stacking-context-ref.html",
+ "=="
+ ]
+ ],
+ {}
+ ]
+ ]
+ },
"css-gaps": {
"agnostic": {
"gap-decorations-003.html": [
@@ -187383,6 +187486,32 @@
{}
]
],
+ "grid-gap-decorations-040.html": [
+ "4bab26db550308a111608e3b0af6d15735c6d041",
+ [
+ null,
+ [
+ [
+ "/css/css-gaps/grid/grid-gap-decorations-040-ref.html",
+ "=="
+ ]
+ ],
+ {}
+ ]
+ ],
+ "grid-gap-decorations-042.html": [
+ "5b2b4936980641296cf1c97f80b4bdbecd19ce2f",
+ [
+ null,
+ [
+ [
+ "/css/css-gaps/grid/grid-gap-decorations-042-ref.html",
+ "=="
+ ]
+ ],
+ {}
+ ]
+ ],
"grid-gap-decorations-38.html": [
"8b87bcd4860ac50a1c2f3de98cec9599bebb77a3",
[
@@ -192381,6 +192510,19 @@
{}
]
],
+ "grid-item-inline-contribution-004.html": [
+ "a4e3cd6f3a47d18efc2a27d1f1e410d5ef92cff5",
+ [
+ null,
+ [
+ [
+ "/css/reference/ref-filled-green-100px-square.xht",
+ "=="
+ ]
+ ],
+ {}
+ ]
+ ],
"grid-item-margins-and-writing-modes-001.html": [
"5209940a9699d6a108f815f81eb4d3b4527dcf79",
[
@@ -211752,6 +211894,37 @@
]
},
"css-masking": {
+ "animations": {
+ "clip-path-interpolation-shape-arc-direction-agnostic-radius.html": [
+ "aa91e1828a7841c4036f6c2d15639ebd2f1bf4e4",
+ [
+ null,
+ [
+ [
+ "/css/css-masking/animations/clip-path-interpolation-shape-arc-direction-agnostic-radius-ref.html",
+ "=="
+ ]
+ ],
+ {
+ "fuzzy": [
+ [
+ null,
+ [
+ [
+ 0,
+ 10
+ ],
+ [
+ 0,
+ 360
+ ]
+ ]
+ ]
+ ]
+ }
+ ]
+ ]
+ },
"clip": {
"clip-absolute-positioned-001.html": [
"c5b0d9001c442012aea33142d47ca1a8d68e319e",
@@ -215146,6 +215319,35 @@
{}
]
],
+ "clip-path-shape-011.html": [
+ "fc1927591e086bf341fcd9fa87a86429e1862053",
+ [
+ null,
+ [
+ [
+ "/css/css-masking/clip-path/reference/clip-path-shape-arc-ref.html",
+ "=="
+ ]
+ ],
+ {
+ "fuzzy": [
+ [
+ null,
+ [
+ [
+ 0,
+ 64
+ ],
+ [
+ 0,
+ 128
+ ]
+ ]
+ ]
+ ]
+ }
+ ]
+ ],
"clip-path-shape-foreignobject-non-zero-xy.html": [
"4e221f36e4cb7bc698f1929dcc09096114ab2693",
[
@@ -250746,6 +250948,19 @@
{}
]
],
+ "image-max-width-and-height-behaves-as-auto.html": [
+ "dcb00ba6a5cdcc1c310e26792172da0490b927c4",
+ [
+ null,
+ [
+ [
+ "/css/reference/ref-filled-green-100px-square-only.html",
+ "=="
+ ]
+ ],
+ {}
+ ]
+ ],
"image-min-max-content-intrinsic-size-change-001.html": [
"b7c57bb7abe161bf66cdec988953ba1d2c0035ab",
[
@@ -251815,6 +252030,84 @@
{}
]
],
+ "responsive-iframe-cross-origin-no-match-element.sub.tentative.html": [
+ "08dda4e6b7660bdea83681b52fa15ae93ad32ceb",
+ [
+ null,
+ [
+ [
+ "/css/css-sizing/responsive-iframe-unsized-ref.html",
+ "=="
+ ]
+ ],
+ {}
+ ]
+ ],
+ "responsive-iframe-cross-origin-not-embedded-sized.sub.tentative.html": [
+ "d9b33973a04c7eb3f8a4756f4d15fda0970bae0d",
+ [
+ null,
+ [
+ [
+ "/css/css-sizing/responsive-iframe-unsized-ref.html",
+ "=="
+ ]
+ ],
+ {}
+ ]
+ ],
+ "responsive-iframe-cross-origin.sub.tentative.html": [
+ "22f6f1d1581af4bc515877dee2f8d119274817e3",
+ [
+ null,
+ [
+ [
+ "/css/css-sizing/responsive-iframe-ref.html",
+ "=="
+ ]
+ ],
+ {}
+ ]
+ ],
+ "responsive-iframe-no-match-element.html": [
+ "685eb60f123fb54066cca118ab5cb29cfcd89db9",
+ [
+ null,
+ [
+ [
+ "/css/css-sizing/responsive-iframe-unsized-ref.html",
+ "=="
+ ]
+ ],
+ {}
+ ]
+ ],
+ "responsive-iframe-not-embedded-sized.tentative.html": [
+ "0d1f91c5789afd8e9af69c2f19204dc0cae60bf3",
+ [
+ null,
+ [
+ [
+ "/css/css-sizing/responsive-iframe-unsized-ref.html",
+ "=="
+ ]
+ ],
+ {}
+ ]
+ ],
+ "responsive-iframe.tentative.html": [
+ "229cf01844968e7aa55c165b128435ea455a40d6",
+ [
+ null,
+ [
+ [
+ "/css/css-sizing/responsive-iframe-ref.html",
+ "=="
+ ]
+ ],
+ {}
+ ]
+ ],
"slice-intrinsic-size.html": [
"05ce6e46304adda6aab773147e8a32d2564680b6",
[
@@ -263486,6 +263779,19 @@
{}
]
],
+ "text-autospace-edit-001.html": [
+ "80c46f54d20ff9249a49d73e55b331a8368df4e1",
+ [
+ null,
+ [
+ [
+ "/css/css-text/text-autospace/text-autospace-edit-001-ref.html",
+ "=="
+ ]
+ ],
+ {}
+ ]
+ ],
"text-autospace-first-line-001.html": [
"0e0f848b062747e6cb36ec4899d2bbfff10fcb44",
[
@@ -263580,6 +263886,19 @@
],
{}
]
+ ],
+ "text-autospace-vs-001.html": [
+ "31c7bbf6073ffac1f614846c6c033cca7ff7d4b4",
+ [
+ null,
+ [
+ [
+ "/css/css-text/text-autospace/text-autospace-vs-001-ref.html",
+ "=="
+ ]
+ ],
+ {}
+ ]
]
},
"text-encoding": {
@@ -272836,6 +273155,19 @@
{}
]
],
+ "word-break-keep-all-u002d.html": [
+ "df3ebb3f22111f4935d3787674a18c7a833083c1",
+ [
+ null,
+ [
+ [
+ "/css/css-text/word-break/reference/word-break-keep-all-u002d-ref.html",
+ "=="
+ ]
+ ],
+ {}
+ ]
+ ],
"word-break-manual-001.html": [
"09d803b0fc1f75f2f253687c5c9dc3305d77616f",
[
@@ -306974,7 +307306,7 @@
]
],
"auto-name-from-id.html": [
- "d3430c93a1d2043146e7205c2734a2b8b19af2e0",
+ "20080d7623a9ce4880d7a065cf729f0f2b3470e1",
[
null,
[
@@ -307975,6 +308307,35 @@
}
]
],
+ "inline-child-with-composited-filter.html": [
+ "36ba9803e1edb2c87d8d3e57b5f2589d349df964",
+ [
+ null,
+ [
+ [
+ "/css/css-view-transitions/inline-child-with-filter-ref.html",
+ "=="
+ ]
+ ],
+ {
+ "fuzzy": [
+ [
+ null,
+ [
+ [
+ 0,
+ 2
+ ],
+ [
+ 0,
+ 2400
+ ]
+ ]
+ ]
+ ]
+ }
+ ]
+ ],
"inline-child-with-filter.html": [
"61f0f1f6a8c389cd7298c56d8c2e35c3f101027b",
[
@@ -308031,7 +308392,7 @@
]
],
"inline-with-offset-from-containing-block.html": [
- "31f8449ff630fe6844eb16b46e445ec840d550d8",
+ "77fb0570966e47909b7b9d06f1330adcd5233ac8",
[
null,
[
@@ -308051,7 +308412,7 @@
],
[
0,
- 1500
+ 1633
]
]
]
@@ -309600,7 +309961,7 @@
]
],
"nested-exit.tentative.html": [
- "83570762061638bd2a780922e45cf39da100d713",
+ "847058be2b4a1659fb4d512e0906b55fa96c4a38",
[
null,
[
@@ -309774,7 +310135,7 @@
]
],
"rounded-border-clipper.html": [
- "239bcdd791db41383dd66765269590d84627a0a3",
+ "098e5566585930a89378c5a8a6ede536fea9e124",
[
null,
[
@@ -309902,7 +310263,7 @@
]
],
"new-content-captures-different-size.html": [
- "eeb7347981daac829fd17d85ada19730fe22af32",
+ "0a754c651ffa2f0e7cbd957ab4ad2b8bb35f2cd2",
[
null,
[
@@ -309922,7 +310283,7 @@
],
[
0,
- 15000
+ 15393
]
]
]
@@ -311275,7 +311636,7 @@
]
],
"pseudo-with-classes-view-transition-group.html": [
- "f9fe20222589283591cee10fa33f88d8d47f15ad",
+ "14717728b15ec9023a1fdeb0dc41c639588d7fee",
[
null,
[
@@ -311438,7 +311799,7 @@
],
"scoped": {
"nested-scope.html": [
- "9fff44e5e732edd1946adf414a8f23668022edda",
+ "b9cc25c3338912ae91da453c20924dd5cc90e294",
[
null,
[
@@ -312471,6 +312832,19 @@
{}
]
],
+ "height.html": [
+ "f608765bcf1f60857bba1ab8a4db820e68577941",
+ [
+ null,
+ [
+ [
+ "/css/css-viewport/zoom/green-square-100px.html",
+ "=="
+ ]
+ ],
+ {}
+ ]
+ ],
"iframe-zoom-nested.html": [
"9dc99a0fa55ea28e4a7e36ecd90166aef64771fb",
[
@@ -312511,7 +312885,7 @@
]
],
"inherited-length.html": [
- "d83111a43528b7f0cf08732084330a43148d998b",
+ "571b533d5d6fd81ba8a334fa23ed21a120daecc5",
[
null,
[
@@ -312575,6 +312949,58 @@
{}
]
],
+ "max-height.html": [
+ "6a0dcd826e245f82e76ee2bff177ff0270299701",
+ [
+ null,
+ [
+ [
+ "/css/css-viewport/zoom/green-square-100px.html",
+ "=="
+ ]
+ ],
+ {}
+ ]
+ ],
+ "max-width.html": [
+ "b6d4139e30a9754eac02ad85c4348adacf793158",
+ [
+ null,
+ [
+ [
+ "/css/css-viewport/zoom/green-square-100px.html",
+ "=="
+ ]
+ ],
+ {}
+ ]
+ ],
+ "min-height.html": [
+ "31a47d92b213baf1fe8ae3d88607b41e29a4c577",
+ [
+ null,
+ [
+ [
+ "/css/css-viewport/zoom/green-square-100px.html",
+ "=="
+ ]
+ ],
+ {}
+ ]
+ ],
+ "min-width.html": [
+ "bd1cda23d3a3b0d0197c63ea536b2b5c85d2b66f",
+ [
+ null,
+ [
+ [
+ "/css/css-viewport/zoom/green-square-100px.html",
+ "=="
+ ]
+ ],
+ {}
+ ]
+ ],
"relative-units-from-parent.html": [
"57df82b6f1c5b8cd9ef405cdc1097826de0e061f",
[
@@ -323706,6 +324132,19 @@
{}
]
],
+ "orthogonal-cell-001.html": [
+ "12e996ac902b138e53936f39f7c2237978f9a1ae",
+ [
+ null,
+ [
+ [
+ "/css/css-writing-modes/orthogonal-cell-001-ref.html",
+ "=="
+ ]
+ ],
+ {}
+ ]
+ ],
"orthogonal-child-with-border.html": [
"877cce5a710f5f5e613c02f581c216070fdd0f41",
[
@@ -339456,6 +339895,19 @@
{}
]
],
+ "visited-nested.html": [
+ "57220446c8688a3a12fcb36aeb00b904c901fd3d",
+ [
+ null,
+ [
+ [
+ "/css/selectors/visited-nested-ref.html",
+ "=="
+ ]
+ ],
+ {}
+ ]
+ ],
"xml-class-selector.xml": [
"5666c0065d6262e0ca3c586d145a67e7f9c2a3cf",
[
@@ -339469,20 +339921,7 @@
{}
]
]
- },
- "visited-nested.html": [
- "57220446c8688a3a12fcb36aeb00b904c901fd3d",
- [
- null,
- [
- [
- "/css/visited-nested-ref.html",
- "=="
- ]
- ],
- {}
- ]
- ]
+ }
},
"custom-elements": {
"form-associated": {
@@ -351498,6 +351937,32 @@
{}
]
],
+ "size-with-color-or-noshade.html": [
+ "db1d583934e6df482cde846eda757e010e7d0310",
+ [
+ null,
+ [
+ [
+ "/html/rendering/non-replaced-elements/the-hr-element-0/size-with-color-or-noshade-ref.html",
+ "=="
+ ]
+ ],
+ {}
+ ]
+ ],
+ "size.html": [
+ "2162131b853ed77917ab373f4fb2c70c536e453c",
+ [
+ null,
+ [
+ [
+ "/html/rendering/non-replaced-elements/the-hr-element-0/size-ref.html",
+ "=="
+ ]
+ ],
+ {}
+ ]
+ ],
"width.html": [
"a436d2ae25a6b03f320bda066f32c374b84e0d92",
[
@@ -356825,6 +357290,34 @@
{}
]
],
+ "permission-icon": {
+ "icon-hidden-reftest.html": [
+ "79055da1badfc827e5cc02ed3be7db3842b49855",
+ [
+ null,
+ [
+ [
+ "/html/semantics/permission-element/permission-icon/standard-location-permission-element-ref.html",
+ "!="
+ ]
+ ],
+ {}
+ ]
+ ],
+ "icon-unique-per-type-reftest.html": [
+ "d51b1c4d398a42c8e59f047c0e457c533eae16ee",
+ [
+ null,
+ [
+ [
+ "/html/semantics/permission-element/permission-icon/standard-location-permission-element-ref.html",
+ "!="
+ ]
+ ],
+ {}
+ ]
+ ]
+ },
"pseudo-elements-in-div.tentative.html": [
"24a2be07fabae34fd969fa89c233b2a209c0c08f",
[
@@ -364728,6 +365221,19 @@
{}
]
],
+ "image-modify-href-4.svg": [
+ "f7e550e5defb0b1eba85edad430b0cef760223e6",
+ [
+ null,
+ [
+ [
+ "/svg/embedded/reference/green-rect-100x100.svg",
+ "=="
+ ]
+ ],
+ {}
+ ]
+ ],
"image-remove-href-1.svg": [
"f35fa08f561dc38363d5c83918ec789fbc523b60",
[
@@ -376553,6 +377059,10 @@
[]
],
"permissions-policy": {
+ "WEB_FEATURES.yml": [
+ "da7599308cc01a95696e952d02553df47ba3f6bf",
+ []
+ ],
"ch-ua-high-entropy-values-disabled-by-permissions-policy.https.sub.html.headers": [
"fcf474880843e220faff943f8946f83b514208a4",
[]
@@ -395794,7 +396304,7 @@
],
"resources": {
"container-timing-helpers.js": [
- "a80ad964fef311f55062631d5548a6d8f0eecb3f",
+ "8b3f21dff56f9cef78b8a7c4df785a5b366034e5",
[]
],
"square100.png": [
@@ -397312,7 +397822,7 @@
[]
],
"script-src-strict_dynamic_parser_inserted.html.headers": [
- "b7918c93323eff9db66ad26a73b78798d35e5f7b",
+ "9d0b3b93d44db43be7d19c34483bc1e63ef777a0",
[]
],
"script-src-strict_dynamic_parser_inserted_correct_nonce.html.headers": [
@@ -397723,7 +398233,7 @@
},
"cookie-store": {
"META.yml": [
- "68c30024552f526e2d34f42eb22416ac3b585114",
+ "4bbc6311bdceece7580ba9c38344081e0b4aba57",
[]
],
"README.md": [
@@ -397736,7 +398246,7 @@
[]
],
"cookie-test-helpers.js": [
- "8e23ff2c4225da41788542908fae6593860146ce",
+ "82ca135f88e423440c3c3fd2bb02df4ed39aa436",
[]
],
"cookie_helper.py": [
@@ -418479,6 +418989,10 @@
"1eb6cbd8df349f0a27b1575b8a77583c95b44a42",
[]
],
+ "corner-shape-img-ref.html": [
+ "565698f79ec3fe89a9078a2c6277b38f494dfd99",
+ []
+ ],
"corner-shape-inset-shadow-ref.html": [
"fa36c9d6ecc527fee37bb589c3c5194df1ff2291",
[]
@@ -418497,11 +419011,11 @@
],
"resources": {
"corner-shape.js": [
- "4757a43ad051f42a88ddefeba344bcea0b9a0149",
+ "c08a95c7d7511e84eb92015d13578e23ad2f2ec5",
[]
],
"corner-utils.js": [
- "ad3b235addff11e418d78e372b20c09a2ebd4a19",
+ "b6f329e82484f14f853c999dbd99a15771db1e8d",
[]
],
"resolve-corner-style.js": [
@@ -423743,10 +424257,6 @@
"3c8e1f475a337e111b7290465b67ede2b35ac4bb",
[]
],
- "flexbox_columns-ref.html": [
- "b8c7a22569882c3687441af49ed683dcc37634bd",
- []
- ],
"flexbox_direction-column-ref.html": [
"9b91d50345528741a8cf3d889bc8212282e678cb",
[]
@@ -432682,6 +433192,12 @@
]
}
},
+ "css-forms": {
+ "datetime-stacking-context-ref.html": [
+ "95bee383d2117d1c054e4706abfd130149d31fc8",
+ []
+ ]
+ },
"css-gaps": {
"agnostic": {
"gap-decorations-001-ref.html": [
@@ -432911,6 +433427,14 @@
"grid-gap-decorations-037-ref.html": [
"4a2ee5bd5c6fbdb25e5a70eac56a9b0bbac5d56f",
[]
+ ],
+ "grid-gap-decorations-040-ref.html": [
+ "2988cf534a969828f1e0b9756a8bf52747966ee8",
+ []
+ ],
+ "grid-gap-decorations-042-ref.html": [
+ "ed44f7a2de37d31d57391731b2b8d7f7886790ad",
+ []
]
},
"multicol": {
@@ -437413,6 +437937,10 @@
"WEB_FEATURES.yml": [
"758ef35275eeacc96b6e584f672f86c4b170e0e1",
[]
+ ],
+ "clip-path-interpolation-shape-arc-direction-agnostic-radius-ref.html": [
+ "2869d38a982b23d72ae49543d16d01bda6f28b21",
+ []
]
},
"clip": {
@@ -437823,6 +438351,10 @@
"b74e6abdd9e7c02adf5392f02854ee61f05bc38f",
[]
],
+ "clip-path-shape-arc-ref.html": [
+ "9cbe55de210580ce38096bf106493d10f33dc7cd",
+ []
+ ],
"clip-path-shape-control-points-ref.html": [
"ebcc87bcf6482b22974787ae80df052b0c67ee02",
[]
@@ -438436,7 +438968,7 @@
[]
],
"column-height-009-ref.html": [
- "034440ebd5c81be43f0d871d3adb276b2a735768",
+ "4696d79695bdd6a5901e4d0d00fffc4935438163",
[]
],
"column-pseudo-background-color-ref.html": [
@@ -441818,6 +442350,10 @@
]
},
"overlay": {
+ "WEB_FEATURES.yml": [
+ "a1a4402ee421efa24e9b02a2337c90812759a4e2",
+ []
+ ],
"green-ref.html": [
"bef7405e96f8181f88fb073ebd212b4af6382e33",
[]
@@ -445127,6 +445663,24 @@
"11afa34a654ec071c00971b11a2261ff95397904",
[]
],
+ "resources": {
+ "iframe-contents-unsized.html": [
+ "db1931a27d5a7ff84d30edf370688d0c33b139b9",
+ []
+ ],
+ "iframe-contents.html": [
+ "3b7406e1e4064bc0f9f829907bfe462c8b6d3891",
+ []
+ ]
+ },
+ "responsive-iframe-ref.html": [
+ "c446474f71a9e0f443ef7f57226a16a1d25f8444",
+ []
+ ],
+ "responsive-iframe-unsized-ref.html": [
+ "2fa633e086dceeb9e05063eb92783295351b4d44",
+ []
+ ],
"slice-intrinsic-size-ref.html": [
"ca4887af7a862b6629a579b306638263ca5192b3",
[]
@@ -448188,6 +448742,10 @@
"d26fae09b03fc19fc561abcc4ab4487b3be91b3f",
[]
],
+ "text-autospace-edit-001-ref.html": [
+ "ca95e197462730462dbd403871173d6b9873c3b0",
+ []
+ ],
"text-autospace-first-line-001-ref.html": [
"4adf09f200df40141453a89171fa1392740cfbd3",
[]
@@ -448219,6 +448777,10 @@
"text-autospace-vertical-upright-001-ref.html": [
"1c9caec112a3f9e132a8b612f748a23556a56de2",
[]
+ ],
+ "text-autospace-vs-001-ref.html": [
+ "b02b4f7a20deeffd4f72b8ed8aa5103e3e2e6518",
+ []
]
},
"text-encoding": {
@@ -449599,6 +450161,10 @@
"cbfd3476089a962634e21ead1122f105f3f58c92",
[]
],
+ "word-break-keep-all-u002d-ref.html": [
+ "4a6553cfe838e41c67f0ccaa9d7e04b6904a1e62",
+ []
+ ],
"word-break-manual-001-ref.html": [
"f51208ab95fd4aaa804684673f09acf1492ded4d",
[]
@@ -454721,6 +455287,10 @@
"bf99b25f76b176520715a245ef3abf01258fdc5a",
[]
],
+ "inline-child-with-composited-filter-ref.html": [
+ "9dd26f2c3b1afb49d60bedb5e721dcb1f193d423",
+ []
+ ],
"inline-child-with-filter-ref.html": [
"44a41f1bf93366e06f2eae0cbfcd4acb126d192f",
[]
@@ -454884,7 +455454,7 @@
[]
],
"auto-name-from-id.html": [
- "71ea52a273e3fca98440cdefc50c77c722663a21",
+ "dc2cf8fd29b2cf46e1c4c57aa2c34f6272a51b20",
[]
],
"chromium-paint-holding-timeout.html": [
@@ -454998,7 +455568,7 @@
],
"resources": {
"compute-common.css": [
- "20337ccce5f3387e7e70e6fb219544369b74aa06",
+ "d8f46179b40fd8d55b2bdc125a04cf26aadf0fba",
[]
],
"compute-test.js": [
@@ -455279,7 +455849,7 @@
[]
],
"nested-scope-ref.html": [
- "804741cd6db993392ba8785e8c87f9c16894af41",
+ "951c0928687dcd6edb32e8e3aa7307bf3d6b3923",
[]
]
},
@@ -456091,6 +456661,10 @@
"28f0e333282a714715f8e593ac810ff3704d029e",
[]
],
+ "orthogonal-cell-001-ref.html": [
+ "f50121ef16d240e2991a9626b1dfe4e72a893fb3",
+ []
+ ],
"orthogonal-containing-block-height-changes-ref.html": [
"b7d32e4dc27ba972345f6dc9be81b4079ed54574",
[]
@@ -460673,6 +461247,10 @@
"64300b13f4291f416eac17f70ff62e2febf604fe",
[]
],
+ "visited-nested-ref.html": [
+ "22f4ecf0d7bbcef307fd679ae0905f9b5318f690",
+ []
+ ],
"xml-class-selector-ref.xml": [
"6b44280737ab254649036ff50808b764bc87cc67",
[]
@@ -460923,11 +461501,7 @@
"e7775276038f307b7cdb0a75d19ee24f67619c2a",
[]
]
- },
- "visited-nested-ref.html": [
- "22f4ecf0d7bbcef307fd679ae0905f9b5318f690",
- []
- ]
+ }
},
"custom-elements": {
"META.yml": [
@@ -466607,7 +467181,7 @@
],
"resources": {
"fetch-private-http.html": [
- "e372d90b26a02bdfa0b9a34c9c8ad956b5d0cc02",
+ "517629b758e89d4e07f2278d0ae7cb1a45b19c17",
[]
],
"fetch-private.html": [
@@ -466615,7 +467189,7 @@
[]
],
"fetch-public-http-wrong-address-space.html": [
- "1d149d00cb351b9aaa4402b9b8b7d975d56a9acb",
+ "c15a87ff7b9206576710b5763a64ac6a9a704d71",
[]
],
"support.sub.js": [
@@ -479883,6 +480457,14 @@
"5cd35c83ada3470ad7a16d14a5028b01596bb60c",
[]
],
+ "size-ref.html": [
+ "03a21eb45737ef46247d8bdd61fe5ea0dcefef3e",
+ []
+ ],
+ "size-with-color-or-noshade-ref.html": [
+ "d6300e250d97d113e9ef358daa300de4bd593850",
+ []
+ ],
"width-ref.html": [
"71e7651c1ab6927f1be436ef8ff749f920924562",
[]
@@ -482744,6 +483326,12 @@
"8b48bb93febed1c7fd88f62fe747b3379b349e22",
[]
],
+ "permission-icon": {
+ "standard-location-permission-element-ref.html": [
+ "15ffe751c51b3f8caeaa8b93f1286a3950c9a815",
+ []
+ ]
+ },
"pseudo-elements-in-div-ref.html": [
"8e6267f9aa350333cef620d248dfce40b85b43e2",
[]
@@ -486210,7 +486798,7 @@
"system-state-and-capabilities": {
"the-navigator-object": {
"WEB_FEATURES.yml": [
- "a1af3e21a48f5941a078209963d1ae7bc379dd59",
+ "7a364e140958e3cea3be9fd13654afc504006664",
[]
],
"resources": {
@@ -488484,6 +489072,10 @@
"6f93db15a74e052913a277e5130226280a3f9311",
[]
],
+ "scoped-custom-elements-registry.idl": [
+ "46ca2d6b9c45805d8aa684af7fe91af6dd5d7919",
+ []
+ ],
"screen-capture.idl": [
"db9282ce0a57bb3b84ea45f5ed2d7e69bc3a8a32",
[]
@@ -489198,6 +489790,10 @@
"10c6aa36cecf918928298102d1934c2ff79d01f2",
[]
],
+ "WEB_FEATURES.yml": [
+ "335b072c1868c1817dbe7ed6c1901907aa8decbc",
+ []
+ ],
"resources": {
"slow-image.py": [
"d9f09b8bca78dd1e054fdfcb108fe9066a31db3b",
@@ -489214,7 +489810,7 @@
}
},
"lint.ignore": [
- "10b5dadba749857f16dc92f348fff31b4400dca3",
+ "60b0f65a6f43a560c5d86ffe937359d5c9717597",
[]
],
"loading": {
@@ -492288,7 +492884,7 @@
[]
],
"nel.sub.js": [
- "26ddd897c2fb72b3e48fe572bcfba745729ddfe1",
+ "f9dfec1dad8c774e2dc04ff7787edaab3554cc96",
[]
],
"no-policy-pass.png": [
@@ -497060,6 +497656,10 @@
"edb4759954d4c3829ddc0aa2ecac84ef7d241e37",
[]
],
+ "testdriver-actions.js.headers": [
+ "5e8f640c6659d176eaca4c71cc1798b7285540b7",
+ []
+ ],
"testdriver-vendor.js": [
"3e88403636396c439759705c751433b28e05f3ab",
[]
@@ -501328,13 +501928,23 @@
[]
],
"soft-navigation-helper.js": [
- "48e7b58d8d1a6a0f05a5c4e30efc3faca83eedaf",
+ "5860738225b8ed03a2063b1c2b9eef7884f33ee5",
[]
],
"soft-navigation-test-helper.js": [
"a572f55e66dbce825d399f61c4a2dfa34df9b4ca",
[]
]
+ },
+ "smoke": {
+ "tentative": {
+ "resources": {
+ "other_window.html": [
+ "406d39c3691853a03731287b2a02f215dcbf721c",
+ []
+ ]
+ }
+ }
}
},
"speculation-rules": {
@@ -501383,13 +501993,17 @@
[]
],
"executor.sub.html": [
- "bb2d58dc9c9cfac6d98380b0b587bc242fbd5e11",
+ "b89c45e4f5c25b274925afd6569d6384d5183fe4",
[]
],
"executor.sub.html.headers": [
"4030ea1d3ddb186a2b5361eb1a3f2404a45531fc",
[]
],
+ "post-navigation-handler.py": [
+ "1749517710ed19eda399f01321e1ffcedfc9b09b",
+ []
+ ],
"prefetch.py": [
"14ac4d1699ea0c52ac4b40f0a4a0f71c99147073",
[]
@@ -501610,6 +502224,10 @@
"10a48df58cf9dd9f13eca87e69c54098af1b64b0",
[]
],
+ "image-with-headers-stash.py": [
+ "dcb8838d4a167d91ded325e7d3fc6b50055c7746",
+ []
+ ],
"indexedb-utils.js": [
"7c57000d5cf48a3bbf74c0b0d8f812922f0575ef",
[]
@@ -513897,7 +514515,7 @@
[]
],
"base.py": [
- "7cea14c7a44b04b1174949816a29bd7d30ef8b16",
+ "707b539ec769696948b6ee9e4c35991b1f1afad8",
[]
],
"bufferhandler.py": [
@@ -515242,11 +515860,11 @@
[]
],
"firefox_android.py": [
- "7bb2e57d417941bbb1710d6c11b8412f45d6fa7d",
+ "d0cd7411af0e29a14a3d2e7dfb955988f8a875f1",
[]
],
"headless_shell.py": [
- "b6f7a40f8a92c347add74a5f69f9996107df46cc",
+ "ccd5620365a03a2a6543087f6046086f1cc7a52c",
[]
],
"ladybird.py": [
@@ -515272,11 +515890,11 @@
]
},
"servo.py": [
- "266aec8fced6eb4cc5ca12a15cb8d938220e65ed",
+ "49a2613ff12ba4f3b085549a31266a21861bbaf1",
[]
],
"servodriver.py": [
- "5011a8fd8592d32af1a8313dd4ba6535a9cc384a",
+ "a8aa5ae001b1ecd53a7f2f4515efa299c9ce8809",
[]
],
"webkit.py": [
@@ -515322,7 +515940,7 @@
[]
],
"executorchrome.py": [
- "1e588d5bfbfd26334fbcf980e0fe8f0bea804f87",
+ "3284e6c8091b7c17ebe6fe158ba4ff09afb628da",
[]
],
"executoredge.py": [
@@ -515497,7 +516115,7 @@
[]
],
"testrunner.py": [
- "19c814bb6c94fb11ddd2b132cf5d156e58956c7b",
+ "be310944fd878b4bcf74e6f052e2a8cc99d3e157",
[]
],
"tests": {
@@ -516192,7 +516810,7 @@
],
"resources": {
"block-text-node-insertion.js": [
- "e9797756417e1c2a42158edab6bb25b37e7d518a",
+ "dd85483a44fa4df26a2f890f06416b6ab5babca8",
[]
]
},
@@ -516571,6 +517189,10 @@
"META.yml": [
"c994748e0f27bcc75019ad7a20816ee138d15f91",
[]
+ ],
+ "WEB_FEATURES.yml": [
+ "2d331cf4060d293c912f564e28b8fff089cfeb09",
+ []
]
},
"uievents": {
@@ -517255,6 +517877,10 @@
"b92b53ee45cd98933a3c2fbcf404478eb8f66a06",
[]
],
+ "urlpattern-generate-test-data.json": [
+ "c118f0a73b5fe108ab1a1f39d41148648daa7baa",
+ []
+ ],
"urlpattern-hasregexpgroups-tests.js": [
"4be886e4a5390d7d43356d853cc00c7bbb23d361",
[]
@@ -524436,6 +525062,10 @@
"58ee7cca1ab3e9856e380eaccde042d5700c2603",
[]
],
+ "WEB_FEATURES.yml": [
+ "1687ef742e2b51872debc6da074022449c2215df",
+ []
+ ],
"Worker-creation-happens-in-parallel.https.html.headers": [
"4b06ac7cc63e8af6f7d6a882b960184c9a4ea281",
[]
@@ -525631,6 +526261,14 @@
"b73781244ebd3fcad445f0227e33411ac08a5205",
[]
]
+ },
+ "tentative": {
+ "resources": {
+ "shared-worker-memory.js": [
+ "b1504f38c504c0003d2aa179cfae5702ab318563",
+ []
+ ]
+ }
}
},
"worklets": {
@@ -568178,6 +568816,13 @@
{}
]
],
+ "containertiming-with-child-ignore-and-child-img.html": [
+ "b4fa9754c1025e255a678d298d3c3db1c30c2b4c",
+ [
+ null,
+ {}
+ ]
+ ],
"containertiming-with-child-img.html": [
"03f0e113902d0d4117a38870dfd22defe99c4653",
[
@@ -568192,6 +568837,20 @@
{}
]
],
+ "containertiming-with-ignore-and-child-img.html": [
+ "20e9e4a92180d36c3a4130139330ea3229227105",
+ [
+ null,
+ {}
+ ]
+ ],
+ "ignore-with-containertiming-and-child-img.html": [
+ "841b4441d4df846317c246a461022cffe875fab3",
+ [
+ null,
+ {}
+ ]
+ ],
"img-not-child-of-container-timing.html": [
"751342a7ceb1eaa2a98d1c07dc4000c34d14e4fd",
[
@@ -568648,7 +569307,7 @@
]
],
"default-src-sri_hash.sub.html": [
- "87fce5961fd1854303377ee939b21b6275b312cf",
+ "87389c306a53fdffa9806ba05f08a097713bcc37",
[
null,
{}
@@ -573246,7 +573905,7 @@
]
],
"script-src-sri_hash.sub.html": [
- "9216e2b0d4971fc46d0010e8dfa7375845187a8d",
+ "e290911183d0b9a5dccf4a6a2eaa3b12ee25c682",
[
null,
{}
@@ -573351,7 +574010,7 @@
]
],
"script-src-strict_dynamic_parser_inserted.html": [
- "c5e33dc4253dbf3ce2b0c6cb2fca4b0306d68244",
+ "9a8ad7a4ef2b5592af70d4dcc56f291e75da8e1b",
[
null,
{}
@@ -575838,7 +576497,7 @@
]
],
"cookieStore_special_names.https.any.js": [
- "e2a3df7fe33f3d4325cb1f602d5582dba97da627",
+ "1e12674a7f7ce9b1fbc5aa46e53be9c6bc08c084",
[
"cookie-store/cookieStore_special_names.https.any.html",
{
@@ -575926,7 +576585,7 @@
]
],
"encoding.https.any.js": [
- "941639bdaec01d0eb619a5850b1d878bdf77f695",
+ "f5d2ca15e717a0837f1e08031ab682db5aa965ea",
[
"cookie-store/encoding.https.any.html",
{
@@ -575967,7 +576626,7 @@
]
],
"httponly_cookies.https.window.js": [
- "605e94e67440aaedbcaa39f185270fe77b316ad3",
+ "836f47da3f6e0f8f2c89445d1b2fbdfdf9ddc9e6",
[
"cookie-store/httponly_cookies.https.window.html",
{
@@ -579951,7 +580610,7 @@
]
],
"anchor-scope-basic.html": [
- "47cb3b8d86a106f37af3e32149b79fbd9c8c2056",
+ "ffe3b45ba0de4d119576bc8b2d307ed55c9ea7f0",
[
null,
{}
@@ -585012,7 +585671,7 @@
]
],
"parsing.html": [
- "2447891f2c4b163cc30eaaa2c6542d9a80a2b4cf",
+ "688043039de4c9a3d9ee58480a3185509ce72814",
[
null,
{}
@@ -586103,6 +586762,13 @@
{}
]
],
+ "style-query-registered-custom-rem-change.html": [
+ "33808fbe198935daf3ad4efc769483cfbc625c8e",
+ [
+ null,
+ {}
+ ]
+ ],
"style-query-unset-on-root.html": [
"89c5cc038a8f1fcee5f0fd0de116c679c666788b",
[
@@ -595126,8 +595792,15 @@
{}
]
],
+ "HighlightRegistry-highlightsFromPoint-ranges.html": [
+ "24cf8aa6dfec302877e445ebf81dca76357cea06",
+ [
+ null,
+ {}
+ ]
+ ],
"HighlightRegistry-highlightsFromPoint.html": [
- "5bb81bea69ac5960db16e3f9ec3bb208f43a7200",
+ "5b4e7704a4df5c01d3effa1c519e39b450bbe30a",
[
null,
{}
@@ -596807,7 +597480,7 @@
]
],
"clip-path-interpolation-shape.html": [
- "6d85c2a06b491bbc54e7cfba6705fd9b6af2098f",
+ "f725e1fc6fa0cbde5928c1e45e5e7c5f72b1a7dd",
[
null,
{}
@@ -597020,7 +597693,7 @@
]
],
"clip-path-shape-parsing.html": [
- "5a4c7415bb40632989c87ee1fbe51540f94af8e2",
+ "b889ee018056c5db7611cc70de823482ed5cac36",
[
null,
{}
@@ -597895,7 +598568,7 @@
]
],
"column-rule-color-invalid.html": [
- "015defb7560038b03fc4d5f18a04a1d0e094a03d",
+ "da8dba0a73c9c7829766cd2fad39bfa79fbc6c40",
[
null,
{}
@@ -597937,7 +598610,7 @@
]
],
"column-rule-style-invalid.html": [
- "db367c273f4f2e4bb59893d56388f119cb90ea40",
+ "e8f2ab60c47748c4a8088024bbcf30eb2c9c16b2",
[
null,
{}
@@ -597965,7 +598638,7 @@
]
],
"column-rule-width-invalid.html": [
- "0bdbbecb8cada68b8243566b265029ee98c55571",
+ "77f55e09d931cf91618cc7be5a9a9f46c85960dc",
[
null,
{}
@@ -605455,6 +606128,13 @@
null,
{}
]
+ ],
+ "from-element.tentative.html": [
+ "fe99ccb23d9c279011e15f66cbbe20cd87e31568",
+ [
+ null,
+ {}
+ ]
]
}
},
@@ -612667,14 +613347,14 @@
]
],
"column-rule-style.html": [
- "8e56f62171485661197a617bfe688e4f4e922569",
+ "7098270a3921df847c907842cd7b64cea43d261b",
[
null,
{}
]
],
"column-rule-width.html": [
- "bd3c0ac8f43d1770d04e46913066c6feddee8a08",
+ "8f09d1cb45aa55c8677810a5911160609514372e",
[
null,
{}
@@ -615461,7 +616141,7 @@
]
],
"if-conditionals.html": [
- "caead7864d550f8732eff919c1b555c8f759508d",
+ "f6d981798ae7a03f97b4fd089ee02141c7f90813",
[
null,
{}
@@ -615925,6 +616605,13 @@
{}
]
],
+ "sibling-function-container-query-invalidation.html": [
+ "c0d6d913af049d6d316ab664e0d93556bff01e7c",
+ [
+ null,
+ {}
+ ]
+ ],
"sibling-function-container-query.html": [
"addcf0b2d48f5c444a9f93264a2136342c4b48d6",
[
@@ -615982,7 +616669,7 @@
]
],
"sibling-index-keyframe-registered-properties-dynamic.html": [
- "77af5434a1c4903928194bec4174745a3bd1efeb",
+ "ac2ed1a8af1b1cddbae8ce18f7afaa7897466a67",
[
null,
{}
@@ -616521,7 +617208,7 @@
},
"css-view-transitions": {
"auto-name-get-animations.html": [
- "0442255542c0349438ef7e951da7c6b47928c858",
+ "b684349a5f9caf390d0a376727dda85602104f28",
[
null,
{}
@@ -617243,6 +617930,13 @@
]
],
"zoom": {
+ "length-implicit-and-explicit-inheritance.html": [
+ "003c7b61c0909f494f02a68e20fad2c152b96a34",
+ [
+ null,
+ {}
+ ]
+ ],
"parsing": {
"zoom-computed-with-sign-expression.html": [
"8029fd3a65e542749792a48100161f18fd25fee9",
@@ -621223,7 +621917,7 @@
]
],
"offset-path-interpolation-008.html": [
- "5fb7c7c333c89f4107e2824390c73862be8107d0",
+ "ff7d4a108c77f65363d91d9e4bc52eed500913c1",
[
null,
{}
@@ -621365,14 +622059,14 @@
]
],
"offset-path-shape-computed.html": [
- "c9ecc3acb06c065913f8b7538fdf81bff6c802df",
+ "6ced1ad395ad46206bf63da5ec871d5481185312",
[
null,
{}
]
],
"offset-path-shape-parsing.html": [
- "013cea2c8211d97a5e90c42379cf5aadfe8b59fd",
+ "4a3d9f169151c3d9a9f7f997410405ad36de2410",
[
null,
{}
@@ -630517,6 +631211,13 @@
{}
]
],
+ "fn-id.html": [
+ "617ff7216d84d56f8cef3f8ca08e902dd67f487d",
+ [
+ null,
+ {}
+ ]
+ ],
"fn-lang.html": [
"1fbd0a2ee4d419275c6d78f54e3425135cf838a1",
[
@@ -633824,13 +634525,6 @@
}
]
],
- "move-inserted-node-from-DOMNodeInserted-during-exec-command-insertHTML.html": [
- "41e012a62e9617f372f85d0a0cedefe8ad42fbd6",
- [
- null,
- {}
- ]
- ],
"no-beforeinput-when-no-selection.html": [
"098a95863a606393502d4e2fc517fcb8ad144d35",
[
@@ -661675,7 +662369,7 @@
"content-encoding": {
"br": {
"bad-br-body.https.any.js": [
- "43ea90a336cd04df56b4f29f57182d2860481938",
+ "af5df674da6dcf957d0c5fb69d3538a12096c005",
[
"fetch/content-encoding/br/bad-br-body.https.any.html",
{
@@ -661799,7 +662493,7 @@
},
"gzip": {
"bad-gzip-body.any.js": [
- "17bc1261a3f5c36a9797c5a171990c522cfe7598",
+ "77a183f408b34c75eb3d3e0a1635daad79ff1355",
[
"fetch/content-encoding/gzip/bad-gzip-body.any.html",
{
@@ -661956,7 +662650,7 @@
},
"zstd": {
"bad-zstd-body.https.any.js": [
- "3f32e4dfba786511d845c3e913e59b818d0f292b",
+ "c59980c2c6fb694080417cdd6db1b237f70715b2",
[
"fetch/content-encoding/zstd/bad-zstd-body.https.any.html",
{
@@ -667031,29 +667725,6 @@
}
]
],
- "mixed-content-fetch.tentative.https.window.js": [
- "dbae5193b5cb02e3b0eba3531483aac372ba8700",
- [
- "fetch/private-network-access/mixed-content-fetch.tentative.https.window.html",
- {
- "script_metadata": [
- [
- "script",
- "/common/utils.js"
- ],
- [
- "script",
- "resources/support.sub.js"
- ],
- [
- "timeout",
- "long"
- ]
- ],
- "timeout": "long"
- }
- ]
- ],
"nested-worker.tentative.https.window.js": [
"3eeb435badb2d00404e0e214e1d42c4be2817f8a",
[
@@ -667414,185 +668085,6 @@
}
]
],
- "window-open-existing.tentative.https.window.js": [
- "6a2a624fc8032d03b626109ee7f825f7acf5874c",
- [
- "fetch/private-network-access/window-open-existing.tentative.https.window.html?include=from-local",
- {
- "script_metadata": [
- [
- "script",
- "/common/subset-tests-by-key.js"
- ],
- [
- "script",
- "/common/dispatcher/dispatcher.js"
- ],
- [
- "script",
- "/common/utils.js"
- ],
- [
- "script",
- "resources/support.sub.js"
- ],
- [
- "timeout",
- "long"
- ],
- [
- "variant",
- "?include=from-local"
- ],
- [
- "variant",
- "?include=from-private"
- ],
- [
- "variant",
- "?include=from-public"
- ],
- [
- "variant",
- "?include=from-treat-as-public"
- ]
- ],
- "timeout": "long"
- }
- ],
- [
- "fetch/private-network-access/window-open-existing.tentative.https.window.html?include=from-private",
- {
- "script_metadata": [
- [
- "script",
- "/common/subset-tests-by-key.js"
- ],
- [
- "script",
- "/common/dispatcher/dispatcher.js"
- ],
- [
- "script",
- "/common/utils.js"
- ],
- [
- "script",
- "resources/support.sub.js"
- ],
- [
- "timeout",
- "long"
- ],
- [
- "variant",
- "?include=from-local"
- ],
- [
- "variant",
- "?include=from-private"
- ],
- [
- "variant",
- "?include=from-public"
- ],
- [
- "variant",
- "?include=from-treat-as-public"
- ]
- ],
- "timeout": "long"
- }
- ],
- [
- "fetch/private-network-access/window-open-existing.tentative.https.window.html?include=from-public",
- {
- "script_metadata": [
- [
- "script",
- "/common/subset-tests-by-key.js"
- ],
- [
- "script",
- "/common/dispatcher/dispatcher.js"
- ],
- [
- "script",
- "/common/utils.js"
- ],
- [
- "script",
- "resources/support.sub.js"
- ],
- [
- "timeout",
- "long"
- ],
- [
- "variant",
- "?include=from-local"
- ],
- [
- "variant",
- "?include=from-private"
- ],
- [
- "variant",
- "?include=from-public"
- ],
- [
- "variant",
- "?include=from-treat-as-public"
- ]
- ],
- "timeout": "long"
- }
- ],
- [
- "fetch/private-network-access/window-open-existing.tentative.https.window.html?include=from-treat-as-public",
- {
- "script_metadata": [
- [
- "script",
- "/common/subset-tests-by-key.js"
- ],
- [
- "script",
- "/common/dispatcher/dispatcher.js"
- ],
- [
- "script",
- "/common/utils.js"
- ],
- [
- "script",
- "resources/support.sub.js"
- ],
- [
- "timeout",
- "long"
- ],
- [
- "variant",
- "?include=from-local"
- ],
- [
- "variant",
- "?include=from-private"
- ],
- [
- "variant",
- "?include=from-public"
- ],
- [
- "variant",
- "?include=from-treat-as-public"
- ]
- ],
- "timeout": "long"
- }
- ]
- ],
"window-open-existing.tentative.window.js": [
"5a6cd4c5cfd20c931a37c4f98524a4a59c0d07c9",
[
@@ -683042,6 +683534,13 @@
{}
]
],
+ "focus-contenteditable-element-in-iframe-scroll-into-view.html": [
+ "1c03382201eb05785a003d068bf0e14150e10608",
+ [
+ null,
+ {}
+ ]
+ ],
"focus-double-sync-calls.html": [
"8d5f5c8a79fc6c65556e151fed9610a9cb915f98",
[
@@ -733174,7 +733673,7 @@
]
],
"image-decode-path-changes-svg.tentative.html": [
- "1bc53a1f18e56fbd2f586b91cf78e00c846eecbb",
+ "3ef59c37a8500f64bc60011174560f4aca0bea5d",
[
null,
{
@@ -733210,7 +733709,7 @@
]
],
"image-decode-with-quick-attach-svg.tentative.html": [
- "0fc49e603606e9233d0b3ae59757aec149c8aaf2",
+ "fbc7143eceead959bc34270b55ad850044215ece",
[
null,
{
@@ -733590,7 +734089,7 @@
]
],
"naturalWidth-naturalHeight-unavailable.tentative.html": [
- "df9eb374b5adc003c93830ab4605b2adad0ae84d",
+ "ae6fa0e432853d111aa63bd87f43206acec86024",
[
null,
{}
@@ -738083,8 +738582,8 @@
}
]
],
- "negative-offset-and-margin.tentative.html": [
- "0b3d8dc98812e01e7255cc166fa0bc0704f0eac4",
+ "negative-offset.tentative.html": [
+ "c1424ad9cc80e27fac9f0693defd87dd273ad2e2",
[
null,
{}
@@ -738098,7 +738597,7 @@
]
],
"no-focus.tentative.html": [
- "9646788518323b331ac7278dd0afb754392ef6be",
+ "1bf29634605cc55210fef4a04cfaaa2c436fcd09",
[
null,
{
@@ -739157,34 +739656,6 @@
{}
]
],
- "042.html": [
- "df3a2f88f29f2e8035d8c778c3397ad464688e18",
- [
- null,
- {}
- ]
- ],
- "043.html": [
- "bcfd90cba47880efa48f9e809f37209f5f024dd6",
- [
- null,
- {}
- ]
- ],
- "044.html": [
- "8d412079e45f9f8a3d074d707db39a55e1d8b946",
- [
- null,
- {}
- ]
- ],
- "045.html": [
- "254e0d13662786d8542d03de3547b39ecf684ede",
- [
- null,
- {}
- ]
- ],
"046.html": [
"4f145d63e1d619df2df429ec6fd713e77e303cb3",
[
@@ -739243,20 +739714,6 @@
{}
]
],
- "054.html": [
- "29ede23414ec57950717a05e375cbc15547c0b4d",
- [
- null,
- {}
- ]
- ],
- "055.html": [
- "c837d78174b108d8b90cca4dccbc91bef8e1efad",
- [
- null,
- {}
- ]
- ],
"056.html": [
"e2d0868034e1b243e610b3e3afdea18d78c418c8",
[
@@ -740212,7 +740669,7 @@
]
],
"invalid-content-type.any.js": [
- "d15fa3f1b7090dc0e309097c497dcd3626301c31",
+ "d0bb6aa9fb17fe49d85bef83486edf4148ac970d",
[
"html/semantics/scripting-1/the-script-element/json-module/invalid-content-type.any.html",
{
@@ -740381,7 +740838,7 @@
]
],
"valid-content-type.html": [
- "3232b84d271e0faa49fd600eac9f4394db7f5630",
+ "fdeba93ba893176df88fe69f54606b4d01020436",
[
null,
{}
@@ -743333,6 +743790,13 @@
"timeout": "long"
}
]
+ ],
+ "source-attribute-retargeting.tentative.html": [
+ "885b75a3387a8f61f8f25fdd93d60fe3027b5599",
+ [
+ null,
+ {}
+ ]
]
},
"interest-target": {
@@ -771868,6 +772332,15 @@
}
]
],
+ "get-persistendeviceid-from-pointer-mouse-event.tentative.html": [
+ "66fb63d54d1acedc17e9a522eefebe0fba76f943",
+ [
+ null,
+ {
+ "testdriver": true
+ }
+ ]
+ ],
"pointer-event-has-persistentdeviceid-from-pointer-event-init.tentative.html": [
"c3fc4270f6177c94ccd191a29d86b77a220f3577",
[
@@ -787247,6 +787720,13 @@
null,
{}
]
+ ],
+ "zoom.html": [
+ "77b4bc49fa7e8e4d13083f8ef97ced833e627a85",
+ [
+ null,
+ {}
+ ]
]
},
"resource-timing": {
@@ -787418,7 +787898,7 @@
]
],
"content-encoding.https.html": [
- "0d67bfc7d4f9a9c471272a8a475655d1c5225552",
+ "80473552f08b0c5f857533bdebf7a168283d5953",
[
null,
{}
@@ -790732,7 +791212,7 @@
]
],
"animation-trigger-repeat.tentative.html": [
- "cfbe9d3c9334148789d4cebc7a01a2f9e848b22d",
+ "6c01e762e5acd18a1def36673c93d7fcdedf4964",
[
null,
{}
@@ -796663,7 +797143,7 @@
]
],
"HighlightRegistry-highlightsFromPoint.html": [
- "5244f923e3404064987ce16d0fd1e9215ad768c3",
+ "4098bc5a9941f23405d754e786351320e14125d6",
[
null,
{}
@@ -799849,7 +800329,7 @@
]
],
"first-interaction-not-softnav.tentative.html": [
- "e02620218368d71ff10196c9ff75a13a361f5d90",
+ "2c9e2aa7c014025ca409da94172d6e0d61d106d7",
[
null,
{
@@ -799893,15 +800373,6 @@
}
]
],
- "innertext.tentative.html": [
- "7716488f25a08ea62635fceec679d97650d1f383",
- [
- null,
- {
- "testdriver": true
- }
- ]
- ],
"interaction-with-paint-before-back.tentative.html": [
"effccbfd762434c84b672173b122b07272542fe5",
[
@@ -800095,7 +800566,7 @@
]
],
"dom.html": [
- "66d23b22788c4749d7b990b89b0cef612872f5f4",
+ "2e3c3809df68ba4093247e2d4e3fe114f8c9f729",
[
null,
{
@@ -800120,6 +800591,15 @@
"testdriver": true
}
]
+ ],
+ "window-open-cross-scheduling.html": [
+ "1a41be6ddd2d716c4012b5524e8a30b9821ec3e3",
+ [
+ null,
+ {
+ "testdriver": true
+ }
+ ]
]
}
},
@@ -800559,6 +801039,15 @@
{}
]
],
+ "no-prefetch-for-post.https.html": [
+ "7739f4f8c7105b2c4e9ed4671081b00d0c0b8c6e",
+ [
+ null,
+ {
+ "timeout": "long"
+ }
+ ]
+ ],
"no-vary-search": {
"prefetch-single-with-hint.https.html": [
"f2d8b3090e1f8447f86bd62a6f24ca9daae06ec7",
@@ -801551,6 +802040,15 @@
}
]
],
+ "headers.https.html": [
+ "2ef6b5ce072866d3c88ce7a86fcea6436de3364a",
+ [
+ null,
+ {
+ "timeout": "long"
+ }
+ ]
+ ],
"iframe-added-post-activation.https.html": [
"d22b511e108d8b7c7f0b63f28e5bf485eca98758",
[
@@ -821765,14 +822263,14 @@
]
],
"block-text-node-insertion-into-script-element.html": [
- "65b40b933ff8417ad5147ce29d68bc19707bc0b9",
+ "1a1256d05a8c996d078ca287950660fd5d1e9071",
[
null,
{}
]
],
"block-text-node-insertion-into-svg-script-element.html": [
- "f4ff24350355a29f033489d51bf4a021d9673dd2",
+ "18c6af8f5efcf72c11876b4f2740cdddd5cf1c84",
[
null,
{}
@@ -822768,13 +823266,6 @@
},
"legacy-domevents-tests": {
"approved": {
- "ProcessingInstruction.DOMCharacterDataModified.html": [
- "2da0a389e2e3bc51861fef752b11a629203897d0",
- [
- null,
- {}
- ]
- ],
"dispatchEvent.click.checkbox.html": [
"8cb548f84c60eb6b528c1049884649b26c4f18ba",
[
@@ -822782,13 +823273,6 @@
{}
]
],
- "domnodeinserted.html": [
- "e5064d8d46cd9aad4768aa81dacb18b989e2c993",
- [
- null,
- {}
- ]
- ],
"stopImmediatePropagation.effect.html": [
"a414d60298acece6dce5d970e6f0448a99fd65da",
[
@@ -826096,6 +826580,53 @@
}
]
],
+ "urlpattern-generate.tentative.any.js": [
+ "1f6962942d88f88684c5302175202e0278d3d971",
+ [
+ "urlpattern/urlpattern-generate.tentative.any.html",
+ {
+ "script_metadata": [
+ [
+ "global",
+ "window,worker"
+ ]
+ ]
+ }
+ ],
+ [
+ "urlpattern/urlpattern-generate.tentative.any.serviceworker.html",
+ {
+ "script_metadata": [
+ [
+ "global",
+ "window,worker"
+ ]
+ ]
+ }
+ ],
+ [
+ "urlpattern/urlpattern-generate.tentative.any.sharedworker.html",
+ {
+ "script_metadata": [
+ [
+ "global",
+ "window,worker"
+ ]
+ ]
+ }
+ ],
+ [
+ "urlpattern/urlpattern-generate.tentative.any.worker.html",
+ {
+ "script_metadata": [
+ [
+ "global",
+ "window,worker"
+ ]
+ ]
+ }
+ ]
+ ],
"urlpattern-hasregexpgroups.any.js": [
"33133d2511b065ca94cc5e793066cc8111b4d6e6",
[
@@ -855415,7 +855946,7 @@
]
],
"cumulative_sum.https.any.js": [
- "85e1ab427d208f76aae62bff8c603b0d891f7180",
+ "34a625152b26a3183a7cd62c38883a684ac93908",
[
"webnn/conformance_tests/cumulative_sum.https.any.html?cpu",
{
@@ -859171,7 +859702,7 @@
]
],
"linear.https.any.js": [
- "9231aaf9ecad0996b8dfb9530c4a7f55b2aa8e06",
+ "1f13fe170d46fa157035bd6e14de6eb68462c7a4",
[
"webnn/conformance_tests/linear.https.any.html?cpu",
{
@@ -861604,7 +862135,7 @@
]
],
"qdq_subgraph.https.any.js": [
- "ac384c917b33dda2243779a396d0d557c40003dc",
+ "996a6b472c5689bc082388d5c267d2f5fe460080",
[
"webnn/conformance_tests/qdq_subgraph.https.any.html?cpu",
{
@@ -865945,7 +866476,7 @@
]
],
"subgraph.https.any.js": [
- "9b21d6e4f9453fb72c3f7a6850c5690cc9ed87cf",
+ "8a0b7faa92f938282c7a6bb02ac61ef6730f021d",
[
"webnn/conformance_tests/subgraph.https.any.html?cpu",
{
@@ -882776,7 +883307,7 @@
]
],
"RTCConfiguration-iceServers.html": [
- "bc7831361ab5f417b46a507b0e5977bef9bedd49",
+ "65a6015f52a7233260ab8405fb43bc347fa0ff4b",
[
null,
{}
@@ -884735,7 +885266,7 @@
]
],
"RTCEncodedAudioFrame-metadata.https.html": [
- "df4577c5614a82afd7b02d988d0f15caa3b9e848",
+ "1e148fe1b29a167e6451162125b7390151ec90bd",
[
null,
{
@@ -897599,7 +898130,7 @@
]
],
"remote-close.any.js": [
- "b7fd321914a4e6f9bf70d431bca591a7c5460675",
+ "c3e7ad5f9fbef1494ed7594dc7d497e9f867361a",
[
"websockets/stream/tentative/remote-close.any.html?default",
{
@@ -898019,6 +898550,429 @@
]
}
]
+ ],
+ "write.any.js": [
+ "43af7da614c675fcc0571d7edff3515a92774caf",
+ [
+ "websockets/stream/tentative/write.any.html?default",
+ {
+ "script_metadata": [
+ [
+ "script",
+ "../../constants.sub.js"
+ ],
+ [
+ "script",
+ "resources/url-constants.js"
+ ],
+ [
+ "script",
+ "/common/gc.js"
+ ],
+ [
+ "global",
+ "window,worker"
+ ],
+ [
+ "variant",
+ "?default"
+ ],
+ [
+ "variant",
+ "?wss"
+ ],
+ [
+ "variant",
+ "?wpt_flags=h2"
+ ]
+ ]
+ }
+ ],
+ [
+ "websockets/stream/tentative/write.any.html?wpt_flags=h2",
+ {
+ "script_metadata": [
+ [
+ "script",
+ "../../constants.sub.js"
+ ],
+ [
+ "script",
+ "resources/url-constants.js"
+ ],
+ [
+ "script",
+ "/common/gc.js"
+ ],
+ [
+ "global",
+ "window,worker"
+ ],
+ [
+ "variant",
+ "?default"
+ ],
+ [
+ "variant",
+ "?wss"
+ ],
+ [
+ "variant",
+ "?wpt_flags=h2"
+ ]
+ ]
+ }
+ ],
+ [
+ "websockets/stream/tentative/write.any.html?wss",
+ {
+ "script_metadata": [
+ [
+ "script",
+ "../../constants.sub.js"
+ ],
+ [
+ "script",
+ "resources/url-constants.js"
+ ],
+ [
+ "script",
+ "/common/gc.js"
+ ],
+ [
+ "global",
+ "window,worker"
+ ],
+ [
+ "variant",
+ "?default"
+ ],
+ [
+ "variant",
+ "?wss"
+ ],
+ [
+ "variant",
+ "?wpt_flags=h2"
+ ]
+ ]
+ }
+ ],
+ [
+ "websockets/stream/tentative/write.any.serviceworker.html?default",
+ {
+ "script_metadata": [
+ [
+ "script",
+ "../../constants.sub.js"
+ ],
+ [
+ "script",
+ "resources/url-constants.js"
+ ],
+ [
+ "script",
+ "/common/gc.js"
+ ],
+ [
+ "global",
+ "window,worker"
+ ],
+ [
+ "variant",
+ "?default"
+ ],
+ [
+ "variant",
+ "?wss"
+ ],
+ [
+ "variant",
+ "?wpt_flags=h2"
+ ]
+ ]
+ }
+ ],
+ [
+ "websockets/stream/tentative/write.any.serviceworker.html?wpt_flags=h2",
+ {
+ "script_metadata": [
+ [
+ "script",
+ "../../constants.sub.js"
+ ],
+ [
+ "script",
+ "resources/url-constants.js"
+ ],
+ [
+ "script",
+ "/common/gc.js"
+ ],
+ [
+ "global",
+ "window,worker"
+ ],
+ [
+ "variant",
+ "?default"
+ ],
+ [
+ "variant",
+ "?wss"
+ ],
+ [
+ "variant",
+ "?wpt_flags=h2"
+ ]
+ ]
+ }
+ ],
+ [
+ "websockets/stream/tentative/write.any.serviceworker.html?wss",
+ {
+ "script_metadata": [
+ [
+ "script",
+ "../../constants.sub.js"
+ ],
+ [
+ "script",
+ "resources/url-constants.js"
+ ],
+ [
+ "script",
+ "/common/gc.js"
+ ],
+ [
+ "global",
+ "window,worker"
+ ],
+ [
+ "variant",
+ "?default"
+ ],
+ [
+ "variant",
+ "?wss"
+ ],
+ [
+ "variant",
+ "?wpt_flags=h2"
+ ]
+ ]
+ }
+ ],
+ [
+ "websockets/stream/tentative/write.any.sharedworker.html?default",
+ {
+ "script_metadata": [
+ [
+ "script",
+ "../../constants.sub.js"
+ ],
+ [
+ "script",
+ "resources/url-constants.js"
+ ],
+ [
+ "script",
+ "/common/gc.js"
+ ],
+ [
+ "global",
+ "window,worker"
+ ],
+ [
+ "variant",
+ "?default"
+ ],
+ [
+ "variant",
+ "?wss"
+ ],
+ [
+ "variant",
+ "?wpt_flags=h2"
+ ]
+ ]
+ }
+ ],
+ [
+ "websockets/stream/tentative/write.any.sharedworker.html?wpt_flags=h2",
+ {
+ "script_metadata": [
+ [
+ "script",
+ "../../constants.sub.js"
+ ],
+ [
+ "script",
+ "resources/url-constants.js"
+ ],
+ [
+ "script",
+ "/common/gc.js"
+ ],
+ [
+ "global",
+ "window,worker"
+ ],
+ [
+ "variant",
+ "?default"
+ ],
+ [
+ "variant",
+ "?wss"
+ ],
+ [
+ "variant",
+ "?wpt_flags=h2"
+ ]
+ ]
+ }
+ ],
+ [
+ "websockets/stream/tentative/write.any.sharedworker.html?wss",
+ {
+ "script_metadata": [
+ [
+ "script",
+ "../../constants.sub.js"
+ ],
+ [
+ "script",
+ "resources/url-constants.js"
+ ],
+ [
+ "script",
+ "/common/gc.js"
+ ],
+ [
+ "global",
+ "window,worker"
+ ],
+ [
+ "variant",
+ "?default"
+ ],
+ [
+ "variant",
+ "?wss"
+ ],
+ [
+ "variant",
+ "?wpt_flags=h2"
+ ]
+ ]
+ }
+ ],
+ [
+ "websockets/stream/tentative/write.any.worker.html?default",
+ {
+ "script_metadata": [
+ [
+ "script",
+ "../../constants.sub.js"
+ ],
+ [
+ "script",
+ "resources/url-constants.js"
+ ],
+ [
+ "script",
+ "/common/gc.js"
+ ],
+ [
+ "global",
+ "window,worker"
+ ],
+ [
+ "variant",
+ "?default"
+ ],
+ [
+ "variant",
+ "?wss"
+ ],
+ [
+ "variant",
+ "?wpt_flags=h2"
+ ]
+ ]
+ }
+ ],
+ [
+ "websockets/stream/tentative/write.any.worker.html?wpt_flags=h2",
+ {
+ "script_metadata": [
+ [
+ "script",
+ "../../constants.sub.js"
+ ],
+ [
+ "script",
+ "resources/url-constants.js"
+ ],
+ [
+ "script",
+ "/common/gc.js"
+ ],
+ [
+ "global",
+ "window,worker"
+ ],
+ [
+ "variant",
+ "?default"
+ ],
+ [
+ "variant",
+ "?wss"
+ ],
+ [
+ "variant",
+ "?wpt_flags=h2"
+ ]
+ ]
+ }
+ ],
+ [
+ "websockets/stream/tentative/write.any.worker.html?wss",
+ {
+ "script_metadata": [
+ [
+ "script",
+ "../../constants.sub.js"
+ ],
+ [
+ "script",
+ "resources/url-constants.js"
+ ],
+ [
+ "script",
+ "/common/gc.js"
+ ],
+ [
+ "global",
+ "window,worker"
+ ],
+ [
+ "variant",
+ "?default"
+ ],
+ [
+ "variant",
+ "?wss"
+ ],
+ [
+ "variant",
+ "?wpt_flags=h2"
+ ]
+ ]
+ }
+ ]
]
}
},
@@ -905196,6 +906150,15 @@
{}
]
],
+ "tentative": {
+ "SharedWorker-extendedLifetime.html": [
+ "3c76eddd7647991ae171b4d5e4766af5d156dd9a",
+ [
+ null,
+ {}
+ ]
+ ]
+ },
"worker-performance.worker.js": [
"c913b2e7375067c1a21bdc655f394b5c27bc5aed",
[
diff --git a/tests/wpt/meta/content-security-policy/connect-src/connect-src-syncxmlhttprequest-redirect-to-blocked.sub.html.ini b/tests/wpt/meta/content-security-policy/connect-src/connect-src-syncxmlhttprequest-redirect-to-blocked.sub.html.ini
deleted file mode 100644
index e6156eab928..00000000000
--- a/tests/wpt/meta/content-security-policy/connect-src/connect-src-syncxmlhttprequest-redirect-to-blocked.sub.html.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[connect-src-syncxmlhttprequest-redirect-to-blocked.sub.html]
- [Expecting logs: ["PASS Sync XMLHttpRequest.send() did not follow the disallowed redirect.","TEST COMPLETE","violated-directive=connect-src"\]]
- expected: FAIL
diff --git a/tests/wpt/meta/content-security-policy/connect-src/connect-src-xmlhttprequest-redirect-to-blocked.sub.html.ini b/tests/wpt/meta/content-security-policy/connect-src/connect-src-xmlhttprequest-redirect-to-blocked.sub.html.ini
deleted file mode 100644
index 9b86b6b2d9c..00000000000
--- a/tests/wpt/meta/content-security-policy/connect-src/connect-src-xmlhttprequest-redirect-to-blocked.sub.html.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[connect-src-xmlhttprequest-redirect-to-blocked.sub.html]
- [Expecting logs: ["PASS XMLHttpRequest.send() did not follow the disallowed redirect.","TEST COMPLETE","violated-directive=connect-src"\]]
- expected: FAIL
diff --git a/tests/wpt/meta/content-security-policy/gen/top.http-rp/script-src-self/script-tag.http.html.ini b/tests/wpt/meta/content-security-policy/gen/top.http-rp/script-src-self/script-tag.http.html.ini
index 5891a18681e..0c6a81792db 100644
--- a/tests/wpt/meta/content-security-policy/gen/top.http-rp/script-src-self/script-tag.http.html.ini
+++ b/tests/wpt/meta/content-security-policy/gen/top.http-rp/script-src-self/script-tag.http.html.ini
@@ -1,6 +1,3 @@
[script-tag.http.html]
[Content Security Policy: Expects blocked for script-tag to same-http origin and swap-origin redirection from http context.]
expected: FAIL
-
- [Content Security Policy: Expects blocked for script-tag to same-http origin and swap-origin redirection from http context.: securitypolicyviolation]
- expected: FAIL
diff --git a/tests/wpt/meta/content-security-policy/gen/top.http-rp/script-src-self/script-tag.https.html.ini b/tests/wpt/meta/content-security-policy/gen/top.http-rp/script-src-self/script-tag.https.html.ini
index 699a0dd6238..b5c643337e2 100644
--- a/tests/wpt/meta/content-security-policy/gen/top.http-rp/script-src-self/script-tag.https.html.ini
+++ b/tests/wpt/meta/content-security-policy/gen/top.http-rp/script-src-self/script-tag.https.html.ini
@@ -1,6 +1,3 @@
[script-tag.https.html]
[Content Security Policy: Expects blocked for script-tag to same-https origin and swap-origin redirection from https context.]
expected: FAIL
-
- [Content Security Policy: Expects blocked for script-tag to same-https origin and swap-origin redirection from https context.: securitypolicyviolation]
- expected: FAIL
diff --git a/tests/wpt/meta/content-security-policy/gen/top.meta/script-src-self/script-tag.http.html.ini b/tests/wpt/meta/content-security-policy/gen/top.meta/script-src-self/script-tag.http.html.ini
index 5891a18681e..0c6a81792db 100644
--- a/tests/wpt/meta/content-security-policy/gen/top.meta/script-src-self/script-tag.http.html.ini
+++ b/tests/wpt/meta/content-security-policy/gen/top.meta/script-src-self/script-tag.http.html.ini
@@ -1,6 +1,3 @@
[script-tag.http.html]
[Content Security Policy: Expects blocked for script-tag to same-http origin and swap-origin redirection from http context.]
expected: FAIL
-
- [Content Security Policy: Expects blocked for script-tag to same-http origin and swap-origin redirection from http context.: securitypolicyviolation]
- expected: FAIL
diff --git a/tests/wpt/meta/content-security-policy/gen/top.meta/script-src-self/script-tag.https.html.ini b/tests/wpt/meta/content-security-policy/gen/top.meta/script-src-self/script-tag.https.html.ini
index 699a0dd6238..b5c643337e2 100644
--- a/tests/wpt/meta/content-security-policy/gen/top.meta/script-src-self/script-tag.https.html.ini
+++ b/tests/wpt/meta/content-security-policy/gen/top.meta/script-src-self/script-tag.https.html.ini
@@ -1,6 +1,3 @@
[script-tag.https.html]
[Content Security Policy: Expects blocked for script-tag to same-https origin and swap-origin redirection from https context.]
expected: FAIL
-
- [Content Security Policy: Expects blocked for script-tag to same-https origin and swap-origin redirection from https context.: securitypolicyviolation]
- expected: FAIL
diff --git a/tests/wpt/meta/content-security-policy/generic/wildcard-host-part.sub.window.js.ini b/tests/wpt/meta/content-security-policy/generic/wildcard-host-part.sub.window.js.ini
deleted file mode 100644
index 7770d4e4454..00000000000
--- a/tests/wpt/meta/content-security-policy/generic/wildcard-host-part.sub.window.js.ini
+++ /dev/null
@@ -1,2 +0,0 @@
-[wildcard-host-part.sub.window.html]
- expected: CRASH
diff --git a/tests/wpt/meta/content-security-policy/inside-worker/dedicatedworker-connect-src.html.ini b/tests/wpt/meta/content-security-policy/inside-worker/dedicatedworker-connect-src.html.ini
index ad01d630c28..72db221f4dd 100644
--- a/tests/wpt/meta/content-security-policy/inside-worker/dedicatedworker-connect-src.html.ini
+++ b/tests/wpt/meta/content-security-policy/inside-worker/dedicatedworker-connect-src.html.ini
@@ -1,7 +1,4 @@
[dedicatedworker-connect-src.html]
- [Same-origin => cross-origin 'fetch()' in http: with connect-src 'self']
- expected: FAIL
-
[Reports match in http: with connect-src 'self']
expected: FAIL
diff --git a/tests/wpt/meta/content-security-policy/reporting/report-original-url.sub.html.ini b/tests/wpt/meta/content-security-policy/reporting/report-original-url.sub.html.ini
index 66a2ee93f3b..f160ad3d25d 100644
--- a/tests/wpt/meta/content-security-policy/reporting/report-original-url.sub.html.ini
+++ b/tests/wpt/meta/content-security-policy/reporting/report-original-url.sub.html.ini
@@ -1,10 +1,3 @@
[report-original-url.sub.html]
- expected: TIMEOUT
- [Block after redirect, same-origin = original URL in report]
- expected: TIMEOUT
-
- [Block after redirect, cross-origin = original URL in report]
- expected: TIMEOUT
-
[Violation report status OK.]
expected: FAIL
diff --git a/tests/wpt/meta/content-security-policy/securitypolicyviolation/img-src-redirect.sub.html.ini b/tests/wpt/meta/content-security-policy/securitypolicyviolation/img-src-redirect.sub.html.ini
deleted file mode 100644
index 95cb135df4e..00000000000
--- a/tests/wpt/meta/content-security-policy/securitypolicyviolation/img-src-redirect.sub.html.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[img-src-redirect.sub.html]
- [The blocked URI in the security policy violation event should be the original URI before redirects.]
- expected: FAIL
diff --git a/tests/wpt/meta/css/css-borders/tentative/corner-shape/corner-shape-render-fuzzy.html.ini b/tests/wpt/meta/css/css-borders/tentative/corner-shape/corner-shape-render-fuzzy.html.ini
index 11dc161d87a..34de05fc1cc 100644
--- a/tests/wpt/meta/css/css-borders/tentative/corner-shape/corner-shape-render-fuzzy.html.ini
+++ b/tests/wpt/meta/css/css-borders/tentative/corner-shape/corner-shape-render-fuzzy.html.ini
@@ -78,3 +78,6 @@
[corner-shape-render-fuzzy.html?border-radius=50%&corner-top-right-shape=scoop&corner-bottom-left-shape=scoop&corner-top-left-shape=notch&corner-bottom-right-shape=notch&border-width=10px]
expected: FAIL
+
+[corner-shape-render-fuzzy.html?corner-shape=superellipse(0.8)&border-radius=40px&border-width=10px]
+ expected: FAIL
diff --git a/tests/wpt/meta/css/css-borders/tentative/corner-shape/corner-shape-render-precise.html.ini b/tests/wpt/meta/css/css-borders/tentative/corner-shape/corner-shape-render-precise.html.ini
index 68682a3e807..1fda8aa0448 100644
--- a/tests/wpt/meta/css/css-borders/tentative/corner-shape/corner-shape-render-precise.html.ini
+++ b/tests/wpt/meta/css/css-borders/tentative/corner-shape/corner-shape-render-precise.html.ini
@@ -37,9 +37,6 @@
[corner-shape-render-precise.html?corner-top-left-shape=bevel&border-width=10px&border-color=black]
expected: FAIL
-[corner-shape-render-precise.html?corner-bottom-right-shape=bevel&corner-bottom-left-shape=bevel]
- expected: FAIL
-
[corner-shape-render-precise.html?corner-shape=superellipse(8)&border-radius=10px&box-shadow=10px 10px 0 10px black]
expected: FAIL
@@ -90,3 +87,6 @@
[corner-shape-render-precise.html?corner-shape=superellipse(-2)&border-top-left-radius=40%&border-width=20px]
expected: FAIL
+
+[corner-shape-render-precise.html?corner-shape=notch&border-radius=30px&border-width=30px]
+ expected: FAIL
diff --git a/tests/wpt/meta/css/css-conditional/container-queries/style-query-registered-custom-rem-change.html.ini b/tests/wpt/meta/css/css-conditional/container-queries/style-query-registered-custom-rem-change.html.ini
new file mode 100644
index 00000000000..ee69bd41b83
--- /dev/null
+++ b/tests/wpt/meta/css/css-conditional/container-queries/style-query-registered-custom-rem-change.html.ini
@@ -0,0 +1,3 @@
+[style-query-registered-custom-rem-change.html]
+ [Changing the :root font-size to 10px makes 1rem * 10 evaluate to 100px]
+ expected: FAIL
diff --git a/tests/wpt/meta/css/css-gaps/grid/grid-gap-decorations-040.html.ini b/tests/wpt/meta/css/css-gaps/grid/grid-gap-decorations-040.html.ini
new file mode 100644
index 00000000000..961df8f5b9b
--- /dev/null
+++ b/tests/wpt/meta/css/css-gaps/grid/grid-gap-decorations-040.html.ini
@@ -0,0 +1,2 @@
+[grid-gap-decorations-040.html]
+ expected: FAIL
diff --git a/tests/wpt/meta/css/css-masking/clip-path/clip-path-shape-011.html.ini b/tests/wpt/meta/css/css-masking/clip-path/clip-path-shape-011.html.ini
new file mode 100644
index 00000000000..7598b3ef8ec
--- /dev/null
+++ b/tests/wpt/meta/css/css-masking/clip-path/clip-path-shape-011.html.ini
@@ -0,0 +1,2 @@
+[clip-path-shape-011.html]
+ expected: FAIL
diff --git a/tests/wpt/meta/css/css-overflow/overflow-video.html.ini b/tests/wpt/meta/css/css-overflow/overflow-video.html.ini
deleted file mode 100644
index 1d0a9d754d6..00000000000
--- a/tests/wpt/meta/css/css-overflow/overflow-video.html.ini
+++ /dev/null
@@ -1,2 +0,0 @@
-[overflow-video.html]
- expected: FAIL
diff --git a/tests/wpt/meta/css/css-sizing/responsive-iframe-cross-origin.sub.tentative.html.ini b/tests/wpt/meta/css/css-sizing/responsive-iframe-cross-origin.sub.tentative.html.ini
new file mode 100644
index 00000000000..9682a816732
--- /dev/null
+++ b/tests/wpt/meta/css/css-sizing/responsive-iframe-cross-origin.sub.tentative.html.ini
@@ -0,0 +1,2 @@
+[responsive-iframe-cross-origin.sub.tentative.html]
+ expected: FAIL
diff --git a/tests/wpt/meta/css/css-sizing/responsive-iframe.tentative.html.ini b/tests/wpt/meta/css/css-sizing/responsive-iframe.tentative.html.ini
new file mode 100644
index 00000000000..768b6a9e977
--- /dev/null
+++ b/tests/wpt/meta/css/css-sizing/responsive-iframe.tentative.html.ini
@@ -0,0 +1,2 @@
+[responsive-iframe.tentative.html]
+ expected: FAIL
diff --git a/tests/wpt/meta/css/css-tables/table-cell-overflow-auto-scrolled.html.ini b/tests/wpt/meta/css/css-tables/table-cell-overflow-auto-scrolled.html.ini
new file mode 100644
index 00000000000..55805c45ee2
--- /dev/null
+++ b/tests/wpt/meta/css/css-tables/table-cell-overflow-auto-scrolled.html.ini
@@ -0,0 +1,2 @@
+[table-cell-overflow-auto-scrolled.html]
+ expected: FAIL
diff --git a/tests/wpt/meta/css/css-text/text-autospace/text-autospace-vs-001.html.ini b/tests/wpt/meta/css/css-text/text-autospace/text-autospace-vs-001.html.ini
new file mode 100644
index 00000000000..04071c4d8b3
--- /dev/null
+++ b/tests/wpt/meta/css/css-text/text-autospace/text-autospace-vs-001.html.ini
@@ -0,0 +1,2 @@
+[text-autospace-vs-001.html]
+ expected: FAIL
diff --git a/tests/wpt/meta/css/css-text/word-break/word-break-keep-all-u002d.html.ini b/tests/wpt/meta/css/css-text/word-break/word-break-keep-all-u002d.html.ini
new file mode 100644
index 00000000000..5de432ffdee
--- /dev/null
+++ b/tests/wpt/meta/css/css-text/word-break/word-break-keep-all-u002d.html.ini
@@ -0,0 +1,2 @@
+[word-break-keep-all-u002d.html]
+ expected: FAIL
diff --git a/tests/wpt/meta/css/css-values/if-conditionals.html.ini b/tests/wpt/meta/css/css-values/if-conditionals.html.ini
index aa2285ad06e..25afac97880 100644
--- a/tests/wpt/meta/css/css-values/if-conditionals.html.ini
+++ b/tests/wpt/meta/css/css-values/if-conditionals.html.ini
@@ -442,3 +442,126 @@
[CSS Values and Units Test: CSS inline if() function 147]
expected: FAIL
+
+ [CSS Values and Units Test: CSS inline if() function 148]
+ expected: FAIL
+
+ [CSS Values and Units Test: CSS inline if() function 149]
+ expected: FAIL
+
+ [CSS Values and Units Test: CSS inline if() function 150]
+ expected: FAIL
+
+ [CSS Values and Units Test: CSS inline if() function 151]
+ expected: FAIL
+
+ [CSS Values and Units Test: CSS inline if() function 152]
+ expected: FAIL
+
+ [CSS Values and Units Test: CSS inline if() function 153]
+ expected: FAIL
+
+ [CSS Values and Units Test: CSS inline if() function 154]
+ expected: FAIL
+
+ [CSS Values and Units Test: CSS inline if() function 155]
+ expected: FAIL
+
+ [CSS Values and Units Test: CSS inline if() function 156]
+ expected: FAIL
+
+ [CSS Values and Units Test: CSS inline if() function 157]
+ expected: FAIL
+
+ [CSS Values and Units Test: CSS inline if() function 158]
+ expected: FAIL
+
+ [CSS Values and Units Test: CSS inline if() function 159]
+ expected: FAIL
+
+ [CSS Values and Units Test: CSS inline if() function 160]
+ expected: FAIL
+
+ [CSS Values and Units Test: CSS inline if() function 161]
+ expected: FAIL
+
+ [CSS Values and Units Test: CSS inline if() function 162]
+ expected: FAIL
+
+ [CSS Values and Units Test: CSS inline if() function 163]
+ expected: FAIL
+
+ [CSS Values and Units Test: CSS inline if() function 164]
+ expected: FAIL
+
+ [CSS Values and Units Test: CSS inline if() function 165]
+ expected: FAIL
+
+ [CSS Values and Units Test: CSS inline if() function 166]
+ expected: FAIL
+
+ [CSS Values and Units Test: CSS inline if() function 167]
+ expected: FAIL
+
+ [CSS Values and Units Test: CSS inline if() function 168]
+ expected: FAIL
+
+ [CSS Values and Units Test: CSS inline if() function 169]
+ expected: FAIL
+
+ [CSS Values and Units Test: CSS inline if() function 170]
+ expected: FAIL
+
+ [CSS Values and Units Test: CSS inline if() function 171]
+ expected: FAIL
+
+ [CSS Values and Units Test: CSS inline if() function 172]
+ expected: FAIL
+
+ [CSS Values and Units Test: CSS inline if() function 173]
+ expected: FAIL
+
+ [CSS Values and Units Test: CSS inline if() function 174]
+ expected: FAIL
+
+ [CSS Values and Units Test: CSS inline if() function 175]
+ expected: FAIL
+
+ [CSS Values and Units Test: CSS inline if() function 176]
+ expected: FAIL
+
+ [CSS Values and Units Test: CSS inline if() function 177]
+ expected: FAIL
+
+ [CSS Values and Units Test: CSS inline if() function 178]
+ expected: FAIL
+
+ [CSS Values and Units Test: CSS inline if() function 179]
+ expected: FAIL
+
+ [CSS Values and Units Test: CSS inline if() function 180]
+ expected: FAIL
+
+ [CSS Values and Units Test: CSS inline if() function 181]
+ expected: FAIL
+
+ [CSS Values and Units Test: CSS inline if() function 182]
+ expected: FAIL
+
+ [CSS Values and Units Test: CSS inline if() function 183]
+ expected: FAIL
+
+ [CSS Values and Units Test: CSS inline if() function 184]
+ expected: FAIL
+
+ [CSS Values and Units Test: CSS inline if() function 185]
+ expected: FAIL
+
+ [CSS Values and Units Test: CSS inline if() function 186]
+ expected: FAIL
+
+ [CSS Values and Units Test: CSS inline if() function 187]
+ expected: FAIL
+
+ [CSS Values and Units Test: CSS inline if() function 188]
+ expected: FAIL
diff --git a/tests/wpt/meta/css/css-values/tree-counting/sibling-function-container-query-invalidation.html.ini b/tests/wpt/meta/css/css-values/tree-counting/sibling-function-container-query-invalidation.html.ini
new file mode 100644
index 00000000000..4d74ed1e63c
--- /dev/null
+++ b/tests/wpt/meta/css/css-values/tree-counting/sibling-function-container-query-invalidation.html.ini
@@ -0,0 +1,12 @@
+[sibling-function-container-query-invalidation.html]
+ [sibling-index() in @container width query matching after removal]
+ expected: FAIL
+
+ [sibling-count() in @container width query matching after removal]
+ expected: FAIL
+
+ [sibling-index() in @container style() query matching after removal]
+ expected: FAIL
+
+ [sibling-count() in @container style() query matching after removal]
+ expected: FAIL
diff --git a/tests/wpt/meta/css/css-values/tree-counting/sibling-index-keyframe-registered-properties-dynamic.html.ini b/tests/wpt/meta/css/css-values/tree-counting/sibling-index-keyframe-registered-properties-dynamic.html.ini
index 807d5e54ab4..4be76b217d3 100644
--- a/tests/wpt/meta/css/css-values/tree-counting/sibling-index-keyframe-registered-properties-dynamic.html.ini
+++ b/tests/wpt/meta/css/css-values/tree-counting/sibling-index-keyframe-registered-properties-dynamic.html.ini
@@ -52,3 +52,9 @@
[Removing a preceding sibling of #target reduces the sibling-index() for --color]
expected: FAIL
+
+ [Initially, the sibling-index() is 3 for --list]
+ expected: FAIL
+
+ [Removing a preceding sibling of #target reduces the sibling-index() for --list]
+ expected: FAIL
diff --git a/tests/wpt/meta/custom-elements/registries/idlharness.window.js.ini b/tests/wpt/meta/custom-elements/registries/idlharness.window.js.ini
index 44fbd51d205..e033f991a62 100644
--- a/tests/wpt/meta/custom-elements/registries/idlharness.window.js.ini
+++ b/tests/wpt/meta/custom-elements/registries/idlharness.window.js.ini
@@ -1,3 +1,42 @@
[idlharness.window.html]
[idl_test setup]
expected: FAIL
+
+ [idl_test validation]
+ expected: FAIL
+
+ [Partial interface CustomElementRegistry: member names are unique]
+ expected: FAIL
+
+ [Partial interface HTMLTemplateElement: member names are unique]
+ expected: FAIL
+
+ [Partial interface Element: member names are unique]
+ expected: FAIL
+
+ [Partial dictionary ShadowRootInit: member names are unique]
+ expected: FAIL
+
+ [Partial dictionary ElementCreationOptions: member names are unique]
+ expected: FAIL
+
+ [Document includes DocumentOrShadowRoot: member names are unique]
+ expected: FAIL
+
+ [ShadowRoot includes DocumentOrShadowRoot: member names are unique]
+ expected: FAIL
+
+ [HTMLTemplateElement interface: attribute shadowRootCustomElementRegistry]
+ expected: FAIL
+
+ [CustomElementRegistry interface: operation initialize(Node)]
+ expected: FAIL
+
+ [Document interface: attribute customElementRegistry]
+ expected: FAIL
+
+ [ShadowRoot interface: attribute customElementRegistry]
+ expected: FAIL
+
+ [Element interface: attribute customElementRegistry]
+ expected: FAIL
diff --git a/tests/wpt/meta/dom/ranges/Range-in-shadow-after-the-shadow-removed.html.ini b/tests/wpt/meta/dom/ranges/Range-in-shadow-after-the-shadow-removed.html.ini
deleted file mode 100644
index b2003b5c788..00000000000
--- a/tests/wpt/meta/dom/ranges/Range-in-shadow-after-the-shadow-removed.html.ini
+++ /dev/null
@@ -1,14 +0,0 @@
-[Range-in-shadow-after-the-shadow-removed.html?mode=closed]
- [Range in shadow should stay in the shadow after the host is removed]
- expected: FAIL
-
- [Range in shadow should stay in the shadow after the host parent is removed]
- expected: FAIL
-
-
-[Range-in-shadow-after-the-shadow-removed.html?mode=open]
- [Range in shadow should stay in the shadow after the host is removed]
- expected: FAIL
-
- [Range in shadow should stay in the shadow after the host parent is removed]
- expected: FAIL
diff --git a/tests/wpt/meta/domxpath/fn-lang.html.ini b/tests/wpt/meta/domxpath/fn-lang.html.ini
deleted file mode 100644
index 31754463dcc..00000000000
--- a/tests/wpt/meta/domxpath/fn-lang.html.ini
+++ /dev/null
@@ -1,21 +0,0 @@
-[fn-lang.html]
- [lang("en"): <root><match lang="en"></match></root>]
- expected: FAIL
-
- [lang("en"): <root><match lang="EN"></match></root>]
- expected: FAIL
-
- [lang("en"): <root><match lang="en-us"></match></root>]
- expected: FAIL
-
- [lang("en"): <root><unmatch></unmatch></root>]
- expected: FAIL
-
- [lang("ja"): <root lang="ja"><match></match></root>]
- expected: FAIL
-
- [lang("ja"): <root lang="ja-jp"><unmatch lang="ja_JP"></unmatch></root>]
- expected: FAIL
-
- [lang("ko"): <root><unmatch lang="Ko"></unmatch></root>]
- expected: FAIL
diff --git a/tests/wpt/meta/domxpath/node-sets.html.ini b/tests/wpt/meta/domxpath/node-sets.html.ini
deleted file mode 100644
index 856f22dd655..00000000000
--- a/tests/wpt/meta/domxpath/node-sets.html.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[node-sets.html]
- [| operator should evaluate both sides of expressions with the same context node]
- expected: FAIL
diff --git a/tests/wpt/meta/domxpath/text-html-attributes.html.ini b/tests/wpt/meta/domxpath/text-html-attributes.html.ini
index 803f418282a..7257f61a118 100644
--- a/tests/wpt/meta/domxpath/text-html-attributes.html.ini
+++ b/tests/wpt/meta/domxpath/text-html-attributes.html.ini
@@ -1,13 +1,7 @@
[text-html-attributes.html]
- [Select html element based on attribute]
- expected: FAIL
-
[Select html element based on attribute mixed case]
expected: FAIL
- [Select both HTML and SVG elements based on attribute]
- expected: FAIL
-
[Select HTML element with non-ascii attribute 1]
expected: FAIL
@@ -23,9 +17,6 @@
[Select both HTML and SVG elements based on mixed case attribute]
expected: FAIL
- [Select SVG elements with refX attribute]
- expected: FAIL
-
[Select SVG element with non-ascii attribute 1]
expected: FAIL
diff --git a/tests/wpt/meta/domxpath/xml_xpath_runner.html.ini b/tests/wpt/meta/domxpath/xml_xpath_runner.html.ini
deleted file mode 100644
index e7d698afb6b..00000000000
--- a/tests/wpt/meta/domxpath/xml_xpath_runner.html.ini
+++ /dev/null
@@ -1,3072 +0,0 @@
-[xml_xpath_runner.html]
- [XPath tests]
- expected: FAIL
-
- [XPath tests 1]
- expected: FAIL
-
- [XPath tests 2]
- expected: FAIL
-
- [XPath tests 3]
- expected: FAIL
-
- [XPath tests 4]
- expected: FAIL
-
- [XPath tests 5]
- expected: FAIL
-
- [XPath tests 6]
- expected: FAIL
-
- [XPath tests 7]
- expected: FAIL
-
- [XPath tests 8]
- expected: FAIL
-
- [XPath tests 9]
- expected: FAIL
-
- [XPath tests 10]
- expected: FAIL
-
- [XPath tests 11]
- expected: FAIL
-
- [XPath tests 12]
- expected: FAIL
-
- [XPath tests 13]
- expected: FAIL
-
- [XPath tests 14]
- expected: FAIL
-
- [XPath tests 15]
- expected: FAIL
-
- [XPath tests 16]
- expected: FAIL
-
- [XPath tests 17]
- expected: FAIL
-
- [XPath tests 18]
- expected: FAIL
-
- [XPath tests 19]
- expected: FAIL
-
- [XPath tests 20]
- expected: FAIL
-
- [XPath tests 21]
- expected: FAIL
-
- [XPath tests 22]
- expected: FAIL
-
- [XPath tests 23]
- expected: FAIL
-
- [XPath tests 24]
- expected: FAIL
-
- [XPath tests 25]
- expected: FAIL
-
- [XPath tests 26]
- expected: FAIL
-
- [XPath tests 27]
- expected: FAIL
-
- [XPath tests 28]
- expected: FAIL
-
- [XPath tests 29]
- expected: FAIL
-
- [XPath tests 30]
- expected: FAIL
-
- [XPath tests 31]
- expected: FAIL
-
- [XPath tests 32]
- expected: FAIL
-
- [XPath tests 33]
- expected: FAIL
-
- [XPath tests 34]
- expected: FAIL
-
- [XPath tests 35]
- expected: FAIL
-
- [XPath tests 36]
- expected: FAIL
-
- [XPath tests 37]
- expected: FAIL
-
- [XPath tests 38]
- expected: FAIL
-
- [XPath tests 39]
- expected: FAIL
-
- [XPath tests 40]
- expected: FAIL
-
- [XPath tests 41]
- expected: FAIL
-
- [XPath tests 42]
- expected: FAIL
-
- [XPath tests 43]
- expected: FAIL
-
- [XPath tests 44]
- expected: FAIL
-
- [XPath tests 45]
- expected: FAIL
-
- [XPath tests 46]
- expected: FAIL
-
- [XPath tests 47]
- expected: FAIL
-
- [XPath tests 48]
- expected: FAIL
-
- [XPath tests 49]
- expected: FAIL
-
- [XPath tests 50]
- expected: FAIL
-
- [XPath tests 51]
- expected: FAIL
-
- [XPath tests 52]
- expected: FAIL
-
- [XPath tests 53]
- expected: FAIL
-
- [XPath tests 54]
- expected: FAIL
-
- [XPath tests 55]
- expected: FAIL
-
- [XPath tests 56]
- expected: FAIL
-
- [XPath tests 57]
- expected: FAIL
-
- [XPath tests 58]
- expected: FAIL
-
- [XPath tests 59]
- expected: FAIL
-
- [XPath tests 60]
- expected: FAIL
-
- [XPath tests 61]
- expected: FAIL
-
- [XPath tests 62]
- expected: FAIL
-
- [XPath tests 63]
- expected: FAIL
-
- [XPath tests 64]
- expected: FAIL
-
- [XPath tests 65]
- expected: FAIL
-
- [XPath tests 66]
- expected: FAIL
-
- [XPath tests 67]
- expected: FAIL
-
- [XPath tests 68]
- expected: FAIL
-
- [XPath tests 69]
- expected: FAIL
-
- [XPath tests 70]
- expected: FAIL
-
- [XPath tests 71]
- expected: FAIL
-
- [XPath tests 72]
- expected: FAIL
-
- [XPath tests 73]
- expected: FAIL
-
- [XPath tests 74]
- expected: FAIL
-
- [XPath tests 75]
- expected: FAIL
-
- [XPath tests 76]
- expected: FAIL
-
- [XPath tests 77]
- expected: FAIL
-
- [XPath tests 78]
- expected: FAIL
-
- [XPath tests 79]
- expected: FAIL
-
- [XPath tests 80]
- expected: FAIL
-
- [XPath tests 81]
- expected: FAIL
-
- [XPath tests 82]
- expected: FAIL
-
- [XPath tests 83]
- expected: FAIL
-
- [XPath tests 84]
- expected: FAIL
-
- [XPath tests 85]
- expected: FAIL
-
- [XPath tests 86]
- expected: FAIL
-
- [XPath tests 87]
- expected: FAIL
-
- [XPath tests 88]
- expected: FAIL
-
- [XPath tests 89]
- expected: FAIL
-
- [XPath tests 90]
- expected: FAIL
-
- [XPath tests 91]
- expected: FAIL
-
- [XPath tests 92]
- expected: FAIL
-
- [XPath tests 93]
- expected: FAIL
-
- [XPath tests 94]
- expected: FAIL
-
- [XPath tests 95]
- expected: FAIL
-
- [XPath tests 96]
- expected: FAIL
-
- [XPath tests 97]
- expected: FAIL
-
- [XPath tests 98]
- expected: FAIL
-
- [XPath tests 99]
- expected: FAIL
-
- [XPath tests 100]
- expected: FAIL
-
- [XPath tests 101]
- expected: FAIL
-
- [XPath tests 102]
- expected: FAIL
-
- [XPath tests 103]
- expected: FAIL
-
- [XPath tests 104]
- expected: FAIL
-
- [XPath tests 105]
- expected: FAIL
-
- [XPath tests 106]
- expected: FAIL
-
- [XPath tests 107]
- expected: FAIL
-
- [XPath tests 108]
- expected: FAIL
-
- [XPath tests 109]
- expected: FAIL
-
- [XPath tests 110]
- expected: FAIL
-
- [XPath tests 111]
- expected: FAIL
-
- [XPath tests 112]
- expected: FAIL
-
- [XPath tests 113]
- expected: FAIL
-
- [XPath tests 114]
- expected: FAIL
-
- [XPath tests 115]
- expected: FAIL
-
- [XPath tests 116]
- expected: FAIL
-
- [XPath tests 117]
- expected: FAIL
-
- [XPath tests 118]
- expected: FAIL
-
- [XPath tests 119]
- expected: FAIL
-
- [XPath tests 120]
- expected: FAIL
-
- [XPath tests 121]
- expected: FAIL
-
- [XPath tests 122]
- expected: FAIL
-
- [XPath tests 123]
- expected: FAIL
-
- [XPath tests 124]
- expected: FAIL
-
- [XPath tests 125]
- expected: FAIL
-
- [XPath tests 126]
- expected: FAIL
-
- [XPath tests 127]
- expected: FAIL
-
- [XPath tests 128]
- expected: FAIL
-
- [XPath tests 129]
- expected: FAIL
-
- [XPath tests 130]
- expected: FAIL
-
- [XPath tests 131]
- expected: FAIL
-
- [XPath tests 132]
- expected: FAIL
-
- [XPath tests 133]
- expected: FAIL
-
- [XPath tests 134]
- expected: FAIL
-
- [XPath tests 135]
- expected: FAIL
-
- [XPath tests 136]
- expected: FAIL
-
- [XPath tests 137]
- expected: FAIL
-
- [XPath tests 138]
- expected: FAIL
-
- [XPath tests 139]
- expected: FAIL
-
- [XPath tests 140]
- expected: FAIL
-
- [XPath tests 141]
- expected: FAIL
-
- [XPath tests 142]
- expected: FAIL
-
- [XPath tests 143]
- expected: FAIL
-
- [XPath tests 144]
- expected: FAIL
-
- [XPath tests 145]
- expected: FAIL
-
- [XPath tests 146]
- expected: FAIL
-
- [XPath tests 147]
- expected: FAIL
-
- [XPath tests 148]
- expected: FAIL
-
- [XPath tests 149]
- expected: FAIL
-
- [XPath tests 150]
- expected: FAIL
-
- [XPath tests 151]
- expected: FAIL
-
- [XPath tests 152]
- expected: FAIL
-
- [XPath tests 153]
- expected: FAIL
-
- [XPath tests 154]
- expected: FAIL
-
- [XPath tests 155]
- expected: FAIL
-
- [XPath tests 156]
- expected: FAIL
-
- [XPath tests 157]
- expected: FAIL
-
- [XPath tests 158]
- expected: FAIL
-
- [XPath tests 159]
- expected: FAIL
-
- [XPath tests 160]
- expected: FAIL
-
- [XPath tests 161]
- expected: FAIL
-
- [XPath tests 162]
- expected: FAIL
-
- [XPath tests 163]
- expected: FAIL
-
- [XPath tests 164]
- expected: FAIL
-
- [XPath tests 165]
- expected: FAIL
-
- [XPath tests 166]
- expected: FAIL
-
- [XPath tests 167]
- expected: FAIL
-
- [XPath tests 168]
- expected: FAIL
-
- [XPath tests 169]
- expected: FAIL
-
- [XPath tests 170]
- expected: FAIL
-
- [XPath tests 171]
- expected: FAIL
-
- [XPath tests 172]
- expected: FAIL
-
- [XPath tests 173]
- expected: FAIL
-
- [XPath tests 174]
- expected: FAIL
-
- [XPath tests 175]
- expected: FAIL
-
- [XPath tests 176]
- expected: FAIL
-
- [XPath tests 177]
- expected: FAIL
-
- [XPath tests 178]
- expected: FAIL
-
- [XPath tests 179]
- expected: FAIL
-
- [XPath tests 180]
- expected: FAIL
-
- [XPath tests 181]
- expected: FAIL
-
- [XPath tests 182]
- expected: FAIL
-
- [XPath tests 183]
- expected: FAIL
-
- [XPath tests 184]
- expected: FAIL
-
- [XPath tests 185]
- expected: FAIL
-
- [XPath tests 186]
- expected: FAIL
-
- [XPath tests 187]
- expected: FAIL
-
- [XPath tests 188]
- expected: FAIL
-
- [XPath tests 189]
- expected: FAIL
-
- [XPath tests 190]
- expected: FAIL
-
- [XPath tests 191]
- expected: FAIL
-
- [XPath tests 192]
- expected: FAIL
-
- [XPath tests 193]
- expected: FAIL
-
- [XPath tests 194]
- expected: FAIL
-
- [XPath tests 195]
- expected: FAIL
-
- [XPath tests 196]
- expected: FAIL
-
- [XPath tests 197]
- expected: FAIL
-
- [XPath tests 198]
- expected: FAIL
-
- [XPath tests 199]
- expected: FAIL
-
- [XPath tests 200]
- expected: FAIL
-
- [XPath tests 201]
- expected: FAIL
-
- [XPath tests 202]
- expected: FAIL
-
- [XPath tests 203]
- expected: FAIL
-
- [XPath tests 204]
- expected: FAIL
-
- [XPath tests 205]
- expected: FAIL
-
- [XPath tests 206]
- expected: FAIL
-
- [XPath tests 207]
- expected: FAIL
-
- [XPath tests 208]
- expected: FAIL
-
- [XPath tests 209]
- expected: FAIL
-
- [XPath tests 210]
- expected: FAIL
-
- [XPath tests 211]
- expected: FAIL
-
- [XPath tests 212]
- expected: FAIL
-
- [XPath tests 213]
- expected: FAIL
-
- [XPath tests 214]
- expected: FAIL
-
- [XPath tests 215]
- expected: FAIL
-
- [XPath tests 216]
- expected: FAIL
-
- [XPath tests 217]
- expected: FAIL
-
- [XPath tests 218]
- expected: FAIL
-
- [XPath tests 219]
- expected: FAIL
-
- [XPath tests 220]
- expected: FAIL
-
- [XPath tests 221]
- expected: FAIL
-
- [XPath tests 222]
- expected: FAIL
-
- [XPath tests 223]
- expected: FAIL
-
- [XPath tests 224]
- expected: FAIL
-
- [XPath tests 225]
- expected: FAIL
-
- [XPath tests 226]
- expected: FAIL
-
- [XPath tests 227]
- expected: FAIL
-
- [XPath tests 228]
- expected: FAIL
-
- [XPath tests 229]
- expected: FAIL
-
- [XPath tests 230]
- expected: FAIL
-
- [XPath tests 231]
- expected: FAIL
-
- [XPath tests 232]
- expected: FAIL
-
- [XPath tests 233]
- expected: FAIL
-
- [XPath tests 234]
- expected: FAIL
-
- [XPath tests 235]
- expected: FAIL
-
- [XPath tests 236]
- expected: FAIL
-
- [XPath tests 237]
- expected: FAIL
-
- [XPath tests 238]
- expected: FAIL
-
- [XPath tests 239]
- expected: FAIL
-
- [XPath tests 240]
- expected: FAIL
-
- [XPath tests 241]
- expected: FAIL
-
- [XPath tests 242]
- expected: FAIL
-
- [XPath tests 243]
- expected: FAIL
-
- [XPath tests 244]
- expected: FAIL
-
- [XPath tests 245]
- expected: FAIL
-
- [XPath tests 246]
- expected: FAIL
-
- [XPath tests 247]
- expected: FAIL
-
- [XPath tests 248]
- expected: FAIL
-
- [XPath tests 249]
- expected: FAIL
-
- [XPath tests 250]
- expected: FAIL
-
- [XPath tests 251]
- expected: FAIL
-
- [XPath tests 252]
- expected: FAIL
-
- [XPath tests 253]
- expected: FAIL
-
- [XPath tests 254]
- expected: FAIL
-
- [XPath tests 255]
- expected: FAIL
-
- [XPath tests 256]
- expected: FAIL
-
- [XPath tests 257]
- expected: FAIL
-
- [XPath tests 258]
- expected: FAIL
-
- [XPath tests 259]
- expected: FAIL
-
- [XPath tests 260]
- expected: FAIL
-
- [XPath tests 261]
- expected: FAIL
-
- [XPath tests 262]
- expected: FAIL
-
- [XPath tests 263]
- expected: FAIL
-
- [XPath tests 264]
- expected: FAIL
-
- [XPath tests 265]
- expected: FAIL
-
- [XPath tests 266]
- expected: FAIL
-
- [XPath tests 267]
- expected: FAIL
-
- [XPath tests 268]
- expected: FAIL
-
- [XPath tests 269]
- expected: FAIL
-
- [XPath tests 270]
- expected: FAIL
-
- [XPath tests 271]
- expected: FAIL
-
- [XPath tests 272]
- expected: FAIL
-
- [XPath tests 273]
- expected: FAIL
-
- [XPath tests 274]
- expected: FAIL
-
- [XPath tests 275]
- expected: FAIL
-
- [XPath tests 276]
- expected: FAIL
-
- [XPath tests 277]
- expected: FAIL
-
- [XPath tests 278]
- expected: FAIL
-
- [XPath tests 279]
- expected: FAIL
-
- [XPath tests 280]
- expected: FAIL
-
- [XPath tests 281]
- expected: FAIL
-
- [XPath tests 282]
- expected: FAIL
-
- [XPath tests 283]
- expected: FAIL
-
- [XPath tests 284]
- expected: FAIL
-
- [XPath tests 285]
- expected: FAIL
-
- [XPath tests 286]
- expected: FAIL
-
- [XPath tests 287]
- expected: FAIL
-
- [XPath tests 288]
- expected: FAIL
-
- [XPath tests 289]
- expected: FAIL
-
- [XPath tests 290]
- expected: FAIL
-
- [XPath tests 291]
- expected: FAIL
-
- [XPath tests 292]
- expected: FAIL
-
- [XPath tests 293]
- expected: FAIL
-
- [XPath tests 294]
- expected: FAIL
-
- [XPath tests 295]
- expected: FAIL
-
- [XPath tests 296]
- expected: FAIL
-
- [XPath tests 297]
- expected: FAIL
-
- [XPath tests 298]
- expected: FAIL
-
- [XPath tests 299]
- expected: FAIL
-
- [XPath tests 300]
- expected: FAIL
-
- [XPath tests 301]
- expected: FAIL
-
- [XPath tests 302]
- expected: FAIL
-
- [XPath tests 303]
- expected: FAIL
-
- [XPath tests 304]
- expected: FAIL
-
- [XPath tests 305]
- expected: FAIL
-
- [XPath tests 306]
- expected: FAIL
-
- [XPath tests 307]
- expected: FAIL
-
- [XPath tests 308]
- expected: FAIL
-
- [XPath tests 309]
- expected: FAIL
-
- [XPath tests 310]
- expected: FAIL
-
- [XPath tests 311]
- expected: FAIL
-
- [XPath tests 312]
- expected: FAIL
-
- [XPath tests 313]
- expected: FAIL
-
- [XPath tests 314]
- expected: FAIL
-
- [XPath tests 315]
- expected: FAIL
-
- [XPath tests 316]
- expected: FAIL
-
- [XPath tests 317]
- expected: FAIL
-
- [XPath tests 318]
- expected: FAIL
-
- [XPath tests 319]
- expected: FAIL
-
- [XPath tests 320]
- expected: FAIL
-
- [XPath tests 321]
- expected: FAIL
-
- [XPath tests 322]
- expected: FAIL
-
- [XPath tests 323]
- expected: FAIL
-
- [XPath tests 324]
- expected: FAIL
-
- [XPath tests 325]
- expected: FAIL
-
- [XPath tests 326]
- expected: FAIL
-
- [XPath tests 327]
- expected: FAIL
-
- [XPath tests 328]
- expected: FAIL
-
- [XPath tests 329]
- expected: FAIL
-
- [XPath tests 330]
- expected: FAIL
-
- [XPath tests 331]
- expected: FAIL
-
- [XPath tests 332]
- expected: FAIL
-
- [XPath tests 333]
- expected: FAIL
-
- [XPath tests 334]
- expected: FAIL
-
- [XPath tests 335]
- expected: FAIL
-
- [XPath tests 336]
- expected: FAIL
-
- [XPath tests 337]
- expected: FAIL
-
- [XPath tests 338]
- expected: FAIL
-
- [XPath tests 339]
- expected: FAIL
-
- [XPath tests 340]
- expected: FAIL
-
- [XPath tests 341]
- expected: FAIL
-
- [XPath tests 342]
- expected: FAIL
-
- [XPath tests 343]
- expected: FAIL
-
- [XPath tests 344]
- expected: FAIL
-
- [XPath tests 345]
- expected: FAIL
-
- [XPath tests 346]
- expected: FAIL
-
- [XPath tests 347]
- expected: FAIL
-
- [XPath tests 348]
- expected: FAIL
-
- [XPath tests 349]
- expected: FAIL
-
- [XPath tests 350]
- expected: FAIL
-
- [XPath tests 351]
- expected: FAIL
-
- [XPath tests 352]
- expected: FAIL
-
- [XPath tests 353]
- expected: FAIL
-
- [XPath tests 354]
- expected: FAIL
-
- [XPath tests 355]
- expected: FAIL
-
- [XPath tests 356]
- expected: FAIL
-
- [XPath tests 357]
- expected: FAIL
-
- [XPath tests 358]
- expected: FAIL
-
- [XPath tests 359]
- expected: FAIL
-
- [XPath tests 360]
- expected: FAIL
-
- [XPath tests 361]
- expected: FAIL
-
- [XPath tests 362]
- expected: FAIL
-
- [XPath tests 363]
- expected: FAIL
-
- [XPath tests 364]
- expected: FAIL
-
- [XPath tests 365]
- expected: FAIL
-
- [XPath tests 366]
- expected: FAIL
-
- [XPath tests 367]
- expected: FAIL
-
- [XPath tests 368]
- expected: FAIL
-
- [XPath tests 369]
- expected: FAIL
-
- [XPath tests 370]
- expected: FAIL
-
- [XPath tests 371]
- expected: FAIL
-
- [XPath tests 372]
- expected: FAIL
-
- [XPath tests 373]
- expected: FAIL
-
- [XPath tests 374]
- expected: FAIL
-
- [XPath tests 375]
- expected: FAIL
-
- [XPath tests 376]
- expected: FAIL
-
- [XPath tests 377]
- expected: FAIL
-
- [XPath tests 378]
- expected: FAIL
-
- [XPath tests 379]
- expected: FAIL
-
- [XPath tests 380]
- expected: FAIL
-
- [XPath tests 381]
- expected: FAIL
-
- [XPath tests 382]
- expected: FAIL
-
- [XPath tests 383]
- expected: FAIL
-
- [XPath tests 384]
- expected: FAIL
-
- [XPath tests 385]
- expected: FAIL
-
- [XPath tests 386]
- expected: FAIL
-
- [XPath tests 387]
- expected: FAIL
-
- [XPath tests 388]
- expected: FAIL
-
- [XPath tests 389]
- expected: FAIL
-
- [XPath tests 390]
- expected: FAIL
-
- [XPath tests 391]
- expected: FAIL
-
- [XPath tests 392]
- expected: FAIL
-
- [XPath tests 393]
- expected: FAIL
-
- [XPath tests 394]
- expected: FAIL
-
- [XPath tests 395]
- expected: FAIL
-
- [XPath tests 396]
- expected: FAIL
-
- [XPath tests 397]
- expected: FAIL
-
- [XPath tests 398]
- expected: FAIL
-
- [XPath tests 399]
- expected: FAIL
-
- [XPath tests 400]
- expected: FAIL
-
- [XPath tests 401]
- expected: FAIL
-
- [XPath tests 402]
- expected: FAIL
-
- [XPath tests 403]
- expected: FAIL
-
- [XPath tests 404]
- expected: FAIL
-
- [XPath tests 405]
- expected: FAIL
-
- [XPath tests 406]
- expected: FAIL
-
- [XPath tests 407]
- expected: FAIL
-
- [XPath tests 408]
- expected: FAIL
-
- [XPath tests 409]
- expected: FAIL
-
- [XPath tests 410]
- expected: FAIL
-
- [XPath tests 411]
- expected: FAIL
-
- [XPath tests 412]
- expected: FAIL
-
- [XPath tests 413]
- expected: FAIL
-
- [XPath tests 414]
- expected: FAIL
-
- [XPath tests 415]
- expected: FAIL
-
- [XPath tests 416]
- expected: FAIL
-
- [XPath tests 417]
- expected: FAIL
-
- [XPath tests 418]
- expected: FAIL
-
- [XPath tests 419]
- expected: FAIL
-
- [XPath tests 420]
- expected: FAIL
-
- [XPath tests 421]
- expected: FAIL
-
- [XPath tests 422]
- expected: FAIL
-
- [XPath tests 423]
- expected: FAIL
-
- [XPath tests 424]
- expected: FAIL
-
- [XPath tests 425]
- expected: FAIL
-
- [XPath tests 426]
- expected: FAIL
-
- [XPath tests 427]
- expected: FAIL
-
- [XPath tests 428]
- expected: FAIL
-
- [XPath tests 429]
- expected: FAIL
-
- [XPath tests 430]
- expected: FAIL
-
- [XPath tests 431]
- expected: FAIL
-
- [XPath tests 432]
- expected: FAIL
-
- [XPath tests 433]
- expected: FAIL
-
- [XPath tests 434]
- expected: FAIL
-
- [XPath tests 435]
- expected: FAIL
-
- [XPath tests 436]
- expected: FAIL
-
- [XPath tests 437]
- expected: FAIL
-
- [XPath tests 438]
- expected: FAIL
-
- [XPath tests 439]
- expected: FAIL
-
- [XPath tests 440]
- expected: FAIL
-
- [XPath tests 441]
- expected: FAIL
-
- [XPath tests 442]
- expected: FAIL
-
- [XPath tests 443]
- expected: FAIL
-
- [XPath tests 444]
- expected: FAIL
-
- [XPath tests 445]
- expected: FAIL
-
- [XPath tests 446]
- expected: FAIL
-
- [XPath tests 447]
- expected: FAIL
-
- [XPath tests 448]
- expected: FAIL
-
- [XPath tests 449]
- expected: FAIL
-
- [XPath tests 450]
- expected: FAIL
-
- [XPath tests 451]
- expected: FAIL
-
- [XPath tests 452]
- expected: FAIL
-
- [XPath tests 453]
- expected: FAIL
-
- [XPath tests 454]
- expected: FAIL
-
- [XPath tests 455]
- expected: FAIL
-
- [XPath tests 456]
- expected: FAIL
-
- [XPath tests 457]
- expected: FAIL
-
- [XPath tests 458]
- expected: FAIL
-
- [XPath tests 459]
- expected: FAIL
-
- [XPath tests 460]
- expected: FAIL
-
- [XPath tests 461]
- expected: FAIL
-
- [XPath tests 462]
- expected: FAIL
-
- [XPath tests 463]
- expected: FAIL
-
- [XPath tests 464]
- expected: FAIL
-
- [XPath tests 465]
- expected: FAIL
-
- [XPath tests 466]
- expected: FAIL
-
- [XPath tests 467]
- expected: FAIL
-
- [XPath tests 468]
- expected: FAIL
-
- [XPath tests 469]
- expected: FAIL
-
- [XPath tests 470]
- expected: FAIL
-
- [XPath tests 471]
- expected: FAIL
-
- [XPath tests 472]
- expected: FAIL
-
- [XPath tests 473]
- expected: FAIL
-
- [XPath tests 474]
- expected: FAIL
-
- [XPath tests 475]
- expected: FAIL
-
- [XPath tests 476]
- expected: FAIL
-
- [XPath tests 477]
- expected: FAIL
-
- [XPath tests 478]
- expected: FAIL
-
- [XPath tests 479]
- expected: FAIL
-
- [XPath tests 480]
- expected: FAIL
-
- [XPath tests 481]
- expected: FAIL
-
- [XPath tests 482]
- expected: FAIL
-
- [XPath tests 483]
- expected: FAIL
-
- [XPath tests 484]
- expected: FAIL
-
- [XPath tests 485]
- expected: FAIL
-
- [XPath tests 486]
- expected: FAIL
-
- [XPath tests 487]
- expected: FAIL
-
- [XPath tests 488]
- expected: FAIL
-
- [XPath tests 489]
- expected: FAIL
-
- [XPath tests 490]
- expected: FAIL
-
- [XPath tests 491]
- expected: FAIL
-
- [XPath tests 492]
- expected: FAIL
-
- [XPath tests 493]
- expected: FAIL
-
- [XPath tests 494]
- expected: FAIL
-
- [XPath tests 495]
- expected: FAIL
-
- [XPath tests 496]
- expected: FAIL
-
- [XPath tests 497]
- expected: FAIL
-
- [XPath tests 498]
- expected: FAIL
-
- [XPath tests 499]
- expected: FAIL
-
- [XPath tests 500]
- expected: FAIL
-
- [XPath tests 501]
- expected: FAIL
-
- [XPath tests 502]
- expected: FAIL
-
- [XPath tests 503]
- expected: FAIL
-
- [XPath tests 504]
- expected: FAIL
-
- [XPath tests 505]
- expected: FAIL
-
- [XPath tests 506]
- expected: FAIL
-
- [XPath tests 507]
- expected: FAIL
-
- [XPath tests 508]
- expected: FAIL
-
- [XPath tests 509]
- expected: FAIL
-
- [XPath tests 510]
- expected: FAIL
-
- [XPath tests 511]
- expected: FAIL
-
- [XPath tests 512]
- expected: FAIL
-
- [XPath tests 513]
- expected: FAIL
-
- [XPath tests 514]
- expected: FAIL
-
- [XPath tests 515]
- expected: FAIL
-
- [XPath tests 516]
- expected: FAIL
-
- [XPath tests 517]
- expected: FAIL
-
- [XPath tests 518]
- expected: FAIL
-
- [XPath tests 519]
- expected: FAIL
-
- [XPath tests 520]
- expected: FAIL
-
- [XPath tests 521]
- expected: FAIL
-
- [XPath tests 522]
- expected: FAIL
-
- [XPath tests 523]
- expected: FAIL
-
- [XPath tests 524]
- expected: FAIL
-
- [XPath tests 525]
- expected: FAIL
-
- [XPath tests 526]
- expected: FAIL
-
- [XPath tests 527]
- expected: FAIL
-
- [XPath tests 528]
- expected: FAIL
-
- [XPath tests 529]
- expected: FAIL
-
- [XPath tests 530]
- expected: FAIL
-
- [XPath tests 531]
- expected: FAIL
-
- [XPath tests 532]
- expected: FAIL
-
- [XPath tests 533]
- expected: FAIL
-
- [XPath tests 534]
- expected: FAIL
-
- [XPath tests 535]
- expected: FAIL
-
- [XPath tests 536]
- expected: FAIL
-
- [XPath tests 537]
- expected: FAIL
-
- [XPath tests 538]
- expected: FAIL
-
- [XPath tests 539]
- expected: FAIL
-
- [XPath tests 540]
- expected: FAIL
-
- [XPath tests 541]
- expected: FAIL
-
- [XPath tests 542]
- expected: FAIL
-
- [XPath tests 543]
- expected: FAIL
-
- [XPath tests 544]
- expected: FAIL
-
- [XPath tests 545]
- expected: FAIL
-
- [XPath tests 546]
- expected: FAIL
-
- [XPath tests 547]
- expected: FAIL
-
- [XPath tests 548]
- expected: FAIL
-
- [XPath tests 549]
- expected: FAIL
-
- [XPath tests 550]
- expected: FAIL
-
- [XPath tests 551]
- expected: FAIL
-
- [XPath tests 552]
- expected: FAIL
-
- [XPath tests 553]
- expected: FAIL
-
- [XPath tests 554]
- expected: FAIL
-
- [XPath tests 555]
- expected: FAIL
-
- [XPath tests 556]
- expected: FAIL
-
- [XPath tests 557]
- expected: FAIL
-
- [XPath tests 558]
- expected: FAIL
-
- [XPath tests 559]
- expected: FAIL
-
- [XPath tests 560]
- expected: FAIL
-
- [XPath tests 561]
- expected: FAIL
-
- [XPath tests 562]
- expected: FAIL
-
- [XPath tests 563]
- expected: FAIL
-
- [XPath tests 564]
- expected: FAIL
-
- [XPath tests 565]
- expected: FAIL
-
- [XPath tests 566]
- expected: FAIL
-
- [XPath tests 567]
- expected: FAIL
-
- [XPath tests 568]
- expected: FAIL
-
- [XPath tests 569]
- expected: FAIL
-
- [XPath tests 570]
- expected: FAIL
-
- [XPath tests 571]
- expected: FAIL
-
- [XPath tests 572]
- expected: FAIL
-
- [XPath tests 573]
- expected: FAIL
-
- [XPath tests 574]
- expected: FAIL
-
- [XPath tests 575]
- expected: FAIL
-
- [XPath tests 576]
- expected: FAIL
-
- [XPath tests 577]
- expected: FAIL
-
- [XPath tests 578]
- expected: FAIL
-
- [XPath tests 579]
- expected: FAIL
-
- [XPath tests 580]
- expected: FAIL
-
- [XPath tests 581]
- expected: FAIL
-
- [XPath tests 582]
- expected: FAIL
-
- [XPath tests 583]
- expected: FAIL
-
- [XPath tests 584]
- expected: FAIL
-
- [XPath tests 585]
- expected: FAIL
-
- [XPath tests 586]
- expected: FAIL
-
- [XPath tests 587]
- expected: FAIL
-
- [XPath tests 588]
- expected: FAIL
-
- [XPath tests 589]
- expected: FAIL
-
- [XPath tests 590]
- expected: FAIL
-
- [XPath tests 591]
- expected: FAIL
-
- [XPath tests 592]
- expected: FAIL
-
- [XPath tests 593]
- expected: FAIL
-
- [XPath tests 594]
- expected: FAIL
-
- [XPath tests 595]
- expected: FAIL
-
- [XPath tests 596]
- expected: FAIL
-
- [XPath tests 597]
- expected: FAIL
-
- [XPath tests 598]
- expected: FAIL
-
- [XPath tests 599]
- expected: FAIL
-
- [XPath tests 600]
- expected: FAIL
-
- [XPath tests 601]
- expected: FAIL
-
- [XPath tests 602]
- expected: FAIL
-
- [XPath tests 603]
- expected: FAIL
-
- [XPath tests 604]
- expected: FAIL
-
- [XPath tests 605]
- expected: FAIL
-
- [XPath tests 606]
- expected: FAIL
-
- [XPath tests 607]
- expected: FAIL
-
- [XPath tests 608]
- expected: FAIL
-
- [XPath tests 609]
- expected: FAIL
-
- [XPath tests 610]
- expected: FAIL
-
- [XPath tests 611]
- expected: FAIL
-
- [XPath tests 612]
- expected: FAIL
-
- [XPath tests 613]
- expected: FAIL
-
- [XPath tests 614]
- expected: FAIL
-
- [XPath tests 615]
- expected: FAIL
-
- [XPath tests 616]
- expected: FAIL
-
- [XPath tests 617]
- expected: FAIL
-
- [XPath tests 618]
- expected: FAIL
-
- [XPath tests 619]
- expected: FAIL
-
- [XPath tests 620]
- expected: FAIL
-
- [XPath tests 621]
- expected: FAIL
-
- [XPath tests 622]
- expected: FAIL
-
- [XPath tests 623]
- expected: FAIL
-
- [XPath tests 624]
- expected: FAIL
-
- [XPath tests 625]
- expected: FAIL
-
- [XPath tests 626]
- expected: FAIL
-
- [XPath tests 627]
- expected: FAIL
-
- [XPath tests 628]
- expected: FAIL
-
- [XPath tests 629]
- expected: FAIL
-
- [XPath tests 630]
- expected: FAIL
-
- [XPath tests 631]
- expected: FAIL
-
- [XPath tests 632]
- expected: FAIL
-
- [XPath tests 633]
- expected: FAIL
-
- [XPath tests 634]
- expected: FAIL
-
- [XPath tests 635]
- expected: FAIL
-
- [XPath tests 636]
- expected: FAIL
-
- [XPath tests 637]
- expected: FAIL
-
- [XPath tests 638]
- expected: FAIL
-
- [XPath tests 639]
- expected: FAIL
-
- [XPath tests 640]
- expected: FAIL
-
- [XPath tests 641]
- expected: FAIL
-
- [XPath tests 642]
- expected: FAIL
-
- [XPath tests 643]
- expected: FAIL
-
- [XPath tests 644]
- expected: FAIL
-
- [XPath tests 645]
- expected: FAIL
-
- [XPath tests 646]
- expected: FAIL
-
- [XPath tests 647]
- expected: FAIL
-
- [XPath tests 648]
- expected: FAIL
-
- [XPath tests 649]
- expected: FAIL
-
- [XPath tests 650]
- expected: FAIL
-
- [XPath tests 651]
- expected: FAIL
-
- [XPath tests 652]
- expected: FAIL
-
- [XPath tests 653]
- expected: FAIL
-
- [XPath tests 654]
- expected: FAIL
-
- [XPath tests 655]
- expected: FAIL
-
- [XPath tests 656]
- expected: FAIL
-
- [XPath tests 657]
- expected: FAIL
-
- [XPath tests 658]
- expected: FAIL
-
- [XPath tests 659]
- expected: FAIL
-
- [XPath tests 660]
- expected: FAIL
-
- [XPath tests 661]
- expected: FAIL
-
- [XPath tests 662]
- expected: FAIL
-
- [XPath tests 663]
- expected: FAIL
-
- [XPath tests 664]
- expected: FAIL
-
- [XPath tests 665]
- expected: FAIL
-
- [XPath tests 666]
- expected: FAIL
-
- [XPath tests 667]
- expected: FAIL
-
- [XPath tests 668]
- expected: FAIL
-
- [XPath tests 669]
- expected: FAIL
-
- [XPath tests 670]
- expected: FAIL
-
- [XPath tests 671]
- expected: FAIL
-
- [XPath tests 672]
- expected: FAIL
-
- [XPath tests 673]
- expected: FAIL
-
- [XPath tests 674]
- expected: FAIL
-
- [XPath tests 675]
- expected: FAIL
-
- [XPath tests 676]
- expected: FAIL
-
- [XPath tests 677]
- expected: FAIL
-
- [XPath tests 678]
- expected: FAIL
-
- [XPath tests 679]
- expected: FAIL
-
- [XPath tests 680]
- expected: FAIL
-
- [XPath tests 681]
- expected: FAIL
-
- [XPath tests 682]
- expected: FAIL
-
- [XPath tests 683]
- expected: FAIL
-
- [XPath tests 684]
- expected: FAIL
-
- [XPath tests 685]
- expected: FAIL
-
- [XPath tests 686]
- expected: FAIL
-
- [XPath tests 687]
- expected: FAIL
-
- [XPath tests 688]
- expected: FAIL
-
- [XPath tests 689]
- expected: FAIL
-
- [XPath tests 690]
- expected: FAIL
-
- [XPath tests 691]
- expected: FAIL
-
- [XPath tests 692]
- expected: FAIL
-
- [XPath tests 693]
- expected: FAIL
-
- [XPath tests 694]
- expected: FAIL
-
- [XPath tests 695]
- expected: FAIL
-
- [XPath tests 696]
- expected: FAIL
-
- [XPath tests 697]
- expected: FAIL
-
- [XPath tests 698]
- expected: FAIL
-
- [XPath tests 699]
- expected: FAIL
-
- [XPath tests 700]
- expected: FAIL
-
- [XPath tests 701]
- expected: FAIL
-
- [XPath tests 702]
- expected: FAIL
-
- [XPath tests 703]
- expected: FAIL
-
- [XPath tests 704]
- expected: FAIL
-
- [XPath tests 705]
- expected: FAIL
-
- [XPath tests 706]
- expected: FAIL
-
- [XPath tests 707]
- expected: FAIL
-
- [XPath tests 708]
- expected: FAIL
-
- [XPath tests 709]
- expected: FAIL
-
- [XPath tests 710]
- expected: FAIL
-
- [XPath tests 711]
- expected: FAIL
-
- [XPath tests 712]
- expected: FAIL
-
- [XPath tests 713]
- expected: FAIL
-
- [XPath tests 714]
- expected: FAIL
-
- [XPath tests 715]
- expected: FAIL
-
- [XPath tests 716]
- expected: FAIL
-
- [XPath tests 717]
- expected: FAIL
-
- [XPath tests 718]
- expected: FAIL
-
- [XPath tests 719]
- expected: FAIL
-
- [XPath tests 720]
- expected: FAIL
-
- [XPath tests 721]
- expected: FAIL
-
- [XPath tests 722]
- expected: FAIL
-
- [XPath tests 723]
- expected: FAIL
-
- [XPath tests 724]
- expected: FAIL
-
- [XPath tests 725]
- expected: FAIL
-
- [XPath tests 726]
- expected: FAIL
-
- [XPath tests 727]
- expected: FAIL
-
- [XPath tests 728]
- expected: FAIL
-
- [XPath tests 729]
- expected: FAIL
-
- [XPath tests 730]
- expected: FAIL
-
- [XPath tests 731]
- expected: FAIL
-
- [XPath tests 732]
- expected: FAIL
-
- [XPath tests 733]
- expected: FAIL
-
- [XPath tests 734]
- expected: FAIL
-
- [XPath tests 735]
- expected: FAIL
-
- [XPath tests 736]
- expected: FAIL
-
- [XPath tests 737]
- expected: FAIL
-
- [XPath tests 738]
- expected: FAIL
-
- [XPath tests 739]
- expected: FAIL
-
- [XPath tests 740]
- expected: FAIL
-
- [XPath tests 741]
- expected: FAIL
-
- [XPath tests 742]
- expected: FAIL
-
- [XPath tests 743]
- expected: FAIL
-
- [XPath tests 744]
- expected: FAIL
-
- [XPath tests 745]
- expected: FAIL
-
- [XPath tests 746]
- expected: FAIL
-
- [XPath tests 747]
- expected: FAIL
-
- [XPath tests 748]
- expected: FAIL
-
- [XPath tests 749]
- expected: FAIL
-
- [XPath tests 750]
- expected: FAIL
-
- [XPath tests 751]
- expected: FAIL
-
- [XPath tests 752]
- expected: FAIL
-
- [XPath tests 753]
- expected: FAIL
-
- [XPath tests 754]
- expected: FAIL
-
- [XPath tests 755]
- expected: FAIL
-
- [XPath tests 756]
- expected: FAIL
-
- [XPath tests 757]
- expected: FAIL
-
- [XPath tests 758]
- expected: FAIL
-
- [XPath tests 759]
- expected: FAIL
-
- [XPath tests 760]
- expected: FAIL
-
- [XPath tests 761]
- expected: FAIL
-
- [XPath tests 762]
- expected: FAIL
-
- [XPath tests 763]
- expected: FAIL
-
- [XPath tests 764]
- expected: FAIL
-
- [XPath tests 765]
- expected: FAIL
-
- [XPath tests 766]
- expected: FAIL
-
- [XPath tests 767]
- expected: FAIL
-
- [XPath tests 768]
- expected: FAIL
-
- [XPath tests 769]
- expected: FAIL
-
- [XPath tests 770]
- expected: FAIL
-
- [XPath tests 771]
- expected: FAIL
-
- [XPath tests 772]
- expected: FAIL
-
- [XPath tests 773]
- expected: FAIL
-
- [XPath tests 774]
- expected: FAIL
-
- [XPath tests 775]
- expected: FAIL
-
- [XPath tests 776]
- expected: FAIL
-
- [XPath tests 777]
- expected: FAIL
-
- [XPath tests 778]
- expected: FAIL
-
- [XPath tests 779]
- expected: FAIL
-
- [XPath tests 780]
- expected: FAIL
-
- [XPath tests 781]
- expected: FAIL
-
- [XPath tests 782]
- expected: FAIL
-
- [XPath tests 783]
- expected: FAIL
-
- [XPath tests 784]
- expected: FAIL
-
- [XPath tests 785]
- expected: FAIL
-
- [XPath tests 786]
- expected: FAIL
-
- [XPath tests 787]
- expected: FAIL
-
- [XPath tests 788]
- expected: FAIL
-
- [XPath tests 789]
- expected: FAIL
-
- [XPath tests 790]
- expected: FAIL
-
- [XPath tests 791]
- expected: FAIL
-
- [XPath tests 792]
- expected: FAIL
-
- [XPath tests 793]
- expected: FAIL
-
- [XPath tests 794]
- expected: FAIL
-
- [XPath tests 795]
- expected: FAIL
-
- [XPath tests 796]
- expected: FAIL
-
- [XPath tests 797]
- expected: FAIL
-
- [XPath tests 798]
- expected: FAIL
-
- [XPath tests 799]
- expected: FAIL
-
- [XPath tests 800]
- expected: FAIL
-
- [XPath tests 801]
- expected: FAIL
-
- [XPath tests 802]
- expected: FAIL
-
- [XPath tests 803]
- expected: FAIL
-
- [XPath tests 804]
- expected: FAIL
-
- [XPath tests 805]
- expected: FAIL
-
- [XPath tests 806]
- expected: FAIL
-
- [XPath tests 807]
- expected: FAIL
-
- [XPath tests 808]
- expected: FAIL
-
- [XPath tests 809]
- expected: FAIL
-
- [XPath tests 810]
- expected: FAIL
-
- [XPath tests 811]
- expected: FAIL
-
- [XPath tests 812]
- expected: FAIL
-
- [XPath tests 813]
- expected: FAIL
-
- [XPath tests 814]
- expected: FAIL
-
- [XPath tests 815]
- expected: FAIL
-
- [XPath tests 816]
- expected: FAIL
-
- [XPath tests 817]
- expected: FAIL
-
- [XPath tests 818]
- expected: FAIL
-
- [XPath tests 819]
- expected: FAIL
-
- [XPath tests 820]
- expected: FAIL
-
- [XPath tests 821]
- expected: FAIL
-
- [XPath tests 822]
- expected: FAIL
-
- [XPath tests 823]
- expected: FAIL
-
- [XPath tests 824]
- expected: FAIL
-
- [XPath tests 825]
- expected: FAIL
-
- [XPath tests 826]
- expected: FAIL
-
- [XPath tests 827]
- expected: FAIL
-
- [XPath tests 828]
- expected: FAIL
-
- [XPath tests 829]
- expected: FAIL
-
- [XPath tests 830]
- expected: FAIL
-
- [XPath tests 831]
- expected: FAIL
-
- [XPath tests 832]
- expected: FAIL
-
- [XPath tests 833]
- expected: FAIL
-
- [XPath tests 834]
- expected: FAIL
-
- [XPath tests 835]
- expected: FAIL
-
- [XPath tests 836]
- expected: FAIL
-
- [XPath tests 837]
- expected: FAIL
-
- [XPath tests 838]
- expected: FAIL
-
- [XPath tests 839]
- expected: FAIL
-
- [XPath tests 840]
- expected: FAIL
-
- [XPath tests 841]
- expected: FAIL
-
- [XPath tests 842]
- expected: FAIL
-
- [XPath tests 843]
- expected: FAIL
-
- [XPath tests 844]
- expected: FAIL
-
- [XPath tests 845]
- expected: FAIL
-
- [XPath tests 846]
- expected: FAIL
-
- [XPath tests 847]
- expected: FAIL
-
- [XPath tests 848]
- expected: FAIL
-
- [XPath tests 849]
- expected: FAIL
-
- [XPath tests 850]
- expected: FAIL
-
- [XPath tests 851]
- expected: FAIL
-
- [XPath tests 852]
- expected: FAIL
-
- [XPath tests 853]
- expected: FAIL
-
- [XPath tests 854]
- expected: FAIL
-
- [XPath tests 855]
- expected: FAIL
-
- [XPath tests 856]
- expected: FAIL
-
- [XPath tests 857]
- expected: FAIL
-
- [XPath tests 858]
- expected: FAIL
-
- [XPath tests 859]
- expected: FAIL
-
- [XPath tests 860]
- expected: FAIL
-
- [XPath tests 861]
- expected: FAIL
-
- [XPath tests 862]
- expected: FAIL
-
- [XPath tests 863]
- expected: FAIL
-
- [XPath tests 864]
- expected: FAIL
-
- [XPath tests 865]
- expected: FAIL
-
- [XPath tests 866]
- expected: FAIL
-
- [XPath tests 867]
- expected: FAIL
-
- [XPath tests 868]
- expected: FAIL
-
- [XPath tests 869]
- expected: FAIL
-
- [XPath tests 870]
- expected: FAIL
-
- [XPath tests 871]
- expected: FAIL
-
- [XPath tests 872]
- expected: FAIL
-
- [XPath tests 873]
- expected: FAIL
-
- [XPath tests 874]
- expected: FAIL
-
- [XPath tests 875]
- expected: FAIL
-
- [XPath tests 876]
- expected: FAIL
-
- [XPath tests 877]
- expected: FAIL
-
- [XPath tests 878]
- expected: FAIL
-
- [XPath tests 879]
- expected: FAIL
-
- [XPath tests 880]
- expected: FAIL
-
- [XPath tests 881]
- expected: FAIL
-
- [XPath tests 882]
- expected: FAIL
-
- [XPath tests 883]
- expected: FAIL
-
- [XPath tests 884]
- expected: FAIL
-
- [XPath tests 885]
- expected: FAIL
-
- [XPath tests 886]
- expected: FAIL
-
- [XPath tests 887]
- expected: FAIL
-
- [XPath tests 888]
- expected: FAIL
-
- [XPath tests 889]
- expected: FAIL
-
- [XPath tests 890]
- expected: FAIL
-
- [XPath tests 891]
- expected: FAIL
-
- [XPath tests 892]
- expected: FAIL
-
- [XPath tests 893]
- expected: FAIL
-
- [XPath tests 894]
- expected: FAIL
-
- [XPath tests 895]
- expected: FAIL
-
- [XPath tests 896]
- expected: FAIL
-
- [XPath tests 897]
- expected: FAIL
-
- [XPath tests 898]
- expected: FAIL
-
- [XPath tests 899]
- expected: FAIL
-
- [XPath tests 900]
- expected: FAIL
-
- [XPath tests 901]
- expected: FAIL
-
- [XPath tests 902]
- expected: FAIL
-
- [XPath tests 903]
- expected: FAIL
-
- [XPath tests 904]
- expected: FAIL
-
- [XPath tests 905]
- expected: FAIL
-
- [XPath tests 906]
- expected: FAIL
-
- [XPath tests 907]
- expected: FAIL
-
- [XPath tests 908]
- expected: FAIL
-
- [XPath tests 909]
- expected: FAIL
-
- [XPath tests 910]
- expected: FAIL
-
- [XPath tests 911]
- expected: FAIL
-
- [XPath tests 912]
- expected: FAIL
-
- [XPath tests 913]
- expected: FAIL
-
- [XPath tests 914]
- expected: FAIL
-
- [XPath tests 915]
- expected: FAIL
-
- [XPath tests 916]
- expected: FAIL
-
- [XPath tests 917]
- expected: FAIL
-
- [XPath tests 918]
- expected: FAIL
-
- [XPath tests 919]
- expected: FAIL
-
- [XPath tests 920]
- expected: FAIL
-
- [XPath tests 921]
- expected: FAIL
-
- [XPath tests 922]
- expected: FAIL
-
- [XPath tests 923]
- expected: FAIL
-
- [XPath tests 924]
- expected: FAIL
-
- [XPath tests 925]
- expected: FAIL
-
- [XPath tests 926]
- expected: FAIL
-
- [XPath tests 927]
- expected: FAIL
-
- [XPath tests 928]
- expected: FAIL
-
- [XPath tests 929]
- expected: FAIL
-
- [XPath tests 930]
- expected: FAIL
-
- [XPath tests 931]
- expected: FAIL
-
- [XPath tests 932]
- expected: FAIL
-
- [XPath tests 933]
- expected: FAIL
-
- [XPath tests 934]
- expected: FAIL
-
- [XPath tests 935]
- expected: FAIL
-
- [XPath tests 936]
- expected: FAIL
-
- [XPath tests 937]
- expected: FAIL
-
- [XPath tests 938]
- expected: FAIL
-
- [XPath tests 939]
- expected: FAIL
-
- [XPath tests 940]
- expected: FAIL
-
- [XPath tests 941]
- expected: FAIL
-
- [XPath tests 942]
- expected: FAIL
-
- [XPath tests 943]
- expected: FAIL
-
- [XPath tests 944]
- expected: FAIL
-
- [XPath tests 945]
- expected: FAIL
-
- [XPath tests 946]
- expected: FAIL
-
- [XPath tests 947]
- expected: FAIL
-
- [XPath tests 948]
- expected: FAIL
-
- [XPath tests 949]
- expected: FAIL
-
- [XPath tests 950]
- expected: FAIL
-
- [XPath tests 951]
- expected: FAIL
-
- [XPath tests 952]
- expected: FAIL
-
- [XPath tests 953]
- expected: FAIL
-
- [XPath tests 954]
- expected: FAIL
-
- [XPath tests 955]
- expected: FAIL
-
- [XPath tests 956]
- expected: FAIL
-
- [XPath tests 957]
- expected: FAIL
-
- [XPath tests 958]
- expected: FAIL
-
- [XPath tests 959]
- expected: FAIL
-
- [XPath tests 960]
- expected: FAIL
-
- [XPath tests 961]
- expected: FAIL
-
- [XPath tests 962]
- expected: FAIL
-
- [XPath tests 963]
- expected: FAIL
-
- [XPath tests 964]
- expected: FAIL
-
- [XPath tests 965]
- expected: FAIL
-
- [XPath tests 966]
- expected: FAIL
-
- [XPath tests 967]
- expected: FAIL
-
- [XPath tests 968]
- expected: FAIL
-
- [XPath tests 969]
- expected: FAIL
-
- [XPath tests 970]
- expected: FAIL
-
- [XPath tests 971]
- expected: FAIL
-
- [XPath tests 972]
- expected: FAIL
-
- [XPath tests 973]
- expected: FAIL
-
- [XPath tests 974]
- expected: FAIL
-
- [XPath tests 975]
- expected: FAIL
-
- [XPath tests 976]
- expected: FAIL
-
- [XPath tests 977]
- expected: FAIL
-
- [XPath tests 978]
- expected: FAIL
-
- [XPath tests 979]
- expected: FAIL
-
- [XPath tests 980]
- expected: FAIL
-
- [XPath tests 981]
- expected: FAIL
-
- [XPath tests 982]
- expected: FAIL
-
- [XPath tests 983]
- expected: FAIL
-
- [XPath tests 984]
- expected: FAIL
-
- [XPath tests 985]
- expected: FAIL
-
- [XPath tests 986]
- expected: FAIL
-
- [XPath tests 987]
- expected: FAIL
-
- [XPath tests 988]
- expected: FAIL
-
- [XPath tests 989]
- expected: FAIL
-
- [XPath tests 990]
- expected: FAIL
-
- [XPath tests 991]
- expected: FAIL
-
- [XPath tests 992]
- expected: FAIL
-
- [XPath tests 993]
- expected: FAIL
-
- [XPath tests 994]
- expected: FAIL
-
- [XPath tests 995]
- expected: FAIL
-
- [XPath tests 996]
- expected: FAIL
-
- [XPath tests 997]
- expected: FAIL
-
- [XPath tests 998]
- expected: FAIL
-
- [XPath tests 999]
- expected: FAIL
-
- [XPath tests 1000]
- expected: FAIL
-
- [XPath tests 1001]
- expected: FAIL
-
- [XPath tests 1002]
- expected: FAIL
-
- [XPath tests 1003]
- expected: FAIL
-
- [XPath tests 1004]
- expected: FAIL
-
- [XPath tests 1005]
- expected: FAIL
-
- [XPath tests 1006]
- expected: FAIL
-
- [XPath tests 1007]
- expected: FAIL
-
- [XPath tests 1008]
- expected: FAIL
-
- [XPath tests 1009]
- expected: FAIL
-
- [XPath tests 1010]
- expected: FAIL
-
- [XPath tests 1011]
- expected: FAIL
-
- [XPath tests 1012]
- expected: FAIL
-
- [XPath tests 1013]
- expected: FAIL
-
- [XPath tests 1014]
- expected: FAIL
-
- [XPath tests 1015]
- expected: FAIL
-
- [XPath tests 1016]
- expected: FAIL
-
- [XPath tests 1017]
- expected: FAIL
-
- [XPath tests 1018]
- expected: FAIL
-
- [XPath tests 1019]
- expected: FAIL
-
- [XPath tests 1020]
- expected: FAIL
-
- [XPath tests 1021]
- expected: FAIL
-
- [XPath tests 1022]
- expected: FAIL
-
- [XPath tests 1023]
- expected: FAIL
diff --git a/tests/wpt/meta/fetch/content-encoding/br/bad-br-body.https.any.js.ini b/tests/wpt/meta/fetch/content-encoding/br/bad-br-body.https.any.js.ini
index 2a7f8c45be1..16e5901cca3 100644
--- a/tests/wpt/meta/fetch/content-encoding/br/bad-br-body.https.any.js.ini
+++ b/tests/wpt/meta/fetch/content-encoding/br/bad-br-body.https.any.js.ini
@@ -1,3 +1,15 @@
[bad-br-body.https.any.html]
[Consuming the body of a resource with bad br content with arrayBuffer() should reject]
expected: FAIL
+
+ [Consuming the body of a resource with bad br content with blob() should reject]
+ expected: FAIL
+
+ [Consuming the body of a resource with bad br content with bytes() should reject]
+ expected: FAIL
+
+ [Consuming the body of a resource with bad br content with json() should reject]
+ expected: FAIL
+
+ [Consuming the body of a resource with bad br content with text() should reject]
+ expected: FAIL
diff --git a/tests/wpt/meta/fetch/content-encoding/gzip/bad-gzip-body.any.js.ini b/tests/wpt/meta/fetch/content-encoding/gzip/bad-gzip-body.any.js.ini
index 24a7b7bcc7f..aec86e6cdb2 100644
--- a/tests/wpt/meta/fetch/content-encoding/gzip/bad-gzip-body.any.js.ini
+++ b/tests/wpt/meta/fetch/content-encoding/gzip/bad-gzip-body.any.js.ini
@@ -11,6 +11,9 @@
[Consuming the body of a resource with bad gzip content with text() should reject]
expected: FAIL
+ [Consuming the body of a resource with bad gzip content with bytes() should reject]
+ expected: FAIL
+
[bad-gzip-body.any.worker.html]
[Consuming the body of a resource with bad gzip content with arrayBuffer() should reject]
@@ -25,6 +28,9 @@
[Consuming the body of a resource with bad gzip content with text() should reject]
expected: FAIL
+ [Consuming the body of a resource with bad gzip content with bytes() should reject]
+ expected: FAIL
+
[bad-gzip-body.any.serviceworker.html]
expected: ERROR
diff --git a/tests/wpt/meta/fetch/content-encoding/zstd/bad-zstd-body.https.any.js.ini b/tests/wpt/meta/fetch/content-encoding/zstd/bad-zstd-body.https.any.js.ini
index ed17fcbaf81..121ae28c821 100644
--- a/tests/wpt/meta/fetch/content-encoding/zstd/bad-zstd-body.https.any.js.ini
+++ b/tests/wpt/meta/fetch/content-encoding/zstd/bad-zstd-body.https.any.js.ini
@@ -11,6 +11,9 @@
[Consuming the body of a resource with bad zstd content with text() should reject]
expected: FAIL
+ [Consuming the body of a resource with bad zstd content with bytes() should reject]
+ expected: FAIL
+
[bad-zstd-body.https.any.worker.html]
[Consuming the body of a resource with bad zstd content with arrayBuffer() should reject]
@@ -25,6 +28,9 @@
[Consuming the body of a resource with bad zstd content with text() should reject]
expected: FAIL
+ [Consuming the body of a resource with bad zstd content with bytes() should reject]
+ expected: FAIL
+
[bad-zstd-body.https.any.sharedworker.html]
expected: ERROR
diff --git a/tests/wpt/meta/fetch/metadata/redirect/multiple-redirect-https-downgrade-upgrade.sub.html.ini b/tests/wpt/meta/fetch/metadata/redirect/multiple-redirect-https-downgrade-upgrade.sub.html.ini
index 77fa4b61164..46f58cc786e 100644
--- a/tests/wpt/meta/fetch/metadata/redirect/multiple-redirect-https-downgrade-upgrade.sub.html.ini
+++ b/tests/wpt/meta/fetch/metadata/redirect/multiple-redirect-https-downgrade-upgrade.sub.html.ini
@@ -33,9 +33,6 @@
[Https downgrade-upgrade embed]
expected: TIMEOUT
- [Https downgrade-upgrade preload]
- expected: TIMEOUT
-
[Https downgrade-upgrade iframe: sec-fetch-mode]
expected: FAIL
diff --git a/tests/wpt/meta/fetch/nosniff/importscripts.html.ini b/tests/wpt/meta/fetch/nosniff/importscripts.html.ini
deleted file mode 100644
index 50d9a81d542..00000000000
--- a/tests/wpt/meta/fetch/nosniff/importscripts.html.ini
+++ /dev/null
@@ -1,4 +0,0 @@
-[importscripts.html]
- expected: ERROR
- [Test importScripts()]
- expected: TIMEOUT
diff --git a/tests/wpt/meta/fetch/private-network-access/mixed-content-fetch.tentative.https.window.js.ini b/tests/wpt/meta/fetch/private-network-access/mixed-content-fetch.tentative.https.window.js.ini
deleted file mode 100644
index 695ae5a48a0..00000000000
--- a/tests/wpt/meta/fetch/private-network-access/mixed-content-fetch.tentative.https.window.js.ini
+++ /dev/null
@@ -1,156 +0,0 @@
-[mixed-content-fetch.tentative.https.window.html]
- [https-local to http-local: wrong targetAddressSpace "unknown".]
- expected: FAIL
-
- [https-local to http-local: wrong targetAddressSpace "private".]
- expected: FAIL
-
- [https-local to http-local: wrong targetAddressSpace "public".]
- expected: FAIL
-
- [https-local to http-local: not a private network request.]
- expected: FAIL
-
- [https-local to http-private: wrong targetAddressSpace "unknown".]
- expected: FAIL
-
- [https-local to http-private: wrong targetAddressSpace "local".]
- expected: FAIL
-
- [https-local to http-private: wrong targetAddressSpace "public".]
- expected: FAIL
-
- [https-local to http-private: not a private network request.]
- expected: FAIL
-
- [https-local to http-public: wrong targetAddressSpace "unknown".]
- expected: FAIL
-
- [https-local to http-public: wrong targetAddressSpace "local".]
- expected: FAIL
-
- [https-local to http-public: wrong targetAddressSpace "private".]
- expected: FAIL
-
- [https-local to http-public: not a private network request.]
- expected: FAIL
-
- [https-private to http-local: missing targetAddressSpace.]
- expected: FAIL
-
- [https-private to http-local: wrong targetAddressSpace "unknown".]
- expected: FAIL
-
- [https-private to http-local: wrong targetAddressSpace "private".]
- expected: FAIL
-
- [https-private to http-local: wrong targetAddressSpace "public".]
- expected: FAIL
-
- [https-private to http-local: failed preflight.]
- expected: FAIL
-
- [https-private to http-local: success.]
- expected: FAIL
-
- [https-private to http-private: wrong targetAddressSpace "unknown".]
- expected: FAIL
-
- [https-private to http-private: wrong targetAddressSpace "local".]
- expected: FAIL
-
- [https-private to http-private: wrong targetAddressSpace "public".]
- expected: FAIL
-
- [https-private to http-private: not a private network request.]
- expected: FAIL
-
- [https-private to http-public: wrong targetAddressSpace "unknown".]
- expected: FAIL
-
- [https-private to http-public: wrong targetAddressSpace "local".]
- expected: FAIL
-
- [https-private to http-public: wrong targetAddressSpace "private".]
- expected: FAIL
-
- [https-private to http-public: not a private network request.]
- expected: FAIL
-
- [https-public to http-local: missing targetAddressSpace.]
- expected: FAIL
-
- [https-public to http-local: wrong targetAddressSpace "unknown".]
- expected: FAIL
-
- [https-public to http-local: wrong targetAddressSpace "private".]
- expected: FAIL
-
- [https-public to http-local: wrong targetAddressSpace "public".]
- expected: FAIL
-
- [https-public to http-local: failed preflight.]
- expected: FAIL
-
- [https-public to http-local: success.]
- expected: FAIL
-
- [https-public to http-private: missing targetAddressSpace.]
- expected: FAIL
-
- [https-public to http-private: wrong targetAddressSpace "unknown".]
- expected: FAIL
-
- [https-public to http-private: wrong targetAddressSpace "local".]
- expected: FAIL
-
- [https-public to http-private: wrong targetAddressSpace "public".]
- expected: FAIL
-
- [https-public to http-private: failed preflight.]
- expected: FAIL
-
- [https-public to http-private: success.]
- expected: FAIL
-
- [https-public to http-public: wrong targetAddressSpace "unknown".]
- expected: FAIL
-
- [https-public to http-public: wrong targetAddressSpace "local".]
- expected: FAIL
-
- [https-public to http-public: wrong targetAddressSpace "private".]
- expected: FAIL
-
- [https-public to http-public: not a private network request.]
- expected: FAIL
-
- [https-treat-as-public to http-local: wrong targetAddressSpace "private".]
- expected: FAIL
-
- [https-treat-as-public to http-private: wrong targetAddressSpace "local".]
- expected: FAIL
-
- [https-treat-as-public to http-private: success.]
- expected: FAIL
-
- [https-private to http-local: PUT success.]
- expected: FAIL
-
- [https-private to http-local: no-cors success.]
- expected: FAIL
-
- [https-public to http-local: PUT success.]
- expected: FAIL
-
- [https-public to http-local: no-cors success.]
- expected: FAIL
-
- [https-public to http-private: PUT success.]
- expected: FAIL
-
- [https-public to http-private: no-cors success.]
- expected: FAIL
-
- [https-treat-as-public to http-local: success.]
- expected: FAIL
diff --git a/tests/wpt/meta/fetch/private-network-access/window-open-existing.tentative.https.window.js.ini b/tests/wpt/meta/fetch/private-network-access/window-open-existing.tentative.https.window.js.ini
deleted file mode 100644
index 6bcaf322518..00000000000
--- a/tests/wpt/meta/fetch/private-network-access/window-open-existing.tentative.https.window.js.ini
+++ /dev/null
@@ -1,72 +0,0 @@
-[window-open-existing.tentative.https.window.html?include=from-treat-as-public]
- [treat-as-public-address to local: failed preflight.]
- expected: FAIL
-
- [treat-as-public-address to local: missing CORS headers.]
- expected: FAIL
-
- [treat-as-public-address to local: missing PNA header.]
- expected: FAIL
-
- [treat-as-public-address to local: success.]
- expected: FAIL
-
- [treat-as-public-address to private: failed preflight.]
- expected: FAIL
-
- [treat-as-public-address to private: missing CORS headers.]
- expected: FAIL
-
- [treat-as-public-address to private: missing PNA header.]
- expected: FAIL
-
- [treat-as-public-address to private: success.]
- expected: FAIL
-
-
-[window-open-existing.tentative.https.window.html?include=from-public]
- [public to local: failed preflight.]
- expected: FAIL
-
- [public to local: missing CORS headers.]
- expected: FAIL
-
- [public to local: missing PNA header.]
- expected: FAIL
-
- [public to local: success.]
- expected: FAIL
-
- [public to private: failed preflight.]
- expected: FAIL
-
- [public to private: missing CORS headers.]
- expected: FAIL
-
- [public to private: missing PNA header.]
- expected: FAIL
-
- [public to private: success.]
- expected: FAIL
-
- [public to public redirected to private: missing CORS headers.]
- expected: FAIL
-
- [public to public to private: success.]
- expected: FAIL
-
-
-[window-open-existing.tentative.https.window.html?include=from-local]
-
-[window-open-existing.tentative.https.window.html?include=from-private]
- [private to local: failed preflight.]
- expected: FAIL
-
- [private to local: missing CORS headers.]
- expected: FAIL
-
- [private to local: missing PNA header.]
- expected: FAIL
-
- [private to local: success.]
- expected: FAIL
diff --git a/tests/wpt/meta/focus/focus-contenteditable-element-in-iframe-scroll-into-view.html.ini b/tests/wpt/meta/focus/focus-contenteditable-element-in-iframe-scroll-into-view.html.ini
new file mode 100644
index 00000000000..1740303b284
--- /dev/null
+++ b/tests/wpt/meta/focus/focus-contenteditable-element-in-iframe-scroll-into-view.html.ini
@@ -0,0 +1,3 @@
+[focus-contenteditable-element-in-iframe-scroll-into-view.html]
+ [Check contenteditable element in an iframe scroll into view on second focusing]
+ expected: FAIL
diff --git a/tests/wpt/meta/html/browsers/browsing-the-web/navigating-across-documents/008.html.ini b/tests/wpt/meta/html/browsers/browsing-the-web/navigating-across-documents/008.html.ini
deleted file mode 100644
index c253f779d78..00000000000
--- a/tests/wpt/meta/html/browsers/browsing-the-web/navigating-across-documents/008.html.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[008.html]
- [Link with onclick form submit to javascript url and href navigation ]
- expected: FAIL
diff --git a/tests/wpt/meta/html/browsers/browsing-the-web/navigating-across-documents/009.html.ini b/tests/wpt/meta/html/browsers/browsing-the-web/navigating-across-documents/009.html.ini
new file mode 100644
index 00000000000..3fb21c9b2c6
--- /dev/null
+++ b/tests/wpt/meta/html/browsers/browsing-the-web/navigating-across-documents/009.html.ini
@@ -0,0 +1,3 @@
+[009.html]
+ [Link with onclick form submit to javascript url with document.write and href navigation ]
+ expected: FAIL
diff --git a/tests/wpt/meta/webdriver/tests/classic/set_timeouts/set.py.ini b/tests/wpt/meta/html/browsers/history/the-history-interface/001.html.ini
index bfc9d7723d9..b0bdba7f308 100644
--- a/tests/wpt/meta/webdriver/tests/classic/set_timeouts/set.py.ini
+++ b/tests/wpt/meta/html/browsers/history/the-history-interface/001.html.ini
@@ -1,2 +1,2 @@
-[set.py]
+[001.html]
expected: TIMEOUT
diff --git a/tests/wpt/meta/html/browsers/history/the-history-interface/traverse_the_history_3.html.ini b/tests/wpt/meta/html/browsers/history/the-history-interface/traverse_the_history_3.html.ini
new file mode 100644
index 00000000000..a03a8322165
--- /dev/null
+++ b/tests/wpt/meta/html/browsers/history/the-history-interface/traverse_the_history_3.html.ini
@@ -0,0 +1,3 @@
+[traverse_the_history_3.html]
+ [Multiple history traversals, last would be aborted]
+ expected: FAIL
diff --git a/tests/wpt/meta/html/canvas/element/manual/imagebitmap/createImageBitmap-origin.sub.html.ini b/tests/wpt/meta/html/canvas/element/manual/imagebitmap/createImageBitmap-origin.sub.html.ini
index d7226bfed74..0420669cc09 100644
--- a/tests/wpt/meta/html/canvas/element/manual/imagebitmap/createImageBitmap-origin.sub.html.ini
+++ b/tests/wpt/meta/html/canvas/element/manual/imagebitmap/createImageBitmap-origin.sub.html.ini
@@ -1,5 +1,4 @@
[createImageBitmap-origin.sub.html]
- expected: TIMEOUT
[redirected to cross-origin HTMLVideoElement: origin unclear 2dContext.drawImage]
expected: FAIL
diff --git a/tests/wpt/meta/html/canvas/element/manual/imagebitmap/createImageBitmap-transfer.html.ini b/tests/wpt/meta/html/canvas/element/manual/imagebitmap/createImageBitmap-transfer.html.ini
index 20be1f3b9e5..495a1789274 100644
--- a/tests/wpt/meta/html/canvas/element/manual/imagebitmap/createImageBitmap-transfer.html.ini
+++ b/tests/wpt/meta/html/canvas/element/manual/imagebitmap/createImageBitmap-transfer.html.ini
@@ -1,4 +1,5 @@
[createImageBitmap-transfer.html]
+ expected: ERROR
[Transfer ImageBitmap created from a vector HTMLImageElement]
expected: FAIL
diff --git a/tests/wpt/meta/html/dom/idlharness.https.html.ini b/tests/wpt/meta/html/dom/idlharness.https.html.ini
index 81d2aa5b8a5..b2ea5b118c1 100644
--- a/tests/wpt/meta/html/dom/idlharness.https.html.ini
+++ b/tests/wpt/meta/html/dom/idlharness.https.html.ini
@@ -5455,18 +5455,6 @@
[HTMLHeadingElement interface: document.createElement("h1") must inherit property "align" with the proper type]
expected: FAIL
- [HTMLHRElement interface: attribute noShade]
- expected: FAIL
-
- [HTMLHRElement interface: attribute size]
- expected: FAIL
-
- [HTMLHRElement interface: document.createElement("hr") must inherit property "noShade" with the proper type]
- expected: FAIL
-
- [HTMLHRElement interface: document.createElement("hr") must inherit property "size" with the proper type]
- expected: FAIL
-
[HTMLOListElement interface: attribute reversed]
expected: FAIL
diff --git a/tests/wpt/meta/html/dom/reflection-grouping.html.ini b/tests/wpt/meta/html/dom/reflection-grouping.html.ini
index 556eea039e9..ec7075bc5ab 100644
--- a/tests/wpt/meta/html/dom/reflection-grouping.html.ini
+++ b/tests/wpt/meta/html/dom/reflection-grouping.html.ini
@@ -383,234 +383,6 @@
[hr.tabIndex: IDL set to -2147483648]
expected: FAIL
- [hr.noShade: typeof IDL attribute]
- expected: FAIL
-
- [hr.noShade: IDL get with DOM attribute unset]
- expected: FAIL
-
- [hr.noShade: setAttribute() to ""]
- expected: FAIL
-
- [hr.noShade: setAttribute() to " foo "]
- expected: FAIL
-
- [hr.noShade: setAttribute() to undefined]
- expected: FAIL
-
- [hr.noShade: setAttribute() to null]
- expected: FAIL
-
- [hr.noShade: setAttribute() to 7]
- expected: FAIL
-
- [hr.noShade: setAttribute() to 1.5]
- expected: FAIL
-
- [hr.noShade: setAttribute() to "5%"]
- expected: FAIL
-
- [hr.noShade: setAttribute() to "+100"]
- expected: FAIL
-
- [hr.noShade: setAttribute() to ".5"]
- expected: FAIL
-
- [hr.noShade: setAttribute() to true]
- expected: FAIL
-
- [hr.noShade: setAttribute() to false]
- expected: FAIL
-
- [hr.noShade: setAttribute() to object "[object Object\]"]
- expected: FAIL
-
- [hr.noShade: setAttribute() to NaN]
- expected: FAIL
-
- [hr.noShade: setAttribute() to Infinity]
- expected: FAIL
-
- [hr.noShade: setAttribute() to -Infinity]
- expected: FAIL
-
- [hr.noShade: setAttribute() to "\\0"]
- expected: FAIL
-
- [hr.noShade: setAttribute() to object "test-toString"]
- expected: FAIL
-
- [hr.noShade: setAttribute() to object "test-valueOf"]
- expected: FAIL
-
- [hr.noShade: setAttribute() to "noShade"]
- expected: FAIL
-
- [hr.noShade: IDL set to ""]
- expected: FAIL
-
- [hr.noShade: IDL set to " foo "]
- expected: FAIL
-
- [hr.noShade: IDL set to undefined]
- expected: FAIL
-
- [hr.noShade: IDL set to null]
- expected: FAIL
-
- [hr.noShade: IDL set to 7]
- expected: FAIL
-
- [hr.noShade: IDL set to 1.5]
- expected: FAIL
-
- [hr.noShade: IDL set to "5%"]
- expected: FAIL
-
- [hr.noShade: IDL set to "+100"]
- expected: FAIL
-
- [hr.noShade: IDL set to ".5"]
- expected: FAIL
-
- [hr.noShade: IDL set to false]
- expected: FAIL
-
- [hr.noShade: IDL set to object "[object Object\]"]
- expected: FAIL
-
- [hr.noShade: IDL set to NaN]
- expected: FAIL
-
- [hr.noShade: IDL set to Infinity]
- expected: FAIL
-
- [hr.noShade: IDL set to -Infinity]
- expected: FAIL
-
- [hr.noShade: IDL set to "\\0"]
- expected: FAIL
-
- [hr.noShade: IDL set to object "test-toString"]
- expected: FAIL
-
- [hr.noShade: IDL set to object "test-valueOf"]
- expected: FAIL
-
- [hr.size: typeof IDL attribute]
- expected: FAIL
-
- [hr.size: IDL get with DOM attribute unset]
- expected: FAIL
-
- [hr.size: setAttribute() to ""]
- expected: FAIL
-
- [hr.size: setAttribute() to " \\0\\x01\\x02\\x03\\x04\\x05\\x06\\x07 \\b\\t\\n\\v\\f\\r\\x0e\\x0f \\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17 \\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f foo "]
- expected: FAIL
-
- [hr.size: setAttribute() to undefined]
- expected: FAIL
-
- [hr.size: setAttribute() to 7]
- expected: FAIL
-
- [hr.size: setAttribute() to 1.5]
- expected: FAIL
-
- [hr.size: setAttribute() to "5%"]
- expected: FAIL
-
- [hr.size: setAttribute() to "+100"]
- expected: FAIL
-
- [hr.size: setAttribute() to ".5"]
- expected: FAIL
-
- [hr.size: setAttribute() to true]
- expected: FAIL
-
- [hr.size: setAttribute() to false]
- expected: FAIL
-
- [hr.size: setAttribute() to object "[object Object\]"]
- expected: FAIL
-
- [hr.size: setAttribute() to NaN]
- expected: FAIL
-
- [hr.size: setAttribute() to Infinity]
- expected: FAIL
-
- [hr.size: setAttribute() to -Infinity]
- expected: FAIL
-
- [hr.size: setAttribute() to "\\0"]
- expected: FAIL
-
- [hr.size: setAttribute() to null]
- expected: FAIL
-
- [hr.size: setAttribute() to object "test-toString"]
- expected: FAIL
-
- [hr.size: setAttribute() to object "test-valueOf"]
- expected: FAIL
-
- [hr.size: IDL set to ""]
- expected: FAIL
-
- [hr.size: IDL set to " \\0\\x01\\x02\\x03\\x04\\x05\\x06\\x07 \\b\\t\\n\\v\\f\\r\\x0e\\x0f \\x10\\x11\\x12\\x13\\x14\\x15\\x16\\x17 \\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f foo "]
- expected: FAIL
-
- [hr.size: IDL set to undefined]
- expected: FAIL
-
- [hr.size: IDL set to 7]
- expected: FAIL
-
- [hr.size: IDL set to 1.5]
- expected: FAIL
-
- [hr.size: IDL set to "5%"]
- expected: FAIL
-
- [hr.size: IDL set to "+100"]
- expected: FAIL
-
- [hr.size: IDL set to ".5"]
- expected: FAIL
-
- [hr.size: IDL set to true]
- expected: FAIL
-
- [hr.size: IDL set to false]
- expected: FAIL
-
- [hr.size: IDL set to object "[object Object\]"]
- expected: FAIL
-
- [hr.size: IDL set to NaN]
- expected: FAIL
-
- [hr.size: IDL set to Infinity]
- expected: FAIL
-
- [hr.size: IDL set to -Infinity]
- expected: FAIL
-
- [hr.size: IDL set to "\\0"]
- expected: FAIL
-
- [hr.size: IDL set to null]
- expected: FAIL
-
- [hr.size: IDL set to object "test-toString"]
- expected: FAIL
-
- [hr.size: IDL set to object "test-valueOf"]
- expected: FAIL
-
[pre.accessKey: typeof IDL attribute]
expected: FAIL
diff --git a/tests/wpt/meta/html/semantics/embedded-content/media-elements/media_fragment_seek.html.ini b/tests/wpt/meta/html/semantics/embedded-content/media-elements/media_fragment_seek.html.ini
deleted file mode 100644
index dbbc149ee4a..00000000000
--- a/tests/wpt/meta/html/semantics/embedded-content/media-elements/media_fragment_seek.html.ini
+++ /dev/null
@@ -1,2 +0,0 @@
-[media_fragment_seek.html]
- expected: CRASH
diff --git a/tests/wpt/meta/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_escaping-1.html.ini b/tests/wpt/meta/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_escaping-1.html.ini
index 24903b5f66f..d7e7d1b9815 100644
--- a/tests/wpt/meta/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_escaping-1.html.ini
+++ b/tests/wpt/meta/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_escaping-1.html.ini
@@ -1,4 +1,4 @@
[iframe_sandbox_popups_escaping-1.html]
- expected: TIMEOUT
+ expected: CRASH
[Check that popups from a sandboxed iframe escape the sandbox if\n allow-popups-to-escape-sandbox is used]
expected: TIMEOUT
diff --git a/tests/wpt/meta/html/semantics/permission-element/negative-offset-and-margin.tentative.html.ini b/tests/wpt/meta/html/semantics/permission-element/negative-offset-and-margin.tentative.html.ini
deleted file mode 100644
index 75e70650007..00000000000
--- a/tests/wpt/meta/html/semantics/permission-element/negative-offset-and-margin.tentative.html.ini
+++ /dev/null
@@ -1,12 +0,0 @@
-[negative-offset-and-margin.tentative.html]
- [Negative margins/offset should be changed to 0px]
- expected: FAIL
-
- [Expressions margins/offset should always return at least 0px]
- expected: FAIL
-
- [Negative margins/offset should be changed to 4px]
- expected: FAIL
-
- [Expressions margins/offset should always return at least 4px]
- expected: FAIL
diff --git a/tests/wpt/meta/html/semantics/permission-element/negative-offset.tentative.html.ini b/tests/wpt/meta/html/semantics/permission-element/negative-offset.tentative.html.ini
new file mode 100644
index 00000000000..74386d1c491
--- /dev/null
+++ b/tests/wpt/meta/html/semantics/permission-element/negative-offset.tentative.html.ini
@@ -0,0 +1,9 @@
+[negative-offset.tentative.html]
+ [Negative offset should be changed to 0px]
+ expected: FAIL
+
+ [Expressions offset min(-50px, 50px) should return at least 0px]
+ expected: FAIL
+
+ [Expressions offset clamp(-100px, 1vw, -50px) should return at least 0px]
+ expected: FAIL
diff --git a/tests/wpt/meta/html/semantics/permission-element/permission-icon/icon-hidden-reftest.html.ini b/tests/wpt/meta/html/semantics/permission-element/permission-icon/icon-hidden-reftest.html.ini
new file mode 100644
index 00000000000..bc9fdd0cbaf
--- /dev/null
+++ b/tests/wpt/meta/html/semantics/permission-element/permission-icon/icon-hidden-reftest.html.ini
@@ -0,0 +1,2 @@
+[icon-hidden-reftest.html]
+ expected: FAIL
diff --git a/tests/wpt/meta/html/semantics/permission-element/permission-icon/icon-unique-per-type-reftest.html.ini b/tests/wpt/meta/html/semantics/permission-element/permission-icon/icon-unique-per-type-reftest.html.ini
new file mode 100644
index 00000000000..248944bc32e
--- /dev/null
+++ b/tests/wpt/meta/html/semantics/permission-element/permission-icon/icon-unique-per-type-reftest.html.ini
@@ -0,0 +1,2 @@
+[icon-unique-per-type-reftest.html]
+ expected: FAIL
diff --git a/tests/wpt/meta/html/semantics/scripting-1/the-script-element/execution-timing/042.html.ini b/tests/wpt/meta/html/semantics/scripting-1/the-script-element/execution-timing/042.html.ini
deleted file mode 100644
index 6c2be5a1ab2..00000000000
--- a/tests/wpt/meta/html/semantics/scripting-1/the-script-element/execution-timing/042.html.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[042.html]
- [ scheduler: DOM mutation events when adding scripts: DOMNodeInserted ]
- expected: FAIL
diff --git a/tests/wpt/meta/html/semantics/scripting-1/the-script-element/execution-timing/043.html.ini b/tests/wpt/meta/html/semantics/scripting-1/the-script-element/execution-timing/043.html.ini
deleted file mode 100644
index 83a6a3fb2a9..00000000000
--- a/tests/wpt/meta/html/semantics/scripting-1/the-script-element/execution-timing/043.html.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[043.html]
- [ scheduler: DOM mutation events when adding external scripts: DOMNodeInserted ]
- expected: FAIL
diff --git a/tests/wpt/meta/html/semantics/scripting-1/the-script-element/execution-timing/044.html.ini b/tests/wpt/meta/html/semantics/scripting-1/the-script-element/execution-timing/044.html.ini
deleted file mode 100644
index 4e428ec9a29..00000000000
--- a/tests/wpt/meta/html/semantics/scripting-1/the-script-element/execution-timing/044.html.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[044.html]
- [ scheduler: DOM mutation events when adding scripts: DOMNodeInsertedIntoDocument ]
- expected: FAIL
diff --git a/tests/wpt/meta/html/semantics/scripting-1/the-script-element/execution-timing/045.html.ini b/tests/wpt/meta/html/semantics/scripting-1/the-script-element/execution-timing/045.html.ini
deleted file mode 100644
index b5409fbb4ac..00000000000
--- a/tests/wpt/meta/html/semantics/scripting-1/the-script-element/execution-timing/045.html.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[045.html]
- [ scheduler: DOM mutation events when adding external scripts: DOMNodeInsertedIntoDocument ]
- expected: FAIL
diff --git a/tests/wpt/meta/html/semantics/scripting-1/the-script-element/execution-timing/054.html.ini b/tests/wpt/meta/html/semantics/scripting-1/the-script-element/execution-timing/054.html.ini
deleted file mode 100644
index abdc47b56ae..00000000000
--- a/tests/wpt/meta/html/semantics/scripting-1/the-script-element/execution-timing/054.html.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[054.html]
- [ scheduler: removing newly inserted script from DOMNodeInserted handler - external script ]
- expected: FAIL
diff --git a/tests/wpt/meta/html/semantics/scripting-1/the-script-element/execution-timing/055.html.ini b/tests/wpt/meta/html/semantics/scripting-1/the-script-element/execution-timing/055.html.ini
deleted file mode 100644
index af2467b3e71..00000000000
--- a/tests/wpt/meta/html/semantics/scripting-1/the-script-element/execution-timing/055.html.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[055.html]
- [ scheduler: removing newly inserted script from DOMNodeInserted handler - inline script ]
- expected: FAIL
diff --git a/tests/wpt/meta/html/semantics/the-button-element/command-and-commandfor/source-attribute-retargeting.tentative.html.ini b/tests/wpt/meta/html/semantics/the-button-element/command-and-commandfor/source-attribute-retargeting.tentative.html.ini
new file mode 100644
index 00000000000..c882098a91c
--- /dev/null
+++ b/tests/wpt/meta/html/semantics/the-button-element/command-and-commandfor/source-attribute-retargeting.tentative.html.ini
@@ -0,0 +1,9 @@
+[source-attribute-retargeting.tentative.html]
+ [CommandEvent.source and ToggleEvent.source should be retargeted during and after event dispatch.]
+ expected: FAIL
+
+ [CommandEvent.source should be retargeted when manually dispatched with composed set to true.]
+ expected: FAIL
+
+ [CommandEvent.source and ToggleEvent.source should not be set to null after dispatch without ShadowDOM.]
+ expected: FAIL
diff --git a/tests/wpt/meta/navigation-timing/test-navigation-type-reload.html.ini b/tests/wpt/meta/navigation-timing/test-navigation-type-reload.html.ini
index 20d32f43049..484aa044de7 100644
--- a/tests/wpt/meta/navigation-timing/test-navigation-type-reload.html.ini
+++ b/tests/wpt/meta/navigation-timing/test-navigation-type-reload.html.ini
@@ -16,3 +16,15 @@
[Reload fetchStart > Original fetchStart]
expected: FAIL
+
+ [Reload domComplete > Original domComplete]
+ expected: FAIL
+
+ [Reload domContentLoadedEventEnd > Original domContentLoadedEventEnd]
+ expected: FAIL
+
+ [Reload loadEventEnd > Original loadEventEnd]
+ expected: FAIL
+
+ [Reload loadEventStart > Original loadEventStart]
+ expected: FAIL
diff --git a/tests/wpt/meta/preload/preload-error.sub.html.ini b/tests/wpt/meta/preload/preload-error.sub.html.ini
index 11cddb179c3..f383c31f2fd 100644
--- a/tests/wpt/meta/preload/preload-error.sub.html.ini
+++ b/tests/wpt/meta/preload/preload-error.sub.html.ini
@@ -5,36 +5,24 @@
[CORS-error (image): main]
expected: FAIL
- [CSP-error (image): preload events]
- expected: FAIL
-
[CSP-error (image): main]
expected: FAIL
[CORS-error (style): main]
expected: FAIL
- [CSP-error (style): preload events]
- expected: FAIL
-
[CSP-error (style): main]
expected: FAIL
[CORS-error (script): main]
expected: FAIL
- [CSP-error (script): preload events]
- expected: FAIL
-
[CSP-error (script): main]
expected: FAIL
[CORS-error (xhr): main]
expected: FAIL
- [CSP-error (xhr): preload events]
- expected: FAIL
-
[CSP-error (xhr): main]
expected: FAIL
@@ -50,9 +38,6 @@
[CORS-error (fetch): main]
expected: FAIL
- [CSP-error (fetch): preload events]
- expected: FAIL
-
[CSP-error (fetch): main]
expected: FAIL
diff --git a/tests/wpt/meta/resize-observer/change-layout-in-error.html.ini b/tests/wpt/meta/resize-observer/change-layout-in-error.html.ini
new file mode 100644
index 00000000000..5d07f60e0b6
--- /dev/null
+++ b/tests/wpt/meta/resize-observer/change-layout-in-error.html.ini
@@ -0,0 +1,3 @@
+[change-layout-in-error.html]
+ [Changing layout in window error handler should not result in lifecyle loop when resize observer loop limit is reached.]
+ expected: FAIL
diff --git a/tests/wpt/meta/resize-observer/zoom.html.ini b/tests/wpt/meta/resize-observer/zoom.html.ini
new file mode 100644
index 00000000000..a08a15e7c82
--- /dev/null
+++ b/tests/wpt/meta/resize-observer/zoom.html.ini
@@ -0,0 +1,3 @@
+[zoom.html]
+ [ResizeObserver sizes account for zoom]
+ expected: FAIL
diff --git a/tests/wpt/meta/trusted-types/block-text-node-insertion-into-script-element.html.ini b/tests/wpt/meta/trusted-types/block-text-node-insertion-into-script-element.html.ini
index 34f64b9ef70..366c956d411 100644
--- a/tests/wpt/meta/trusted-types/block-text-node-insertion-into-script-element.html.ini
+++ b/tests/wpt/meta/trusted-types/block-text-node-insertion-into-script-element.html.ini
@@ -17,3 +17,12 @@
[Spot tests around script + innerHTML interaction with default policy.]
expected: FAIL
+
+ [Regression test: Bypass via appendChild into off-document script element.]
+ expected: FAIL
+
+ [Regression test: Bypass via appendChild into live script element.]
+ expected: FAIL
+
+ [Test that default policy applies to module script.]
+ expected: FAIL
diff --git a/tests/wpt/meta/trusted-types/block-text-node-insertion-into-svg-script-element.html.ini b/tests/wpt/meta/trusted-types/block-text-node-insertion-into-svg-script-element.html.ini
index e0fbb2a6064..4d469799e85 100644
--- a/tests/wpt/meta/trusted-types/block-text-node-insertion-into-svg-script-element.html.ini
+++ b/tests/wpt/meta/trusted-types/block-text-node-insertion-into-svg-script-element.html.ini
@@ -10,3 +10,6 @@
[Spot tests around script + innerHTML interaction with default policy.]
expected: FAIL
+
+ [Test that default policy applies with module script. svg:script]
+ expected: FAIL
diff --git a/tests/wpt/meta/uievents/legacy-domevents-tests/approved/ProcessingInstruction.DOMCharacterDataModified.html.ini b/tests/wpt/meta/uievents/legacy-domevents-tests/approved/ProcessingInstruction.DOMCharacterDataModified.html.ini
deleted file mode 100644
index e36472cb628..00000000000
--- a/tests/wpt/meta/uievents/legacy-domevents-tests/approved/ProcessingInstruction.DOMCharacterDataModified.html.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[ProcessingInstruction.DOMCharacterDataModified.html]
- [Test Description: DOMCharacterDataModified event fires after ProcessingInstruction.data have been modified, but the node itself has not been inserted or deleted. The proximal event target of this event shall be the ProcessingInstruction node.]
- expected: FAIL
diff --git a/tests/wpt/meta/uievents/legacy-domevents-tests/approved/domnodeinserted.html.ini b/tests/wpt/meta/uievents/legacy-domevents-tests/approved/domnodeinserted.html.ini
deleted file mode 100644
index 27f8ad9e90f..00000000000
--- a/tests/wpt/meta/uievents/legacy-domevents-tests/approved/domnodeinserted.html.ini
+++ /dev/null
@@ -1,4 +0,0 @@
-[domnodeinserted.html]
- expected: TIMEOUT
- [Test Description: DOMNodeInserted event fires when a node has been added as a child of another node.]
- expected: NOTRUN
diff --git a/tests/wpt/meta/urlpattern/urlpattern-generate.tentative.any.js.ini b/tests/wpt/meta/urlpattern/urlpattern-generate.tentative.any.js.ini
new file mode 100644
index 00000000000..3c01bdb3c49
--- /dev/null
+++ b/tests/wpt/meta/urlpattern/urlpattern-generate.tentative.any.js.ini
@@ -0,0 +1,63 @@
+[urlpattern-generate.tentative.any.worker.html]
+ [Pattern: {"pathname":"/foo"} Component: pathname Groups: {}]
+ expected: FAIL
+
+ [Pattern: {"pathname":"/:foo"} Component: pathname Groups: {"foo":"bar"}]
+ expected: FAIL
+
+ [Pattern: {"pathname":"/:foo"} Component: pathname Groups: {"foo":"🍅"}]
+ expected: FAIL
+
+ [Pattern: {"hostname":"{:foo}.example.com"} Component: hostname Groups: {"foo":"🍅"}]
+ expected: FAIL
+
+ [Pattern: {"pathname":"/foo/:bar"} Component: pathname Groups: {"bar":"baz"}]
+ expected: FAIL
+
+ [Pattern: {"pathname":"/foo:bar"} Component: pathname Groups: {"bar":"baz"}]
+ expected: FAIL
+
+ [Pattern: {"pathname":"/:foo/:bar"} Component: pathname Groups: {"foo":"baz","bar":"qux"}]
+ expected: FAIL
+
+ [Pattern: "https://example.com/:foo" Component: pathname Groups: {"foo":" "}]
+ expected: FAIL
+
+ [Pattern: "original-scheme://example.com/:foo" Component: pathname Groups: {"foo":" "}]
+ expected: FAIL
+
+
+[urlpattern-generate.tentative.any.html]
+ [Pattern: {"pathname":"/foo"} Component: pathname Groups: {}]
+ expected: FAIL
+
+ [Pattern: {"pathname":"/:foo"} Component: pathname Groups: {"foo":"bar"}]
+ expected: FAIL
+
+ [Pattern: {"pathname":"/:foo"} Component: pathname Groups: {"foo":"🍅"}]
+ expected: FAIL
+
+ [Pattern: {"hostname":"{:foo}.example.com"} Component: hostname Groups: {"foo":"🍅"}]
+ expected: FAIL
+
+ [Pattern: {"pathname":"/foo/:bar"} Component: pathname Groups: {"bar":"baz"}]
+ expected: FAIL
+
+ [Pattern: {"pathname":"/foo:bar"} Component: pathname Groups: {"bar":"baz"}]
+ expected: FAIL
+
+ [Pattern: {"pathname":"/:foo/:bar"} Component: pathname Groups: {"foo":"baz","bar":"qux"}]
+ expected: FAIL
+
+ [Pattern: "https://example.com/:foo" Component: pathname Groups: {"foo":" "}]
+ expected: FAIL
+
+ [Pattern: "original-scheme://example.com/:foo" Component: pathname Groups: {"foo":" "}]
+ expected: FAIL
+
+
+[urlpattern-generate.tentative.any.serviceworker.html]
+ expected: ERROR
+
+[urlpattern-generate.tentative.any.sharedworker.html]
+ expected: ERROR
diff --git a/tests/wpt/meta/webaudio/the-audio-api/the-audiobuffersourcenode-interface/sub-sample-buffer-stitching.html.ini b/tests/wpt/meta/webaudio/the-audio-api/the-audiobuffersourcenode-interface/sub-sample-buffer-stitching.html.ini
index 960779501c4..5d66c9ba352 100644
--- a/tests/wpt/meta/webaudio/the-audio-api/the-audiobuffersourcenode-interface/sub-sample-buffer-stitching.html.ini
+++ b/tests/wpt/meta/webaudio/the-audio-api/the-audiobuffersourcenode-interface/sub-sample-buffer-stitching.html.ini
@@ -805,3 +805,12 @@
[X Stitched sine-wave buffers at sample rate 43800 does not equal [0,0.06264832615852356,0.12505052983760834,0.18696144223213196,0.24813786149024963,0.308339387178421,0.36732959747314453,0.4248766601085663,0.480754554271698,0.5347436666488647,0.5866320133209229,0.6362156271934509,0.6832997798919678,0.7276994585990906,0.7692402601242065,0.8077589869499207...\] with an element-wise tolerance of {"absoluteThreshold":0.0038986,"relativeThreshold":0}.\n\tIndex\tActual\t\t\tExpected\t\tAbsError\t\tRelError\t\tTest threshold\n\t[14650\]\t2.4329547374028208e-17\t8.6956524848937988e-1\t8.6956524848937988e-1\t1.0000000000000000e+0\t3.8985999999999999e-3\n\t[14651\]\t3.0547976493835449e-1\t8.9879405498504639e-1\t5.9331429004669189e-1\t6.6012262403823208e-1\t3.8985999999999999e-3\n\tMax AbsError of 8.6956524848937988e-1 at index of 14650.\n\tMax RelError of 1.0000000000000000e+0 at index of 14650.\n]
expected: FAIL
+
+ [X Stitched sine-wave buffers at sample rate 43800 does not equal [0,0.06264832615852356,0.12505052983760834,0.18696144223213196,0.24813786149024963,0.308339387178421,0.36732959747314453,0.4248766601085663,0.480754554271698,0.5347436666488647,0.5866320133209229,0.6362156271934509,0.6832997798919678,0.7276994585990906,0.7692402601242065,0.8077589869499207...\] with an element-wise tolerance of {"absoluteThreshold":0.0038986,"relativeThreshold":0}.\n\tIndex\tActual\t\t\tExpected\t\tAbsError\t\tRelError\t\tTest threshold\n\t[14650\]\t3.3752832548824226e-34\t8.6956524848937988e-1\t8.6956524848937988e-1\t1.0000000000000000e+0\t3.8985999999999999e-3\n\t[14651\]\t3.0547976493835449e-1\t8.9879405498504639e-1\t5.9331429004669189e-1\t6.6012262403823208e-1\t3.8985999999999999e-3\n\tMax AbsError of 8.6956524848937988e-1 at index of 14650.\n\tMax RelError of 1.0000000000000000e+0 at index of 14650.\n]
+ expected: FAIL
+
+ [X Stitched sine-wave buffers at sample rate 43800 does not equal [0,0.06264832615852356,0.12505052983760834,0.18696144223213196,0.24813786149024963,0.308339387178421,0.36732959747314453,0.4248766601085663,0.480754554271698,0.5347436666488647,0.5866320133209229,0.6362156271934509,0.6832997798919678,0.7276994585990906,0.7692402601242065,0.8077589869499207...\] with an element-wise tolerance of {"absoluteThreshold":0.0038986,"relativeThreshold":0}.\n\tIndex\tActual\t\t\tExpected\t\tAbsError\t\tRelError\t\tTest threshold\n\t[14650\]\t4.5710336303710938e+2\t8.6956524848937988e-1\t4.5623379778862000e+2\t5.2466884869329283e+2\t3.8985999999999999e-3\n\t[14651\]\t3.0547976493835449e-1\t8.9879405498504639e-1\t5.9331429004669189e-1\t6.6012262403823208e-1\t3.8985999999999999e-3\n\tMax AbsError of 4.5623379778862000e+2 at index of 14650.\n\tMax RelError of 5.2466884869329283e+2 at index of 14650.\n]
+ expected: FAIL
+
+ [X SNR (-9.749670615505378 dB) is not greater than or equal to 65.737. Got -9.749670615505378.]
+ expected: FAIL
diff --git a/tests/wpt/meta/webdriver/tests/classic/accept_alert/accept.py.ini b/tests/wpt/meta/webdriver/tests/classic/accept_alert/accept.py.ini
index 00caf69c8d5..a5d10aa6fe2 100644
--- a/tests/wpt/meta/webdriver/tests/classic/accept_alert/accept.py.ini
+++ b/tests/wpt/meta/webdriver/tests/classic/accept_alert/accept.py.ini
@@ -1,4 +1,5 @@
[accept.py]
+ expected: TIMEOUT
[test_null_response_value]
expected: FAIL
diff --git a/tests/wpt/meta/webdriver/tests/classic/dismiss_alert/dismiss.py.ini b/tests/wpt/meta/webdriver/tests/classic/dismiss_alert/dismiss.py.ini
index cd2546ede8b..a2869095ca8 100644
--- a/tests/wpt/meta/webdriver/tests/classic/dismiss_alert/dismiss.py.ini
+++ b/tests/wpt/meta/webdriver/tests/classic/dismiss_alert/dismiss.py.ini
@@ -1,4 +1,5 @@
[dismiss.py]
+ expected: TIMEOUT
[test_no_top_browsing_context]
expected: FAIL
diff --git a/tests/wpt/meta/webdriver/tests/classic/element_clear/clear.py.ini b/tests/wpt/meta/webdriver/tests/classic/element_clear/clear.py.ini
index 541ffc25ca6..6a82e9170b8 100644
--- a/tests/wpt/meta/webdriver/tests/classic/element_clear/clear.py.ini
+++ b/tests/wpt/meta/webdriver/tests/classic/element_clear/clear.py.ini
@@ -1,2 +1,210 @@
[clear.py]
- expected: TIMEOUT
+ [test_null_response_value]
+ expected: FAIL
+
+ [test_no_top_browsing_context]
+ expected: FAIL
+
+ [test_no_browsing_context]
+ expected: FAIL
+
+ [test_no_such_element_with_invalid_value]
+ expected: FAIL
+
+ [test_no_such_element_with_shadow_root]
+ expected: FAIL
+
+ [test_no_such_element_from_other_window_handle[open\]]
+ expected: FAIL
+
+ [test_no_such_element_from_other_window_handle[closed\]]
+ expected: FAIL
+
+ [test_no_such_element_from_other_frame[open\]]
+ expected: FAIL
+
+ [test_no_such_element_from_other_frame[closed\]]
+ expected: FAIL
+
+ [test_stale_element_reference[top_context\]]
+ expected: FAIL
+
+ [test_stale_element_reference[child_context\]]
+ expected: FAIL
+
+ [test_pointer_interactable]
+ expected: FAIL
+
+ [test_keyboard_interactable]
+ expected: FAIL
+
+ [test_input[number-42-\]]
+ expected: FAIL
+
+ [test_input[range-42-50\]]
+ expected: FAIL
+
+ [test_input[email-foo@example.com-\]]
+ expected: FAIL
+
+ [test_input[password-password-\]]
+ expected: FAIL
+
+ [test_input[search-search-\]]
+ expected: FAIL
+
+ [test_input[tel-999-\]]
+ expected: FAIL
+
+ [test_input[text-text-\]]
+ expected: FAIL
+
+ [test_input[url-https://example.com/-\]]
+ expected: FAIL
+
+ [test_input[color-#ff0000-#000000\]]
+ expected: FAIL
+
+ [test_input[date-2017-12-26-\]]
+ expected: FAIL
+
+ [test_input[datetime-2017-12-26T19:48-\]]
+ expected: FAIL
+
+ [test_input[datetime-local-2017-12-26T19:48-\]]
+ expected: FAIL
+
+ [test_input[time-19:48-\]]
+ expected: FAIL
+
+ [test_input[month-2017-11-\]]
+ expected: FAIL
+
+ [test_input[week-2017-W52-\]]
+ expected: FAIL
+
+ [test_input_readonly[number\]]
+ expected: FAIL
+
+ [test_input_readonly[range\]]
+ expected: FAIL
+
+ [test_input_readonly[email\]]
+ expected: FAIL
+
+ [test_input_readonly[password\]]
+ expected: FAIL
+
+ [test_input_readonly[search\]]
+ expected: FAIL
+
+ [test_input_readonly[tel\]]
+ expected: FAIL
+
+ [test_input_readonly[text\]]
+ expected: FAIL
+
+ [test_input_readonly[url\]]
+ expected: FAIL
+
+ [test_input_readonly[color\]]
+ expected: FAIL
+
+ [test_input_readonly[date\]]
+ expected: FAIL
+
+ [test_input_readonly[datetime\]]
+ expected: FAIL
+
+ [test_input_readonly[datetime-local\]]
+ expected: FAIL
+
+ [test_input_readonly[time\]]
+ expected: FAIL
+
+ [test_input_readonly[month\]]
+ expected: FAIL
+
+ [test_input_readonly[week\]]
+ expected: FAIL
+
+ [test_input_readonly[file\]]
+ expected: FAIL
+
+ [test_textarea]
+ expected: FAIL
+
+ [test_textarea_readonly]
+ expected: FAIL
+
+ [test_input_file]
+ expected: FAIL
+
+ [test_input_file_multiple]
+ expected: FAIL
+
+ [test_button[button\]]
+ expected: FAIL
+
+ [test_button[reset\]]
+ expected: FAIL
+
+ [test_button[submit\]]
+ expected: FAIL
+
+ [test_button_with_subtree]
+ expected: FAIL
+
+ [test_contenteditable]
+ expected: FAIL
+
+ [test_designmode]
+ expected: FAIL
+
+ [test_resettable_element_focus_when_empty]
+ expected: FAIL
+
+ [test_resettable_element_does_not_satisfy_validation_constraints[number-foo\]]
+ expected: FAIL
+
+ [test_resettable_element_does_not_satisfy_validation_constraints[email-foo\]]
+ expected: FAIL
+
+ [test_resettable_element_does_not_satisfy_validation_constraints[url-foo\]]
+ expected: FAIL
+
+ [test_resettable_element_does_not_satisfy_validation_constraints[date-foo\]]
+ expected: FAIL
+
+ [test_resettable_element_does_not_satisfy_validation_constraints[datetime-local-foo\]]
+ expected: FAIL
+
+ [test_resettable_element_does_not_satisfy_validation_constraints[time-foo\]]
+ expected: FAIL
+
+ [test_resettable_element_does_not_satisfy_validation_constraints[month-foo\]]
+ expected: FAIL
+
+ [test_resettable_element_does_not_satisfy_validation_constraints[week-foo\]]
+ expected: FAIL
+
+ [test_non_editable_inputs[checkbox\]]
+ expected: FAIL
+
+ [test_non_editable_inputs[radio\]]
+ expected: FAIL
+
+ [test_non_editable_inputs[hidden\]]
+ expected: FAIL
+
+ [test_non_editable_inputs[submit\]]
+ expected: FAIL
+
+ [test_non_editable_inputs[button\]]
+ expected: FAIL
+
+ [test_non_editable_inputs[image\]]
+ expected: FAIL
+
+ [test_scroll_into_view]
+ expected: FAIL
diff --git a/tests/wpt/meta/webdriver/tests/classic/element_clear/disabled.py.ini b/tests/wpt/meta/webdriver/tests/classic/element_clear/disabled.py.ini
index f6367167d66..76b124f1dca 100644
--- a/tests/wpt/meta/webdriver/tests/classic/element_clear/disabled.py.ini
+++ b/tests/wpt/meta/webdriver/tests/classic/element_clear/disabled.py.ini
@@ -1,5 +1,4 @@
[disabled.py]
- expected: TIMEOUT
[test_button[button\]]
expected: FAIL
diff --git a/tests/wpt/meta/webdriver/tests/classic/element_click/bubbling.py.ini b/tests/wpt/meta/webdriver/tests/classic/element_click/bubbling.py.ini
deleted file mode 100644
index d99f3672ef6..00000000000
--- a/tests/wpt/meta/webdriver/tests/classic/element_click/bubbling.py.ini
+++ /dev/null
@@ -1,6 +0,0 @@
-[bubbling.py]
- [test_click_event_bubbles_to_parents]
- expected: FAIL
-
- [test_spin_event_loop]
- expected: FAIL
diff --git a/tests/wpt/meta/webdriver/tests/classic/element_click/center_point.py.ini b/tests/wpt/meta/webdriver/tests/classic/element_click/center_point.py.ini
index 3e3bfa2708e..48358dc41c1 100644
--- a/tests/wpt/meta/webdriver/tests/classic/element_click/center_point.py.ini
+++ b/tests/wpt/meta/webdriver/tests/classic/element_click/center_point.py.ini
@@ -1,4 +1,5 @@
[center_point.py]
+ expected: TIMEOUT
[test_entirely_in_view]
expected: FAIL
diff --git a/tests/wpt/meta/webdriver/tests/classic/element_click/click.py.ini b/tests/wpt/meta/webdriver/tests/classic/element_click/click.py.ini
index 9cdf1e0d0da..7405df1cdfb 100644
--- a/tests/wpt/meta/webdriver/tests/classic/element_click/click.py.ini
+++ b/tests/wpt/meta/webdriver/tests/classic/element_click/click.py.ini
@@ -7,9 +7,3 @@
[test_no_such_element_from_other_window_handle[closed\]]
expected: FAIL
-
- [test_no_such_element_from_other_frame[open\]]
- expected: FAIL
-
- [test_no_such_element_from_other_frame[closed\]]
- expected: FAIL
diff --git a/tests/wpt/meta/webdriver/tests/classic/element_click/events.py.ini b/tests/wpt/meta/webdriver/tests/classic/element_click/events.py.ini
deleted file mode 100644
index 8f57d96cef8..00000000000
--- a/tests/wpt/meta/webdriver/tests/classic/element_click/events.py.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[events.py]
- [test_event_mousemove]
- expected: FAIL
diff --git a/tests/wpt/meta/webdriver/tests/classic/element_click/interactability.py.ini b/tests/wpt/meta/webdriver/tests/classic/element_click/interactability.py.ini
index 982ea5ca753..9c185c61557 100644
--- a/tests/wpt/meta/webdriver/tests/classic/element_click/interactability.py.ini
+++ b/tests/wpt/meta/webdriver/tests/classic/element_click/interactability.py.ini
@@ -1,4 +1,5 @@
[interactability.py]
+ expected: TIMEOUT
[test_display_none]
expected: FAIL
diff --git a/tests/wpt/meta/webdriver/tests/classic/element_click/shadow_dom.py.ini b/tests/wpt/meta/webdriver/tests/classic/element_click/shadow_dom.py.ini
index 92d8bfe9a3d..32fd2854998 100644
--- a/tests/wpt/meta/webdriver/tests/classic/element_click/shadow_dom.py.ini
+++ b/tests/wpt/meta/webdriver/tests/classic/element_click/shadow_dom.py.ini
@@ -2,14 +2,8 @@
[test_shadow_element_click[host_element\]]
expected: FAIL
- [test_shadow_element_click[checkbox_element\]]
- expected: FAIL
-
[test_nested_shadow_element_click[outer_element\]]
expected: FAIL
[test_nested_shadow_element_click[inner_element\]]
expected: FAIL
-
- [test_nested_shadow_element_click[checkbox\]]
- expected: FAIL
diff --git a/tests/wpt/meta/webdriver/tests/classic/element_send_keys/events.py.ini b/tests/wpt/meta/webdriver/tests/classic/element_send_keys/events.py.ini
index 26b3aaa641b..5e4543ef0e9 100644
--- a/tests/wpt/meta/webdriver/tests/classic/element_send_keys/events.py.ini
+++ b/tests/wpt/meta/webdriver/tests/classic/element_send_keys/events.py.ini
@@ -1,7 +1,4 @@
[events.py]
- [test_file_upload]
- expected: FAIL
-
[test_form_control_send_text[input\]]
expected: FAIL
diff --git a/tests/wpt/meta/webdriver/tests/classic/element_send_keys/file_upload.py.ini b/tests/wpt/meta/webdriver/tests/classic/element_send_keys/file_upload.py.ini
index 4fd4b29e87f..40a4a701288 100644
--- a/tests/wpt/meta/webdriver/tests/classic/element_send_keys/file_upload.py.ini
+++ b/tests/wpt/meta/webdriver/tests/classic/element_send_keys/file_upload.py.ini
@@ -1,50 +1,19 @@
[file_upload.py]
- expected: TIMEOUT
[test_empty_text]
expected: FAIL
- [test_multiple_files]
- expected: FAIL
-
[test_multiple_files_last_path_not_found]
expected: FAIL
- [test_multiple_files_without_multiple_attribute]
- expected: FAIL
-
[test_multiple_files_send_twice]
expected: FAIL
[test_multiple_files_reset_with_element_clear]
expected: FAIL
- [test_single_file]
- expected: FAIL
-
- [test_single_file_replaces_without_multiple_attribute]
- expected: FAIL
-
[test_single_file_appends_with_multiple_attribute]
expected: FAIL
- [test_transparent]
- expected: FAIL
-
- [test_obscured]
- expected: FAIL
-
- [test_outside_viewport]
- expected: FAIL
-
- [test_hidden]
- expected: FAIL
-
- [test_display_none]
- expected: FAIL
-
- [test_not_focused]
- expected: FAIL
-
[test_focused]
expected: ERROR
diff --git a/tests/wpt/meta/webdriver/tests/classic/element_send_keys/send_keys.py.ini b/tests/wpt/meta/webdriver/tests/classic/element_send_keys/send_keys.py.ini
index 10a5a86e3d2..9dca7adc465 100644
--- a/tests/wpt/meta/webdriver/tests/classic/element_send_keys/send_keys.py.ini
+++ b/tests/wpt/meta/webdriver/tests/classic/element_send_keys/send_keys.py.ini
@@ -7,9 +7,3 @@
[test_no_such_element_from_other_window_handle[closed\]]
expected: FAIL
-
- [test_no_such_element_from_other_frame[open\]]
- expected: FAIL
-
- [test_no_such_element_from_other_frame[closed\]]
- expected: FAIL
diff --git a/tests/wpt/meta/webdriver/tests/classic/execute_async_script/arguments.py.ini b/tests/wpt/meta/webdriver/tests/classic/execute_async_script/arguments.py.ini
index 6bcbe1197f6..72a20a6f7cf 100644
--- a/tests/wpt/meta/webdriver/tests/classic/execute_async_script/arguments.py.ini
+++ b/tests/wpt/meta/webdriver/tests/classic/execute_async_script/arguments.py.ini
@@ -1,2 +1,78 @@
[arguments.py]
- expected: TIMEOUT
+ [test_no_such_element_with_unknown_id]
+ expected: FAIL
+
+ [test_no_such_element_from_other_window_handle[open\]]
+ expected: FAIL
+
+ [test_no_such_element_from_other_window_handle[closed\]]
+ expected: FAIL
+
+ [test_no_such_element_from_other_frame[open\]]
+ expected: FAIL
+
+ [test_no_such_element_from_other_frame[closed\]]
+ expected: FAIL
+
+ [test_no_such_shadow_root_with_unknown_id]
+ expected: FAIL
+
+ [test_no_such_shadow_root_from_other_window_handle[open\]]
+ expected: FAIL
+
+ [test_no_such_shadow_root_from_other_window_handle[closed\]]
+ expected: FAIL
+
+ [test_no_such_shadow_root_from_other_frame[open\]]
+ expected: FAIL
+
+ [test_no_such_shadow_root_from_other_frame[closed\]]
+ expected: FAIL
+
+ [test_stale_element_reference[top_context\]]
+ expected: FAIL
+
+ [test_stale_element_reference[child_context\]]
+ expected: FAIL
+
+ [test_invalid_argument_for_window_with_invalid_type[None-frame\]]
+ expected: FAIL
+
+ [test_invalid_argument_for_window_with_invalid_type[None-window\]]
+ expected: FAIL
+
+ [test_invalid_argument_for_window_with_invalid_type[False-frame\]]
+ expected: FAIL
+
+ [test_invalid_argument_for_window_with_invalid_type[False-window\]]
+ expected: FAIL
+
+ [test_invalid_argument_for_window_with_invalid_type[42-frame\]]
+ expected: FAIL
+
+ [test_invalid_argument_for_window_with_invalid_type[42-window\]]
+ expected: FAIL
+
+ [test_invalid_argument_for_window_with_invalid_type[value3-frame\]]
+ expected: FAIL
+
+ [test_invalid_argument_for_window_with_invalid_type[value3-window\]]
+ expected: FAIL
+
+ [test_invalid_argument_for_window_with_invalid_type[value4-frame\]]
+ expected: FAIL
+
+ [test_invalid_argument_for_window_with_invalid_type[value4-window\]]
+ expected: FAIL
+
+ [test_no_such_window_for_window_with_invalid_value]
+ expected: FAIL
+
+ [test_element_reference[frame\]]
+ expected: FAIL
+
+ [test_element_reference[shadow-root\]]
+ expected: FAIL
+
+ [test_element_reference[window\]]
+ expected: FAIL
diff --git a/tests/wpt/meta/webdriver/tests/classic/execute_async_script/execute_async.py.ini b/tests/wpt/meta/webdriver/tests/classic/execute_async_script/execute_async.py.ini
index 6885d2e743e..26921d513c2 100644
--- a/tests/wpt/meta/webdriver/tests/classic/execute_async_script/execute_async.py.ini
+++ b/tests/wpt/meta/webdriver/tests/classic/execute_async_script/execute_async.py.ini
@@ -1,4 +1,5 @@
[execute_async.py]
+ expected: TIMEOUT
[test_no_browsing_context]
expected: FAIL
diff --git a/tests/wpt/meta/webdriver/tests/classic/execute_script/arguments.py.ini b/tests/wpt/meta/webdriver/tests/classic/execute_script/arguments.py.ini
index 8818990c5ef..9c6615f080f 100644
--- a/tests/wpt/meta/webdriver/tests/classic/execute_script/arguments.py.ini
+++ b/tests/wpt/meta/webdriver/tests/classic/execute_script/arguments.py.ini
@@ -1,5 +1,4 @@
[arguments.py]
- expected: TIMEOUT
[test_no_such_element_with_unknown_id]
expected: FAIL
@@ -78,9 +77,6 @@
[test_element_reference[frame\]]
expected: FAIL
- [test_element_reference[node\]]
- expected: FAIL
-
[test_element_reference[shadow-root\]]
expected: FAIL
diff --git a/tests/wpt/meta/webdriver/tests/classic/execute_script/execute.py.ini b/tests/wpt/meta/webdriver/tests/classic/execute_script/execute.py.ini
index 8a1571d1d7b..ff13c80a5fe 100644
--- a/tests/wpt/meta/webdriver/tests/classic/execute_script/execute.py.ini
+++ b/tests/wpt/meta/webdriver/tests/classic/execute_script/execute.py.ini
@@ -1,4 +1,5 @@
[execute.py]
+ expected: TIMEOUT
[test_no_browsing_context]
expected: FAIL
diff --git a/tests/wpt/meta/webdriver/tests/classic/find_element/find.py.ini b/tests/wpt/meta/webdriver/tests/classic/find_element/find.py.ini
index 7564f644b10..60f973b8a44 100644
--- a/tests/wpt/meta/webdriver/tests/classic/find_element/find.py.ini
+++ b/tests/wpt/meta/webdriver/tests/classic/find_element/find.py.ini
@@ -1,7 +1,6 @@
[find.py]
- expected: TIMEOUT
[test_no_browsing_context]
- expected: ERROR
+ expected: FAIL
[test_no_such_element_with_unknown_selector[not-existent\]]
expected: FAIL
@@ -15,18 +14,6 @@
[test_find_element[xpath-//a\]]
expected: FAIL
- [test_xhtml_namespace[css selector-#linkText\]]
- expected: FAIL
-
- [test_xhtml_namespace[link text-full link text\]]
- expected: FAIL
-
- [test_xhtml_namespace[partial link text-link text\]]
- expected: FAIL
-
- [test_xhtml_namespace[tag name-a\]]
- expected: FAIL
-
[test_xhtml_namespace[xpath-//*[name()='a'\]\]]
expected: FAIL
diff --git a/tests/wpt/meta/webdriver/tests/classic/find_element_from_shadow_root/find.py.ini b/tests/wpt/meta/webdriver/tests/classic/find_element_from_shadow_root/find.py.ini
index dba98c7726b..05e490d14fe 100644
--- a/tests/wpt/meta/webdriver/tests/classic/find_element_from_shadow_root/find.py.ini
+++ b/tests/wpt/meta/webdriver/tests/classic/find_element_from_shadow_root/find.py.ini
@@ -1,5 +1,4 @@
[find.py]
- expected: TIMEOUT
[test_null_parameter_value]
expected: FAIL
@@ -7,7 +6,7 @@
expected: FAIL
[test_no_browsing_context]
- expected: ERROR
+ expected: FAIL
[test_no_such_shadow_root_with_element]
expected: FAIL
diff --git a/tests/wpt/meta/webdriver/tests/classic/find_elements/find.py.ini b/tests/wpt/meta/webdriver/tests/classic/find_elements/find.py.ini
index 44f232824bb..06a8b89b5b6 100644
--- a/tests/wpt/meta/webdriver/tests/classic/find_elements/find.py.ini
+++ b/tests/wpt/meta/webdriver/tests/classic/find_elements/find.py.ini
@@ -1,74 +1,22 @@
[find.py]
- expected: TIMEOUT
[test_no_browsing_context]
- expected: ERROR
-
- [test_find_elements[css selector-#linkText\]]
- expected: FAIL
-
- [test_find_elements[link text-full link text\]]
- expected: FAIL
-
- [test_find_elements[partial link text-link text\]]
- expected: FAIL
-
- [test_find_elements[tag name-a\]]
expected: FAIL
[test_find_elements[xpath-//a\]]
expected: FAIL
- [test_find_elements_link_text[<a href=#>link text</a>-link text\]]
- expected: FAIL
-
- [test_find_elements_link_text[<a href=#>&nbsp;link text&nbsp;</a>-link text\]]
- expected: FAIL
-
[test_find_elements_link_text[<a href=#>link<br>text</a>-link\\ntext\]]
expected: FAIL
- [test_find_elements_link_text[<a href=#>link&amp;text</a>-link&text\]]
- expected: FAIL
-
- [test_find_elements_link_text[<a href=#>LINK TEXT</a>-LINK TEXT\]]
- expected: FAIL
-
[test_find_elements_link_text[<a href=# style='text-transform: uppercase'>link text</a>-LINK TEXT\]]
expected: FAIL
- [test_find_elements_partial_link_text[<a href=#>partial link text</a>-link\]]
- expected: FAIL
-
- [test_find_elements_partial_link_text[<a href=#>&nbsp;partial link text&nbsp;</a>-link\]]
- expected: FAIL
-
- [test_find_elements_partial_link_text[<a href=#>partial link text</a>-k t\]]
- expected: FAIL
-
[test_find_elements_partial_link_text[<a href=#>partial link<br>text</a>-k\\nt\]]
expected: FAIL
- [test_find_elements_partial_link_text[<a href=#>partial link&amp;text</a>-k&t\]]
- expected: FAIL
-
- [test_find_elements_partial_link_text[<a href=#>PARTIAL LINK TEXT</a>-LINK\]]
- expected: FAIL
-
[test_find_elements_partial_link_text[<a href=# style='text-transform: uppercase'>partial link text</a>-LINK\]]
expected: FAIL
- [test_xhtml_namespace[css selector-#linkText\]]
- expected: FAIL
-
- [test_xhtml_namespace[link text-full link text\]]
- expected: FAIL
-
- [test_xhtml_namespace[partial link text-link text\]]
- expected: FAIL
-
- [test_xhtml_namespace[tag name-a\]]
- expected: FAIL
-
[test_xhtml_namespace[xpath-//*[name()='a'\]\]]
expected: FAIL
diff --git a/tests/wpt/meta/webdriver/tests/classic/find_elements_from_element/find.py.ini b/tests/wpt/meta/webdriver/tests/classic/find_elements_from_element/find.py.ini
index 69ec1b4bbcc..47ac0c0b589 100644
--- a/tests/wpt/meta/webdriver/tests/classic/find_elements_from_element/find.py.ini
+++ b/tests/wpt/meta/webdriver/tests/classic/find_elements_from_element/find.py.ini
@@ -1,77 +1,28 @@
[find.py]
- expected: TIMEOUT
[test_no_browsing_context]
- expected: ERROR
-
- [test_no_such_element_with_shadow_root]
expected: FAIL
- [test_no_such_element_with_startnode_from_other_window_handle]
+ [test_no_such_element_with_shadow_root]
expected: FAIL
[test_no_such_element_with_startnode_from_other_frame]
expected: FAIL
- [test_stale_element_reference[top_context\]]
- expected: FAIL
-
- [test_stale_element_reference[child_context\]]
- expected: FAIL
-
[test_find_elements[xpath-//a\]]
expected: FAIL
- [test_find_elements_link_text[<a href=#>link text</a>-link text\]]
- expected: FAIL
-
- [test_find_elements_link_text[<a href=#>&nbsp;link text&nbsp;</a>-link text\]]
- expected: FAIL
-
[test_find_elements_link_text[<a href=#>link<br>text</a>-link\\ntext\]]
expected: FAIL
- [test_find_elements_link_text[<a href=#>link&amp;text</a>-link&text\]]
- expected: FAIL
-
- [test_find_elements_link_text[<a href=#>LINK TEXT</a>-LINK TEXT\]]
- expected: FAIL
-
[test_find_elements_link_text[<a href=# style='text-transform: uppercase'>link text</a>-LINK TEXT\]]
expected: FAIL
- [test_find_elements_partial_link_text[<a href=#>partial link text</a>-link\]]
- expected: FAIL
-
- [test_find_elements_partial_link_text[<a href=#>&nbsp;partial link text&nbsp;</a>-link\]]
- expected: FAIL
-
- [test_find_elements_partial_link_text[<a href=#>partial link text</a>-k t\]]
- expected: FAIL
-
[test_find_elements_partial_link_text[<a href=#>partial link<br>text</a>-k\\nt\]]
expected: FAIL
- [test_find_elements_partial_link_text[<a href=#>partial link&amp;text</a>-k&t\]]
- expected: FAIL
-
- [test_find_elements_partial_link_text[<a href=#>PARTIAL LINK TEXT</a>-LINK\]]
- expected: FAIL
-
[test_find_elements_partial_link_text[<a href=# style='text-transform: uppercase'>partial link text</a>-LINK\]]
expected: FAIL
- [test_xhtml_namespace[css selector-#linkText\]]
- expected: FAIL
-
- [test_xhtml_namespace[link text-full link text\]]
- expected: FAIL
-
- [test_xhtml_namespace[partial link text-link text\]]
- expected: FAIL
-
- [test_xhtml_namespace[tag name-a\]]
- expected: FAIL
-
[test_xhtml_namespace[xpath-//*[name()='a'\]\]]
expected: FAIL
diff --git a/tests/wpt/meta/webdriver/tests/classic/find_elements_from_shadow_root/find.py.ini b/tests/wpt/meta/webdriver/tests/classic/find_elements_from_shadow_root/find.py.ini
index 5328af1b701..18ed273c743 100644
--- a/tests/wpt/meta/webdriver/tests/classic/find_elements_from_shadow_root/find.py.ini
+++ b/tests/wpt/meta/webdriver/tests/classic/find_elements_from_shadow_root/find.py.ini
@@ -1,5 +1,4 @@
[find.py]
- expected: TIMEOUT
[test_null_parameter_value]
expected: FAIL
@@ -7,7 +6,7 @@
expected: FAIL
[test_no_browsing_context]
- expected: ERROR
+ expected: FAIL
[test_no_such_shadow_root_with_element]
expected: FAIL
diff --git a/tests/wpt/meta/webdriver/tests/classic/get_computed_role/get.py.ini b/tests/wpt/meta/webdriver/tests/classic/get_computed_role/get.py.ini
index f00172fdc5a..44749396246 100644
--- a/tests/wpt/meta/webdriver/tests/classic/get_computed_role/get.py.ini
+++ b/tests/wpt/meta/webdriver/tests/classic/get_computed_role/get.py.ini
@@ -8,11 +8,5 @@
[test_no_such_element_from_other_window_handle[closed\]]
expected: FAIL
- [test_no_such_element_from_other_frame[open\]]
- expected: FAIL
-
- [test_no_such_element_from_other_frame[closed\]]
- expected: FAIL
-
[test_computed_roles[<article>foo</article>-article-article\]]
expected: FAIL
diff --git a/tests/wpt/meta/webdriver/tests/classic/get_element_attribute/get.py.ini b/tests/wpt/meta/webdriver/tests/classic/get_element_attribute/get.py.ini
index 69b4a4c7d0b..c5bc0a36f6d 100644
--- a/tests/wpt/meta/webdriver/tests/classic/get_element_attribute/get.py.ini
+++ b/tests/wpt/meta/webdriver/tests/classic/get_element_attribute/get.py.ini
@@ -1,35 +1,13 @@
[get.py]
- expected: TIMEOUT
- [test_no_top_browsing_context]
- expected: FAIL
-
[test_no_browsing_context]
- expected: ERROR
-
- [test_no_such_element_with_shadow_root]
expected: FAIL
- [test_no_such_element_from_other_window_handle[open\]]
+ [test_no_such_element_with_shadow_root]
expected: FAIL
[test_no_such_element_from_other_window_handle[closed\]]
expected: FAIL
- [test_no_such_element_from_other_frame[open\]]
- expected: FAIL
-
- [test_no_such_element_from_other_frame[closed\]]
- expected: FAIL
-
- [test_stale_element_reference[top_context\]]
- expected: FAIL
-
- [test_stale_element_reference[child_context\]]
- expected: FAIL
-
- [test_normal]
- expected: FAIL
-
[test_boolean_attribute[audio-attrs0\]]
expected: FAIL
@@ -86,9 +64,3 @@
[test_global_boolean_attributes]
expected: FAIL
-
- [test_anchor_href[relative\]]
- expected: FAIL
-
- [test_anchor_href[absolute\]]
- expected: FAIL
diff --git a/tests/wpt/meta/webdriver/tests/classic/get_element_css_value/get.py.ini b/tests/wpt/meta/webdriver/tests/classic/get_element_css_value/get.py.ini
index d55c5312a47..0af7750e50e 100644
--- a/tests/wpt/meta/webdriver/tests/classic/get_element_css_value/get.py.ini
+++ b/tests/wpt/meta/webdriver/tests/classic/get_element_css_value/get.py.ini
@@ -7,9 +7,3 @@
[test_no_such_element_from_other_window_handle[closed\]]
expected: FAIL
-
- [test_no_such_element_from_other_frame[open\]]
- expected: FAIL
-
- [test_no_such_element_from_other_frame[closed\]]
- expected: FAIL
diff --git a/tests/wpt/meta/webdriver/tests/classic/get_element_property/get.py.ini b/tests/wpt/meta/webdriver/tests/classic/get_element_property/get.py.ini
index 646e2846e18..991123b881c 100644
--- a/tests/wpt/meta/webdriver/tests/classic/get_element_property/get.py.ini
+++ b/tests/wpt/meta/webdriver/tests/classic/get_element_property/get.py.ini
@@ -1,94 +1,12 @@
[get.py]
- expected: TIMEOUT
- [test_no_top_browsing_context]
- expected: FAIL
-
[test_no_browsing_context]
- expected: ERROR
-
- [test_no_such_element_with_shadow_root]
expected: FAIL
- [test_no_such_element_from_other_window_handle[open\]]
+ [test_no_such_element_with_shadow_root]
expected: FAIL
[test_no_such_element_from_other_window_handle[closed\]]
expected: FAIL
- [test_no_such_element_from_other_frame[open\]]
- expected: FAIL
-
- [test_no_such_element_from_other_frame[closed\]]
- expected: FAIL
-
- [test_stale_element_reference[top_context\]]
- expected: FAIL
-
- [test_stale_element_reference[child_context\]]
- expected: FAIL
-
- [test_property_non_existent]
- expected: FAIL
-
- [test_content_attribute]
- expected: FAIL
-
- [test_idl_attribute]
- expected: FAIL
-
- [test_primitives["foobar"-foobar\]]
- expected: FAIL
-
- [test_primitives[42-42\]]
- expected: FAIL
-
- [test_primitives[js_primitive2-py_primitive2\]]
- expected: FAIL
-
- [test_primitives[js_primitive3-py_primitive3\]]
- expected: FAIL
-
- [test_primitives[null-None\]]
- expected: FAIL
-
- [test_primitives[undefined-None\]]
- expected: FAIL
-
- [test_collection_dom_token_list]
- expected: FAIL
-
- [test_primitives_set_by_execute_script["foobar"-foobar\]]
- expected: FAIL
-
- [test_primitives_set_by_execute_script[42-42\]]
- expected: FAIL
-
- [test_primitives_set_by_execute_script[js_primitive2-py_primitive2\]]
- expected: FAIL
-
- [test_primitives_set_by_execute_script[js_primitive3-py_primitive3\]]
- expected: FAIL
-
- [test_primitives_set_by_execute_script[null-None\]]
- expected: FAIL
-
- [test_primitives_set_by_execute_script[undefined-None\]]
- expected: FAIL
-
- [test_web_reference[frame-WebFrame\]]
- expected: FAIL
-
[test_web_reference[shadowRoot-ShadowRoot\]]
expected: FAIL
-
- [test_web_reference[window-WebWindow\]]
- expected: FAIL
-
- [test_mutated_element]
- expected: FAIL
-
- [test_anchor_href[relative\]]
- expected: FAIL
-
- [test_anchor_href[absolute\]]
- expected: FAIL
diff --git a/tests/wpt/meta/webdriver/tests/classic/get_element_rect/get.py.ini b/tests/wpt/meta/webdriver/tests/classic/get_element_rect/get.py.ini
index 67875a58cd9..10339e7291b 100644
--- a/tests/wpt/meta/webdriver/tests/classic/get_element_rect/get.py.ini
+++ b/tests/wpt/meta/webdriver/tests/classic/get_element_rect/get.py.ini
@@ -8,11 +8,5 @@
[test_no_such_element_from_other_window_handle[closed\]]
expected: FAIL
- [test_no_such_element_from_other_frame[open\]]
- expected: FAIL
-
- [test_no_such_element_from_other_frame[closed\]]
- expected: FAIL
-
[test_basic]
expected: FAIL
diff --git a/tests/wpt/meta/webdriver/tests/classic/get_element_tag_name/get.py.ini b/tests/wpt/meta/webdriver/tests/classic/get_element_tag_name/get.py.ini
index 0ac8ff98d59..879854dfc56 100644
--- a/tests/wpt/meta/webdriver/tests/classic/get_element_tag_name/get.py.ini
+++ b/tests/wpt/meta/webdriver/tests/classic/get_element_tag_name/get.py.ini
@@ -8,11 +8,5 @@
[test_no_such_element_from_other_window_handle[closed\]]
expected: FAIL
- [test_no_such_element_from_other_frame[open\]]
- expected: FAIL
-
- [test_no_such_element_from_other_frame[closed\]]
- expected: FAIL
-
[test_get_element_tag_name]
expected: FAIL
diff --git a/tests/wpt/meta/webdriver/tests/classic/get_element_text/get.py.ini b/tests/wpt/meta/webdriver/tests/classic/get_element_text/get.py.ini
index ad870f8f49b..66e31b2d5a7 100644
--- a/tests/wpt/meta/webdriver/tests/classic/get_element_text/get.py.ini
+++ b/tests/wpt/meta/webdriver/tests/classic/get_element_text/get.py.ini
@@ -8,12 +8,6 @@
[test_no_such_element_from_other_window_handle[closed\]]
expected: FAIL
- [test_no_such_element_from_other_frame[open\]]
- expected: FAIL
-
- [test_no_such_element_from_other_frame[closed\]]
- expected: FAIL
-
[test_transform_capitalize[space\]]
expected: FAIL
diff --git a/tests/wpt/meta/webdriver/tests/classic/is_element_enabled/enabled.py.ini b/tests/wpt/meta/webdriver/tests/classic/is_element_enabled/enabled.py.ini
index 1f97f812861..9f75dbb4f9e 100644
--- a/tests/wpt/meta/webdriver/tests/classic/is_element_enabled/enabled.py.ini
+++ b/tests/wpt/meta/webdriver/tests/classic/is_element_enabled/enabled.py.ini
@@ -1,2 +1,18 @@
[enabled.py]
- expected: TIMEOUT
+ [test_no_browsing_context]
+ expected: FAIL
+
+ [test_no_such_element_with_shadow_root]
+ expected: FAIL
+
+ [test_no_such_element_from_other_window_handle[closed\]]
+ expected: FAIL
+
+ [test_stale_element_reference[child_context\]]
+ expected: FAIL
+
+ [test_option_with_select[disabled\]]
+ expected: FAIL
+
+ [test_optgroup_with_select[disabled\]]
+ expected: FAIL
diff --git a/tests/wpt/meta/webdriver/tests/classic/is_element_selected/selected.py.ini b/tests/wpt/meta/webdriver/tests/classic/is_element_selected/selected.py.ini
index eb4c0299197..2c5777abee2 100644
--- a/tests/wpt/meta/webdriver/tests/classic/is_element_selected/selected.py.ini
+++ b/tests/wpt/meta/webdriver/tests/classic/is_element_selected/selected.py.ini
@@ -8,8 +8,5 @@
[test_no_such_element_from_other_window_handle[closed\]]
expected: FAIL
- [test_no_such_element_from_other_frame[open\]]
- expected: FAIL
-
- [test_no_such_element_from_other_frame[closed\]]
+ [test_stale_element_reference[child_context\]]
expected: FAIL
diff --git a/tests/wpt/meta/webdriver/tests/classic/new_session/unhandled_prompt_behavior.py.ini b/tests/wpt/meta/webdriver/tests/classic/new_session/unhandled_prompt_behavior.py.ini
index ff2e1c72126..7ea404e4f6a 100644
--- a/tests/wpt/meta/webdriver/tests/classic/new_session/unhandled_prompt_behavior.py.ini
+++ b/tests/wpt/meta/webdriver/tests/classic/new_session/unhandled_prompt_behavior.py.ini
@@ -1,4 +1,5 @@
[unhandled_prompt_behavior.py]
+ expected: TIMEOUT
[test_unhandled_prompt_behavior_as_object_default[handler0-expected_capability0-True-True\]]
expected: FAIL
diff --git a/tests/wpt/meta/webdriver/tests/classic/perform_actions/key.py.ini b/tests/wpt/meta/webdriver/tests/classic/perform_actions/key.py.ini
index 0a9efbca289..42ceab66336 100644
--- a/tests/wpt/meta/webdriver/tests/classic/perform_actions/key.py.ini
+++ b/tests/wpt/meta/webdriver/tests/classic/perform_actions/key.py.ini
@@ -9,16 +9,19 @@
expected: FAIL
[test_backspace_erases_keys]
- expected: FAIL
+ expected: ERROR
[test_element_in_shadow_tree[outer-open\]]
- expected: FAIL
+ expected: ERROR
[test_element_in_shadow_tree[outer-closed\]]
- expected: FAIL
+ expected: ERROR
[test_element_in_shadow_tree[inner-open\]]
- expected: FAIL
+ expected: ERROR
[test_element_in_shadow_tree[inner-closed\]]
- expected: FAIL
+ expected: ERROR
+
+ [test_element_not_focused]
+ expected: ERROR
diff --git a/tests/wpt/meta/webdriver/tests/classic/perform_actions/key_events.py.ini b/tests/wpt/meta/webdriver/tests/classic/perform_actions/key_events.py.ini
index 6dabfbb793f..ab545d924ac 100644
--- a/tests/wpt/meta/webdriver/tests/classic/perform_actions/key_events.py.ini
+++ b/tests/wpt/meta/webdriver/tests/classic/perform_actions/key_events.py.ini
@@ -1,273 +1,12 @@
[key_events.py]
- [test_modifier_key_sends_correct_events[\\ue00a-ALT\]]
- expected: FAIL
-
- [test_modifier_key_sends_correct_events[\\ue009-CONTROL\]]
- expected: FAIL
-
- [test_modifier_key_sends_correct_events[\\ue03d-META\]]
- expected: FAIL
-
[test_modifier_key_sends_correct_events[\\ue008-SHIFT\]]
expected: FAIL
- [test_modifier_key_sends_correct_events[\\ue052-R_ALT\]]
- expected: FAIL
-
- [test_modifier_key_sends_correct_events[\\ue051-R_CONTROL\]]
- expected: FAIL
-
- [test_modifier_key_sends_correct_events[\\ue053-R_META\]]
- expected: FAIL
-
- [test_modifier_key_sends_correct_events[\\ue050-R_SHIFT\]]
- expected: FAIL
-
[test_non_printable_key_sends_events[\\ue00c-ESCAPE\]]
expected: FAIL
- [test_non_printable_key_sends_events[\\ue014-RIGHT\]]
- expected: FAIL
-
- [test_printable_key_sends_correct_events[a-KeyA0\]]
- expected: FAIL
-
- [test_printable_key_sends_correct_events[a-KeyA1\]]
- expected: FAIL
-
- [test_printable_key_sends_correct_events["-Quote\]]
- expected: FAIL
-
- [test_printable_key_sends_correct_events[,-Comma\]]
- expected: FAIL
-
- [test_printable_key_sends_correct_events[\\xe0-\]]
- expected: FAIL
-
- [test_printable_key_sends_correct_events[\\u0416-\]]
- expected: FAIL
-
- [test_printable_key_sends_correct_events[@-Digit2\]]
- expected: FAIL
-
- [test_printable_key_sends_correct_events[\\u2603-\]]
- expected: FAIL
-
- [test_printable_key_sends_correct_events[\\uf6c2-\]]
- expected: FAIL
-
- [test_sequence_of_keydown_printable_keys_sends_events]
- expected: FAIL
-
- [test_sequence_of_keydown_printable_characters_sends_events]
- expected: FAIL
-
- [test_special_key_sends_keydown[ADD-expected0\]]
- expected: FAIL
-
- [test_special_key_sends_keydown[ALT-expected1\]]
- expected: FAIL
-
- [test_special_key_sends_keydown[BACKSPACE-expected2\]]
- expected: FAIL
-
- [test_special_key_sends_keydown[CANCEL-expected3\]]
- expected: FAIL
-
- [test_special_key_sends_keydown[CLEAR-expected4\]]
- expected: FAIL
-
- [test_special_key_sends_keydown[CONTROL-expected5\]]
- expected: FAIL
-
- [test_special_key_sends_keydown[DECIMAL-expected6\]]
- expected: FAIL
-
- [test_special_key_sends_keydown[DELETE-expected7\]]
- expected: FAIL
-
- [test_special_key_sends_keydown[DIVIDE-expected8\]]
- expected: FAIL
-
- [test_special_key_sends_keydown[DOWN-expected9\]]
- expected: FAIL
-
- [test_special_key_sends_keydown[END-expected10\]]
- expected: FAIL
-
- [test_special_key_sends_keydown[ENTER-expected11\]]
- expected: FAIL
-
[test_special_key_sends_keydown[EQUALS-expected12\]]
expected: FAIL
- [test_special_key_sends_keydown[ESCAPE-expected13\]]
- expected: FAIL
-
- [test_special_key_sends_keydown[F1-expected14\]]
- expected: FAIL
-
- [test_special_key_sends_keydown[F10-expected15\]]
- expected: FAIL
-
- [test_special_key_sends_keydown[F11-expected16\]]
- expected: FAIL
-
- [test_special_key_sends_keydown[F12-expected17\]]
- expected: FAIL
-
- [test_special_key_sends_keydown[F2-expected18\]]
- expected: FAIL
-
- [test_special_key_sends_keydown[F3-expected19\]]
- expected: FAIL
-
- [test_special_key_sends_keydown[F4-expected20\]]
- expected: FAIL
-
- [test_special_key_sends_keydown[F5-expected21\]]
- expected: FAIL
-
- [test_special_key_sends_keydown[F6-expected22\]]
- expected: FAIL
-
- [test_special_key_sends_keydown[F7-expected23\]]
- expected: FAIL
-
- [test_special_key_sends_keydown[F8-expected24\]]
- expected: FAIL
-
- [test_special_key_sends_keydown[F9-expected25\]]
- expected: FAIL
-
- [test_special_key_sends_keydown[HELP-expected26\]]
- expected: FAIL
-
- [test_special_key_sends_keydown[HOME-expected27\]]
- expected: FAIL
-
- [test_special_key_sends_keydown[INSERT-expected28\]]
- expected: FAIL
-
- [test_special_key_sends_keydown[LEFT-expected29\]]
- expected: FAIL
-
- [test_special_key_sends_keydown[META-expected30\]]
- expected: FAIL
-
- [test_special_key_sends_keydown[MULTIPLY-expected31\]]
- expected: FAIL
-
- [test_special_key_sends_keydown[NULL-expected32\]]
- expected: FAIL
-
- [test_special_key_sends_keydown[NUMPAD0-expected33\]]
- expected: FAIL
-
- [test_special_key_sends_keydown[NUMPAD1-expected34\]]
- expected: FAIL
-
- [test_special_key_sends_keydown[NUMPAD2-expected35\]]
- expected: FAIL
-
- [test_special_key_sends_keydown[NUMPAD3-expected36\]]
- expected: FAIL
-
- [test_special_key_sends_keydown[NUMPAD4-expected37\]]
- expected: FAIL
-
- [test_special_key_sends_keydown[NUMPAD5-expected38\]]
- expected: FAIL
-
- [test_special_key_sends_keydown[NUMPAD6-expected39\]]
- expected: FAIL
-
- [test_special_key_sends_keydown[NUMPAD7-expected40\]]
- expected: FAIL
-
- [test_special_key_sends_keydown[NUMPAD8-expected41\]]
- expected: FAIL
-
- [test_special_key_sends_keydown[NUMPAD9-expected42\]]
- expected: FAIL
-
- [test_special_key_sends_keydown[PAGE_DOWN-expected43\]]
- expected: FAIL
-
- [test_special_key_sends_keydown[PAGE_UP-expected44\]]
- expected: FAIL
-
[test_special_key_sends_keydown[PAUSE-expected45\]]
expected: FAIL
-
- [test_special_key_sends_keydown[RETURN-expected46\]]
- expected: FAIL
-
- [test_special_key_sends_keydown[RIGHT-expected47\]]
- expected: FAIL
-
- [test_special_key_sends_keydown[R_ALT-expected48\]]
- expected: FAIL
-
- [test_special_key_sends_keydown[R_ARROWDOWN-expected49\]]
- expected: FAIL
-
- [test_special_key_sends_keydown[R_ARROWLEFT-expected50\]]
- expected: FAIL
-
- [test_special_key_sends_keydown[R_ARROWRIGHT-expected51\]]
- expected: FAIL
-
- [test_special_key_sends_keydown[R_ARROWUP-expected52\]]
- expected: FAIL
-
- [test_special_key_sends_keydown[R_CONTROL-expected53\]]
- expected: FAIL
-
- [test_special_key_sends_keydown[R_DELETE-expected54\]]
- expected: FAIL
-
- [test_special_key_sends_keydown[R_END-expected55\]]
- expected: FAIL
-
- [test_special_key_sends_keydown[R_HOME-expected56\]]
- expected: FAIL
-
- [test_special_key_sends_keydown[R_INSERT-expected57\]]
- expected: FAIL
-
- [test_special_key_sends_keydown[R_META-expected58\]]
- expected: FAIL
-
- [test_special_key_sends_keydown[R_PAGEDOWN-expected59\]]
- expected: FAIL
-
- [test_special_key_sends_keydown[R_PAGEUP-expected60\]]
- expected: FAIL
-
- [test_special_key_sends_keydown[R_SHIFT-expected61\]]
- expected: FAIL
-
- [test_special_key_sends_keydown[SEMICOLON-expected62\]]
- expected: FAIL
-
- [test_special_key_sends_keydown[SEPARATOR-expected63\]]
- expected: FAIL
-
- [test_special_key_sends_keydown[SHIFT-expected64\]]
- expected: FAIL
-
- [test_special_key_sends_keydown[SPACE-expected65\]]
- expected: FAIL
-
- [test_special_key_sends_keydown[SUBTRACT-expected66\]]
- expected: FAIL
-
- [test_special_key_sends_keydown[TAB-expected67\]]
- expected: FAIL
-
- [test_special_key_sends_keydown[UP-expected68\]]
- expected: FAIL
-
- [test_special_key_sends_keydown[ZENKAKUHANKAKU-expected69\]]
- expected: FAIL
diff --git a/tests/wpt/meta/webdriver/tests/classic/perform_actions/key_modifiers.py.ini b/tests/wpt/meta/webdriver/tests/classic/perform_actions/key_modifiers.py.ini
index 70b4b687388..118e70b33a8 100644
--- a/tests/wpt/meta/webdriver/tests/classic/perform_actions/key_modifiers.py.ini
+++ b/tests/wpt/meta/webdriver/tests/classic/perform_actions/key_modifiers.py.ini
@@ -1,10 +1,4 @@
[key_modifiers.py]
- [test_shift_modifier_and_non_printable_keys[\\ue008\]]
- expected: FAIL
-
- [test_shift_modifier_and_non_printable_keys[\\ue050\]]
- expected: FAIL
-
[test_shift_modifier_generates_capital_letters[\\ue008\]]
expected: FAIL
diff --git a/tests/wpt/meta/webdriver/tests/classic/perform_actions/key_shortcuts.py.ini b/tests/wpt/meta/webdriver/tests/classic/perform_actions/key_shortcuts.py.ini
index 43e9ac6cf32..8a5f8770474 100644
--- a/tests/wpt/meta/webdriver/tests/classic/perform_actions/key_shortcuts.py.ini
+++ b/tests/wpt/meta/webdriver/tests/classic/perform_actions/key_shortcuts.py.ini
@@ -1,3 +1,6 @@
[key_shortcuts.py]
[test_mod_a_mod_c_right_mod_v_pastes_text]
expected: FAIL
+
+ [test_mod_a_mod_x_deletes_all_text]
+ expected: FAIL
diff --git a/tests/wpt/meta/webdriver/tests/classic/perform_actions/key_special_keys.py.ini b/tests/wpt/meta/webdriver/tests/classic/perform_actions/key_special_keys.py.ini
index 9f97050ec49..5e1b1b41869 100644
--- a/tests/wpt/meta/webdriver/tests/classic/perform_actions/key_special_keys.py.ini
+++ b/tests/wpt/meta/webdriver/tests/classic/perform_actions/key_special_keys.py.ini
@@ -1,7 +1,4 @@
[key_special_keys.py]
- [test_codepoint_keys_behave_correctly[\\U0001f604\]]
- expected: FAIL
-
[test_codepoint_keys_behave_correctly[\\U0001f60d\]]
expected: FAIL
diff --git a/tests/wpt/meta/webdriver/tests/classic/perform_actions/navigation.py.ini b/tests/wpt/meta/webdriver/tests/classic/perform_actions/navigation.py.ini
index 38af76d3cf4..b7b8bf52a22 100644
--- a/tests/wpt/meta/webdriver/tests/classic/perform_actions/navigation.py.ini
+++ b/tests/wpt/meta/webdriver/tests/classic/perform_actions/navigation.py.ini
@@ -1,4 +1,5 @@
[navigation.py]
+ expected: TIMEOUT
[test_key]
expected: FAIL
diff --git a/tests/wpt/meta/webdriver/tests/classic/perform_actions/pointer_contextmenu.py.ini b/tests/wpt/meta/webdriver/tests/classic/perform_actions/pointer_contextmenu.py.ini
index e0fb2381634..62af3a877f5 100644
--- a/tests/wpt/meta/webdriver/tests/classic/perform_actions/pointer_contextmenu.py.ini
+++ b/tests/wpt/meta/webdriver/tests/classic/perform_actions/pointer_contextmenu.py.ini
@@ -1,9 +1,9 @@
[pointer_contextmenu.py]
[test_control_click[\\ue009-ctrlKey\]]
- expected: ERROR
+ expected: FAIL
[test_control_click[\\ue051-ctrlKey\]]
- expected: ERROR
+ expected: FAIL
[test_release_control_click]
- expected: ERROR
+ expected: FAIL
diff --git a/tests/wpt/meta/webdriver/tests/classic/perform_actions/pointer_dblclick.py.ini b/tests/wpt/meta/webdriver/tests/classic/perform_actions/pointer_dblclick.py.ini
deleted file mode 100644
index 523d8d29edb..00000000000
--- a/tests/wpt/meta/webdriver/tests/classic/perform_actions/pointer_dblclick.py.ini
+++ /dev/null
@@ -1,9 +0,0 @@
-[pointer_dblclick.py]
- [test_dblclick_at_coordinates[0\]]
- expected: FAIL
-
- [test_dblclick_at_coordinates[200\]]
- expected: FAIL
-
- [test_no_dblclick_when_mouse_moves]
- expected: FAIL
diff --git a/tests/wpt/meta/webdriver/tests/classic/perform_actions/pointer_modifier_click.py.ini b/tests/wpt/meta/webdriver/tests/classic/perform_actions/pointer_modifier_click.py.ini
index ebb9ef4dcc0..af13d756701 100644
--- a/tests/wpt/meta/webdriver/tests/classic/perform_actions/pointer_modifier_click.py.ini
+++ b/tests/wpt/meta/webdriver/tests/classic/perform_actions/pointer_modifier_click.py.ini
@@ -1,21 +1,21 @@
[pointer_modifier_click.py]
[test_modifier_click[\\ue00a-altKey\]]
- expected: ERROR
+ expected: FAIL
[test_modifier_click[\\ue052-altKey\]]
- expected: ERROR
+ expected: FAIL
[test_modifier_click[\\ue03d-metaKey\]]
- expected: ERROR
+ expected: FAIL
[test_modifier_click[\\ue053-metaKey\]]
- expected: ERROR
+ expected: FAIL
[test_modifier_click[\\ue008-shiftKey\]]
- expected: ERROR
+ expected: FAIL
[test_modifier_click[\\ue050-shiftKey\]]
- expected: ERROR
+ expected: FAIL
[test_many_modifiers_click]
- expected: ERROR
+ expected: FAIL
diff --git a/tests/wpt/meta/webdriver/tests/classic/perform_actions/pointer_mouse.py.ini b/tests/wpt/meta/webdriver/tests/classic/perform_actions/pointer_mouse.py.ini
index 4222966b349..d4ef4398b7f 100644
--- a/tests/wpt/meta/webdriver/tests/classic/perform_actions/pointer_mouse.py.ini
+++ b/tests/wpt/meta/webdriver/tests/classic/perform_actions/pointer_mouse.py.ini
@@ -1,4 +1,5 @@
[pointer_mouse.py]
+ expected: TIMEOUT
[test_no_top_browsing_context]
expected: FAIL
diff --git a/tests/wpt/meta/webdriver/tests/classic/perform_actions/pointer_pen.py.ini b/tests/wpt/meta/webdriver/tests/classic/perform_actions/pointer_pen.py.ini
index 5c08076b7b2..d7922cb4283 100644
--- a/tests/wpt/meta/webdriver/tests/classic/perform_actions/pointer_pen.py.ini
+++ b/tests/wpt/meta/webdriver/tests/classic/perform_actions/pointer_pen.py.ini
@@ -1,4 +1,5 @@
[pointer_pen.py]
+ expected: TIMEOUT
[test_no_top_browsing_context]
expected: FAIL
diff --git a/tests/wpt/meta/webdriver/tests/classic/perform_actions/pointer_touch.py.ini b/tests/wpt/meta/webdriver/tests/classic/perform_actions/pointer_touch.py.ini
index 2dd2ee19891..85e34998125 100644
--- a/tests/wpt/meta/webdriver/tests/classic/perform_actions/pointer_touch.py.ini
+++ b/tests/wpt/meta/webdriver/tests/classic/perform_actions/pointer_touch.py.ini
@@ -1,4 +1,5 @@
[pointer_touch.py]
+ expected: TIMEOUT
[test_no_top_browsing_context]
expected: FAIL
diff --git a/tests/wpt/meta/webdriver/tests/classic/release_actions/sequence_tentative.py.ini b/tests/wpt/meta/webdriver/tests/classic/release_actions/sequence_tentative.py.ini
index aed5f673813..9c048ff9b5f 100644
--- a/tests/wpt/meta/webdriver/tests/classic/release_actions/sequence_tentative.py.ini
+++ b/tests/wpt/meta/webdriver/tests/classic/release_actions/sequence_tentative.py.ini
@@ -1,4 +1,5 @@
[sequence_tentative.py]
+ expected: TIMEOUT
[test_release_mouse_sequence_resets_dblclick_state[with release actions\]]
expected: FAIL
diff --git a/tests/wpt/meta/webdriver/tests/classic/set_window_rect/set.py.ini b/tests/wpt/meta/webdriver/tests/classic/set_window_rect/set.py.ini
index 6b28c2efdf8..d530b687213 100644
--- a/tests/wpt/meta/webdriver/tests/classic/set_window_rect/set.py.ini
+++ b/tests/wpt/meta/webdriver/tests/classic/set_window_rect/set.py.ini
@@ -15,7 +15,7 @@
expected: FAIL
[test_set_to_available_size]
- expected: ERROR
+ expected: FAIL
[test_set_smaller_than_minimum_browser_size]
expected: FAIL
@@ -30,10 +30,22 @@
expected: FAIL
[test_negative_x_y]
- expected: ERROR
+ expected: FAIL
[test_set_to_screen_size]
- expected: ERROR
+ expected: FAIL
[test_set_larger_than_screen_size]
- expected: ERROR
+ expected: FAIL
+
+ [test_width_height_floats]
+ expected: FAIL
+
+ [test_height_width_as_current]
+ expected: FAIL
+
+ [test_height_as_current]
+ expected: FAIL
+
+ [test_width_as_current]
+ expected: FAIL
diff --git a/tests/wpt/meta/webdriver/tests/classic/switch_to_frame/switch.py.ini b/tests/wpt/meta/webdriver/tests/classic/switch_to_frame/switch.py.ini
index ee73fbf4ce8..66625728565 100644
--- a/tests/wpt/meta/webdriver/tests/classic/switch_to_frame/switch.py.ini
+++ b/tests/wpt/meta/webdriver/tests/classic/switch_to_frame/switch.py.ini
@@ -16,6 +16,3 @@
[test_frame_id_shadow_root]
expected: FAIL
-
- [test_frame_id_null]
- expected: FAIL
diff --git a/tests/wpt/meta/webdriver/tests/classic/switch_to_parent_frame/switch.py.ini b/tests/wpt/meta/webdriver/tests/classic/switch_to_parent_frame/switch.py.ini
index ffd3d06f212..352421f84c1 100644
--- a/tests/wpt/meta/webdriver/tests/classic/switch_to_parent_frame/switch.py.ini
+++ b/tests/wpt/meta/webdriver/tests/classic/switch_to_parent_frame/switch.py.ini
@@ -1,6 +1,3 @@
[switch.py]
- [test_switch_from_iframe]
- expected: FAIL
-
[test_switch_from_top_level]
expected: FAIL
diff --git a/tests/wpt/meta/webdriver/tests/classic/switch_to_window/alerts.py.ini b/tests/wpt/meta/webdriver/tests/classic/switch_to_window/alerts.py.ini
index 3e6ad0c8af9..aa34b0b2489 100644
--- a/tests/wpt/meta/webdriver/tests/classic/switch_to_window/alerts.py.ini
+++ b/tests/wpt/meta/webdriver/tests/classic/switch_to_window/alerts.py.ini
@@ -1,3 +1,4 @@
[alerts.py]
+ expected: TIMEOUT
[test_retain_tab_modal_status]
expected: FAIL
diff --git a/tests/wpt/meta/webdriver/tests/classic/switch_to_window/switch.py.ini b/tests/wpt/meta/webdriver/tests/classic/switch_to_window/switch.py.ini
index 9b0ec38199b..44ac97a7a36 100644
--- a/tests/wpt/meta/webdriver/tests/classic/switch_to_window/switch.py.ini
+++ b/tests/wpt/meta/webdriver/tests/classic/switch_to_window/switch.py.ini
@@ -1,4 +1,5 @@
[switch.py]
+ expected: TIMEOUT
[test_no_top_browsing_context]
expected: FAIL
diff --git a/tests/wpt/meta/webdriver/tests/classic/take_element_screenshot/iframe.py.ini b/tests/wpt/meta/webdriver/tests/classic/take_element_screenshot/iframe.py.ini
index dd77eca9d72..c6374102e3f 100644
--- a/tests/wpt/meta/webdriver/tests/classic/take_element_screenshot/iframe.py.ini
+++ b/tests/wpt/meta/webdriver/tests/classic/take_element_screenshot/iframe.py.ini
@@ -1,9 +1,3 @@
[iframe.py]
[test_frame_element]
expected: FAIL
-
- [test_source_origin[same_origin\]]
- expected: FAIL
-
- [test_source_origin[cross_origin\]]
- expected: FAIL
diff --git a/tests/wpt/meta/webdriver/tests/classic/take_screenshot/iframe.py.ini b/tests/wpt/meta/webdriver/tests/classic/take_screenshot/iframe.py.ini
new file mode 100644
index 00000000000..b63f4c9fb07
--- /dev/null
+++ b/tests/wpt/meta/webdriver/tests/classic/take_screenshot/iframe.py.ini
@@ -0,0 +1,9 @@
+[iframe.py]
+ [test_always_captures_top_browsing_context]
+ expected: FAIL
+
+ [test_source_origin[same_origin\]]
+ expected: FAIL
+
+ [test_source_origin[cross_origin\]]
+ expected: FAIL
diff --git a/tests/wpt/meta/webdriver/tests/classic/take_screenshot/screenshot.py.ini b/tests/wpt/meta/webdriver/tests/classic/take_screenshot/screenshot.py.ini
index f2fac7a7fa1..aef7c9d5ddc 100644
--- a/tests/wpt/meta/webdriver/tests/classic/take_screenshot/screenshot.py.ini
+++ b/tests/wpt/meta/webdriver/tests/classic/take_screenshot/screenshot.py.ini
@@ -4,3 +4,6 @@
[test_no_browsing_context]
expected: FAIL
+
+ [test_format_and_dimensions]
+ expected: FAIL
diff --git a/tests/wpt/meta/websockets/stream/tentative/write.any.js.ini b/tests/wpt/meta/websockets/stream/tentative/write.any.js.ini
new file mode 100644
index 00000000000..491b41e2c47
--- /dev/null
+++ b/tests/wpt/meta/websockets/stream/tentative/write.any.js.ini
@@ -0,0 +1,118 @@
+[write.any.sharedworker.html?wpt_flags=h2]
+ expected: ERROR
+
+[write.any.serviceworker.html?default]
+ expected: ERROR
+
+[write.any.worker.html?wpt_flags=h2]
+ [a write that was incomplete at close time should reject]
+ expected: FAIL
+
+ [garbage collection after close with a pending write promise should not crash]
+ expected: FAIL
+
+ [writing a value that cannot be stringified should cause a rejection]
+ expected: FAIL
+
+ [writing a resizable ArrayBuffer should be rejected]
+ expected: FAIL
+
+ [writing a view on a shared buffer should be rejected]
+ expected: FAIL
+
+
+[write.any.sharedworker.html?wss]
+ expected: ERROR
+
+[write.any.html?default]
+ [a write that was incomplete at close time should reject]
+ expected: FAIL
+
+ [garbage collection after close with a pending write promise should not crash]
+ expected: FAIL
+
+ [writing a value that cannot be stringified should cause a rejection]
+ expected: FAIL
+
+ [writing a resizable ArrayBuffer should be rejected]
+ expected: FAIL
+
+ [writing a view on a shared buffer should be rejected]
+ expected: FAIL
+
+
+[write.any.worker.html?wss]
+ [a write that was incomplete at close time should reject]
+ expected: FAIL
+
+ [garbage collection after close with a pending write promise should not crash]
+ expected: FAIL
+
+ [writing a value that cannot be stringified should cause a rejection]
+ expected: FAIL
+
+ [writing a resizable ArrayBuffer should be rejected]
+ expected: FAIL
+
+ [writing a view on a shared buffer should be rejected]
+ expected: FAIL
+
+
+[write.any.serviceworker.html?wpt_flags=h2]
+ expected: ERROR
+
+[write.any.html?wpt_flags=h2]
+ [a write that was incomplete at close time should reject]
+ expected: FAIL
+
+ [garbage collection after close with a pending write promise should not crash]
+ expected: FAIL
+
+ [writing a value that cannot be stringified should cause a rejection]
+ expected: FAIL
+
+ [writing a resizable ArrayBuffer should be rejected]
+ expected: FAIL
+
+ [writing a view on a shared buffer should be rejected]
+ expected: FAIL
+
+
+[write.any.serviceworker.html?wss]
+ expected: ERROR
+
+[write.any.sharedworker.html?default]
+ expected: ERROR
+
+[write.any.worker.html?default]
+ [a write that was incomplete at close time should reject]
+ expected: FAIL
+
+ [garbage collection after close with a pending write promise should not crash]
+ expected: FAIL
+
+ [writing a value that cannot be stringified should cause a rejection]
+ expected: FAIL
+
+ [writing a resizable ArrayBuffer should be rejected]
+ expected: FAIL
+
+ [writing a view on a shared buffer should be rejected]
+ expected: FAIL
+
+
+[write.any.html?wss]
+ [a write that was incomplete at close time should reject]
+ expected: FAIL
+
+ [garbage collection after close with a pending write promise should not crash]
+ expected: FAIL
+
+ [writing a value that cannot be stringified should cause a rejection]
+ expected: FAIL
+
+ [writing a resizable ArrayBuffer should be rejected]
+ expected: FAIL
+
+ [writing a view on a shared buffer should be rejected]
+ expected: FAIL
diff --git a/tests/wpt/meta/workers/constructors/Worker/Worker-constructor.html.ini b/tests/wpt/meta/workers/constructors/Worker/Worker-constructor.html.ini
new file mode 100644
index 00000000000..80f9a4f15b8
--- /dev/null
+++ b/tests/wpt/meta/workers/constructors/Worker/Worker-constructor.html.ini
@@ -0,0 +1,2 @@
+[Worker-constructor.html]
+ expected: ERROR
diff --git a/tests/wpt/meta/workers/tentative/SharedWorker-extendedLifetime.html.ini b/tests/wpt/meta/workers/tentative/SharedWorker-extendedLifetime.html.ini
new file mode 100644
index 00000000000..086935d2b6d
--- /dev/null
+++ b/tests/wpt/meta/workers/tentative/SharedWorker-extendedLifetime.html.ini
@@ -0,0 +1,3 @@
+[SharedWorker-extendedLifetime.html]
+ [SharedWorker lifetime should be extended with extendedLifetime]
+ expected: FAIL
diff --git a/tests/wpt/meta/xhr/abort-during-done.window.js.ini b/tests/wpt/meta/xhr/abort-during-done.window.js.ini
deleted file mode 100644
index cfce26bf75b..00000000000
--- a/tests/wpt/meta/xhr/abort-during-done.window.js.ini
+++ /dev/null
@@ -1,9 +0,0 @@
-[abort-during-done.window.html]
- [XMLHttpRequest: abort() during DONE (sync)]
- expected: FAIL
-
- [XMLHttpRequest: abort() during DONE (sync aborted in readystatechange)]
- expected: FAIL
-
- [XMLHttpRequest: abort() during DONE (async)]
- expected: FAIL
diff --git a/tests/wpt/meta/xhr/abort-during-headers-received.window.js.ini b/tests/wpt/meta/xhr/abort-during-headers-received.window.js.ini
deleted file mode 100644
index aa78b3966cc..00000000000
--- a/tests/wpt/meta/xhr/abort-during-headers-received.window.js.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[abort-during-headers-received.window.html]
- [XMLHttpRequest: abort() during HEADERS_RECEIVED]
- expected: FAIL
diff --git a/tests/wpt/meta/xhr/abort-during-loading.window.js.ini b/tests/wpt/meta/xhr/abort-during-loading.window.js.ini
deleted file mode 100644
index 33a6772164b..00000000000
--- a/tests/wpt/meta/xhr/abort-during-loading.window.js.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[abort-during-loading.window.html]
- [XMLHttpRequest: abort() during LOADING]
- expected: FAIL
diff --git a/tests/wpt/tests/client-hints/permissions-policy/WEB_FEATURES.yml b/tests/wpt/tests/client-hints/permissions-policy/WEB_FEATURES.yml
new file mode 100644
index 00000000000..da7599308cc
--- /dev/null
+++ b/tests/wpt/tests/client-hints/permissions-policy/WEB_FEATURES.yml
@@ -0,0 +1,6 @@
+features:
+- name: ua-client-hints
+ # Note: if any permissions-policy tests are added that do not
+ # depend on ua-client-hints, `files` below should be updated
+ # accordingly.
+ files: "**"
diff --git a/tests/wpt/tests/container-timing/resources/container-timing-helpers.js b/tests/wpt/tests/container-timing/resources/container-timing-helpers.js
index a80ad964fef..8b3f21dff56 100644
--- a/tests/wpt/tests/container-timing/resources/container-timing-helpers.js
+++ b/tests/wpt/tests/container-timing/resources/container-timing-helpers.js
@@ -20,3 +20,19 @@ function checkContainerEntry(entry, identifier, last_element_id, beforeRender) {
function checkContainerSize(entry, size) {
assert_equals(entry.size, size);
}
+
+function finishOnElementTiming(t) {
+ const finish_observer = new PerformanceObserver(() => {
+ requestAnimationFrame(() => { t.done(); });
+ });
+ finish_observer.observe({ entryTypes: ['element'] });
+}
+
+function addPaintingElementTimingAfterDoubleRAF(parent) {
+ requestAnimationFrame(() => requestAnimationFrame(() => {
+ const finish_img = document.createElement('img');
+ finish_img.src = '/container-timing/resources/square100.png';
+ finish_img.setAttribute('elementtiming', '');
+ parent.appendChild(finish_img);
+ }));
+}
diff --git a/tests/wpt/tests/container-timing/tentative/containertiming-with-child-ignore-and-child-img.html b/tests/wpt/tests/container-timing/tentative/containertiming-with-child-ignore-and-child-img.html
new file mode 100644
index 00000000000..b4fa9754c10
--- /dev/null
+++ b/tests/wpt/tests/container-timing/tentative/containertiming-with-child-ignore-and-child-img.html
@@ -0,0 +1,46 @@
+<!DOCTYPE HTML>
+<meta charset=utf-8>
+<title>Container Timing: an image inside a containertiming-ignore inside a containertiming root</title>
+<body>
+<style>
+body {
+ margin: 0;
+}
+</style>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/container-timing/resources/container-timing-helpers.js"></script>
+<script src="/element-timing/resources/element-timing-helpers.js"></script>
+<script>
+ async_test(function (t) {
+ assert_implements(window.PerformanceContainerTiming, "PerformanceContainerTiming is not implemented");
+ const observer = new PerformanceObserver(
+ function(entryList) {
+ assert_unreached("No entry is expected with nothing to paint");
+ }
+ );
+ observer.observe({entryTypes: ['container']});
+
+ finishOnElementTiming(t);
+
+ // Add a div that is the container timing root
+ const div1 = document.createElement('div');
+ div1.setAttribute('containertiming', 'div1_ct');
+ document.body.appendChild(div1);
+
+ // Intermediate ignore should block paint events
+ const div2 = document.createElement('div');
+ div2.setAttribute('containertiming-ignore', '');
+ div1.appendChild(div2)
+
+ // Add image of width equal to 100 and height equal to 100.
+ const img = document.createElement('img');
+ img.src = '/container-timing/resources/square100.png';
+ img.setAttribute('id', 'img_id');
+ div2.appendChild(img);
+
+ addPaintingElementTimingAfterDoubleRAF(document.body);
+ }, 'Paint of the image child of container timing with ignore in the middle is not reported.');
+</script>
+
+</body>
diff --git a/tests/wpt/tests/container-timing/tentative/containertiming-with-ignore-and-child-img.html b/tests/wpt/tests/container-timing/tentative/containertiming-with-ignore-and-child-img.html
new file mode 100644
index 00000000000..20e9e4a9218
--- /dev/null
+++ b/tests/wpt/tests/container-timing/tentative/containertiming-with-ignore-and-child-img.html
@@ -0,0 +1,45 @@
+<!DOCTYPE HTML>
+<meta charset=utf-8>
+<title>Container Timing: observe with a node with containertiming and containertiming-ignore, and an image child</title>
+<body>
+<style>
+body {
+ margin: 0;
+}
+</style>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/container-timing/resources/container-timing-helpers.js"></script>
+<script src="/element-timing/resources/element-timing-helpers.js"></script>
+<script>
+ let beforeRender;
+ async_test(function (t) {
+ assert_implements(window.PerformanceContainerTiming, "PerformanceContainerTiming is not implemented");
+ const observer = new PerformanceObserver(
+ t.step_func_done(function(entryList) {
+ assert_equals(entryList.getEntries().length, 1);
+ const entry = entryList.getEntries()[0];
+ checkContainerEntry(entry, 'div_ct', 'img_id', beforeRender)
+ checkRect(entry, [0, 100, 0, 100])
+ checkContainerSize(entry, 10000);
+ })
+ );
+ observer.observe({entryTypes: ['container']});
+
+ // Add a div that is the container timing root
+ // and containertiming-ignore, that should be ignored as
+ // containertiming takes precedence.
+ const div = document.createElement('div');
+ div.setAttribute('containertiming', 'div_ct');
+ div.setAttribute('containertiming-ignore', '');
+ document.body.appendChild(div);
+ // Add image of width equal to 100 and height equal to 100.
+ const img = document.createElement('img');
+ img.src = '/container-timing/resources/square100.png';
+ img.setAttribute('id', 'img_id');
+ div.appendChild(img);
+ beforeRender = performance.now();
+ }, 'Paint of the image child of container timing with ignore is not blocked.');
+</script>
+
+</body>
diff --git a/tests/wpt/tests/container-timing/tentative/ignore-with-containertiming-and-child-img.html b/tests/wpt/tests/container-timing/tentative/ignore-with-containertiming-and-child-img.html
new file mode 100644
index 00000000000..841b4441d4d
--- /dev/null
+++ b/tests/wpt/tests/container-timing/tentative/ignore-with-containertiming-and-child-img.html
@@ -0,0 +1,49 @@
+<!DOCTYPE HTML>
+<meta charset=utf-8>
+<title>Container Timing: an image inside a containertiming inside a containertiming-ignore</title>
+<body>
+<style>
+body {
+ margin: 0;
+}
+</style>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/container-timing/resources/container-timing-helpers.js"></script>
+<script src="/element-timing/resources/element-timing-helpers.js"></script>
+<script>
+ let beforeRender;
+ async_test(function (t) {
+ assert_implements(window.PerformanceContainerTiming, "PerformanceContainerTiming is not implemented");
+ const observer = new PerformanceObserver(
+ t.step_func_done(function(entryList) {
+ assert_equals(entryList.getEntries().length, 1);
+ const entry = entryList.getEntries()[0];
+ checkContainerEntry(entry, 'div2_ct', 'img_id', beforeRender)
+ checkRect(entry, [0, 100, 0, 100])
+ checkContainerSize(entry, 10000);
+ })
+ );
+ observer.observe({entryTypes: ['container']});
+
+ // Add a div that is the container timing root
+ const div1 = document.createElement('div');
+ div1.setAttribute('containertiming-ignore', '');
+ document.body.appendChild(div1);
+
+ // Intermediate ignore should block paint events
+ const div2 = document.createElement('div');
+ div2.setAttribute('containertiming', 'div2_ct');
+ div1.appendChild(div2)
+
+ // Add image of width equal to 100 and height equal to 100.
+ const img = document.createElement('img');
+ img.src = '/container-timing/resources/square100.png';
+ img.setAttribute('id', 'img_id');
+ div2.appendChild(img);
+
+ beforeRender = performance.now();
+}, 'An image inside a containertiming, inside a containertiming-ignore is still reported.');
+</script>
+
+</body>
diff --git a/tests/wpt/tests/content-security-policy/default-src/default-src-sri_hash.sub.html b/tests/wpt/tests/content-security-policy/default-src/default-src-sri_hash.sub.html
index 87fce5961fd..87389c306a5 100644
--- a/tests/wpt/tests/content-security-policy/default-src/default-src-sri_hash.sub.html
+++ b/tests/wpt/tests/content-security-policy/default-src/default-src-sri_hash.sub.html
@@ -7,6 +7,9 @@
<script src='/resources/testharnessreport.js' nonce='dummy'></script>
<!-- CSP served: default-src {{domains[www]}}:* 'nonce-dummy' 'sha256-wIc3KtqOuTFEu6t17sIBuOswgkV406VJvhSk79Gw6U0=' 'ShA256-L7/UQ9VWpyG7C9RDEC4ctS5hI3Zcw+ta+haPGlByG9c=' 'sha512-rYCVMxWV5nq8IsMo+UZNObWtEiWGok/vDN8BMoEQi41s0znSes6E1Q2aag3Lw3u2J1w2rqH7uF2ws6FpQhfSOA=='; style-src 'unsafe-inline' -->
+ <!-- The domain here is intentionally served with `www`. In the event that the integrity check fails,
+ the request should be disallowed by the source list. If we were to use {{domains[]}},
+ then we would not be able to observe the difference with regards to the integrity check -->
<!-- ShA256 is intentionally mixed case -->
</head>
@@ -18,6 +21,8 @@
var port = "{{ports[http][0]}}";
if (location.protocol === "https:")
port = "{{ports[https][0]}}";
+ // Since {{domains[www]}} is allowed by the CSP policy, regardless of the integrity check
+ // the request would be allowed.
var crossorigin_base = location.protocol + "//{{domains[www]}}:" + port;
// Test name, src, integrity, expected to run.
diff --git a/tests/wpt/tests/content-security-policy/script-src/script-src-sri_hash.sub.html b/tests/wpt/tests/content-security-policy/script-src/script-src-sri_hash.sub.html
index 9216e2b0d49..e290911183d 100644
--- a/tests/wpt/tests/content-security-policy/script-src/script-src-sri_hash.sub.html
+++ b/tests/wpt/tests/content-security-policy/script-src/script-src-sri_hash.sub.html
@@ -7,6 +7,9 @@
<script src='/resources/testharnessreport.js' nonce='dummy'></script>
<!-- CSP served: script-src {{domains[www]}}:* 'nonce-dummy' 'sha256-wIc3KtqOuTFEu6t17sIBuOswgkV406VJvhSk79Gw6U0=' 'ShA256-L7/UQ9VWpyG7C9RDEC4ctS5hI3Zcw+ta+haPGlByG9c=' 'sha512-rYCVMxWV5nq8IsMo+UZNObWtEiWGok/vDN8BMoEQi41s0znSes6E1Q2aag3Lw3u2J1w2rqH7uF2ws6FpQhfSOA==' -->
+ <!-- The domain here is intentionally served with `www`. In the event that the integrity check fails,
+ the request should be disallowed by the source list. If we were to use {{domains[]}},
+ then we would not be able to observe the difference with regards to the integrity check -->
<!-- ShA256 is intentionally mixed case -->
</head>
@@ -18,6 +21,8 @@
var port = "{{ports[http][0]}}";
if (location.protocol === "https:")
port = "{{ports[https][0]}}";
+ // Since {{domains[www]}} is allowed by the CSP policy, regardless of the integrity check
+ // the request would be allowed.
var crossorigin_base = location.protocol + "//{{domains[www]}}:" + port;
// Test name, src, integrity, expected to run.
diff --git a/tests/wpt/tests/content-security-policy/script-src/script-src-strict_dynamic_parser_inserted.html b/tests/wpt/tests/content-security-policy/script-src/script-src-strict_dynamic_parser_inserted.html
index c5e33dc4253..9a8ad7a4ef2 100644
--- a/tests/wpt/tests/content-security-policy/script-src/script-src-strict_dynamic_parser_inserted.html
+++ b/tests/wpt/tests/content-security-policy/script-src/script-src-strict_dynamic_parser_inserted.html
@@ -2,11 +2,12 @@
<html>
<head>
- <title>Parser-inserted scripts without a correct nonce are not allowed with `strict-dynamic` in the script-src directive.</title>
+ <title>Parser-inserted scripts without a correct nonce are not allowed with `Strict-Dynamic` in the script-src directive.</title>
<script src='/resources/testharness.js' nonce='dummy'></script>
<script src='/resources/testharnessreport.js' nonce='dummy'></script>
- <!-- CSP served: script-src 'strict-dynamic' 'nonce-dummy' -->
+ <!-- CSP served: script-src 'Strict-Dynamic' 'nonce-dummy' -->
+ <!-- Strict-Dynamic is intentionally mixed case -->
</head>
<body>
diff --git a/tests/wpt/tests/content-security-policy/script-src/script-src-strict_dynamic_parser_inserted.html.headers b/tests/wpt/tests/content-security-policy/script-src/script-src-strict_dynamic_parser_inserted.html.headers
index b7918c93323..9d0b3b93d44 100644
--- a/tests/wpt/tests/content-security-policy/script-src/script-src-strict_dynamic_parser_inserted.html.headers
+++ b/tests/wpt/tests/content-security-policy/script-src/script-src-strict_dynamic_parser_inserted.html.headers
@@ -2,4 +2,4 @@ Expires: Mon, 26 Jul 1997 05:00:00 GMT
Cache-Control: no-store, no-cache, must-revalidate
Cache-Control: post-check=0, pre-check=0, false
Pragma: no-cache
-Content-Security-Policy: script-src 'strict-dynamic' 'nonce-dummy'
+Content-Security-Policy: script-src 'Strict-Dynamic' 'nonce-dummy'
diff --git a/tests/wpt/tests/cookie-store/META.yml b/tests/wpt/tests/cookie-store/META.yml
index 68c30024552..4bbc6311bdc 100644
--- a/tests/wpt/tests/cookie-store/META.yml
+++ b/tests/wpt/tests/cookie-store/META.yml
@@ -1,4 +1,3 @@
spec: https://wicg.github.io/cookie-store/
suggested_reviewers:
- - inexorabletash
- - ayuishii
+ - dcthetall
diff --git a/tests/wpt/tests/cookie-store/cookieStore_special_names.https.any.js b/tests/wpt/tests/cookie-store/cookieStore_special_names.https.any.js
index e2a3df7fe33..1e12674a7f7 100644
--- a/tests/wpt/tests/cookie-store/cookieStore_special_names.https.any.js
+++ b/tests/wpt/tests/cookie-store/cookieStore_special_names.https.any.js
@@ -3,7 +3,7 @@
'use strict';
-['__Secure-', '__Host-'].forEach(prefix => {
+['__Secure-', '__secure-', '__Host-', '__host-'].forEach(prefix => {
promise_test(async testCase => {
await cookieStore.set(`${prefix}cookie-name`, `secure-cookie-value`);
assert_equals(
@@ -32,25 +32,27 @@
}, `cookieStore.delete with ${prefix} name on secure origin`);
});
-promise_test(async testCase => {
- const currentUrl = new URL(self.location.href);
- const currentDomain = currentUrl.hostname;
- await promise_rejects_js(testCase, TypeError,
- cookieStore.set({ name: '__Host-cookie-name', value: 'cookie-value',
- domain: currentDomain }));
-}, 'cookieStore.set with __Host- prefix and a domain option');
+['__Host-', '__host-'].forEach(prefix => {
+ promise_test(async testCase => {
+ const currentUrl = new URL(self.location.href);
+ const currentDomain = currentUrl.hostname;
+ await promise_rejects_js(testCase, TypeError,
+ cookieStore.set({ name: `${prefix}cookie-name`, value: 'cookie-value',
+ domain: currentDomain }));
+ }, `cookieStore.set with ${prefix} prefix and a domain option`);
-promise_test(async testCase => {
- await cookieStore.set({ name: '__Host-cookie-name', value: 'cookie-value',
- path: "/" });
+ promise_test(async testCase => {
+ await cookieStore.set({ name: `${prefix}cookie-name`, value: 'cookie-value',
+ path: "/" });
- assert_equals(
- (await cookieStore.get(`__Host-cookie-name`)).value, "cookie-value");
+ assert_equals(
+ (await cookieStore.get(`${prefix}cookie-name`)).value, "cookie-value");
- await promise_rejects_js(testCase, TypeError,
- cookieStore.set( { name: '__Host-cookie-name', value: 'cookie-value',
- path: "/path" }));
-}, 'cookieStore.set with __Host- prefix a path option');
+ await promise_rejects_js(testCase, TypeError,
+ cookieStore.set( { name: `${prefix}cookie-name`, value: 'cookie-value',
+ path: "/path" }));
+ }, `cookieStore.set with ${prefix} prefix a path option`);
+});
promise_test(async testCase => {
let exceptionThrown = false;
diff --git a/tests/wpt/tests/cookie-store/encoding.https.any.js b/tests/wpt/tests/cookie-store/encoding.https.any.js
index 941639bdaec..f5d2ca15e71 100644
--- a/tests/wpt/tests/cookie-store/encoding.https.any.js
+++ b/tests/wpt/tests/cookie-store/encoding.https.any.js
@@ -4,15 +4,21 @@
'use strict';
-cookie_test(async t => {
+promise_test(async t => {
await setCookieStringHttp('\uFEFFcookie=value; path=/');
+ t.add_cleanup(async () => {
+ await setCookieStringHttp('\uFEFFcookie=value; path=/; Max-Age=0');
+ });
const cookie = await cookieStore.get('\uFEFFcookie');
assert_equals(cookie.name, '\uFEFFcookie');
assert_equals(cookie.value, 'value');
}, 'BOM not stripped from name');
-cookie_test(async t => {
+promise_test(async t => {
await setCookieStringHttp('cookie=\uFEFFvalue; path=/');
+ t.add_cleanup(async () => {
+ await setCookieStringHttp('cookie=\uFEFFvalue; path=/; Max-Age=0');
+ });
const cookie = await cookieStore.get('cookie');
assert_equals(cookie.name, 'cookie');
assert_equals(cookie.value, '\uFEFFvalue');
diff --git a/tests/wpt/tests/cookie-store/httponly_cookies.https.window.js b/tests/wpt/tests/cookie-store/httponly_cookies.https.window.js
index 605e94e6744..836f47da3f6 100644
--- a/tests/wpt/tests/cookie-store/httponly_cookies.https.window.js
+++ b/tests/wpt/tests/cookie-store/httponly_cookies.https.window.js
@@ -2,7 +2,7 @@
'use strict';
-cookie_test(async t => {
+promise_test(async t => {
let eventPromise = observeNextCookieChangeEvent();
await setCookieStringHttp('HTTPONLY-cookie=value; path=/; httponly');
assert_equals(
@@ -29,6 +29,9 @@ cookie_test(async t => {
eventPromise = observeNextCookieChangeEvent();
await setCookieStringHttp(
'HTTPONLY-cookie=DELETED; path=/; max-age=0; httponly');
+ t.add_cleanup(async () => {
+ await setCookieStringHttp(`HTTPONLY-cookie=DELETED; path=/; httponly; Max-Age=0`);
+ });
assert_equals(
await getCookieString(),
undefined,
@@ -41,6 +44,9 @@ cookie_test(async t => {
// HTTPONLY cookie changes should not have been observed; perform
// a dummy change to verify that nothing else was queued up.
await cookieStore.set('TEST', 'dummy');
+ t.add_cleanup(async () => {
+ await cookieStore.delete('TEST');
+ });
await verifyCookieChangeEvent(
eventPromise, {changed: [{name: 'TEST', value: 'dummy'}]},
'HttpOnly cookie deletion was not observed');
@@ -68,8 +74,11 @@ cookie_test(async t => {
'httpOnly is not an option for CookieStore.set()');
}, 'HttpOnly cookies can not be set by CookieStore');
-cookie_test(async t => {
+promise_test(async t => {
await setCookieStringHttp('HTTPONLY-cookie=value; path=/; httponly');
+ t.add_cleanup(async () => {
+ await setCookieStringHttp(`HTTPONLY-cookie=DELETED; path=/; httponly; Max-Age=0`);
+ });
assert_equals(
await getCookieString(),
undefined,
diff --git a/tests/wpt/tests/cookie-store/resources/cookie-test-helpers.js b/tests/wpt/tests/cookie-store/resources/cookie-test-helpers.js
index 8e23ff2c422..82ca135f88e 100644
--- a/tests/wpt/tests/cookie-store/resources/cookie-test-helpers.js
+++ b/tests/wpt/tests/cookie-store/resources/cookie-test-helpers.js
@@ -210,10 +210,12 @@ async function cookie_test(func, description) {
// Wipe cookies used by tests before and after the test.
async function deleteAllCookies() {
- await Promise.all((await cookieStore.getAll()).map(async ({name, value}) => {
- await cookieStore.delete(name);
- await cookieStore.delete({name: name, partitioned: true});
- }));
+ const cookies = await cookieStore.getAll();
+ await Promise.all(cookies.flatMap(
+ ({name}) =>
+ [cookieStore.delete(name),
+ cookieStore.delete({name, partitioned: true}),
+ ]));
}
return promise_test(async t => {
diff --git a/tests/wpt/tests/css/css-anchor-position/anchor-scope-basic.html b/tests/wpt/tests/css/css-anchor-position/anchor-scope-basic.html
index 47cb3b8d86a..ffe3b45ba0d 100644
--- a/tests/wpt/tests/css/css-anchor-position/anchor-scope-basic.html
+++ b/tests/wpt/tests/css/css-anchor-position/anchor-scope-basic.html
@@ -11,7 +11,8 @@
.anchor-a { anchor-name: --a; }
.anchor-b { anchor-name: --b; }
- .anchor-a, .anchor-b {
+ .anchor-ab { anchor-name: --a, --b; }
+ .anchor-a, .anchor-b, .anchor-ab {
background: skyblue;
height: 10px;
}
@@ -159,7 +160,8 @@
<div class=anchor-b></div>
<div class=anchor-a></div><!--A-->
<div class=scope-a>
- <div class=anchor-b></div><!--B-->
+ <div class=anchor-b></div>
+ <div class=anchor-ab></div><!--B-->
<div class=anchor-a></div>
</div>
<div class=anchored-a></div>
@@ -169,7 +171,7 @@
test((t) => {
inflate(t, test_scope_a);
assert_equals(getComputedStyle(main.querySelector('.anchored-a')).top, '20px');
- assert_equals(getComputedStyle(main.querySelector('.anchored-b')).top, '30px');
+ assert_equals(getComputedStyle(main.querySelector('.anchored-b')).top, '40px');
}, 'anchor-scope:--a scopes only --a');
</script>
@@ -177,8 +179,8 @@
<div class=anchor-b></div><!--B-->
<div class=anchor-a></div>
<div class=scope-b>
- <div class=anchor-b></div>
<div class=anchor-a></div><!--A-->
+ <div class=anchor-b></div>
</div>
<div class=anchored-a></div>
<div class=anchored-b></div>
@@ -186,7 +188,7 @@
<script>
test((t) => {
inflate(t, test_scope_b);
- assert_equals(getComputedStyle(main.querySelector('.anchored-a')).top, '40px');
+ assert_equals(getComputedStyle(main.querySelector('.anchored-a')).top, '30px');
assert_equals(getComputedStyle(main.querySelector('.anchored-b')).top, '10px');
}, 'anchor-scope:--b scopes only --b');
</script>
diff --git a/tests/wpt/tests/css/css-anchor-position/chrome-420329041-crash.html b/tests/wpt/tests/css/css-anchor-position/chrome-420329041-crash.html
new file mode 100644
index 00000000000..2b236a371e5
--- /dev/null
+++ b/tests/wpt/tests/css/css-anchor-position/chrome-420329041-crash.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<link rel="help" href="https://crbug.com/420329041">
+<style>
+ #crash {
+ position: absolute;
+ left: anchor(right);
+ --svg: url("data:image/svg+xml,");
+ content: var(--svg);
+ fill: var(--svg);
+ }
+</style>
+<p>Pass if no crash</p>
+<div id="crash"></div>
diff --git a/tests/wpt/tests/css/css-borders/tentative/corner-shape/corner-shape-img-ref.html b/tests/wpt/tests/css/css-borders/tentative/corner-shape/corner-shape-img-ref.html
new file mode 100644
index 00000000000..565698f79ec
--- /dev/null
+++ b/tests/wpt/tests/css/css-borders/tentative/corner-shape/corner-shape-img-ref.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<style>
+ .target {
+ width: 100px;
+ height: 100px;
+ border-radius: 25px;
+ box-sizing: border-box;
+ background-image: url("/images/green.png");
+ corner-shape: notch superellipse(3) bevel scoop;
+ }
+</style>
+<div class=target></div>
diff --git a/tests/wpt/tests/css/css-borders/tentative/corner-shape/corner-shape-img.html b/tests/wpt/tests/css/css-borders/tentative/corner-shape/corner-shape-img.html
new file mode 100644
index 00000000000..82662d25562
--- /dev/null
+++ b/tests/wpt/tests/css/css-borders/tentative/corner-shape/corner-shape-img.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<link rel="match" href="corner-shape-img-ref.html">
+<meta name="fuzzy" content="maxDifference=0-64;totalPixels=0-100">
+<style>
+ img {
+ width: 100px;
+ height: 100px;
+ border-radius: 25px;
+ box-sizing: border-box;
+ corner-shape: notch superellipse(3) bevel scoop;
+ }
+</style>
+<img src="/images/green.png"> \ No newline at end of file
diff --git a/tests/wpt/tests/css/css-borders/tentative/corner-shape/corner-shape-render-fuzzy.html b/tests/wpt/tests/css/css-borders/tentative/corner-shape/corner-shape-render-fuzzy.html
index 12cd2546bf4..2d4b56f831b 100644
--- a/tests/wpt/tests/css/css-borders/tentative/corner-shape/corner-shape-render-fuzzy.html
+++ b/tests/wpt/tests/css/css-borders/tentative/corner-shape/corner-shape-render-fuzzy.html
@@ -17,7 +17,7 @@
<meta name="variant" content="?corner-top-left-shape=superellipse(-4)&border-radius=40%">
<meta name="variant" content="?corner-top-left-shape=superellipse(2.5)&border-radius=20%&border-width=10px">
<meta name="variant" content="?corner-top-right-shape=scoop&border-radius=20%&border-width=10px">
-<meta name="variant" content="?corner-shape=superellipse(0.8)&border-radius=40px&border-width=10px&border-left-color=purple">
+<meta name="variant" content="?corner-shape=superellipse(0.8)&border-radius=40px&border-width=10px">
<meta name="variant" content="?corner-shape=superellipse(3)&border-radius=40px&box-shadow=10px 10px 0 10px black">
<meta name="variant" content="?border-radius=30%&corner-shape=superellipse(-1.5)&box-shadow=10px%2010px%200%2010px%20black">
<meta name="variant" content="?border-radius=40%&corner-shape=notch&box-shadow=10px%2010px%200%2010px%20yellow">
diff --git a/tests/wpt/tests/css/css-borders/tentative/corner-shape/corner-shape-render-precise.html b/tests/wpt/tests/css/css-borders/tentative/corner-shape/corner-shape-render-precise.html
index 5293589222a..4a0c575b3b7 100644
--- a/tests/wpt/tests/css/css-borders/tentative/corner-shape/corner-shape-render-precise.html
+++ b/tests/wpt/tests/css/css-borders/tentative/corner-shape/corner-shape-render-precise.html
@@ -19,13 +19,14 @@
<meta name="variant" content="?corner-top-left-shape=superellipse(-0.5)&border-radius=40px">
<meta name="variant" content="?corner-shape=squircle&border-top-left-radius=25%&border-width=10px">
<meta name="variant" content="?corner-bottom-left-shape=bevel&border-bottom-left-radius=30px">
-<meta name="variant" content="?corner-top-left-shape=bevel&border-width=10px&border-color=black">
-<meta name="variant" content="?corner-top-right-shape=bevel&border-width=10px&border-color=black">
+<meta name="variant" content="?corner-top-left-shape=bevel&border-width=10px">
+<meta name="variant" content="?corner-top-right-shape=bevel&border-width=10px">
<meta name="variant" content="?corner-bottom-left-shape=bevel&border-width=10px&border-radius=20px">
<meta name="variant" content="?corner-bottom-right-shape=bevel&border-width=10px&border-radius=20px">
<meta name="variant" content="?corner-bottom-right-shape=bevel&corner-bottom-left-shape=bevel">
<meta name="variant" content="?border-top-left-radius=50%&corner-shape=superellipse(0.7)&border-left-width=30px&border-top-width=30px">
<meta name="variant" content="?border-radius=50%&corner-shape=bevel&box-shadow=10px%2010px%200%2010px%20black">
+<meta name="variant" content="?corner-shape=notch&border-radius=30px&border-width=30px">
<style>
body {
margin: 0;
diff --git a/tests/wpt/tests/css/css-borders/tentative/corner-shape/resources/corner-shape.js b/tests/wpt/tests/css/css-borders/tentative/corner-shape/resources/corner-shape.js
index 4757a43ad05..c08a95c7d75 100644
--- a/tests/wpt/tests/css/css-borders/tentative/corner-shape/resources/corner-shape.js
+++ b/tests/wpt/tests/css/css-borders/tentative/corner-shape/resources/corner-shape.js
@@ -87,10 +87,6 @@ function add_corner(ctx, ax, ay, bx, by, curvature) {
* 'border-top-right-radius': [number, number],
* 'border-bottom-left-radius': [number, number],
* 'border-bottom-right-radius': [number, number],
- * 'border-top-color': string,
- * 'border-right-color': string,
- * 'border-left-color': string,
- * 'border-bottom-color': string,
* 'border-top-width': number,
* 'border-right-width': number,
* 'border-bottom-width': number,
@@ -109,42 +105,8 @@ function render_rect_with_corner_shapes(style, ctx, width, height) {
add_corner(ctx, ...params.outer_rect, params.shape);
}
- function draw_inner_corner_from_params(params) {
- add_corner(ctx, ...params.inner_rect, params.shape);
- }
-
function draw_inner_corner(corner) {
- draw_inner_corner_from_params(corner_params[corner]);
- }
-
- function draw_shadow() {
- if (!style.shadow || !style.shadow.length) {
- return;
- }
-
- for (const {spread, offset, color} of style.shadow) {
- const params = resolve_corner_params(style, width, height, spread);
- ctx.save();
- ctx.translate(...offset);
- ctx.beginPath();
- ctx.lineTo(params['top-right'].inner_rect[0], params['top-right'].inner_rect[1]);
- draw_inner_corner_from_params(params['top-right']);
- ctx.lineTo(params['top-right'].inner_rect[2], params['top-right'].inner_rect[3])
- ctx.lineTo(params['bottom-right'].inner_rect[0], params['bottom-right'].inner_rect[1])
- draw_inner_corner_from_params(params['bottom-right']);
- ctx.lineTo(params['bottom-right'].inner_rect[2], params['bottom-right'].inner_rect[3]);
- ctx.lineTo(params['bottom-left'].inner_rect[0], params['bottom-left'].inner_rect[1]);
- draw_inner_corner_from_params(params['bottom-left']);
- ctx.lineTo(params['bottom-left'].inner_rect[2], params['bottom-left'].inner_rect[3])
- ctx.lineTo(params['top-left'].inner_rect[0], params['top-left'].inner_rect[1])
- draw_inner_corner_from_params(params['top-left']);
- ctx.lineTo(params['top-left'].inner_rect[2], params['top-left'].inner_rect[3]);
- ctx.lineTo(params['top-right'].inner_rect[0], params['top-right'].inner_rect[1]);
- ctx.fillStyle = color;
- ctx.closePath();
- ctx.fill("nonzero");
- ctx.restore();
- }
+ add_corner(ctx, ...corner_params[corner].inner_rect, corner_params[corner].shape);
}
function draw_outer_path() {
@@ -157,6 +119,15 @@ function render_rect_with_corner_shapes(style, ctx, width, height) {
ctx.fill("nonzero");
}
+ for (const {spread, offset, color} of (style.shadow || [])) {
+ ctx.save();
+ ctx.translate(offset[0] - spread, offset[1] - spread);
+ ctx.scale((width + spread * 2) / width, (height + spread * 2) / height);
+ ctx.fillStyle = color;
+ draw_outer_path();
+ ctx.restore();
+ }
+
const inner_rect = [
style["border-left-width"],
style["border-top-width"],
@@ -164,70 +135,8 @@ function render_rect_with_corner_shapes(style, ctx, width, height) {
height - style["border-bottom-width"],
];
- draw_shadow();
- {
- ctx.save();
- ctx.beginPath();
- ctx.moveTo(0, 0);
- ctx.lineTo(corner_params['top-left'].inner_rect[2], corner_params['top-left'].inner_rect[1])
- ctx.lineTo(corner_params['top-left'].inner_rect[2], inner_rect[1]);
- ctx.lineTo(corner_params['top-right'].inner_rect[0], inner_rect[1]);
- ctx.lineTo(corner_params['top-right'].inner_rect[0], corner_params['top-right'].inner_rect[3]);
- ctx.lineTo(width, 0);
- ctx.closePath();
- ctx.clip();
- ctx.fillStyle = style['border-top-color'];
- draw_outer_path();
- ctx.restore();
- }
-
- {
- ctx.save();
- ctx.beginPath();
- ctx.moveTo(width, 0);
- ctx.lineTo(corner_params['top-right'].inner_rect[0], corner_params['top-right'].inner_rect[3]);
- ctx.lineTo(inner_rect[2], corner_params['top-right'].inner_rect[3]);
- ctx.lineTo(inner_rect[2], corner_params['bottom-right'].inner_rect[1]);
- ctx.lineTo(corner_params['bottom-right'].inner_rect[2], corner_params['bottom-right'].inner_rect[1]);
- ctx.lineTo(width, height);
- ctx.closePath();
- ctx.clip();
- ctx.fillStyle = style['border-right-color'];
- draw_outer_path();
- ctx.restore();
- }
-
- {
- ctx.save();
- ctx.beginPath();
- ctx.lineTo(width, height);
- ctx.lineTo(corner_params['bottom-right'].inner_rect[2], corner_params['bottom-right'].inner_rect[1]);
- ctx.lineTo(corner_params['bottom-right'].inner_rect[2], inner_rect[3]);
- ctx.lineTo(corner_params['bottom-left'].inner_rect[0], inner_rect[3]);
- ctx.lineTo(corner_params['bottom-left'].inner_rect[0], corner_params['bottom-left'].inner_rect[3]);
- ctx.lineTo(0, height);
- ctx.closePath();
- ctx.clip();
- ctx.fillStyle = style['border-bottom-color'];
- draw_outer_path();
- ctx.restore();
- }
-
- {
- ctx.save();
- ctx.beginPath();
- ctx.lineTo(0, height);
- ctx.lineTo(corner_params['bottom-left'].inner_rect[0], corner_params['bottom-left'].inner_rect[3]);
- ctx.lineTo(inner_rect[0], corner_params['bottom-left'].inner_rect[3]);
- ctx.lineTo(inner_rect[0], corner_params['top-left'].inner_rect[1]);
- ctx.lineTo(corner_params['top-left'].inner_rect[2], corner_params['top-left'].inner_rect[1])
- ctx.lineTo(0, 0);
- ctx.closePath();
- ctx.clip();
- ctx.fillStyle = style['border-left-color'];
- draw_outer_path();
- ctx.restore();
- }
+ ctx.fillStyle = "black";
+ draw_outer_path();
ctx.save();
ctx.beginPath();
diff --git a/tests/wpt/tests/css/css-borders/tentative/corner-shape/resources/corner-utils.js b/tests/wpt/tests/css/css-borders/tentative/corner-shape/resources/corner-utils.js
index ad3b235addf..b6f329e8248 100644
--- a/tests/wpt/tests/css/css-borders/tentative/corner-shape/resources/corner-utils.js
+++ b/tests/wpt/tests/css/css-borders/tentative/corner-shape/resources/corner-utils.js
@@ -112,29 +112,11 @@ function resolve_corner_params(style, width, height, outset = null) {
outer_rect[3] + inner_offset[3] * offset[0],
];
- let inner_shape = shape;
- if (outset) {
- const new_width = width + outset * 2;
- const new_height = height + outset * 2;
- inner_rect = [
- (outer_rect[0] / width) * new_width - outset,
- (outer_rect[1] / height) * new_height - outset,
- (outer_rect[2] / width) * new_width - outset,
- (outer_rect[3] / height) * new_height - outset
- ]
- } else if (shape > 2 || shape < 0.5) {
- const outer_length = Math.hypot(
- outer_rect[2] - outer_rect[0], outer_rect[3] - outer_rect[1]);
- const inner_length = Math.hypot(
- inner_rect[2] - inner_rect[0], inner_rect[3] - inner_rect[1])
- }
-
return [
corner,
{
outer_rect,
shape,
- inner_shape,
inset,
inner_rect,
inner_offset,
diff --git a/tests/wpt/tests/css/css-color-hdr/parsing.html b/tests/wpt/tests/css/css-color-hdr/parsing.html
index 2447891f2c4..688043039de 100644
--- a/tests/wpt/tests/css/css-color-hdr/parsing.html
+++ b/tests/wpt/tests/css/css-color-hdr/parsing.html
@@ -15,7 +15,6 @@
test_valid_value("dynamic-range-limit", "dynamic-range-limit-mix(no-limit 8%, standard 2%)");
test_valid_value("dynamic-range-limit", "dynamic-range-limit-mix(no-limit 99%, standard 99%)");
test_valid_value("dynamic-range-limit", "dynamic-range-limit-mix(no-limit 99%, standard 99%, constrained 10%)");
- test_valid_value("dynamic-range-limit", "dynamic-range-limit-mix(no-limit 1%)");
test_valid_value("dynamic-range-limit", "dynamic-range-limit-mix(constrained 20%, no-limit 80%)");
test_valid_value("dynamic-range-limit", "dynamic-range-limit-mix(dynamic-range-limit-mix(constrained 90%, no-limit 10%) 1%, no-limit 80%)");
test_valid_value("dynamic-range-limit", "dynamic-range-limit-mix(no-limit 1%, dynamic-range-limit-mix(constrained 2%, no-limit 10%) 80%)");
@@ -31,6 +30,7 @@
test_invalid_value("dynamic-range-limit", "hdr");
test_invalid_value("dynamic-range-limit", "sdr");
test_invalid_value("dynamic-range-limit", "low");
+ test_invalid_value("dynamic-range-limit", "dynamic-range-limit-mix(no-limit 1%)");
test_invalid_value("dynamic-range-limit", "dynamic-range-limit-mix(no-limit 80% standard 20%)");
test_invalid_value("dynamic-range-limit", "dynamic-range-limit-mix(low, no-limit, 10%)");
test_invalid_value("dynamic-range-limit", "dynamic-range-limit-mix(no-limit 101%, standard 1%)");
diff --git a/tests/wpt/tests/css/css-conditional/container-queries/style-query-registered-custom-rem-change.html b/tests/wpt/tests/css/css-conditional/container-queries/style-query-registered-custom-rem-change.html
new file mode 100644
index 00000000000..33808fbe198
--- /dev/null
+++ b/tests/wpt/tests/css/css-conditional/container-queries/style-query-registered-custom-rem-change.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<title>CSS Container Queries Test: style() query with rem unit for registered custom property</title>
+<link rel="help" href="https://drafts.csswg.org/css-conditional-5/#style-container">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="support/cq-testcommon.js"></script>
+<style>
+ @property --length {
+ syntax: "<length>";
+ initial-value: 0px;
+ inherits: false;
+ }
+
+ :root, body { font-size: 16px; }
+ #container { --length: 100px; }
+
+ #target { color: red; }
+ @container style(--length: calc(1rem * 10)) {
+ #target { color: green; }
+ }
+</style>
+<div id="container">
+ <div id="target">Should be green</div>
+</div>
+<script>
+ test(() => {
+ assert_equals(getComputedStyle(target).color, "rgb(255, 0, 0)");
+ }, "Initially, 1rem * 10 evaluates to 160px");
+
+ test(() => {
+ document.documentElement.style.fontSize = "10px";
+ assert_equals(getComputedStyle(target).color, "rgb(0, 128, 0)");
+ }, "Changing the :root font-size to 10px makes 1rem * 10 evaluate to 100px");
+</script>
diff --git a/tests/wpt/tests/css/css-flexbox/flexbox_columns-ref.html b/tests/wpt/tests/css/css-flexbox/flexbox_columns-ref.html
deleted file mode 100644
index b8c7a225698..00000000000
--- a/tests/wpt/tests/css/css-flexbox/flexbox_columns-ref.html
+++ /dev/null
@@ -1,10 +0,0 @@
-<!DOCTYPE html>
-<title>flexbox | multicol</title>
-<link rel="author" href="http://opera.com" title="Opera Software">
-<style>
-div {
- background: black;
-}
-</style>
-
-<div>x</div>
diff --git a/tests/wpt/tests/css/css-flexbox/flexbox_columns.html b/tests/wpt/tests/css/css-flexbox/flexbox_columns.html
deleted file mode 100644
index d39c2db55f2..00000000000
--- a/tests/wpt/tests/css/css-flexbox/flexbox_columns.html
+++ /dev/null
@@ -1,27 +0,0 @@
-<!DOCTYPE html>
-<title>flexbox | multicol</title>
-<link rel="author" href="http://opera.com" title="Opera Software">
-<link rel="help"
- href="http://www.w3.org/TR/css-flexbox-1/#flex-containers">
-<link rel="match" href="flexbox_columns-ref.html">
-<style>
-ul {
- background: black;
- padding: 0;
- margin: 0;
-
- display: flex;
- justify-content: space-around;
- columns: 3;
- column-rule: 1em solid red;
-}
-::marker { font-family:inherit; }
-</style>
-
-<ul>
- <li>one two three four</li>
- <li>filler</li>
- <li>filler</li>
- <li>filler</li>
- <li>filler</li>
-</ul>
diff --git a/tests/wpt/tests/css/css-forms/datetime-stacking-context-ref.html b/tests/wpt/tests/css/css-forms/datetime-stacking-context-ref.html
new file mode 100644
index 00000000000..95bee383d21
--- /dev/null
+++ b/tests/wpt/tests/css/css-forms/datetime-stacking-context-ref.html
@@ -0,0 +1,12 @@
+<!doctype html>
+<style>
+ #cover {
+ background: white;
+ position: fixed;
+ width: 100%;
+ height: 200px;
+ top: 0;
+ border: 1px solid black;
+ }
+</style>
+<div id="cover"></div>
diff --git a/tests/wpt/tests/css/css-forms/datetime-stacking-context.html b/tests/wpt/tests/css/css-forms/datetime-stacking-context.html
new file mode 100644
index 00000000000..4754cacf09d
--- /dev/null
+++ b/tests/wpt/tests/css/css-forms/datetime-stacking-context.html
@@ -0,0 +1,16 @@
+<!doctype html>
+<title>Datetime input doesn't have stacking contexts inside</title>
+<link rel="help" href="https://drafts.csswg.org/css-forms/"> <!-- a bit of a stretch but... -->
+<link rel="match" href="datetime-stacking-context-ref.html">
+<style>
+ #cover {
+ background: white;
+ position: fixed;
+ width: 100%;
+ height: 200px;
+ top: 0;
+ border: 1px solid black;
+ }
+</style>
+<div id="cover"></div>
+<input type=datetime>
diff --git a/tests/wpt/tests/css/css-gaps/grid/grid-gap-decorations-040-ref.html b/tests/wpt/tests/css/css-gaps/grid/grid-gap-decorations-040-ref.html
new file mode 100644
index 00000000000..2988cf534a9
--- /dev/null
+++ b/tests/wpt/tests/css/css-gaps/grid/grid-gap-decorations-040-ref.html
@@ -0,0 +1,88 @@
+<!DOCTYPE html>
+<link rel="help" href="https://drafts.csswg.org/css-gaps-1/#break">
+<link rel="author" title="Sam Davis Omekara Jr." href="mailto:samomekarajr@microsoft.com">
+<style>
+ body {
+ margin: 0px;
+ }
+
+ .grid-container {
+ display: grid;
+ grid-template-columns: repeat(4, 100px);
+ grid-template-rows: repeat(4, 100px);
+ gap: 10px;
+ width: 430px;
+ height: 430px;
+ }
+
+ .grid-item {
+ background-color: gray;
+ opacity: 0.5;
+ border: 1px solid #000;
+ }
+
+ .col-gap {
+ width: 0;
+ border-left: solid 5px blue;
+ }
+
+ .col-gap1 {
+ position: absolute;
+ top: 212.5px;
+ left: 102.5px;
+ height: 217.5px;
+ }
+
+ .col-gap2 {
+ position: absolute;
+ top: 0px;
+ left: 212.5px;
+ height: 430px;
+ }
+
+ .col-gap3 {
+ position: absolute;
+ top: 0px;
+ left: 322.5px;
+ height: 430px;
+ }
+
+ .row-gap {
+ height: 0px;
+ border-bottom: solid 5px red;
+ }
+
+ .row-gap1 {
+ position: absolute;
+ top: 102.5px;
+ left: 325px;
+ width: 105px;
+ }
+
+ .row-gap2 {
+ position: absolute;
+ top: 212.5px;
+ left: 0px;
+ width: 430px;
+ }
+
+ .row-gap3 {
+ position: absolute;
+ top: 322.5px;
+ left: 0px;
+ width: 430px;
+ }
+</style>
+
+<div class="grid-container">
+ <div class="grid-item" style="grid-column: 1 / 3; grid-row: 1 / 3;"></div>
+ <div class="grid-item" style="grid-column: 3 / 4; grid-row: 1 / 3;"></div>
+</div>
+
+<div class="col-gap col-gap1"> </div>
+<div class="col-gap col-gap2"> </div>
+<div class="col-gap col-gap3"> </div>
+
+<div class="row-gap row-gap1"> </div>
+<div class="row-gap row-gap2"> </div>
+<div class="row-gap row-gap3"> </div>
diff --git a/tests/wpt/tests/css/css-gaps/grid/grid-gap-decorations-040.html b/tests/wpt/tests/css/css-gaps/grid/grid-gap-decorations-040.html
new file mode 100644
index 00000000000..4bab26db550
--- /dev/null
+++ b/tests/wpt/tests/css/css-gaps/grid/grid-gap-decorations-040.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<title>
+ CSS Gap Decorations: *rule-break properly adheres to spanning-item when repeater tracks are used.
+</title>
+<link rel="help" href="https://drafts.csswg.org/css-gaps-1/#break">
+<link rel="match" href="grid-gap-decorations-040-ref.html">
+<link rel="author" title="Sam Davis Omekara Jr." href="mailto:samomekarajr@microsoft.com">
+<style>
+ body {
+ margin: 0px;
+ }
+ .grid-container {
+ display: grid;
+ grid-template-columns: repeat(4, 100px);
+ grid-template-rows: repeat(4, 100px);
+ gap: 10px;
+
+ width: 430px;
+ height: 430px;
+
+ column-rule: 5px solid blue;
+ row-rule: 5px solid red;
+ }
+
+ .grid-item {
+ background-color: gray;
+ opacity: 0.5;
+ border: 1px solid #000;
+ }
+
+</style>
+<div class="grid-container">
+ <div class="grid-item" style="grid-column: 1 / 3; grid-row: 1 / 3;"></div>
+ <div class="grid-item" style="grid-column: 3 / 4; grid-row: 1 / 3;"></div>
+</div>
diff --git a/tests/wpt/tests/css/css-gaps/grid/grid-gap-decorations-041-crash.html b/tests/wpt/tests/css/css-gaps/grid/grid-gap-decorations-041-crash.html
new file mode 100644
index 00000000000..be3e2280b5f
--- /dev/null
+++ b/tests/wpt/tests/css/css-gaps/grid/grid-gap-decorations-041-crash.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<title>
+ CSS Gap Decorations: Renderer doesn't crash when gap decorations is used on grid with no rows/columns.
+</title>
+<link rel="help" href="https://drafts.csswg.org/css-gaps-1/">
+<link rel="author" title="Sam Davis Omekara Jr." href="mailto:samomekarajr@microsoft.com">
+<style>
+ .grid-container {
+ display: grid;
+
+ column-rule: solid blue;
+ row-rule: dotted red;
+ }
+</style>
+
+<div class="grid-container"></div>
diff --git a/tests/wpt/tests/css/css-gaps/grid/grid-gap-decorations-042-ref.html b/tests/wpt/tests/css/css-gaps/grid/grid-gap-decorations-042-ref.html
new file mode 100644
index 00000000000..ed44f7a2de3
--- /dev/null
+++ b/tests/wpt/tests/css/css-gaps/grid/grid-gap-decorations-042-ref.html
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<link rel="help" href="https://drafts.csswg.org/css-gaps-1/">
+<link rel="author" title="Sam Davis Omekara Jr." href="mailto:samomekarajr@microsoft.com">
+<style>
+ .grid-container {
+ display: grid;
+ grid-template-columns: repeat(4, 1fr);
+ width: 430px;
+ height: 430px;
+ }
+
+ .grid-item {
+ background-color: gray;
+ opacity: 0.5;
+ border: 1px solid #000;
+ }
+</style>
+
+<div class="grid-container">
+ <div class="grid-item" style="grid-column: 1 / 3; grid-row: 1 / 2;"></div>
+ <div class="grid-item" style="grid-column: 3 / 4; grid-row: 1 / 3;"></div>
+ <div class="grid-item" style="grid-row: 2 / 4;"></div>
+ <div class="grid-item" style="grid-column: 2 / 4; grid-row: 3 / 4;"></div>
+ <div class="grid-item" style="grid-column: 2 / 3; grid-row: 2 / 3;"></div>
+ <div class="grid-item" style="grid-column: 4 / 5; grid-row: 1 / 4;"></div>
+ <div class="grid-item" style="grid-column: 1 / 4; grid-row: 4 / 5;"></div>
+ <div class="grid-item" style="grid-column: 4 / 5; grid-row: 4 / 5;"></div>
+</div>
diff --git a/tests/wpt/tests/css/css-gaps/grid/grid-gap-decorations-042.html b/tests/wpt/tests/css/css-gaps/grid/grid-gap-decorations-042.html
new file mode 100644
index 00000000000..5b2b4936980
--- /dev/null
+++ b/tests/wpt/tests/css/css-gaps/grid/grid-gap-decorations-042.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<title>
+ CSS Gap Decorations: gap decorations are not painted when there are no gaps.
+</title>
+<link rel="help" href="https://drafts.csswg.org/css-gaps-1/">
+<link rel="match" href="grid-gap-decorations-042-ref.html">
+<link rel="author" title="Sam Davis Omekara Jr." href="mailto:samomekarajr@microsoft.com">
+<style>
+ .grid-container {
+ display: grid;
+ grid-template-columns: repeat(4, 1fr);
+
+ width: 430px;
+ height: 430px;
+
+ column-rule: 5px solid blue;
+ row-rule: 5px dotted red;
+ }
+
+ .grid-item {
+ background-color: gray;
+ opacity: 0.5;
+ border: 1px solid #000;
+ }
+
+</style>
+<div class="grid-container">
+ <div class="grid-item" style="grid-column: 1 / 3; grid-row: 1 / 2;"></div>
+ <div class="grid-item" style="grid-column: 3 / 4; grid-row: 1 / 3;"></div>
+ <div class="grid-item" style="grid-row: 2 / 4;"></div>
+ <div class="grid-item" style="grid-column: 2 / 4; grid-row: 3 / 4;"></div>
+ <div class="grid-item" style="grid-column: 2 / 3; grid-row: 2 / 3;"></div>
+ <div class="grid-item" style="grid-column: 4 / 5; grid-row: 1 / 4;"></div>
+ <div class="grid-item" style="grid-column: 1 / 4; grid-row: 4 / 5;"></div>
+ <div class="grid-item" style="grid-column: 4 / 5; grid-row: 4 / 5;"></div>
+</div>
diff --git a/tests/wpt/tests/css/css-grid/grid-items/grid-item-inline-contribution-004.html b/tests/wpt/tests/css/css-grid/grid-items/grid-item-inline-contribution-004.html
new file mode 100644
index 00000000000..a4e3cd6f3a4
--- /dev/null
+++ b/tests/wpt/tests/css/css-grid/grid-items/grid-item-inline-contribution-004.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<link rel="author" title="Ting-Yu Lin" href="mailto:tlin@mozilla.com">
+<link rel="author" title="Mozilla" href="https://www.mozilla.org/">
+<link rel="help" href="https://drafts.csswg.org/css-grid-2/#algo-grid-sizing">
+<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/6356#issuecomment-862800005">
+<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1957501">
+<link rel="match" href="../../reference/ref-filled-green-100px-square.xht">
+<meta name="assert" content="Tests the min-content contribution is re-resolved during a 2nd pass.">
+
+<!--
+
+Quoting step 3 of css-grid-2 section 12.1. Grid Sizing Algorithm:
+
+"
+ Then, if the min-content contribution of any grid item has changed based on
+ the row sizes and alignment calculated in step 2, re-resolve the sizes of the
+ grid columns with the new min-content and max-content contributions (once
+ only).
+"
+
+In this testcase initially the row size is indefinite, then resolves to 100px.
+Using this information we re-resolve the columns, resulting in 50px for the
+first column.
+
+-->
+<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
+<div style="display: grid; width: 0; grid-template: auto / auto auto;">
+ <div style="background: green; height: 100%;">
+ <canvas width="5" height="10" style="height: 100%;">
+ </div>
+ <div style="background: green">
+ <div style="width: 50px; height: 100px;"></div>
+ </div>
+</div>
diff --git a/tests/wpt/tests/css/css-highlight-api/HighlightRegistry-highlightsFromPoint-ranges.html b/tests/wpt/tests/css/css-highlight-api/HighlightRegistry-highlightsFromPoint-ranges.html
new file mode 100644
index 00000000000..24cf8aa6dfe
--- /dev/null
+++ b/tests/wpt/tests/css/css-highlight-api/HighlightRegistry-highlightsFromPoint-ranges.html
@@ -0,0 +1,109 @@
+<!doctype html>
+<meta name="author" title="Fernando Fiori" href="mailto:ffiori@microsoft.com">
+<meta name="assert" content="HighlightRegistry.highlightsFromPoint returns the Highlights and their corresponding Ranges and StaticRanges present at the coordinates provided as argument in the right order in multi-line text.">
+<link rel="help" href="https://github.com/MicrosoftEdge/MSEdgeExplainers/blob/main/highlight/HighlightsFromPointsExplainer.md">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<style>
+::highlight(example-highlight) {
+ background-color: rgba(0, 255, 255, 0.5);
+}
+body {
+ font-family: monospace;
+}
+</style>
+<span id="example-span-1">0123456789</span><br>
+<span id="example-span-2">0123456789</span>
+<script>
+ const textNode1 = document.querySelector("#example-span-1");
+ const textNode2 = document.querySelector("#example-span-2");
+
+ function test_ranges(ranges) {
+ assert_equals(ranges.length, 2, 'test_ranges() should be called with exactly two ranges.');
+ let big_range = ranges[0].startOffset < ranges[1].startOffset ? ranges[0] : ranges[1];
+
+ let highlight = new Highlight(...ranges);
+ CSS.highlights.set("example-highlight", highlight);
+
+ const rect = textNode1.getBoundingClientRect();
+ const characterWidth = rect.width / textNode1.textContent.length;
+ const characterHeight = rect.height;
+
+ // No Highlights outside of text contents.
+ let x = rect.left - 1;
+ let y = rect.top - 1;
+ let highlight_hit_results = CSS.highlights.highlightsFromPoint(x, y);
+ assert_equals(highlight_hit_results.length, 0, 'CSS.highlights.highlightsFromPoint() returns an empty array when the coordinates provided are outside of the text contents');
+
+ // Get x and y coordinates between characters '0' and '1' on the first line (not highlighted).
+ x = rect.left + characterWidth;
+ y = rect.top + characterHeight / 2;
+ highlights = CSS.highlights.highlightsFromPoint(x, y);
+ assert_equals(highlight_hit_results.length, 0, 'CSS.highlights.highlightsFromPoint() returns an empty array when the coordinates provided are outside of the highlighted ranges');
+
+ // Get x and y coordinates between characters '2' and '3' on the first line.
+ x = rect.left + 3 * characterWidth;
+ highlight_hit_results = CSS.highlights.highlightsFromPoint(x, y);
+ assert_equals(highlight_hit_results.length, 1, 'CSS.highlights.highlightsFromPoint() returns exactly one HighlightHitResult when the coordinates provided point at one Highlight');
+ assert_equals(highlight_hit_results[0].highlight, highlight, 'CSS.highlights.highlightsFromPoint() returns a HighlightHitResult with the Highlight present at the coordinates provided');
+ assert_array_equals(highlight_hit_results[0].ranges, [big_range], 'CSS.highlights.highlightsFromPoint() returns a HighlightHitResult with the ranges of the Highlight present at the coordinates provided');
+
+ // Get x and y coordinates between characters '6' and '7' on the first line.
+ x = rect.left + 7 * characterWidth;
+ highlight_hit_results = CSS.highlights.highlightsFromPoint(x, y);
+ assert_equals(highlight_hit_results.length, 1, 'CSS.highlights.highlightsFromPoint() returns exactly one HighlightHitResult when the coordinates provided point at one Highlight');
+ assert_equals(highlight_hit_results[0].highlight, highlight, 'CSS.highlights.highlightsFromPoint() returns a HighlightHitResult with the Highlight present at the coordinates provided');
+ assert_array_equals(highlight_hit_results[0].ranges, ranges, 'CSS.highlights.highlightsFromPoint() returns a HighlightHitResult with the ranges of the Highlight present at the coordinates provided in the right order');
+
+ // Get x and y coordinates to the right of the last character of the first line.
+ x = rect.left + 12 * characterWidth;
+ highlight_hit_results = CSS.highlights.highlightsFromPoint(x, y);
+ assert_equals(highlight_hit_results.length, 0, 'CSS.highlights.highlightsFromPoint() returns an empty array when the coordinates provided are to the right of the text contents');
+
+ // Get x and y coordinates between characters '0' and '1' on the second line.
+ x = rect.left + characterWidth;
+ y = rect.top + 1.5 * characterHeight;
+ highlight_hit_results = CSS.highlights.highlightsFromPoint(x, y);
+ assert_equals(highlight_hit_results.length, 1, 'CSS.highlights.highlightsFromPoint() returns exactly one HighlightHitResult when the coordinates provided point at one Highlight');
+ assert_equals(highlight_hit_results[0].highlight, highlight, 'CSS.highlights.highlightsFromPoint() returns a HighlightHitResult with the Highlight present at the coordinates provided');
+ assert_array_equals(highlight_hit_results[0].ranges, [big_range], 'CSS.highlights.highlightsFromPoint() returns a HighlightHitResult with the ranges of the Highlight present at the coordinates provided');
+
+ // Get x and y coordinates between characters '8' and '9' on the second line (not highlighted).
+ x = rect.left + 9 * characterWidth;
+ highlight_hit_results = CSS.highlights.highlightsFromPoint(x, y);
+ assert_equals(highlight_hit_results.length, 0, 'CSS.highlights.highlightsFromPoint() returns an empty array when the coordinates provided are outside of the highlighted ranges');
+
+ // Get x and y coordinates to the right of the last character of the second line.
+ x = rect.left + 12 * characterWidth;
+ highlight_hit_results = CSS.highlights.highlightsFromPoint(x, y);
+ assert_equals(highlight_hit_results.length, 0, 'CSS.highlights.highlightsFromPoint() returns an empty array when the coordinates provided are to the right of the text contents');
+
+ // Get x and y coordinates below the second line.
+ x = rect.left + 5 * characterWidth;
+ y = rect.top + 3 * characterHeight;
+ highlight_hit_results = CSS.highlights.highlightsFromPoint(x, y);
+ assert_equals(highlight_hit_results.length, 0, 'CSS.highlights.highlightsFromPoint() returns an empty array when the coordinates provided are below the text contents');
+ }
+
+ test(() => {
+ // Set a Highlight with two nested ranges in this way:
+ // 01[234(56789)
+ // 01234567]89
+ let range1 = new Range();
+ range1.setStart(textNode1.childNodes[0], 5);
+ range1.setEnd(textNode1.childNodes[0], 10);
+ let range2 = new Range();
+ range2.setStart(textNode1.childNodes[0], 2);
+ range2.setEnd(textNode2.childNodes[0], 8);
+
+ let static_range1 = new StaticRange({startContainer: textNode1.childNodes[0], startOffset: 5, endContainer: textNode1.childNodes[0], endOffset: 10})
+ let static_range2 = new StaticRange({startContainer: textNode1.childNodes[0], startOffset: 2, endContainer: textNode2.childNodes[0], endOffset: 8})
+
+ test_ranges([range1, range2]);
+ test_ranges([range2, range1]);
+ test_ranges([static_range1, static_range2]);
+ test_ranges([static_range2, static_range1]);
+ test_ranges([static_range1, range2]);
+ test_ranges([range1, static_range2]);
+ }, 'CSS.highlights.highlightsFromPoint() returns HighlightHitResults with the Highlights and their corresponding Ranges and StaticRanges present at the given point in the right order on multi-line text.');
+</script> \ No newline at end of file
diff --git a/tests/wpt/tests/css/css-highlight-api/HighlightRegistry-highlightsFromPoint.html b/tests/wpt/tests/css/css-highlight-api/HighlightRegistry-highlightsFromPoint.html
index 5bb81bea69a..5b4e7704a4d 100644
--- a/tests/wpt/tests/css/css-highlight-api/HighlightRegistry-highlightsFromPoint.html
+++ b/tests/wpt/tests/css/css-highlight-api/HighlightRegistry-highlightsFromPoint.html
@@ -26,7 +26,7 @@ body {
test(() => {
assert_equals(CSS.highlights.highlightsFromPoint(-1,-1).length, 0);
- }, 'CSS.highlights.highlightsFromPoint() should return an empty vector when called with a point outside the document.');
+ }, 'CSS.highlights.highlightsFromPoint() should return an empty array when called with a point outside the document.');
test(() => {
// Set two Highlights in this way: 01[234[56789]]
@@ -49,35 +49,38 @@ body {
// No Highlights outside of text contents.
let x = rect.left - 1;
let y = rect.top - 1;
- let highlights = CSS.highlights.highlightsFromPoint(x, y);
- assert_equals(highlights.length, 0, 'CSS.highlights.highlightsFromPoint() returns no Highlights when the coordinates provided are outside of the text contents');
+ let highlight_hit_results = CSS.highlights.highlightsFromPoint(x, y);
+ assert_equals(highlight_hit_results.length, 0, 'CSS.highlights.highlightsFromPoint() returns an empty array when the coordinates provided are outside of the text contents');
// Get x and y coordinates between '0' and '1'.
x = rect.left + characterWidth;
y = rect.top + rect.height / 2;
highlights = CSS.highlights.highlightsFromPoint(x, y);
- assert_equals(highlights.length, 0, 'CSS.highlights.highlightsFromPoint() returns no Highlights when the coordinates provided point at no Highlights');
+ assert_equals(highlight_hit_results.length, 0, 'CSS.highlights.highlightsFromPoint() returns an empty array when the coordinates provided point at no Highlights');
// Get x and y coordinates between '2' and '3'.
x = rect.left + 3 * characterWidth;
- highlights = CSS.highlights.highlightsFromPoint(x, y);
- assert_equals(highlights.length, 1, 'CSS.highlights.highlightsFromPoint() returns exactly one Highlight when the coordinates provided point at one Highlight');
- assert_equals(highlights[0], highlight1, 'CSS.highlights.highlightsFromPoint() returns the Highlight present at the coordinates provided');
+ highlight_hit_results = CSS.highlights.highlightsFromPoint(x, y);
+ assert_equals(highlight_hit_results.length, 1, 'CSS.highlights.highlightsFromPoint() returns exactly one HighlightHitResult when the coordinates provided point at one Highlight');
+ assert_equals(highlight_hit_results[0].highlight, highlight1, 'CSS.highlights.highlightsFromPoint() returns a HighlightHitResult with the Highlight present at the coordinates provided');
+ assert_array_equals(highlight_hit_results[0].ranges, [range1], 'CSS.highlights.highlightsFromPoint() returns a HighlightHitResult with the ranges of the Highlight present at the coordinates provided');
// Get x and y coordinates between '6' and '7'.
// Same priority for the Highlights, break tie by order of registration.
x = rect.left + 7 * characterWidth;
- highlights = CSS.highlights.highlightsFromPoint(x, y);
- assert_equals(highlights.length, 2, 'CSS.highlights.highlightsFromPoint() returns exactly two Highlights when the coordinates provided point at two overlapping Highlights');
- assert_equals(highlights[0], highlight2, 'CSS.highlights.highlightsFromPoint() returns first the Highlight registered last when both Highlights present at the point provided have the same priority');
- assert_equals(highlights[1], highlight1, 'CSS.highlights.highlightsFromPoint() returns last the Highlight registered first when both Highlights present at the point provided have the same priority');
+ highlight_hit_results = CSS.highlights.highlightsFromPoint(x, y);
+ assert_equals(highlight_hit_results.length, 2, 'CSS.highlights.highlightsFromPoint() returns exactly two HighlightHitResults when the coordinates provided point at two overlapping Highlights');
+ assert_equals(highlight_hit_results[0].highlight, highlight2, 'CSS.highlights.highlightsFromPoint() returns first a HighlightHitResult with the Highlight registered last when both Highlights present at the point provided have the same priority');
+ assert_equals(highlight_hit_results[1].highlight, highlight1, 'CSS.highlights.highlightsFromPoint() returns last a HighlightHitResult with the Highlight registered first when both Highlights present at the point provided have the same priority');
+ assert_array_equals(highlight_hit_results[0].ranges, [range2], 'CSS.highlights.highlightsFromPoint() returns first a HighlightHitResult with the ranges of the Highlight present on top at the coordinates provided');
+ assert_array_equals(highlight_hit_results[1].ranges, [range1], 'CSS.highlights.highlightsFromPoint() returns last a HighlightHitResult with the ranges of the Highlight present at the bottom at the coordinates provided');
// Now highlight1 should be first because it's got higher priority.
highlight1.priority = 2;
highlight2.priority = 1;
- highlights = CSS.highlights.highlightsFromPoint(x, y);
- assert_equals(highlights.length, 2, 'CSS.highlights.highlightsFromPoint() returns exactly two Highlights when the coordinates provided point at two overlapping Highlights');
- assert_equals(highlights[0], highlight1, 'CSS.highlights.highlightsFromPoint() returns first the Highlight with higher priority when there are two Highlights present at the point provided');
- assert_equals(highlights[1], highlight2, 'CSS.highlights.highlightsFromPoint() returns last the Highlight with lower priority when there are two Highlights present at the point provided');
- }, 'CSS.highlights.highlightsFromPoint() returns Highlights present at the given point in the right order.');
+ highlight_hit_results = CSS.highlights.highlightsFromPoint(x, y);
+ assert_equals(highlight_hit_results.length, 2, 'CSS.highlights.highlightsFromPoint() returns exactly two HighlightHitResults when the coordinates provided point at two overlapping Highlights');
+ assert_equals(highlight_hit_results[0].highlight, highlight1, 'CSS.highlights.highlightsFromPoint() returns first a HighlightHitResult with the Highlight with higher priority when there are two Highlights present at the point provided');
+ assert_equals(highlight_hit_results[1].highlight, highlight2, 'CSS.highlights.highlightsFromPoint() returns last a HighlightHitResult with the Highlight with lower priority when there are two Highlights present at the point provided');
+ }, 'CSS.highlights.highlightsFromPoint() returns the Highlights with their corresponding ranges present at the given point in the right order.');
</script> \ No newline at end of file
diff --git a/tests/wpt/tests/css/css-masking/animations/clip-path-interpolation-shape-arc-direction-agnostic-radius-ref.html b/tests/wpt/tests/css/css-masking/animations/clip-path-interpolation-shape-arc-direction-agnostic-radius-ref.html
new file mode 100644
index 00000000000..2869d38a982
--- /dev/null
+++ b/tests/wpt/tests/css/css-masking/animations/clip-path-interpolation-shape-arc-direction-agnostic-radius-ref.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>CSS Masking: Test clip-path property and shape function with single-value arc radius</title>
+</head>
+<style>
+@keyframes animate-shape {
+ from {
+ clip-path: shape(from 40px 100px, arc to 200px 100px of 50% 50% small cw, arc to 0 100px of 30% 30% small cw);
+ }
+ to {
+ clip-path: shape(from 40px 100px, arc to 200px 100px of 30% 30% small cw, arc to 0 100px of calc(10px + 45%) calc(10px + 45%) small cw);
+ }
+}
+#shape {
+ width: calc(500px / sqrt(2));
+ height: calc(500px / sqrt(2));
+ background: green;
+ animation: animate-shape 100s;
+ animation-play-state: paused;
+ animation-timing-function: steps(2, start);
+}
+</style>
+
+<div id="shape"></div>
+</html>
diff --git a/tests/wpt/tests/css/css-masking/animations/clip-path-interpolation-shape-arc-direction-agnostic-radius.html b/tests/wpt/tests/css/css-masking/animations/clip-path-interpolation-shape-arc-direction-agnostic-radius.html
new file mode 100644
index 00000000000..aa91e1828a7
--- /dev/null
+++ b/tests/wpt/tests/css/css-masking/animations/clip-path-interpolation-shape-arc-direction-agnostic-radius.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>CSS Masking: Test animating single-value arc radius of the shape() function</title>
+ <link rel="help" href="https://drafts.csswg.org/css-shapes-2/#funcdef-shape">
+ <link rel="match" href="clip-path-interpolation-shape-arc-direction-agnostic-radius-ref.html">
+ <meta name="fuzzy" content="maxDifference=0-10;totalPixels=0-360">
+</head>
+<style>
+@keyframes animate-shape {
+ from {
+ clip-path: shape(from 40px 100px, arc to 200px 100px of 50% small cw, arc to 0 100px of 30% small cw);
+ }
+ to {
+ clip-path: shape(from 40px 100px, arc to 200px 100px of 30% small cw, arc to 0 100px of calc(10px + 45%) small cw);
+ }
+}
+#shape {
+ width: 400px;
+ height: 300px;
+ background: green;
+ animation: animate-shape 100s;
+ animation-play-state: paused;
+ animation-timing-function: steps(2, start);
+}
+</style>
+
+<div id="shape"></div>
+</html>
diff --git a/tests/wpt/tests/css/css-masking/animations/clip-path-interpolation-shape.html b/tests/wpt/tests/css/css-masking/animations/clip-path-interpolation-shape.html
index 6d85c2a06b4..f725e1fc6fa 100644
--- a/tests/wpt/tests/css/css-masking/animations/clip-path-interpolation-shape.html
+++ b/tests/wpt/tests/css/css-masking/animations/clip-path-interpolation-shape.html
@@ -145,15 +145,28 @@ test_interpolation({
test_interpolation({
property: 'clip-path',
- from: 'shape(from 5% 5px, arc to 15% -15px of 10px 20px, arc by 15% -5px of 30px cw rotate 30deg large, arc to 25% 20px of 10px 5px small)',
- to: 'shape(from 15% 15px, arc to 5% -25px of 20px 30px, arc by 25% -15px of 20px cw rotate 270deg small, arc to 25% 20px of 10px 5px small cw)'
+ from: 'shape(from 5% 5px, arc to 15% -15px of 10px 20px, arc by 15% -5px of 30px 30px cw rotate 30deg large, arc to 25% 20px of 10px 5px small)',
+ to: 'shape(from 15% 15px, arc to 5% -25px of 20px 30px, arc by 25% -15px of 20px 20px cw rotate 270deg small, arc to 25% 20px of 10px 5px small cw)'
}, [
{at: -0.3, expect: 'shape(from 2% 2px, arc to 18% -12px of 7px 17px, arc by 12% -2px of 33px 33px rotate -42deg cw large , arc to 25% 20px of 10px 5px)'},
- {at: 0, expect: 'shape(from 5% 5px, arc to 15% -15px of 10px 20px, arc by 15% -5px of 30px cw rotate 30deg large, arc to 25% 20px of 10px 5px)'},
+ {at: 0, expect: 'shape(from 5% 5px, arc to 15% -15px of 10px 20px, arc by 15% -5px of 30px 30px cw rotate 30deg large, arc to 25% 20px of 10px 5px)'},
{at: 0.3, expect: 'shape(from 8% 8px, arc to 12% -18px of 13px 23px, arc by 18% -8px of 27px 27px rotate 102deg cw large, arc to 25% 20px of 10px 5px cw)'},
- {at: 0.5, expect: 'shape(from 10% 10px, arc to 10% -20px of 15px 25px, arc by 20% -10px of 25px rotate 150deg cw large, arc to 25% 20px of 10px 5px cw)'},
- {at: 1, expect: 'shape(from 15% 15px, arc to 5% -25px of 20px 30px, arc by 25% -15px of 20px rotate 270deg cw, arc to 25% 20px of 10px 5px cw)'},
- {at: 1.5, expect: 'shape(from 20% 20px, arc to 0% -30px of 25px 35px, arc by 30% -20px of 15px rotate 390deg cw, arc to 25% 20px of 10px 5px cw)'},
+ {at: 0.5, expect: 'shape(from 10% 10px, arc to 10% -20px of 15px 25px, arc by 20% -10px of 25px 25px rotate 150deg cw large, arc to 25% 20px of 10px 5px cw)'},
+ {at: 1, expect: 'shape(from 15% 15px, arc to 5% -25px of 20px 30px, arc by 25% -15px of 20px 20px rotate 270deg cw, arc to 25% 20px of 10px 5px cw)'},
+ {at: 1.5, expect: 'shape(from 20% 20px, arc to 0% -30px of 25px 35px, arc by 30% -20px of 15px 15px rotate 390deg cw, arc to 25% 20px of 10px 5px cw)'},
+]);
+
+test_interpolation({
+ property: 'clip-path',
+ from: 'shape(from 5% 5px, arc to 15% -15px of 10px, arc by 15% -5px of 30% cw rotate 30deg large, arc to 25% 20px of 10% small)',
+ to: 'shape(from 15% 15px, arc to 5% -25px of 15%, arc by 25% -15px of 12rem cw rotate 270deg small, arc to 15% 20px of 20% small cw)'
+}, [
+ {at: -0.3, expect: 'shape(from 2% 2px, arc to 18% -12px of calc(-4.5% + 13px), arc by 12% -2px of calc(39% - 57.6px) cw large rotate -42deg, arc to 28% 20px of 7%)'},
+ {at: 0, expect: 'shape(from 5% 5px, arc to 15% -15px of calc(0% + 10px), arc by 15% -5px of 30% cw large rotate 30deg, arc to 25% 20px of 10%)'},
+ {at: 0.3, expect: 'shape(from 8% 8px, arc to 12% -18px of calc(4.5% + 7px), arc by 18% -8px of calc(21% + 57.6px) rotate 102deg cw large, arc to 22% 20px of 13% cw)'},
+ {at: 0.5, expect: 'shape(from 10% 10px, arc to 10% -20px of calc(7.5% + 5px), arc by 20% -10px of calc(15% + 96px) cw large rotate 150deg, arc to 20% 20px of 15% cw)'},
+ {at: 1, expect: 'shape(from 15% 15px, arc to 5% -25px of 15%, arc by 25% -15px of calc(0% + 192px) cw rotate 270deg, arc to 15% 20px of 20% cw)'},
+ {at: 1.5, expect: 'shape(from 20% 20px, arc to 0% -30px of calc(22.5% - 5px), arc by 30% -20px of calc(-15% + 288px) cw rotate 390deg, arc to 10% 20px of 25% cw)'},
]);
test_interpolation({
@@ -254,28 +267,28 @@ test_interpolation({
test_interpolation({
property: 'clip-path',
- from: 'shape(from 5% 5px, arc to 15% -15px of 10px 20px, arc by 15% -5px of 30px cw rotate 30deg large, arc to 25% 20px of 10px 5px small)',
+ from: 'shape(from 5% 5px, arc to 15% -15px of 10px 20px, arc by 15% -5px of 30px 30px cw rotate 30deg large, arc to 25% 20px of 10px 5px small)',
to: 'path("M 15 15 A 20,30 0 0,0 5,-25 a 20,20 270 0,1 25,-15 A 10,5 0 0,0 25 20")',
}, [
- {at: -0.3, expect: 'shape(from calc(6.5% - 4.5px) 2px, arc to calc(19.5% - 1.5px) -12px of 7px 17px, arc by calc(19.5% - 7.5px) -2px of 33px cw large rotate -42deg, arc to calc(32.5% - 7.5px) 20px of 10px 5px)'},
- {at: 0, expect: 'shape(from 5% 5px, arc to 15% -15px of 10px 20px, arc by 15% -5px of 30px cw rotate 30deg large, arc to 25% 20px of 10px 5px small)'},
- {at: 0.3, expect: 'shape(from calc(3.5% + 4.5px) 8px, arc to calc(10.5% + 1.5px) -18px of 13px 23px, arc by calc(10.5% + 7.5px) -8px of 27px cw large rotate 102deg, arc to calc(17.5% + 7.5px) 20px of 10px 5px)'},
- {at: 0.5, expect: 'shape(from calc(2.5% + 7.5px) 10px, arc to calc(7.5% + 2.5px) -20px of 15px 25px, arc by calc(7.5% + 12.5px) -10px of 25px cw large rotate 150deg, arc to calc(12.5% + 12.5px) 20px of 10px 5px)'},
- {at: 1, expect: 'shape(from calc(0% + 15px) 15px, arc to calc(0% + 5px) -25px of 20px 30px, arc by calc(0% + 25px) -15px of 20px cw rotate 270deg, arc to calc(0% + 25px) 20px of 10px 5px)'},
- {at: 1.5, expect: 'shape(from calc(-2.5% + 22.5px) 20px, arc to calc(-7.5% + 7.5px) -30px of 25px 35px, arc by calc(-7.5% + 37.5px) -20px of 15px cw rotate 390deg, arc to calc(-12.5% + 37.5px) 20px of 10px 5px)'},
+ {at: -0.3, expect: 'shape(from calc(6.5% - 4.5px) 2px, arc to calc(19.5% - 1.5px) -12px of 7px 17px, arc by calc(19.5% - 7.5px) -2px of 33px 33px cw large rotate -42deg, arc to calc(32.5% - 7.5px) 20px of 10px 5px)'},
+ {at: 0, expect: 'shape(from 5% 5px, arc to 15% -15px of 10px 20px, arc by 15% -5px of 30px 30px cw rotate 30deg large, arc to 25% 20px of 10px 5px small)'},
+ {at: 0.3, expect: 'shape(from calc(3.5% + 4.5px) 8px, arc to calc(10.5% + 1.5px) -18px of 13px 23px, arc by calc(10.5% + 7.5px) -8px of 27px 27px cw large rotate 102deg, arc to calc(17.5% + 7.5px) 20px of 10px 5px)'},
+ {at: 0.5, expect: 'shape(from calc(2.5% + 7.5px) 10px, arc to calc(7.5% + 2.5px) -20px of 15px 25px, arc by calc(7.5% + 12.5px) -10px of 25px 25px cw large rotate 150deg, arc to calc(12.5% + 12.5px) 20px of 10px 5px)'},
+ {at: 1, expect: 'shape(from calc(0% + 15px) 15px, arc to calc(0% + 5px) -25px of 20px 30px, arc by calc(0% + 25px) -15px of 20px 20px cw rotate 270deg, arc to calc(0% + 25px) 20px of 10px 5px)'},
+ {at: 1.5, expect: 'shape(from calc(-2.5% + 22.5px) 20px, arc to calc(-7.5% + 7.5px) -30px of 25px 35px, arc by calc(-7.5% + 37.5px) -20px of 15px 15px cw rotate 390deg, arc to calc(-12.5% + 37.5px) 20px of 10px 5px)'},
]);
test_interpolation({
property: 'clip-path',
from: 'path("M 5 5 A 10,20 0 0,0 15,-15 a 30,30 30 1,1 15,-5 A 10,5 0 0,0 25 20")',
- to: 'shape(from 15px 15px, arc to 5px -25px of 20px 30px, arc by 25px -15px of 20px cw rotate 270deg small, arc to 25px 20px of 10px 5px small cw)' // ccw, cw, cw
+ to: 'shape(from 15px 15px, arc to 5px -25px of 20px 30px, arc by 25px -15px of 20px 20px cw rotate 270deg small, arc to 25px 20px of 10px 5px small cw)' // ccw, cw, cw
}, [
{at: -0.3, expect: 'shape(from 2px 2px, arc to 18px -12px of 7px 17px, arc by 12px -2px of 33px 33px rotate -42deg cw large, arc to 25px 20px of 10px 5px)'},
- {at: 0, expect: 'shape(from 5px 5px, arc to 15px -15px of 10px 20px, arc by 15px -5px of 30px cw rotate 30deg large, arc to 25px 20px of 10px 5px)'},
+ {at: 0, expect: 'shape(from 5px 5px, arc to 15px -15px of 10px 20px, arc by 15px -5px of 30px 30px cw rotate 30deg large, arc to 25px 20px of 10px 5px)'},
{at: 0.3, expect: 'shape(from 8px 8px, arc to 12px -18px of 13px 23px, arc by 18px -8px of 27px 27px rotate 102deg cw large, arc to 25px 20px of 10px 5px cw)'},
- {at: 0.5, expect: 'shape(from 10px 10px, arc to 10px -20px of 15px 25px, arc by 20px -10px of 25px rotate 150deg cw large, arc to 25px 20px of 10px 5px cw)'},
- {at: 1, expect: 'shape(from 15px 15px, arc to 5px -25px of 20px 30px, arc by 25px -15px of 20px rotate 270deg cw, arc to 25px 20px of 10px 5px cw)'},
- {at: 1.5, expect: 'shape(from 20px 20px, arc to 0px -30px of 25px 35px, arc by 30px -20px of 15px rotate 390deg cw, arc to 25px 20px of 10px 5px cw)'},
+ {at: 0.5, expect: 'shape(from 10px 10px, arc to 10px -20px of 15px 25px, arc by 20px -10px of 25px 25px rotate 150deg cw large, arc to 25px 20px of 10px 5px cw)'},
+ {at: 1, expect: 'shape(from 15px 15px, arc to 5px -25px of 20px 30px, arc by 25px -15px of 20px 20px rotate 270deg cw, arc to 25px 20px of 10px 5px cw)'},
+ {at: 1.5, expect: 'shape(from 20px 20px, arc to 0px -30px of 25px 35px, arc by 30px -20px of 15px 15px rotate 390deg cw, arc to 25px 20px of 10px 5px cw)'},
]);
</script>
diff --git a/tests/wpt/tests/css/css-masking/clip-path/clip-path-shape-011.html b/tests/wpt/tests/css/css-masking/clip-path/clip-path-shape-011.html
new file mode 100644
index 00000000000..fc1927591e0
--- /dev/null
+++ b/tests/wpt/tests/css/css-masking/clip-path/clip-path-shape-011.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>CSS Masking: Test clip-path property and shape function with single-value arc radius</title>
+ <link rel="help" href="https://drafts.csswg.org/css-shapes-2/#funcdef-shape">
+ <link rel="match" href="reference/clip-path-shape-arc-ref.html">
+ <meta name="assert" content="When providing one radius value with percentage, the percentage should be relative to the diagonal.">
+<meta name="fuzzy" content="maxDifference=0-64;totalPixels=0-128">
+</head>
+<style>
+#shape {
+ width: 400px;
+ height: 300px;
+ background: green;
+ clip-path: shape(
+ from 0px 100px,
+ arc to 20px 100px of 10% large cw,
+ arc to 100px 20px of 5% small,
+ arc to 0 100px of calc(10px + 15%)
+ rotate 30deg);
+}
+</style>
+
+<body>
+ <div id="shape"></div>
+</body>
+</html>
diff --git a/tests/wpt/tests/css/css-masking/clip-path/reference/clip-path-shape-arc-ref.html b/tests/wpt/tests/css/css-masking/clip-path/reference/clip-path-shape-arc-ref.html
new file mode 100644
index 00000000000..9cbe55de210
--- /dev/null
+++ b/tests/wpt/tests/css/css-masking/clip-path/reference/clip-path-shape-arc-ref.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>CSS Masking: Test clip-path property and shape function with single-value arc radius</title>
+ <link rel="help" href="https://drafts.csswg.org/css-shapes-2/#funcdef-shape">
+</head>
+<style>
+#shape {
+ /* 500/sqrt(2) ~= 353 */
+ width: 353px;
+ height: 353px;
+ background: green;
+ clip-path: shape(
+ from 0px 100px,
+ arc to 20px 100px of 10% large cw,
+ arc to 100px 20px of 5% small,
+ arc to 0 100px of calc(10px + 15%)
+ rotate 30deg);
+}
+</style>
+
+<body>
+ <div id="shape"></div>
+</body>
+</html>
diff --git a/tests/wpt/tests/css/css-masking/parsing/clip-path-shape-parsing.html b/tests/wpt/tests/css/css-masking/parsing/clip-path-shape-parsing.html
index 5a4c7415bb4..b889ee01805 100644
--- a/tests/wpt/tests/css/css-masking/parsing/clip-path-shape-parsing.html
+++ b/tests/wpt/tests/css/css-masking/parsing/clip-path-shape-parsing.html
@@ -29,8 +29,10 @@ test_valid_value("clip-path", "shape(from 10px 10px, curve to 50px 20px with 10r
test_valid_value("clip-path", "shape(from 10px 10px, curve by 50px 20px with 10rem 1px / 20vh 1ch)");
test_valid_value("clip-path", "shape(from 10px 10px, smooth to 50px 20px with 10rem 1%)");
test_valid_value("clip-path", "shape(from 10px 10px, smooth to 50px 1pt)");
-test_valid_value("clip-path", "shape(from 10px 10px, arc to 50px 1pt of 10px 10px)", "shape(from 10px 10px, arc to 50px 1pt of 10px)");
-test_valid_value("clip-path", "shape(from 10px 10px, arc to 50px 1pt of 10px 10px small rotate 0deg)", "shape(from 10px 10px, arc to 50px 1pt of 10px)");
+test_valid_value("clip-path", "shape(from 10px 10px, arc to 50px 1pt of 10px 10px)");
+test_valid_value("clip-path", "shape(from 10px 10px, arc to 50px 1pt of 10%)");
+test_valid_value("clip-path", "shape(from 10px 10px, arc to 50px 1pt of 10px 10px small rotate 0deg)", "shape(from 10px 10px, arc to 50px 1pt of 10px 10px)");
+test_valid_value("clip-path", "shape(from 10px 10px, arc to 50px 1pt of 10px small rotate 0deg)", "shape(from 10px 10px, arc to 50px 1pt of 10px)");
test_valid_value("clip-path", "shape(from 10% 1rem, arc to 50px 1pt of 20% cw large rotate 25deg)", "shape(from 10% 1rem, arc to 50px 1pt of 20% cw large rotate 25deg)");
test_valid_value("clip-path", "shape(evenodd from 0px 0px, close)");
diff --git a/tests/wpt/tests/css/css-multicol/column-height-009-ref.html b/tests/wpt/tests/css/css-multicol/column-height-009-ref.html
index 034440ebd5c..4696d79695b 100644
--- a/tests/wpt/tests/css/css-multicol/column-height-009-ref.html
+++ b/tests/wpt/tests/css/css-multicol/column-height-009-ref.html
@@ -32,7 +32,7 @@
<div class="item">i<br>j</div>
<div class="item">o<br>p</div>
</div>
- <div class="rule" style="height:100px;"></div>
+ <div class="rule" style="height:160px;"></div>
<div class="column">
<div class="item">e<br>f</div>
<div class="item">k<br>l</div>
diff --git a/tests/wpt/tests/css/css-multicol/crashtests/repeated-table-column.html b/tests/wpt/tests/css/css-multicol/crashtests/repeated-table-column.html
new file mode 100644
index 00000000000..0d6a1accfd1
--- /dev/null
+++ b/tests/wpt/tests/css/css-multicol/crashtests/repeated-table-column.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<link rel="author" title="Morten Stenshorne" href="mailto:mstensho@chromium.org">
+<link rel="help" href="https://issues.chromium.org/issues/420267099">
+<div style="columns:2; column-fill:auto; height:100px;">
+ <div style="display:table;">
+ <div style="display:table-header-group; break-inside:avoid;">
+ <div style="display:table;">
+ <div id="col" style="display:table-column;"></div>
+ <div style="width:10px; height:10px;"></div>
+ </div>
+ </div>
+ <div style="height:150px;"></div>
+ </div>
+</div>
+<script>
+ col.offsetLeft;
+</script>
diff --git a/tests/wpt/tests/css/css-multicol/parsing/column-rule-color-invalid.html b/tests/wpt/tests/css/css-multicol/parsing/column-rule-color-invalid.html
index 015defb7560..da8dba0a73c 100644
--- a/tests/wpt/tests/css/css-multicol/parsing/column-rule-color-invalid.html
+++ b/tests/wpt/tests/css/css-multicol/parsing/column-rule-color-invalid.html
@@ -13,7 +13,6 @@
<script>
test_invalid_value("column-rule-color", "auto");
-test_invalid_value("column-rule-color", "green blue");
test_invalid_value("column-rule-color", "green, blue");
</script>
</body>
diff --git a/tests/wpt/tests/css/css-multicol/parsing/column-rule-style-invalid.html b/tests/wpt/tests/css/css-multicol/parsing/column-rule-style-invalid.html
index db367c273f4..e8f2ab60c47 100644
--- a/tests/wpt/tests/css/css-multicol/parsing/column-rule-style-invalid.html
+++ b/tests/wpt/tests/css/css-multicol/parsing/column-rule-style-invalid.html
@@ -12,7 +12,6 @@
<body>
<script>
test_invalid_value("column-rule-style", "auto");
-test_invalid_value("column-rule-style", "double dashed");
</script>
</body>
</html>
diff --git a/tests/wpt/tests/css/css-multicol/parsing/column-rule-width-invalid.html b/tests/wpt/tests/css/css-multicol/parsing/column-rule-width-invalid.html
index 0bdbbecb8ca..77f55e09d93 100644
--- a/tests/wpt/tests/css/css-multicol/parsing/column-rule-width-invalid.html
+++ b/tests/wpt/tests/css/css-multicol/parsing/column-rule-width-invalid.html
@@ -18,7 +18,6 @@ test_invalid_value("column-rule-width", "10");
test_invalid_value("column-rule-width", "-20px");
test_invalid_value("column-rule-width", "30%");
-test_invalid_value("column-rule-width", "medium 40px");
</script>
</body>
</html>
diff --git a/tests/wpt/tests/css/css-position/overlay/WEB_FEATURES.yml b/tests/wpt/tests/css/css-position/overlay/WEB_FEATURES.yml
new file mode 100644
index 00000000000..a1a4402ee42
--- /dev/null
+++ b/tests/wpt/tests/css/css-position/overlay/WEB_FEATURES.yml
@@ -0,0 +1,3 @@
+features:
+- name: overlay
+ files: "**"
diff --git a/tests/wpt/tests/css/css-sizing/contain-intrinsic-size/parsing/from-element.tentative.html b/tests/wpt/tests/css/css-sizing/contain-intrinsic-size/parsing/from-element.tentative.html
new file mode 100644
index 00000000000..fe99ccb23d9
--- /dev/null
+++ b/tests/wpt/tests/css/css-sizing/contain-intrinsic-size/parsing/from-element.tentative.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>CSS Intrinsic Size Test: intrinsic-size with from-element</title>
+<link rel="author" title="Chris Harrelson" href="mailto:chrishtr@chromium.org">
+<link rel="help" href="https://drafts.csswg.org/css-sizing-4/#intrinsic-size-override">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/css/support/parsing-testcommon.js"></script>
+</head>
+<body>
+<script>
+test_valid_value("contain-intrinsic-size", "from-element");
+</script>
+</body>
+</html>
+
diff --git a/tests/wpt/tests/css/css-sizing/image-max-width-and-height-behaves-as-auto.html b/tests/wpt/tests/css/css-sizing/image-max-width-and-height-behaves-as-auto.html
new file mode 100644
index 00000000000..dcb00ba6a5c
--- /dev/null
+++ b/tests/wpt/tests/css/css-sizing/image-max-width-and-height-behaves-as-auto.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<html>
+<head>
+<link rel="help" href="https://www.w3.org/TR/CSS22/visudet.html#min-max-widths">
+<link rel="help" href="https://drafts.csswg.org/css-sizing-4/#aspect-ratio-size-transfers">
+<meta name="assert" content="When computed logical width is auto, computed logical height behaves as auto,
+the used logical height should be determined with respect to any max logical width constraint.">
+<link rel="match" href="../reference/ref-filled-green-100px-square-only.html">
+<style>
+.container {
+ width: 100px;
+}
+img {
+ max-width: 100%;
+ height: 100%;
+}
+</style>
+</head>
+<body>
+ <p>Test passes if there is a filled green square.</p>
+ <div class="container">
+ <img src="aspect-ratio/support/200x200-green.png"/>
+ </div>
+</body>
+</html>
diff --git a/tests/wpt/tests/css/css-sizing/resources/iframe-contents-unsized.html b/tests/wpt/tests/css/css-sizing/resources/iframe-contents-unsized.html
new file mode 100644
index 00000000000..db1931a27d5
--- /dev/null
+++ b/tests/wpt/tests/css/css-sizing/resources/iframe-contents-unsized.html
@@ -0,0 +1,7 @@
+<!doctype HTML>
+<head>
+<style>
+ * { margin: 0 }
+</style>
+</head>
+<div style="width: 100px; height: 400px"></div>
diff --git a/tests/wpt/tests/css/css-sizing/resources/iframe-contents.html b/tests/wpt/tests/css/css-sizing/resources/iframe-contents.html
new file mode 100644
index 00000000000..3b7406e1e40
--- /dev/null
+++ b/tests/wpt/tests/css/css-sizing/resources/iframe-contents.html
@@ -0,0 +1,8 @@
+<!doctype HTML>
+<head>
+<style>
+ * { margin: 0 }
+</style>
+<meta name="responsive-embedded-sizing">
+</head>
+<div style="width: 100px; height: 400px"></div>
diff --git a/tests/wpt/tests/css/css-sizing/responsive-iframe-cross-origin-no-match-element.sub.tentative.html b/tests/wpt/tests/css/css-sizing/responsive-iframe-cross-origin-no-match-element.sub.tentative.html
new file mode 100644
index 00000000000..08dda4e6b76
--- /dev/null
+++ b/tests/wpt/tests/css/css-sizing/responsive-iframe-cross-origin-no-match-element.sub.tentative.html
@@ -0,0 +1,12 @@
+<!doctype HTML>
+<title>Test that a cross-origin iframe is responsively sized.</title>
+<link rel="author" href="mailto:chrishtr@chromium.org">
+<link rel="help" href="https://drafts.csswg.org/css-sizing/">
+<link rel="match" href="responsive-iframe-unsized-ref.html">
+<style>
+iframe {
+ border: 1px solid black;
+}
+</style>
+<iframe frameborder=0 scrolling=no src="http://{{hosts[alt][]}}:{{ports[http][0]}}/css/css-sizing/resources/iframe-contents.html">
+</iframe>
diff --git a/tests/wpt/tests/css/css-sizing/responsive-iframe-cross-origin-not-embedded-sized.sub.tentative.html b/tests/wpt/tests/css/css-sizing/responsive-iframe-cross-origin-not-embedded-sized.sub.tentative.html
new file mode 100644
index 00000000000..d9b33973a04
--- /dev/null
+++ b/tests/wpt/tests/css/css-sizing/responsive-iframe-cross-origin-not-embedded-sized.sub.tentative.html
@@ -0,0 +1,13 @@
+<!doctype HTML>
+<title>Test that a cross-origin iframe is responsively sized.</title>
+<link rel="author" href="mailto:chrishtr@chromium.org">
+<link rel="help" href="https://drafts.csswg.org/css-sizing/">
+<link rel="match" href="responsive-iframe-unsized-ref.html">
+<style>
+iframe {
+ border: 1px solid black;
+ contain-intrinsic-size: from-element;
+}
+</style>
+<iframe frameborder=0 scrolling=no src="http://{{hosts[alt][]}}:{{ports[http][0]}}/css/css-sizing/resources/iframe-contents-unsized.html">
+</iframe>
diff --git a/tests/wpt/tests/css/css-sizing/responsive-iframe-cross-origin.sub.tentative.html b/tests/wpt/tests/css/css-sizing/responsive-iframe-cross-origin.sub.tentative.html
new file mode 100644
index 00000000000..22f6f1d1581
--- /dev/null
+++ b/tests/wpt/tests/css/css-sizing/responsive-iframe-cross-origin.sub.tentative.html
@@ -0,0 +1,13 @@
+<!doctype HTML>
+<title>Test that a cross-origin iframe is responsively sized.</title>
+<link rel="author" href="mailto:chrishtr@chromium.org">
+<link rel="help" href="https://drafts.csswg.org/css-sizing/">
+<link rel="match" href="responsive-iframe-ref.html">
+<style>
+iframe {
+ border: 1px solid black;
+ contain-intrinsic-size: from-element;
+}
+</style>
+<iframe frameborder=0 src="http://{{hosts[alt][]}}:{{ports[http][0]}}/css/css-sizing/resources/iframe-contents.html">
+</iframe>
diff --git a/tests/wpt/tests/css/css-sizing/responsive-iframe-no-match-element.html b/tests/wpt/tests/css/css-sizing/responsive-iframe-no-match-element.html
new file mode 100644
index 00000000000..685eb60f123
--- /dev/null
+++ b/tests/wpt/tests/css/css-sizing/responsive-iframe-no-match-element.html
@@ -0,0 +1,12 @@
+<!doctype HTML>
+<title>Test that a same-origin iframe is responsively sized.</title>
+<link rel="author" href="mailto:chrishtr@chromium.org">
+<link rel="help" href="https://drafts.csswg.org/css-sizing/">
+<link rel="match" href="responsive-iframe-unsized-ref.html">
+<style>
+iframe {
+ border: 1px solid black;
+}
+</style>
+<iframe frameborder=0 scrolling=no src="resources/iframe-contents.html">
+</iframe>
diff --git a/tests/wpt/tests/css/css-sizing/responsive-iframe-not-embedded-sized.tentative.html b/tests/wpt/tests/css/css-sizing/responsive-iframe-not-embedded-sized.tentative.html
new file mode 100644
index 00000000000..0d1f91c5789
--- /dev/null
+++ b/tests/wpt/tests/css/css-sizing/responsive-iframe-not-embedded-sized.tentative.html
@@ -0,0 +1,13 @@
+<!doctype HTML>
+<title>Test that a same-origin iframe is responsively sized.</title>
+<link rel="author" href="mailto:chrishtr@chromium.org">
+<link rel="help" href="https://drafts.csswg.org/css-sizing/">
+<link rel="match" href="responsive-iframe-unsized-ref.html">
+<style>
+iframe {
+ border: 1px solid black;
+ contain-intrinsic-size: from-element;
+}
+</style>
+<iframe frameborder=0 scrolling=no src="resources/iframe-contents-unsized.html">
+</iframe>
diff --git a/tests/wpt/tests/css/css-sizing/responsive-iframe-ref.html b/tests/wpt/tests/css/css-sizing/responsive-iframe-ref.html
new file mode 100644
index 00000000000..c446474f71a
--- /dev/null
+++ b/tests/wpt/tests/css/css-sizing/responsive-iframe-ref.html
@@ -0,0 +1,10 @@
+<!doctype HTML>
+<style>
+div {
+ width: 300px;
+ height: 400px;
+ border: 1px solid black;
+}
+</style>
+<div>
+</div>
diff --git a/tests/wpt/tests/css/css-sizing/responsive-iframe-unsized-ref.html b/tests/wpt/tests/css/css-sizing/responsive-iframe-unsized-ref.html
new file mode 100644
index 00000000000..2fa633e086d
--- /dev/null
+++ b/tests/wpt/tests/css/css-sizing/responsive-iframe-unsized-ref.html
@@ -0,0 +1,10 @@
+<!doctype HTML>
+<style>
+div {
+ width: 300px;
+ height: 150px;
+ border: 1px solid black;
+}
+</style>
+<div>
+</div>
diff --git a/tests/wpt/tests/css/css-sizing/responsive-iframe.tentative.html b/tests/wpt/tests/css/css-sizing/responsive-iframe.tentative.html
new file mode 100644
index 00000000000..229cf018449
--- /dev/null
+++ b/tests/wpt/tests/css/css-sizing/responsive-iframe.tentative.html
@@ -0,0 +1,13 @@
+<!doctype HTML>
+<title>Test that a same-origin iframe is responsively sized.</title>
+<link rel="author" href="mailto:chrishtr@chromium.org">
+<link rel="help" href="https://drafts.csswg.org/css-sizing/">
+<link rel="match" href="responsive-iframe-ref.html">
+<style>
+iframe {
+ border: 1px solid black;
+ contain-intrinsic-size: from-element;
+}
+</style>
+<iframe frameborder=0 src="resources/iframe-contents.html">
+</iframe>
diff --git a/tests/wpt/tests/css/css-text/text-autospace/text-autospace-edit-001-ref.html b/tests/wpt/tests/css/css-text/text-autospace/text-autospace-edit-001-ref.html
new file mode 100644
index 00000000000..ca95e197462
--- /dev/null
+++ b/tests/wpt/tests/css/css-text/text-autospace/text-autospace-edit-001-ref.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" />
+<style>
+#container {
+ font-family: Ahem;
+ font-size: 40px;
+}
+</style>
+<div id="container">
+ <div>1国国国国国国国国国国</div>
+ <div>1国国国国国国国国国国</div>
+ <div>1国国国国国国国国国国国国</div>
+ <div>1国国国国国国国国国国国国</div>
+</div>
diff --git a/tests/wpt/tests/css/css-text/text-autospace/text-autospace-edit-001.html b/tests/wpt/tests/css/css-text/text-autospace/text-autospace-edit-001.html
new file mode 100644
index 00000000000..80c46f54d20
--- /dev/null
+++ b/tests/wpt/tests/css/css-text/text-autospace/text-autospace-edit-001.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<link rel="help" href="https://drafts.csswg.org/css-text-4/#text-autospace-property">
+<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" />
+<link rel="match" href="text-autospace-edit-001-ref.html">
+<style>
+#container {
+ font-family: Ahem;
+ font-size: 40px;
+}
+</style>
+<div id="container">
+ <div data-append="10">1国国国国国国国国国国</div>
+ <div data-append="11">1国国国国国国国国国国国国</div>
+</div>
+<script>
+for (const reference of document.querySelectorAll("[data-append]")) {
+ // Split the `textContent` at the `data-append` offset.
+ const text = reference.textContent;
+ const offset = parseInt(reference.dataset.append);
+ const initiaL_text = text.substring(0, offset);
+ const append_text = text.substring(offset);
+
+ // Create a `<div>` with the `initial_text`, then append `append_text`
+ // one character at a time, with a forced layout.
+ const element = document.createElement("div");
+ const text_node = document.createTextNode(initiaL_text);
+ element.appendChild(text_node);
+ reference.after(element);
+ for (const ch of append_text) {
+ element.offsetTop;
+ text_node.appendData(ch);
+ }
+}
+</script>
diff --git a/tests/wpt/tests/css/css-text/text-autospace/text-autospace-vs-001-ref.html b/tests/wpt/tests/css/css-text/text-autospace/text-autospace-vs-001-ref.html
new file mode 100644
index 00000000000..b02b4f7a20d
--- /dev/null
+++ b/tests/wpt/tests/css/css-text/text-autospace/text-autospace-vs-001-ref.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" />
+<style>
+#container {
+ font-family: Ahem;
+ font-size: 40px;
+ text-autospace: no-autospace;
+
+ span {
+ margin-left: calc(1em / 8);
+ margin-right: calc(1em / 8);
+ }
+}
+</style>
+<div id="container">
+ <div class="test">国&#xFE00;国</div>
+ <div class="test">国&#xFE00;<span>A</span></div>
+ <div class="test">A&#xFE00;<span>国</span></div>
+ <div class="test">国&#xE0100;国</div>
+ <div class="test">国&#xE0100;<span>A</span></div>
+ <div class="test">A&#xE0100;<span>国</span></div>
+</div>
diff --git a/tests/wpt/tests/css/css-text/text-autospace/text-autospace-vs-001.html b/tests/wpt/tests/css/css-text/text-autospace/text-autospace-vs-001.html
new file mode 100644
index 00000000000..31c7bbf6073
--- /dev/null
+++ b/tests/wpt/tests/css/css-text/text-autospace/text-autospace-vs-001.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<link rel="help" href="https://drafts.csswg.org/css-text-4/#text-autospace-property">
+<link rel="stylesheet" type="text/css" href="/fonts/ahem.css" />
+<link rel="match" href="text-autospace-vs-001-ref.html">
+<style>
+#container {
+ font-family: Ahem;
+ font-size: 40px;
+}
+</style>
+<div id="container">
+ <div class="test">国&#xFE00;国</div>
+ <div class="test">国&#xFE00;A</div>
+ <div class="test">A&#xFE00;国</div>
+ <div class="test">国&#xE0100;国</div>
+ <div class="test">国&#xE0100;A</div>
+ <div class="test">A&#xE0100;国</div>
+</div>
diff --git a/tests/wpt/tests/css/css-text/word-break/reference/word-break-keep-all-u002d-ref.html b/tests/wpt/tests/css/css-text/word-break/reference/word-break-keep-all-u002d-ref.html
new file mode 100644
index 00000000000..4a6553cfe83
--- /dev/null
+++ b/tests/wpt/tests/css/css-text/word-break/reference/word-break-keep-all-u002d-ref.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<style>
+#container {
+ font-size: 20px;
+ width: 3ch;
+}
+</style>
+<div id="container">
+ <div>AB-CD-EF</div>
+ <div>12-34-56</div>
+</div>
diff --git a/tests/wpt/tests/css/css-text/word-break/word-break-keep-all-u002d.html b/tests/wpt/tests/css/css-text/word-break/word-break-keep-all-u002d.html
new file mode 100644
index 00000000000..df3ebb3f221
--- /dev/null
+++ b/tests/wpt/tests/css/css-text/word-break/word-break-keep-all-u002d.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<link rel="help" href="https://drafts.csswg.org/css-text-3/#valdef-word-break-keep-all">
+<link rel="match" href="reference/word-break-keep-all-u002d-ref.html">
+<style>
+#container {
+ font-size: 20px;
+ width: 3ch;
+ word-break: keep-all;
+}
+</style>
+<div id="container">
+ <div>AB-CD-EF</div>
+ <div>12-34-56</div>
+</div>
diff --git a/tests/wpt/tests/css/css-typed-om/the-stylepropertymap/properties/column-rule-style.html b/tests/wpt/tests/css/css-typed-om/the-stylepropertymap/properties/column-rule-style.html
index 8e56f621714..7098270a392 100644
--- a/tests/wpt/tests/css/css-typed-om/the-stylepropertymap/properties/column-rule-style.html
+++ b/tests/wpt/tests/css/css-typed-om/the-stylepropertymap/properties/column-rule-style.html
@@ -14,16 +14,36 @@
'use strict';
runPropertyTests('column-rule-style', [
- { syntax: 'none' },
- { syntax: 'hidden' },
- { syntax: 'dotted' },
- { syntax: 'dashed' },
- { syntax: 'solid' },
- { syntax: 'double' },
- { syntax: 'groove' },
- { syntax: 'ridge' },
- { syntax: 'inset' },
- { syntax: 'outset' }
+ { syntax: 'none',
+ computed: (_, result) => assert_class_string(result, 'CSSStyleValue')
+ },
+ { syntax: 'hidden',
+ computed: (_, result) => assert_class_string(result, 'CSSStyleValue')
+ },
+ { syntax: 'dotted',
+ computed: (_, result) => assert_class_string(result, 'CSSStyleValue')
+ },
+ { syntax: 'dashed',
+ computed: (_, result) => assert_class_string(result, 'CSSStyleValue')
+ },
+ { syntax: 'solid',
+ computed: (_, result) => assert_class_string(result, 'CSSStyleValue')
+ },
+ { syntax: 'double',
+ computed: (_, result) => assert_class_string(result, 'CSSStyleValue')
+ },
+ { syntax: 'groove',
+ computed: (_, result) => assert_class_string(result, 'CSSStyleValue')
+ },
+ { syntax: 'ridge',
+ computed: (_, result) => assert_class_string(result, 'CSSStyleValue')
+ },
+ { syntax: 'inset',
+ computed: (_, result) => assert_class_string(result, 'CSSStyleValue')
+ },
+ { syntax: 'outset',
+ computed: (_, result) => assert_class_string(result, 'CSSStyleValue')
+ }
]);
</script>
diff --git a/tests/wpt/tests/css/css-typed-om/the-stylepropertymap/properties/column-rule-width.html b/tests/wpt/tests/css/css-typed-om/the-stylepropertymap/properties/column-rule-width.html
index bd3c0ac8f43..8f09d1cb45a 100644
--- a/tests/wpt/tests/css/css-typed-om/the-stylepropertymap/properties/column-rule-width.html
+++ b/tests/wpt/tests/css/css-typed-om/the-stylepropertymap/properties/column-rule-width.html
@@ -13,30 +13,29 @@
<script>
'use strict';
-function assert_is_zero_px(result) {
- assert_style_value_equals(result, new CSSUnitValue(0, 'px'));
-}
-
runPropertyTests('column-rule-width', [
- // Computed value is 0 when column-rule-style is 'none'.
- // FIXME: Add separate test where column-rule-style is not 'none' or 'hidden'.
{
syntax: 'thin',
- computed: (_, result) => assert_is_zero_px(result)
+ computed: (_, result) => assert_class_string(result, 'CSSStyleValue')
},
{
syntax: 'medium',
- computed: (_, result) => assert_is_zero_px(result)
+ computed: (_, result) => assert_class_string(result, 'CSSStyleValue')
},
{
syntax: 'thick',
- computed: (_, result) => assert_is_zero_px(result)
+ computed: (_, result) => assert_class_string(result, 'CSSStyleValue')
},
{
syntax: '<length>',
specified: assert_is_equal_with_range_handling,
- computed: (_, result) => assert_is_zero_px(result)
+ computed: (_, result) => assert_class_string(result, 'CSSStyleValue')
},
]);
+runUnsupportedPropertyTests('column-rule-width', [
+ 'thin', 'medium', 'thick', '2px', '3px',
+ '4px 5px', 'thin medium thick',
+]);
+
</script>
diff --git a/tests/wpt/tests/css/css-values/if-conditionals.html b/tests/wpt/tests/css/css-values/if-conditionals.html
index caead7864d5..f6d981798ae 100644
--- a/tests/wpt/tests/css/css-values/if-conditionals.html
+++ b/tests/wpt/tests/css/css-values/if-conditionals.html
@@ -37,6 +37,21 @@
inherits: true;
initial-value: 3;
}
+ @property --angle {
+ syntax: "<angle>";
+ inherits: true;
+ initial-value: 3deg;
+ }
+ @property --time {
+ syntax: "<time>";
+ inherits: true;
+ initial-value: 3s;
+ }
+ @property --resolution {
+ syntax: "<resolution>";
+ inherits: true;
+ initial-value: 3dpi;
+ }
div {
font-size: 30px;
}
@@ -511,6 +526,122 @@
[['--length', 'attr(data-foo type(<length>))']],
'false_value');
+ // style() queries with range syntax in the condition, literals on both sides of equation
+ test_if_with_custom_properties('if(style(10em > 3px): true_value; else: false_value)', [], 'true_value');
+ test_if_with_custom_properties('if(style(1em > 1px): true_value; else: false_value)', [], 'true_value');
+ test_if_with_custom_properties('if(style(7px > 3px): true_value; else: false_value)', [], 'true_value');
+ test_if_with_custom_properties('if(style(3px > 3px): true_value; else: false_value)', [], 'false_value');
+ test_if_with_custom_properties('if(style(3turn > 3deg): true_value; else: false_value)', [], 'true_value');
+ test_if_with_custom_properties('if(style(3turn <= 3deg): true_value; else: false_value)', [], 'false_value');
+ test_if_with_custom_properties('if(style(3% >= 3%): true_value; else: false_value)', [], 'true_value');
+ test_if_with_custom_properties('if(style(3s > 3ms): true_value; else: false_value)', [], 'true_value');
+ test_if_with_custom_properties('if(style(3dppx > 96dpi): true_value; else: false_value)', [], 'true_value');
+
+ // style() queries with range syntax in the condition, simple custom properties in the condition
+ test_if_with_custom_properties('if(style(--x <= 3): true_value; else: false_value)',
+ [['--x', '3']],
+ 'true_value');
+ test_if_with_custom_properties('if(style(--x >= --y): true_value; else: false_value)',
+ [['--x', '3'], ['--y', '3']],
+ 'true_value');
+ test_if_with_custom_properties('if(style(--length > 3px): true_value; else: false_value)',
+ [['--length', '11px']],
+ 'true_value');
+ test_if_with_custom_properties('if(style(--x > 3px): true_value; else: false_value)',
+ [['--x', '11px']],
+ 'true_value');
+ test_if_with_custom_properties('if(style(--number >= 3): true_value; else: false_value)',
+ [['--number', '3']],
+ 'true_value');
+ test_if_with_custom_properties('if(style(--x >= 3): true_value; else: false_value)',
+ [['--x', '3']],
+ 'true_value');
+ test_if_with_custom_properties('if(style(--percentage > 3%): true_value; else: false_value)',
+ [['--percentage', '5%']],
+ 'true_value');
+ test_if_with_custom_properties('if(style(--x > 3%): true_value; else: false_value)',
+ [['--x', '5%']],
+ 'true_value');
+ test_if_with_custom_properties('if(style(--angle < 1turn): true_value; else: false_value)',
+ [['--angle', '1deg']],
+ 'true_value');
+ test_if_with_custom_properties('if(style(--x < 1turn): true_value; else: false_value)',
+ [['--x', '1deg']],
+ 'true_value');
+ test_if_with_custom_properties('if(style(--time <= 1000ms): true_value; else: false_value)',
+ [['--time', '1s']],
+ 'true_value');
+ test_if_with_custom_properties('if(style(--x <= 1000ms): true_value; else: false_value)',
+ [['--x', '1s']],
+ 'true_value');
+ test_if_with_custom_properties('if(style(3dppx > --resolution): true_value; else: false_value)',
+ [['--resolution', '96dpi']],
+ 'true_value');
+ test_if_with_custom_properties('if(style(3dppx > --x): true_value; else: false_value)',
+ [['--x', '96dpi']],
+ 'true_value');
+
+ // style() queries with range syntax in the condition, invalid custom properties in the condition
+ test_if_with_custom_properties('if(style(--x + 1 >= --y): true_value; else: false_value)',
+ [['--x', '5'], ['--y', '3']],
+ 'false_value');
+ test_if_with_custom_properties('if(style(--x >= --y + 1): true_value; else: false_value)',
+ [['--x', '5'], ['--y', '3']],
+ 'false_value');
+ test_if_with_custom_properties('if(style(calc(--x + 1) >= --y): true_value; else: false_value)',
+ [['--x', '5'], ['--y', '3']],
+ 'false_value');
+ test_if_with_custom_properties('if(style(--x >= calc(--y + 1)): true_value; else: false_value)',
+ [['--x', '5'], ['--y', '3']],
+ 'false_value');
+
+ // style() queries with range syntax in the condition, custom properties with functions in the condition
+ test_if_with_custom_properties('if(style(--x >= calc(3px + 3px)): true_value; else: false_value)',
+ [['--x', '7px']],
+ 'true_value');
+ test_if_with_custom_properties('if(style(calc(var(--x) + 1) >= var(--y)): true_value; else: false_value)',
+ [['--x', '5'], ['--y', '3']],
+ 'true_value');
+ test_if_with_custom_properties('if(style(var(--x) >= --x): true_value; else: false_value)',
+ [['--x', '3']],
+ 'true_value');
+
+ // style() queries with range syntax in the condition, incompatible types in the range.
+ test_if_with_custom_properties('if(style(3px > 3): true_value; else: false_value)',
+ [],
+ 'false_value');
+ test_if_with_custom_properties('if(style(3em > 3deg): true_value; else: false_value)',
+ [],
+ 'false_value');
+ test_if_with_custom_properties('if(style(1px >= 1%) or style(1px <= 1%): true_value; else: false_value)',
+ [],
+ 'false_value');
+ test_if_with_custom_properties('if(style(--length > 3): true_value; else: false_value)',
+ [['--length', '11em']],
+ 'false_value');
+ test_if_with_custom_properties('if(style(--number > 3px): true_value; else: false_value)',
+ [['--number', '11']],
+ 'false_value');
+ test_if_with_custom_properties('if(style(--x >= 3): true_value; else: false_value)',
+ [['--x', '3px']],
+ 'false_value');
+ test_if_with_custom_properties(`if(style(--length >= 30px): true_value;
+ else: false_value)`,
+ [['--length', 'attr(data-foo type(<length>))']],
+ 'true_value');
+
+ // style() queries with range syntax in the condition, double range
+ test_if_with_custom_properties('if(style(10px <= 10px < 11px): true_value; else: false_value)', [], 'true_value');
+ test_if_with_custom_properties('if(style(3 < --x <= 5): true_value; else: false_value)',
+ [['--x', '5']],
+ 'true_value');
+ test_if_with_custom_properties('if(style(--x >= --y > --z): true_value; else: false_value)',
+ [['--x', '3'], ['--y', '3'], ['--z', '3']],
+ 'false_value');
+ test_if_with_custom_properties('if(style(--x >= --y > --z): true_value; else: false_value)',
+ [['--x', '3'], ['--y', '3'], ['--z', '1']],
+ 'true_value');
+
// media() queries in the condition
test_if(`if(media(max-width: 1px): true_value;
else: false_value)`,
diff --git a/tests/wpt/tests/css/css-values/tree-counting/sibling-function-container-query-invalidation.html b/tests/wpt/tests/css/css-values/tree-counting/sibling-function-container-query-invalidation.html
new file mode 100644
index 00000000000..c0d6d913af0
--- /dev/null
+++ b/tests/wpt/tests/css/css-values/tree-counting/sibling-function-container-query-invalidation.html
@@ -0,0 +1,92 @@
+<!DOCTYPE html>
+<title>CSS Values and Units Test: sibling-index() and sibling-count() changes in container queries</title>
+<link rel="help" href="https://drafts.csswg.org/css-values-5/#tree-counting">
+<link rel="help" href="https://drafts.csswg.org/css-conditional-5/#container-features">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<style>
+ @property --length {
+ syntax: "<length>";
+ initial-value: 0px;
+ inherits: false;
+ }
+ .container { container-type: inline-size; }
+ #c1 {
+ width: 100px;
+ --length: 100px;
+ }
+ #c2 {
+ width: 400px;
+ --length: 600px;
+ }
+ span {
+ --match-100: no;
+ --match-600: no;
+ }
+ @container (width = calc(100px * sibling-index())) {
+ span { background-color: green; }
+ }
+ @container (width = calc(200px * sibling-count())) {
+ span { color: lime; }
+ }
+ @container style(--length: calc(100px * sibling-index())) {
+ span { --match-100: yes; }
+ }
+ @container style(--length: calc(300px * sibling-count())) {
+ span { --match-600: yes; }
+ }
+</style>
+<div style="color:black">
+ <div id="rm1"></div>
+ <div id="rm2"></div>
+ <div id="c1" class="container">
+ <span id="t1"></span>
+ </div>
+ <div id="c2" class="container">
+ <span id="t2"></span>
+ </div>
+</div>
+<script>
+ test(() => {
+ assert_equals(getComputedStyle(t1).backgroundColor, "rgba(0, 0, 0, 0)");
+ assert_equals(getComputedStyle(t1).color, "rgb(0, 0, 0)");
+ }, "sibling-index() in @container width query initially not matching");
+
+ test(() => {
+ assert_equals(getComputedStyle(t1).backgroundColor, "rgba(0, 0, 0, 0)");
+ assert_equals(getComputedStyle(t1).color, "rgb(0, 0, 0)");
+ }, "sibling-count() in @container width query initially not matching");
+
+ test(() => {
+ assert_equals(getComputedStyle(t1).getPropertyValue("--match-100"), "no");
+ assert_equals(getComputedStyle(t1).getPropertyValue("--match-600"), "no");
+ }, "sibling-index() in @container style() query initially not matching");
+
+ test(() => {
+ assert_equals(getComputedStyle(t2).getPropertyValue("--match-100"), "no");
+ assert_equals(getComputedStyle(t2).getPropertyValue("--match-600"), "no");
+ }, "sibling-count() in @container style() query initially not matching");
+
+ rm1.remove();
+ rm2.remove();
+
+ test(() => {
+ assert_equals(getComputedStyle(t1).backgroundColor, "rgb(0, 128, 0)");
+ assert_equals(getComputedStyle(t1).color, "rgb(0, 0, 0)");
+ }, "sibling-index() in @container width query matching after removal");
+
+ test(() => {
+ assert_equals(getComputedStyle(t2).backgroundColor, "rgba(0, 0, 0, 0)");
+ assert_equals(getComputedStyle(t2).color, "rgb(0, 255, 0)");
+ }, "sibling-count() in @container width query matching after removal");
+
+ test(() => {
+ assert_equals(getComputedStyle(t1).getPropertyValue("--match-100"), "yes");
+ assert_equals(getComputedStyle(t1).getPropertyValue("--match-600"), "no");
+ }, "sibling-index() in @container style() query matching after removal");
+
+ test(() => {
+ assert_equals(getComputedStyle(t2).getPropertyValue("--match-100"), "no");
+ assert_equals(getComputedStyle(t2).getPropertyValue("--match-600"), "yes");
+ }, "sibling-count() in @container style() query matching after removal");
+</script>
diff --git a/tests/wpt/tests/css/css-values/tree-counting/sibling-index-keyframe-registered-properties-dynamic.html b/tests/wpt/tests/css/css-values/tree-counting/sibling-index-keyframe-registered-properties-dynamic.html
index 77af5434a1c..ac2ed1a8af1 100644
--- a/tests/wpt/tests/css/css-values/tree-counting/sibling-index-keyframe-registered-properties-dynamic.html
+++ b/tests/wpt/tests/css/css-values/tree-counting/sibling-index-keyframe-registered-properties-dynamic.html
@@ -13,6 +13,7 @@
@property --length { syntax: "<length>"; initial-value: 0px; inherits: false; }
@property --length-percentage { syntax: "<length-percentage>"; initial-value: 0px; inherits: false; }
@property --color { syntax: "<color>"; initial-value: black; inherits: false; }
+ @property --list { syntax: "<integer>+"; initial-value: 0; inherits: false; }
@keyframes --anim {
from {
@@ -25,6 +26,7 @@
--length: calc(sibling-index() * 7px);
--length-percentage: calc((sibling-index() * 8px) + (sibling-count() * 5%));
--color: color(srgb 0 calc(0.2 * sibling-index()) 0);
+ --list: 13 sibling-index();
}
to {
--time: 13s;
@@ -36,6 +38,7 @@
--length: 13px;
--length-percentage: calc(13px + 7%);
--color: red;
+ --list: 29 sibling-index();
}
}
#target {
@@ -75,6 +78,9 @@
test(() => {
assert_equals(getComputedStyle(target).getPropertyValue("--color"), "color(srgb 0 0.6 0)");
}, "Initially, the sibling-index() is 3 for --color");
+ test(() => {
+ assert_equals(getComputedStyle(target).getPropertyValue("--list"), "13 3");
+ }, "Initially, the sibling-index() is 3 for --list");
rm.remove();
@@ -105,5 +111,8 @@
test(() => {
assert_equals(getComputedStyle(target).getPropertyValue("--color"), "color(srgb 0 0.4 0)");
}, "Removing a preceding sibling of #target reduces the sibling-index() for --color");
+ test(() => {
+ assert_equals(getComputedStyle(target).getPropertyValue("--list"), "13 2");
+ }, "Removing a preceding sibling of #target reduces the sibling-index() for --list");
</script>
diff --git a/tests/wpt/tests/css/css-view-transitions/auto-name-from-id.html b/tests/wpt/tests/css/css-view-transitions/auto-name-from-id.html
index d3430c93a1d..20080d7623a 100644
--- a/tests/wpt/tests/css/css-view-transitions/auto-name-from-id.html
+++ b/tests/wpt/tests/css/css-view-transitions/auto-name-from-id.html
@@ -34,6 +34,12 @@ main.switch #item1 {
left: 100px;
}
+/* Make test fail if ID matches */
+::view-transition-group(item1),
+::view-transition-group(item2) {
+ border: 2px solid red;
+}
+
html::view-transition {
background: rebeccapurple;
}
diff --git a/tests/wpt/tests/css/css-view-transitions/auto-name-get-animations.html b/tests/wpt/tests/css/css-view-transitions/auto-name-get-animations.html
index 0442255542c..b684349a5f9 100644
--- a/tests/wpt/tests/css/css-view-transitions/auto-name-get-animations.html
+++ b/tests/wpt/tests/css/css-view-transitions/auto-name-get-animations.html
@@ -1,6 +1,6 @@
<!DOCTYPE html>
<html >
-<title>View transitions: generated names should not be visible from script</title>
+<title>View transitions: generated names should be prefixed with -ua- in script</title>
<link rel="help" href="https://drafts.csswg.org/css-view-transitions-2/">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
@@ -57,12 +57,20 @@ main.switch .item1 {
}).ready;
const animations = document.documentElement.getAnimations({subtree: true});
const pseudos = Array.from(new Set(animations.map(a => a.effect.pseudoElement)));
+ const item1GeneratedName = pseudos[0].replace("::view-transition-group(", "").slice(0, -1);
+ const item2GeneratedName = pseudos[3].replace("::view-transition-group(", "").slice(0, -1);
+ assert_true(item1GeneratedName.startsWith("-ua-"), "Item 1 generated name starts with -ua-");
+ assert_true(item2GeneratedName.startsWith("-ua-"), "Item 2 generated name starts with -ua-");
assert_array_equals(pseudos,
[
- "::view-transition-group(match-element)",
- "::view-transition-new(match-element)",
- "::view-transition-old(match-element)"]);
- }, "Generated view-transition-names should not be reflected in script");
+ `::view-transition-group(${item1GeneratedName})`,
+ `::view-transition-old(${item1GeneratedName})`,
+ `::view-transition-new(${item1GeneratedName})`,
+ `::view-transition-group(${item2GeneratedName})`,
+ `::view-transition-old(${item2GeneratedName})`,
+ `::view-transition-new(${item2GeneratedName})`
+ ], "Generated names should start with -ua- and pseudo-elements should be in tree order");
+ }, "Generated view-transition-names should be prefixed with -ua- in script");
</script>
</body> \ No newline at end of file
diff --git a/tests/wpt/tests/css/css-view-transitions/inline-child-with-composited-filter-ref.html b/tests/wpt/tests/css/css-view-transitions/inline-child-with-composited-filter-ref.html
new file mode 100644
index 00000000000..9dd26f2c3b1
--- /dev/null
+++ b/tests/wpt/tests/css/css-view-transitions/inline-child-with-composited-filter-ref.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<title>View transitions: inline child with filter (ref)</title>
+<link rel="help" href="https://www.w3.org/TR/css-view-transitions-1/">
+<link rel="author" href="mailto:vmpstr@chromium.org">
+<link rel="author" href="mailto:mattwoodrow@apple.com">
+
+<style>
+body { margin : 0; }
+#target {
+ width: 100px;
+ height: 100px;
+ background-color: grey;
+ overflow-clip-margin: 40px;
+ contain: paint;
+ view-transition-name: target;
+}
+
+#child {
+ position: relative;
+ left: 100px;
+ top: 100px;
+ color: lightgreen;
+ background-color: darkgreen;
+ filter: blur(30px);
+ transform: translateZ(0px);
+}
+</style>
+
+<div id="target">
+ <span id="child">INLINEBOX</span>
+</div>
diff --git a/tests/wpt/tests/css/css-view-transitions/inline-child-with-composited-filter.html b/tests/wpt/tests/css/css-view-transitions/inline-child-with-composited-filter.html
new file mode 100644
index 00000000000..36ba9803e1e
--- /dev/null
+++ b/tests/wpt/tests/css/css-view-transitions/inline-child-with-composited-filter.html
@@ -0,0 +1,57 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<title>View transitions: inline child with filter</title>
+<link rel="help" href="https://www.w3.org/TR/css-view-transitions-1/">
+<link rel="author" href="mailto:vmpstr@chromium.org">
+<link rel="author" href="mailto:mattwoodrow@apple.com">
+<link rel="match" href="inline-child-with-filter-ref.html">
+<meta name=fuzzy content="maxDifference=0-2;totalPixels=0-2400">
+<script src="/common/reftest-wait.js"></script>
+
+<style>
+body { margin : 0; }
+#target {
+ width: 100px;
+ height: 100px;
+ background-color: grey;
+ overflow-clip-margin: 40px;
+ contain: paint;
+ view-transition-name: target;
+}
+
+#child {
+ position: relative;
+ left: 100px;
+ top: 100px;
+ color: lightgreen;
+ background-color: darkgreen;
+ filter: blur(30px);
+ transform: translateZ(0px);
+}
+
+html::view-transition-group(root) { animation-duration: 300s; }
+html::view-transition-old(target) {
+ animation: unset;
+ opacity: 1;
+}
+html::view-transition-new(target) {
+ animation: unset;
+ opacity: 0;
+}
+</style>
+
+<div id="target">
+ <span id="child">INLINEBOX</span>
+</div>
+
+<script>
+failIfNot(document.startViewTransition, "Missing document.startViewTransition");
+
+async function runTest() {
+ let transition = document.startViewTransition(async () => {
+ document.getElementById("target").remove();
+ });
+ transition.ready.then(() => requestAnimationFrame(takeScreenshot));
+}
+onload = () => requestAnimationFrame(() => requestAnimationFrame(runTest));
+</script>
diff --git a/tests/wpt/tests/css/css-view-transitions/inline-with-offset-from-containing-block.html b/tests/wpt/tests/css/css-view-transitions/inline-with-offset-from-containing-block.html
index 31f8449ff63..77fb0570966 100644
--- a/tests/wpt/tests/css/css-view-transitions/inline-with-offset-from-containing-block.html
+++ b/tests/wpt/tests/css/css-view-transitions/inline-with-offset-from-containing-block.html
@@ -4,7 +4,7 @@
<link rel="help" href="https://drafts.csswg.org/css-view-transitions-1/">
<link rel="author" href="mailto:khushalsagar@chromium.org">
<link rel="match" href="inline-with-offset-from-containing-block-ref.html">
-<meta name="fuzzy" content="maxDifference=0-255; totalPixels=0-1500">
+<meta name="fuzzy" content="maxDifference=0-255; totalPixels=0-1633">
<script src="/common/reftest-wait.js"></script>
<script src="/common/rendering-utils.js"></script>
diff --git a/tests/wpt/tests/css/css-view-transitions/navigation/resources/auto-name-from-id.html b/tests/wpt/tests/css/css-view-transitions/navigation/resources/auto-name-from-id.html
index 71ea52a273e..dc2cf8fd29b 100644
--- a/tests/wpt/tests/css/css-view-transitions/navigation/resources/auto-name-from-id.html
+++ b/tests/wpt/tests/css/css-view-transitions/navigation/resources/auto-name-from-id.html
@@ -29,6 +29,11 @@ html::view-transition-group(*) {
animation-timing-function: steps(2, start);
}
+/* Make test fail if ID matches */
+::view-transition-group(green) {
+ border: 2px solid red;
+}
+
#green {
background: green;
width: 100px;
diff --git a/tests/wpt/tests/css/css-view-transitions/nested/nested-exit.tentative.html b/tests/wpt/tests/css/css-view-transitions/nested/nested-exit.tentative.html
index 83570762061..847058be2b4 100644
--- a/tests/wpt/tests/css/css-view-transitions/nested/nested-exit.tentative.html
+++ b/tests/wpt/tests/css/css-view-transitions/nested/nested-exit.tentative.html
@@ -15,6 +15,10 @@
animation-play-state: paused;
}
+ ::view-transition-group-children(*) {
+ background: inherit;
+ }
+
::view-transition-group(parent) {
background: green;
visibility: hidden;
diff --git a/tests/wpt/tests/css/css-view-transitions/nested/resources/compute-common.css b/tests/wpt/tests/css/css-view-transitions/nested/resources/compute-common.css
index 20337ccce5f..d8f46179b40 100644
--- a/tests/wpt/tests/css/css-view-transitions/nested/resources/compute-common.css
+++ b/tests/wpt/tests/css/css-view-transitions/nested/resources/compute-common.css
@@ -57,6 +57,9 @@ html.no-match::view-transition {
::view-transition-group(green) {
background: green;
}
+::view-transition-group-children(*) {
+ background: inherit;
+}
::view-transition-group(test) {
background: inherit;
}
diff --git a/tests/wpt/tests/css/css-view-transitions/nested/rounded-border-clipper.html b/tests/wpt/tests/css/css-view-transitions/nested/rounded-border-clipper.html
index 239bcdd791d..098e5566585 100644
--- a/tests/wpt/tests/css/css-view-transitions/nested/rounded-border-clipper.html
+++ b/tests/wpt/tests/css/css-view-transitions/nested/rounded-border-clipper.html
@@ -33,6 +33,9 @@
::view-transition-group(clipper) {
animation-play-state: paused;
+}
+
+::view-transition-group-children(clipper) {
overflow: clip;
border-radius: 20px;
}
diff --git a/tests/wpt/tests/css/css-view-transitions/new-content-captures-different-size.html b/tests/wpt/tests/css/css-view-transitions/new-content-captures-different-size.html
index eeb7347981d..0a754c651ff 100644
--- a/tests/wpt/tests/css/css-view-transitions/new-content-captures-different-size.html
+++ b/tests/wpt/tests/css/css-view-transitions/new-content-captures-different-size.html
@@ -5,7 +5,7 @@
<link rel="help" href="https://drafts.csswg.org/css-view-transitions-1/">
<link rel="author" href="mailto:vmpstr@chromium.org">
<link rel="match" href="new-content-captures-different-size-ref.html">
-<meta name=fuzzy content="maxDifference=0-100; totalPixels=0-15000">
+<meta name=fuzzy content="maxDifference=0-100; totalPixels=0-15393">
<script src="/common/reftest-wait.js"></script>
<style>
html {
diff --git a/tests/wpt/tests/css/css-view-transitions/pseudo-with-classes-view-transition-group.html b/tests/wpt/tests/css/css-view-transitions/pseudo-with-classes-view-transition-group.html
index f9fe2022258..14717728b15 100644
--- a/tests/wpt/tests/css/css-view-transitions/pseudo-with-classes-view-transition-group.html
+++ b/tests/wpt/tests/css/css-view-transitions/pseudo-with-classes-view-transition-group.html
@@ -17,7 +17,10 @@
view-transition-class: cls;
}
-:root::view-transition-group(*) {
+:root::view-transition-group(*),
+:root::view-transition-image-pair(*),
+:root::view-transition-new(*),
+:root::view-transition-old(*) {
animation-play-state: paused;
}
diff --git a/tests/wpt/tests/css/css-view-transitions/scoped/crashtests/participating-scope.html b/tests/wpt/tests/css/css-view-transitions/scoped/crashtests/participating-scope.html
new file mode 100644
index 00000000000..26979e58458
--- /dev/null
+++ b/tests/wpt/tests/css/css-view-transitions/scoped/crashtests/participating-scope.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<html class="test-wait">
+<head>
+<style>
+body { margin: 5px; }
+#scope { contain: strict; position: relative; z-index: 0;
+ width: 150px; height: 100px; border: 5px solid #ccc;
+ view-transition-name: container; }
+.item { width: 6rem; height: 4rem; margin: 10px; background: #def;
+ view-transition-name: a1; contain: strict; }
+::view-transition-group(*),
+::view-transition-old(*),
+::view-transition-new(*) { animation: unset; }
+</style>
+</head>
+<body>
+<div id="scope"><div class="item"></div></div>
+<script>
+onload = async () => {
+ await scope.startViewTransition().finished;
+ document.documentElement.classList.remove('test-wait');
+}
+</script>
+</body>
+</html>
diff --git a/tests/wpt/tests/css/css-view-transitions/scoped/nested-scope-ref.html b/tests/wpt/tests/css/css-view-transitions/scoped/nested-scope-ref.html
index 804741cd6db..951c0928687 100644
--- a/tests/wpt/tests/css/css-view-transitions/scoped/nested-scope-ref.html
+++ b/tests/wpt/tests/css/css-view-transitions/scoped/nested-scope-ref.html
@@ -4,7 +4,7 @@
<style>
.box { position: relative; contain: strict; }
-#scopeA { background: #ddd;
+#scopeA { background: #ccc;
left: 0; top: 0; width: 300px; height: 300px; }
#partA { background: #4af;
left: 30px; top: 30px; width: 240px; height: 240px; }
diff --git a/tests/wpt/tests/css/css-view-transitions/scoped/nested-scope.html b/tests/wpt/tests/css/css-view-transitions/scoped/nested-scope.html
index 9fff44e5e73..b9cc25c3338 100644
--- a/tests/wpt/tests/css/css-view-transitions/scoped/nested-scope.html
+++ b/tests/wpt/tests/css/css-view-transitions/scoped/nested-scope.html
@@ -36,11 +36,22 @@
failIfNot(scopeA.startViewTransition, "Missing element.startViewTransition");
+// This test runs simultaneous transitions on two scopes, one inside the other.
+// It verifies that the inner and outer participants are both visible while both
+// transitions are in progress. (This entails rendering the inner transition
+// through the ::view-transition-new for the outer participant.)
async function runTest() {
await waitForCompositorReady();
await scopeB.startViewTransition().ready;
+
+ // Untag partB to avoid a collision when the outer transition looks for its
+ // participants. (We can stop doing this once we have contain: view-transition
+ // or similar.)
partB.classList.remove("tr");
- await scopeA.startViewTransition().ready;
+
+ await scopeA.startViewTransition(() => {
+ scopeA.style.background = "#ccc";
+ }).ready;
requestAnimationFrame(takeScreenshot);
}
onload = () => runTest();
diff --git a/tests/wpt/tests/css/css-viewport/zoom/height.html b/tests/wpt/tests/css/css-viewport/zoom/height.html
new file mode 100644
index 00000000000..f608765bcf1
--- /dev/null
+++ b/tests/wpt/tests/css/css-viewport/zoom/height.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<title>height:inherit applies zoom</title>
+<link rel="help" href="https://drafts.csswg.org/css-viewport/">
+<link rel="match" href="green-square-100px.html">
+<style>
+ div > div {
+ background-color: green;
+ }
+</style>
+<div style="height:50px">
+ <div style="zoom:2; width:50px; height:inherit;"></div>
+</div>
diff --git a/tests/wpt/tests/css/css-viewport/zoom/inherited-length.html b/tests/wpt/tests/css/css-viewport/zoom/inherited-length.html
index d83111a4352..571b533d5d6 100644
--- a/tests/wpt/tests/css/css-viewport/zoom/inherited-length.html
+++ b/tests/wpt/tests/css/css-viewport/zoom/inherited-length.html
@@ -10,6 +10,6 @@ div {
background-color: green;
}
</style>
-<div style="width: 100px; height: 100px;">
- <div style="zoom: 2; width: inherit;"></div>
+<div style="width: 50px; height: 50px;">
+ <div style="zoom: 2; width: inherit; height: inherit;"></div>
</div>
diff --git a/tests/wpt/tests/css/css-viewport/zoom/length-implicit-and-explicit-inheritance.html b/tests/wpt/tests/css/css-viewport/zoom/length-implicit-and-explicit-inheritance.html
new file mode 100644
index 00000000000..003c7b61c09
--- /dev/null
+++ b/tests/wpt/tests/css/css-viewport/zoom/length-implicit-and-explicit-inheritance.html
@@ -0,0 +1,38 @@
+<!doctype html>
+<meta charset="utf-8">
+<link rel="author" href="mailto:emilio@crisal.io" title="Emilio Cobos Álvarez">
+<link rel="author" href="https://mozilla.org" title="Mozilla">
+<link rel="help" href="https://drafts.csswg.org/css-viewport/#zoom-property">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div style="zoom: 2">
+ <div style="zoom: 2" id="parent">
+ <!-- effective zoom of 8, inherited zoom (4) times specified zoom (2) -->
+ <div style="zoom: 2" id="target"></div>
+ </div>
+</div>
+<script>
+ const kTestCases = [
+ // Explicitly inherited reset properties.
+ ["width", "100px", "inherit", "100px"],
+ ["height", "100px", "inherit", "100px"],
+ // Explicitly inherited properties.
+ ["word-spacing", "100px", "inherit", "100px"],
+ ["word-spacing", "100px", "unset", "100px"],
+ // Implicitly inherited properties.
+ ["word-spacing", "100px", "", "100px"],
+ ];
+
+ const parent = document.getElementById("parent");
+ const target = document.getElementById("target");
+ for (const [prop, parentValue, childValue, expected] of kTestCases) {
+ test(function(t) {
+ parent.style[prop] = parentValue;
+ target.style[prop] = childValue;
+ t.add_cleanup(function() {
+ parent.style[prop] = target.style[prop] = "";
+ });
+ assert_equals(getComputedStyle(target).getPropertyValue(prop), expected);
+ }, `${prop}: ${childValue} from ${parentValue}`);
+ }
+</script>
diff --git a/tests/wpt/tests/css/css-viewport/zoom/max-height.html b/tests/wpt/tests/css/css-viewport/zoom/max-height.html
new file mode 100644
index 00000000000..6a0dcd826e2
--- /dev/null
+++ b/tests/wpt/tests/css/css-viewport/zoom/max-height.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<title>max-height:inherit applies zoom</title>
+<link rel="help" href="https://drafts.csswg.org/css-viewport/">
+<link rel="match" href="green-square-100px.html">
+<style>
+ div > div {
+ background-color: green;
+ }
+</style>
+<div style="max-height:50px">
+ <div style="zoom:2; width:50px; height:200px; max-height:inherit;"></div>
+</div>
diff --git a/tests/wpt/tests/css/css-viewport/zoom/max-width.html b/tests/wpt/tests/css/css-viewport/zoom/max-width.html
new file mode 100644
index 00000000000..b6d4139e30a
--- /dev/null
+++ b/tests/wpt/tests/css/css-viewport/zoom/max-width.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<title>max-width:inherit applies zoom</title>
+<link rel="help" href="https://drafts.csswg.org/css-viewport/">
+<link rel="match" href="green-square-100px.html">
+<style>
+ div > div {
+ background-color: green;
+ }
+</style>
+<div style="max-width:50px">
+ <div style="zoom:2; max-width:inherit; height:50px; width:300px;"></div>
+</div>
diff --git a/tests/wpt/tests/css/css-viewport/zoom/min-height.html b/tests/wpt/tests/css/css-viewport/zoom/min-height.html
new file mode 100644
index 00000000000..31a47d92b21
--- /dev/null
+++ b/tests/wpt/tests/css/css-viewport/zoom/min-height.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<title>min-height:inherit applies zoom</title>
+<link rel="help" href="https://drafts.csswg.org/css-viewport/">
+<link rel="match" href="green-square-100px.html">
+<style>
+ div > div {
+ background-color: green;
+ }
+</style>
+<div style="min-height:50px">
+ <div style="zoom:2; width:50px; min-height:inherit;"></div>
+</div>
diff --git a/tests/wpt/tests/css/css-viewport/zoom/min-width.html b/tests/wpt/tests/css/css-viewport/zoom/min-width.html
new file mode 100644
index 00000000000..bd1cda23d3a
--- /dev/null
+++ b/tests/wpt/tests/css/css-viewport/zoom/min-width.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<title>min-width:inherit applies zoom</title>
+<link rel="help" href="https://drafts.csswg.org/css-viewport/">
+<link rel="match" href="green-square-100px.html">
+<style>
+ div > div {
+ background-color: green;
+ }
+</style>
+<div style="min-width:50px">
+ <div style="zoom:2; min-width:inherit; height:50px; width:0px"></div>
+</div>
diff --git a/tests/wpt/tests/css/css-writing-modes/orthogonal-cell-001-ref.html b/tests/wpt/tests/css/css-writing-modes/orthogonal-cell-001-ref.html
new file mode 100644
index 00000000000..f50121ef16d
--- /dev/null
+++ b/tests/wpt/tests/css/css-writing-modes/orthogonal-cell-001-ref.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+
+<title>CSS writing-mode reference</title>
+
+<style>
+table { margin: 10px; }
+td { background: green; padding: 10px 20px 30px 40px; }
+div { width: 20px; height: 40px; background: blue; }
+</style>
+
+<p>All five green squares should look the same, with a blue rectangle towards the upper right.</p>
+
+<table>
+ <td><div></div></td>
+</table>
+
+<table>
+ <td><div></div></td>
+</table>
+
+<table>
+ <td><div></div></td>
+</table>
+
+<table>
+ <td><div></div></td>
+</table>
+
+<table>
+ <td><div></div></td>
+</table>
diff --git a/tests/wpt/tests/css/css-writing-modes/orthogonal-cell-001.html b/tests/wpt/tests/css/css-writing-modes/orthogonal-cell-001.html
new file mode 100644
index 00000000000..12e996ac902
--- /dev/null
+++ b/tests/wpt/tests/css/css-writing-modes/orthogonal-cell-001.html
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+
+<title>CSS writing-mode test: orthogonal table cells</title>
+<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1959395">
+<link rel="match" href="orthogonal-cell-001-ref.html">
+
+<style>
+table { margin: 10px; }
+td { background: green; padding: 10px 20px 30px 40px; }
+div { width: 20px; height: 40px; background: blue; }
+.htb { writing-mode: horizontal-tb; }
+.vlr { writing-mode: vertical-lr; }
+.vrl { writing-mode: vertical-rl; }
+</style>
+
+<p>All five green squares should look the same, with a blue rectangle towards the upper right.</p>
+
+<table>
+ <td><div></div></td>
+</table>
+
+<!-- The different writing modes should not disrupt the table cell/row sizing. -->
+<table class=htb>
+ <td class=vlr><div></div></td>
+</table>
+
+<table class=htb>
+ <td class=vrl><div></div></td>
+</table>
+
+<table class=vlr>
+ <td class=htb><div></div></td>
+</table>
+
+<table class=vrl>
+ <td class=htb><div></div></td>
+</table>
diff --git a/tests/wpt/tests/css/motion/animation/offset-path-interpolation-008.html b/tests/wpt/tests/css/motion/animation/offset-path-interpolation-008.html
index 5fb7c7c333c..ff7d4a108c7 100644
--- a/tests/wpt/tests/css/motion/animation/offset-path-interpolation-008.html
+++ b/tests/wpt/tests/css/motion/animation/offset-path-interpolation-008.html
@@ -132,15 +132,15 @@
test_interpolation({
property: 'offset-path',
- from: 'shape(from 5% 5px, arc to 15% -15px of 10px 20px, arc by 15% -5px of 30px cw rotate 30deg large, arc to 25% 20px of 10px 5px small)',
- to: 'shape(from 15% 15px, arc to 5% -25px of 20px 30px, arc by 25% -15px of 20px cw rotate 270deg small, arc to 25% 20px of 10px 5px small cw)'
+ from: 'shape(from 5% 5px, arc to 15% -15px of 10px 20px, arc by 15% -5px of 30px 30px cw rotate 30deg large, arc to 25% 20px of 10px 5px small)',
+ to: 'shape(from 15% 15px, arc to 5% -25px of 20px 30px, arc by 25% -15px of 20px 20px cw rotate 270deg small, arc to 25% 20px of 10px 5px small cw)'
}, [
{at: -0.3, expect: 'shape(from 2% 2px, arc to 18% -12px of 7px 17px ccw small, arc by 12% -2px of 33px 33px rotate -42deg cw large , arc to 25% 20px of 10px 5px ccw small)'},
- {at: 0, expect: 'shape(from 5% 5px, arc to 15% -15px of 10px 20px, arc by 15% -5px of 30px cw rotate 30deg large, arc to 25% 20px of 10px 5px small)'},
+ {at: 0, expect: 'shape(from 5% 5px, arc to 15% -15px of 10px 20px, arc by 15% -5px of 30px 30px cw rotate 30deg large, arc to 25% 20px of 10px 5px small)'},
{at: 0.3, expect: 'shape(from 8% 8px, arc to 12% -18px of 13px 23px ccw small, arc by 18% -8px of 27px 27px rotate 102deg cw large, arc to 25% 20px of 10px 5px cw small )'},
- {at: 0.5, expect: 'shape(from 10% 10px, arc to 10% -20px of 15px 25px ccw small, arc by 20% -10px of 25px rotate 150deg cw large, arc to 25% 20px of 10px 5px cw small)'},
- {at: 1, expect: 'shape(from 15% 15px, arc to 5% -25px of 20px 30px, arc by 25% -15px of 20px rotate 270deg cw small, arc to 25% 20px of 10px 5px cw small)'},
- {at: 1.5, expect: 'shape(from 20% 20px, arc to 0% -30px of 25px 35px ccw small, arc by 30% -20px of 15px rotate 390deg cw small, arc to 25% 20px of 10px 5px cw small)'},
+ {at: 0.5, expect: 'shape(from 10% 10px, arc to 10% -20px of 15px 25px ccw small, arc by 20% -10px of 25px 25px rotate 150deg cw large, arc to 25% 20px of 10px 5px cw small)'},
+ {at: 1, expect: 'shape(from 15% 15px, arc to 5% -25px of 20px 30px, arc by 25% -15px of 20px 20px rotate 270deg cw small, arc to 25% 20px of 10px 5px cw small)'},
+ {at: 1.5, expect: 'shape(from 20% 20px, arc to 0% -30px of 25px 35px ccw small, arc by 30% -20px of 15px 15px rotate 390deg cw small, arc to 25% 20px of 10px 5px cw small)'},
]);
test_interpolation({
@@ -235,28 +235,28 @@
test_interpolation({
property: 'offset-path',
- from: 'shape(from 5% 5px, arc to 15% -15px of 10px 20px, arc by 15% -5px of 30px cw rotate 30deg large, arc to 25% 20px of 10px 5px small)',
+ from: 'shape(from 5% 5px, arc to 15% -15px of 10px 20px, arc by 15% -5px of 30px 30px cw rotate 30deg large, arc to 25% 20px of 10px 5px small)',
to: 'path("M 15 15 A 20,30 0 0,0 5,-25 a 20,20 270 0,1 25,-15 A 10,5 0 0,0 25 20")',
}, [
- {at: -0.3, expect: 'shape(from calc(6.5% - 4.5px) 2px, arc to calc(19.5% - 1.5px) -12px of 7px 17px, arc by calc(19.5% - 7.5px) -2px of 33px cw large rotate -42deg, arc to calc(32.5% - 7.5px) 20px of 10px 5px)'},
- {at: 0, expect: 'shape(from 5% 5px, arc to 15% -15px of 10px 20px, arc by 15% -5px of 30px cw rotate 30deg large, arc to 25% 20px of 10px 5px small)'},
- {at: 0.3, expect: 'shape(from calc(3.5% + 4.5px) 8px, arc to calc(10.5% + 1.5px) -18px of 13px 23px, arc by calc(10.5% + 7.5px) -8px of 27px cw large rotate 102deg, arc to calc(17.5% + 7.5px) 20px of 10px 5px)'},
- {at: 0.5, expect: 'shape(from calc(2.5% + 7.5px) 10px, arc to calc(7.5% + 2.5px) -20px of 15px 25px, arc by calc(7.5% + 12.5px) -10px of 25px cw large rotate 150deg, arc to calc(12.5% + 12.5px) 20px of 10px 5px)'},
- {at: 1, expect: 'shape(from calc(0% + 15px) 15px, arc to calc(0% + 5px) -25px of 20px 30px, arc by calc(0% + 25px) -15px of 20px cw rotate 270deg, arc to calc(0% + 25px) 20px of 10px 5px)'},
- {at: 1.5, expect: 'shape(from calc(-2.5% + 22.5px) 20px, arc to calc(-7.5% + 7.5px) -30px of 25px 35px, arc by calc(-7.5% + 37.5px) -20px of 15px cw rotate 390deg, arc to calc(-12.5% + 37.5px) 20px of 10px 5px)'},
+ {at: -0.3, expect: 'shape(from calc(6.5% - 4.5px) 2px, arc to calc(19.5% - 1.5px) -12px of 7px 17px, arc by calc(19.5% - 7.5px) -2px of 33px 33px cw large rotate -42deg, arc to calc(32.5% - 7.5px) 20px of 10px 5px)'},
+ {at: 0, expect: 'shape(from 5% 5px, arc to 15% -15px of 10px 20px, arc by 15% -5px of 30px 30px cw large rotate 30deg, arc to 25% 20px of 10px 5px)'},
+ {at: 0.3, expect: 'shape(from calc(3.5% + 4.5px) 8px, arc to calc(10.5% + 1.5px) -18px of 13px 23px, arc by calc(10.5% + 7.5px) -8px of 27px 27px cw large rotate 102deg, arc to calc(17.5% + 7.5px) 20px of 10px 5px)'},
+ {at: 0.5, expect: 'shape(from calc(2.5% + 7.5px) 10px, arc to calc(7.5% + 2.5px) -20px of 15px 25px, arc by calc(7.5% + 12.5px) -10px of 25px 25px cw large rotate 150deg, arc to calc(12.5% + 12.5px) 20px of 10px 5px)'},
+ {at: 1, expect: 'shape(from calc(0% + 15px) 15px, arc to calc(0% + 5px) -25px of 20px 30px, arc by calc(0% + 25px) -15px of 20px 20px cw rotate 270deg, arc to calc(0% + 25px) 20px of 10px 5px)'},
+ {at: 1.5, expect: 'shape(from calc(-2.5% + 22.5px) 20px, arc to calc(-7.5% + 7.5px) -30px of 25px 35px, arc by calc(-7.5% + 37.5px) -20px of 15px 15px cw rotate 390deg, arc to calc(-12.5% + 37.5px) 20px of 10px 5px)'},
]);
test_interpolation({
property: 'offset-path',
from: 'path("M 5 5 A 10,20 0 0,0 15,-15 a 30,30 30 1,1 15,-5 A 10,5 0 0,0 25 20")',
- to: 'shape(from 15px 15px, arc to 5px -25px of 20px 30px, arc by 25px -15px of 20px cw rotate 270deg small, arc to 25px 20px of 10px 5px small cw)'
+ to: 'shape(from 15px 15px, arc to 5px -25px of 20px 30px, arc by 25px -15px of 20px 20px cw rotate 270deg small, arc to 25px 20px of 10px 5px small cw)'
}, [
- {at: -0.3, expect: 'shape(from 2px 2px, arc to 18px -12px of 7px 17px ccw small, arc by 12px -2px of 33px 33px rotate -42deg cw large, arc to 25px 20px of 10px 5px ccw small)'},
- {at: 0, expect: 'shape(from 5px 5px, arc to 15px -15px of 10px 20px, arc by 15px -5px of 30px cw rotate 30deg large, arc to 25px 20px of 10px 5px small)'},
+ {at: -0.3, expect: 'shape(from 2px 2px, arc to 18px -12px of 7px 17px ccw small, arc by 12px -2px of 33px 33px rotate -42deg cw large, arc to 25px 20px of 10px 5px ccw small)'},
+ {at: 0, expect: 'shape(from 5px 5px, arc to 15px -15px of 10px 20px, arc by 15px -5px of 30px 30px cw rotate 30deg large, arc to 25px 20px of 10px 5px small)'},
{at: 0.3, expect: 'shape(from 8px 8px, arc to 12px -18px of 13px 23px ccw small, arc by 18px -8px of 27px 27px rotate 102deg cw large, arc to 25px 20px of 10px 5px cw small)'},
- {at: 0.5, expect: 'shape(from 10px 10px, arc to 10px -20px of 15px 25px ccw small, arc by 20px -10px of 25px rotate 150deg cw large, arc to 25px 20px of 10px 5px cw small)'},
- {at: 1, expect: 'shape(from 15px 15px, arc to 5px -25px of 20px 30px, arc by 25px -15px of 20px rotate 270deg cw small, arc to 25px 20px of 10px 5px cw small)'},
- {at: 1.5, expect: 'shape(from 20px 20px, arc to 0px -30px of 25px 35px ccw small, arc by 30px -20px of 15px rotate 390deg cw small, arc to 25px 20px of 10px 5px cw small)'},
+ {at: 0.5, expect: 'shape(from 10px 10px, arc to 10px -20px of 15px 25px ccw small, arc by 20px -10px of 25px 25px rotate 150deg cw large, arc to 25px 20px of 10px 5px cw small)'},
+ {at: 1, expect: 'shape(from 15px 15px, arc to 5px -25px of 20px 30px, arc by 25px -15px of 20px 20px rotate 270deg cw small, arc to 25px 20px of 10px 5px cw small)'},
+ {at: 1.5, expect: 'shape(from 20px 20px, arc to 0px -30px of 25px 35px ccw small, arc by 30px -20px of 15px 15px rotate 390deg cw small, arc to 25px 20px of 10px 5px cw small)'},
]);
</script>
diff --git a/tests/wpt/tests/css/motion/parsing/offset-path-shape-computed.html b/tests/wpt/tests/css/motion/parsing/offset-path-shape-computed.html
index c9ecc3acb06..6ced1ad395a 100644
--- a/tests/wpt/tests/css/motion/parsing/offset-path-shape-computed.html
+++ b/tests/wpt/tests/css/motion/parsing/offset-path-shape-computed.html
@@ -27,8 +27,8 @@ test_computed_value("offset-path", "shape(from 10px 10px, curve to 50px 20px wit
test_computed_value("offset-path", "shape(from 10px 10px, curve to 50px 20px with 10rem 1px / 20% 1em)", "shape(from 10px 10px, curve to 50px 20px with 160px 1px / 20% 16px)");
test_computed_value("offset-path", "shape(from 10px 10px, smooth to 50px 20px with 10rem 1%)", "shape(from 10px 10px, smooth to 50px 20px with 160px 1%)");
test_computed_value("offset-path", "shape(from 10px 10px, smooth to 50px 3pt)", "shape(from 10px 10px, smooth to 50px 4px)");
-test_computed_value("offset-path", "shape(from 10px 10px, arc to 50px 3pt of 10px 10px)", "shape(from 10px 10px, arc to 50px 4px of 10px)");
-test_computed_value("offset-path", "shape(from 10px 10px, arc to 50px 3pt of 10px 10px small rotate 0deg)", "shape(from 10px 10px, arc to 50px 4px of 10px)");
+test_computed_value("offset-path", "shape(from 10px 10px, arc to 50px 3pt of 10px 10px)", "shape(from 10px 10px, arc to 50px 4px of 10px 10px)");
+test_computed_value("offset-path", "shape(from 10px 10px, arc to 50px 3pt of 10px small rotate 0deg)", "shape(from 10px 10px, arc to 50px 4px of 10px)");
test_computed_value("offset-path", "shape(from 10% 1rem, arc to 50px 3pt of 20% cw large rotate 25deg)", "shape(from 10% 16px, arc to 50px 4px of 20% cw large rotate 25deg)");
</script>
</body>
diff --git a/tests/wpt/tests/css/motion/parsing/offset-path-shape-parsing.html b/tests/wpt/tests/css/motion/parsing/offset-path-shape-parsing.html
index 013cea2c821..4a3d9f16915 100644
--- a/tests/wpt/tests/css/motion/parsing/offset-path-shape-parsing.html
+++ b/tests/wpt/tests/css/motion/parsing/offset-path-shape-parsing.html
@@ -28,8 +28,8 @@ test_valid_value("offset-path", "shape(from 10px 10px, curve to 50px 20px with 1
test_valid_value("offset-path", "shape(from 10px 10px, curve by 50px 20px with 10rem 1px / 20vh 1ch)");
test_valid_value("offset-path", "shape(from 10px 10px, smooth to 50px 20px with 10rem 1%)");
test_valid_value("offset-path", "shape(from 10px 10px, smooth to 50px 1pt)");
-test_valid_value("offset-path", "shape(from 10px 10px, arc to 50px 1pt of 10px 10px)", "shape(from 10px 10px, arc to 50px 1pt of 10px)");
-test_valid_value("offset-path", "shape(from 10px 10px, arc to 50px 1pt of 10px 10px small rotate 0deg)", "shape(from 10px 10px, arc to 50px 1pt of 10px)");
+test_valid_value("offset-path", "shape(from 10px 10px, arc to 50px 1pt of 10px 10px)", "shape(from 10px 10px, arc to 50px 1pt of 10px 10px)");
+test_valid_value("offset-path", "shape(from 10px 10px, arc to 50px 1pt of 10px 10px small rotate 0deg)", "shape(from 10px 10px, arc to 50px 1pt of 10px 10px)");
test_valid_value("offset-path", "shape(from 10% 1rem, arc to 50px 1pt of 20% cw large rotate 25deg)", "shape(from 10% 1rem, arc to 50px 1pt of 20% cw large rotate 25deg)");
test_valid_value("offset-path", "shape(evenodd from 0px 0px, line to 10px 10px)");
test_valid_value("offset-path", "shape(nonzero from 0px 0px, line to 10px 10px)", "shape(from 0px 0px, line to 10px 10px)");
diff --git a/tests/wpt/tests/css/visited-nested-ref.html b/tests/wpt/tests/css/selectors/visited-nested-ref.html
index 22f4ecf0d7b..22f4ecf0d7b 100644
--- a/tests/wpt/tests/css/visited-nested-ref.html
+++ b/tests/wpt/tests/css/selectors/visited-nested-ref.html
diff --git a/tests/wpt/tests/css/visited-nested.html b/tests/wpt/tests/css/selectors/visited-nested.html
index 57220446c86..57220446c86 100644
--- a/tests/wpt/tests/css/visited-nested.html
+++ b/tests/wpt/tests/css/selectors/visited-nested.html
diff --git a/tests/wpt/tests/domxpath/fn-id.html b/tests/wpt/tests/domxpath/fn-id.html
new file mode 100644
index 00000000000..617ff7216d8
--- /dev/null
+++ b/tests/wpt/tests/domxpath/fn-id.html
@@ -0,0 +1,47 @@
+<!DOCTYPE html>
+<link rel="help" href="https://www.w3.org/TR/1999/REC-xpath-19991116/#function-id">
+<body>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+// Test the id() function with various scenarios
+function testIdFunction(expression, xmlString, expectedIds) {
+ let doc = (new DOMParser()).parseFromString(xmlString, 'text/xml');
+ test(() => {
+ let result = doc.evaluate(expression, doc.documentElement, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
+ assert_equals(result.resultType, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE);
+ let actualIds = [];
+ for (let i = 0; i < result.snapshotLength; i++) {
+ actualIds.push(result.snapshotItem(i).getAttribute('id'));
+ }
+ actualIds.sort();
+ expectedIds.sort();
+ assert_array_equals(actualIds, expectedIds, `Expected IDs ${expectedIds}, got ${actualIds}`);
+ }, `${expression}: ${doc.documentElement.outerHTML}`);
+}
+
+// Test single ID
+testIdFunction('id("test1")', '<root><div id="test1">Match</div></root>', ['test1']);
+
+// Test multiple IDs in space-separated string
+testIdFunction('id("test1 test2")', '<root><div id="test1">First</div><div id="test2">Second</div></root>', ['test1', 'test2']);
+
+// Test non-existent ID
+testIdFunction('id("nonexistent")', '<root><div id="test1">No match</div></root>', []);
+
+// Test mixed case IDs (should be case-sensitive)
+testIdFunction('id("Test1")', '<root><div id="test1">No match</div></root>', []);
+
+// Test multiple elements with same ID (should return all)
+testIdFunction('id("duplicate")', '<root><div id="duplicate">First</div><div id="duplicate">Second</div></root>', ['duplicate', 'duplicate']);
+
+// Test IDs with special characters
+testIdFunction('id("test-1")', '<root><div id="test-1">Match</div></root>', ['test-1']);
+
+// Test empty ID string
+testIdFunction('id("")', '<root><div id="">Empty ID</div></root>', []);
+
+// Test whitespace in ID string
+testIdFunction('id(" test1 ")', '<root><div id="test1">Match</div></root>', ['test1']);
+</script>
+</body>
diff --git a/tests/wpt/tests/editing/crashtests/indent-outdent-after-closing-editable-dialog-element.html b/tests/wpt/tests/editing/crashtests/indent-outdent-after-closing-editable-dialog-element.html
deleted file mode 100644
index 7f73de048d7..00000000000
--- a/tests/wpt/tests/editing/crashtests/indent-outdent-after-closing-editable-dialog-element.html
+++ /dev/null
@@ -1,31 +0,0 @@
-<html class="reftest-wait">
-<script>
-var eventCount = 0;
-document.addEventListener("DOMContentLoaded", () => {
- const dialog = document.querySelector("dialog");
- const object = document.createElement("object");
- object.addEventListener("DOMSubtreeModified", () => {
- dialog.show();
- dialog.focus();
- document.execCommand("selectAll");
- dialog.close();
- setTimeout(() => {
- document.execCommand("selectAll");
- document.execCommand("strikeThrough");
- document.execCommand("indent");
- document.execCommand("outdent");
- eventCount--;
- if (!eventCount) {
- document.documentElement.removeAttribute("class");
- }
- });
- eventCount++;
- });
- object.setAttribute("role", "x"); // Run DOMSubtreeModified
- object.setAttribute("role", "y"); // Run DOMSubtreeModified
- document.execCommand("forwardDelete");
- document.execCommand("justifyRight");
-})
-</script>
-<dialog id="a" contenteditable="true">a</dialog>
-</html> \ No newline at end of file
diff --git a/tests/wpt/tests/editing/other/move-inserted-node-from-DOMNodeInserted-during-exec-command-insertHTML.html b/tests/wpt/tests/editing/other/move-inserted-node-from-DOMNodeInserted-during-exec-command-insertHTML.html
deleted file mode 100644
index 41e012a62e9..00000000000
--- a/tests/wpt/tests/editing/other/move-inserted-node-from-DOMNodeInserted-during-exec-command-insertHTML.html
+++ /dev/null
@@ -1,27 +0,0 @@
-<!doctype html>
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<div contenteditable>
-<p id="p1"><br></p>
-<p id="p2"></p>
-</div>
-<script>
-"use strict";
-let editor = document.querySelector("[contenteditable]");
-let p1 = document.getElementById("p1");
-let p2 = document.getElementById("p2");
-p1.addEventListener("DOMNodeInserted", event => {
- if (event.target.localName === "i") {
- p2.appendChild(event.target);
- }
-});
-document.getSelection().collapse(p1, 0);
-document.execCommand("insertHTML", false,
- "<b>bold1</b><i>italic1</i><b>bold2</b><i>italic2</i>");
-test(function () {
- assert_in_array(p1.innerHTML, ["<b>bold1</b><b>bold2</b><br>", "<b>bold1</b><b>bold2</b>"]);
-}, "First <p> element should have only <b> elements");
-test(function () {
- assert_equals(p2.innerHTML, "<i>italic1</i><i>italic2</i>");
-}, "Second <p> element should have only <i> elements");
-</script> \ No newline at end of file
diff --git a/tests/wpt/tests/fetch/content-encoding/br/bad-br-body.https.any.js b/tests/wpt/tests/fetch/content-encoding/br/bad-br-body.https.any.js
index 43ea90a336c..af5df674da6 100644
--- a/tests/wpt/tests/fetch/content-encoding/br/bad-br-body.https.any.js
+++ b/tests/wpt/tests/fetch/content-encoding/br/bad-br-body.https.any.js
@@ -2,6 +2,11 @@
[
"arrayBuffer",
+ "blob",
+ "bytes",
+ "formData",
+ "json",
+ "text"
].forEach(method => {
promise_test(t => {
return fetch("resources/bad-br-body.py").then(res => {
diff --git a/tests/wpt/tests/fetch/content-encoding/gzip/bad-gzip-body.any.js b/tests/wpt/tests/fetch/content-encoding/gzip/bad-gzip-body.any.js
index 17bc1261a3f..77a183f408b 100644
--- a/tests/wpt/tests/fetch/content-encoding/gzip/bad-gzip-body.any.js
+++ b/tests/wpt/tests/fetch/content-encoding/gzip/bad-gzip-body.any.js
@@ -9,6 +9,7 @@ promise_test((test) => {
[
"arrayBuffer",
"blob",
+ "bytes",
"formData",
"json",
"text"
diff --git a/tests/wpt/tests/fetch/content-encoding/zstd/bad-zstd-body.https.any.js b/tests/wpt/tests/fetch/content-encoding/zstd/bad-zstd-body.https.any.js
index 3f32e4dfba7..c59980c2c6f 100644
--- a/tests/wpt/tests/fetch/content-encoding/zstd/bad-zstd-body.https.any.js
+++ b/tests/wpt/tests/fetch/content-encoding/zstd/bad-zstd-body.https.any.js
@@ -9,6 +9,7 @@ promise_test((test) => {
[
"arrayBuffer",
"blob",
+ "bytes",
"formData",
"json",
"text"
diff --git a/tests/wpt/tests/fetch/local-network-access/resources/fetch-private-http.html b/tests/wpt/tests/fetch/local-network-access/resources/fetch-private-http.html
index e372d90b26a..517629b758e 100644
--- a/tests/wpt/tests/fetch/local-network-access/resources/fetch-private-http.html
+++ b/tests/wpt/tests/fetch/local-network-access/resources/fetch-private-http.html
@@ -23,8 +23,7 @@ Promise.resolve().then(async () => {
};
const targetUrl = resolveTargetUrl(target);
- // TODO(crbug.com/406991278): rename address space for LNA spec
- fetch(targetUrl, {targetAddressSpace: 'private'})
+ fetch(targetUrl, {targetAddressSpace: 'local'})
.then(async function(response) {
const body = await response.text();
const message = {
diff --git a/tests/wpt/tests/fetch/local-network-access/resources/fetch-public-http-wrong-address-space.html b/tests/wpt/tests/fetch/local-network-access/resources/fetch-public-http-wrong-address-space.html
index 1d149d00cb3..c15a87ff7b9 100644
--- a/tests/wpt/tests/fetch/local-network-access/resources/fetch-public-http-wrong-address-space.html
+++ b/tests/wpt/tests/fetch/local-network-access/resources/fetch-public-http-wrong-address-space.html
@@ -25,8 +25,7 @@ Promise.resolve().then(async () => {
};
const targetUrl = resolveTargetUrl(target);
- // TODO(crbug.com/406991278): rename address space for LNA spec
- fetch(targetUrl, {targetAddressSpace: 'private'})
+ fetch(targetUrl, {targetAddressSpace: 'local'})
.then(async function(response) {
const body = await response.text();
const message = {
diff --git a/tests/wpt/tests/fetch/private-network-access/mixed-content-fetch.tentative.https.window.js b/tests/wpt/tests/fetch/private-network-access/mixed-content-fetch.tentative.https.window.js
deleted file mode 100644
index dbae5193b5c..00000000000
--- a/tests/wpt/tests/fetch/private-network-access/mixed-content-fetch.tentative.https.window.js
+++ /dev/null
@@ -1,278 +0,0 @@
-// META: script=/common/utils.js
-// META: script=resources/support.sub.js
-// META: timeout=long
-//
-// Spec: https://wicg.github.io/private-network-access
-//
-// These tests verify that secure contexts can fetch non-secure subresources
-// from more private address spaces, avoiding mixed context checks, as long as
-// they specify a valid `targetAddressSpace` fetch option that matches the
-// target server's address space.
-
-setup(() => {
- // Making sure we are in a secure context, as expected.
- assert_true(window.isSecureContext);
-});
-
-// Given `addressSpace`, returns the other three possible IP address spaces.
-function otherAddressSpaces(addressSpace) {
- switch (addressSpace) {
- case "local": return ["unknown", "private", "public"];
- case "private": return ["unknown", "local", "public"];
- case "public": return ["unknown", "local", "private"];
- }
-}
-
-// Generates tests of `targetAddressSpace` for the given (source, target)
-// address space pair, expecting fetches to succeed iff `targetAddressSpace` is
-// correct.
-//
-// Scenarios exercised:
-//
-// - cors mode:
-// - missing targetAddressSpace option
-// - incorrect targetAddressSpace option (x3, see `otherAddressSpaces()`)
-// - failed preflight
-// - success
-// - success with PUT method (non-"simple" request)
-// - no-cors mode:
-// - success
-//
-function makeTests({ source, target }) {
- const sourceServer = Server.get("https", source);
- const targetServer = Server.get("http", target);
-
- const makeTest = ({
- fetchOptions,
- targetBehavior,
- name,
- expected
- }) => {
- promise_test_parallel(t => fetchTest(t, {
- source: { server: sourceServer },
- target: {
- server: targetServer,
- behavior: targetBehavior,
- },
- fetchOptions,
- expected,
- }), `${sourceServer.name} to ${targetServer.name}: ${name}.`);
- };
-
- makeTest({
- name: "missing targetAddressSpace",
- targetBehavior: {
- preflight: PreflightBehavior.success(token()),
- response: ResponseBehavior.allowCrossOrigin(),
- },
- expected: FetchTestResult.FAILURE,
- });
-
- const correctAddressSpace = targetServer.addressSpace;
-
- for (const targetAddressSpace of otherAddressSpaces(correctAddressSpace)) {
- makeTest({
- name: `wrong targetAddressSpace "${targetAddressSpace}"`,
- targetBehavior: {
- preflight: PreflightBehavior.success(token()),
- response: ResponseBehavior.allowCrossOrigin(),
- },
- fetchOptions: { targetAddressSpace },
- expected: FetchTestResult.FAILURE,
- });
- }
-
- makeTest({
- name: "failed preflight",
- targetBehavior: {
- preflight: PreflightBehavior.failure(),
- response: ResponseBehavior.allowCrossOrigin(),
- },
- fetchOptions: { targetAddressSpace: correctAddressSpace },
- expected: FetchTestResult.FAILURE,
- });
-
- makeTest({
- name: "success",
- targetBehavior: {
- preflight: PreflightBehavior.success(token()),
- response: ResponseBehavior.allowCrossOrigin(),
- },
- fetchOptions: { targetAddressSpace: correctAddressSpace },
- expected: FetchTestResult.SUCCESS,
- });
-
- makeTest({
- name: "PUT success",
- targetBehavior: {
- preflight: PreflightBehavior.success(token()),
- response: ResponseBehavior.allowCrossOrigin(),
- },
- fetchOptions: {
- targetAddressSpace: correctAddressSpace,
- method: "PUT",
- },
- expected: FetchTestResult.SUCCESS,
- });
-
- makeTest({
- name: "no-cors success",
- targetBehavior: {
- preflight: PreflightBehavior.success(token()),
- response: ResponseBehavior.allowCrossOrigin(),
- },
- fetchOptions: {
- targetAddressSpace: correctAddressSpace,
- mode: "no-cors",
- },
- expected: FetchTestResult.OPAQUE,
- });
-}
-
-// Generates tests for the given (source, target) address space pair expecting
-// that `targetAddressSpace` cannot be used to bypass mixed content.
-//
-// Scenarios exercised:
-//
-// - wrong `targetAddressSpace` (x3, see `otherAddressSpaces()`)
-// - correct `targetAddressSpace`
-//
-function makeNoBypassTests({ source, target }) {
- const sourceServer = Server.get("https", source);
- const targetServer = Server.get("http", target);
-
- const prefix = `${sourceServer.name} to ${targetServer.name}: `;
-
- const correctAddressSpace = targetServer.addressSpace;
- for (const targetAddressSpace of otherAddressSpaces(correctAddressSpace)) {
- promise_test_parallel(t => fetchTest(t, {
- source: { server: sourceServer },
- target: {
- server: targetServer,
- behavior: {
- preflight: PreflightBehavior.success(token()),
- response: ResponseBehavior.allowCrossOrigin(),
- },
- },
- fetchOptions: { targetAddressSpace },
- expected: FetchTestResult.FAILURE,
- }), prefix + `wrong targetAddressSpace "${targetAddressSpace}".`);
- }
-
- promise_test_parallel(t => fetchTest(t, {
- source: { server: sourceServer },
- target: {
- server: targetServer,
- behavior: {
- preflight: PreflightBehavior.success(token()),
- response: ResponseBehavior.allowCrossOrigin(),
- },
- },
- fetchOptions: { targetAddressSpace: correctAddressSpace },
- expected: FetchTestResult.FAILURE,
- }), prefix + 'not a private network request.');
-}
-
-// Source: local secure context.
-//
-// Fetches to the local and private address spaces cannot use
-// `targetAddressSpace` to bypass mixed content, as they are not otherwise
-// blocked by Private Network Access.
-
-makeNoBypassTests({ source: "local", target: "local" });
-makeNoBypassTests({ source: "local", target: "private" });
-makeNoBypassTests({ source: "local", target: "public" });
-
-// Source: private secure context.
-//
-// Fetches to the local address space requires the right `targetAddressSpace`
-// option, as well as a successful preflight response carrying a PNA-specific
-// header.
-//
-// Fetches to the private address space cannot use `targetAddressSpace` to
-// bypass mixed content, as they are not otherwise blocked by Private Network
-// Access.
-
-makeTests({ source: "private", target: "local" });
-
-makeNoBypassTests({ source: "private", target: "private" });
-makeNoBypassTests({ source: "private", target: "public" });
-
-// Source: public secure context.
-//
-// Fetches to the local and private address spaces require the right
-// `targetAddressSpace` option, as well as a successful preflight response
-// carrying a PNA-specific header.
-
-makeTests({ source: "public", target: "local" });
-makeTests({ source: "public", target: "private" });
-
-makeNoBypassTests({ source: "public", target: "public" });
-
-// These tests verify that documents fetched from the `local` address space yet
-// carrying the `treat-as-public-address` CSP directive are treated as if they
-// had been fetched from the `public` address space.
-
-promise_test_parallel(t => fetchTest(t, {
- source: {
- server: Server.HTTPS_LOCAL,
- treatAsPublic: true,
- },
- target: {
- server: Server.HTTP_LOCAL,
- behavior: {
- preflight: PreflightBehavior.optionalSuccess(token()),
- response: ResponseBehavior.allowCrossOrigin(),
- },
- },
- fetchOptions: { targetAddressSpace: "private" },
- expected: FetchTestResult.FAILURE,
-}), 'https-treat-as-public to http-local: wrong targetAddressSpace "private".');
-
-promise_test_parallel(t => fetchTest(t, {
- source: {
- server: Server.HTTPS_LOCAL,
- treatAsPublic: true,
- },
- target: {
- server: Server.HTTP_LOCAL,
- behavior: {
- preflight: PreflightBehavior.optionalSuccess(token()),
- response: ResponseBehavior.allowCrossOrigin(),
- },
- },
- fetchOptions: { targetAddressSpace: "local" },
- expected: FetchTestResult.SUCCESS,
-}), "https-treat-as-public to http-local: success.");
-
-promise_test_parallel(t => fetchTest(t, {
- source: {
- server: Server.HTTPS_LOCAL,
- treatAsPublic: true,
- },
- target: {
- server: Server.HTTP_PRIVATE,
- behavior: {
- preflight: PreflightBehavior.success(token()),
- response: ResponseBehavior.allowCrossOrigin(),
- },
- },
- fetchOptions: { targetAddressSpace: "local" },
- expected: FetchTestResult.FAILURE,
-}), 'https-treat-as-public to http-private: wrong targetAddressSpace "local".');
-
-promise_test_parallel(t => fetchTest(t, {
- source: {
- server: Server.HTTPS_LOCAL,
- treatAsPublic: true,
- },
- target: {
- server: Server.HTTP_PRIVATE,
- behavior: {
- preflight: PreflightBehavior.success(token()),
- response: ResponseBehavior.allowCrossOrigin(),
- },
- },
- fetchOptions: { targetAddressSpace: "private" },
- expected: FetchTestResult.SUCCESS,
-}), "https-treat-as-public to http-private: success.");
diff --git a/tests/wpt/tests/fetch/private-network-access/window-open-existing.tentative.https.window.js b/tests/wpt/tests/fetch/private-network-access/window-open-existing.tentative.https.window.js
deleted file mode 100644
index 6a2a624fc80..00000000000
--- a/tests/wpt/tests/fetch/private-network-access/window-open-existing.tentative.https.window.js
+++ /dev/null
@@ -1,209 +0,0 @@
-// META: script=/common/subset-tests-by-key.js
-// META: script=/common/dispatcher/dispatcher.js
-// META: script=/common/utils.js
-// META: script=resources/support.sub.js
-// META: timeout=long
-// META: variant=?include=from-local
-// META: variant=?include=from-private
-// META: variant=?include=from-public
-// META: variant=?include=from-treat-as-public
-//
-// These tests verify that secure contexts can navigate to less-public address
-// spaces via window.open to an existing window iff the target server responds
-// affirmatively to preflight requests.
-
-setup(() => {
- assert_true(window.isSecureContext);
-});
-
-// Source: secure local context.
-//
-// All fetches unaffected by Private Network Access.
-
-subsetTestByKey(
- 'from-local', promise_test_parallel,
- t => windowOpenExistingTest(t, {
- source: {server: Server.HTTPS_LOCAL},
- target: {server: Server.HTTPS_LOCAL},
- expected: NavigationTestResult.SUCCESS,
- }),
- 'local to local: no preflight required.');
-
-subsetTestByKey(
- 'from-local', promise_test_parallel,
- t => windowOpenExistingTest(t, {
- source: {server: Server.HTTPS_LOCAL},
- target: {server: Server.HTTPS_PRIVATE},
- expected: NavigationTestResult.SUCCESS,
- }),
- 'local to private: no preflight required.');
-
-subsetTestByKey(
- 'from-local', promise_test_parallel,
- t => windowOpenExistingTest(t, {
- source: {server: Server.HTTPS_LOCAL},
- target: {server: Server.HTTPS_PUBLIC},
- expected: NavigationTestResult.SUCCESS,
- }),
- 'local to public: no preflight required.');
-
-// Generates tests of preflight behavior for a single (source, target) pair.
-//
-// Scenarios:
-//
-// - preflight response has non-2xx HTTP code
-// - preflight response is missing CORS headers
-// - preflight response is missing the PNA-specific `Access-Control` header
-// - success
-//
-function makePreflightTests({
- key,
- sourceName,
- sourceServer,
- sourceTreatAsPublic,
- targetName,
- targetServer,
-}) {
- const prefix =
- `${sourceName} to ${targetName}: `;
-
- const source = {
- server: sourceServer,
- treatAsPublic: sourceTreatAsPublic,
- };
-
- promise_test_parallel(t => windowOpenExistingTest(t, {
- source,
- target: {
- server: targetServer,
- behavior: { preflight: PreflightBehavior.failure() },
- },
- expected: NavigationTestResult.FAILURE,
- }), prefix + "failed preflight.");
-
- promise_test_parallel(t => windowOpenExistingTest(t, {
- source,
- target: {
- server: targetServer,
- behavior: { preflight: PreflightBehavior.noCorsHeader(token()) },
- },
- expected: NavigationTestResult.FAILURE,
- }), prefix + "missing CORS headers.");
-
- promise_test_parallel(t => windowOpenExistingTest(t, {
- source,
- target: {
- server: targetServer,
- behavior: { preflight: PreflightBehavior.noPnaHeader(token()) },
- },
- expected: NavigationTestResult.FAILURE,
- }), prefix + "missing PNA header.");
-
- promise_test_parallel(t => windowOpenExistingTest(t, {
- source,
- target: {
- server: targetServer,
- behavior: { preflight: PreflightBehavior.navigation(token()) },
- },
- expected: NavigationTestResult.SUCCESS,
- }), prefix + "success.");
-}
-
-// Source: private secure context.
-//
-// Navigating to the local address space require a successful preflight response
-// carrying a PNA-specific header.
-
-subsetTestByKey('from-private', makePreflightTests, {
- sourceServer: Server.HTTPS_PRIVATE,
- sourceName: 'private',
- targetServer: Server.HTTPS_LOCAL,
- targetName: 'local',
-});
-
-subsetTestByKey(
- 'from-private', promise_test_parallel,
- t => windowOpenExistingTest(t, {
- source: {server: Server.HTTPS_PRIVATE},
- target: {server: Server.HTTPS_PRIVATE},
- expected: NavigationTestResult.SUCCESS,
- }),
- 'private to private: no preflight required.');
-
-subsetTestByKey(
- 'from-private', promise_test_parallel,
- t => windowOpenExistingTest(t, {
- source: {server: Server.HTTPS_PRIVATE},
- target: {server: Server.HTTPS_PUBLIC},
- expected: NavigationTestResult.SUCCESS,
- }),
- 'private to public: no preflight required.');
-
-// Source: public secure context.
-//
-// Navigating to the local and private address spaces require a successful
-// preflight response carrying a PNA-specific header.
-
-subsetTestByKey('from-public', makePreflightTests, {
- sourceServer: Server.HTTPS_PUBLIC,
- sourceName: "public",
- targetServer: Server.HTTPS_LOCAL,
- targetName: "local",
-});
-
-subsetTestByKey('from-public', makePreflightTests, {
- sourceServer: Server.HTTPS_PUBLIC,
- sourceName: "public",
- targetServer: Server.HTTPS_PRIVATE,
- targetName: "private",
-});
-
-subsetTestByKey(
- 'from-public', promise_test_parallel,
- t => windowOpenExistingTest(t, {
- source: {server: Server.HTTPS_PUBLIC},
- target: {server: Server.HTTPS_PUBLIC},
- expected: NavigationTestResult.SUCCESS,
- }),
- 'public to public: no preflight required.');
-
-// The following tests verify that `CSP: treat-as-public-address` makes
-// documents behave as if they had been served from a public IP address.
-
-subsetTestByKey('from-treat-as-public', makePreflightTests, {
- sourceServer: Server.HTTPS_LOCAL,
- sourceTreatAsPublic: true,
- sourceName: "treat-as-public-address",
- targetServer: Server.OTHER_HTTPS_LOCAL,
- targetName: "local",
-});
-
-subsetTestByKey("from-treat-as-public", promise_test_parallel,
- t => windowOpenExistingTest(t, {
- source: {
- server: Server.HTTPS_LOCAL,
- treatAsPublic: true,
- },
- target: {server: Server.HTTPS_LOCAL},
- expected: NavigationTestResult.SUCCESS,
- }),
- 'treat-as-public-address to local (same-origin): no preflight required.');
-
-subsetTestByKey('from-treat-as-public', makePreflightTests, {
- sourceServer: Server.HTTPS_LOCAL,
- sourceTreatAsPublic: true,
- sourceName: 'treat-as-public-address',
- targetServer: Server.HTTPS_PRIVATE,
- targetName: 'private',
-});
-
-subsetTestByKey("from-treat-as-public", promise_test_parallel,
- t => windowOpenExistingTest(t, {
- source: {
- server: Server.HTTPS_LOCAL,
- treatAsPublic: true,
- },
- target: {server: Server.HTTPS_PUBLIC},
- expected: NavigationTestResult.SUCCESS,
- }),
- 'treat-as-public-address to public: no preflight required.');
diff --git a/tests/wpt/tests/focus/focus-contenteditable-element-in-iframe-scroll-into-view.html b/tests/wpt/tests/focus/focus-contenteditable-element-in-iframe-scroll-into-view.html
new file mode 100644
index 00000000000..1c03382201e
--- /dev/null
+++ b/tests/wpt/tests/focus/focus-contenteditable-element-in-iframe-scroll-into-view.html
@@ -0,0 +1,74 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset=utf-8>
+<meta name="viewport" content="width=device-width,initial-scale=1">
+<title>focus contenteditable element in iframe scroll into view</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<style>
+
+iframe {
+ position: absolute;
+ left: 250vw;
+}
+
+.spacer {
+ width: 100vw;
+ height: 250vh;
+}
+
+</style>
+</head>
+<body>
+ <div id="focusable-1" class="editor" contenteditable="true">focusable 1</div>
+ <div class="spacer"></div>
+ <iframe srcdoc="<div id='focusable-2' contenteditable='true'>focusable 2</div>"></iframe>
+ <div class="spacer"></div>
+</body>
+<script>
+
+function waitForLoad(w) {
+ return new Promise(resolve => w.addEventListener('load', resolve));
+}
+
+function waitForFrame() {
+ return new Promise(resolve => {
+ requestAnimationFrame(() => requestAnimationFrame(() => resolve()));
+ });
+}
+
+promise_test(async (t) => {
+ await waitForLoad(window);
+ const focusable_1 = document.getElementById("focusable-1");
+ const iframeDocument = document.querySelector("iframe").contentDocument;
+ const focusable_2 = iframeDocument.getElementById("focusable-2");
+
+ focusable_1.focus();
+ focusable_2.focus();
+ await waitForFrame();
+ const firstScrollX = window.scrollX;
+ const firstScrollY = window.scrollY;
+
+ assert_greater_than(firstScrollX, window.innerWidth, "scroll X is greater than window.innerWidth");
+ assert_greater_than(firstScrollY, window.innerHeight, "scroll Y is greater than window.innerHeight");
+
+ window.scroll(0, 0);
+ assert_equals(window.scrollX, 0, "scroll X is reset to 0");
+ assert_equals(window.scrollY, 0, "scroll Y is reset to 0");
+
+ focusable_1.focus();
+ focusable_2.focus();
+ await waitForFrame();
+ const secondScrollX = window.scrollX;
+ const secondScrollY = window.scrollY;
+
+ // Ensure that both scroll positions are within +/- 1
+ assert_approx_equals(firstScrollX, secondScrollX, 1.0,
+ "scroll X is within +/- 1 of a element in an iframe");
+ assert_approx_equals(firstScrollY, secondScrollY, 1.0,
+ "scroll Y is within +/- 1 of a element in an iframe");
+}, "Check contenteditable element in an iframe scroll into view on second focusing");
+
+</script>
+</html>
diff --git a/tests/wpt/tests/html/editing/dnd/events/ua-shadow-contents-manual.html b/tests/wpt/tests/html/editing/dnd/events/ua-shadow-contents-manual.html
new file mode 100644
index 00000000000..23908ca9274
--- /dev/null
+++ b/tests/wpt/tests/html/editing/dnd/events/ua-shadow-contents-manual.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<html lang="en">
+<meta charset="utf-8">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<body draggable="true" style="padding:20px">
+Drag this input down quickly. Try multiple times. No errors should be reported.<br>
+<input type=color>
+
+<script>
+document.body.addEventListener('dragenter', (e) => {
+ let target = e.relatedTarget;
+ while (target) {
+ assert_false(target instanceof ShadowRoot,'Drag events should not expose UA shadow roots');
+ // This console log can also cause DevTools crashes, so this is explicitly
+ // left in on purpose:
+ console.log(target);
+ target = target.parentNode;
+ }
+});
+</script>
diff --git a/tests/wpt/tests/html/rendering/non-replaced-elements/the-hr-element-0/size-ref.html b/tests/wpt/tests/html/rendering/non-replaced-elements/the-hr-element-0/size-ref.html
new file mode 100644
index 00000000000..03a21eb4573
--- /dev/null
+++ b/tests/wpt/tests/html/rendering/non-replaced-elements/the-hr-element-0/size-ref.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <style>
+ #foo {
+ height: 50px;
+ box-sizing: border-box;
+ }
+ #bar {
+ border-bottom-width: 0px;
+ box-sizing: border-box;
+ }
+ </style>
+</head>
+<body>
+ <hr id="foo">
+ <hr id="bar">
+</body>
+</html>
+
diff --git a/tests/wpt/tests/html/rendering/non-replaced-elements/the-hr-element-0/size-with-color-or-noshade-ref.html b/tests/wpt/tests/html/rendering/non-replaced-elements/the-hr-element-0/size-with-color-or-noshade-ref.html
new file mode 100644
index 00000000000..d6300e250d9
--- /dev/null
+++ b/tests/wpt/tests/html/rendering/non-replaced-elements/the-hr-element-0/size-with-color-or-noshade-ref.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <style>
+ hr {
+ border-width: 25px;
+ }
+ </style>
+</head>
+<body>
+ <hr color="black">
+ <hr color="totally-not-a-color">
+ <hr noshade>
+ <hr color="black" noshade>
+</body>
+</html>
+
diff --git a/tests/wpt/tests/html/rendering/non-replaced-elements/the-hr-element-0/size-with-color-or-noshade.html b/tests/wpt/tests/html/rendering/non-replaced-elements/the-hr-element-0/size-with-color-or-noshade.html
new file mode 100644
index 00000000000..db1d583934e
--- /dev/null
+++ b/tests/wpt/tests/html/rendering/non-replaced-elements/the-hr-element-0/size-with-color-or-noshade.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<link rel="help" href="https://html.spec.whatwg.org/multipage/rendering.html#the-hr-element-2" />
+<title>hr elements: Tests behaviour of a size attribute with color/noshade attributes present</title>
+<link rel="author" title="Simon Wülker" href="mailto:simon.wuelker@arcor.de">
+<link rel="match" href="/html/rendering/non-replaced-elements/the-hr-element-0/size-with-color-or-noshade-ref.html">
+<meta name="assert" content="This checks that the size attribute of a hr element changes the border widths when color/noshade attributes are present">
+<body>
+ <hr size=50 color="black">
+ <hr size=50 color="totally-not-a-color">
+ <hr size=50 noshade>
+ <hr size=50 color="black" noshade>
+</body>
+</html>
+
diff --git a/tests/wpt/tests/html/rendering/non-replaced-elements/the-hr-element-0/size.html b/tests/wpt/tests/html/rendering/non-replaced-elements/the-hr-element-0/size.html
new file mode 100644
index 00000000000..2162131b853
--- /dev/null
+++ b/tests/wpt/tests/html/rendering/non-replaced-elements/the-hr-element-0/size.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<html>
+<link rel="help" href="https://html.spec.whatwg.org/multipage/rendering.html#the-hr-element-2" />
+<title>hr elements: Tests behaviour of a size attribute without color/noshade attributes</title>
+<link rel="author" title="Simon Wülker" href="mailto:simon.wuelker@arcor.de">
+<link rel="match" href="/html/rendering/non-replaced-elements/the-hr-element-0/size-ref.html">
+<meta name="assert" content="This checks that the size attribute of a hr element changes its height.">
+<body>
+ <hr size=50>
+ <hr size=1>
+</body>
+</html>
+
diff --git a/tests/wpt/tests/html/semantics/embedded-content/the-img-element/decode/image-decode-path-changes-svg.tentative.html b/tests/wpt/tests/html/semantics/embedded-content/the-img-element/decode/image-decode-path-changes-svg.tentative.html
index 1bc53a1f18e..3ef59c37a85 100644
--- a/tests/wpt/tests/html/semantics/embedded-content/the-img-element/decode/image-decode-path-changes-svg.tentative.html
+++ b/tests/wpt/tests/html/semantics/embedded-content/the-img-element/decode/image-decode-path-changes-svg.tentative.html
@@ -13,25 +13,25 @@
// -------------------
promise_test(function(t) {
var img = document.createElementNS('http://www.w3.org/2000/svg', 'image');
- img.setAttributeNS('http://www.w3.org/1999/xlink', 'xlink:href', "/images/green.png");
+ img.setAttributeNS('http://www.w3.org/1999/xlink', 'xlink:href', "/images/green.png?image-decode-path-changes-1");
var promise = img.decode();
- img.setAttributeNS('http://www.w3.org/1999/xlink', 'xlink:href', "/images/green.svg");
+ img.setAttributeNS('http://www.w3.org/1999/xlink', 'xlink:href', "/images/green.svg?image-decode-path-changes-1");
return promise_rejects_dom(t, "EncodingError", promise);
}, document.title + " xlink:href changes fail decode.");
promise_test(function(t) {
var img = document.createElementNS('http://www.w3.org/2000/svg', 'image');
- img.setAttribute('href', "/images/green.png");
+ img.setAttribute('href', "/images/green.png?image-decode-path-changes-2");
var promise = img.decode();
- img.setAttribute('href', "/images/green.svg");
+ img.setAttribute('href', "/images/green.svg?image-decode-path-changes-2");
return promise_rejects_dom(t, "EncodingError", promise);
}, document.title + " href changes fail decode.");
promise_test(function(t) {
var img = document.createElementNS('http://www.w3.org/2000/svg', 'image');
- img.setAttributeNS('http://www.w3.org/1999/xlink', 'xlink:href', "/images/green.png");
+ img.setAttributeNS('http://www.w3.org/1999/xlink', 'xlink:href', "/images/green.png?image-decode-path-changes-3");
var first_promise = img.decode();
- img.setAttributeNS('http://www.w3.org/1999/xlink', 'xlink:href', "/images/green.svg");
+ img.setAttributeNS('http://www.w3.org/1999/xlink', 'xlink:href', "/images/green.svg?image-decode-path-changes-3");
var second_promise = img.decode();
assert_not_equals(first_promise, second_promise);
return Promise.all([
@@ -42,9 +42,9 @@ promise_test(function(t) {
promise_test(function(t) {
var img = document.createElementNS('http://www.w3.org/2000/svg', 'image');
- img.setAttribute('href', "/images/green.png");
+ img.setAttribute('href', "/images/green.png?image-decode-path-changes-4");
var first_promise = img.decode();
- img.setAttribute('href', "/images/green.svg");
+ img.setAttribute('href', "/images/green.svg?image-decode-path-changes-4");
var second_promise = img.decode();
assert_not_equals(first_promise, second_promise);
return Promise.all([
@@ -55,9 +55,9 @@ promise_test(function(t) {
promise_test(function(t) {
var img = document.createElementNS('http://www.w3.org/2000/svg', 'image');
- img.setAttributeNS('http://www.w3.org/1999/xlink', 'xlink:href', "/images/green.png");
+ img.setAttributeNS('http://www.w3.org/1999/xlink', 'xlink:href', "/images/green.png?image-decode-path-changes-5");
var first_promise = img.decode();
- img.setAttributeNS('http://www.w3.org/1999/xlink', 'xlink:href', "/non/existent/path.png");
+ img.setAttributeNS('http://www.w3.org/1999/xlink', 'xlink:href', "/non/existent/path.png?image-decode-path-changes-5");
var second_promise = img.decode();
assert_not_equals(first_promise, second_promise);
return Promise.all([
@@ -68,9 +68,9 @@ promise_test(function(t) {
promise_test(function(t) {
var img = document.createElementNS('http://www.w3.org/2000/svg', 'image');
- img.setAttribute('href', "/images/green.png");
+ img.setAttribute('href', "/images/green.png?image-decode-path-changes-6");
var first_promise = img.decode();
- img.setAttribute('href', "/non/existent/path.png");
+ img.setAttribute('href', "/non/existent/path.png?image-decode-path-changes-6");
var second_promise = img.decode();
assert_not_equals(first_promise, second_promise);
return Promise.all([
diff --git a/tests/wpt/tests/html/semantics/embedded-content/the-img-element/decode/image-decode-with-quick-attach-svg.tentative.html b/tests/wpt/tests/html/semantics/embedded-content/the-img-element/decode/image-decode-with-quick-attach-svg.tentative.html
index 0fc49e60360..fbc7143ecee 100644
--- a/tests/wpt/tests/html/semantics/embedded-content/the-img-element/decode/image-decode-with-quick-attach-svg.tentative.html
+++ b/tests/wpt/tests/html/semantics/embedded-content/the-img-element/decode/image-decode-with-quick-attach-svg.tentative.html
@@ -9,9 +9,11 @@
<script>
"use strict";
+let png = "/images/green.png?image-decode-with-quick-attach-" + Math.random();
+
promise_test(function() {
var img = document.createElementNS('http://www.w3.org/2000/svg', 'image');
- img.setAttributeNS('http://www.w3.org/1999/xlink', 'xlink:href', "/images/green.png");
+ img.setAttributeNS('http://www.w3.org/1999/xlink', 'xlink:href', png);
const promise = img.decode().then(function(arg) {
assert_equals(arg, undefined);
});
diff --git a/tests/wpt/tests/html/semantics/embedded-content/the-img-element/naturalWidth-naturalHeight-unavailable.tentative.html b/tests/wpt/tests/html/semantics/embedded-content/the-img-element/naturalWidth-naturalHeight-unavailable.tentative.html
index df9eb374b5a..ae6fa0e4328 100644
--- a/tests/wpt/tests/html/semantics/embedded-content/the-img-element/naturalWidth-naturalHeight-unavailable.tentative.html
+++ b/tests/wpt/tests/html/semantics/embedded-content/the-img-element/naturalWidth-naturalHeight-unavailable.tentative.html
@@ -1,4 +1,5 @@
<!doctype html>
+<head>
<meta charset="utf-8">
<title>HTMLImageElement naturalWidth/naturalHeight behavior for SVG that lacks at least one natural dimension</title>
<!-- Note: this test asserts a different expectation from what the HTML spec
@@ -6,7 +7,11 @@
behavior doesn't appear to be web-compatible for some of the cases here,
and issue https://github.com/whatwg/html/issues/11287 is filed on
addresing that. In the meantime, this test is named with ".tentative" to
- indicate that it's not authoritative. -->
+ indicate that it's not authoritative. After the spec change is accepted,
+ we can remove the neighboring naturalWidth-naturalHeight.html test which
+ asserts the prior spec text's expectations, since this test covers the
+ same ground but with its expectations set according to the
+ soon-to-be-updated spec text. -->
<link rel="help" href="https://github.com/whatwg/html/issues/11287">
<link rel="help" href="https://html.spec.whatwg.org/multipage/embedded-content.html#dom-img-naturalwidth-dev">
<link rel="help" href="https://html.spec.whatwg.org/multipage/embedded-content.html#dom-img-width">
@@ -15,7 +20,7 @@
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<style>
-.scroller {
+#scroller {
/* We wrap all the test content in a scroller so that it doesn't push
* the textual test-results too far out of view.
*/
@@ -24,7 +29,7 @@
width: max-content;
overflow: scroll;
}
-.container {
+#containingBlock {
/* There are a few SVG images here that size so that their margin-box fills
* their containing block width. We define a specific size here so that we
* can then check for it (minus the margins) in the "data-width" attribute.
@@ -35,13 +40,24 @@ img {
/* This styling is just cosmetic, to help visualize the images. */
border: 5px solid teal;
margin: 5px;
- vertical-align: top;
display: block;
- width: max-content;
}
</style>
-<div class="scroller">
- <div class="container">
+<!-- We specify the img elements in a <template> and then clone them for
+ testing, so that we can dynamically generate and test several variants
+ of each img. -->
+<template id="imgTemplates">
+<!-- For each img element:
+ * The "data-natural-{width,height}" attributes represent the expected
+ values of the img element's "naturalWidth" and "naturalHeight" IDL
+ attributes. This test implicitly expects the "width" and "height" IDL
+ attributes to have those same expected values; but in cases where that's
+ not correct, we provide the actual expected value in the
+ "data-{width,height}" attributes (as distinguished from
+ data-natural-{width,height}).
+ * The "title" attribute is a description of the scenario being tested, and
+ it must be unique to satisfy the test harness requirements. -->
+
<!-- FIRST PART OF TEST: No viewBox. Just a missing (or edge-casey, i.e.
negative or percent-valued) values, for the width and height attrs on the
root svg element in a SVG image. -->
@@ -163,18 +179,37 @@ img {
<img src="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' width='-5' height='-5' viewBox='0 0 600 200'></svg>"
title="SVG image, with natural width and height being negative, and aspect ratio from viewBox"
data-natural-width="0" data-natural-height="0">
+</template>
+</head>
+<body>
+<div id="scroller">
+ <div id="containingBlock">
+ </div>
</div>
-</div>
+<!-- We generate and append all of the tested <img> elements while we're inside
+ the <body>, so that all of the <img> elements' "load" events will block
+ the window onload event: -->
<script>
setup({explicit_done:true});
+// Clone and append a copy of the contents of imgTemplates, for testing:
+let clone = imgTemplates.content.cloneNode("true");
+containingBlock.appendChild(clone);
+
+// After all the img elements have loaded (indicated by the window load event),
+// we run the various tests:
onload = function() {
Array.from(document.images).forEach(img => {
test(function() {
+ // We expect naturalWidth to match the provided data-natural-width
+ // (and similar for 'height').
const expectedNaturalWidth = parseFloat(img.dataset.naturalWidth);
const expectedNaturalHeight = parseFloat(img.dataset.naturalHeight);
assert_equals(img.naturalWidth, expectedNaturalWidth, 'naturalWidth');
assert_equals(img.naturalHeight, expectedNaturalHeight, 'naturalHeight');
+ // If 'data-width' is provided, then we expect img.width to match it.
+ // Otherwise we expect img.width to match the 'data-natural-width'.
+ // (And similar for 'height'.)
const expectedWidth = 'width' in img.dataset ?
parseFloat(img.dataset.width) : expectedNaturalWidth;
const expectedHeight = 'height' in img.dataset ?
@@ -187,3 +222,4 @@ onload = function() {
done();
};
</script>
+</body>
diff --git a/tests/wpt/tests/html/semantics/forms/the-select-element/customizable-select/select-highlight-crash.html b/tests/wpt/tests/html/semantics/forms/the-select-element/customizable-select/select-highlight-crash.html
new file mode 100644
index 00000000000..a45120a2459
--- /dev/null
+++ b/tests/wpt/tests/html/semantics/forms/the-select-element/customizable-select/select-highlight-crash.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<link rel=author href="mailto:jarhar@chromium.org">
+<link rel=help href="https://issues.chromium.org/issues/419167530">
+
+<style>
+ @container (width) {
+ div::highlight(custom-highlight) {
+ --foo: bar;
+ }
+ }
+</style>
+
+<select>
+ <div style="container-type:inline-size"></div>
+</select>
diff --git a/tests/wpt/tests/html/semantics/permission-element/negative-offset-and-margin.tentative.html b/tests/wpt/tests/html/semantics/permission-element/negative-offset-and-margin.tentative.html
deleted file mode 100644
index 0b3d8dc9881..00000000000
--- a/tests/wpt/tests/html/semantics/permission-element/negative-offset-and-margin.tentative.html
+++ /dev/null
@@ -1,68 +0,0 @@
-<!DOCTYPE html>
-<meta charset=utf-8>
-<link rel="help" href="https://github.com/WICG/PEPC/blob/main/explainer.md#locking-the-pepc-style">
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<body>
-<!--The permission element should not allow setting negative outline-offset or margins under 4px.
--->
-<style>
- #id1 {
- outline-offset: -50px;
- margin-top: 3px;
- margin-left: -50px;
- margin-bottom: 0px;
- margin-right: -50px;
- }
- #id2 {
- outline-offset: 50px;
- margin-top: 50px;
- margin-left: 50px;
- margin-bottom: 50px;
- margin-right: 50px;
- }
-
- /* These various expressions all result in a negative value when calculated */
- #id3 {
- outline-offset: min(-50px, 50px);
- margin-top: min(10%, -50px);
- margin-left: clamp(-100px, 1vw, -50px);
- margin-bottom: 1% - 10000px;
- margin-right: max(min(-1em, 10em), -5%);
- }
-</style>
-
-
-<permission id="id1" type="geolocation"></permission>
-<permission id="id2" type="camera"></permission>
-<permission id="id3" type="microphone"></permission>
-
-<script>
- test(function(){
- var el_with_negatives = document.getElementById("id1");
- assert_equals(getComputedStyle(el_with_negatives).outlineOffset, "0px", "outline-offset");
- assert_equals(getComputedStyle(el_with_negatives).marginLeft, "4px", "margin-left");
- assert_equals(getComputedStyle(el_with_negatives).marginRight, "4px", "margin-right");
- assert_equals(getComputedStyle(el_with_negatives).marginTop, "4px", "margin-top");
- assert_equals(getComputedStyle(el_with_negatives).marginBottom, "4px", "margin-bottom");
- }, "Negative margins/offset should be changed to 4px");
-
- test(function(){
- var el_with_positives = document.getElementById("id2");
- assert_equals(getComputedStyle(el_with_positives).outlineOffset, "50px", "outline-offset");
- assert_equals(getComputedStyle(el_with_positives).marginLeft, "50px", "margin-left");
- assert_equals(getComputedStyle(el_with_positives).marginRight, "50px", "margin-right");
- assert_equals(getComputedStyle(el_with_positives).marginTop, "50px", "margin-top");
- assert_equals(getComputedStyle(el_with_positives).marginBottom, "50px", "margin-bottom");
- }, "Positive margins/offset are unaffected");
-
- test(function(){
- var el_with_negative_expr = document.getElementById("id3");
- assert_equals(getComputedStyle(el_with_negative_expr).outlineOffset, "0px", "outline-offset");
- assert_equals(getComputedStyle(el_with_negative_expr).marginLeft, "4px", "margin-left");
- assert_equals(getComputedStyle(el_with_negative_expr).marginRight, "4px", "margin-right");
- assert_equals(getComputedStyle(el_with_negative_expr).marginTop, "4px", "margin-top");
- assert_equals(getComputedStyle(el_with_negative_expr).marginBottom, "4px", "margin-bottom");
- }, "Expressions margins/offset should always return at least 4px");
-</script>
-</body> \ No newline at end of file
diff --git a/tests/wpt/tests/html/semantics/permission-element/negative-offset.tentative.html b/tests/wpt/tests/html/semantics/permission-element/negative-offset.tentative.html
new file mode 100644
index 00000000000..c1424ad9cc8
--- /dev/null
+++ b/tests/wpt/tests/html/semantics/permission-element/negative-offset.tentative.html
@@ -0,0 +1,79 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<link rel="help" href="https://github.com/WICG/PEPC/blob/main/explainer.md#locking-the-pepc-style">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<body>
+<!--The permission element should not allow setting negative outline-offset.
+-->
+<style>
+ #id1 {
+ outline-offset: -50px;
+ }
+ #id2 {
+ outline-offset: 50px;
+ }
+
+ /* These various expressions all result in a negative value when calculated */
+ #id3 {
+ outline-offset: min(-50px, 50px);
+ }
+ #id4 {
+ outline-offset: min(10%, -50px);
+ }
+ #id5 {
+ outline-offset: clamp(-100px, 1vw, -50px);
+ }
+ #id6 {
+ outline-offset: 1% - 10000px;
+ }
+ #id7 {
+ outline-offset: max(min(-1em, 10em), -5%);
+ }
+</style>
+
+<permission id="id1" type="geolocation"></permission>
+<permission id="id2" type="camera"></permission>
+<permission id="id3" type="microphone"></permission>
+<permission id="id4" type="camera"></permission>
+<permission id="id5" type="geolocation"></permission>
+<permission id="id6" type="microphone"></permission>
+<permission id="id7" type="camera microphone"></permission>
+
+<script>
+ test(function(){
+ var el_with_negatives = document.getElementById("id1");
+ assert_equals(getComputedStyle(el_with_negatives).outlineOffset, "0px", "outline-offset");
+ }, "Negative offset should be changed to 0px");
+
+ test(function(){
+ var el_with_positives = document.getElementById("id2");
+ assert_equals(getComputedStyle(el_with_positives).outlineOffset, "50px", "outline-offset");
+ }, "Positive offset are unaffected");
+
+ test(function(){
+ var el_with_negative_expr = document.getElementById("id3");
+ assert_equals(getComputedStyle(el_with_negative_expr).outlineOffset, "0px", "outline-offset");
+ }, "Expressions offset min(-50px, 50px) should return at least 0px");
+
+ test(function(){
+ var el_with_negative_expr = document.getElementById("id4");
+ assert_equals(getComputedStyle(el_with_negative_expr).outlineOffset, "0px", "outline-offset");
+ }, "Expressions offset outline-offset: min(10%, -50px) should return at least 0px");
+
+ test(function(){
+ var el_with_negative_expr = document.getElementById("id5");
+ assert_equals(getComputedStyle(el_with_negative_expr).outlineOffset, "0px", "outline-offset");
+ }, "Expressions offset clamp(-100px, 1vw, -50px) should return at least 0px");
+
+ test(function(){
+ var el_with_negative_expr = document.getElementById("id6");
+ assert_equals(getComputedStyle(el_with_negative_expr).outlineOffset, "0px", "outline-offset");
+ }, "Expressions offset 1% - 10000px should return at least 0px");
+
+ test(function(){
+ var el_with_negative_expr = document.getElementById("id7");
+ assert_equals(getComputedStyle(el_with_negative_expr).outlineOffset, "0px", "outline-offset");
+ }, "Expressions offset max(min(-1em, 10em), -5%) should return at least 0px");
+</script>
+</body> \ No newline at end of file
diff --git a/tests/wpt/tests/html/semantics/permission-element/no-focus.tentative.html b/tests/wpt/tests/html/semantics/permission-element/no-focus.tentative.html
index 96467885183..1bf29634605 100644
--- a/tests/wpt/tests/html/semantics/permission-element/no-focus.tentative.html
+++ b/tests/wpt/tests/html/semantics/permission-element/no-focus.tentative.html
@@ -18,35 +18,34 @@
<script>
promise_test(async() => {
+ invalid_permission_element.focus();
+ assert_equals(document.activeElement, invalid_permission_element,
+ "Invalid permission element should be focusable");
+
+ focusable_span.focus();
valid_permission_element.focus();
- assert_equals(document.activeElement, document.body,
- "Permission element should not be focused. Instead the parent element gets focus.");
+ assert_equals(document.activeElement, focusable_span,
+ "Permission element should not be focused.");
+ focusable_span.focus();
+ await test_driver.bless('Focus with user activation', () => {
+ valid_permission_element.focus();
+ });
+ assert_equals(document.activeElement, valid_permission_element,
+ "Focus is allowed with user activation");
+
+ focusable_span.focus();
actions = new test_driver.Actions()
.pointerMove(1, 1, {origin: valid_permission_element})
.pointerDown()
.addTick();
await actions.send();
-
assert_equals(document.activeElement, valid_permission_element,
- "Users can still focus the element");
+ "Users can focus the element");
focusable_span.focus();
assert_equals(document.activeElement, focusable_span,
- "Other element should be focused");
-
- invalid_permission_element.focus();
- assert_equals(document.activeElement, focusable_span,
- "Invalid permission element should not be focused");
-
- actions = new test_driver.Actions()
- .pointerMove(1, 1, {origin: invalid_permission_element})
- .pointerDown()
- .addTick();
- await actions.send();
-
- assert_equals(document.activeElement, invalid_permission_element,
- "Permission elements with an invalid-type can be focused like any other HTML element");
-}, "Permission element is not focusable by script");
+ "Other element should be focused");
+}, "Permission element is not focusable by script without user activation");
</script>
</body> \ No newline at end of file
diff --git a/tests/wpt/tests/html/semantics/permission-element/permission-icon/icon-hidden-reftest.html b/tests/wpt/tests/html/semantics/permission-element/permission-icon/icon-hidden-reftest.html
new file mode 100644
index 00000000000..79055da1bad
--- /dev/null
+++ b/tests/wpt/tests/html/semantics/permission-element/permission-icon/icon-hidden-reftest.html
@@ -0,0 +1,11 @@
+<!doctype html>
+<title>The icon of the location permission element should not be visibe if it is set to display:none</title>
+<!-- TODO: Update the link to the permission icon spec -->
+<link rel="help" href="https://github.com/WICG/PEPC/blob/main/explainer.md">
+<link rel="mismatch" href="standard-location-permission-element-ref.html">
+<style>
+ ::permission-icon {
+ display: none;
+ }
+</style>
+<permission id="geolocation" type="geolocation"/>
diff --git a/tests/wpt/tests/html/semantics/permission-element/permission-icon/icon-unique-per-type-reftest.html b/tests/wpt/tests/html/semantics/permission-element/permission-icon/icon-unique-per-type-reftest.html
new file mode 100644
index 00000000000..d51b1c4d398
--- /dev/null
+++ b/tests/wpt/tests/html/semantics/permission-element/permission-icon/icon-unique-per-type-reftest.html
@@ -0,0 +1,6 @@
+<!doctype html>
+<title>The camera permission element icon should be different to the location permission element</title>
+<!-- TODO: Update the link to the permission icon spec -->
+<link rel="help" href="https://github.com/WICG/PEPC/blob/main/explainer.md">
+<link rel="mismatch" href="standard-location-permission-element-ref.html">
+<permission id="camera" type="camera"/>
diff --git a/tests/wpt/tests/html/semantics/permission-element/permission-icon/standard-location-permission-element-ref.html b/tests/wpt/tests/html/semantics/permission-element/permission-icon/standard-location-permission-element-ref.html
new file mode 100644
index 00000000000..15ffe751c51
--- /dev/null
+++ b/tests/wpt/tests/html/semantics/permission-element/permission-icon/standard-location-permission-element-ref.html
@@ -0,0 +1,4 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>A standard permission element of type location, without any non-default styling</title>
+<permission id="geolocation" type="geolocation"/>
diff --git a/tests/wpt/tests/html/semantics/popovers/popover-root-crash.html b/tests/wpt/tests/html/semantics/popovers/popover-root-crash.html
new file mode 100644
index 00000000000..86498607730
--- /dev/null
+++ b/tests/wpt/tests/html/semantics/popovers/popover-root-crash.html
@@ -0,0 +1,7 @@
+<!doctype html>
+<script>
+ window.addEventListener("load", async () => {
+ document.documentElement.popover = "manual"
+ document.documentElement.togglePopover(true)
+ })
+</script>
diff --git a/tests/wpt/tests/html/semantics/scripting-1/the-script-element/execution-timing/042.html b/tests/wpt/tests/html/semantics/scripting-1/the-script-element/execution-timing/042.html
deleted file mode 100644
index df3a2f88f29..00000000000
--- a/tests/wpt/tests/html/semantics/scripting-1/the-script-element/execution-timing/042.html
+++ /dev/null
@@ -1,29 +0,0 @@
-<!DOCTYPE html>
-<html><head>
- <title> scheduler: DOM mutation events when adding scripts: DOMNodeInserted </title>
- <script src="/resources/testharness.js"></script>
- <script src="/resources/testharnessreport.js"></script>
- <script src="testlib/testlib.js"></script>
-</head>
-<body>
-
- <div id="log">FAILED (This TC requires JavaScript enabled)</div>
-
- <script>log('inline script #1');
- document.addEventListener( 'DOMNodeInserted', function(){ log('DOMNodeInserted'); }, false );
- testlib.addScript('log(\'head script #1\')', {}, document.getElementsByTagName('head')[0], false);
- log('end script #1');
- </script>
-
- <script type="text/javascript">
- log( 'inline script #2' );
- var t = async_test()
-
- function test() {
- assert_array_equals(eventOrder, ['inline script #1', 'head script #1', 'DOMNodeInserted', 'end script #1', 'inline script #2']);
- t.done();
- }
- onload = t.step_func(test)
- </script>
-
-</body></html>
diff --git a/tests/wpt/tests/html/semantics/scripting-1/the-script-element/execution-timing/043.html b/tests/wpt/tests/html/semantics/scripting-1/the-script-element/execution-timing/043.html
deleted file mode 100644
index bcfd90cba47..00000000000
--- a/tests/wpt/tests/html/semantics/scripting-1/the-script-element/execution-timing/043.html
+++ /dev/null
@@ -1,31 +0,0 @@
-<!DOCTYPE html>
-<html><head>
- <title> scheduler: DOM mutation events when adding external scripts: DOMNodeInserted </title>
- <script src="/resources/testharness.js"></script>
- <script src="/resources/testharnessreport.js"></script>
- <script src="testlib/testlib.js"></script>
-</head>
-<body>
-
- <div id="log">FAILED (This TC requires JavaScript enabled)</div>
-
- <script>log('inline script #1');
- document.addEventListener( 'DOMNodeInserted', function(){ log('DOMNodeInserted'); }, false );
- testlib.addScript('', { src: 'scripts/include-1.js' }, document.getElementsByTagName('head')[0], false);
- log('end script #1');
- </script>
-
- <script type="text/javascript">
- log( 'inline script #2' );
- var t = async_test()
-
- function test() {
- assert_any(assert_array_equals, eventOrder, [['inline script #1', 'DOMNodeInserted', 'end script #1', 'external script #1', 'inline script #2'],
- ['inline script #1', 'DOMNodeInserted', 'end script #1', 'inline script #2', 'external script #1']]
- );
- t.done();
- }
- onload = t.step_func(test)
- </script>
-
-</body></html>
diff --git a/tests/wpt/tests/html/semantics/scripting-1/the-script-element/execution-timing/044.html b/tests/wpt/tests/html/semantics/scripting-1/the-script-element/execution-timing/044.html
deleted file mode 100644
index 8d412079e45..00000000000
--- a/tests/wpt/tests/html/semantics/scripting-1/the-script-element/execution-timing/044.html
+++ /dev/null
@@ -1,28 +0,0 @@
-<!DOCTYPE html>
-<html><head>
- <title> scheduler: DOM mutation events when adding scripts: DOMNodeInsertedIntoDocument </title>
- <script src="/resources/testharness.js"></script>
- <script src="/resources/testharnessreport.js"></script>
- <script src="testlib/testlib.js"></script>
-</head>
-<body>
-
- <div id="log">FAILED (This TC requires JavaScript enabled)</div>
-
- <script>log('inline script #1');
- testlib.addScript('log(\'head script #1\')', {}, document.getElementsByTagName('head')[0], false, function(s){s.addEventListener( 'DOMNodeInsertedIntoDocument', function(){ log('DOMNodeInsertedIntoDocument'); }, false ); } );
- log('end script #1');
- </script>
-
- <script type="text/javascript">
- log( 'inline script #2' );
- var t = async_test()
-
- function test() {
- assert_array_equals(eventOrder, ['inline script #1', 'head script #1', 'DOMNodeInsertedIntoDocument', 'end script #1', 'inline script #2']);
- t.done();
- }
- onload = t.step_func(test)
- </script>
-
-</body></html>
diff --git a/tests/wpt/tests/html/semantics/scripting-1/the-script-element/execution-timing/045.html b/tests/wpt/tests/html/semantics/scripting-1/the-script-element/execution-timing/045.html
deleted file mode 100644
index 254e0d13662..00000000000
--- a/tests/wpt/tests/html/semantics/scripting-1/the-script-element/execution-timing/045.html
+++ /dev/null
@@ -1,28 +0,0 @@
-<!DOCTYPE html>
-<html><head>
- <title> scheduler: DOM mutation events when adding external scripts: DOMNodeInsertedIntoDocument </title>
- <script src="/resources/testharness.js"></script>
- <script src="/resources/testharnessreport.js"></script>
- <script src="testlib/testlib.js"></script>
-</head>
-<body>
-
- <div id="log">FAILED (This TC requires JavaScript enabled)</div>
-
- <script>log('inline script #1');
- testlib.addScript('', {src:'scripts/include-1.js'}, document.getElementsByTagName('head')[0], false, function(s){s.addEventListener( 'DOMNodeInsertedIntoDocument', function(){ log('DOMNodeInsertedIntoDocument'); }, false);});
- log('end script #1');
- </script>
-
- <script type="text/javascript">
- log( 'inline script #2' );
- var t = async_test()
-
- onload = t.step_func(function() {
- assert_any(assert_array_equals, eventOrder, [['inline script #1', 'DOMNodeInsertedIntoDocument', 'end script #1', 'external script #1', 'inline script #2'],
- ['inline script #1', 'DOMNodeInsertedIntoDocument', 'end script #1', 'inline script #2', 'external script #1']]);
- t.done();
- });
- </script>
-
-</body></html>
diff --git a/tests/wpt/tests/html/semantics/scripting-1/the-script-element/execution-timing/054.html b/tests/wpt/tests/html/semantics/scripting-1/the-script-element/execution-timing/054.html
deleted file mode 100644
index 29ede23414e..00000000000
--- a/tests/wpt/tests/html/semantics/scripting-1/the-script-element/execution-timing/054.html
+++ /dev/null
@@ -1,33 +0,0 @@
-<!DOCTYPE html>
-<html><head>
- <title> scheduler: removing newly inserted script from DOMNodeInserted handler - external script </title>
- <script src="/resources/testharness.js"></script>
- <script src="/resources/testharnessreport.js"></script>
- <script src="testlib/testlib.js"></script>
-</head>
-<body>
-
- <div id="log">FAILED (This TC requires JavaScript enabled)</div>
-
- <script>log('inline script #1');
- document.addEventListener( 'DOMNodeInserted', function listener(e){
- log('DOMNodeInserted event');
- e.target.parentNode.removeChild(e.target);
- document.removeEventListener('DOMNodeInserted', listener);
- }, false );
- var script=testlib.addScript('', { src:'scripts/include-1.js?'+Math.random() }, document.getElementsByTagName('body')[0], true );
- log('end script #1');
- </script>
- <script type="text/javascript">
- log( 'inline script #2' );
- var t = async_test()
-
- function test() {
- assert_any(assert_array_equals, eventOrder, [['inline script #1', 'DOMNodeInserted event', 'end script #1', 'inline script #2', 'external script #1'],
- ['inline script #1', 'DOMNodeInserted event', 'end script #1', 'external script #1', 'inline script #2']]);
- t.done();
- }
- onload = t.step_func(test);
- </script>
-
-</body></html>
diff --git a/tests/wpt/tests/html/semantics/scripting-1/the-script-element/execution-timing/055.html b/tests/wpt/tests/html/semantics/scripting-1/the-script-element/execution-timing/055.html
deleted file mode 100644
index c837d78174b..00000000000
--- a/tests/wpt/tests/html/semantics/scripting-1/the-script-element/execution-timing/055.html
+++ /dev/null
@@ -1,32 +0,0 @@
-<!DOCTYPE html>
-<html><head>
- <title> scheduler: removing newly inserted script from DOMNodeInserted handler - inline script </title>
- <script src="/resources/testharness.js"></script>
- <script src="/resources/testharnessreport.js"></script>
- <script src="testlib/testlib.js"></script>
-</head>
-<body>
-
- <div id="log">FAILED (This TC requires JavaScript enabled)</div>
-
- <script>log('inline script #1');
- document.addEventListener( 'DOMNodeInserted', function listener(e){
- log('DOMNodeInserted event');
- e.target.parentNode.removeChild(e.target);
- document.removeEventListener('DOMNodeInserted', listener);
- }, false );
- var script=testlib.addScript('log(\'added script\')', { }, document.getElementsByTagName('body')[0], true );
- log('end script #1');
- </script>
- <script type="text/javascript">
- log( 'inline script #2' );
- var t = async_test()
-
- function test() {
- assert_array_equals(eventOrder, ['inline script #1', 'added script', 'DOMNodeInserted event', 'end script #1', 'inline script #2']);
- t.done();
- }
- onload = t.step_func(test);
- </script>
-
-</body></html>
diff --git a/tests/wpt/tests/html/semantics/scripting-1/the-script-element/json-module/invalid-content-type.any.js b/tests/wpt/tests/html/semantics/scripting-1/the-script-element/json-module/invalid-content-type.any.js
index d15fa3f1b70..d0bb6aa9fb1 100644
--- a/tests/wpt/tests/html/semantics/scripting-1/the-script-element/json-module/invalid-content-type.any.js
+++ b/tests/wpt/tests/html/semantics/scripting-1/the-script-element/json-module/invalid-content-type.any.js
@@ -7,6 +7,12 @@ const content_types = [
"text/json+blah",
"application/blahjson",
"image/json",
+ "text+json",
+ "json+json",
+ "text/json/json+json",
+ "text/html;+json",
+ "text/html+json+xml",
+ "text/json/json",
];
for (const content_type of content_types) {
promise_test(async test => {
diff --git a/tests/wpt/tests/html/semantics/scripting-1/the-script-element/json-module/valid-content-type.html b/tests/wpt/tests/html/semantics/scripting-1/the-script-element/json-module/valid-content-type.html
index 3232b84d271..fdeba93ba89 100644
--- a/tests/wpt/tests/html/semantics/scripting-1/the-script-element/json-module/valid-content-type.html
+++ b/tests/wpt/tests/html/semantics/scripting-1/the-script-element/json-module/valid-content-type.html
@@ -19,6 +19,8 @@ const t3 = async_test("text/html+json");
const t4 = async_test("image/svg+json");
const t5 = async_test("text/json;boundary=something");
const t6 = async_test("text/json;foo=bar");
+const t7 = async_test("text/json;+json");
+const t8 = async_test("text/html+xml+json");
</script>
<script type="module" onerror="t1.step(() => assert_unreached(event))">
import v from "../serve-with-content-type.py?fn=json-module/module.json&ct=text/json" with { type: "json"};
@@ -43,4 +45,12 @@ check(t5, v);
<script type="module" onerror="t6.step(() => assert_unreached(event))">
import v from "../serve-with-content-type.py?fn=json-module/module.json&ct=text/json;foo=bar" with { type: "json"};
check(t6, v);
+</script>
+<script type="module" onerror="t7.step(() => assert_unreached(event))">
+import v from "../serve-with-content-type.py?fn=json-module/module.json&ct=text/json;%2Bjson" with { type: "json"};
+check(t7, v);
+</script>
+<script type="module" onerror="t8.step(() => assert_unreached(event))">
+import v from "../serve-with-content-type.py?fn=json-module/module.json&ct=text/html%2Bxml%2Bjson" with { type: "json"};
+check(t8, v);
</script> \ No newline at end of file
diff --git a/tests/wpt/tests/html/semantics/the-button-element/command-and-commandfor/source-attribute-retargeting.tentative.html b/tests/wpt/tests/html/semantics/the-button-element/command-and-commandfor/source-attribute-retargeting.tentative.html
new file mode 100644
index 00000000000..885b75a3387
--- /dev/null
+++ b/tests/wpt/tests/html/semantics/the-button-element/command-and-commandfor/source-attribute-retargeting.tentative.html
@@ -0,0 +1,132 @@
+<!DOCTYPE html>
+<link rel=author href="mailto:jarhar@chromium.org">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<div id=popover popover=auto>popover</div>
+<div id=host>
+ <template shadowrootmode=open>
+ <button id=shadow-button command=show-popover>button in shadowroot</button>
+ </template>
+</div>
+
+<script>
+promise_test(async () => {
+ const popover = document.getElementById('popover');
+ const host = document.getElementById('host');
+ const shadowButton = host.shadowRoot.getElementById('shadow-button');
+ shadowButton.commandForElement = popover;
+
+ const eventNames = ['beforetoggle', 'toggle', 'command'];
+ const eventNameToEvent = {};
+ const eventNameToCaptureSource = {};
+ const eventNameToBubbleSource = {};
+
+ for (const eventName of eventNames) {
+ popover.addEventListener(eventName, event => {
+ eventNameToEvent[eventName] = event;
+ eventNameToBubbleSource[eventName] = event.source;
+ });
+ popover.addEventListener(eventName, event => {
+ eventNameToCaptureSource[eventName] = event.source;
+ }, {capture: true});
+ }
+
+ shadowButton.click();
+ await new Promise(requestAnimationFrame);
+ await new Promise(requestAnimationFrame);
+
+ for (const eventName of eventNames) {
+ const event = eventNameToEvent[eventName];
+ assert_true(!!event, `A ${eventName} event should have been fired.`);
+ assert_equals(eventNameToCaptureSource[eventName], host,
+ `${eventName}.source during capture.`);
+ assert_equals(eventNameToBubbleSource[eventName], host,
+ `${eventName}.source during bubble.`);
+ assert_not_equals(event.source, shadowButton,
+ `${eventName}.source shouldn't leak the shadow button.`);
+ assert_equals(event.source, host,
+ `${eventName}.source after dispatch.`);
+ }
+}, 'CommandEvent.source and ToggleEvent.source should be retargeted during and after event dispatch.');
+</script>
+
+<div id=host2>
+ <template shadowrootmode=open>
+ <div id=source>source</div>
+ <div id=innerhost>
+ <template shadowrootmode=open>
+ <div id=target>target</div>
+ </template>
+ </div>
+ </template>
+</div>
+
+<script>
+// This does not test ToggleEvent because ToggleEventInit does not have a source attribute.
+promise_test(async () => {
+ const host2 = document.getElementById('host2');
+ const source = host2.shadowRoot.getElementById('source');
+ const innerhost = host2.shadowRoot.getElementById('innerhost');
+ const target = innerhost.shadowRoot.getElementById('target');
+
+ const targets = [host2, innerhost, target];
+ const targetToEvent = new Map();
+ const targetToCaptureSource = new Map();
+ const targetToBubbleSource = new Map();
+
+ for (const target of targets) {
+ target.addEventListener('command', event => {
+ targetToEvent.set(target, event);
+ targetToBubbleSource.set(target, event.source);
+ });
+ target.addEventListener('command', event => {
+ targetToCaptureSource.set(target, event.source);
+ }, {capture: true});
+ }
+
+ const commandEvent = new CommandEvent('command', {composed: true, source});
+ target.dispatchEvent(commandEvent);
+
+ for (const target of targets) {
+ const expectedSource = target == host2 ? host2 : source;
+ assert_true(targetToEvent.has(target),
+ `${target.id}: event should have fired.`);
+ assert_equals(targetToCaptureSource.get(target), expectedSource,
+ `${target.id}: event.source at capture.`);
+ assert_equals(targetToBubbleSource.get(target), expectedSource,
+ `${target.id}: event.source at bubble.`);
+ assert_equals(targetToEvent.get(target).source, host2,
+ `${target.id}: event.source after dispatch.`);
+ }
+}, 'CommandEvent.source should be retargeted when manually dispatched with composed set to true.');
+</script>
+
+<div id=popover3 popover=auto>popover 3</div>
+<button id=button3 commandfor=popover3 command=show-popover>show popover 3</button>
+
+<script>
+promise_test(async () => {
+ const button = document.getElementById('button3');
+ const popover = document.getElementById('popover3');
+
+ const eventNames = ['beforetoggle', 'toggle', 'command'];
+ const eventNameToEvent = {};
+ for (const eventName of eventNames) {
+ popover.addEventListener(eventName, event => {
+ eventNameToEvent[eventName] = event;
+ });
+ }
+
+ button.click();
+ await new Promise(requestAnimationFrame);
+ await new Promise(requestAnimationFrame);
+
+ for (const eventName of eventNames) {
+ const event = eventNameToEvent[eventName];
+ assert_true(!!event, `${eventName} should have been fired.`);
+ assert_equals(event.source, button,
+ `${eventName}.source should be the invoker button after dispatch.`);
+ }
+}, 'CommandEvent.source and ToggleEvent.source should not be set to null after dispatch without ShadowDOM.');
+</script>
diff --git a/tests/wpt/tests/html/webappapis/system-state-and-capabilities/the-navigator-object/WEB_FEATURES.yml b/tests/wpt/tests/html/webappapis/system-state-and-capabilities/the-navigator-object/WEB_FEATURES.yml
index a1af3e21a48..7a364e14095 100644
--- a/tests/wpt/tests/html/webappapis/system-state-and-capabilities/the-navigator-object/WEB_FEATURES.yml
+++ b/tests/wpt/tests/html/webappapis/system-state-and-capabilities/the-navigator-object/WEB_FEATURES.yml
@@ -2,3 +2,7 @@ features:
- name: pdf-viewer
files:
- plugins-and-mimetypes.html
+- name: ua-client-hints
+ files:
+ - navigator_user_agent.tentative.html
+ - navigator_user_agent.https.tentative.html
diff --git a/tests/wpt/tests/interfaces/scoped-custom-elements-registry.idl b/tests/wpt/tests/interfaces/scoped-custom-elements-registry.idl
new file mode 100644
index 00000000000..46ca2d6b9c4
--- /dev/null
+++ b/tests/wpt/tests/interfaces/scoped-custom-elements-registry.idl
@@ -0,0 +1,38 @@
+[Exposed=Window]
+partial interface CustomElementRegistry {
+ constructor();
+ undefined initialize(Node root);
+};
+
+[Exposed=Window]
+partial interface HTMLTemplateElement {
+ [CEReactions] attribute DOMString shadowRootCustomElementRegistry;
+};
+
+[Exposed=Window]
+partial interface Document {
+ readonly attribute CustomElementRegistry? customElementRegistry;
+};
+
+[Exposed=Window]
+partial interface Element {
+ readonly attribute CustomElementRegistry? customElementRegistry;
+};
+
+[Exposed=Window]
+partial interface ShadowRoot {
+ readonly attribute CustomElementRegistry? customElementRegistry;
+};
+
+dictionary ImportNodeOptions {
+ CustomElementRegistry customElementRegistry;
+ boolean selfOnly = false;
+};
+
+partial dictionary ShadowRootInit {
+ CustomElementRegistry customElementRegistry;
+};
+
+partial dictionary ElementCreationOptions {
+ CustomElementRegistry customElementRegistry;
+};
diff --git a/tests/wpt/tests/layout-instability/WEB_FEATURES.yml b/tests/wpt/tests/layout-instability/WEB_FEATURES.yml
new file mode 100644
index 00000000000..335b072c186
--- /dev/null
+++ b/tests/wpt/tests/layout-instability/WEB_FEATURES.yml
@@ -0,0 +1,3 @@
+features:
+- name: layout-instability
+ files: "**"
diff --git a/tests/wpt/tests/lint.ignore b/tests/wpt/tests/lint.ignore
index 10b5dadba74..60b0f65a6f4 100644
--- a/tests/wpt/tests/lint.ignore
+++ b/tests/wpt/tests/lint.ignore
@@ -126,6 +126,7 @@ CONSOLE: webaudio/resources/audit.js:41
# Intentional use of console.*
CONSOLE: infrastructure/webdriver/bidi/subscription.html
CONSOLE: infrastructure/webdriver/bidi/subscription.window.js
+CONSOLE: html/editing/dnd/events/ua-shadow-contents-manual.html
# use of console in a public library - annotation-model ensures
# it is not actually used
diff --git a/tests/wpt/tests/network-error-logging/support/nel.sub.js b/tests/wpt/tests/network-error-logging/support/nel.sub.js
index 26ddd897c2f..f9dfec1dad8 100644
--- a/tests/wpt/tests/network-error-logging/support/nel.sub.js
+++ b/tests/wpt/tests/network-error-logging/support/nel.sub.js
@@ -18,6 +18,7 @@ function releaseNELLock() {
function nel_test(callback, name, properties) {
promise_test(async t => {
await obtainNELLock();
+ await assertNELIsImplemented();
await clearReportingAndNELConfigurations();
await callback(t);
await releaseNELLock();
@@ -27,6 +28,7 @@ function nel_test(callback, name, properties) {
function nel_iframe_test(callback, name, properties) {
promise_test(async t => {
await obtainNELLock();
+ await assertNELIsImplemented();
await clearReportingAndNELConfigurationsInIframe();
await callback(t);
await releaseNELLock();
@@ -251,9 +253,10 @@ function _isSubsetOf(obj1, obj2) {
* expected.
*/
-async function reportExists(expected, retain_reports) {
- var timeout =
- document.querySelector("meta[name=timeout][content=long]") ? 50 : 1;
+async function reportExists(expected, retain_reports, timeout) {
+ if (!timeout) {
+ timeout = document.querySelector("meta[name=timeout][content=long]") ? 50 : 1;
+ }
var reportLocation =
"/reporting/resources/report.py?op=retrieve_report&timeout=" +
timeout + "&reportID=" + reportID;
@@ -295,3 +298,13 @@ async function reportsExist(expected_reports, retain_reports) {
}
return true;
}
+
+// this runs first to avoid testing on browsers not implementing NEL
+async function assertNELIsImplemented() {
+ await fetchResourceWithBasicPolicy();
+ // Assert that the report was generated
+ assert_implements(await reportExists({
+ url: getURLForResourceWithBasicPolicy(),
+ type: "network-error"
+ }, false, 1), "'Basic NEL support: missing network-error report'");
+}
diff --git a/tests/wpt/tests/pointerevents/persistentDeviceId/get-persistendeviceid-from-pointer-mouse-event.tentative.html b/tests/wpt/tests/pointerevents/persistentDeviceId/get-persistendeviceid-from-pointer-mouse-event.tentative.html
new file mode 100644
index 00000000000..66fb63d54d1
--- /dev/null
+++ b/tests/wpt/tests/pointerevents/persistentDeviceId/get-persistendeviceid-from-pointer-mouse-event.tentative.html
@@ -0,0 +1,42 @@
+<!DOCTYPE html>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/resources/testdriver.js"></script>
+<script src="/resources/testdriver-actions.js"></script>
+<script src="/resources/testdriver-vendor.js"></script>
+
+<style>
+ div {
+ user-select: none; // Prevents text selection on drag.
+ }
+</style>
+<div id="logger" draggable="false"></div>
+<div id="console"></div>
+<!-- This test documents the current behavior in Chrome for some
+ pointerType == "mouse" events -->
+<script>
+ function CheckDeviceIdOne(event) {
+ assert_equals(event.persistentDeviceId, 1, event.type + " deviceId is 1");
+ }
+
+ function CheckDeviceIdZero(event) {
+ assert_equals(event.persistentDeviceId, 0, event.type + " deviceId is 0");
+ }
+
+ window.addEventListener("pointerdown", CheckDeviceIdOne, false);
+ window.addEventListener("pointermove", CheckDeviceIdOne, false);
+ window.addEventListener("pointerover", CheckDeviceIdOne, false);
+ window.addEventListener("pointerup", CheckDeviceIdOne, false);
+ window.addEventListener("click", CheckDeviceIdZero, false);
+
+ promise_test(async () => {
+ let actions = new test_driver.Actions()
+ .addPointer("TestPointer", "mouse")
+ .pointerDown()
+ .pointerMove(100, 100)
+ .pointerUp();
+
+ await actions.send();
+
+ }, 'PointerEvent.persistentDeviceId');
+</script>
diff --git a/tests/wpt/tests/resize-observer/zoom.html b/tests/wpt/tests/resize-observer/zoom.html
new file mode 100644
index 00000000000..77b4bc49fa7
--- /dev/null
+++ b/tests/wpt/tests/resize-observer/zoom.html
@@ -0,0 +1,55 @@
+<!doctype html>
+<link rel="help" href="https://drafts.csswg.org/css-viewport/#zoom-om">
+<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/9398">
+<link rel="author" href="mailto:emilio@crisal.io" title="Emilio Cobos Álvarez">
+<link rel="author" href="https://mozilla.org" title="Mozilla">
+<title>ResizeObserver sizes account for zoom</title>
+<meta name="viewport" content="width=device-width,initial-scale=1">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<style>
+ div {
+ width: 100px;
+ height: 100px;
+ border: 5px solid;
+ padding: 5px;
+ margin: 5px;
+ box-sizing: border-box;
+ }
+</style>
+<div></div>
+<div style="zoom: 2"></div>
+<div style="zoom: 4"></div>
+<script>
+promise_test(async function() {
+ let { promise, resolve } = Promise.withResolvers();
+ let observer = new ResizeObserver(entries => {
+ resolve(entries);
+ });
+ for (let div of document.querySelectorAll("div")) {
+ observer.observe(div);
+ }
+ let entries = await promise;
+ observer.disconnect();
+ assert_equals(entries.length, 3, "Should have three entries");
+ for (let entry of entries) {
+ assert_equals(entry.contentRect.top, 5, "content-rect top should be scaled by zoom");
+ assert_equals(entry.contentRect.left, 5, "content-rect left should be scaled by zoom");
+ assert_equals(entry.contentRect.width, 80, "content-rect width should be scaled by zoom");
+ assert_equals(entry.contentRect.height, 80, "content-rect height should be scaled by zoom");
+
+ for (let sizeArray of [entry.borderBoxSize, entry.contentBoxSize, entry.devicePixelContentBoxSize]) {
+ assert_equals(sizeArray.length, 1, "Should have one box");
+ }
+ let borderBoxSize = entry.borderBoxSize[0];
+ let contentBoxSize = entry.contentBoxSize[0];
+ let devicePixelContentBoxSize = entry.devicePixelContentBoxSize[0];
+ assert_equals(borderBoxSize.inlineSize, 100, "border inline size should be scaled by zoom");
+ assert_equals(borderBoxSize.blockSize, 100, "border block size should be scaled by zoom");
+ assert_equals(contentBoxSize.inlineSize, 80, "content inline size should be scaled by zoom");
+ assert_equals(contentBoxSize.blockSize, 80, "content block size should be scaled by zoom");
+ assert_equals(devicePixelContentBoxSize.inlineSize, 80 * entry.target.currentCSSZoom * window.devicePixelRatio, "dev-px size should _not_ be scaled by zoom");
+ assert_equals(devicePixelContentBoxSize.blockSize, 80 * entry.target.currentCSSZoom * window.devicePixelRatio, "dev-px size should _not_ be scaled by zoom");
+ }
+});
+</script>
diff --git a/tests/wpt/tests/resource-timing/content-encoding.https.html b/tests/wpt/tests/resource-timing/content-encoding.https.html
index 0d67bfc7d4f..80473552f08 100644
--- a/tests/wpt/tests/resource-timing/content-encoding.https.html
+++ b/tests/wpt/tests/resource-timing/content-encoding.https.html
@@ -33,10 +33,10 @@
run_same_origin_test("/resource-timing/resources/foo.text.zst", "zstd");
run_same_origin_test("/resource-timing/resources/compressed-js.py?content_encoding=deflate", "deflate");
run_same_origin_test("/resource-timing/resources/compressed-js.py?content_encoding=gzip", "gzip");
- // Unrecognized content encoding value should be transformed to "unknown".
- run_same_origin_test("/resource-timing/resources/compressed-js.py?content_encoding=unrecognizedname", "unknown");
- // "identity" is not allowed in response header and should be transformed to "unknown".
- run_same_origin_test("/resource-timing/resources/compressed-js.py?content_encoding=identity", "unknown");
+ // Unrecognized content encoding value should be transformed to "@unknown".
+ run_same_origin_test("/resource-timing/resources/compressed-js.py?content_encoding=unrecognizedname", "@unknown");
+ // "identity" is not allowed in response header and should be transformed to "@unknown".
+ run_same_origin_test("/resource-timing/resources/compressed-js.py?content_encoding=identity", "@unknown");
// Mult-encodinging and formatting tests.
run_same_origin_test("/resource-timing/resources/content-encoding-headers.py?content_encoding=gzip, deflate,Apple", "multiple");
run_same_origin_test("/resource-timing/resources/content-encoding-headers.py?content_encoding=gzip, ", "multiple");
diff --git a/tests/wpt/tests/resources/testdriver-actions.js.headers b/tests/wpt/tests/resources/testdriver-actions.js.headers
new file mode 100644
index 00000000000..5e8f640c665
--- /dev/null
+++ b/tests/wpt/tests/resources/testdriver-actions.js.headers
@@ -0,0 +1,2 @@
+Content-Type: text/javascript; charset=utf-8
+Cache-Control: max-age=3600
diff --git a/tests/wpt/tests/scroll-animations/animation-trigger/animation-trigger-repeat.tentative.html b/tests/wpt/tests/scroll-animations/animation-trigger/animation-trigger-repeat.tentative.html
index cfbe9d3c933..6c01e762e5a 100644
--- a/tests/wpt/tests/scroll-animations/animation-trigger/animation-trigger-repeat.tentative.html
+++ b/tests/wpt/tests/scroll-animations/animation-trigger/animation-trigger-repeat.tentative.html
@@ -21,7 +21,7 @@
}
.target {
animation: myAnim linear 0.5s both;
- animation-trigger: repeat;
+ animation-trigger-type: repeat;
animation-trigger-range: 250px 300px;
animation-trigger-exit-range: 200px 350px;
}
@@ -76,6 +76,7 @@
// let target;
async function testRepeatAnimationTrigger(test, rangeBoundaries) {
+ const initial_transform = getComputedStyle(target).transform;
// Just short of the trigger range start, no trigger action expected.
await testAnimationTrigger(test, () => {
return rangeBoundaries.exitTriggerRangeAbove();
@@ -91,15 +92,14 @@
return rangeBoundaries.enterTriggerRange();
}, target, ["animationstart", "animationend"], [true, true]);
- // This is a repeat trigger, exiting the exit range resets the animation.
- // We waited for an animationend event in the previous step so we won't
- // see an animationcancel event here. But, by inspecting
- // style.transform, we should see that the animation was reset.
+ // This is a repeat trigger, exiting the exit range resets the
+ // animation. By inspecting style.transform, we should see that the
+ // animation was reset.
await testAnimationTrigger(test, () => {
return rangeBoundaries.exitExitRangeAbove();
}, target, ["animationstart", "animationend", "animationcancel"],
[false, false, false]);
- assert_equals(getComputedStyle(target).transform, "none");
+ assert_equals(getComputedStyle(target).transform, initial_transform);
// This is a repeat trigger, re-entering plays the animation.
await testAnimationTrigger(test, async () => {
@@ -109,7 +109,7 @@
// Exit the range.
return rangeBoundaries.exitExitRangeBelow();
}, target, ["animationstart", "animationend", "animationcancel"],
- [true, false, true]);
+ [true, false, false]);
}
const CSS_TRIGGER_START_PX = 250;
@@ -127,7 +127,7 @@
CSS_EXIT_END_PX,
scroller);
await testRepeatAnimationTrigger(test, rangeBoundaries);
- }, "once animation triggered via scroll() timeline.");
+ }, "repeat animation triggered via scroll() timeline.");
promise_test(async (test) => {
scroller = view_scroller;
@@ -142,7 +142,7 @@
COVER_START_OFFSET + CSS_EXIT_END_PX,
scroller);
await testRepeatAnimationTrigger(test, rangeBoundaries);
- }, "once animation triggered via view() timeline.");
+ }, "repeat animation triggered via view() timeline.");
promise_test(async (test) => {
scroller = deferred_scroller;
@@ -157,7 +157,7 @@
COVER_START_OFFSET + CSS_EXIT_END_PX,
scroller);
await testRepeatAnimationTrigger(test, rangeBoundaries);
- }, "once animation triggered via deferred (view) timeline.");
+ }, "repeat animation triggered via deferred (view) timeline.");
</script>
</body>
</html>
diff --git a/tests/wpt/tests/shadow-dom/HighlightRegistry-highlightsFromPoint.html b/tests/wpt/tests/shadow-dom/HighlightRegistry-highlightsFromPoint.html
index 5244f923e34..4098bc5a994 100644
--- a/tests/wpt/tests/shadow-dom/HighlightRegistry-highlightsFromPoint.html
+++ b/tests/wpt/tests/shadow-dom/HighlightRegistry-highlightsFromPoint.html
@@ -1,7 +1,7 @@
<!doctype html>
<body>
<meta name="author" title="Fernando Fiori" href="mailto:ffiori@microsoft.com">
-<meta name="assert" content="HighlightRegistry.highlightsFromPoint returns the Highlights present at at a given point inside the shadow roots passed as argument.">
+<meta name="assert" content="HighlightRegistry.highlightsFromPoint returns HighlightHitResults with the Highlights and their corresponding ranges present at a given point inside the shadow roots passed as argument.">
<link rel="help" href="https://github.com/MicrosoftEdge/MSEdgeExplainers/blob/main/highlight/HighlightsFromPointsExplainer.md">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
@@ -57,25 +57,28 @@ body {
// Get x and y coordinates between '0' and '1'.
let x = spanBoundingRectangle.left + characterWidth;
let y = spanBoundingRectangle.top + spanBoundingRectangle.height / 2;
- let highlights = CSS.highlights.highlightsFromPoint(x, y, {shadowRoots: [shadowRoot]});
- assert_equals(highlights.length, 0, 'CSS.highlights.highlightsFromPoint() returns no Highlights when the coordinates provided point at no Highlights');
+ let highlight_hit_results = CSS.highlights.highlightsFromPoint(x, y, {shadowRoots: [shadowRoot]});
+ assert_equals(highlight_hit_results.length, 0, 'CSS.highlights.highlightsFromPoint() returns no Highlights when the coordinates provided point at no Highlights');
// Get x and y coordinates between '2' and '3'.
x = spanBoundingRectangle.left + 3 * characterWidth;
- highlights = CSS.highlights.highlightsFromPoint(x, y, {shadowRoots: [shadowRoot]});
- assert_equals(highlights.length, 1, 'CSS.highlights.highlightsFromPoint() returns exactly one Highlight when the given coordinates point at a Highlight under the shadow root provided');
- assert_equals(highlights[0], highlight, 'CSS.highlights.highlightsFromPoint() returns the Highlight present at the given coordinates when it\'s under the shadow root provided');
+ highlight_hit_results = CSS.highlights.highlightsFromPoint(x, y, {shadowRoots: [shadowRoot]});
+ assert_equals(highlight_hit_results.length, 1, 'CSS.highlights.highlightsFromPoint() returns exactly one Highlight when the given coordinates point at a Highlight under the shadow root provided');
+ assert_equals(highlight_hit_results[0].highlight, highlight, 'CSS.highlights.highlightsFromPoint() returns the Highlight present at the given coordinates when it\'s under the shadow root provided');
+ assert_array_equals(highlight_hit_results[0].ranges, [range], 'CSS.highlights.highlightsFromPoint() returns a HighlightHitResult with the ranges of the Highlight present at the coordinates provided');
- highlights = CSS.highlights.highlightsFromPoint(x, y);
- assert_equals(highlights.length, 0, 'CSS.highlights.highlightsFromPoint() returns no Highlights when the coordinates provided point at one Highlight in the shadow DOM but shadowRoots provided is empty');
+ highlight_hit_results = CSS.highlights.highlightsFromPoint(x, y);
+ assert_equals(highlight_hit_results.length, 0, 'CSS.highlights.highlightsFromPoint() returns no Highlights when the coordinates provided point at one Highlight in the shadow DOM but shadowRoots provided is empty');
// Get x and y coordinates between '6' and '7'.
// Same priority for the Highlights, break tie by order of registration.
x = spanBoundingRectangle.left + 7 * characterWidth;
- highlights = CSS.highlights.highlightsFromPoint(x, y, {shadowRoots: [shadowRoot]});
- assert_equals(highlights.length, 2, 'CSS.highlights.highlightsFromPoint() returns exactly two Highlights when the coordinates provided point at two overlapping Highlights');
- assert_equals(highlights[0], highlight2, 'CSS.highlights.highlightsFromPoint() returns first the Highlight registered last when both Highlights present at the point provided have the same priority');
- assert_equals(highlights[1], highlight, 'CSS.highlights.highlightsFromPoint() returns last the Highlight registered first when both Highlights present at the point provided have the same priority');
+ highlight_hit_results = CSS.highlights.highlightsFromPoint(x, y, {shadowRoots: [shadowRoot]});
+ assert_equals(highlight_hit_results.length, 2, 'CSS.highlights.highlightsFromPoint() returns exactly two Highlights when the coordinates provided point at two overlapping Highlights');
+ assert_equals(highlight_hit_results[0].highlight, highlight2, 'CSS.highlights.highlightsFromPoint() returns first the Highlight registered last when both Highlights present at the point provided have the same priority');
+ assert_equals(highlight_hit_results[1].highlight, highlight, 'CSS.highlights.highlightsFromPoint() returns last the Highlight registered first when both Highlights present at the point provided have the same priority');
+ assert_array_equals(highlight_hit_results[0].ranges, [range2], 'CSS.highlights.highlightsFromPoint() returns first a HighlightHitResult with the ranges of the Highlight present on top at the coordinates provided');
+ assert_array_equals(highlight_hit_results[1].ranges, [range], 'CSS.highlights.highlightsFromPoint() returns last a HighlightHitResult with the ranges of the Highlight present at the bottom at the coordinates provided');
}, 'CSS.highlights.highlightsFromPoint() returns Highlights present at a given point inside a shadow tree in the right order.');
test(() => {
@@ -109,23 +112,25 @@ body {
// Get x and y coordinates between '0' and '1' in the first line.
let x = spanBoundingRectangle.left + characterWidth;
let y = container.getBoundingClientRect().top + characterHeight / 2.0;
- let highlights = CSS.highlights.highlightsFromPoint(x, y);
- assert_equals(highlights.length, 1, 'CSS.highlights.highlightsFromPoint() returns one Highlight present at the coordinates provided');
- assert_equals(highlights[0], highlight, 'CSS.highlights.highlightsFromPoint() returns the Highlight present at the given coordinates even when no shadowRoots are provided because it\'s outside the shadow DOM');
+ let highlight_hit_results = CSS.highlights.highlightsFromPoint(x, y);
+ assert_equals(highlight_hit_results.length, 1, 'CSS.highlights.highlightsFromPoint() returns one Highlight present at the coordinates provided');
+ assert_equals(highlight_hit_results[0].highlight, highlight, 'CSS.highlights.highlightsFromPoint() returns the Highlight present at the given coordinates even when no shadowRoots are provided because it\'s outside the shadow DOM');
+ assert_array_equals(highlight_hit_results[0].ranges, [range], 'CSS.highlights.highlightsFromPoint() returns a HighlightHitResult with the ranges of the Highlight present at the coordinates provided');
// Now move y to the second line (inside shadow DOM).
y += characterHeight;
- highlights = CSS.highlights.highlightsFromPoint(x, y, {shadowRoots: [shadowRoot]});
- assert_equals(highlights.length, 0, 'CSS.highlights.highlightsFromPoint() returns no Highlights when the given coordinates point at text under the shadow root provided even when there is a Highlight set with a Range that starts and ends in the regular DOM surrounding it, even when shadowRoots are provided');
+ highlight_hit_results = CSS.highlights.highlightsFromPoint(x, y, {shadowRoots: [shadowRoot]});
+ assert_equals(highlight_hit_results.length, 0, 'CSS.highlights.highlightsFromPoint() returns no Highlights when the given coordinates point at text under the shadow root provided even when there is a Highlight set with a Range that starts and ends in the regular DOM surrounding it, even when shadowRoots are provided');
- highlights = CSS.highlights.highlightsFromPoint(x, y);
- assert_equals(highlights.length, 0, 'CSS.highlights.highlightsFromPoint() returns no Highlights when the given coordinates point at text under the shadow root provided even when there is a Highlight set with a Range that starts and ends in the regular DOM surrounding it');
+ highlight_hit_results = CSS.highlights.highlightsFromPoint(x, y);
+ assert_equals(highlight_hit_results.length, 0, 'CSS.highlights.highlightsFromPoint() returns no Highlights when the given coordinates point at text under the shadow root provided even when there is a Highlight set with a Range that starts and ends in the regular DOM surrounding it');
// Now move y to the third line.
y += characterHeight;
- highlights = CSS.highlights.highlightsFromPoint(x, y);
- assert_equals(highlights.length, 1, 'CSS.highlights.highlightsFromPoint() returns one Highlight present at the coordinates provided');
- assert_equals(highlights[0], highlight, 'CSS.highlights.highlightsFromPoint() returns the Highlight present at the given coordinates because it\'s outside of the shadow DOM');
+ highlight_hit_results = CSS.highlights.highlightsFromPoint(x, y);
+ assert_equals(highlight_hit_results.length, 1, 'CSS.highlights.highlightsFromPoint() returns one Highlight present at the coordinates provided');
+ assert_equals(highlight_hit_results[0].highlight, highlight, 'CSS.highlights.highlightsFromPoint() returns the Highlight present at the given coordinates because it\'s outside of the shadow DOM');
+ assert_array_equals(highlight_hit_results[0].ranges, [range], 'CSS.highlights.highlightsFromPoint() returns a HighlightHitResult with the ranges of the Highlight present at the coordinates provided');
// Set a Highlight with a range like this one:
// [0123456789
@@ -138,13 +143,13 @@ body {
// Set x and y coordinates between '0' and '1' in the first line.
y = container.getBoundingClientRect().top + characterHeight / 2.0;
- highlights = CSS.highlights.highlightsFromPoint(x, y, {shadowRoots: [shadowRoot]});
- assert_equals(highlights.length, 0, 'CSS.highlights.highlightsFromPoint() returns no Highlights when the given coordinates point at text in the light DOM that is not highlighted even when there is a Highlight set with a StaticRange that starts in the light DOM and ends in the shadow DOM surrounding it');
+ highlight_hit_results = CSS.highlights.highlightsFromPoint(x, y, {shadowRoots: [shadowRoot]});
+ assert_equals(highlight_hit_results.length, 0, 'CSS.highlights.highlightsFromPoint() returns no Highlights when the given coordinates point at text in the light DOM that is not highlighted even when there is a Highlight set with a StaticRange that starts in the light DOM and ends in the shadow DOM surrounding it');
// Now move y to the second line (inside shadow DOM).
y += characterHeight;
- highlights = CSS.highlights.highlightsFromPoint(x, y, {shadowRoots: [shadowRoot]});
- assert_equals(highlights.length, 0, 'CSS.highlights.highlightsFromPoint() returns no Highlights when the given coordinates point at text in the shadow DOM that is not highlighted even when there is a Highlight set with a StaticRange that starts in the light DOM and ends in the shadow DOM surrounding it');
+ highlight_hit_results = CSS.highlights.highlightsFromPoint(x, y, {shadowRoots: [shadowRoot]});
+ assert_equals(highlight_hit_results.length, 0, 'CSS.highlights.highlightsFromPoint() returns no Highlights when the given coordinates point at text in the shadow DOM that is not highlighted even when there is a Highlight set with a StaticRange that starts in the light DOM and ends in the shadow DOM surrounding it');
}, 'CSS.highlights.highlightsFromPoint() doesn\'t return Highlights that are not painted at the given coordinates even when they fall inside the Highlights\' ranges');
</script>
</body>
diff --git a/tests/wpt/tests/soft-navigation-heuristics/first-interaction-not-softnav.tentative.html b/tests/wpt/tests/soft-navigation-heuristics/first-interaction-not-softnav.tentative.html
index e0262021836..2c9e2aa7c01 100644
--- a/tests/wpt/tests/soft-navigation-heuristics/first-interaction-not-softnav.tentative.html
+++ b/tests/wpt/tests/soft-navigation-heuristics/first-interaction-not-softnav.tentative.html
@@ -1,36 +1,37 @@
-<!DOCTYPE HTML>
+<!doctype html>
<html>
-<head>
-<meta charset="utf-8">
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script src="/resources/testdriver.js"></script>
-<script src="/resources/testdriver-vendor.js"></script>
-<script src="resources/soft-navigation-helper.js"></script>
-</head>
-<body>
- <main id=main>
- <p><a id=firstlink>Click me!</a></p>
- <p><a id=secondlink>Then click me!</a></p>
- </main>
- <script>
- (async () => {
- if (test_driver) {
- const firstlink = document.getElementById("firstlink");
- const clickPromise = new Promise(r => {
- firstlink.addEventListener("click", r);
- });
- test_driver.click(firstlink);
- await clickPromise;
- }
- })();
- const secondlink = document.getElementById("secondlink");
- testSoftNavigation({
- addContent: () => {
- addImageToMain();
- },
- link: secondlink,
- test: "first interaction in the middle of a soft navigation"});
- </script>
-</body>
+ <head>
+ <meta charset="utf-8" />
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/resources/testdriver.js"></script>
+ <script src="/resources/testdriver-vendor.js"></script>
+ <script src="resources/soft-navigation-helper.js"></script>
+ </head>
+ <body>
+ <main id="main">
+ <p><a id="firstlink">Click me!</a></p>
+ <p><a id="secondlink">Then click me!</a></p>
+ </main>
+ <script>
+ const secondlink = document.getElementById("secondlink");
+ testSoftNavigation({
+ preTestWork: async () => {
+ if (test_driver) {
+ const firstlink = document.getElementById("firstlink");
+ const clickPromise = new Promise((r) => {
+ firstlink.addEventListener("click", r);
+ });
+ test_driver.click(firstlink);
+ await clickPromise;
+ }
+ },
+ addContent: () => {
+ addImageToMain();
+ },
+ link: secondlink,
+ test: "first interaction before a soft navigation",
+ });
+ </script>
+ </body>
</html>
diff --git a/tests/wpt/tests/soft-navigation-heuristics/innertext.tentative.html b/tests/wpt/tests/soft-navigation-heuristics/innertext.tentative.html
deleted file mode 100644
index 7716488f25a..00000000000
--- a/tests/wpt/tests/soft-navigation-heuristics/innertext.tentative.html
+++ /dev/null
@@ -1,37 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
-<meta charset="utf-8">
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<script src="/resources/testdriver.js"></script>
-<script src="/resources/testdriver-vendor.js"></script>
-<script src="resources/soft-navigation-helper.js"></script>
-</head>
-<body>
- <main id=main>
- <a id=link>Click me!</a>
- <!-- This test fails if the paragraph below already has content. The reason
- is that secondary paints are not being properly recorded, and hence don't
- count for soft navigation heuristics. -->
- <p id="softnav-content"></p>
- </main>
- <script>
- const link = document.getElementById("link");
- testSoftNavigation({
- addContent: async () => {
- document.getElementById("softnav-content").innerText =
- 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, ' +
- 'sed do eiusmod tempor incididunt ut labore et dolore magna ' +
- 'aliqua. Ut enim ad minim veniam, quis nostrud exercitation ' +
- 'ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis ' +
- 'aute irure dolor in reprehenderit in voluptate velit esse ' +
- 'cillum dolore eu fugiat nulla pariatur. Excepteur sint ' +
- 'occaecat cupidatat non proident, sunt in culpa qui officia ' +
- 'deserunt mollit anim id est laborum.';
- },
- link: link,
- test: "Soft navigation when only innerText was modified"});
- </script>
-</body>
-</html>
diff --git a/tests/wpt/tests/soft-navigation-heuristics/resources/soft-navigation-helper.js b/tests/wpt/tests/soft-navigation-heuristics/resources/soft-navigation-helper.js
index 48e7b58d8d1..5860738225b 100644
--- a/tests/wpt/tests/soft-navigation-heuristics/resources/soft-navigation-helper.js
+++ b/tests/wpt/tests/soft-navigation-heuristics/resources/soft-navigation-helper.js
@@ -48,7 +48,11 @@ const testSoftNavigation = options => {
const eventType = readValue(options.eventType, 'click');
const interactionFunc = options.interactionFunc;
const eventPrepWork = options.eventPrepWork;
+ const preTestWork = options.preTestWork;
promise_test(async t => {
+ if (preTestWork) {
+ await preTestWork();
+ }
await withTimeoutMessage(
t, waitInitialLCP(), 'Timed out waiting for initial LCP');
const preClickLcp = await withTimeoutMessage(
diff --git a/tests/wpt/tests/soft-navigation-heuristics/smoke/tentative/dom.html b/tests/wpt/tests/soft-navigation-heuristics/smoke/tentative/dom.html
index 66d23b22788..2e3c3809df6 100644
--- a/tests/wpt/tests/soft-navigation-heuristics/smoke/tentative/dom.html
+++ b/tests/wpt/tests/soft-navigation-heuristics/smoke/tentative/dom.html
@@ -61,6 +61,20 @@
document.body.appendChild(cloned);
history.pushState({}, "", "/template-element");
}
+
+ // Uses Element.innerText to add to the DOM, without overriding existing text.
+ // https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/innerText
+ function elementInnerTextInitial() {
+ document.getElementById("element-inner-text-initial-dest").innerText = "Hello, World.";
+ history.pushState({}, "", "/element-inner-text-initial");
+ }
+
+ // Uses Element.innerText to add to the DOM, overriding existing text.
+ // https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/innerText
+ function elementInnerTextOverride() {
+ document.getElementById("element-inner-text-override-dest").innerText = "Hello, World.";
+ history.pushState({}, "", "/element-inner-text-override");
+ }
</script>
</head>
<body>
@@ -70,6 +84,14 @@
<div id="document-import-node" onclick="documentImportNode()">Click here!</div>
<div id="document-adopt-node" onclick="documentAdoptNode()">Click here!</div>
<div id="template-element" onclick="templateElement()">Click here!</div>
+ <div id="element-inner-text-initial" onclick="elementInnerTextInitial()">
+ Click here!
+ <div id="element-inner-text-initial-dest"></div>
+ </div>
+ <div id="element-inner-text-override" onclick="elementInnerTextOverride()">
+ Click here!
+ <div id="element-inner-text-override-dest">Some text already there.</div>
+ </div>
<iframe id="iframe-example" srcdoc="&lt;div id='import-this'>Hello, World.&lt;/div>"></iframe>
@@ -111,6 +133,14 @@
"Soft Navigation Detection supports Document.adoptNode.",
);
test_template("template-element", "Soft Navigation Detection supports template elements.");
+ test_template(
+ "element-inner-text-initial",
+ "Soft Navigation Detection supports Element.innerText when it does not override existing text.",
+ );
+ test_template(
+ "element-inner-text-override",
+ "Soft Navigation Detection supports Element.innerText when it overrides existing text.",
+ );
</script>
</body>
</html>
diff --git a/tests/wpt/tests/soft-navigation-heuristics/smoke/tentative/resources/other_window.html b/tests/wpt/tests/soft-navigation-heuristics/smoke/tentative/resources/other_window.html
new file mode 100644
index 00000000000..406d39c3691
--- /dev/null
+++ b/tests/wpt/tests/soft-navigation-heuristics/smoke/tentative/resources/other_window.html
@@ -0,0 +1,19 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+
+<h1>This is some text</h1>
+
+<script>
+ function navigate() {
+ history.pushState({}, "", "/different-url");
+ }
+
+ async function getNextSoftNavEntry() {
+ return new Promise(resolve => {
+ new PerformanceObserver((list, observer) => {
+ observer.disconnect();
+ resolve(list.getEntries()[0]);
+ }).observe({ type: "soft-navigation" });
+ });
+ }
+</script>
diff --git a/tests/wpt/tests/soft-navigation-heuristics/smoke/tentative/window-open-cross-scheduling.html b/tests/wpt/tests/soft-navigation-heuristics/smoke/tentative/window-open-cross-scheduling.html
new file mode 100644
index 00000000000..1a41be6ddd2
--- /dev/null
+++ b/tests/wpt/tests/soft-navigation-heuristics/smoke/tentative/window-open-cross-scheduling.html
@@ -0,0 +1,45 @@
+<!doctype html>
+<html>
+ <head>
+ <meta charset="utf-8" />
+ <title>Scheduling soft navigations across windows.</title>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/resources/testdriver.js"></script>
+ <script src="/resources/testdriver-vendor.js"></script>
+ <script></script>
+ </head>
+ <body>
+ <button id="button" onclick="navigateChild()">Press Me!</button>
+
+ <script>
+ const child = window.open('resources/other_window.html');
+ const childLoaded = new Promise(resolve => child.onload = resolve);
+
+ function navigateChild() {
+ // `child.navigate()` is a function declared in the `other_window.html`.
+ child.navigate();
+ }
+
+ promise_test(async (t) => {
+ await childLoaded;
+
+ if (test_driver) {
+ test_driver.click(document.getElementById("button"));
+ }
+
+ new PerformanceObserver((list, observer) => t.step(() => {
+ observer.disconnect();
+ assert_unreached("Parent window should not detect a soft-navigation.");
+ })).observe({ type: "soft-navigation" });
+
+ child.getNextSoftNavEntry().then((entry) => {
+ assert_unreached("Child window should not detect a soft-navigation.");
+ });
+
+ await new Promise(resolve => t.step_timeout(resolve, 2000));
+
+ }, "Opening a new window and updating a URL in it shouldn't crash");
+ </script>
+ </body>
+</html>
diff --git a/tests/wpt/tests/speculation-rules/prefetch/no-prefetch-for-post.https.html b/tests/wpt/tests/speculation-rules/prefetch/no-prefetch-for-post.https.html
new file mode 100644
index 00000000000..7739f4f8c71
--- /dev/null
+++ b/tests/wpt/tests/speculation-rules/prefetch/no-prefetch-for-post.https.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<meta name="timeout" content="long">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/dispatcher/dispatcher.js"></script>
+<script src="/common/utils.js"></script>
+<script src="../resources/utils.js"></script>
+<script src="resources/utils.sub.js"></script>
+<script>
+ setup(() => assertSpeculationRulesIsSupported());
+
+ promise_test(async t => {
+ let agent = await spawnWindow(t);
+ let nextUrl = agent.getExecutorURL({ executor: 'post-navigation-handler.py', protocol: 'https', page: 2 });
+ await agent.forceSinglePrefetch(nextUrl);
+
+ await agent.execute_script(async (nextUrl) => {
+ window.executor.suspend(() => {
+ navigate_by_form_generated_post(nextUrl);
+ });
+ }, [nextUrl]);
+
+ assert_not_prefetched(await agent.getRequestHeaders());
+ }, "post navigations should not use cached prefetch");
+</script>
diff --git a/tests/wpt/tests/speculation-rules/prefetch/resources/executor.sub.html b/tests/wpt/tests/speculation-rules/prefetch/resources/executor.sub.html
index bb2d58dc9c9..b89c45e4f5c 100644
--- a/tests/wpt/tests/speculation-rules/prefetch/resources/executor.sub.html
+++ b/tests/wpt/tests/speculation-rules/prefetch/resources/executor.sub.html
@@ -82,6 +82,13 @@ async function start_non_eager_prefetch_on_pointerdown(id) {
await new test_driver.Actions().addPointer("mouse").pointerMove(0, 0, {origin: target}).pointerDown().pointerMove(0, 0).pointerUp().send();
}
+async function navigate_by_form_generated_post(url) {
+ let form = document.createElement('form');
+ form.method = 'POST';
+ form.action = url;
+ document.body.appendChild(form);
+ form.submit();
+}
// The fetch request's URL sent to the server.
window.requestUrl = reverse_html_escape(
diff --git a/tests/wpt/tests/speculation-rules/prefetch/resources/post-navigation-handler.py b/tests/wpt/tests/speculation-rules/prefetch/resources/post-navigation-handler.py
new file mode 100644
index 00000000000..1749517710e
--- /dev/null
+++ b/tests/wpt/tests/speculation-rules/prefetch/resources/post-navigation-handler.py
@@ -0,0 +1,10 @@
+import os
+from wptserve.pipes import template
+
+# This is used only to accept POST navigations.
+def main(request, response):
+ response.headers.set(b"Content-Type", b"text/html")
+ response.headers.set(b"Cache-Control", b"no-store")
+ response.content = template(
+ request,
+ open(os.path.join(os.path.dirname(__file__), "executor.sub.html"), "rb").read()) \ No newline at end of file
diff --git a/tests/wpt/tests/speculation-rules/prerender/headers.https.html b/tests/wpt/tests/speculation-rules/prerender/headers.https.html
new file mode 100644
index 00000000000..2ef6b5ce072
--- /dev/null
+++ b/tests/wpt/tests/speculation-rules/prerender/headers.https.html
@@ -0,0 +1,159 @@
+<!DOCTYPE html>
+<title>Sec-Purpose header on prerendered page</title>
+<meta name="timeout" content="long">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/get-host-info.sub.js"></script>
+<script src="/common/utils.js"></script>
+<script src="/common/dispatcher/dispatcher.js"></script>
+<script src="/html/browsers/browsing-the-web/remote-context-helper/resources/remote-context-helper.js"></script>
+<script src="../resources/utils.js"></script>
+<script src="resources/utils.js"></script>
+
+<body>
+<script>
+setup(() => assertSpeculationRulesIsSupported());
+
+promise_test(async () => {
+ const rcHelper = new RemoteContextHelper();
+ const referrerRC = await rcHelper.addWindow(undefined, { features: 'noopener' });
+ const prerenderedRC = await addPrerenderRC(referrerRC);
+
+ const prerenderedHeaders = await prerenderedRC.getRequestHeaders();
+ assertHeaders(prerenderedHeaders, true, true, 'prerendered page');
+
+ const iframeRC = await prerenderedRC.addIframe();
+ const iframeHeaders = await iframeRC.getRequestHeaders();
+ assertHeaders(iframeHeaders, true, false, 'iframe');
+
+ // No test for cross-origin iframe, since those requests are delayed until
+ // after activation. See below.
+
+ const imageHeaders = await insertImageAndGetRequestHeaders(prerenderedRC);
+ assertHeaders(imageHeaders, true, false, 'image');
+
+ const crossOriginImageHeaders = await insertImageAndGetRequestHeaders(
+ prerenderedRC,
+ get_host_info().HTTPS_REMOTE_ORIGIN
+ );
+ assertHeaders(crossOriginImageHeaders, true, false, 'cross-origin image');
+
+ const fetchHeaders = await doFetchAndGetRequestHeaders(prerenderedRC);
+ assertHeaders(fetchHeaders, true, false, 'fetch');
+
+ const crossOriginFetchHeaders = await doFetchAndGetRequestHeaders(
+ prerenderedRC,
+ get_host_info().HTTPS_REMOTE_ORIGIN
+ );
+ assertHeaders(crossOriginFetchHeaders, true, false, 'cross-origin fetch');
+
+ const navigatedToRC = await prerenderedRC.navigateToNew();
+ const navigatedToHeaders = await navigatedToRC.getRequestHeaders();
+ assertHeaders(navigatedToHeaders, true, false, 'navigated-to page');
+}, 'Headers before activation, including prerendered page navigation');
+
+promise_test(async () => {
+ const rcHelper = new RemoteContextHelper();
+ const referrerRC = await rcHelper.addWindow(undefined, { features: 'noopener' });
+ const prerenderedRC = await addPrerenderRC(referrerRC);
+
+ // Add the iframe now, but only check its headers after activation.
+ const crossOriginIframeBeforeActivationRC = await prerenderedRC.addIframe({ origin: 'HTTPS_REMOTE_ORIGIN' });
+
+ await activatePrerenderRC(referrerRC, prerenderedRC);
+
+ const crossOriginIframeBeforeActivationHeaders = await crossOriginIframeBeforeActivationRC.getRequestHeaders();
+ assertHeaders(crossOriginIframeBeforeActivationHeaders, true, false, 'cross-origin iframe before activation');
+
+ const iframeRC = await prerenderedRC.addIframe();
+ const iframeHeaders = await iframeRC.getRequestHeaders();
+ assertHeaders(iframeHeaders, false, false, 'post-activation iframe');
+
+ const imageHeaders = await insertImageAndGetRequestHeaders(prerenderedRC);
+ assertHeaders(imageHeaders, false, false, 'post-activation image');
+
+ const crossOriginImageHeaders = await insertImageAndGetRequestHeaders(
+ prerenderedRC,
+ get_host_info().HTTPS_REMOTE_ORIGIN
+ );
+ assertHeaders(crossOriginImageHeaders, false, false, 'cross-origin image');
+
+ const fetchHeaders = await doFetchAndGetRequestHeaders(prerenderedRC);
+ assertHeaders(fetchHeaders, false, false, 'post-activation fetch');
+
+ const crossOriginFetchHeaders = await doFetchAndGetRequestHeaders(
+ prerenderedRC,
+ get_host_info().HTTPS_REMOTE_ORIGIN
+ );
+ assertHeaders(crossOriginFetchHeaders, false, false, 'cross-origin fetch');
+}, 'Headers after activation (plus cross-origin iframe before activation)');
+
+async function insertImageAndGetRequestHeaders(rc, hostname) {
+ const uuid = token();
+ const url = (new URL(`resources/image-with-headers-stash.py?image=${uuid}`, location.href));
+ const headersURL = (new URL(`resources/image-with-headers-stash.py?read=${uuid}`, location.href));
+
+ if (hostname !== undefined) {
+ url.hostname = hostname;
+ headersURL.hostname = hostname;
+ }
+
+ await rc.executeScript(async (url) => {
+ const img = new Image();
+ img.src = url;
+ const promise = new Promise(resolve => img.onload = resolve);
+ document.body.append(img);
+ return promise;
+ }, [url]);
+
+ const headersJSON = await (await fetch(headersURL)).json();
+ assert_not_equals(headersJSON, null, 'image headers should not be null');
+ return new Headers(headersJSON);
+}
+
+async function doFetchAndGetRequestHeaders(rc, hostname) {
+ const uuid = token();
+ const url = (new URL(`resources/image-with-headers-stash.py?image=${uuid}`, location.href));
+ const headersURL = (new URL(`resources/image-with-headers-stash.py?read=${uuid}`, location.href));
+
+ if (hostname !== undefined) {
+ url.hostname = hostname;
+ headersURL.hostname = hostname;
+ }
+
+ await rc.executeScript(async (url) => {
+ return fetch(url, { mode: "cors" });
+ }, [url]);
+
+ const headersJSON = await (await fetch(headersURL)).json();
+ assert_not_equals(headersJSON, null, 'fetch headers should not be null');
+ return new Headers(headersJSON);
+}
+
+function assertHeaders(headers, secPurposeIsPrefetchPrerender, secSpeculationTagsIsPresent, label) {
+ if (secPurposeIsPrefetchPrerender) {
+ assert_equals(
+ headers.get('Sec-Purpose'),
+ 'prefetch;prerender',
+ `${label} Sec-Purpose`
+ );
+ } else {
+ assert_false(
+ headers.has('Sec-Purpose'),
+ `${label} Sec-Purpose should not be present`
+ );
+ }
+ if (secSpeculationTagsIsPresent) {
+ assert_equals(
+ headers.get('Sec-Speculation-Tags'),
+ 'null',
+ `${label} Sec-Speculation-Tags`
+ );
+ } else {
+ assert_false(
+ headers.has('Sec-Speculation-Tags'),
+ `${label} Sec-Speculation-Tags should not be present`
+ );
+ }
+}
+</script>
diff --git a/tests/wpt/tests/speculation-rules/prerender/resources/image-with-headers-stash.py b/tests/wpt/tests/speculation-rules/prerender/resources/image-with-headers-stash.py
new file mode 100644
index 00000000000..dcb8838d4a1
--- /dev/null
+++ b/tests/wpt/tests/speculation-rules/prerender/resources/image-with-headers-stash.py
@@ -0,0 +1,45 @@
+# Supports two operations:
+# - ?image=uuid: Returns an image, and records the request headers that were
+# used to get that image.
+# - ?read=uuid: Returns the request headers in the stash keyed by a given uuid.
+
+import os
+import json
+
+from wptserve.utils import isomorphic_decode
+
+def main(request, response):
+ if b"image" in request.GET:
+ uuid = request.GET[b"image"]
+
+ header_pairs = []
+ for header_name in request.headers.keys():
+ # ensure the header name/value are unicode strings
+ name = header_name.lower().decode("utf-8")
+ for header_value in request.headers.get_list(header_name):
+ value = header_value.decode("utf-8")
+ header_pairs.append([name, value])
+
+ request_headers = json.dumps(header_pairs)
+ request.server.stash.put(uuid, request_headers)
+
+ # Return a basic image.
+ response_headers = [
+ (b"Content-Type", b"image/png"),
+ (b"Access-Control-Allow-Origin", b"*")
+ ]
+ image_path = os.path.join(
+ os.path.dirname(isomorphic_decode(__file__)),
+ u"../../../common/square.png"
+ )
+ return (200, response_headers, open(image_path, mode='rb').read())
+
+ elif b"read" in request.GET:
+ uuid = request.GET[b"read"]
+ stash_value = request.server.stash.take(uuid)
+
+ if stash_value is None:
+ stash_value = "null"
+ return (200, [(b"Content-Type", b"application/json")], str(stash_value))
+
+ return (404 , [], "Not found")
diff --git a/tests/wpt/tests/svg/embedded/image-modify-href-4.svg b/tests/wpt/tests/svg/embedded/image-modify-href-4.svg
new file mode 100644
index 00000000000..f7e550e5def
--- /dev/null
+++ b/tests/wpt/tests/svg/embedded/image-modify-href-4.svg
@@ -0,0 +1,30 @@
+<svg xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:h="http://www.w3.org/1999/xhtml" width="200" height="200" class="reftest-wait" onload="test()">
+ <metadata>
+ <title>modifying xlink:href on an SVG image</title>
+ <h:link rel="match" href="reference/green-rect-100x100.svg"/>
+ </metadata>
+ <script href="/common/reftest-wait.js"></script>
+ <script href="/common/rendering-utils.js"></script>
+ <script>
+ const SVG_NS = "http://www.w3.org/2000/svg";
+
+ async function test() {
+ await waitForAtLeastOneFrame();
+
+ const doc = document.implementation.createDocument(SVG_NS, "svg");
+
+ const image = doc.createElementNS(SVG_NS, "image");
+ image.setAttribute("width", 100);
+ image.setAttribute("height", 100);
+ image.setAttribute("href", "reference/green-rect-100x100.svg");
+ doc.documentElement.appendChild(image);
+
+ document.documentElement.appendChild(document.adoptNode(image));
+
+ await waitForAtLeastOneFrame();
+ takeScreenshot();
+ }
+ </script>
+</svg>
diff --git a/tests/wpt/tests/tools/third_party_modified/mozlog/mozlog/handlers/base.py b/tests/wpt/tests/tools/third_party_modified/mozlog/mozlog/handlers/base.py
index 7cea14c7a44..707b539ec76 100644
--- a/tests/wpt/tests/tools/third_party_modified/mozlog/mozlog/handlers/base.py
+++ b/tests/wpt/tests/tools/third_party_modified/mozlog/mozlog/handlers/base.py
@@ -18,7 +18,7 @@ class BaseHandler(object):
def __init__(self, inner):
self.message_handler = MessageHandler()
if hasattr(inner, "message_handler"):
- self.message_handler.wrapped.append(inner)
+ self.message_handler.wrapped.append(inner.message_handler)
class LogLevelFilter(BaseHandler):
diff --git a/tests/wpt/tests/tools/wptrunner/wptrunner/browsers/firefox_android.py b/tests/wpt/tests/tools/wptrunner/wptrunner/browsers/firefox_android.py
index 7bb2e57d417..d0cd7411af0 100644
--- a/tests/wpt/tests/tools/wptrunner/wptrunner/browsers/firefox_android.py
+++ b/tests/wpt/tests/tools/wptrunner/wptrunner/browsers/firefox_android.py
@@ -381,6 +381,9 @@ class FirefoxAndroidBrowser(Browser):
class FirefoxAndroidWdSpecBrowser(FirefoxWdSpecBrowser):
def __init__(self, logger, config=None, device_serial=None, adb_binary=None, **kwargs):
+ if "profile_creator_cls" not in kwargs:
+ kwargs["profile_creator_cls"] = ProfileCreator
+
super().__init__(logger, config=config, **kwargs)
self.config = config
diff --git a/tests/wpt/tests/tools/wptrunner/wptrunner/browsers/headless_shell.py b/tests/wpt/tests/tools/wptrunner/wptrunner/browsers/headless_shell.py
index b6f7a40f8a9..ccd5620365a 100644
--- a/tests/wpt/tests/tools/wptrunner/wptrunner/browsers/headless_shell.py
+++ b/tests/wpt/tests/tools/wptrunner/wptrunner/browsers/headless_shell.py
@@ -3,6 +3,7 @@
from .base import require_arg
from .base import get_timeout_multiplier # noqa: F401
from .chrome import ChromeBrowser # noqa: F401
+from .chrome import browser_kwargs as browser_kwargs # noqa: F401
from .chrome import executor_kwargs as chrome_executor_kwargs
from ..executors.base import WdspecExecutor # noqa: F401
from ..executors.executorchrome import ( # noqa: F401
@@ -35,13 +36,6 @@ def check_args(**kwargs):
require_arg(kwargs, "webdriver_binary")
-def browser_kwargs(logger, test_type, run_info_data, config, **kwargs):
- return {"binary": kwargs["binary"],
- "webdriver_binary": kwargs["webdriver_binary"],
- "webdriver_args": kwargs.get("webdriver_args"),
- "debug_info": kwargs["debug_info"]}
-
-
def executor_kwargs(logger, test_type, test_environment, run_info_data, subsuite,
**kwargs):
executor_kwargs = chrome_executor_kwargs(logger, test_type, test_environment, run_info_data,
diff --git a/tests/wpt/tests/tools/wptrunner/wptrunner/browsers/servo.py b/tests/wpt/tests/tools/wptrunner/wptrunner/browsers/servo.py
index 266aec8fced..49a2613ff12 100644
--- a/tests/wpt/tests/tools/wptrunner/wptrunner/browsers/servo.py
+++ b/tests/wpt/tests/tools/wptrunner/wptrunner/browsers/servo.py
@@ -37,7 +37,8 @@ def check_args(**kwargs):
require_arg(kwargs, "binary")
-def browser_kwargs(logger, test_type, run_info_data, config, **kwargs):
+def browser_kwargs(logger, test_type, run_info_data, config, subsuite, **kwargs):
+ kwargs["binary_args"].extend(subsuite.config.get("binary_args", []))
return {
"binary": kwargs["binary"],
"debug_info": kwargs["debug_info"],
@@ -68,7 +69,7 @@ def env_options():
def update_properties():
- return ["debug", "os", "processor"], {"os": ["version"], "processor": ["bits"]}
+ return ["debug", "os", "processor", "subsuite"], {"os": ["version"], "processor": ["bits"]}
class ServoBrowser(NullBrowser):
diff --git a/tests/wpt/tests/tools/wptrunner/wptrunner/browsers/servodriver.py b/tests/wpt/tests/tools/wptrunner/wptrunner/browsers/servodriver.py
index 5011a8fd859..a8aa5ae001b 100644
--- a/tests/wpt/tests/tools/wptrunner/wptrunner/browsers/servodriver.py
+++ b/tests/wpt/tests/tools/wptrunner/wptrunner/browsers/servodriver.py
@@ -39,7 +39,8 @@ def check_args(**kwargs):
require_arg(kwargs, "binary")
-def browser_kwargs(logger, test_type, run_info_data, config, **kwargs):
+def browser_kwargs(logger, test_type, run_info_data, config, subsuite, **kwargs):
+ kwargs["binary_args"].extend(subsuite.config.get("binary_args", []))
return {
"binary": kwargs["binary"],
"binary_args": kwargs["binary_args"],
@@ -67,7 +68,7 @@ def env_options():
def update_properties():
- return (["debug", "os", "processor"], {"os": ["version"], "processor": ["bits"]})
+ return (["debug", "os", "processor", "subsuite"], {"os": ["version"], "processor": ["bits"]})
def write_hosts_file(config):
diff --git a/tests/wpt/tests/tools/wptrunner/wptrunner/executors/executorchrome.py b/tests/wpt/tests/tools/wptrunner/wptrunner/executors/executorchrome.py
index 1e588d5bfbf..3284e6c8091 100644
--- a/tests/wpt/tests/tools/wptrunner/wptrunner/executors/executorchrome.py
+++ b/tests/wpt/tests/tools/wptrunner/wptrunner/executors/executorchrome.py
@@ -304,6 +304,10 @@ class ChromeDriverTestharnessExecutor(WebDriverTestharnessExecutor):
test_window = self.protocol.testharness.persistent_test_window = None
if not test_window:
test_window = super().get_or_create_test_window(protocol)
+ if self.reuse_window:
+ self.logger.info(f"Created new test window {test_window}")
+ # Without `--reuse-window`, each testharness test always creates a
+ # new window, so tracing that event is not interesting.
if self.reuse_window:
self.protocol.testharness.persistent_test_window = test_window
return test_window
diff --git a/tests/wpt/tests/tools/wptrunner/wptrunner/testrunner.py b/tests/wpt/tests/tools/wptrunner/wptrunner/testrunner.py
index 19c814bb6c9..be310944fd8 100644
--- a/tests/wpt/tests/tools/wptrunner/wptrunner/testrunner.py
+++ b/tests/wpt/tests/tools/wptrunner/wptrunner/testrunner.py
@@ -313,7 +313,7 @@ class TestSource:
if not self.current_group.group or len(self.current_group.group) == 0:
try:
self.current_group = self.test_queue.get()
- self.logger.debug(f"Got new test group subsuite:{self.current_group[1]} "
+ self.logger.debug(f"Got new test group subsuite:{self.current_group[1]!r} "
f"test_type:{self.current_group[2]}")
except Empty:
return testloader.TestGroup(None, None, None, None)
@@ -473,11 +473,11 @@ class TestRunnerManager(threading.Thread):
if skipped_tests:
self.logger.critical(
- f"Tests left in the queue: {subsuite}:{skipped_tests[0].id!r} "
+ f"Tests left in the queue: {subsuite!r}:{skipped_tests[0].id!r} "
f"and {len(skipped_tests) - 1} others"
)
for test in skipped_tests[1:]:
- self.logger.debug(f"Test left in the queue: {subsuite}:{test.id!r}")
+ self.logger.debug(f"Test left in the queue: {subsuite!r}:{test.id!r}")
force_stop = (not isinstance(self.state, RunnerManagerState.stop) or
self.state.force_stop)
@@ -900,7 +900,7 @@ class TestRunnerManager(threading.Thread):
if test is None:
return RunnerManagerState.stop(force_stop)
if subsuite != self.state.subsuite:
- self.logger.info(f"Restarting browser for new subsuite:{subsuite}")
+ self.logger.info(f"Restarting browser for new subsuite:{subsuite!r}")
restart = True
elif self.restart_on_new_group and test_group is not self.state.test_group:
self.logger.info("Restarting browser for new test group")
diff --git a/tests/wpt/tests/trusted-types/block-text-node-insertion-into-script-element.html b/tests/wpt/tests/trusted-types/block-text-node-insertion-into-script-element.html
index 65b40b933ff..1a1256d05a8 100644
--- a/tests/wpt/tests/trusted-types/block-text-node-insertion-into-script-element.html
+++ b/tests/wpt/tests/trusted-types/block-text-node-insertion-into-script-element.html
@@ -49,12 +49,12 @@
assert_equals(s.text, "");
// Try to insertAdjacentText into the <script>, starting from the <p>
- await checkMessage(_ =>
+ await checkMessage(t, _ =>
p.insertAdjacentText("beforebegin",
"postMessage('beforebegin should be blocked', '*');")
);
assert_true(s.text.includes("postMessage"));
- await checkMessage(_ =>
+ await checkMessage(t, _ =>
p.insertAdjacentText("afterend",
"postMessage('afterend should be blocked', '*');")
);
@@ -74,12 +74,12 @@
container.appendChild(s);
// Try to insertAdjacentText into the <script>, starting from the <p>
- await checkMessage(_ =>
+ await checkMessage(t, _ =>
p.insertAdjacentText("beforebegin",
"postMessage('beforebegin should be blocked', '*');")
);
assert_true(s.textContent.includes("postMessage"));
- await checkMessage(_ =>
+ await checkMessage(t, _ =>
p.insertAdjacentText("afterend",
"postMessage('afterend should be blocked', '*');")
);
@@ -94,7 +94,7 @@
let text = document.createTextNode("postMessage('appendChild with a " +
"text node should be blocked', '*');");
s.appendChild(text);
- await checkMessage(_ => container.appendChild(s));
+ await checkMessage(t, _ => container.appendChild(s));
}, "Regression test: Bypass via appendChild into off-document script element.");
// Variant: Create a <script> element and insert it into the document. Then
@@ -106,7 +106,7 @@
container.appendChild(s);
let text = document.createTextNode("postMessage('appendChild with a live " +
"text node should be blocked', '*');");
- await checkMessage(_ => s.appendChild(text));
+ await checkMessage(t, _ => s.appendChild(text));
}, "Regression test: Bypass via appendChild into live script element.");
promise_test(async t => {
@@ -150,7 +150,7 @@
let text = document.createTextNode("postMessage('default', '*');");
s.appendChild(text);
await no_trusted_type_violation_for(async _ =>
- await checkMessage(_ => container.appendChild(s), 1)
+ await checkMessage(t, _ => container.appendChild(s), 1)
);
assert_array_equals(seenSinks, ["HTMLScriptElement text"]);
}, "Test that default policy applies.");
@@ -158,10 +158,22 @@
promise_test(async t => {
t.add_cleanup(clearSeenSinks);
let s = createScriptElement();
+ s.setAttribute("type", "module")
+ let text = document.createTextNode("postMessage('default', '*');");
+ s.appendChild(text);
+ await no_trusted_type_violation_for(async _ =>
+ await checkMessage(t, _ => container.appendChild(s), 1)
+ );
+ assert_array_equals(seenSinks, ["HTMLScriptElement text"]);
+ }, "Test that default policy applies to module script.");
+
+ promise_test(async t => {
+ t.add_cleanup(clearSeenSinks);
+ let s = createScriptElement();
let text = document.createTextNode("fail");
s.appendChild(text);
await trusted_type_violation_without_exception_for(async _ =>
- await checkMessage(_ => container.appendChild(s), 0)
+ await checkMessage(t, _ => container.appendChild(s), 0)
);
assert_array_equals(seenSinks, ["HTMLScriptElement text"]);
}, "Test a failing default policy.");
diff --git a/tests/wpt/tests/trusted-types/block-text-node-insertion-into-svg-script-element.html b/tests/wpt/tests/trusted-types/block-text-node-insertion-into-svg-script-element.html
index f4ff2435035..18c6af8f5ef 100644
--- a/tests/wpt/tests/trusted-types/block-text-node-insertion-into-svg-script-element.html
+++ b/tests/wpt/tests/trusted-types/block-text-node-insertion-into-svg-script-element.html
@@ -49,12 +49,12 @@
container.appendChild(s);
// Try to insertAdjacentText into the <script>, starting from the <p>
- await checkMessage(_ =>
+ await checkMessage(t, _ =>
p.insertAdjacentText("beforebegin",
"postMessage('beforebegin should be blocked', '*');")
);
assert_true(s.textContent.includes("postMessage"));
- await checkMessage(_ =>
+ await checkMessage(t, _ =>
p.insertAdjacentText("afterend",
"postMessage('afterend should be blocked', '*');")
);
@@ -69,7 +69,7 @@
let text = document.createTextNode("postMessage('appendChild with a " +
"text node should be blocked', '*');");
s.appendChild(text);
- await checkMessage(_ => container.appendChild(s));
+ await checkMessage(t, _ => container.appendChild(s));
}, "Regression test: Bypass via appendChild into off-document script element. svg:script");
// Variant: Create a <script> element and insert it into the document. Then
@@ -81,7 +81,7 @@
container.appendChild(s);
let text = document.createTextNode("postMessage('appendChild with a live " +
"text node should be blocked', '*');");
- await checkMessage(_ => s.appendChild(text));
+ await checkMessage(t, _ => s.appendChild(text));
}, "Regression test: Bypass via appendChild into live script element. svg:script");
promise_test(async t => {
@@ -125,7 +125,7 @@
let text = document.createTextNode("postMessage('default', '*');");
s.appendChild(text);
await no_trusted_type_violation_for(async _ =>
- await checkMessage(_ => container.appendChild(s), 1)
+ await checkMessage(t, _ => container.appendChild(s), 1)
);
assert_array_equals(seenSinks, ["SVGScriptElement text"]);
}, "Test that default policy applies. svg:script");
@@ -133,10 +133,22 @@
promise_test(async t => {
t.add_cleanup(clearSeenSinks);
let s = createScriptElement();
+ s.setAttribute("type", "module");
+ let text = document.createTextNode("postMessage('default', '*');");
+ s.appendChild(text);
+ await no_trusted_type_violation_for(async _ =>
+ await checkMessage(t, _ => container.appendChild(s), 1)
+ );
+ assert_array_equals(seenSinks, ["SVGScriptElement text"]);
+ }, "Test that default policy applies with module script. svg:script");
+
+ promise_test(async t => {
+ t.add_cleanup(clearSeenSinks);
+ let s = createScriptElement();
let text = document.createTextNode("fail");
s.appendChild(text);
await trusted_type_violation_without_exception_for(async _ =>
- await checkMessage(_ => container.appendChild(s), 0)
+ await checkMessage(t, _ => container.appendChild(s), 0)
);
assert_array_equals(seenSinks, ["SVGScriptElement text"]);
}, "Test a failing default policy. svg:script");
diff --git a/tests/wpt/tests/trusted-types/resources/block-text-node-insertion.js b/tests/wpt/tests/trusted-types/resources/block-text-node-insertion.js
index e9797756417..dd85483a44f 100644
--- a/tests/wpt/tests/trusted-types/resources/block-text-node-insertion.js
+++ b/tests/wpt/tests/trusted-types/resources/block-text-node-insertion.js
@@ -14,10 +14,13 @@
// - includes "count": Count these, and later check against expect_count.
// - includes "done": Unregister the event handler and finish the test.
// - all else: Reject, as this is probably an error in the test.
- function checkMessage(fn, expect_count) {
+ function checkMessage(t, fn, expect_count) {
return new Promise((resolve, reject) => {
let count = 0;
globalThis.addEventListener("message", function handler(e) {
+ t.add_cleanup(() => {
+ globalThis.removeEventListener("message", handler);
+ });
if (e.data.includes("block")) {
reject(`'block' received (${e.data})`);
} else if (e.data.includes("count")) {
@@ -35,6 +38,6 @@
}
});
fn();
- postMessage("done", "*");
+ requestAnimationFrame(_ => requestAnimationFrame(_ => postMessage("done", "*")));
});
}
diff --git a/tests/wpt/tests/ua-client-hints/WEB_FEATURES.yml b/tests/wpt/tests/ua-client-hints/WEB_FEATURES.yml
new file mode 100644
index 00000000000..2d331cf4060
--- /dev/null
+++ b/tests/wpt/tests/ua-client-hints/WEB_FEATURES.yml
@@ -0,0 +1,3 @@
+features:
+- name: ua-client-hints
+ files: "**"
diff --git a/tests/wpt/tests/uievents/legacy-domevents-tests/approved/ProcessingInstruction.DOMCharacterDataModified.html b/tests/wpt/tests/uievents/legacy-domevents-tests/approved/ProcessingInstruction.DOMCharacterDataModified.html
deleted file mode 100644
index 2da0a389e2e..00000000000
--- a/tests/wpt/tests/uievents/legacy-domevents-tests/approved/ProcessingInstruction.DOMCharacterDataModified.html
+++ /dev/null
@@ -1,32 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<title> ProcessingInstruction.data and DOMCharacterDataModified event </title>
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-</head>
-<body>
-<div id=log></div>
-
-<iframe id="helper" style="display: none"></iframe>
-
-<script>
- var description = "Test Description: " +
- "DOMCharacterDataModified event fires after ProcessingInstruction.data have been modified, " +
- "but the node itself has not been inserted or deleted. The proximal event target of this " +
- "event shall be the ProcessingInstruction node.";
-
- var t = async_test(description);
-
- var HELPER = document.getElementById("helper");
-
- HELPER.onload = t.step_func(function()
- {
- assert_true(HELPER.contentWindow.TestResult);
- t.done();
- });
-
- HELPER.src = "./support/ProcessingInstruction.DOMCharacterDataModified.xml";
-</script>
-</body>
-</html>
diff --git a/tests/wpt/tests/uievents/legacy-domevents-tests/approved/domnodeinserted.html b/tests/wpt/tests/uievents/legacy-domevents-tests/approved/domnodeinserted.html
deleted file mode 100644
index e5064d8d46c..00000000000
--- a/tests/wpt/tests/uievents/legacy-domevents-tests/approved/domnodeinserted.html
+++ /dev/null
@@ -1,26 +0,0 @@
-<!DOCTYPE html>
-<title>MutationEvent: DOMNodeInserted Event Type</title>
-<script src="/resources/testharness.js"></script>
-<script src="/resources/testharnessreport.js"></script>
-<div id=log></div>
-
-<div id="target" style="display: none"></div>
-
-<script>
-var EVENT = "DOMNodeInserted";
-var TARGET;
-var NODE;
-
-var t = async_test("Test Description: DOMNodeInserted event fires when a node has been added as a child of another node.");
-
-TARGET = document.getElementById("target");
-
-TARGET.addEventListener(EVENT, t.step_func(function(evt)
-{
- assert_equals(evt.type, EVENT);
- t.done();
-}), true);
-
-NODE = document.createElement("INPUT");
-TARGET.appendChild(NODE);
-</script>
diff --git a/tests/wpt/tests/urlpattern/resources/urlpattern-generate-test-data.json b/tests/wpt/tests/urlpattern/resources/urlpattern-generate-test-data.json
new file mode 100644
index 00000000000..c118f0a73b5
--- /dev/null
+++ b/tests/wpt/tests/urlpattern/resources/urlpattern-generate-test-data.json
@@ -0,0 +1,116 @@
+[
+ {
+ "pattern": { "pathname": "/foo" },
+ "component": "invalid",
+ "groups": {},
+ "expected": null
+ },
+ {
+ "pattern": { "pathname": "/foo" },
+ "component": "pathname",
+ "groups": {},
+ "expected": "/foo"
+ },
+ {
+ "pattern": { "pathname": "/:foo" },
+ "component": "pathname",
+ "groups": { "foo": "bar" },
+ "expected": "/bar"
+ },
+ {
+ "pattern": { "pathname": "/:foo" },
+ "component": "pathname",
+ "groups": { "foo": "🍅" },
+ "expected": "/%F0%9F%8D%85"
+ },
+ {
+ "pattern": { "hostname": "{:foo}.example.com" },
+ "component": "hostname",
+ "groups": { "foo": "🍅" },
+ "expected": "xn--fi8h.example.com"
+ },
+ {
+ "pattern": { "pathname": "/:foo" },
+ "component": "pathname",
+ "groups": {},
+ "expected": null
+ },
+ {
+ "pattern": { "pathname": "/foo/:bar" },
+ "component": "pathname",
+ "groups": { "bar": "baz" },
+ "expected": "/foo/baz"
+ },
+ {
+ "pattern": { "pathname": "/foo:bar" },
+ "component": "pathname",
+ "groups": { "bar": "baz" },
+ "expected": "/foobaz"
+ },
+ {
+ "pattern": { "pathname": "/:foo/:bar" },
+ "component": "pathname",
+ "groups": { "foo": "baz", "bar": "qux" },
+ "expected": "/baz/qux"
+ },
+ {
+ "pattern": "https://example.com/:foo",
+ "component": "pathname",
+ "groups": { "foo": " " },
+ "expected": "/%20"
+ },
+ {
+ "pattern": "original-scheme://example.com/:foo",
+ "component": "pathname",
+ "groups": { "foo": " " },
+ "expected": "/ "
+ },
+ {
+ "pattern": { "pathname": "/:foo" },
+ "component": "pathname",
+ "groups": { "foo": "bar/baz" },
+ "expected": null
+ },
+ {
+ "pattern": { "pathname": "*" },
+ "component": "pathname",
+ "groups": {},
+ "expected": null
+ },
+ {
+ "pattern": { "pathname": "/{foo}+" },
+ "component": "pathname",
+ "groups": {},
+ "expected": null
+ },
+ {
+ "pattern": { "pathname": "/{foo}?" },
+ "component": "pathname",
+ "groups": {},
+ "expected": null
+ },
+ {
+ "pattern": { "pathname": "/{foo}*" },
+ "component": "pathname",
+ "groups": {},
+ "expected": null
+ },
+ {
+ "pattern": { "pathname": "/(regexp)" },
+ "component": "pathname",
+ "groups": {},
+ "expected": null
+ },
+ {
+ "pattern": { "pathname": "/([^\\/]+?)" },
+ "component": "pathname",
+ "groups": {},
+ "expected": null
+ },
+ {
+ "pattern": { "port": "([^\\:]+?)" },
+ "component": "port",
+ "groups": {},
+ "expected": null
+ }
+]
diff --git a/tests/wpt/tests/urlpattern/urlpattern-generate.tentative.any.js b/tests/wpt/tests/urlpattern/urlpattern-generate.tentative.any.js
new file mode 100644
index 00000000000..1f6962942d8
--- /dev/null
+++ b/tests/wpt/tests/urlpattern/urlpattern-generate.tentative.any.js
@@ -0,0 +1,26 @@
+// META: global=window,worker
+
+function runTests(data) {
+ for (let entry of data) {
+ test(function () {
+ const pattern = new URLPattern(entry.pattern);
+
+ if (entry.expected === null) {
+ assert_throws_js(TypeError, _ => pattern.generate(entry.component, entry.groups),
+ 'generate() should fail with TypeError');
+ return;
+ }
+
+ const result = pattern.generate(entry.component, entry.groups);
+ assert_equals(result, entry.expected);
+ }, `Pattern: ${JSON.stringify(entry.pattern)} ` +
+ `Component: ${entry.component} ` +
+ `Groups: ${JSON.stringify(entry.groups)}`);
+ }
+}
+
+promise_test(async function () {
+ const response = await fetch('resources/urlpattern-generate-test-data.json');
+ const data = await response.json();
+ runTests(data);
+}, 'Loading data...');
diff --git a/tests/wpt/tests/webnn/conformance_tests/cumulative_sum.https.any.js b/tests/wpt/tests/webnn/conformance_tests/cumulative_sum.https.any.js
index 85e1ab427d2..34a625152b2 100644
--- a/tests/wpt/tests/webnn/conformance_tests/cumulative_sum.https.any.js
+++ b/tests/wpt/tests/webnn/conformance_tests/cumulative_sum.https.any.js
@@ -26,13 +26,14 @@ const getCumulativeSumPrecisionTolerance = (graphResources) => {
const axis = args[1][Object.keys(args[1])[0]];
let tolerance = inputShape[axis] - 1;
- const toleranceValueDict = {float32: tolerance, int32: 0};
+ const toleranceValueDict = {float32: tolerance, float16: tolerance, int32: 0};
const expectedDataType =
getExpectedDataTypeOfSingleOutput(graphResources.expectedOutputs);
return {metricType: 'ULP', value: toleranceValueDict[expectedDataType]};
};
const cumulativeSumTests = [
+ // float32 tests
{
'name': 'cumulativeSum with float32 input and default options.',
'graph': {
@@ -51,7 +52,7 @@ const cumulativeSumTests = [
'name': 'cumulativeSum',
'arguments': [
{'input': 'cumulativeSumInput'},
- {'axis': 3},
+ {'axis': 3}
],
'outputs': 'cumulativeSumOutput'
}],
@@ -68,32 +69,41 @@ const cumulativeSumTests = [
}
},
{
- 'name': 'cumulativeSum with int32 input and axis = 2.',
+ 'name': 'cumulativeSum with float32 input and set exclusive to true.',
'graph': {
'inputs': {
'cumulativeSumInput': {
- 'data': [2, 1, 3, 5, 3, 8, 7, 3, 9, 6, 2, 4],
- 'descriptor': {shape: [1, 1, 3, 4], dataType: 'int32'}
+ 'data': [
+ 60.42374038696289, -86.92247772216797, -19.496112823486328,
+ -15.150615692138672, 13.455190658569336, 45.433597564697266,
+ 61.082862854003906, 70.71882629394531, -31.278579711914062,
+ 56.08354187011719, 38.992767333984375, -3.27536940574646
+ ],
+ 'descriptor': {shape: [1, 1, 3, 4], dataType: 'float32'}
}
},
'operators': [{
'name': 'cumulativeSum',
'arguments': [
{'input': 'cumulativeSumInput'},
- {'axis': 2},
+ {'axis': 3},
+ {'options': {'exclusive': true}}
],
'outputs': 'cumulativeSumOutput'
}],
'expectedOutputs': {
'cumulativeSumOutput': {
- 'data': [2, 1, 3, 5, 5, 9, 10, 8, 14, 15, 12, 12],
- 'descriptor': {shape: [1, 1, 3, 4], dataType: 'int32'}
+ 'data': [
+ 0.0, 60.4237404, -26.4987373, -45.994854, 0.0, 13.4551907,
+ 58.8887863, 119.9716568, 0.0, -31.2785797, 24.8049622, 63.7977295
+ ],
+ 'descriptor': {shape: [1, 1, 3, 4], dataType: 'float32'}
}
}
}
},
{
- 'name': 'cumulativeSum with float32 input and set exclusive to true.',
+ 'name': 'cumulativeSum with float32 input and set reversed to true.',
'graph': {
'inputs': {
'cumulativeSumInput': {
@@ -111,56 +121,141 @@ const cumulativeSumTests = [
'arguments': [
{'input': 'cumulativeSumInput'},
{'axis': 3},
- {'options': {'exclusive': true}},
+ {'options': {'reversed': true}}
],
'outputs': 'cumulativeSumOutput'
}],
'expectedOutputs': {
'cumulativeSumOutput': {
'data': [
- 0.0, 60.4237404, -26.4987373, -45.994854, 0.0, 13.4551907,
- 58.8887863, 119.9716568, 0.0, -31.2785797, 24.8049622, 63.7977295
+ -61.1454659, -121.5692139, -34.6467285, -15.1506157, 190.6904907,
+ 177.2352905, 131.8016968, 70.7188263, 60.5223618, 91.8009415,
+ 35.7173996, -3.2753694
],
'descriptor': {shape: [1, 1, 3, 4], dataType: 'float32'}
}
}
}
},
+
+ // float16 tests
{
- 'name': 'cumulativeSum with float32 input and set reversed to true.',
+ 'name': 'cumulativeSum with float16 input and default options.',
'graph': {
'inputs': {
'cumulativeSumInput': {
'data': [
- 60.42374038696289, -86.92247772216797, -19.496112823486328,
- -15.150615692138672, 13.455190658569336, 45.433597564697266,
- 61.082862854003906, 70.71882629394531, -31.278579711914062,
- 56.08354187011719, 38.992767333984375, -3.27536940574646
+ 60.4375, -86.9375, -19.5, -15.1484375, 13.453125, 45.4375, 61.09375,
+ 70.75, -31.28125, 56.09375, 39, -3.275390625
],
- 'descriptor': {shape: [1, 1, 3, 4], dataType: 'float32'}
+ 'descriptor': {shape: [1, 1, 3, 4], dataType: 'float16'}
+ }
+ },
+ 'operators': [{
+ 'name': 'cumulativeSum',
+ 'arguments': [{'input': 'cumulativeSumInput'}, {'axis': 3}],
+ 'outputs': 'cumulativeSumOutput'
+ }],
+ 'expectedOutputs': {
+ 'cumulativeSumOutput': {
+ 'data': [
+ 60.4375, -26.5, -46, -61.15625, 13.453125, 58.875, 120, 190.75,
+ -31.28125, 24.8125, 63.8125, 60.53125
+ ],
+ 'descriptor': {shape: [1, 1, 3, 4], dataType: 'float16'}
+ }
+ }
+ }
+ },
+ {
+ 'name': 'cumulativeSum with float16 input and set exclusive to true.',
+ 'graph': {
+ 'inputs': {
+ 'cumulativeSumInput': {
+ 'data': [
+ 60.4375, -86.9375, -19.5, -15.1484375, 13.453125, 45.4375, 61.09375,
+ 70.75, -31.28125, 56.09375, 39, -3.275390625
+ ],
+ 'descriptor': {shape: [1, 1, 3, 4], dataType: 'float16'}
}
},
'operators': [{
'name': 'cumulativeSum',
'arguments': [
- {'input': 'cumulativeSumInput'},
- {'axis': 3},
- {'options': {'reversed': true}},
+ {'input': 'cumulativeSumInput'}, {'axis': 3},
+ {'options': {'exclusive': true}}
],
'outputs': 'cumulativeSumOutput'
}],
'expectedOutputs': {
'cumulativeSumOutput': {
'data': [
- -61.1454659, -121.5692139, -34.6467285, -15.1506157, 190.6904907,
- 177.2352905, 131.8016968, 70.7188263, 60.5223618, 91.8009415,
- 35.7173996, -3.2753694
+ 0, 60.4375, -26.5, -46, 0, 13.453125, 58.875, 120, 0, -31.28125,
+ 24.8125, 63.8125
],
- 'descriptor': {shape: [1, 1, 3, 4], dataType: 'float32'}
+ 'descriptor': {shape: [1, 1, 3, 4], dataType: 'float16'}
}
}
}
},
+ {
+ 'name': 'cumulativeSum with float16 input and set reversed to true.',
+ 'graph': {
+ 'inputs': {
+ 'cumulativeSumInput': {
+ 'data': [
+ 60.4375, -86.9375, -19.5, -15.1484375, 13.453125, 45.4375, 61.09375,
+ 70.75, -31.28125, 56.09375, 39, -3.275390625
+ ],
+ 'descriptor': {shape: [1, 1, 3, 4], dataType: 'float16'}
+ }
+ },
+ 'operators': [{
+ 'name': 'cumulativeSum',
+ 'arguments': [
+ {'input': 'cumulativeSumInput'}, {'axis': 3},
+ {'options': {'reversed': true}}
+ ],
+ 'outputs': 'cumulativeSumOutput'
+ }],
+ 'expectedOutputs': {
+ 'cumulativeSumOutput': {
+ 'data': [
+ -61.15625, -121.5625, -34.65625, -15.1484375, 190.75, 177.25,
+ 131.875, 70.75, 60.53125, 91.8125, 35.71875, -3.275390625
+ ],
+ 'descriptor': {shape: [1, 1, 3, 4], dataType: 'float16'}
+ }
+ }
+ }
+ },
+
+ // int32 tests
+ {
+ 'name': 'cumulativeSum with int32 input and axis = 2.',
+ 'graph': {
+ 'inputs': {
+ 'cumulativeSumInput': {
+ 'data': [2, 1, 3, 5, 3, 8, 7, 3, 9, 6, 2, 4],
+ 'descriptor': {shape: [1, 1, 3, 4], dataType: 'int32'}
+ }
+ },
+ 'operators': [{
+ 'name': 'cumulativeSum',
+ 'arguments': [
+ {'input': 'cumulativeSumInput'},
+ {'axis': 2}
+ ],
+ 'outputs': 'cumulativeSumOutput'
+ }],
+ 'expectedOutputs': {
+ 'cumulativeSumOutput': {
+ 'data': [2, 1, 3, 5, 5, 9, 10, 8, 14, 15, 12, 12],
+ 'descriptor': {shape: [1, 1, 3, 4], dataType: 'int32'}
+ }
+ }
+ }
+ }
];
if (navigator.ml) {
diff --git a/tests/wpt/tests/webnn/conformance_tests/linear.https.any.js b/tests/wpt/tests/webnn/conformance_tests/linear.https.any.js
index 9231aaf9eca..1f13fe170d4 100644
--- a/tests/wpt/tests/webnn/conformance_tests/linear.https.any.js
+++ b/tests/wpt/tests/webnn/conformance_tests/linear.https.any.js
@@ -19,6 +19,7 @@
// MLOperand linear(MLOperand input, optional MLLinearOptions options = {});
const linearTests = [
+ // float32 tests
{
'name': 'linear float32 1D constant tensor default options',
'graph': {
@@ -542,6 +543,474 @@ const linearTests = [
}
}
}
+ },
+
+ // float16 tests
+ {
+ 'name': 'linear float16 1D constant tensor default options',
+ 'graph': {
+ 'inputs': {
+ 'linearInput': {
+ 'data': [
+ -1.1220703125, -6.60546875, -1.955078125, -4.59765625,
+ 4.234375, 3.09765625, 3.74609375, -4.48828125,
+ 6.40625, -4.35546875, -5.8203125, 3.720703125,
+ -6.33203125, 8.578125, -6.765625, 6.43359375,
+ -9.7109375, 2.642578125, 5.21484375, 9.65625,
+ -8.71875, -0.453369140625, 9.9921875, -6.46875
+ ],
+ 'descriptor': {shape: [24], dataType: 'float16'},
+ 'constant': true
+ }
+ },
+ 'operators': [{
+ 'name': 'linear',
+ 'arguments': [{'input': 'linearInput'}],
+ 'outputs': 'linearOutput'
+ }],
+ 'expectedOutputs': {
+ 'linearOutput': {
+ 'data': [
+ -1.1220703125, -6.60546875, -1.955078125, -4.59765625,
+ 4.234375, 3.09765625, 3.74609375, -4.48828125,
+ 6.40625, -4.35546875, -5.8203125, 3.720703125,
+ -6.33203125, 8.578125, -6.765625, 6.43359375,
+ -9.7109375, 2.642578125, 5.21484375, 9.65625,
+ -8.71875, -0.453369140625, 9.9921875, -6.46875
+ ],
+ 'descriptor': {shape: [24], dataType: 'float16'}
+ }
+ }
+ }
+ },
+ {
+ 'name': 'linear float16 0D tensor default options',
+ 'graph': {
+ 'inputs': {
+ 'linearInput': {
+ 'data': [-1.1220703125],
+ 'descriptor': {shape: [], dataType: 'float16'}
+ }
+ },
+ 'operators': [{
+ 'name': 'linear',
+ 'arguments': [{'input': 'linearInput'}],
+ 'outputs': 'linearOutput'
+ }],
+ 'expectedOutputs': {
+ 'linearOutput': {
+ 'data': [-1.1220703125],
+ 'descriptor': {shape: [], dataType: 'float16'}
+ }
+ }
+ }
+ },
+ {
+ 'name': 'linear float16 1D tensor default options',
+ 'graph': {
+ 'inputs': {
+ 'linearInput': {
+ 'data': [
+ -1.1220703125, -6.60546875, -1.955078125, -4.59765625,
+ 4.234375, 3.09765625, 3.74609375, -4.48828125,
+ 6.40625, -4.35546875, -5.8203125, 3.720703125,
+ -6.33203125, 8.578125, -6.765625, 6.43359375,
+ -9.7109375, 2.642578125, 5.21484375, 9.65625,
+ -8.71875, -0.453369140625, 9.9921875, -6.46875
+ ],
+ 'descriptor': {shape: [24], dataType: 'float16'}
+ }
+ },
+ 'operators': [{
+ 'name': 'linear',
+ 'arguments': [{'input': 'linearInput'}],
+ 'outputs': 'linearOutput'
+ }],
+ 'expectedOutputs': {
+ 'linearOutput': {
+ 'data': [
+ -1.1220703125, -6.60546875, -1.955078125, -4.59765625,
+ 4.234375, 3.09765625, 3.74609375, -4.48828125,
+ 6.40625, -4.35546875, -5.8203125, 3.720703125,
+ -6.33203125, 8.578125, -6.765625, 6.43359375,
+ -9.7109375, 2.642578125, 5.21484375, 9.65625,
+ -8.71875, -0.453369140625, 9.9921875, -6.46875
+ ],
+ 'descriptor': {shape: [24], dataType: 'float16'}
+ }
+ }
+ }
+ },
+ {
+ 'name': 'linear float16 2D tensor default options',
+ 'graph': {
+ 'inputs': {
+ 'linearInput': {
+ 'data': [
+ -1.1220703125, -6.60546875, -1.955078125, -4.59765625,
+ 4.234375, 3.09765625, 3.74609375, -4.48828125,
+ 6.40625, -4.35546875, -5.8203125, 3.720703125,
+ -6.33203125, 8.578125, -6.765625, 6.43359375,
+ -9.7109375, 2.642578125, 5.21484375, 9.65625,
+ -8.71875, -0.453369140625, 9.9921875, -6.46875
+ ],
+ 'descriptor': {shape: [4, 6], dataType: 'float16'}
+ }
+ },
+ 'operators': [{
+ 'name': 'linear',
+ 'arguments': [{'input': 'linearInput'}],
+ 'outputs': 'linearOutput'
+ }],
+ 'expectedOutputs': {
+ 'linearOutput': {
+ 'data': [
+ -1.1220703125, -6.60546875, -1.955078125, -4.59765625,
+ 4.234375, 3.09765625, 3.74609375, -4.48828125,
+ 6.40625, -4.35546875, -5.8203125, 3.720703125,
+ -6.33203125, 8.578125, -6.765625, 6.43359375,
+ -9.7109375, 2.642578125, 5.21484375, 9.65625,
+ -8.71875, -0.453369140625, 9.9921875, -6.46875
+ ],
+ 'descriptor': {shape: [4, 6], dataType: 'float16'}
+ }
+ }
+ }
+ },
+ {
+ 'name': 'linear float16 3D tensor default options',
+ 'graph': {
+ 'inputs': {
+ 'linearInput': {
+ 'data': [
+ -1.1220703125, -6.60546875, -1.955078125, -4.59765625,
+ 4.234375, 3.09765625, 3.74609375, -4.48828125,
+ 6.40625, -4.35546875, -5.8203125, 3.720703125,
+ -6.33203125, 8.578125, -6.765625, 6.43359375,
+ -9.7109375, 2.642578125, 5.21484375, 9.65625,
+ -8.71875, -0.453369140625, 9.9921875, -6.46875
+ ],
+ 'descriptor': {shape: [2, 3, 4], dataType: 'float16'}
+ }
+ },
+ 'operators': [{
+ 'name': 'linear',
+ 'arguments': [{'input': 'linearInput'}],
+ 'outputs': 'linearOutput'
+ }],
+ 'expectedOutputs': {
+ 'linearOutput': {
+ 'data': [
+ -1.1220703125, -6.60546875, -1.955078125, -4.59765625,
+ 4.234375, 3.09765625, 3.74609375, -4.48828125,
+ 6.40625, -4.35546875, -5.8203125, 3.720703125,
+ -6.33203125, 8.578125, -6.765625, 6.43359375,
+ -9.7109375, 2.642578125, 5.21484375, 9.65625,
+ -8.71875, -0.453369140625, 9.9921875, -6.46875
+ ],
+ 'descriptor': {shape: [2, 3, 4], dataType: 'float16'}
+ }
+ }
+ }
+ },
+ {
+ 'name': 'linear float16 4D tensor default options',
+ 'graph': {
+ 'inputs': {
+ 'linearInput': {
+ 'data': [
+ -1.1220703125, -6.60546875, -1.955078125, -4.59765625,
+ 4.234375, 3.09765625, 3.74609375, -4.48828125,
+ 6.40625, -4.35546875, -5.8203125, 3.720703125,
+ -6.33203125, 8.578125, -6.765625, 6.43359375,
+ -9.7109375, 2.642578125, 5.21484375, 9.65625,
+ -8.71875, -0.453369140625, 9.9921875, -6.46875
+ ],
+ 'descriptor': {shape: [2, 2, 2, 3], dataType: 'float16'}
+ }
+ },
+ 'operators': [{
+ 'name': 'linear',
+ 'arguments': [{'input': 'linearInput'}],
+ 'outputs': 'linearOutput'
+ }],
+ 'expectedOutputs': {
+ 'linearOutput': {
+ 'data': [
+ -1.1220703125, -6.60546875, -1.955078125, -4.59765625,
+ 4.234375, 3.09765625, 3.74609375, -4.48828125,
+ 6.40625, -4.35546875, -5.8203125, 3.720703125,
+ -6.33203125, 8.578125, -6.765625, 6.43359375,
+ -9.7109375, 2.642578125, 5.21484375, 9.65625,
+ -8.71875, -0.453369140625, 9.9921875, -6.46875
+ ],
+ 'descriptor': {shape: [2, 2, 2, 3], dataType: 'float16'}
+ }
+ }
+ }
+ },
+ {
+ 'name': 'linear float16 5D tensor default options',
+ 'graph': {
+ 'inputs': {
+ 'linearInput': {
+ 'data': [
+ -1.1220703125, -6.60546875, -1.955078125, -4.59765625,
+ 4.234375, 3.09765625, 3.74609375, -4.48828125,
+ 6.40625, -4.35546875, -5.8203125, 3.720703125,
+ -6.33203125, 8.578125, -6.765625, 6.43359375,
+ -9.7109375, 2.642578125, 5.21484375, 9.65625,
+ -8.71875, -0.453369140625, 9.9921875, -6.46875
+ ],
+ 'descriptor': {shape: [2, 1, 4, 1, 3], dataType: 'float16'}
+ }
+ },
+ 'operators': [{
+ 'name': 'linear',
+ 'arguments': [{'input': 'linearInput'}],
+ 'outputs': 'linearOutput'
+ }],
+ 'expectedOutputs': {
+ 'linearOutput': {
+ 'data': [
+ -1.1220703125, -6.60546875, -1.955078125, -4.59765625,
+ 4.234375, 3.09765625, 3.74609375, -4.48828125,
+ 6.40625, -4.35546875, -5.8203125, 3.720703125,
+ -6.33203125, 8.578125, -6.765625, 6.43359375,
+ -9.7109375, 2.642578125, 5.21484375, 9.65625,
+ -8.71875, -0.453369140625, 9.9921875, -6.46875
+ ],
+ 'descriptor': {shape: [2, 1, 4, 1, 3], dataType: 'float16'}
+ }
+ }
+ }
+ },
+ {
+ 'name':
+ 'linear float16 4D tensor specified options.alpha and default options.beta',
+ 'graph': {
+ 'inputs': {
+ 'linearInput': {
+ 'data': [
+ -1.1220703125, -6.60546875, -1.955078125, -4.59765625,
+ 4.234375, 3.09765625, 3.74609375, -4.48828125,
+ 6.40625, -4.35546875, -5.8203125, 3.720703125,
+ -6.33203125, 8.578125, -6.765625, 6.43359375,
+ -9.7109375, 2.642578125, 5.21484375, 9.65625,
+ -8.71875, -0.453369140625, 9.9921875, -6.46875
+ ],
+ 'descriptor': {shape: [2, 2, 2, 3], dataType: 'float16'}
+ }
+ },
+ 'operators': [{
+ 'name': 'linear',
+ 'arguments': [
+ {'input': 'linearInput'}, {'options': {'alpha': 7.398793812746618}}
+ ],
+ 'outputs': 'linearOutput'
+ }],
+ 'expectedOutputs': {
+ 'linearOutput': {
+ 'data': [
+ -8.3046875, -48.875, -14.46875, -34.03125, 31.328125,
+ 22.921875, 27.71875, -33.21875, 47.40625, -32.21875,
+ -43.0625, 27.53125, -46.84375, 63.46875, -50.0625,
+ 47.59375, -71.875, 19.546875, 38.59375, 71.4375,
+ -64.5, -3.353515625, 73.9375, -47.875
+ ],
+ 'descriptor': {shape: [2, 2, 2, 3], dataType: 'float16'}
+ }
+ }
+ }
+ },
+ {
+ 'name':
+ 'linear float16 positive 4D tensor specified positive options.beta and default options.alpha',
+ 'graph': {
+ 'inputs': {
+ 'linearInput': {
+ 'data': [
+ 5.09765625, 3.380859375, 8.0546875, 8.078125, 0.470703125,
+ 5.2421875, 3.828125, 5.37109375, 6.1015625, 3.75,
+ 0.748046875, 1.8935546875, 1.9052734375, 7.86328125, 4.58203125,
+ 9.375, 6.5859375, 9.34375, 5.16015625, 0.80615234375,
+ 9.1328125, 3.193359375, 5.75, 4.11328125
+ ],
+ 'descriptor': {shape: [2, 2, 2, 3], dataType: 'float16'}
+ }
+ },
+ 'operators': [{
+ 'name': 'linear',
+ 'arguments': [
+ {'input': 'linearInput'}, {'options': {'beta': 5.919095653700928}}
+ ],
+ 'outputs': 'linearOutput'
+ }],
+ 'expectedOutputs': {
+ 'linearOutput': {
+ 'data': [
+ 11.015625, 9.296875, 13.9765625, 14, 6.390625,
+ 11.1640625, 9.75, 11.2890625, 12.0234375, 9.671875,
+ 6.66796875, 7.8125, 7.82421875, 13.78125, 10.5,
+ 15.296875, 12.5078125, 15.265625, 11.078125, 6.7265625,
+ 15.0546875, 9.109375, 11.671875, 10.03125
+ ],
+ 'descriptor': {shape: [2, 2, 2, 3], dataType: 'float16'}
+ }
+ }
+ }
+ },
+ {
+ 'name':
+ 'linear float16 negative 4D tensor specified negative options.beta and default options.alpha',
+ 'graph': {
+ 'inputs': {
+ 'linearInput': {
+ 'data': [
+ -5.09765625, -3.380859375, -8.0546875, -8.078125,
+ -0.470703125, -5.2421875, -3.828125, -5.37109375,
+ -6.1015625, -3.75, -0.748046875, -1.8935546875,
+ -1.9052734375, -7.86328125, -4.58203125, -9.375,
+ -6.5859375, -9.34375, -5.16015625, -0.80615234375,
+ -9.1328125, -3.193359375, -5.75, -4.11328125
+ ],
+ 'descriptor': {shape: [2, 2, 2, 3], dataType: 'float16'}
+ }
+ },
+ 'operators': [{
+ 'name': 'linear',
+ 'arguments': [
+ {'input': 'linearInput'}, {'options': {'beta': -5.919095653700928}}
+ ],
+ 'outputs': 'linearOutput'
+ }],
+ 'expectedOutputs': {
+ 'linearOutput': {
+ 'data': [
+ -11.015625, -9.296875, -13.9765625, -14, -6.390625,
+ -11.1640625, -9.75, -11.2890625, -12.0234375, -9.671875,
+ -6.66796875, -7.8125, -7.82421875, -13.78125, -10.5,
+ -15.296875, -12.5078125, -15.265625, -11.078125, -6.7265625,
+ -15.0546875, -9.109375, -11.671875, -10.03125
+ ],
+ 'descriptor': {shape: [2, 2, 2, 3], dataType: 'float16'}
+ }
+ }
+ }
+ },
+ {
+ 'name':
+ 'linear float16 positive 4D tensor all options (positive options.alpha and positive options.beta)',
+ 'graph': {
+ 'inputs': {
+ 'linearInput': {
+ 'data': [
+ 5.09765625, 3.380859375, 8.0546875, 8.078125, 0.470703125,
+ 5.2421875, 3.828125, 5.37109375, 6.1015625, 3.75,
+ 0.748046875, 1.8935546875, 1.9052734375, 7.86328125, 4.58203125,
+ 9.375, 6.5859375, 9.34375, 5.16015625, 0.80615234375,
+ 9.1328125, 3.193359375, 5.75, 4.11328125
+ ],
+ 'descriptor': {shape: [2, 2, 2, 3], dataType: 'float16'}
+ }
+ },
+ 'operators': [{
+ 'name': 'linear',
+ 'arguments': [
+ {'input': 'linearInput'},
+ {'options': {'alpha': 7.398793812746618, 'beta': 5.919095653700928}}
+ ],
+ 'outputs': 'linearOutput'
+ }],
+ 'expectedOutputs': {
+ 'linearOutput': {
+ 'data': [
+ 43.625, 30.9375, 65.5, 65.6875, 9.3984375, 44.71875,
+ 34.25, 45.65625, 51.0625, 33.65625, 11.453125, 19.921875,
+ 20.015625, 64.125, 39.8125, 75.3125, 54.65625, 75.0625,
+ 44.09375, 11.8828125, 73.5, 29.546875, 48.46875, 36.34375
+ ],
+ 'descriptor': {shape: [2, 2, 2, 3], dataType: 'float16'}
+ }
+ }
+ }
+ },
+ {
+ 'name':
+ 'linear float16 positive 4D tensor all options (negative options.alpha and negative options.beta)',
+ 'graph': {
+ 'inputs': {
+ 'linearInput': {
+ 'data': [
+ 5.09765625, 3.380859375, 8.0546875, 8.078125, 0.470703125,
+ 5.2421875, 3.828125, 5.37109375, 6.1015625, 3.75,
+ 0.748046875, 1.8935546875, 1.9052734375, 7.86328125, 4.58203125,
+ 9.375, 6.5859375, 9.34375, 5.16015625, 0.80615234375,
+ 9.1328125, 3.193359375, 5.75, 4.11328125
+ ],
+ 'descriptor': {shape: [2, 2, 2, 3], dataType: 'float16'}
+ }
+ },
+ 'operators': [{
+ 'name': 'linear',
+ 'arguments': [
+ {'input': 'linearInput'},
+ {'options': {'alpha': -7.398793812746618, 'beta': -5.919095653700928}}
+ ],
+ 'outputs': 'linearOutput'
+ }],
+ 'expectedOutputs': {
+ 'linearOutput': {
+ 'data': [
+ -43.625, -30.9375, -65.5, -65.6875, -9.3984375,
+ -44.71875, -34.25, -45.65625, -51.0625, -33.65625,
+ -11.453125, -19.921875, -20.015625, -64.125, -39.8125,
+ -75.3125, -54.65625, -75.0625, -44.09375, -11.8828125,
+ -73.5, -29.546875, -48.46875, -36.34375
+ ],
+ 'descriptor': {shape: [2, 2, 2, 3], dataType: 'float16'}
+ }
+ }
+ }
+ },
+ {
+ 'name':
+ 'linear float16 negative 4D tensor all options (positive options.alpha and negative options.beta)',
+ 'graph': {
+ 'inputs': {
+ 'linearInput': {
+ 'data': [
+ -5.09765625, -3.380859375, -8.0546875, -8.078125,
+ -0.470703125, -5.2421875, -3.828125, -5.37109375,
+ -6.1015625, -3.75, -0.748046875, -1.8935546875,
+ -1.9052734375, -7.86328125, -4.58203125, -9.375,
+ -6.5859375, -9.34375, -5.16015625, -0.80615234375,
+ -9.1328125, -3.193359375, -5.75, -4.11328125
+ ],
+ 'descriptor': {shape: [2, 2, 2, 3], dataType: 'float16'}
+ }
+ },
+ 'operators': [{
+ 'name': 'linear',
+ 'arguments': [
+ {'input': 'linearInput'},
+ {'options': {'alpha': 7.398793812746618, 'beta': -5.919095653700928}}
+ ],
+ 'outputs': 'linearOutput'
+ }],
+ 'expectedOutputs': {
+ 'linearOutput': {
+ 'data': [
+ -43.625, -30.9375, -65.5, -65.6875, -9.3984375,
+ -44.71875, -34.25, -45.65625, -51.0625, -33.65625,
+ -11.453125, -19.921875, -20.015625, -64.125, -39.8125,
+ -75.3125, -54.65625, -75.0625, -44.09375, -11.8828125,
+ -73.5, -29.546875, -48.46875, -36.34375
+ ],
+ 'descriptor': {shape: [2, 2, 2, 3], dataType: 'float16'}
+ }
+ }
+ }
}
];
diff --git a/tests/wpt/tests/webnn/conformance_tests/qdq_subgraph.https.any.js b/tests/wpt/tests/webnn/conformance_tests/qdq_subgraph.https.any.js
index ac384c917b3..996a6b472c5 100644
--- a/tests/wpt/tests/webnn/conformance_tests/qdq_subgraph.https.any.js
+++ b/tests/wpt/tests/webnn/conformance_tests/qdq_subgraph.https.any.js
@@ -141,6 +141,283 @@ const subgraphTests = [
}
},
{
+ 'name': 'dequantizeLinear -> conv2d -> clamp -> quantizeLinear',
+ 'graph': {
+ 'inputs': {
+ 'input': {
+ 'data': [0.05605664849281311, 0.7114229798316956, 0.6529743671417236],
+ 'descriptor': {shape: [1, 1, 1, 3], dataType: 'float32'},
+ 'constant': false
+ },
+ 'inputScale': {
+ 'data': [0.003921568859368563],
+ 'descriptor': {shape: [1], dataType: 'float32'},
+ 'constant': true
+ },
+ 'inputZeroPoint': {
+ 'data': [-128],
+ 'descriptor': {shape: [1], dataType: 'int8'},
+ 'constant': true
+ },
+ 'filter': {
+ 'data': [2, 3, 4],
+ 'descriptor': {shape: [1, 1, 1, 3], dataType: 'int8'},
+ 'constant': true
+ },
+ 'filterScale': {
+ 'data': [0.023458752938762234],
+ 'descriptor': {shape: [1], dataType: 'float32'},
+ 'constant': true
+ },
+ 'filterZeroPoint': {
+ 'data': [0],
+ 'descriptor': {shape: [1], dataType: 'int8'},
+ 'constant': true
+ },
+ 'bias': {
+ 'data': [1],
+ 'descriptor': {shape: [1], dataType: 'int32'},
+ 'constant': true
+ },
+ 'biasScale': {
+ 'data': [0.000091995115004270],
+ 'descriptor': {shape: [1], dataType: 'float32'},
+ 'constant': true
+ },
+ 'biasZeroPoint': {
+ 'data': [0],
+ 'descriptor': {shape: [1], dataType: 'int32'},
+ 'constant': true
+ },
+ 'outputScale': {
+ 'data': [0.003921568859368563],
+ 'descriptor': {shape: [1], dataType: 'float32'},
+ 'constant': true
+ },
+ 'outputZeroPoint': {
+ 'data': [0],
+ 'descriptor': {shape: [1], dataType: 'int8'},
+ 'constant': true
+ },
+ },
+ 'operators': [
+ {
+ 'name': 'quantizeLinear',
+ 'arguments': [
+ {'input': 'input'},
+ {'scale': 'inputScale', 'zeroPoint': 'inputZeroPoint'}
+ ],
+ 'outputs': 'quantizedInput'
+ },
+ {
+ 'name': 'dequantizeLinear',
+ 'arguments': [
+ {'input': 'quantizedInput'},
+ {'scale': 'inputScale', 'zeroPoint': 'inputZeroPoint'}
+ ],
+ 'outputs': 'dequantizedInput'
+ },
+ {
+ 'name': 'dequantizeLinear',
+ 'arguments': [
+ {'input': 'filter'},
+ {'scale': 'filterScale', 'zeroPoint': 'filterZeroPoint'}
+ ],
+ 'outputs': 'dequantizedFilter'
+ },
+ {
+ 'name': 'dequantizeLinear',
+ 'arguments': [
+ {'input': 'bias'},
+ {'scale': 'biasScale', 'zeroPoint': 'biasZeroPoint'}
+ ],
+ 'outputs': 'dequantizedBias'
+ },
+ {
+ 'name': 'conv2d',
+ 'arguments': [
+ {'input': 'dequantizedInput'}, {'filter': 'dequantizedFilter'}, {
+ 'options': {
+ 'inputLayout': 'nhwc',
+ 'bias': 'dequantizedBias',
+ 'filterLayout': 'ohwi'
+ }
+ }
+ ],
+ 'outputs': 'conv2dOutput'
+ },
+ {
+ 'name': 'clamp',
+ 'arguments': [
+ {'input': 'conv2dOutput'},
+ {'options': {'minValue': 0, 'maxValue': 6}}
+ ],
+ 'outputs': 'clampOutput'
+ },
+ {
+ 'name': 'quantizeLinear',
+ 'arguments': [
+ {'input': 'clampOutput'},
+ {'scale': 'outputScale', 'zeroPoint': 'outputZeroPoint'}
+ ],
+ 'outputs': 'quantizedClampOutput'
+ },
+ {
+ 'name': 'dequantizeLinear',
+ 'arguments': [
+ {'input': 'quantizedClampOutput'},
+ {'scale': 'outputScale', 'zeroPoint': 'outputZeroPoint'}
+ ],
+ 'outputs': 'output'
+ }
+ ],
+ 'expectedOutputs': {
+ 'output': {
+ 'data': [0.11372549831867218],
+ 'descriptor': {shape: [1, 1, 1, 1], dataType: 'float32'}
+ }
+ }
+ }
+ },
+ {
+ 'name': 'dequantizeLinear -> conv2d -> relu -> quantizeLinear',
+ 'graph': {
+ 'inputs': {
+ 'input': {
+ 'data': [0.05605664849281311, 0.7114229798316956, 0.6529743671417236],
+ 'descriptor': {shape: [1, 1, 1, 3], dataType: 'float32'},
+ 'constant': false
+ },
+ 'inputScale': {
+ 'data': [0.003921568859368563],
+ 'descriptor': {shape: [1], dataType: 'float32'},
+ 'constant': true
+ },
+ 'inputZeroPoint': {
+ 'data': [-128],
+ 'descriptor': {shape: [1], dataType: 'int8'},
+ 'constant': true
+ },
+ 'filter': {
+ 'data': [2, 3, 4],
+ 'descriptor': {shape: [1, 1, 1, 3], dataType: 'int8'},
+ 'constant': true
+ },
+ 'filterScale': {
+ 'data': [0.7114229798316956],
+ 'descriptor': {shape: [1], dataType: 'float32'},
+ 'constant': true
+ },
+ 'filterZeroPoint': {
+ 'data': [-128],
+ 'descriptor': {shape: [1], dataType: 'int8'},
+ 'constant': true
+ },
+ 'bias': {
+ 'data': [1],
+ 'descriptor': {shape: [1], dataType: 'int32'},
+ 'constant': true
+ },
+ 'biasScale': {
+ 'data': [0.000091995115004270],
+ 'descriptor': {shape: [1], dataType: 'float32'},
+ 'constant': true
+ },
+ 'biasZeroPoint': {
+ 'data': [0],
+ 'descriptor': {shape: [1], dataType: 'int32'},
+ 'constant': true
+ },
+ 'outputScale': {
+ 'data': [0.003921568859368563],
+ 'descriptor': {shape: [1], dataType: 'float32'},
+ 'constant': true
+ },
+ 'outputZeroPoint': {
+ 'data': [0],
+ 'descriptor': {shape: [1], dataType: 'int8'},
+ 'constant': true
+ },
+ },
+ 'operators': [
+ {
+ 'name': 'quantizeLinear',
+ 'arguments': [
+ {'input': 'input'},
+ {'scale': 'inputScale', 'zeroPoint': 'inputZeroPoint'}
+ ],
+ 'outputs': 'quantizedInput'
+ },
+ {
+ 'name': 'dequantizeLinear',
+ 'arguments': [
+ {'input': 'quantizedInput'},
+ {'scale': 'inputScale', 'zeroPoint': 'inputZeroPoint'}
+ ],
+ 'outputs': 'dequantizedInput'
+ },
+ {
+ 'name': 'dequantizeLinear',
+ 'arguments': [
+ {'input': 'filter'},
+ {'scale': 'filterScale', 'zeroPoint': 'filterZeroPoint'}
+ ],
+ 'outputs': 'dequantizedFilter'
+ },
+ {
+ 'name': 'dequantizeLinear',
+ 'arguments': [
+ {'input': 'bias'},
+ {'scale': 'biasScale', 'zeroPoint': 'biasZeroPoint'}
+ ],
+ 'outputs': 'dequantizedBias'
+ },
+ {
+ 'name': 'conv2d',
+ 'arguments': [
+ {'input': 'dequantizedInput'}, {'filter': 'dequantizedFilter'}, {
+ 'options': {
+ 'inputLayout': 'nhwc',
+ 'bias': 'dequantizedBias',
+ 'filterLayout': 'ohwi'
+ }
+ }
+ ],
+ 'outputs': 'conv2dOutput'
+ },
+ {
+ 'name': 'relu',
+ 'arguments': [
+ {'input': 'conv2dOutput'}
+ ],
+ 'outputs': 'reluOutput'
+ },
+ {
+ 'name': 'quantizeLinear',
+ 'arguments': [
+ {'input': 'reluOutput'},
+ {'scale': 'outputScale', 'zeroPoint': 'outputZeroPoint'}
+ ],
+ 'outputs': 'quantizedReluOutput'
+ },
+ {
+ 'name': 'dequantizeLinear',
+ 'arguments': [
+ {'input': 'quantizedReluOutput'},
+ {'scale': 'outputScale', 'zeroPoint': 'outputZeroPoint'}
+ ],
+ 'outputs': 'output'
+ }
+ ],
+ 'expectedOutputs': {
+ 'output': {
+ 'data': [0.49803924560546875],
+ 'descriptor': {shape: [1, 1, 1, 1], dataType: 'float32'}
+ }
+ }
+ }
+ },
+ {
'name': 'quantized element-wise binary add',
'graph': {
'inputs': {
@@ -1846,6 +2123,423 @@ const subgraphTests = [
}
}
},
+ {
+ 'name': 'quantized reduceMax',
+ 'graph': {
+ 'inputs': {
+ 'input': {
+ 'data': [
+ 1.6811466217041016, 0.0479511022567749, 0.33355462551116943,
+ -0.1988269537687301, -0.0041167140007019, -0.0634240251779556,
+ ],
+ 'descriptor': {shape: [2, 3], dataType: 'float32'},
+ 'constant': false
+ },
+ 'inputScale': {
+ 'data': [0.003921568859368563],
+ 'descriptor': {shape: [1], dataType: 'float32'},
+ 'constant': true
+ },
+ 'inputZeroPoint': {
+ 'data': [0],
+ 'descriptor': {shape: [1], dataType: 'int8'},
+ 'constant': true
+ },
+ 'outputScale': {
+ 'data': [0.003921568859368563],
+ 'descriptor': {shape: [1], dataType: 'float32'},
+ 'constant': true
+ },
+ 'outputZeroPoint': {
+ 'data': [0],
+ 'descriptor': {shape: [1], dataType: 'int8'},
+ 'constant': true
+ },
+ },
+ 'operators': [
+ {
+ 'name': 'quantizeLinear',
+ 'arguments': [
+ {'input': 'input'},
+ {'scale': 'inputScale', 'zeroPoint': 'inputZeroPoint'}
+ ],
+ 'outputs': 'quantizedInput'
+ },
+ {
+ 'name': 'dequantizeLinear',
+ 'arguments': [
+ {'input': 'quantizedInput'},
+ {'scale': 'inputScale', 'zeroPoint': 'inputZeroPoint'}
+ ],
+ 'outputs': 'dequantizedInput'
+ },
+ {
+ 'name': 'reduceMax',
+ 'arguments': [{'input': 'dequantizedInput'}, {'options': {'axes': [1]}}],
+ 'outputs': 'reduceMaxOutput'
+ },
+ {
+ 'name': 'quantizeLinear',
+ 'arguments': [
+ {'input': 'reduceMaxOutput'},
+ {'scale': 'outputScale', 'zeroPoint': 'outputZeroPoint'}
+ ],
+ 'outputs': 'quantizedReduceMaxOutput'
+ },
+ {
+ 'name': 'dequantizeLinear',
+ 'arguments': [
+ {'input': 'quantizedReduceMaxOutput'},
+ {'scale': 'outputScale', 'zeroPoint': 'outputZeroPoint'}
+ ],
+ 'outputs': 'output'
+ }
+ ],
+ 'expectedOutputs': {
+ 'output': {
+ 'data': [
+ 0.49803924560546875, -0.003921568859368563,
+ ],
+ 'descriptor': {shape: [2], dataType: 'float32'}
+ }
+ }
+ }
+ },
+ {
+ 'name': 'quantized reduceMin',
+ 'graph': {
+ 'inputs': {
+ 'input': {
+ 'data': [
+ 1.6811466217041016, 0.0479511022567749, 0.33355462551116943,
+ -0.1988269537687301, -0.0041167140007019, -0.0634240251779556,
+ ],
+ 'descriptor': {shape: [2, 3], dataType: 'float32'},
+ 'constant': false
+ },
+ 'inputScale': {
+ 'data': [0.003921568859368563],
+ 'descriptor': {shape: [1], dataType: 'float32'},
+ 'constant': true
+ },
+ 'inputZeroPoint': {
+ 'data': [0],
+ 'descriptor': {shape: [1], dataType: 'int8'},
+ 'constant': true
+ },
+ 'outputScale': {
+ 'data': [0.003921568859368563],
+ 'descriptor': {shape: [1], dataType: 'float32'},
+ 'constant': true
+ },
+ 'outputZeroPoint': {
+ 'data': [0],
+ 'descriptor': {shape: [1], dataType: 'int8'},
+ 'constant': true
+ },
+ },
+ 'operators': [
+ {
+ 'name': 'quantizeLinear',
+ 'arguments': [
+ {'input': 'input'},
+ {'scale': 'inputScale', 'zeroPoint': 'inputZeroPoint'}
+ ],
+ 'outputs': 'quantizedInput'
+ },
+ {
+ 'name': 'dequantizeLinear',
+ 'arguments': [
+ {'input': 'quantizedInput'},
+ {'scale': 'inputScale', 'zeroPoint': 'inputZeroPoint'}
+ ],
+ 'outputs': 'dequantizedInput'
+ },
+ {
+ 'name': 'reduceMin',
+ 'arguments': [{'input': 'dequantizedInput'}, {'options': {'axes': [1]}}],
+ 'outputs': 'reduceMinOutput'
+ },
+ {
+ 'name': 'quantizeLinear',
+ 'arguments': [
+ {'input': 'reduceMinOutput'},
+ {'scale': 'outputScale', 'zeroPoint': 'outputZeroPoint'}
+ ],
+ 'outputs': 'quantizedReduceMinOutput'
+ },
+ {
+ 'name': 'dequantizeLinear',
+ 'arguments': [
+ {'input': 'quantizedReduceMinOutput'},
+ {'scale': 'outputScale', 'zeroPoint': 'outputZeroPoint'}
+ ],
+ 'outputs': 'output'
+ }
+ ],
+ 'expectedOutputs': {
+ 'output': {
+ 'data': [
+ 0.0470588281750679, -0.20000001788139343,
+ ],
+ 'descriptor': {shape: [2], dataType: 'float32'}
+ }
+ }
+ }
+ },
+ {
+ 'name': 'quantized reduceMean',
+ 'graph': {
+ 'inputs': {
+ 'input': {
+ 'data': [
+ 1.6811466217041016, 0.0479511022567749, 0.33355462551116943,
+ -0.1988269537687301, -0.0041167140007019, -0.0634240251779556,
+ ],
+ 'descriptor': {shape: [2, 3], dataType: 'float32'},
+ 'constant': false
+ },
+ 'inputScale': {
+ 'data': [0.003921568859368563],
+ 'descriptor': {shape: [1], dataType: 'float32'},
+ 'constant': true
+ },
+ 'inputZeroPoint': {
+ 'data': [0],
+ 'descriptor': {shape: [1], dataType: 'int8'},
+ 'constant': true
+ },
+ 'outputScale': {
+ 'data': [0.003921568859368563],
+ 'descriptor': {shape: [1], dataType: 'float32'},
+ 'constant': true
+ },
+ 'outputZeroPoint': {
+ 'data': [0],
+ 'descriptor': {shape: [1], dataType: 'int8'},
+ 'constant': true
+ },
+ },
+ 'operators': [
+ {
+ 'name': 'quantizeLinear',
+ 'arguments': [
+ {'input': 'input'},
+ {'scale': 'inputScale', 'zeroPoint': 'inputZeroPoint'}
+ ],
+ 'outputs': 'quantizedInput'
+ },
+ {
+ 'name': 'dequantizeLinear',
+ 'arguments': [
+ {'input': 'quantizedInput'},
+ {'scale': 'inputScale', 'zeroPoint': 'inputZeroPoint'}
+ ],
+ 'outputs': 'dequantizedInput'
+ },
+ {
+ 'name': 'reduceMean',
+ 'arguments': [{'input': 'dequantizedInput'}, {'options': {'axes': [1]}}],
+ 'outputs': 'reduceMeanOutput'
+ },
+ {
+ 'name': 'quantizeLinear',
+ 'arguments': [
+ {'input': 'reduceMeanOutput'},
+ {'scale': 'outputScale', 'zeroPoint': 'outputZeroPoint'}
+ ],
+ 'outputs': 'quantizedReduceMeanOutput'
+ },
+ {
+ 'name': 'dequantizeLinear',
+ 'arguments': [
+ {'input': 'quantizedReduceMeanOutput'},
+ {'scale': 'outputScale', 'zeroPoint': 'outputZeroPoint'}
+ ],
+ 'outputs': 'output'
+ }
+ ],
+ 'expectedOutputs': {
+ 'output': {
+ 'data': [
+ 0.29411765933036804, -0.09019608050584793,
+ ],
+ 'descriptor': {shape: [2], dataType: 'float32'}
+ }
+ }
+ }
+ },
+ {
+ 'name': 'quantized reduceSum',
+ 'graph': {
+ 'inputs': {
+ 'input': {
+ 'data': [
+ 1.6811466217041016, 0.0479511022567749, 0.33355462551116943,
+ -0.1988269537687301, -0.0041167140007019, -0.0634240251779556,
+ ],
+ 'descriptor': {shape: [2, 3], dataType: 'float32'},
+ 'constant': false
+ },
+ 'inputScale': {
+ 'data': [0.003921568859368563],
+ 'descriptor': {shape: [1], dataType: 'float32'},
+ 'constant': true
+ },
+ 'inputZeroPoint': {
+ 'data': [0],
+ 'descriptor': {shape: [1], dataType: 'int8'},
+ 'constant': true
+ },
+ 'outputScale': {
+ 'data': [0.003921568859368563],
+ 'descriptor': {shape: [1], dataType: 'float32'},
+ 'constant': true
+ },
+ 'outputZeroPoint': {
+ 'data': [0],
+ 'descriptor': {shape: [1], dataType: 'int8'},
+ 'constant': true
+ },
+ },
+ 'operators': [
+ {
+ 'name': 'quantizeLinear',
+ 'arguments': [
+ {'input': 'input'},
+ {'scale': 'inputScale', 'zeroPoint': 'inputZeroPoint'}
+ ],
+ 'outputs': 'quantizedInput'
+ },
+ {
+ 'name': 'dequantizeLinear',
+ 'arguments': [
+ {'input': 'quantizedInput'},
+ {'scale': 'inputScale', 'zeroPoint': 'inputZeroPoint'}
+ ],
+ 'outputs': 'dequantizedInput'
+ },
+ {
+ 'name': 'reduceSum',
+ 'arguments': [{'input': 'dequantizedInput'}, {'options': {'axes': [1]}}],
+ 'outputs': 'reduceSumOutput'
+ },
+ {
+ 'name': 'quantizeLinear',
+ 'arguments': [
+ {'input': 'reduceSumOutput'},
+ {'scale': 'outputScale', 'zeroPoint': 'outputZeroPoint'}
+ ],
+ 'outputs': 'quantizedReduceSumOutput'
+ },
+ {
+ 'name': 'dequantizeLinear',
+ 'arguments': [
+ {'input': 'quantizedReduceSumOutput'},
+ {'scale': 'outputScale', 'zeroPoint': 'outputZeroPoint'}
+ ],
+ 'outputs': 'output'
+ }
+ ],
+ 'expectedOutputs': {
+ 'output': {
+ 'data': [
+ 0.49803924560546875, -0.2666666805744171,
+ ],
+ 'descriptor': {shape: [2], dataType: 'float32'}
+ }
+ }
+ }
+ },
+ {
+ 'name': 'quantized resample2d',
+ 'graph': {
+ 'inputs': {
+ 'input': {
+ 'data': [
+ 1.6811466217041016, 0.0479511022567749, 0.33355462551116943,
+ -0.1988269537687301, -0.0041167140007019, -0.0634240251779556,
+ ],
+ 'descriptor': {shape: [1, 2, 3, 1], dataType: 'float32'},
+ 'constant': false
+ },
+ 'inputScale': {
+ 'data': [0.003921568859368563],
+ 'descriptor': {shape: [1], dataType: 'float32'},
+ 'constant': true
+ },
+ 'inputZeroPoint': {
+ 'data': [0],
+ 'descriptor': {shape: [1], dataType: 'int8'},
+ 'constant': true
+ },
+ 'outputScale': {
+ 'data': [0.003921568859368563],
+ 'descriptor': {shape: [1], dataType: 'float32'},
+ 'constant': true
+ },
+ 'outputZeroPoint': {
+ 'data': [0],
+ 'descriptor': {shape: [1], dataType: 'int8'},
+ 'constant': true
+ },
+ },
+ 'operators': [
+ {
+ 'name': 'quantizeLinear',
+ 'arguments': [
+ {'input': 'input'},
+ {'scale': 'inputScale', 'zeroPoint': 'inputZeroPoint'}
+ ],
+ 'outputs': 'quantizedInput'
+ },
+ {
+ 'name': 'dequantizeLinear',
+ 'arguments': [
+ {'input': 'quantizedInput'},
+ {'scale': 'inputScale', 'zeroPoint': 'inputZeroPoint'}
+ ],
+ 'outputs': 'dequantizedInput'
+ },
+ {
+ 'name': 'resample2d',
+ 'arguments': [{'input': 'dequantizedInput'}, {'options': {'sizes': [4, 6], 'axes': [1, 2]}}],
+ 'outputs': 'resample2dOutput'
+ },
+ {
+ 'name': 'quantizeLinear',
+ 'arguments': [
+ {'input': 'resample2dOutput'},
+ {'scale': 'outputScale', 'zeroPoint': 'outputZeroPoint'}
+ ],
+ 'outputs': 'quantizedResample2dOutput'
+ },
+ {
+ 'name': 'dequantizeLinear',
+ 'arguments': [
+ {'input': 'quantizedResample2dOutput'},
+ {'scale': 'outputScale', 'zeroPoint': 'outputZeroPoint'}
+ ],
+ 'outputs': 'output'
+ }
+ ],
+ 'expectedOutputs': {
+ 'output': {
+ 'data': [
+ 0.49803924560546875, 0.49803924560546875, 0.0470588281750679,
+ 0.0470588281750679, 0.3333333432674408, 0.3333333432674408,
+ 0.49803924560546875, 0.49803924560546875, 0.0470588281750679,
+ 0.0470588281750679, 0.3333333432674408, 0.3333333432674408,
+ -0.20000001788139343, -0.20000001788139343, -0.003921568859368563,
+ -0.003921568859368563, -0.062745101749897, -0.062745101749897,
+ -0.20000001788139343, -0.20000001788139343, -0.003921568859368563,
+ -0.003921568859368563, -0.062745101749897, -0.062745101749897,
+ ],
+ 'descriptor': {shape: [1, 4, 6, 1], dataType: 'float32'}
+ }
+ }
+ }
+ },
];
if (navigator.ml) {
diff --git a/tests/wpt/tests/webnn/conformance_tests/subgraph.https.any.js b/tests/wpt/tests/webnn/conformance_tests/subgraph.https.any.js
index 9b21d6e4f94..8a0b7faa92f 100644
--- a/tests/wpt/tests/webnn/conformance_tests/subgraph.https.any.js
+++ b/tests/wpt/tests/webnn/conformance_tests/subgraph.https.any.js
@@ -2523,6 +2523,45 @@ const subgraphTests = [
}
}
},
+ {
+ 'name': 'float16 graph with float32 input and output',
+ 'graph': {
+ 'inputs': {
+ 'input': {
+ 'data': [1, 2, 3, 4],
+ 'descriptor': {shape: [4], dataType: 'float32'}
+ },
+ 'weight': {
+ 'data': [2],
+ 'descriptor': {shape: [], dataType: 'float16'},
+ 'constant': true
+ }
+ },
+ 'operators': [
+ {
+ 'name': 'cast',
+ 'arguments': [{'input': 'input'}, {'type': 'float16'}],
+ 'outputs': 'castOutput',
+ },
+ {
+ 'name': 'add',
+ 'arguments': [{'a': 'castOutput'}, {'b': 'weight'}],
+ 'outputs': 'addOutput'
+ },
+ {
+ 'name': 'cast',
+ 'arguments': [{'input': 'addOutput'}, {'type': 'float32'}],
+ 'outputs': 'output'
+ },
+ ],
+ 'expectedOutputs': {
+ 'output': {
+ 'data': [3, 4, 5, 6],
+ 'descriptor': {shape: [4], dataType: 'float32'}
+ }
+ }
+ }
+ },
];
if (navigator.ml) {
diff --git a/tests/wpt/tests/webrtc-encoded-transform/tentative/RTCEncodedAudioFrame-metadata.https.html b/tests/wpt/tests/webrtc-encoded-transform/tentative/RTCEncodedAudioFrame-metadata.https.html
index df4577c5614..1e148fe1b29 100644
--- a/tests/wpt/tests/webrtc-encoded-transform/tentative/RTCEncodedAudioFrame-metadata.https.html
+++ b/tests/wpt/tests/webrtc-encoded-transform/tentative/RTCEncodedAudioFrame-metadata.https.html
@@ -8,6 +8,7 @@
<script src='../../mediacapture-streams/permission-helper.js'></script>
<script src="../../webrtc/RTCPeerConnection-helper.js"></script>
<script src="../../service-workers/service-worker/resources/test-helpers.sub.js"></script>
+<script src='RTCEncodedFrame-timestamps-helper.js'></script>
<script>
"use strict";
@@ -130,4 +131,56 @@ promise_test(async t => {
return framesReceivedCorrectly;
}, "Constructing audio frame with bad metadata argument before sending does not work");
+
+promise_test(async t => {
+ const kCaptureTime = 12345;
+ const pc1 = new RTCPeerConnection({encodedInsertableStreams:true});
+ t.add_cleanup(() => pc1.close());
+ const pc2 = new RTCPeerConnection({encodedInsertableStreams:true});
+ t.add_cleanup(() => pc2.close());
+
+ exchangeIceCandidates(pc1, pc2);
+
+ let numFrames = 0;
+ let audioLevelRead = new Promise((resolve, reject) => {
+ pc2.ontrack = t.step_func(e => {
+ const receiverTransformer = new TransformStream({
+ async transform(encodedFrame, controller) {
+ const metadata = encodedFrame.getMetadata();
+ if (metadata.captureTime < kCaptureTime - 1 || metadata.captureTime > kCaptureTime + 1) {
+ reject("Unexpected captureTime");
+ }
+ controller.enqueue(encodedFrame);
+ if (++numFrames == 10)
+ resolve();
+ }
+ });
+ const receiverStreams = e.receiver.createEncodedStreams();
+ receiverStreams.readable
+ .pipeThrough(receiverTransformer)
+ .pipeTo(receiverStreams.writable);
+ });
+ });
+
+ const stream = await navigator.mediaDevices.getUserMedia({audio:true});
+ t.add_cleanup(() => stream.getTracks().forEach(track => track.stop()));
+ const sender = pc1.addTrack(stream.getAudioTracks()[0]);
+ const senderStreams = sender.createEncodedStreams();
+ const senderTransformer = new TransformStream({
+ async transform(encodedFrame, controller) {
+ let metadata = encodedFrame.getMetadata();
+ metadata.captureTime = kCaptureTime;
+ controller.enqueue(new RTCEncodedAudioFrame(encodedFrame, {metadata}));
+ }
+ });
+ senderStreams.readable
+ .pipeThrough(senderTransformer)
+ .pipeTo(senderStreams.writable);
+
+ await addAbsCaptureTimeAndExchangeOffer(pc1, pc2);
+ await checkAbsCaptureTimeAndExchangeAnswer(pc1, pc2, true);
+
+ await audioLevelRead;
+}, 'Basic simulcast setup with three spatial layers');
+
</script>
diff --git a/tests/wpt/tests/webrtc/RTCConfiguration-iceServers.html b/tests/wpt/tests/webrtc/RTCConfiguration-iceServers.html
index bc7831361ab..65a6015f52a 100644
--- a/tests/wpt/tests/webrtc/RTCConfiguration-iceServers.html
+++ b/tests/wpt/tests/webrtc/RTCConfiguration-iceServers.html
@@ -34,11 +34,14 @@
DOMString credential;
};
*/
+ // RFC 8489 limits the length of the TURN username to 509 bytes:
+ // https://datatracker.ietf.org/doc/html/rfc8489#section-14.3
+ const kUsernameOfMaxPermittedLength = 'a'.repeat(509);
test(() => {
const pc = new RTCPeerConnection();
assert_array_equals(pc.getConfiguration().iceServers, []);
- }, 'new RTCPeerConnection() should have default configuration.iceServers of undefined');
+ }, 'new RTCPeerConnection() should have default configuration.iceServers of []');
config_test(makePc => {
makePc({});
@@ -181,6 +184,15 @@
}, `with one turns server, one turn server, username, credential should succeed`);
+ config_test(makePc => {
+ assert_equals(kUsernameOfMaxPermittedLength.length, 509);
+ const pc = makePc({ iceServers: [{
+ urls: 'turn:turn.example.net',
+ username: kUsernameOfMaxPermittedLength,
+ credential: 'cred'
+ }] });
+ }, `with a turn server and a username of 509 characters should succeed`);
+
/*
4.3.2. To set a configuration
11.4. If scheme name is turn or turns, and either of server.username or
@@ -232,6 +244,16 @@
}] }));
}, 'with turns server and only credential should throw InvalidAccessError');
+ config_test(makePc => {
+ assert_equals(kUsernameOfMaxPermittedLength.length, 509);
+ assert_throws_dom('InvalidAccessError', () =>
+ makePc({ iceServers: [{
+ urls: 'turns:turn.example.net',
+ username: kUsernameOfMaxPermittedLength + 'a',
+ credential: 'cred'
+ }] }));
+ }, `with a turn server and a username of 510 characters throw InvalidAccessError`);
+
/*
4.3.2. To set a configuration
11.3. For each url in server.urls parse url and obtain scheme name.
@@ -284,6 +306,8 @@
assert_throws_dom("SyntaxError", () =>
makePc({ iceServers: [{
urls: 'turn://example.org/foo?x=y'
+ // `username` and `credential` are not passed because the invalid url
+ // should be rejected before the check for those arguments.
}] }));
}, 'with invalid turn url should throw SyntaxError');
diff --git a/tests/wpt/tests/websockets/stream/tentative/remote-close.any.js b/tests/wpt/tests/websockets/stream/tentative/remote-close.any.js
index b7fd321914a..c3e7ad5f9fb 100644
--- a/tests/wpt/tests/websockets/stream/tentative/remote-close.any.js
+++ b/tests/wpt/tests/websockets/stream/tentative/remote-close.any.js
@@ -48,7 +48,8 @@ promise_test(async t => {
const closedError = await wss.closed.then(t.unreached_func('closed should reject'), e => e);
assert_equals(closedError.constructor, WebSocketError, 'error should be WebSocketError');
assert_equals(closedError.closeCode, 4567, 'closeCode should be set');
- promise_rejects_js(t, WebSocketError, writePromise, 'write() should reject');
+ await promise_rejects_dom(
+ t, 'InvalidStateError', writePromise, 'write() should reject');
}, 'close with unwritten data should not be considered clean');
promise_test(async t => {
diff --git a/tests/wpt/tests/websockets/stream/tentative/write.any.js b/tests/wpt/tests/websockets/stream/tentative/write.any.js
new file mode 100644
index 00000000000..43af7da614c
--- /dev/null
+++ b/tests/wpt/tests/websockets/stream/tentative/write.any.js
@@ -0,0 +1,96 @@
+// META: script=../../constants.sub.js
+// META: script=resources/url-constants.js
+// META: script=/common/gc.js
+// META: global=window,worker
+// META: variant=?default
+// META: variant=?wss
+// META: variant=?wpt_flags=h2
+
+'use strict';
+
+const GOODBYE_MESSAGE = 'Goodbye'; // Must match echo_exit_wsh.py
+
+// This message needs to be large enough that writing it cannot complete
+// synchronously, and to fill up the TCP send buffer and any user agent internal
+// send buffers so that the user agent has to receive the "Close" frame from the
+// server before it can complete sending this message.
+const BIG_MESSAGE_SIZE = 8 * 1024 * 1024;
+
+// Common setup used by two tests. Sends a "Goodbye" message to tell the server
+// to close the WebSocket, and immediately afterwards a big message that cannot
+// be completely sent before the connection closes. Waits for the "Goodbye"
+// message to be sent and the connection to be closed before returning. `t` is
+// the test object provided by promse_test.
+async function sendGoodbyeThenBigMessage(t) {
+ const wss = new WebSocketStream(BASEURL + '/echo_exit');
+ const { writable } = await wss.opened;
+ const writer = writable.getWriter();
+ const bigMessage = new Uint8Array(BIG_MESSAGE_SIZE);
+ const goodbyePromise = writer.write(GOODBYE_MESSAGE);
+ const bigMessagePromise = writer.write(bigMessage);
+ await goodbyePromise;
+ // testharness.js doesn't know about WebSocketError yet.
+ await wss.closed.then(
+ t.unreached_func('closed promise should reject'),
+ e => assert_equals(
+ e.constructor, WebSocketError,
+ 'a WebSocketError should be thrown'));
+ return { writer, bigMessagePromise };
+}
+
+promise_test(async t => {
+ const { writer, bigMessagePromise } = await sendGoodbyeThenBigMessage(t);
+ await promise_rejects_dom(
+ t, 'InvalidStateError', bigMessagePromise,
+ 'write() should reject with an InvalidStateError');
+ const invalidStateError = await bigMessagePromise.then(
+ t.unreached_func('write() promise should reject'), e => e);
+ await promise_rejects_exactly(
+ t, invalidStateError, writer.write('word'),
+ 'stream should be errored with same object');
+}, 'a write that was incomplete at close time should reject');
+
+promise_test(async t => {
+ const { bigMessagePromise } = await sendGoodbyeThenBigMessage(t);
+ // For some reason 5 is the magic number that causes garbage collection to
+ // really really collect garbage.
+ for (let i = 0; i < 5; ++i) {
+ await garbageCollect();
+ }
+ await promise_rejects_dom(
+ t, 'InvalidStateError', bigMessagePromise,
+ 'write() should reject with an InvalidStateError');
+}, 'garbage collection after close with a pending write promise should not ' +
+ 'crash');
+
+promise_test(async t => {
+ const wss = new WebSocketStream(ECHOURL);
+ const { writable } = await wss.opened;
+ const writer = writable.getWriter();
+ const cannotStringify = { toString() { return this; } };
+ await promise_rejects_js(
+ t, TypeError, writer.write(cannotStringify), 'write() should reject');
+}, 'writing a value that cannot be stringified should cause a rejection');
+
+promise_test(async t => {
+ const wss = new WebSocketStream(ECHOURL);
+ const { writable } = await wss.opened;
+ const writer = writable.getWriter();
+ const buffer = new ArrayBuffer(1024, { maxByteLength: 65536 });
+ await promise_rejects_js(
+ t, TypeError, writer.write(buffer), 'write() should reject');
+}, 'writing a resizable ArrayBuffer should be rejected');
+
+promise_test(async t => {
+ const wss = new WebSocketStream(ECHOURL);
+ const { writable } = await wss.opened;
+ const writer = writable.getWriter();
+ const memory = new WebAssembly.Memory({
+ initial: 4096,
+ maximum: 65536,
+ shared: true,
+ });
+ const view = new Uint8Array(memory.buffer);
+ await promise_rejects_js(
+ t, TypeError, writer.write(view), 'write() should reject');
+}, 'writing a view on a shared buffer should be rejected');
diff --git a/tests/wpt/tests/workers/WEB_FEATURES.yml b/tests/wpt/tests/workers/WEB_FEATURES.yml
new file mode 100644
index 00000000000..1687ef742e2
--- /dev/null
+++ b/tests/wpt/tests/workers/WEB_FEATURES.yml
@@ -0,0 +1,6 @@
+features:
+- name: ua-client-hints
+ files:
+ - WorkerNavigator_userAgentData.http.html
+ - WorkerNavigator_userAgentData.https.html
+ - WorkerNavigator_userAgentData.https.tentative.html
diff --git a/tests/wpt/tests/workers/tentative/SharedWorker-extendedLifetime.html b/tests/wpt/tests/workers/tentative/SharedWorker-extendedLifetime.html
new file mode 100644
index 00000000000..3c76eddd764
--- /dev/null
+++ b/tests/wpt/tests/workers/tentative/SharedWorker-extendedLifetime.html
@@ -0,0 +1,61 @@
+<!DOCTYPE html>
+<title>SharedWorker extendedLifetime</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/common/utils.js"></script>
+<script src="/common/dispatcher/dispatcher.js"></script>
+<script>
+
+let request_id = 0;
+
+const connectToSharedWorker = async () => {
+ await window.pageShowPromise;
+ window.worker = new SharedWorker(
+ '/workers/tentative/resources/shared-worker-memory.js',
+ {extendedLifetime: true});
+ worker.port.start();
+};
+
+const postAndWait = async (data) => {
+ return new Promise(resolve => {
+ const listener = event => {
+ if (event.data.reqid !== data.reqid) {
+ return;
+ }
+ worker.port.removeEventListener('message', listener);
+ resolve(event.data);
+ };
+ worker.port.addEventListener('message', listener);
+ worker.port.postMessage(data);
+ });
+};
+
+promise_test(async t => {
+ // SharedWorker is started with the extendedLifetime option.
+ // random message is stored there, which can be read later.
+ const uuid = token();
+ const ctx = new RemoteContext(token());
+ const popup = window.open(remoteExecutorUrl(ctx.context_id));
+ await ctx.execute_script(connectToSharedWorker);
+ const popup_response = await ctx.execute_script(postAndWait, [{
+ reqid: request_id++,
+ op: 'store',
+ data: uuid,
+ }]);
+ assert_equals(popup_response.status, 'OK');
+ popup.close();
+
+ // Wait for a second.
+ await new Promise(resolve => setTimeout(resolve, 1));
+
+ const ctx2 = new RemoteContext(token());
+ const popup2 = window.open(remoteExecutorUrl(ctx2.context_id));
+ await ctx2.execute_script(connectToSharedWorker);
+ const popup2_response = await ctx2.execute_script(postAndWait, [{
+ reqid: request_id++,
+ op: 'load',
+ }]);
+ assert_equals(popup2_response.status, 'OK');
+ assert_equals(popup2_response.data, uuid);
+}, "SharedWorker lifetime should be extended with extendedLifetime");
+</script>
diff --git a/tests/wpt/tests/workers/tentative/resources/shared-worker-memory.js b/tests/wpt/tests/workers/tentative/resources/shared-worker-memory.js
new file mode 100644
index 00000000000..b1504f38c50
--- /dev/null
+++ b/tests/wpt/tests/workers/tentative/resources/shared-worker-memory.js
@@ -0,0 +1,30 @@
+'use strict';
+
+let stored_data = null;
+
+function processMessage(e) {
+ function respond(data) {
+ e.currentTarget.postMessage(Object.assign(data, {reqid: e.data.reqid}));
+ }
+
+ switch (e.data.op) {
+ case 'load': {
+ respond({ack: 'load', status: 'OK', data: stored_data});
+ break;
+ }
+ case 'store': {
+ try {
+ stored_data = e.data.data
+ } catch (err) {
+ respond({ack: 'store', status: 'ERROR', error: err.name});
+ return;
+ }
+ respond({ack: 'store', status: 'OK'});
+ break;
+ }
+ }
+}
+
+self.addEventListener('connect', e => {
+ e.ports[0].onmessage = processMessage;
+});
diff --git a/tests/wpt/webgl/meta/conformance/textures/misc/tex-video-using-tex-unit-non-zero.html.ini b/tests/wpt/webgl/meta/conformance/textures/misc/tex-video-using-tex-unit-non-zero.html.ini
index 5b9d4a0e1b9..f8ab654ff94 100644
--- a/tests/wpt/webgl/meta/conformance/textures/misc/tex-video-using-tex-unit-non-zero.html.ini
+++ b/tests/wpt/webgl/meta/conformance/textures/misc/tex-video-using-tex-unit-non-zero.html.ini
@@ -3,9 +3,3 @@
expected: TIMEOUT
[Overall test]
expected: NOTRUN
-
- [WebGL test #0]
- expected: FAIL
-
- [WebGL test #1]
- expected: FAIL
diff --git a/tests/wpt/webgl/meta/conformance/textures/misc/texture-upload-size.html.ini b/tests/wpt/webgl/meta/conformance/textures/misc/texture-upload-size.html.ini
index 435cfbe0d5c..e9f1c0ae3f3 100644
--- a/tests/wpt/webgl/meta/conformance/textures/misc/texture-upload-size.html.ini
+++ b/tests/wpt/webgl/meta/conformance/textures/misc/texture-upload-size.html.ini
@@ -13,3 +13,75 @@
[WebGL test #588]
expected: FAIL
+
+ [WebGL test #53]
+ expected: FAIL
+
+ [WebGL test #55]
+ expected: FAIL
+
+ [WebGL test #57]
+ expected: FAIL
+
+ [WebGL test #59]
+ expected: FAIL
+
+ [WebGL test #69]
+ expected: FAIL
+
+ [WebGL test #71]
+ expected: FAIL
+
+ [WebGL test #73]
+ expected: FAIL
+
+ [WebGL test #75]
+ expected: FAIL
+
+ [WebGL test #85]
+ expected: FAIL
+
+ [WebGL test #87]
+ expected: FAIL
+
+ [WebGL test #89]
+ expected: FAIL
+
+ [WebGL test #91]
+ expected: FAIL
+
+ [WebGL test #101]
+ expected: FAIL
+
+ [WebGL test #103]
+ expected: FAIL
+
+ [WebGL test #105]
+ expected: FAIL
+
+ [WebGL test #107]
+ expected: FAIL
+
+ [WebGL test #117]
+ expected: FAIL
+
+ [WebGL test #119]
+ expected: FAIL
+
+ [WebGL test #121]
+ expected: FAIL
+
+ [WebGL test #123]
+ expected: FAIL
+
+ [WebGL test #133]
+ expected: FAIL
+
+ [WebGL test #135]
+ expected: FAIL
+
+ [WebGL test #137]
+ expected: FAIL
+
+ [WebGL test #139]
+ expected: FAIL