aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock22
-rw-r--r--components/layout/flexbox/layout.rs25
-rw-r--r--components/layout/flow/inline/line.rs2
-rw-r--r--components/layout/flow/inline/mod.rs4
-rw-r--r--components/layout/flow/mod.rs5
-rw-r--r--components/layout/flow/root.rs3
-rw-r--r--components/layout/formatting_contexts.rs5
-rw-r--r--components/layout/layout_impl.rs36
-rw-r--r--components/layout/positioned.rs339
-rw-r--r--components/layout/stylesheets/presentational-hints.css (renamed from resources/presentational-hints.css)0
-rw-r--r--components/layout/stylesheets/quirks-mode.css (renamed from resources/quirks-mode.css)0
-rw-r--r--components/layout/stylesheets/servo.css (renamed from resources/servo.css)0
-rw-r--r--components/layout/stylesheets/user-agent.css (renamed from resources/user-agent.css)0
-rw-r--r--components/layout/table/layout.rs47
-rw-r--r--components/layout/taffy/layout.rs72
-rw-r--r--components/layout/taffy/mod.rs5
-rw-r--r--components/net/Cargo.toml1
-rw-r--r--components/net/image_cache.rs26
-rw-r--r--components/net/tests/fetch.rs2
-rw-r--r--components/script/dom/document.rs142
-rw-r--r--components/script/dom/element.rs30
-rw-r--r--components/script/dom/gamepad.rs41
-rw-r--r--components/script/dom/gamepadbutton.rs6
-rw-r--r--components/script/dom/gamepadbuttonlist.rs44
-rw-r--r--components/script/dom/gamepadhapticactuator.rs20
-rw-r--r--components/script/dom/globalscope.rs171
-rw-r--r--components/script/dom/htmlelement.rs19
-rw-r--r--components/script/dom/htmliframeelement.rs17
-rw-r--r--components/script/dom/htmlmediaelement.rs13
-rw-r--r--components/script/dom/htmlscriptelement.rs116
-rw-r--r--components/script/dom/macros.rs26
-rw-r--r--components/script/dom/messageport.rs4
-rw-r--r--components/script/dom/servointernals.rs4
-rw-r--r--components/script/dom/servoparser/mod.rs32
-rw-r--r--components/script/dom/trustedhtml.rs37
-rw-r--r--components/script/dom/trustedscript.rs36
-rw-r--r--components/script/dom/trustedscripturl.rs29
-rw-r--r--components/script/dom/trustedtypepolicy.rs195
-rw-r--r--components/script/dom/trustedtypepolicyfactory.rs60
-rw-r--r--components/script/dom/webgpu/gpu.rs4
-rw-r--r--components/script/dom/webgpu/gpuadapter.rs6
-rw-r--r--components/script/dom/webgpu/gpubuffer.rs6
-rw-r--r--components/script/dom/webgpu/gpudevice.rs18
-rw-r--r--components/script/dom/webgpu/gpuqueue.rs4
-rw-r--r--components/script/dom/webgpu/gpushadermodule.rs9
-rw-r--r--components/script/dom/webxr/xrhittestsource.rs6
-rw-r--r--components/script/dom/webxr/xrinputsource.rs13
-rw-r--r--components/script/dom/webxr/xrinputsourcearray.rs10
-rw-r--r--components/script/dom/webxr/xrrenderstate.rs8
-rw-r--r--components/script/dom/webxr/xrsession.rs12
-rw-r--r--components/script/dom/webxr/xrsystem.rs8
-rw-r--r--components/script/dom/window.rs129
-rw-r--r--components/script/dom/worker.rs17
-rw-r--r--components/script/dom/workerglobalscope.rs23
-rw-r--r--components/script/resources/media-controls.css (renamed from resources/media-controls.css)0
-rw-r--r--components/script/resources/media-controls.js (renamed from resources/media-controls.js)0
-rw-r--r--components/script/routed_promise.rs10
-rw-r--r--components/script/script_thread.rs29
-rw-r--r--components/script_bindings/codegen/Bindings.conf2
-rw-r--r--components/script_bindings/webidls/Document.webidl4
-rw-r--r--components/script_bindings/webidls/HTMLScriptElement.webidl8
-rw-r--r--components/script_bindings/webidls/Worker.webidl2
-rw-r--r--components/script_bindings/webidls/WorkerGlobalScope.webidl2
-rw-r--r--components/servo/Cargo.toml9
-rw-r--r--components/servo/tests/common/mod.rs114
-rw-r--r--components/servo/tests/servo.rs24
-rw-r--r--components/servo/tests/webview.rs49
-rw-r--r--components/shared/constellation/from_script_message.rs4
-rw-r--r--components/shared/embedder/resources.rs38
-rw-r--r--components/shared/net/image_cache.rs6
-rw-r--r--ports/servoshell/egl/android/resources.rs12
-rw-r--r--tests/wpt/meta/FileAPI/url/url-in-tags-revoke.window.js.ini3
-rw-r--r--tests/wpt/meta/FileAPI/url/url-with-fetch.any.js.ini3
-rw-r--r--tests/wpt/meta/MANIFEST.json1515
-rw-r--r--tests/wpt/meta/content-security-policy/generic/invalid-characters-in-policy.html.ini14
-rw-r--r--tests/wpt/meta/content-security-policy/generic/only-valid-whitespaces-are-allowed.html.ini47
-rw-r--r--tests/wpt/meta/content-security-policy/inheritance/document-write-iframe.html.ini3
-rw-r--r--tests/wpt/meta/content-security-policy/inheritance/history-iframe.sub.html.ini6
-rw-r--r--tests/wpt/meta/content-security-policy/inheritance/iframe-all-local-schemes.sub.html.ini18
-rw-r--r--tests/wpt/meta/content-security-policy/inheritance/iframe-srcdoc-inheritance.html.ini7
-rw-r--r--tests/wpt/meta/content-security-policy/inheritance/location-reload.html.ini8
-rw-r--r--tests/wpt/meta/content-security-policy/navigation/to-javascript-parent-initiated-child-csp.html.ini5
-rw-r--r--tests/wpt/meta/content-security-policy/navigation/to-javascript-parent-initiated-parent-csp.html.ini10
-rw-r--r--tests/wpt/meta/content-security-policy/script-src/script-src-strict_dynamic_javascript_uri.html.ini4
-rw-r--r--tests/wpt/meta/content-security-policy/script-src/script-src-trusted_types_eval_with_require_trusted_types_eval.html.ini13
-rw-r--r--tests/wpt/meta/content-security-policy/script-src/srcdoc-doesnt-bypass-script-src.sub.html.ini3
-rw-r--r--tests/wpt/meta/content-security-policy/securitypolicyviolation/linenumber.tentative.html.ini3
-rw-r--r--tests/wpt/meta/content-security-policy/unsafe-eval/eval-blocked-in-about-blank-iframe.html.ini4
-rw-r--r--tests/wpt/meta/content-security-policy/unsafe-hashes/javascript_src_denied_missing_unsafe_hashes-href.html.ini3
-rw-r--r--tests/wpt/meta/content-security-policy/unsafe-hashes/javascript_src_denied_missing_unsafe_hashes-window_location.html.ini3
-rw-r--r--tests/wpt/meta/content-security-policy/unsafe-hashes/javascript_src_denied_wrong_hash-href.html.ini3
-rw-r--r--tests/wpt/meta/content-security-policy/unsafe-hashes/javascript_src_denied_wrong_hash-window_location.html.ini3
-rw-r--r--tests/wpt/meta/css/css-backgrounds/background-image-shared-stylesheet.html.ini2
-rw-r--r--tests/wpt/meta/css/css-gaps/multicol/multicol-gap-decorations-001.html.ini (renamed from tests/wpt/meta/css/css-gaps/tentative/multicol/multicol-gap-decorations-001.html.ini)0
-rw-r--r--tests/wpt/meta/css/css-gaps/multicol/multicol-gap-decorations-002.html.ini (renamed from tests/wpt/meta/css/css-gaps/tentative/multicol/multicol-gap-decorations-002.html.ini)0
-rw-r--r--tests/wpt/meta/css/css-gaps/multicol/multicol-gap-decorations-003.html.ini (renamed from tests/wpt/meta/css/css-gaps/tentative/multicol/multicol-gap-decorations-003.html.ini)0
-rw-r--r--tests/wpt/meta/css/css-gaps/multicol/multicol-gap-decorations-004.html.ini (renamed from tests/wpt/meta/css/css-gaps/tentative/multicol/multicol-gap-decorations-004.html.ini)0
-rw-r--r--tests/wpt/meta/css/css-gaps/multicol/multicol-gap-decorations-005.html.ini (renamed from tests/wpt/meta/css/css-gaps/tentative/multicol/multicol-gap-decorations-005.html.ini)0
-rw-r--r--tests/wpt/meta/css/css-gaps/multicol/multicol-gap-decorations-006.html.ini (renamed from tests/wpt/meta/css/css-gaps/tentative/multicol/multicol-gap-decorations-006.html.ini)0
-rw-r--r--tests/wpt/meta/css/css-gaps/multicol/multicol-gap-decorations-007.html.ini (renamed from tests/wpt/meta/css/css-gaps/tentative/multicol/multicol-gap-decorations-007.html.ini)0
-rw-r--r--tests/wpt/meta/css/css-gaps/multicol/multicol-gap-decorations-008.html.ini (renamed from tests/wpt/meta/css/css-gaps/tentative/multicol/multicol-gap-decorations-008.html.ini)0
-rw-r--r--tests/wpt/meta/css/css-gaps/multicol/multicol-gap-decorations-009.html.ini (renamed from tests/wpt/meta/css/css-gaps/tentative/multicol/multicol-gap-decorations-009.html.ini)0
-rw-r--r--tests/wpt/meta/css/css-gaps/multicol/multicol-gap-decorations-010.html.ini (renamed from tests/wpt/meta/css/css-gaps/tentative/multicol/multicol-gap-decorations-010.html.ini)0
-rw-r--r--tests/wpt/meta/css/css-gaps/multicol/multicol-gap-decorations-011.html.ini (renamed from tests/wpt/meta/css/css-gaps/tentative/multicol/multicol-gap-decorations-011.html.ini)0
-rw-r--r--tests/wpt/meta/css/css-gaps/multicol/multicol-gap-decorations-012.html.ini (renamed from tests/wpt/meta/css/css-gaps/tentative/multicol/multicol-gap-decorations-012.html.ini)0
-rw-r--r--tests/wpt/meta/css/css-gaps/multicol/multicol-gap-decorations-013.html.ini (renamed from tests/wpt/meta/css/css-gaps/tentative/multicol/multicol-gap-decorations-013.html.ini)0
-rw-r--r--tests/wpt/meta/css/css-gaps/multicol/multicol-gap-decorations-014.html.ini (renamed from tests/wpt/meta/css/css-gaps/tentative/multicol/multicol-gap-decorations-014.html.ini)0
-rw-r--r--tests/wpt/meta/css/css-gaps/multicol/multicol-gap-decorations-015.html.ini2
-rw-r--r--tests/wpt/meta/css/css-gaps/multicol/multicol-gap-decorations-016.html.ini2
-rw-r--r--tests/wpt/meta/css/css-grid/subgrid/line-names-015.html.ini2
-rw-r--r--tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-auto-025.tentative.html.ini2
-rw-r--r--tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-001.html.ini2
-rw-r--r--tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-001.tentative.html.ini2
-rw-r--r--tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-002.html.ini2
-rw-r--r--tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-002.tentative.html.ini2
-rw-r--r--tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-003.html.ini2
-rw-r--r--tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-003.tentative.html.ini2
-rw-r--r--tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-004.html.ini2
-rw-r--r--tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-004.tentative.html.ini2
-rw-r--r--tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-005.html.ini2
-rw-r--r--tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-005.tentative.html.ini2
-rw-r--r--tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-006.html.ini2
-rw-r--r--tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-006.tentative.html.ini2
-rw-r--r--tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-007.html.ini2
-rw-r--r--tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-007.tentative.html.ini2
-rw-r--r--tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-008.html.ini2
-rw-r--r--tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-008.tentative.html.ini2
-rw-r--r--tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-009.html.ini2
-rw-r--r--tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-009.tentative.html.ini2
-rw-r--r--tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-010.html.ini2
-rw-r--r--tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-010.tentative.html.ini2
-rw-r--r--tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-011.html.ini2
-rw-r--r--tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-011.tentative.html.ini2
-rw-r--r--tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-012.html.ini2
-rw-r--r--tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-012.tentative.html.ini2
-rw-r--r--tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-013.html.ini2
-rw-r--r--tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-013.tentative.html.ini2
-rw-r--r--tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-014.html.ini2
-rw-r--r--tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-014.tentative.html.ini2
-rw-r--r--tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-015.html.ini2
-rw-r--r--tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-016.html.ini2
-rw-r--r--tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-017.tentative.html.ini2
-rw-r--r--tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-018.html.ini2
-rw-r--r--tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-019.html.ini2
-rw-r--r--tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-020.html.ini2
-rw-r--r--tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-021.html.ini2
-rw-r--r--tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-022.html.ini2
-rw-r--r--tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-001.html.ini2
-rw-r--r--tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-002.html.ini2
-rw-r--r--tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-003.html.ini2
-rw-r--r--tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-004.html.ini2
-rw-r--r--tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-005.html.ini2
-rw-r--r--tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-006.html.ini2
-rw-r--r--tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-007.html.ini2
-rw-r--r--tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-008.html.ini2
-rw-r--r--tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-009.html.ini2
-rw-r--r--tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-010.html.ini2
-rw-r--r--tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-011.html.ini2
-rw-r--r--tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-012.html.ini2
-rw-r--r--tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-013.html.ini2
-rw-r--r--tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-014.html.ini2
-rw-r--r--tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-015.html.ini2
-rw-r--r--tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-016.html.ini2
-rw-r--r--tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-017.html.ini2
-rw-r--r--tests/wpt/meta/css/css-sizing/dynamic-available-size-iframe.html.ini2
-rw-r--r--tests/wpt/meta/css/css-transforms/parsing/transform-valid.html.ini30
-rw-r--r--tests/wpt/meta/css/css-values/tree-counting/calc-sibling-function-in-shadow-dom.html.ini3
-rw-r--r--tests/wpt/meta/fetch/stale-while-revalidate/stale-image.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/initial-empty-document/iframe-nosrc.html.ini3
-rw-r--r--tests/wpt/meta/html/browsers/browsing-the-web/navigating-across-documents/navigation-unload-same-origin.window.js.ini3
-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-invalid-args.html.ini2
-rw-r--r--tests/wpt/meta/html/canvas/element/manual/imagebitmap/createImageBitmap-transfer.html.ini2
-rw-r--r--tests/wpt/meta/html/infrastructure/urls/base-url/document-base-url-window-initiator-is-not-opener.https.window.js.ini1
-rw-r--r--tests/wpt/meta/html/interaction/focus/the-autofocus-attribute/supported-elements.html.ini7
-rw-r--r--tests/wpt/meta/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_escaping-3.html.ini3
-rw-r--r--tests/wpt/meta/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_nonescaping-2.html.ini2
-rw-r--r--tests/wpt/meta/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_nonescaping-3.html.ini1
-rw-r--r--tests/wpt/meta/html/semantics/forms/form-submission-0/text-plain.window.js.ini3
-rw-r--r--tests/wpt/meta/html/semantics/forms/the-select-element/customizable-select/select-parsing.tentative.html.ini3
-rw-r--r--tests/wpt/meta/html/semantics/scripting-1/the-script-element/module/dynamic-import/blob-url.any.js.ini6
-rw-r--r--tests/wpt/meta/quirks/line-height-calculation.html.ini3
-rw-r--r--tests/wpt/meta/quirks/table-cell-width-calculation.html.ini17
-rw-r--r--tests/wpt/meta/trusted-types/DedicatedWorker-constructor-from-DedicatedWorker.html.ini3
-rw-r--r--tests/wpt/meta/trusted-types/DedicatedWorker-constructor.https.html.ini6
-rw-r--r--tests/wpt/meta/trusted-types/DedicatedWorker-importScripts.html.ini18
-rw-r--r--tests/wpt/meta/trusted-types/Document-write-exception-order.xhtml.ini3
-rw-r--r--tests/wpt/meta/trusted-types/HTMLElement-generic.html.ini60
-rw-r--r--tests/wpt/meta/trusted-types/block-string-assignment-to-Document-write.html.ini42
-rw-r--r--tests/wpt/meta/trusted-types/block-string-assignment-to-HTMLElement-generic.html.ini12
-rw-r--r--tests/wpt/meta/trusted-types/block-string-assignment-to-text-and-url-sinks.html.ini9
-rw-r--r--tests/wpt/meta/trusted-types/default-policy.html.ini21
-rw-r--r--tests/wpt/meta/trusted-types/empty-default-policy.html.ini3
-rw-r--r--tests/wpt/meta/trusted-types/require-trusted-types-for-report-only.html.ini6
-rw-r--r--tests/wpt/meta/trusted-types/require-trusted-types-for.html.ini6
-rw-r--r--tests/wpt/meta/trusted-types/trusted-types-createHTMLDocument.html.ini12
-rw-r--r--tests/wpt/meta/trusted-types/trusted-types-report-only.html.ini9
-rw-r--r--tests/wpt/meta/trusted-types/trusted-types-reporting-for-DedicatedWorker-DedicatedWorker-constructor.html.ini3
-rw-r--r--tests/wpt/meta/trusted-types/trusted-types-reporting-for-DedicatedWorker-importScripts.html.ini3
-rw-r--r--tests/wpt/meta/trusted-types/trusted-types-reporting-for-Document-write.html.ini6
-rw-r--r--tests/wpt/meta/trusted-types/trusted-types-reporting-for-HTMLScriptElement.html.ini12
-rw-r--r--tests/wpt/meta/trusted-types/trusted-types-reporting-for-Window-DedicatedWorker-constructor.html.ini3
-rw-r--r--tests/wpt/meta/webaudio/the-audio-api/the-audiobuffersourcenode-interface/sub-sample-buffer-stitching.html.ini12
-rw-r--r--tests/wpt/tests/ai/language_detection/detector-iframe.https.html40
-rw-r--r--tests/wpt/tests/ai/language_detection/detector.https.window.js5
-rw-r--r--tests/wpt/tests/ai/language_detection/resources/iframe-helper.html34
-rw-r--r--tests/wpt/tests/ai/summarizer/summarizer-abort.tentative.https.window.js (renamed from tests/wpt/tests/ai/summarizer/summarizer-abort.tentative.https.any.js)0
-rw-r--r--tests/wpt/tests/ai/summarizer/summarizer-availability-available.tentative.https.window.js (renamed from tests/wpt/tests/ai/summarizer/summarizer-availability-available.tentative.https.any.js)0
-rw-r--r--tests/wpt/tests/ai/summarizer/summarizer-availability.tentative.https.window.js (renamed from tests/wpt/tests/ai/summarizer/summarizer-availability.tentative.https.any.js)0
-rw-r--r--tests/wpt/tests/ai/summarizer/summarizer-create-available.tentative.https.window.js (renamed from tests/wpt/tests/ai/summarizer/summarizer-create-available.tentative.https.any.js)0
-rw-r--r--tests/wpt/tests/ai/summarizer/summarizer-create.tentative.https.window.js (renamed from tests/wpt/tests/ai/summarizer/summarizer-create.tentative.https.any.js)0
-rw-r--r--tests/wpt/tests/ai/summarizer/summarizer-measureInputUsage.tentative.https.window.js (renamed from tests/wpt/tests/ai/summarizer/summarizer-measureInputUsage.tentative.https.any.js)0
-rw-r--r--tests/wpt/tests/ai/summarizer/summarizer-summarize-streaming.tentative.https.window.js (renamed from tests/wpt/tests/ai/summarizer/summarizer-summarize-streaming.tentative.https.any.js)0
-rw-r--r--tests/wpt/tests/ai/summarizer/summarizer-summarize.tentative.https.window.js (renamed from tests/wpt/tests/ai/summarizer/summarizer-summarize.tentative.https.any.js)0
-rw-r--r--tests/wpt/tests/content-security-policy/unsafe-eval/eval-blocked-in-about-blank-iframe.html29
-rw-r--r--tests/wpt/tests/cookie-store/serviceworker_cookiechange_eventhandler_already_expired.https.any.js86
-rw-r--r--tests/wpt/tests/cookie-store/serviceworker_cookiechange_eventhandler_no_change.https.any.js128
-rw-r--r--tests/wpt/tests/cookies/partitioned-cookies/partitioned-cookies-samesite-attribute.https.html59
-rw-r--r--tests/wpt/tests/cookies/partitioned-cookies/resources/partitioned-cookies-samesite-attributes-embed.html31
-rw-r--r--tests/wpt/tests/css/css-align/abspos/align-self-static-position-005-ref.html2
-rw-r--r--tests/wpt/tests/css/css-align/abspos/align-self-static-position-005.html2
-rw-r--r--tests/wpt/tests/css/css-break/nested-fixedpos-in-inline-003-crash.html13
-rw-r--r--tests/wpt/tests/css/css-gaps/multicol/multicol-gap-decorations-001-ref.html (renamed from tests/wpt/tests/css/css-gaps/tentative/multicol/multicol-gap-decorations-001-ref.html)0
-rw-r--r--tests/wpt/tests/css/css-gaps/multicol/multicol-gap-decorations-001.html (renamed from tests/wpt/tests/css/css-gaps/tentative/multicol/multicol-gap-decorations-001.html)0
-rw-r--r--tests/wpt/tests/css/css-gaps/multicol/multicol-gap-decorations-002-ref.html (renamed from tests/wpt/tests/css/css-gaps/tentative/multicol/multicol-gap-decorations-002-ref.html)0
-rw-r--r--tests/wpt/tests/css/css-gaps/multicol/multicol-gap-decorations-002.html (renamed from tests/wpt/tests/css/css-gaps/tentative/multicol/multicol-gap-decorations-002.html)0
-rw-r--r--tests/wpt/tests/css/css-gaps/multicol/multicol-gap-decorations-003-ref.html (renamed from tests/wpt/tests/css/css-gaps/tentative/multicol/multicol-gap-decorations-003-ref.html)0
-rw-r--r--tests/wpt/tests/css/css-gaps/multicol/multicol-gap-decorations-003.html (renamed from tests/wpt/tests/css/css-gaps/tentative/multicol/multicol-gap-decorations-003.html)0
-rw-r--r--tests/wpt/tests/css/css-gaps/multicol/multicol-gap-decorations-004-ref.html (renamed from tests/wpt/tests/css/css-gaps/tentative/multicol/multicol-gap-decorations-004-ref.html)0
-rw-r--r--tests/wpt/tests/css/css-gaps/multicol/multicol-gap-decorations-004.html (renamed from tests/wpt/tests/css/css-gaps/tentative/multicol/multicol-gap-decorations-004.html)0
-rw-r--r--tests/wpt/tests/css/css-gaps/multicol/multicol-gap-decorations-005-ref.html (renamed from tests/wpt/tests/css/css-gaps/tentative/multicol/multicol-gap-decorations-005-ref.html)0
-rw-r--r--tests/wpt/tests/css/css-gaps/multicol/multicol-gap-decorations-005.html (renamed from tests/wpt/tests/css/css-gaps/tentative/multicol/multicol-gap-decorations-005.html)0
-rw-r--r--tests/wpt/tests/css/css-gaps/multicol/multicol-gap-decorations-006-ref.html (renamed from tests/wpt/tests/css/css-gaps/tentative/multicol/multicol-gap-decorations-006-ref.html)0
-rw-r--r--tests/wpt/tests/css/css-gaps/multicol/multicol-gap-decorations-006.html (renamed from tests/wpt/tests/css/css-gaps/tentative/multicol/multicol-gap-decorations-006.html)0
-rw-r--r--tests/wpt/tests/css/css-gaps/multicol/multicol-gap-decorations-007-ref.html (renamed from tests/wpt/tests/css/css-gaps/tentative/multicol/multicol-gap-decorations-007-ref.html)0
-rw-r--r--tests/wpt/tests/css/css-gaps/multicol/multicol-gap-decorations-007.html (renamed from tests/wpt/tests/css/css-gaps/tentative/multicol/multicol-gap-decorations-007.html)0
-rw-r--r--tests/wpt/tests/css/css-gaps/multicol/multicol-gap-decorations-008-ref.html (renamed from tests/wpt/tests/css/css-gaps/tentative/multicol/multicol-gap-decorations-008-ref.html)0
-rw-r--r--tests/wpt/tests/css/css-gaps/multicol/multicol-gap-decorations-008.html (renamed from tests/wpt/tests/css/css-gaps/tentative/multicol/multicol-gap-decorations-008.html)0
-rw-r--r--tests/wpt/tests/css/css-gaps/multicol/multicol-gap-decorations-009-ref.html (renamed from tests/wpt/tests/css/css-gaps/tentative/multicol/multicol-gap-decorations-009-ref.html)0
-rw-r--r--tests/wpt/tests/css/css-gaps/multicol/multicol-gap-decorations-009.html (renamed from tests/wpt/tests/css/css-gaps/tentative/multicol/multicol-gap-decorations-009.html)0
-rw-r--r--tests/wpt/tests/css/css-gaps/multicol/multicol-gap-decorations-010-ref.html (renamed from tests/wpt/tests/css/css-gaps/tentative/multicol/multicol-gap-decorations-010-ref.html)0
-rw-r--r--tests/wpt/tests/css/css-gaps/multicol/multicol-gap-decorations-010.html (renamed from tests/wpt/tests/css/css-gaps/tentative/multicol/multicol-gap-decorations-010.html)0
-rw-r--r--tests/wpt/tests/css/css-gaps/multicol/multicol-gap-decorations-011-ref.html (renamed from tests/wpt/tests/css/css-gaps/tentative/multicol/multicol-gap-decorations-011-ref.html)0
-rw-r--r--tests/wpt/tests/css/css-gaps/multicol/multicol-gap-decorations-011.html (renamed from tests/wpt/tests/css/css-gaps/tentative/multicol/multicol-gap-decorations-011.html)0
-rw-r--r--tests/wpt/tests/css/css-gaps/multicol/multicol-gap-decorations-012-ref.html (renamed from tests/wpt/tests/css/css-gaps/tentative/multicol/multicol-gap-decorations-012-ref.html)0
-rw-r--r--tests/wpt/tests/css/css-gaps/multicol/multicol-gap-decorations-012.html (renamed from tests/wpt/tests/css/css-gaps/tentative/multicol/multicol-gap-decorations-012.html)0
-rw-r--r--tests/wpt/tests/css/css-gaps/multicol/multicol-gap-decorations-013-ref.html (renamed from tests/wpt/tests/css/css-gaps/tentative/multicol/multicol-gap-decorations-013-ref.html)0
-rw-r--r--tests/wpt/tests/css/css-gaps/multicol/multicol-gap-decorations-013.html (renamed from tests/wpt/tests/css/css-gaps/tentative/multicol/multicol-gap-decorations-013.html)0
-rw-r--r--tests/wpt/tests/css/css-gaps/multicol/multicol-gap-decorations-014-ref.html (renamed from tests/wpt/tests/css/css-gaps/tentative/multicol/multicol-gap-decorations-014-ref.html)0
-rw-r--r--tests/wpt/tests/css/css-gaps/multicol/multicol-gap-decorations-014.html (renamed from tests/wpt/tests/css/css-gaps/tentative/multicol/multicol-gap-decorations-014.html)0
-rw-r--r--tests/wpt/tests/css/css-gaps/multicol/multicol-gap-decorations-015-ref.html70
-rw-r--r--tests/wpt/tests/css/css-gaps/multicol/multicol-gap-decorations-015.html55
-rw-r--r--tests/wpt/tests/css/css-gaps/multicol/multicol-gap-decorations-016-ref.html70
-rw-r--r--tests/wpt/tests/css/css-gaps/multicol/multicol-gap-decorations-016.html55
-rw-r--r--tests/wpt/tests/css/css-grid/abspos/abspos-in-flexbox-in-grid-crash.html12
-rw-r--r--tests/wpt/tests/css/css-grid/grid-definition/grid-auto-fit-with-calc.html23
-rw-r--r--tests/wpt/tests/css/css-grid/subgrid/line-names-015.html34
-rw-r--r--tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-auto-031.tentative.html8
-rw-r--r--tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-001.html (renamed from tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-001.tentative.html)12
-rw-r--r--tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-002.html (renamed from tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-002.tentative.html)12
-rw-r--r--tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-003.html29
-rw-r--r--tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-003.tentative.html29
-rw-r--r--tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-004.html34
-rw-r--r--tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-004.tentative.html34
-rw-r--r--tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-005.html (renamed from tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-008.tentative.html)17
-rw-r--r--tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-005.tentative.html29
-rw-r--r--tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-006.html35
-rw-r--r--tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-006.tentative.html34
-rw-r--r--tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-007.html30
-rw-r--r--tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-007.tentative.html30
-rw-r--r--tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-008.html35
-rw-r--r--tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-009.html31
-rw-r--r--tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-010.html36
-rw-r--r--tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-011.html (renamed from tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-009.tentative.html)18
-rw-r--r--tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-012.html37
-rw-r--r--tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-013.html32
-rw-r--r--tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-014.html36
-rw-r--r--tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-015.html32
-rw-r--r--tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-016.html32
-rw-r--r--tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-017.tentative.html37
-rw-r--r--tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-018.html (renamed from tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-010.tentative.html)2
-rw-r--r--tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-019.html (renamed from tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-011.tentative.html)24
-rw-r--r--tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-020.html (renamed from tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-012.tentative.html)22
-rw-r--r--tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-021.html (renamed from tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-013.tentative.html)10
-rw-r--r--tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-022.html (renamed from tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-014.tentative.html)7
-rw-r--r--tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-001.html29
-rw-r--r--tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-002.html34
-rw-r--r--tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-003.html29
-rw-r--r--tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-004.html34
-rw-r--r--tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-005.html30
-rw-r--r--tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-006.html35
-rw-r--r--tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-007.html30
-rw-r--r--tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-008.html35
-rw-r--r--tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-009.html31
-rw-r--r--tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-010.html36
-rw-r--r--tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-011.html33
-rw-r--r--tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-012.html37
-rw-r--r--tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-013.html32
-rw-r--r--tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-014.html36
-rw-r--r--tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-015.html37
-rw-r--r--tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-016.html (renamed from tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-auto-025.tentative.html)18
-rw-r--r--tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-017.html33
-rw-r--r--tests/wpt/tests/css/css-overflow/line-clamp/reference/line-clamp-with-abspos-001-ref.html8
-rw-r--r--tests/wpt/tests/css/css-overflow/line-clamp/reference/line-clamp-with-abspos-005-ref.html13
-rw-r--r--tests/wpt/tests/css/css-overflow/line-clamp/reference/line-clamp-with-abspos-009-ref.html (renamed from tests/wpt/tests/css/css-overflow/line-clamp/reference/line-clamp-with-abspos-006-ref.html)25
-rw-r--r--tests/wpt/tests/css/css-overflow/line-clamp/reference/line-clamp-with-abspos-013-ref.html (renamed from tests/wpt/tests/css/css-overflow/line-clamp/reference/line-clamp-with-abspos-008-ref.html)17
-rw-r--r--tests/wpt/tests/css/css-overflow/line-clamp/reference/line-clamp-with-abspos-016-ref.html (renamed from tests/wpt/tests/css/css-overflow/line-clamp/reference/line-clamp-with-abspos-007-ref.html)16
-rw-r--r--tests/wpt/tests/css/css-overflow/line-clamp/reference/line-clamp-with-abspos-018-ref.html (renamed from tests/wpt/tests/css/css-overflow/line-clamp/reference/line-clamp-with-abspos-010-ref.html)0
-rw-r--r--tests/wpt/tests/css/css-overflow/line-clamp/reference/line-clamp-with-abspos-019-ref.html (renamed from tests/wpt/tests/css/css-overflow/line-clamp/reference/line-clamp-with-abspos-011-ref.html)17
-rw-r--r--tests/wpt/tests/css/css-overflow/line-clamp/webkit-line-clamp-abspos-001.html (renamed from tests/wpt/tests/css/css-overflow/line-clamp/webkit-line-clamp-abspos-001.tentative.html)0
-rw-r--r--tests/wpt/tests/css/css-overflow/scroll-marker-active-unreached-target.html113
-rw-r--r--tests/wpt/tests/css/css-transforms/parsing/transform-valid.html20
-rw-r--r--tests/wpt/tests/css/css-values/tree-counting/calc-sibling-function-in-shadow-dom.html10
-rw-r--r--tests/wpt/tests/css/css-values/tree-counting/sibling-function-invalidation.html52
-rw-r--r--tests/wpt/tests/css/css-view-transitions/scoped/auto-name-on-descendant.html110
-rw-r--r--tests/wpt/tests/css/css-view-transitions/scoped/auto-name.html81
-rw-r--r--tests/wpt/tests/css/css-view-transitions/scoped/display-none-during-transition.html74
-rw-r--r--tests/wpt/tests/css/css-view-transitions/scoped/document-element-start-view-transition.html91
-rw-r--r--tests/wpt/tests/css/css-view-transitions/snapshot-containing-block-static-iframe-ref.html27
-rw-r--r--tests/wpt/tests/css/css-view-transitions/snapshot-containing-block-static-iframe.html55
-rw-r--r--tests/wpt/tests/css/css-view-transitions/view-transition-name-stacking-context-dynamic.html22
-rw-r--r--tests/wpt/tests/css/css-view-transitions/view-transition-types-mutable-no-document-element-crashtest.html9
-rw-r--r--tests/wpt/tests/css/css-view-transitions/window-resize-aborts-transition-before-ready.html8
-rw-r--r--tests/wpt/tests/css/css-view-transitions/window-resize-aborts-transition.html8
-rw-r--r--tests/wpt/tests/css/css-writing-modes/orthogonal-dynamic-size-001.html18
-rw-r--r--tests/wpt/tests/digital-credentials/allow-attribute-with-create.https.html138
-rw-r--r--tests/wpt/tests/digital-credentials/allow-attribute-with-get.https.html (renamed from tests/wpt/tests/digital-credentials/allow-attribute.https.html)2
-rw-r--r--tests/wpt/tests/digital-credentials/create.disabled-by-permissions-policy.https.sub.html49
-rw-r--r--tests/wpt/tests/digital-credentials/create.disabled-by-permissions-policy.https.sub.html.headers1
-rw-r--r--tests/wpt/tests/digital-credentials/create.tentative.https.html188
-rw-r--r--tests/wpt/tests/digital-credentials/dc-types.ts25
-rw-r--r--tests/wpt/tests/digital-credentials/default-permissions-policy.https.sub.html42
-rw-r--r--tests/wpt/tests/digital-credentials/disabled-by-permissions-policy.https.sub.html.headers1
-rw-r--r--tests/wpt/tests/digital-credentials/enabled-on-self-origin-by-permissions-policy.https.sub.html57
-rw-r--r--tests/wpt/tests/digital-credentials/enabled-on-self-origin-by-permissions-policy.https.sub.html.headers2
-rw-r--r--tests/wpt/tests/digital-credentials/get.disabled-by-permissions-policy.https.sub.html (renamed from tests/wpt/tests/digital-credentials/disabled-by-permissions-policy.https.sub.html)0
-rw-r--r--tests/wpt/tests/digital-credentials/get.disabled-by-permissions-policy.https.sub.html.headers1
-rw-r--r--tests/wpt/tests/digital-credentials/get.tentative.https.html2
-rw-r--r--tests/wpt/tests/digital-credentials/support/helper.js158
-rw-r--r--tests/wpt/tests/digital-credentials/user-activation.https.html (renamed from tests/wpt/tests/digital-credentials/get-user-activation.https.html)29
-rw-r--r--tests/wpt/tests/event-timing/interactionid-orphan-pointerup.html11
-rw-r--r--tests/wpt/tests/event-timing/resources/event-timing-test-utils.js15
-rw-r--r--tests/wpt/tests/fonts/math/css-units.woffbin0 -> 1236 bytes
-rw-r--r--tests/wpt/tests/html/interaction/focus/tab-table-caption.html57
-rw-r--r--tests/wpt/tests/html/semantics/forms/the-select-element/customizable-select-in-page/customizable-select-in-page-keyboard-behavior.tentative.html21
-rw-r--r--tests/wpt/tests/html/semantics/forms/the-select-element/customizable-select/select-parsing.tentative.html8
-rw-r--r--tests/wpt/tests/html/semantics/interactive-elements/the-dialog-element/dialog-closedby-bounds-clicking.html100
-rw-r--r--tests/wpt/tests/html/semantics/interactive-elements/the-dialog-element/dialog-closedby-corner-cases.html16
-rw-r--r--tests/wpt/tests/html/semantics/interactive-elements/the-dialog-element/dialog-closedby.html18
-rw-r--r--tests/wpt/tests/mathml/relations/css-styling/lengths-1-ref.html7
-rw-r--r--tests/wpt/tests/mathml/relations/css-styling/lengths-1.html77
-rw-r--r--tests/wpt/tests/mathml/relations/css-styling/lengths-2.html57
-rw-r--r--tests/wpt/tests/mathml/relations/css-styling/lengths-vi-vb-units.html50
-rw-r--r--tests/wpt/tests/mathml/tools/css-units.py19
-rw-r--r--tests/wpt/tests/permissions-policy/resources/digital-credentials-create.html35
-rw-r--r--tests/wpt/tests/shadow-dom/reference-target/tentative/property-reflection-idl-setters.html30
-rw-r--r--tests/wpt/tests/shadow-dom/reference-target/tentative/resources/property-reflection-helper.js87
-rw-r--r--tests/wpt/tests/soft-navigation-heuristics/interaction-with-paint-before-back.tentative.html7
-rw-r--r--tests/wpt/tests/soft-navigation-heuristics/resources/soft-navigation-helper.js6
-rw-r--r--tests/wpt/tests/speculation-rules/prefetch/resources/authenticate.py1
-rw-r--r--tests/wpt/tests/speculation-rules/prefetch/resources/basic-service-worker.js21
-rw-r--r--tests/wpt/tests/speculation-rules/prefetch/resources/cookies.py1
-rw-r--r--tests/wpt/tests/speculation-rules/prefetch/resources/prefetch_nvs_hint.py1
-rw-r--r--tests/wpt/tests/speculation-rules/prefetch/resources/utils.sub.js22
-rw-r--r--tests/wpt/tests/speculation-rules/prefetch/tentative/service-worker/basic.sub.https.html31
-rw-r--r--tests/wpt/tests/streams/WEB_FEATURES.yml5
-rw-r--r--tests/wpt/tests/streams/piping/WEB_FEATURES.yml3
-rw-r--r--tests/wpt/tests/streams/readable-streams/WEB_FEATURES.yml14
-rw-r--r--tests/wpt/tests/streams/readable-streams/crashtests/WEB_FEATURES.yml7
-rw-r--r--tests/wpt/tests/streams/transform-streams/WEB_FEATURES.yml8
-rw-r--r--tests/wpt/tests/streams/writable-streams/WEB_FEATURES.yml3
-rw-r--r--tests/wpt/tests/tools/ci/requirements_macos_color_profile.txt18
-rw-r--r--tests/wpt/tests/trusted-types/block-string-assignment-to-Document-write.html3
-rw-r--r--tests/wpt/tests/viewport-segments/viewport-segments-env-variables.https.html18
-rw-r--r--tests/wpt/tests/viewport-segments/viewport-segments-segments-property.https.html23
-rw-r--r--tests/wpt/tests/webdriver/tests/bidi/web_extension/uninstall/invalid.py15
-rw-r--r--tests/wpt/tests/webnn/conformance_tests/dequantizeLinear.https.any.js9
-rw-r--r--tests/wpt/tests/webxr/depth-sensing/matchDepthViewValues.js4
379 files changed, 6154 insertions, 2549 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 2f8ab0361fa..b8ac73f4f73 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -844,9 +844,9 @@ dependencies = [
[[package]]
name = "cc"
-version = "1.2.20"
+version = "1.2.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "04da6a0d40b948dfc4fa8f5bbf402b0fc1a64a28dbf7d12ffd683550f2c1b63a"
+checksum = "8691782945451c1c383942c4874dbe63814f61cb57ef773cda2972682b7bb3c0"
dependencies = [
"jobserver",
"libc",
@@ -1223,7 +1223,7 @@ dependencies = [
[[package]]
name = "content-security-policy"
version = "0.5.4"
-source = "git+https://github.com/servo/rust-content-security-policy/?branch=servo-csp#81f95254fbfe98dd6e130260fd872cf950de9fcd"
+source = "git+https://github.com/servo/rust-content-security-policy/?branch=servo-csp#fcd91e99139ca96629e04e1a8010f96374f0370f"
dependencies = [
"base64 0.22.1",
"bitflags 2.9.0",
@@ -1768,9 +1768,9 @@ checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2"
[[package]]
name = "dpi"
-version = "0.1.1"
+version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f25c0e292a7ca6d6498557ff1df68f32c99850012b6ea401cf8daf771f22ff53"
+checksum = "d8b14ccef22fc6f5a8f4d7d768562a182c04ce9a3b3157b91390b52ddfdf1a76"
[[package]]
name = "dtoa"
@@ -4025,9 +4025,9 @@ checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c"
[[package]]
name = "jiff"
-version = "0.2.10"
+version = "0.2.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5a064218214dc6a10fbae5ec5fa888d80c45d611aba169222fc272072bf7aef6"
+checksum = "27e77966151130221b079bcec80f1f34a9e414fa489d99152a201c07fd2182bc"
dependencies = [
"jiff-static",
"log",
@@ -4038,9 +4038,9 @@ dependencies = [
[[package]]
name = "jiff-static"
-version = "0.2.10"
+version = "0.2.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "199b7932d97e325aff3a7030e141eafe7f2c6268e1d1b24859b753a627f45254"
+checksum = "97265751f8a9a4228476f2fc17874a9e7e70e96b893368e42619880fe143b48a"
dependencies = [
"proc-macro2",
"quote",
@@ -9195,9 +9195,9 @@ dependencies = [
[[package]]
name = "winnow"
-version = "0.7.8"
+version = "0.7.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9e27d6ad3dac991091e4d35de9ba2d2d00647c5d0fc26c5496dee55984ae111b"
+checksum = "d9fb597c990f03753e08d3c29efbfcf2019a003b4bf4ba19225c158e1549f0f3"
dependencies = [
"memchr",
]
diff --git a/components/layout/flexbox/layout.rs b/components/layout/flexbox/layout.rs
index a5540123681..e69b792e272 100644
--- a/components/layout/flexbox/layout.rs
+++ b/components/layout/flexbox/layout.rs
@@ -49,7 +49,6 @@ use crate::{
struct FlexContext<'a> {
config: FlexContainerConfig,
layout_context: &'a LayoutContext<'a>,
- positioning_context: &'a mut PositioningContext,
containing_block: &'a ContainingBlock<'a>, // For items
container_inner_size_constraint: FlexRelativeVec2<SizeConstraint>,
}
@@ -657,7 +656,6 @@ impl FlexContainer {
let mut flex_context = FlexContext {
config: self.config.clone(),
layout_context,
- positioning_context,
containing_block,
// https://drafts.csswg.org/css-flexbox/#definite-sizes
container_inner_size_constraint: self.config.flex_axis.vec2_to_flex_relative(
@@ -1775,16 +1773,7 @@ impl FlexItem<'_> {
) -> Option<FlexItemLayoutResult> {
let containing_block = flex_context.containing_block;
let independent_formatting_context = &self.box_.independent_formatting_context;
- let mut positioning_context = independent_formatting_context
- .new_positioning_context()
- .unwrap_or_else(|| {
- PositioningContext::new_for_subtree(
- flex_context
- .positioning_context
- .collects_for_nearest_positioned_ancestor(),
- )
- });
-
+ let mut positioning_context = PositioningContext::default();
let item_writing_mode = independent_formatting_context.style().writing_mode;
let item_is_horizontal = item_writing_mode.is_horizontal();
let flex_axis = flex_context.config.flex_axis;
@@ -2617,17 +2606,7 @@ impl FlexItemBox {
cross_size_stretches_to_container_size: bool,
intrinsic_sizing_mode: IntrinsicSizingMode,
) -> Au {
- let mut positioning_context = self
- .independent_formatting_context
- .new_positioning_context()
- .unwrap_or_else(|| {
- PositioningContext::new_for_subtree(
- flex_context
- .positioning_context
- .collects_for_nearest_positioned_ancestor(),
- )
- });
-
+ let mut positioning_context = PositioningContext::default();
let style = self.independent_formatting_context.style();
match &self.independent_formatting_context.contents {
IndependentFormattingContextContents::Replaced(replaced) => {
diff --git a/components/layout/flow/inline/line.rs b/components/layout/flow/inline/line.rs
index e65eaed2367..80bab1080ed 100644
--- a/components/layout/flow/inline/line.rs
+++ b/components/layout/flow/inline/line.rs
@@ -331,7 +331,7 @@ impl LineItemLayout<'_, '_> {
self.calculate_inline_box_block_start(inline_box_state, space_above_baseline);
let positioning_context_or_start_offset_in_parent =
- match inline_box.base.new_positioning_context() {
+ match PositioningContext::new_for_layout_box_base(&inline_box.base) {
Some(positioning_context) => Either::Left(positioning_context),
None => Either::Right(self.current_positioning_context_mut().len()),
};
diff --git a/components/layout/flow/inline/mod.rs b/components/layout/flow/inline/mod.rs
index 25fbaa324b1..2023f4e7174 100644
--- a/components/layout/flow/inline/mod.rs
+++ b/components/layout/flow/inline/mod.rs
@@ -2004,9 +2004,7 @@ impl IndependentFormattingContext {
bidi_level: Level,
) {
// We need to know the inline size of the atomic before deciding whether to do the line break.
- let mut child_positioning_context = self
- .new_positioning_context()
- .unwrap_or_else(|| PositioningContext::new_for_subtree(true));
+ let mut child_positioning_context = PositioningContext::default();
let IndependentFloatOrAtomicLayoutResult {
mut fragment,
baselines,
diff --git a/components/layout/flow/mod.rs b/components/layout/flow/mod.rs
index 983282dc389..772b150ae1c 100644
--- a/components/layout/flow/mod.rs
+++ b/components/layout/flow/mod.rs
@@ -689,16 +689,13 @@ fn layout_block_level_children_in_parallel(
placement_state: &mut PlacementState,
ignore_block_margins_for_stretch: LogicalSides1D<bool>,
) -> Vec<Fragment> {
- let collects_for_nearest_positioned_ancestor =
- positioning_context.collects_for_nearest_positioned_ancestor();
let mut layout_results: Vec<(Fragment, PositioningContext)> =
Vec::with_capacity(child_boxes.len());
child_boxes
.par_iter()
.map(|child_box| {
- let mut child_positioning_context =
- PositioningContext::new_for_subtree(collects_for_nearest_positioned_ancestor);
+ let mut child_positioning_context = PositioningContext::default();
let fragment = child_box.borrow().layout(
layout_context,
&mut child_positioning_context,
diff --git a/components/layout/flow/root.rs b/components/layout/flow/root.rs
index c6498eeed63..bb9ff1d337a 100644
--- a/components/layout/flow/root.rs
+++ b/components/layout/flow/root.rs
@@ -385,8 +385,7 @@ impl BoxTree {
style,
};
- let mut positioning_context =
- PositioningContext::new_for_containing_block_for_all_descendants();
+ let mut positioning_context = PositioningContext::default();
let independent_layout = self.root.layout(
layout_context,
&mut positioning_context,
diff --git a/components/layout/formatting_contexts.rs b/components/layout/formatting_contexts.rs
index 4661c44592c..4982d0dae1a 100644
--- a/components/layout/formatting_contexts.rs
+++ b/components/layout/formatting_contexts.rs
@@ -295,10 +295,7 @@ impl IndependentNonReplacedContents {
);
}
- let mut child_positioning_context = PositioningContext::new_for_subtree(
- positioning_context.collects_for_nearest_positioned_ancestor(),
- );
-
+ let mut child_positioning_context = PositioningContext::default();
let result = self.layout_without_caching(
layout_context,
&mut child_positioning_context,
diff --git a/components/layout/layout_impl.rs b/components/layout/layout_impl.rs
index 3110899d76e..bb84806ebdb 100644
--- a/components/layout/layout_impl.rs
+++ b/components/layout/layout_impl.rs
@@ -16,7 +16,6 @@ use base::Epoch;
use base::id::{PipelineId, WebViewId};
use compositing_traits::CrossProcessCompositorApi;
use constellation_traits::ScrollState;
-use embedder_traits::resources::{self, Resource};
use embedder_traits::{UntrustedNodeAddress, ViewportDetails};
use euclid::default::{Point2D as UntypedPoint2D, Rect as UntypedRect, Size2D as UntypedSize2D};
use euclid::{Point2D, Scale, Size2D, Vector2D};
@@ -100,6 +99,18 @@ thread_local!(static SEEN_POINTERS: LazyCell<RefCell<HashSet<*const c_void>>> =
LazyCell::new(|| RefCell::new(HashSet::new()))
});
+/// A CSS file to style the user agent stylesheet.
+static USER_AGENT_CSS: &[u8] = include_bytes!("./stylesheets/user-agent.css");
+
+/// A CSS file to style the Servo browser.
+static SERVO_CSS: &[u8] = include_bytes!("./stylesheets/servo.css");
+
+/// A CSS file to style the presentational hints.
+static PRESENTATIONAL_HINTS_CSS: &[u8] = include_bytes!("./stylesheets/presentational-hints.css");
+
+/// A CSS file to style the quirks mode.
+static QUIRKS_MODE_CSS: &[u8] = include_bytes!("./stylesheets/quirks-mode.css");
+
/// Information needed by layout.
pub struct LayoutThread {
/// The ID of the pipeline that we belong to.
@@ -441,6 +452,8 @@ impl Layout for LayoutThread {
.map(|tree| tree.conditional_size_of(ops))
.unwrap_or_default(),
});
+
+ reports.push(self.image_cache.memory_report(formatted_url, ops));
}
fn set_quirks_mode(&mut self, quirks_mode: QuirksMode) {
@@ -983,20 +996,12 @@ fn get_ua_stylesheets() -> Result<UserAgentStylesheets, &'static str> {
// FIXME: presentational-hints.css should be at author origin with zero specificity.
// (Does it make a difference?)
let mut user_or_user_agent_stylesheets = vec![
- parse_ua_stylesheet(
- shared_lock,
- "user-agent.css",
- &resources::read_bytes(Resource::UserAgentCSS),
- )?,
- parse_ua_stylesheet(
- shared_lock,
- "servo.css",
- &resources::read_bytes(Resource::ServoCSS),
- )?,
+ parse_ua_stylesheet(shared_lock, "user-agent.css", USER_AGENT_CSS)?,
+ parse_ua_stylesheet(shared_lock, "servo.css", SERVO_CSS)?,
parse_ua_stylesheet(
shared_lock,
"presentational-hints.css",
- &resources::read_bytes(Resource::PresentationalHintsCSS),
+ PRESENTATIONAL_HINTS_CSS,
)?,
];
@@ -1017,11 +1022,8 @@ fn get_ua_stylesheets() -> Result<UserAgentStylesheets, &'static str> {
)));
}
- let quirks_mode_stylesheet = parse_ua_stylesheet(
- shared_lock,
- "quirks-mode.css",
- &resources::read_bytes(Resource::QuirksModeCSS),
- )?;
+ let quirks_mode_stylesheet =
+ parse_ua_stylesheet(shared_lock, "quirks-mode.css", QUIRKS_MODE_CSS)?;
Ok(UserAgentStylesheets {
shared_lock: shared_lock.clone(),
diff --git a/components/layout/positioned.rs b/components/layout/positioned.rs
index 6bfe2af87ef..ff361396fa3 100644
--- a/components/layout/positioned.rs
+++ b/components/layout/positioned.rs
@@ -43,16 +43,6 @@ pub(crate) struct AbsolutelyPositionedBox {
}
#[derive(Clone, MallocSizeOf)]
-pub(crate) struct PositioningContext {
- for_nearest_positioned_ancestor: Option<Vec<HoistedAbsolutelyPositionedBox>>,
-
- // For nearest `containing block for all descendants` as defined by the CSS transforms
- // spec.
- // https://www.w3.org/TR/css-transforms-1/#containing-block-for-all-descendants
- for_nearest_containing_block_for_all_descendants: Vec<HoistedAbsolutelyPositionedBox>,
-}
-
-#[derive(Clone, MallocSizeOf)]
pub(crate) struct HoistedAbsolutelyPositionedBox {
absolutely_positioned_box: ArcRefCell<AbsolutelyPositionedBox>,
@@ -104,55 +94,26 @@ impl AbsolutelyPositionedBox {
}
}
-impl IndependentFormattingContext {
- #[inline]
- pub(crate) fn new_positioning_context(&self) -> Option<PositioningContext> {
- self.base.new_positioning_context()
- }
-}
-
-impl LayoutBoxBase {
- #[inline]
- pub(crate) fn new_positioning_context(&self) -> Option<PositioningContext> {
- PositioningContext::new_for_style(&self.style, &self.base_fragment_info.flags)
- }
+#[derive(Clone, Default, MallocSizeOf)]
+pub(crate) struct PositioningContext {
+ absolutes: Vec<HoistedAbsolutelyPositionedBox>,
}
impl PositioningContext {
- pub(crate) fn new_for_containing_block_for_all_descendants() -> Self {
- Self {
- for_nearest_positioned_ancestor: None,
- for_nearest_containing_block_for_all_descendants: Vec::new(),
- }
- }
-
- /// Create a [PositioningContext] to use for laying out a subtree. The idea is that
- /// when subtree layout is finished, the newly hoisted boxes can be processed
- /// (normally adjusting their static insets) and then appended to the parent
- /// [PositioningContext].
- pub(crate) fn new_for_subtree(collects_for_nearest_positioned_ancestor: bool) -> Self {
- Self {
- for_nearest_positioned_ancestor: if collects_for_nearest_positioned_ancestor {
- Some(Vec::new())
- } else {
- None
- },
- for_nearest_containing_block_for_all_descendants: Vec::new(),
- }
- }
-
- pub(crate) fn collects_for_nearest_positioned_ancestor(&self) -> bool {
- self.for_nearest_positioned_ancestor.is_some()
+ #[inline]
+ pub(crate) fn new_for_layout_box_base(layout_box_base: &LayoutBoxBase) -> Option<Self> {
+ Self::new_for_style_and_fragment_flags(
+ &layout_box_base.style,
+ &layout_box_base.base_fragment_info.flags,
+ )
}
- fn new_for_style(style: &ComputedValues, flags: &FragmentFlags) -> Option<Self> {
- if style.establishes_containing_block_for_all_descendants(*flags) {
- Some(Self::new_for_containing_block_for_all_descendants())
- } else if style.establishes_containing_block_for_absolute_descendants(*flags) {
- Some(Self {
- for_nearest_positioned_ancestor: Some(Vec::new()),
- for_nearest_containing_block_for_all_descendants: Vec::new(),
- })
+ fn new_for_style_and_fragment_flags(
+ style: &ComputedValues,
+ flags: &FragmentFlags,
+ ) -> Option<Self> {
+ if style.establishes_containing_block_for_absolute_descendants(*flags) {
+ Some(Self::default())
} else {
None
}
@@ -195,20 +156,9 @@ impl PositioningContext {
offset: &PhysicalVec<Au>,
index: PositioningContextLength,
) {
- if let Some(hoisted_boxes) = self.for_nearest_positioned_ancestor.as_mut() {
- hoisted_boxes
- .iter_mut()
- .skip(index.for_nearest_positioned_ancestor)
- .for_each(|hoisted_fragment| {
- hoisted_fragment
- .fragment
- .borrow_mut()
- .adjust_offsets(offset)
- })
- }
- self.for_nearest_containing_block_for_all_descendants
+ self.absolutes
.iter_mut()
- .skip(index.for_nearest_containing_block_for_all_descendants)
+ .skip(index.0)
.for_each(|hoisted_fragment| {
hoisted_fragment
.fragment
@@ -227,19 +177,23 @@ impl PositioningContext {
base: &LayoutBoxBase,
fragment_layout_fn: impl FnOnce(&mut Self) -> BoxFragment,
) -> BoxFragment {
- // Try to create a context, but if one isn't necessary, simply create the fragment
- // using the given closure and the current `PositioningContext`.
- let mut new_context = match base.new_positioning_context() {
- Some(new_context) => new_context,
- None => return fragment_layout_fn(self),
- };
+ // If a new `PositioningContext` isn't necessary, simply create the fragment using
+ // the given closure and the current `PositioningContext`.
+ let establishes_containing_block_for_absolutes = base
+ .style
+ .establishes_containing_block_for_absolute_descendants(base.base_fragment_info.flags);
+ if !establishes_containing_block_for_absolutes {
+ return fragment_layout_fn(self);
+ }
+ let mut new_context = PositioningContext::default();
let mut new_fragment = fragment_layout_fn(&mut new_context);
- new_context.layout_collected_children(layout_context, &mut new_fragment);
- // If the new context has any hoisted boxes for the nearest containing block for
- // pass them up the tree.
+ // Lay out all of the absolutely positioned children for this fragment, and, if it
+ // isn't a containing block for fixed elements, then pass those up to the parent.
+ new_context.layout_collected_children(layout_context, &mut new_fragment);
self.append(new_context);
+
if base.style.clone_position() == Position::Relative {
new_fragment.content_rect.origin += relative_adjustement(&base.style, containing_block)
.to_physical_vector(containing_block.style.writing_mode)
@@ -248,13 +202,61 @@ impl PositioningContext {
new_fragment
}
+ fn take_boxes_for_fragment(
+ &mut self,
+ new_fragment: &BoxFragment,
+ boxes_to_layout_out: &mut Vec<HoistedAbsolutelyPositionedBox>,
+ boxes_to_continue_hoisting_out: &mut Vec<HoistedAbsolutelyPositionedBox>,
+ ) {
+ debug_assert!(
+ new_fragment
+ .style
+ .establishes_containing_block_for_absolute_descendants(new_fragment.base.flags)
+ );
+
+ if new_fragment
+ .style
+ .establishes_containing_block_for_all_descendants(new_fragment.base.flags)
+ {
+ boxes_to_layout_out.append(&mut self.absolutes);
+ return;
+ }
+
+ // TODO: This could potentially use `extract_if` when that is stabilized.
+ let (mut boxes_to_layout, mut boxes_to_continue_hoisting) = self
+ .absolutes
+ .drain(..)
+ .partition(|hoisted_box| hoisted_box.position() != Position::Fixed);
+ boxes_to_layout_out.append(&mut boxes_to_layout);
+ boxes_to_continue_hoisting_out.append(&mut boxes_to_continue_hoisting);
+ }
+
// Lay out the hoisted boxes collected into this `PositioningContext` and add them
// to the given `BoxFragment`.
- pub fn layout_collected_children(
+ pub(crate) fn layout_collected_children(
&mut self,
layout_context: &LayoutContext,
new_fragment: &mut BoxFragment,
) {
+ if self.absolutes.is_empty() {
+ return;
+ }
+
+ // Sometimes we create temporary PositioningContexts just to collect hoisted absolutes and
+ // then these are processed later. In that case and if this fragment doesn't establish a
+ // containing block for absolutes at all, we just do nothing. All hoisted fragments will
+ // later be passed up to a parent PositioningContext.
+ //
+ // Handling this case here, when the PositioningContext is completely ineffectual other than
+ // as a temporary container for hoisted boxes, means that callers can execute less conditional
+ // code.
+ if !new_fragment
+ .style
+ .establishes_containing_block_for_absolute_descendants(new_fragment.base.flags)
+ {
+ return;
+ }
+
let padding_rect = PhysicalRect::new(
// Ignore the content rect’s position in its own containing block:
PhysicalPoint::origin(),
@@ -268,83 +270,58 @@ impl PositioningContext {
style: &new_fragment.style,
};
- let take_hoisted_boxes_pending_layout =
- |context: &mut Self| match context.for_nearest_positioned_ancestor.as_mut() {
- Some(fragments) => mem::take(fragments),
- None => mem::take(&mut context.for_nearest_containing_block_for_all_descendants),
- };
+ let mut fixed_position_boxes_to_hoist = Vec::new();
+ let mut boxes_to_layout = Vec::new();
+ self.take_boxes_for_fragment(
+ new_fragment,
+ &mut boxes_to_layout,
+ &mut fixed_position_boxes_to_hoist,
+ );
- // Loop because it’s possible that we discover (the static position of)
- // more absolutely-positioned boxes while doing layout for others.
- let mut hoisted_boxes = take_hoisted_boxes_pending_layout(self);
- let mut laid_out_child_fragments = Vec::new();
- while !hoisted_boxes.is_empty() {
+ // Laying out a `position: absolute` child (which only establishes a containing block for
+ // `position: absolute` descendants) can result in more `position: fixed` descendants
+ // collecting in `self.absolutes`. We need to loop here in order to keep either laying them
+ // out or putting them into `fixed_position_boxes_to_hoist`. We know there aren't any more
+ // when `self.absolutes` is empty.
+ while !boxes_to_layout.is_empty() {
HoistedAbsolutelyPositionedBox::layout_many(
layout_context,
- &mut hoisted_boxes,
- &mut laid_out_child_fragments,
- &mut self.for_nearest_containing_block_for_all_descendants,
+ std::mem::take(&mut boxes_to_layout),
+ &mut new_fragment.children,
+ &mut self.absolutes,
&containing_block,
new_fragment.padding,
);
- hoisted_boxes = take_hoisted_boxes_pending_layout(self);
- }
- new_fragment.children.extend(laid_out_child_fragments);
- }
-
- pub(crate) fn push(&mut self, box_: HoistedAbsolutelyPositionedBox) {
- if let Some(nearest) = &mut self.for_nearest_positioned_ancestor {
- let position = box_
- .absolutely_positioned_box
- .borrow()
- .context
- .style()
- .clone_position();
- match position {
- Position::Fixed => {}, // fall through
- Position::Absolute => return nearest.push(box_),
- Position::Static | Position::Relative | Position::Sticky => unreachable!(),
- }
+ self.take_boxes_for_fragment(
+ new_fragment,
+ &mut boxes_to_layout,
+ &mut fixed_position_boxes_to_hoist,
+ );
}
- self.for_nearest_containing_block_for_all_descendants
- .push(box_)
+
+ // We replace here instead of simply preserving these in `take_boxes_for_fragment`
+ // so that we don't have to continually re-iterate over them when laying out in the
+ // loop above.
+ self.absolutes = fixed_position_boxes_to_hoist;
}
- pub(crate) fn is_empty(&self) -> bool {
- self.for_nearest_containing_block_for_all_descendants
- .is_empty() &&
- self.for_nearest_positioned_ancestor
- .as_ref()
- .is_none_or(|vector| vector.is_empty())
+ pub(crate) fn push(&mut self, hoisted_box: HoistedAbsolutelyPositionedBox) {
+ debug_assert!(matches!(
+ hoisted_box.position(),
+ Position::Absolute | Position::Fixed
+ ));
+ self.absolutes.push(hoisted_box);
}
- pub(crate) fn append(&mut self, other: Self) {
- if other.is_empty() {
+ pub(crate) fn append(&mut self, mut other: Self) {
+ if other.absolutes.is_empty() {
return;
}
-
- vec_append_owned(
- &mut self.for_nearest_containing_block_for_all_descendants,
- other.for_nearest_containing_block_for_all_descendants,
- );
-
- match (
- self.for_nearest_positioned_ancestor.as_mut(),
- other.for_nearest_positioned_ancestor,
- ) {
- (Some(us), Some(them)) => vec_append_owned(us, them),
- (None, Some(them)) => {
- // This is the case where we have laid out the absolute children in a containing
- // block for absolutes and we then are passing up the fixed-position descendants
- // to the containing block for all descendants.
- vec_append_owned(
- &mut self.for_nearest_containing_block_for_all_descendants,
- them,
- );
- },
- (None, None) => {},
- _ => unreachable!(),
+ if self.absolutes.is_empty() {
+ self.absolutes = other.absolutes;
+ } else {
+ self.absolutes.append(&mut other.absolutes)
}
}
@@ -354,19 +331,16 @@ impl PositioningContext {
initial_containing_block: &DefiniteContainingBlock,
fragments: &mut Vec<Fragment>,
) {
- debug_assert!(self.for_nearest_positioned_ancestor.is_none());
-
- // Loop because it’s possible that we discover (the static position of)
- // more absolutely-positioned boxes while doing layout for others.
- while !self
- .for_nearest_containing_block_for_all_descendants
- .is_empty()
- {
+ // Laying out a `position: absolute` child (which only establishes a containing block for
+ // `position: absolute` descendants) can result in more `position: fixed` descendants
+ // collecting in `self.absolutes`. We need to loop here in order to keep laying them out. We
+ // know there aren't any more when `self.absolutes` is empty.
+ while !self.absolutes.is_empty() {
HoistedAbsolutelyPositionedBox::layout_many(
layout_context,
- &mut mem::take(&mut self.for_nearest_containing_block_for_all_descendants),
+ mem::take(&mut self.absolutes),
fragments,
- &mut self.for_nearest_containing_block_for_all_descendants,
+ &mut self.absolutes,
initial_containing_block,
Default::default(),
)
@@ -375,58 +349,46 @@ impl PositioningContext {
/// Get the length of this [PositioningContext].
pub(crate) fn len(&self) -> PositioningContextLength {
- PositioningContextLength {
- for_nearest_positioned_ancestor: self
- .for_nearest_positioned_ancestor
- .as_ref()
- .map_or(0, |vec| vec.len()),
- for_nearest_containing_block_for_all_descendants: self
- .for_nearest_containing_block_for_all_descendants
- .len(),
- }
+ PositioningContextLength(self.absolutes.len())
}
/// Truncate this [PositioningContext] to the given [PositioningContextLength]. This
/// is useful for "unhoisting" boxes in this context and returning it to the state at
/// the time that [`PositioningContext::len()`] was called.
pub(crate) fn truncate(&mut self, length: &PositioningContextLength) {
- if let Some(vec) = self.for_nearest_positioned_ancestor.as_mut() {
- vec.truncate(length.for_nearest_positioned_ancestor);
- }
- self.for_nearest_containing_block_for_all_descendants
- .truncate(length.for_nearest_containing_block_for_all_descendants);
+ self.absolutes.truncate(length.0)
}
}
/// A data structure which stores the size of a positioning context.
#[derive(Clone, Copy, Debug, PartialEq)]
-pub(crate) struct PositioningContextLength {
- /// The number of boxes that will be hoisted the the nearest positioned ancestor for
- /// layout.
- for_nearest_positioned_ancestor: usize,
- /// The number of boxes that will be hoisted the the nearest ancestor which
- /// establishes a containing block for all descendants for layout.
- for_nearest_containing_block_for_all_descendants: usize,
-}
+pub(crate) struct PositioningContextLength(usize);
impl Zero for PositioningContextLength {
fn zero() -> Self {
- PositioningContextLength {
- for_nearest_positioned_ancestor: 0,
- for_nearest_containing_block_for_all_descendants: 0,
- }
+ Self(0)
}
fn is_zero(&self) -> bool {
- self.for_nearest_positioned_ancestor == 0 &&
- self.for_nearest_containing_block_for_all_descendants == 0
+ self.0.is_zero()
}
}
impl HoistedAbsolutelyPositionedBox {
+ fn position(&self) -> Position {
+ let position = self
+ .absolutely_positioned_box
+ .borrow()
+ .context
+ .style()
+ .clone_position();
+ assert!(position == Position::Fixed || position == Position::Absolute);
+ position
+ }
+
pub(crate) fn layout_many(
layout_context: &LayoutContext,
- boxes: &mut [Self],
+ mut boxes: Vec<Self>,
fragments: &mut Vec<Fragment>,
for_nearest_containing_block_for_all_descendants: &mut Vec<HoistedAbsolutelyPositionedBox>,
containing_block: &DefiniteContainingBlock,
@@ -473,7 +435,7 @@ impl HoistedAbsolutelyPositionedBox {
pub(crate) fn layout(
&mut self,
layout_context: &LayoutContext,
- for_nearest_containing_block_for_all_descendants: &mut Vec<HoistedAbsolutelyPositionedBox>,
+ hoisted_absolutes_from_children: &mut Vec<HoistedAbsolutelyPositionedBox>,
containing_block: &DefiniteContainingBlock,
containing_block_padding: PhysicalSides<Au>,
) -> Fragment {
@@ -596,7 +558,7 @@ impl HoistedAbsolutelyPositionedBox {
.sizes
}));
- let mut positioning_context = context.new_positioning_context().unwrap();
+ let mut positioning_context = PositioningContext::default();
let mut new_fragment = {
let content_size: LogicalVec2<Au>;
let fragments;
@@ -709,6 +671,10 @@ impl HoistedAbsolutelyPositionedBox {
)
.with_specific_layout_info(specific_layout_info)
};
+
+ // This is an absolutely positioned element, which means it also establishes a
+ // containing block for absolutes. We lay out any absolutely positioned children
+ // here and pass the rest to `hoisted_absolutes_from_children.`
positioning_context.layout_collected_children(layout_context, &mut new_fragment);
// Any hoisted boxes that remain in this positioning context are going to be hoisted
@@ -721,8 +687,7 @@ impl HoistedAbsolutelyPositionedBox {
PositioningContextLength::zero(),
);
- for_nearest_containing_block_for_all_descendants
- .extend(positioning_context.for_nearest_containing_block_for_all_descendants);
+ hoisted_absolutes_from_children.extend(positioning_context.absolutes);
let fragment = Fragment::Box(ArcRefCell::new(new_fragment));
context.base.set_fragment(fragment.clone());
@@ -1024,14 +989,6 @@ impl AbsoluteAxisSolver<'_> {
}
}
-fn vec_append_owned<T>(a: &mut Vec<T>, mut b: Vec<T>) {
- if a.is_empty() {
- *a = b
- } else {
- a.append(&mut b)
- }
-}
-
/// <https://drafts.csswg.org/css2/visuren.html#relative-positioning>
pub(crate) fn relative_adjustement(
style: &ComputedValues,
diff --git a/resources/presentational-hints.css b/components/layout/stylesheets/presentational-hints.css
index 36a0175bd45..36a0175bd45 100644
--- a/resources/presentational-hints.css
+++ b/components/layout/stylesheets/presentational-hints.css
diff --git a/resources/quirks-mode.css b/components/layout/stylesheets/quirks-mode.css
index cb8d3028441..cb8d3028441 100644
--- a/resources/quirks-mode.css
+++ b/components/layout/stylesheets/quirks-mode.css
diff --git a/resources/servo.css b/components/layout/stylesheets/servo.css
index bc72f01cc56..bc72f01cc56 100644
--- a/resources/servo.css
+++ b/components/layout/stylesheets/servo.css
diff --git a/resources/user-agent.css b/components/layout/stylesheets/user-agent.css
index cea14741d30..cea14741d30 100644
--- a/resources/user-agent.css
+++ b/components/layout/stylesheets/user-agent.css
diff --git a/components/layout/table/layout.rs b/components/layout/table/layout.rs
index 0cbe3e9ca76..2efe339837e 100644
--- a/components/layout/table/layout.rs
+++ b/components/layout/table/layout.rs
@@ -1068,7 +1068,6 @@ impl<'a> TableLayout<'a> {
&mut self,
layout_context: &LayoutContext,
containing_block_for_table: &ContainingBlock,
- parent_positioning_context: &mut PositioningContext,
) {
self.cells_laid_out = self
.table
@@ -1076,30 +1075,6 @@ impl<'a> TableLayout<'a> {
.par_iter()
.enumerate()
.map(|(row_index, row_slots)| {
- // When building the PositioningContext for this cell, we want it to have the same
- // configuration for whatever PositioningContext the contents are ultimately added to.
- let collect_for_nearest_positioned_ancestor = parent_positioning_context
- .collects_for_nearest_positioned_ancestor() ||
- self.table.rows.get(row_index).is_some_and(|row| {
- let row = row.borrow();
- let row_group_collects_for_nearest_positioned_ancestor =
- row.group_index.is_some_and(|group_index| {
- self.table.row_groups[group_index]
- .borrow()
- .base
- .style
- .establishes_containing_block_for_absolute_descendants(
- FragmentFlags::empty(),
- )
- });
- row_group_collects_for_nearest_positioned_ancestor ||
- row.base
- .style
- .establishes_containing_block_for_absolute_descendants(
- FragmentFlags::empty(),
- )
- });
-
row_slots
.par_iter()
.enumerate()
@@ -1141,10 +1116,7 @@ impl<'a> TableLayout<'a> {
style: &cell.base.style,
};
- let mut positioning_context = PositioningContext::new_for_subtree(
- collect_for_nearest_positioned_ancestor,
- );
-
+ let mut positioning_context = PositioningContext::default();
let layout = cell.contents.layout(
layout_context,
&mut positioning_context,
@@ -1503,7 +1475,6 @@ impl<'a> TableLayout<'a> {
layout_context: &LayoutContext,
parent_positioning_context: &mut PositioningContext,
) -> BoxFragment {
- let mut positioning_context = caption.context.new_positioning_context();
let containing_block = &ContainingBlock {
size: ContainingBlockSize {
inline: self.table_width + self.pbm.padding_border_sums.inline,
@@ -1517,6 +1488,8 @@ impl<'a> TableLayout<'a> {
// stretch block size. https://drafts.csswg.org/css-sizing-4/#stretch-fit-sizing
let ignore_block_margins_for_stretch = LogicalSides1D::new(false, false);
+ let mut positioning_context =
+ PositioningContext::new_for_layout_box_base(&caption.context.base);
let mut box_fragment = caption.context.layout_in_flow_block_level(
layout_context,
positioning_context
@@ -1769,11 +1742,7 @@ impl<'a> TableLayout<'a> {
) -> BoxFragment {
self.distributed_column_widths =
Self::distribute_width_to_columns(self.assignable_width, &self.columns);
- self.layout_cells_in_row(
- layout_context,
- containing_block_for_children,
- positioning_context,
- );
+ self.layout_cells_in_row(layout_context, containing_block_for_children);
let table_writing_mode = containing_block_for_children.style.writing_mode;
let first_layout_row_heights = self.do_first_row_layout(table_writing_mode);
self.compute_table_height_and_final_row_heights(
@@ -2325,7 +2294,7 @@ impl<'a> RowFragmentLayout<'a> {
Self {
row: table_row,
rect,
- positioning_context: table_row.base.new_positioning_context(),
+ positioning_context: PositioningContext::new_for_layout_box_base(&table_row.base),
containing_block,
fragments: Vec::new(),
}
@@ -2379,11 +2348,11 @@ impl<'a> RowFragmentLayout<'a> {
if let Some(mut row_positioning_context) = self.positioning_context.take() {
row_positioning_context.layout_collected_children(layout_context, &mut row_fragment);
- let positioning_context = row_group_fragment_layout
+ let parent_positioning_context = row_group_fragment_layout
.as_mut()
.and_then(|layout| layout.positioning_context.as_mut())
.unwrap_or(table_positioning_context);
- positioning_context.append(row_positioning_context);
+ parent_positioning_context.append(row_positioning_context);
}
let fragment = Fragment::Box(ArcRefCell::new(row_fragment));
@@ -2410,7 +2379,7 @@ impl RowGroupFragmentLayout {
let row_group = row_group.borrow();
(
dimensions.get_row_group_rect(&row_group),
- row_group.base.new_positioning_context(),
+ PositioningContext::new_for_layout_box_base(&row_group.base),
)
};
Self {
diff --git a/components/layout/taffy/layout.rs b/components/layout/taffy/layout.rs
index 3777c902053..a5838c1bd65 100644
--- a/components/layout/taffy/layout.rs
+++ b/components/layout/taffy/layout.rs
@@ -29,7 +29,7 @@ use crate::geom::{
use crate::layout_box_base::CacheableLayoutResult;
use crate::positioned::{AbsolutelyPositionedBox, PositioningContext, PositioningContextLength};
use crate::sizing::{ComputeInlineContentSizes, ContentSizes, InlineContentSizesResult};
-use crate::style_ext::{ComputedValuesExt, LayoutStyle};
+use crate::style_ext::LayoutStyle;
use crate::{ConstraintSpace, ContainingBlock, ContainingBlockSize};
const DUMMY_NODE_ID: taffy::NodeId = taffy::NodeId::new(u64::MAX);
@@ -250,29 +250,15 @@ impl taffy::LayoutPartialTree for TaffyContainerContext<'_> {
},
style,
};
- let layout = {
- let mut child_positioning_context = independent_context
- .new_positioning_context()
- .unwrap_or_else(|| {
- PositioningContext::new_for_subtree(
- self.positioning_context
- .collects_for_nearest_positioned_ancestor(),
- )
- });
-
- let layout = non_replaced.layout_without_caching(
- self.layout_context,
- &mut child_positioning_context,
- &content_box_size_override,
- containing_block,
- false, /* depends_on_block_constraints */
- );
- // Store layout data on child for later access
- child.positioning_context = child_positioning_context;
-
- layout
- };
+ child.positioning_context = PositioningContext::default();
+ let layout = non_replaced.layout_without_caching(
+ self.layout_context,
+ &mut child.positioning_context,
+ &content_box_size_override,
+ containing_block,
+ false, /* depends_on_block_constraints */
+ );
child.child_fragments = layout.fragments;
self.child_specific_layout_infos[usize::from(node_id)] =
@@ -373,8 +359,7 @@ impl ComputeInlineContentSizes for TaffyContainer {
let mut grid_context = TaffyContainerContext {
layout_context,
- positioning_context:
- &mut PositioningContext::new_for_containing_block_for_all_descendants(),
+ positioning_context: &mut PositioningContext::default(),
content_box_size_override: containing_block,
style,
source_child_nodes: &self.children,
@@ -540,17 +525,6 @@ impl TaffyContainer {
let child_specific_layout_info: Option<SpecificLayoutInfo> =
std::mem::take(&mut container_ctx.child_specific_layout_infos[child_id]);
- let establishes_containing_block_for_absolute_descendants =
- if let TaffyItemBoxInner::InFlowBox(independent_box) = &child.taffy_level_box {
- child
- .style
- .establishes_containing_block_for_absolute_descendants(
- independent_box.base_fragment_info().flags,
- )
- } else {
- false
- };
-
let fragment = match &mut child.taffy_level_box {
TaffyItemBoxInner::InFlowBox(independent_box) => {
let mut fragment_info = independent_box.base_fragment_info();
@@ -573,29 +547,21 @@ impl TaffyContainer {
})
.with_specific_layout_info(child_specific_layout_info);
- if establishes_containing_block_for_absolute_descendants {
- child.positioning_context.layout_collected_children(
- container_ctx.layout_context,
- &mut box_fragment,
- );
- }
-
- let fragment = Fragment::Box(ArcRefCell::new(box_fragment));
-
+ child.positioning_context.layout_collected_children(
+ container_ctx.layout_context,
+ &mut box_fragment,
+ );
child
.positioning_context
- .adjust_static_position_of_hoisted_fragments(
- &fragment,
+ .adjust_static_position_of_hoisted_fragments_with_offset(
+ &box_fragment.content_rect.origin.to_vector(),
PositioningContextLength::zero(),
);
- let child_positioning_context = std::mem::replace(
- &mut child.positioning_context,
- PositioningContext::new_for_containing_block_for_all_descendants(),
- );
container_ctx
.positioning_context
- .append(child_positioning_context);
- fragment
+ .append(std::mem::take(&mut child.positioning_context));
+
+ Fragment::Box(ArcRefCell::new(box_fragment))
},
TaffyItemBoxInner::OutOfFlowAbsolutelyPositionedBox(abs_pos_box) => {
fn resolve_alignment(value: AlignFlags, auto: AlignFlags) -> AlignFlags {
diff --git a/components/layout/taffy/mod.rs b/components/layout/taffy/mod.rs
index 55a678cd89a..b1ff753ea78 100644
--- a/components/layout/taffy/mod.rs
+++ b/components/layout/taffy/mod.rs
@@ -110,7 +110,7 @@ impl TaffyItemBox {
Self {
taffy_layout: Default::default(),
child_fragments: Vec::new(),
- positioning_context: PositioningContext::new_for_containing_block_for_all_descendants(),
+ positioning_context: PositioningContext::default(),
style,
taffy_level_box: inner,
}
@@ -118,8 +118,7 @@ impl TaffyItemBox {
pub(crate) fn invalidate_cached_fragment(&mut self) {
self.taffy_layout = Default::default();
- self.positioning_context =
- PositioningContext::new_for_containing_block_for_all_descendants();
+ self.positioning_context = PositioningContext::default();
match self.taffy_level_box {
TaffyItemBoxInner::InFlowBox(ref independent_formatting_context) => {
independent_formatting_context
diff --git a/components/net/Cargo.toml b/components/net/Cargo.toml
index 04ef7ac190c..9af310f32bc 100644
--- a/components/net/Cargo.toml
+++ b/components/net/Cargo.toml
@@ -75,6 +75,7 @@ webpki-roots = { workspace = true }
webrender_api = { workspace = true }
[dev-dependencies]
+embedder_traits = { workspace = true, features = ["baked-default-resources"] }
flate2 = "1"
futures = { version = "0.3", features = ["compat"] }
hyper = { workspace = true, features = ["full"] }
diff --git a/components/net/image_cache.rs b/components/net/image_cache.rs
index eab2f9c08fe..e3d31b11736 100644
--- a/components/net/image_cache.rs
+++ b/components/net/image_cache.rs
@@ -431,7 +431,7 @@ pub struct ImageCacheImpl {
store: Arc<Mutex<ImageCacheStore>>,
/// Thread pool for image decoding
- thread_pool: CoreResourceThreadPool,
+ thread_pool: Arc<CoreResourceThreadPool>,
}
impl ImageCache for ImageCacheImpl {
@@ -454,7 +454,10 @@ impl ImageCache for ImageCacheImpl {
placeholder_url: ServoUrl::parse("chrome://resources/rippy.png").unwrap(),
compositor_api,
})),
- thread_pool: CoreResourceThreadPool::new(thread_count, "ImageCache".to_string()),
+ thread_pool: Arc::new(CoreResourceThreadPool::new(
+ thread_count,
+ "ImageCache".to_string(),
+ )),
}
}
@@ -651,6 +654,25 @@ impl ImageCache for ImageCacheImpl {
},
}
}
+
+ fn create_new_image_cache(
+ &self,
+ compositor_api: CrossProcessCompositorApi,
+ ) -> Arc<dyn ImageCache> {
+ let store = self.store.lock().unwrap();
+ let placeholder_image = store.placeholder_image.clone();
+ let placeholder_url = store.placeholder_url.clone();
+ Arc::new(ImageCacheImpl {
+ store: Arc::new(Mutex::new(ImageCacheStore {
+ pending_loads: AllPendingLoads::new(),
+ completed_loads: HashMap::new(),
+ placeholder_image,
+ placeholder_url,
+ compositor_api,
+ })),
+ thread_pool: self.thread_pool.clone(),
+ })
+ }
}
impl ImageCacheImpl {
diff --git a/components/net/tests/fetch.rs b/components/net/tests/fetch.rs
index 7dbf1ca0047..e8c5077f12a 100644
--- a/components/net/tests/fetch.rs
+++ b/components/net/tests/fetch.rs
@@ -225,7 +225,7 @@ fn test_fetch_blob() {
#[test]
fn test_file() {
- let path = Path::new("../../resources/servo.css")
+ let path = Path::new("../../resources/ahem.css")
.canonicalize()
.unwrap();
let url = ServoUrl::from_file_path(path.clone()).unwrap();
diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs
index 2baab15e1b8..9ce24038259 100644
--- a/components/script/dom/document.rs
+++ b/components/script/dom/document.rs
@@ -103,7 +103,9 @@ use crate::dom::bindings::codegen::Bindings::WindowBinding::{
};
use crate::dom::bindings::codegen::Bindings::XPathEvaluatorBinding::XPathEvaluatorMethods;
use crate::dom::bindings::codegen::Bindings::XPathNSResolverBinding::XPathNSResolver;
-use crate::dom::bindings::codegen::UnionTypes::{NodeOrString, StringOrElementCreationOptions};
+use crate::dom::bindings::codegen::UnionTypes::{
+ NodeOrString, StringOrElementCreationOptions, TrustedHTMLOrString,
+};
use crate::dom::bindings::error::{Error, ErrorInfo, ErrorResult, Fallible};
use crate::dom::bindings::inheritance::{Castable, ElementTypeId, HTMLElementTypeId, NodeTypeId};
use crate::dom::bindings::num::Finite;
@@ -184,6 +186,7 @@ use crate::dom::touch::Touch;
use crate::dom::touchevent::TouchEvent as DomTouchEvent;
use crate::dom::touchlist::TouchList;
use crate::dom::treewalker::TreeWalker;
+use crate::dom::trustedhtml::TrustedHTML;
use crate::dom::types::VisibilityStateEntry;
use crate::dom::uievent::UIEvent;
use crate::dom::virtualmethods::vtable_for;
@@ -3818,6 +3821,90 @@ impl Document {
.Performance()
.queue_entry(entry.upcast::<PerformanceEntry>(), can_gc);
}
+
+ /// <https://html.spec.whatwg.org/multipage/#document-write-steps>
+ fn write(
+ &self,
+ text: Vec<TrustedHTMLOrString>,
+ line_feed: bool,
+ containing_class: &str,
+ field: &str,
+ can_gc: CanGc,
+ ) -> ErrorResult {
+ // Step 1: Let string be the empty string.
+ let mut strings: Vec<String> = Vec::with_capacity(text.len());
+ // Step 2: Let isTrusted be false if text contains a string; otherwise true.
+ let mut is_trusted = true;
+ // Step 3: For each value of text:
+ for value in text {
+ match value {
+ // Step 3.1: If value is a TrustedHTML object, then append value's associated data to string.
+ TrustedHTMLOrString::TrustedHTML(trusted_html) => {
+ strings.push(trusted_html.to_string().to_owned());
+ },
+ TrustedHTMLOrString::String(str_) => {
+ // Step 2: Let isTrusted be false if text contains a string; otherwise true.
+ is_trusted = false;
+ // Step 3.2: Otherwise, append value to string.
+ strings.push(str_.into());
+ },
+ };
+ }
+ let mut string = itertools::join(strings, "");
+ // Step 4: If isTrusted is false, set string to the result of invoking the
+ // Get Trusted Type compliant string algorithm with TrustedHTML,
+ // this's relevant global object, string, sink, and "script".
+ if !is_trusted {
+ string = TrustedHTML::get_trusted_script_compliant_string(
+ &self.global(),
+ TrustedHTMLOrString::String(string.into()),
+ containing_class,
+ field,
+ can_gc,
+ )?;
+ }
+ // Step 5: If lineFeed is true, append U+000A LINE FEED to string.
+ if line_feed {
+ string.push('\n');
+ }
+ // Step 6: If document is an XML document, then throw an "InvalidStateError" DOMException.
+ if !self.is_html_document() {
+ return Err(Error::InvalidState);
+ }
+
+ // Step 7: If document's throw-on-dynamic-markup-insertion counter is greater than 0,
+ // then throw an "InvalidStateError" DOMException.
+ if self.throw_on_dynamic_markup_insertion_counter.get() > 0 {
+ return Err(Error::InvalidState);
+ }
+
+ // Step 8: If document's active parser was aborted is true, then return.
+ if !self.is_active() || self.active_parser_was_aborted.get() {
+ return Ok(());
+ }
+
+ let parser = match self.get_current_parser() {
+ Some(ref parser) if parser.can_write() => DomRoot::from_ref(&**parser),
+ // Step 9: If the insertion point is undefined, then:
+ _ => {
+ // Step 9.1: If document's unload counter is greater than 0 or
+ // document's ignore-destructive-writes counter is greater than 0, then return.
+ if self.is_prompting_or_unloading() ||
+ self.ignore_destructive_writes_counter.get() > 0
+ {
+ return Ok(());
+ }
+ // Step 9.2: Run the document open steps with document.
+ self.Open(None, None, can_gc)?;
+ self.get_current_parser().unwrap()
+ },
+ };
+
+ // Steps 10-11.
+ parser.write(string.into(), can_gc);
+
+ Ok(())
+ }
}
fn is_character_value_key(key: &Key) -> bool {
@@ -6408,54 +6495,17 @@ impl DocumentMethods<crate::DomTypeHolder> for Document {
}
// https://html.spec.whatwg.org/multipage/#dom-document-write
- fn Write(&self, text: Vec<DOMString>, can_gc: CanGc) -> ErrorResult {
- if !self.is_html_document() {
- // Step 1.
- return Err(Error::InvalidState);
- }
-
- // Step 2.
- if self.throw_on_dynamic_markup_insertion_counter.get() > 0 {
- return Err(Error::InvalidState);
- }
-
- // Step 3 - what specifies the is_active() part here?
- if !self.is_active() || self.active_parser_was_aborted.get() {
- return Ok(());
- }
-
- let parser = match self.get_current_parser() {
- Some(ref parser) if parser.can_write() => DomRoot::from_ref(&**parser),
- _ => {
- // Either there is no parser, which means the parsing ended;
- // or script nesting level is 0, which means the method was
- // called from outside a parser-executed script.
- if self.is_prompting_or_unloading() ||
- self.ignore_destructive_writes_counter.get() > 0
- {
- // Step 4.
- return Ok(());
- }
- // Step 5.
- self.Open(None, None, can_gc)?;
- self.get_current_parser().unwrap()
- },
- };
-
- // Step 7.
- // TODO: handle reload override buffer.
-
- // Steps 6-8.
- parser.write(text, can_gc);
-
- // Step 9.
- Ok(())
+ fn Write(&self, text: Vec<TrustedHTMLOrString>, can_gc: CanGc) -> ErrorResult {
+ // The document.write(...text) method steps are to run the document write steps
+ // with this, text, false, and "Document write".
+ self.write(text, false, "Document", "write", can_gc)
}
// https://html.spec.whatwg.org/multipage/#dom-document-writeln
- fn Writeln(&self, mut text: Vec<DOMString>, can_gc: CanGc) -> ErrorResult {
- text.push("\n".into());
- self.Write(text, can_gc)
+ fn Writeln(&self, text: Vec<TrustedHTMLOrString>, can_gc: CanGc) -> ErrorResult {
+ // The document.writeln(...text) method steps are to run the document write steps
+ // with this, text, true, and "Document writeln".
+ self.write(text, true, "Document", "writeln", can_gc)
}
// https://html.spec.whatwg.org/multipage/#dom-document-close
diff --git a/components/script/dom/element.rs b/components/script/dom/element.rs
index c040078f707..d92d5c124d1 100644
--- a/components/script/dom/element.rs
+++ b/components/script/dom/element.rs
@@ -149,7 +149,6 @@ use crate::dom::raredata::ElementRareData;
use crate::dom::servoparser::ServoParser;
use crate::dom::shadowroot::{IsUserAgentWidget, ShadowRoot};
use crate::dom::text::Text;
-use crate::dom::types::TrustedTypePolicyFactory;
use crate::dom::validation::Validatable;
use crate::dom::validitystate::ValidationFlags;
use crate::dom::virtualmethods::{VirtualMethods, vtable_for};
@@ -1961,35 +1960,6 @@ impl Element {
.unwrap_or_else(|_| TrustedScriptURLOrUSVString::USVString(USVString(value.to_owned())))
}
- pub(crate) fn set_trusted_type_url_attribute(
- &self,
- local_name: &LocalName,
- value: TrustedScriptURLOrUSVString,
- can_gc: CanGc,
- ) -> Fallible<()> {
- assert_eq!(*local_name, local_name.to_ascii_lowercase());
- let value = match value {
- TrustedScriptURLOrUSVString::USVString(url) => {
- let global = self.owner_global();
- // TODO(36258): Reflectively get the name of the class
- let sink = format!("{} {}", "HTMLScriptElement", &local_name);
- let result = TrustedTypePolicyFactory::get_trusted_type_compliant_string(
- &global,
- url.to_string(),
- &sink,
- "'script'",
- can_gc,
- );
- result?
- },
- // This partially implements <https://w3c.github.io/trusted-types/dist/spec/#get-trusted-type-compliant-string-algorithm>
- // Step 1: If input is an instance of expectedType, return stringified input and abort these steps.
- TrustedScriptURLOrUSVString::TrustedScriptURL(script_url) => script_url.to_string(),
- };
- self.set_attribute(local_name, AttrValue::String(value), can_gc);
- Ok(())
- }
-
pub(crate) fn get_string_attribute(&self, local_name: &LocalName) -> DOMString {
match self.get_attribute(&ns!(), local_name) {
Some(x) => x.Value(),
diff --git a/components/script/dom/gamepad.rs b/components/script/dom/gamepad.rs
index dcafc58bcd9..baf3af7466f 100644
--- a/components/script/dom/gamepad.rs
+++ b/components/script/dom/gamepad.rs
@@ -13,7 +13,7 @@ use crate::dom::bindings::codegen::Bindings::GamepadBinding::{GamepadHand, Gamep
use crate::dom::bindings::codegen::Bindings::GamepadButtonListBinding::GamepadButtonListMethods;
use crate::dom::bindings::inheritance::Castable;
use crate::dom::bindings::num::Finite;
-use crate::dom::bindings::reflector::{DomGlobal, Reflector, reflect_dom_object_with_proto};
+use crate::dom::bindings::reflector::{DomGlobal, Reflector, reflect_dom_object};
use crate::dom::bindings::root::{Dom, DomRoot};
use crate::dom::bindings::str::DOMString;
use crate::dom::event::Event;
@@ -23,6 +23,7 @@ use crate::dom::gamepadevent::{GamepadEvent, GamepadEventType};
use crate::dom::gamepadhapticactuator::GamepadHapticActuator;
use crate::dom::gamepadpose::GamepadPose;
use crate::dom::globalscope::GlobalScope;
+use crate::dom::window::Window;
use crate::script_runtime::{CanGc, JSContext};
// This value is for determining when to consider a gamepad as having a user gesture
@@ -88,39 +89,14 @@ impl Gamepad {
}
}
- #[allow(clippy::too_many_arguments)]
- pub(crate) fn new(
- global: &GlobalScope,
- gamepad_id: u32,
- id: String,
- mapping_type: String,
- axis_bounds: (f64, f64),
- button_bounds: (f64, f64),
- supported_haptic_effects: GamepadSupportedHapticEffects,
- xr: bool,
- can_gc: CanGc,
- ) -> DomRoot<Gamepad> {
- Self::new_with_proto(
- global,
- gamepad_id,
- id,
- mapping_type,
- axis_bounds,
- button_bounds,
- supported_haptic_effects,
- xr,
- can_gc,
- )
- }
-
/// When we construct a new gamepad, we initialize the number of buttons and
/// axes corresponding to the "standard" gamepad mapping.
/// The spec says UAs *may* do this for fingerprint mitigation, and it also
/// happens to simplify implementation
/// <https://www.w3.org/TR/gamepad/#fingerprinting-mitigation>
#[allow(clippy::too_many_arguments)]
- fn new_with_proto(
- global: &GlobalScope,
+ pub(crate) fn new(
+ window: &Window,
gamepad_id: u32,
id: String,
mapping_type: String,
@@ -130,11 +106,11 @@ impl Gamepad {
xr: bool,
can_gc: CanGc,
) -> DomRoot<Gamepad> {
- let button_list = GamepadButtonList::init_buttons(global, can_gc);
+ let button_list = GamepadButtonList::init_buttons(window, can_gc);
let vibration_actuator =
- GamepadHapticActuator::new(global, gamepad_id, supported_haptic_effects, can_gc);
+ GamepadHapticActuator::new(window, gamepad_id, supported_haptic_effects, can_gc);
let index = if xr { -1 } else { 0 };
- let gamepad = reflect_dom_object_with_proto(
+ let gamepad = reflect_dom_object(
Box::new(Gamepad::new_inherited(
gamepad_id,
id,
@@ -149,8 +125,7 @@ impl Gamepad {
button_bounds,
&vibration_actuator,
)),
- global,
- None,
+ window,
can_gc,
);
gamepad.init_axes(can_gc);
diff --git a/components/script/dom/gamepadbutton.rs b/components/script/dom/gamepadbutton.rs
index fead990ccd3..3588ba775ca 100644
--- a/components/script/dom/gamepadbutton.rs
+++ b/components/script/dom/gamepadbutton.rs
@@ -10,7 +10,7 @@ use crate::dom::bindings::codegen::Bindings::GamepadButtonBinding::GamepadButton
use crate::dom::bindings::num::Finite;
use crate::dom::bindings::reflector::{Reflector, reflect_dom_object};
use crate::dom::bindings::root::DomRoot;
-use crate::dom::globalscope::GlobalScope;
+use crate::dom::window::Window;
use crate::script_runtime::CanGc;
#[dom_struct]
@@ -32,14 +32,14 @@ impl GamepadButton {
}
pub(crate) fn new(
- global: &GlobalScope,
+ window: &Window,
pressed: bool,
touched: bool,
can_gc: CanGc,
) -> DomRoot<GamepadButton> {
reflect_dom_object(
Box::new(GamepadButton::new_inherited(pressed, touched)),
- global,
+ window,
can_gc,
)
}
diff --git a/components/script/dom/gamepadbuttonlist.rs b/components/script/dom/gamepadbuttonlist.rs
index 50d9c8172bc..7e540ab56bb 100644
--- a/components/script/dom/gamepadbuttonlist.rs
+++ b/components/script/dom/gamepadbuttonlist.rs
@@ -8,7 +8,7 @@ use crate::dom::bindings::codegen::Bindings::GamepadButtonListBinding::GamepadBu
use crate::dom::bindings::reflector::{Reflector, reflect_dom_object};
use crate::dom::bindings::root::{Dom, DomRoot, DomSlice};
use crate::dom::gamepadbutton::GamepadButton;
-use crate::dom::globalscope::GlobalScope;
+use crate::dom::window::Window;
use crate::script_runtime::CanGc;
// https://w3c.github.io/gamepad/#gamepadbutton-interface
@@ -28,13 +28,13 @@ impl GamepadButtonList {
}
pub(crate) fn new(
- global: &GlobalScope,
+ window: &Window,
list: &[&GamepadButton],
can_gc: CanGc,
) -> DomRoot<GamepadButtonList> {
reflect_dom_object(
Box::new(GamepadButtonList::new_inherited(list)),
- global,
+ window,
can_gc,
)
}
@@ -62,27 +62,27 @@ impl GamepadButtonListMethods<crate::DomTypeHolder> for GamepadButtonList {
impl GamepadButtonList {
/// Initialize the number of buttons in the "standard" gamepad mapping.
/// <https://www.w3.org/TR/gamepad/#dfn-initializing-buttons>
- pub(crate) fn init_buttons(global: &GlobalScope, can_gc: CanGc) -> DomRoot<GamepadButtonList> {
+ pub(crate) fn init_buttons(window: &Window, can_gc: CanGc) -> DomRoot<GamepadButtonList> {
let standard_buttons = &[
- GamepadButton::new(global, false, false, can_gc), // Bottom button in right cluster
- GamepadButton::new(global, false, false, can_gc), // Right button in right cluster
- GamepadButton::new(global, false, false, can_gc), // Left button in right cluster
- GamepadButton::new(global, false, false, can_gc), // Top button in right cluster
- GamepadButton::new(global, false, false, can_gc), // Top left front button
- GamepadButton::new(global, false, false, can_gc), // Top right front button
- GamepadButton::new(global, false, false, can_gc), // Bottom left front button
- GamepadButton::new(global, false, false, can_gc), // Bottom right front button
- GamepadButton::new(global, false, false, can_gc), // Left button in center cluster
- GamepadButton::new(global, false, false, can_gc), // Right button in center cluster
- GamepadButton::new(global, false, false, can_gc), // Left stick pressed button
- GamepadButton::new(global, false, false, can_gc), // Right stick pressed button
- GamepadButton::new(global, false, false, can_gc), // Top button in left cluster
- GamepadButton::new(global, false, false, can_gc), // Bottom button in left cluster
- GamepadButton::new(global, false, false, can_gc), // Left button in left cluster
- GamepadButton::new(global, false, false, can_gc), // Right button in left cluster
- GamepadButton::new(global, false, false, can_gc), // Center button in center cluster
+ GamepadButton::new(window, false, false, can_gc), // Bottom button in right cluster
+ GamepadButton::new(window, false, false, can_gc), // Right button in right cluster
+ GamepadButton::new(window, false, false, can_gc), // Left button in right cluster
+ GamepadButton::new(window, false, false, can_gc), // Top button in right cluster
+ GamepadButton::new(window, false, false, can_gc), // Top left front button
+ GamepadButton::new(window, false, false, can_gc), // Top right front button
+ GamepadButton::new(window, false, false, can_gc), // Bottom left front button
+ GamepadButton::new(window, false, false, can_gc), // Bottom right front button
+ GamepadButton::new(window, false, false, can_gc), // Left button in center cluster
+ GamepadButton::new(window, false, false, can_gc), // Right button in center cluster
+ GamepadButton::new(window, false, false, can_gc), // Left stick pressed button
+ GamepadButton::new(window, false, false, can_gc), // Right stick pressed button
+ GamepadButton::new(window, false, false, can_gc), // Top button in left cluster
+ GamepadButton::new(window, false, false, can_gc), // Bottom button in left cluster
+ GamepadButton::new(window, false, false, can_gc), // Left button in left cluster
+ GamepadButton::new(window, false, false, can_gc), // Right button in left cluster
+ GamepadButton::new(window, false, false, can_gc), // Center button in center cluster
];
rooted_vec!(let buttons <- standard_buttons.iter().map(DomRoot::as_traced));
- Self::new(global, buttons.r(), can_gc)
+ Self::new(window, buttons.r(), can_gc)
}
}
diff --git a/components/script/dom/gamepadhapticactuator.rs b/components/script/dom/gamepadhapticactuator.rs
index d19db6d1279..ddea21b97ee 100644
--- a/components/script/dom/gamepadhapticactuator.rs
+++ b/components/script/dom/gamepadhapticactuator.rs
@@ -18,12 +18,12 @@ use crate::dom::bindings::codegen::Bindings::GamepadHapticActuatorBinding::{
use crate::dom::bindings::codegen::Bindings::WindowBinding::Window_Binding::WindowMethods;
use crate::dom::bindings::error::Error;
use crate::dom::bindings::refcounted::{Trusted, TrustedPromise};
-use crate::dom::bindings::reflector::{DomGlobal, Reflector, reflect_dom_object_with_proto};
+use crate::dom::bindings::reflector::{DomGlobal, Reflector, reflect_dom_object};
use crate::dom::bindings::root::DomRoot;
use crate::dom::bindings::str::DOMString;
use crate::dom::bindings::utils::to_frozen_array;
-use crate::dom::globalscope::GlobalScope;
use crate::dom::promise::Promise;
+use crate::dom::window::Window;
use crate::realms::InRealm;
use crate::script_runtime::{CanGc, JSContext};
use crate::task_source::SendableTaskSource;
@@ -98,27 +98,17 @@ impl GamepadHapticActuator {
}
pub(crate) fn new(
- global: &GlobalScope,
+ window: &Window,
gamepad_index: u32,
supported_haptic_effects: GamepadSupportedHapticEffects,
can_gc: CanGc,
) -> DomRoot<GamepadHapticActuator> {
- Self::new_with_proto(global, gamepad_index, supported_haptic_effects, can_gc)
- }
-
- fn new_with_proto(
- global: &GlobalScope,
- gamepad_index: u32,
- supported_haptic_effects: GamepadSupportedHapticEffects,
- can_gc: CanGc,
- ) -> DomRoot<GamepadHapticActuator> {
- reflect_dom_object_with_proto(
+ reflect_dom_object(
Box::new(GamepadHapticActuator::new_inherited(
gamepad_index,
supported_haptic_effects,
)),
- global,
- None,
+ window,
can_gc,
)
}
diff --git a/components/script/dom/globalscope.rs b/components/script/dom/globalscope.rs
index efa9a9a97ab..527d03eed4e 100644
--- a/components/script/dom/globalscope.rs
+++ b/components/script/dom/globalscope.rs
@@ -18,18 +18,17 @@ use base::id::{
ServiceWorkerId, ServiceWorkerRegistrationId, WebViewId,
};
use constellation_traits::{
- BlobData, BlobImpl, BroadcastMsg, FileBlob, MessagePortImpl, MessagePortMsg, PortMessageTask,
- ScriptToConstellationChan, ScriptToConstellationMessage,
+ BlobData, BlobImpl, BroadcastMsg, FileBlob, LoadData, LoadOrigin, MessagePortImpl,
+ MessagePortMsg, PortMessageTask, ScriptToConstellationChan, ScriptToConstellationMessage,
};
use content_security_policy::{
- CheckResult, CspList, PolicyDisposition, PolicySource, Violation, ViolationResource,
+ CheckResult, CspList, Destination, Initiator, NavigationCheckType, ParserMetadata,
+ PolicyDisposition, PolicySource, Request, Violation, ViolationResource,
};
use crossbeam_channel::Sender;
use devtools_traits::{PageError, ScriptToDevtoolsControlMsg};
use dom_struct::dom_struct;
-use embedder_traits::{
- EmbedderMsg, GamepadEvent, GamepadSupportedHapticEffects, GamepadUpdateType,
-};
+use embedder_traits::EmbedderMsg;
use http::HeaderMap;
use hyper_serde::Serde;
use ipc_channel::ipc::{self, IpcSender};
@@ -64,6 +63,7 @@ use profile_traits::{ipc as profile_ipc, mem as profile_mem, time as profile_tim
use script_bindings::interfaces::GlobalScopeHelpers;
use servo_url::{ImmutableOrigin, MutableOrigin, ServoUrl};
use timers::{TimerEventId, TimerEventRequest, TimerSource};
+use url::Origin;
use uuid::Uuid;
#[cfg(feature = "webgpu")]
use webgpu_traits::{DeviceLostReason, WebGPUDevice};
@@ -81,9 +81,7 @@ use crate::dom::bindings::codegen::Bindings::FunctionBinding::Function;
use crate::dom::bindings::codegen::Bindings::ImageBitmapBinding::{
ImageBitmapOptions, ImageBitmapSource,
};
-use crate::dom::bindings::codegen::Bindings::NavigatorBinding::NavigatorMethods;
use crate::dom::bindings::codegen::Bindings::NotificationBinding::NotificationPermissionCallback;
-use crate::dom::bindings::codegen::Bindings::PerformanceBinding::Performance_Binding::PerformanceMethods;
use crate::dom::bindings::codegen::Bindings::PermissionStatusBinding::{
PermissionName, PermissionState,
};
@@ -113,8 +111,6 @@ use crate::dom::event::{Event, EventBubbles, EventCancelable, EventStatus};
use crate::dom::eventsource::EventSource;
use crate::dom::eventtarget::EventTarget;
use crate::dom::file::File;
-use crate::dom::gamepad::{Gamepad, contains_user_gesture};
-use crate::dom::gamepadevent::GamepadEventType;
use crate::dom::htmlscriptelement::{ScriptId, SourceCode};
use crate::dom::imagebitmap::ImageBitmap;
use crate::dom::messageevent::MessageEvent;
@@ -2957,6 +2953,33 @@ impl GlobalScope {
is_js_evaluation_allowed == CheckResult::Allowed
}
+ pub(crate) fn should_navigation_request_be_blocked(&self, load_data: &LoadData) -> bool {
+ let Some(csp_list) = self.get_csp_list() else {
+ return false;
+ };
+ let request = Request {
+ url: load_data.url.clone().into_url(),
+ origin: match &load_data.load_origin {
+ LoadOrigin::Script(immutable_origin) => immutable_origin.clone().into_url_origin(),
+ _ => Origin::new_opaque(),
+ },
+ // TODO: populate this field correctly
+ redirect_count: 0,
+ destination: Destination::None,
+ initiator: Initiator::None,
+ nonce: "".to_owned(),
+ integrity_metadata: "".to_owned(),
+ parser_metadata: ParserMetadata::None,
+ };
+ // TODO: set correct navigation check type for form submission if applicable
+ let (result, violations) =
+ csp_list.should_navigation_request_be_blocked(&request, NavigationCheckType::Other);
+
+ self.report_csp_violations(violations);
+
+ result == CheckResult::Blocked
+ }
+
pub(crate) fn create_image_bitmap(
&self,
image: ImageBitmapSource,
@@ -3287,134 +3310,6 @@ impl GlobalScope {
}
}
- pub(crate) fn handle_gamepad_event(&self, gamepad_event: GamepadEvent) {
- match gamepad_event {
- GamepadEvent::Connected(index, name, bounds, supported_haptic_effects) => {
- self.handle_gamepad_connect(
- index.0,
- name,
- bounds.axis_bounds,
- bounds.button_bounds,
- supported_haptic_effects,
- );
- },
- GamepadEvent::Disconnected(index) => {
- self.handle_gamepad_disconnect(index.0);
- },
- GamepadEvent::Updated(index, update_type) => {
- self.receive_new_gamepad_button_or_axis(index.0, update_type);
- },
- };
- }
-
- /// <https://www.w3.org/TR/gamepad/#dfn-gamepadconnected>
- fn handle_gamepad_connect(
- &self,
- // As the spec actually defines how to set the gamepad index, the GilRs index
- // is currently unused, though in practice it will almost always be the same.
- // More infra is currently needed to track gamepads across windows.
- _index: usize,
- name: String,
- axis_bounds: (f64, f64),
- button_bounds: (f64, f64),
- supported_haptic_effects: GamepadSupportedHapticEffects,
- ) {
- // TODO: 2. If document is not null and is not allowed to use the "gamepad" permission,
- // then abort these steps.
- let this = Trusted::new(self);
- self.task_manager()
- .gamepad_task_source()
- .queue(task!(gamepad_connected: move || {
- let global = this.root();
-
- if let Some(window) = global.downcast::<Window>() {
- let navigator = window.Navigator();
- let selected_index = navigator.select_gamepad_index();
- let gamepad = Gamepad::new(
- &global,
- selected_index,
- name,
- "standard".into(),
- axis_bounds,
- button_bounds,
- supported_haptic_effects,
- false,
- CanGc::note(),
- );
- navigator.set_gamepad(selected_index as usize, &gamepad, CanGc::note());
- }
- }));
- }
-
- /// <https://www.w3.org/TR/gamepad/#dfn-gamepaddisconnected>
- pub(crate) fn handle_gamepad_disconnect(&self, index: usize) {
- let this = Trusted::new(self);
- self.task_manager()
- .gamepad_task_source()
- .queue(task!(gamepad_disconnected: move || {
- let global = this.root();
- if let Some(window) = global.downcast::<Window>() {
- let navigator = window.Navigator();
- if let Some(gamepad) = navigator.get_gamepad(index) {
- if window.Document().is_fully_active() {
- gamepad.update_connected(false, gamepad.exposed(), CanGc::note());
- navigator.remove_gamepad(index);
- }
- }
- }
- }));
- }
-
- /// <https://www.w3.org/TR/gamepad/#receiving-inputs>
- pub(crate) fn receive_new_gamepad_button_or_axis(
- &self,
- index: usize,
- update_type: GamepadUpdateType,
- ) {
- let this = Trusted::new(self);
-
- // <https://w3c.github.io/gamepad/#dfn-update-gamepad-state>
- self.task_manager().gamepad_task_source().queue(
- task!(update_gamepad_state: move || {
- let global = this.root();
- if let Some(window) = global.downcast::<Window>() {
- let navigator = window.Navigator();
- if let Some(gamepad) = navigator.get_gamepad(index) {
- let current_time = global.performance().Now();
- gamepad.update_timestamp(*current_time);
- match update_type {
- GamepadUpdateType::Axis(index, value) => {
- gamepad.map_and_normalize_axes(index, value);
- },
- GamepadUpdateType::Button(index, value) => {
- gamepad.map_and_normalize_buttons(index, value);
- }
- };
- if !navigator.has_gamepad_gesture() && contains_user_gesture(update_type) {
- navigator.set_has_gamepad_gesture(true);
- navigator.GetGamepads()
- .iter()
- .filter_map(|g| g.as_ref())
- .for_each(|gamepad| {
- gamepad.set_exposed(true);
- gamepad.update_timestamp(*current_time);
- let new_gamepad = Trusted::new(&**gamepad);
- if window.Document().is_fully_active() {
- global.task_manager().gamepad_task_source().queue(
- task!(update_gamepad_connect: move || {
- let gamepad = new_gamepad.root();
- gamepad.notify_event(GamepadEventType::Connected, CanGc::note());
- })
- );
- }
- });
- }
- }
- }
- })
- );
- }
-
pub(crate) fn current_group_label(&self) -> Option<DOMString> {
self.console_group_stack
.borrow()
diff --git a/components/script/dom/htmlelement.rs b/components/script/dom/htmlelement.rs
index e7efbde9b1d..59b71543d6d 100644
--- a/components/script/dom/htmlelement.rs
+++ b/components/script/dom/htmlelement.rs
@@ -116,7 +116,7 @@ impl HTMLElement {
/// `.outerText` in JavaScript.`
///
/// <https://html.spec.whatwg.org/multipage/#get-the-text-steps>
- fn get_inner_outer_text(&self, can_gc: CanGc) -> DOMString {
+ pub(crate) fn get_inner_outer_text(&self, can_gc: CanGc) -> DOMString {
let node = self.upcast::<Node>();
let window = node.owner_window();
let element = self.as_element();
@@ -134,6 +134,16 @@ impl HTMLElement {
DOMString::from(text)
}
+
+ /// <https://html.spec.whatwg.org/multipage/#set-the-inner-text-steps>
+ pub(crate) fn set_inner_text(&self, input: DOMString, can_gc: CanGc) {
+ // Step 1: Let fragment be the rendered text fragment for value given element's node
+ // document.
+ let fragment = self.rendered_text_fragment(input, can_gc);
+
+ // Step 2: Replace all with fragment within element.
+ Node::replace_all(Some(fragment.upcast()), self.upcast::<Node>(), can_gc);
+ }
}
impl HTMLElementMethods<crate::DomTypeHolder> for HTMLElement {
@@ -494,12 +504,7 @@ impl HTMLElementMethods<crate::DomTypeHolder> for HTMLElement {
/// <https://html.spec.whatwg.org/multipage/#set-the-inner-text-steps>
fn SetInnerText(&self, input: DOMString, can_gc: CanGc) {
- // Step 1: Let fragment be the rendered text fragment for value given element's node
- // document.
- let fragment = self.rendered_text_fragment(input, can_gc);
-
- // Step 2: Replace all with fragment within element.
- Node::replace_all(Some(fragment.upcast()), self.upcast::<Node>(), can_gc);
+ self.set_inner_text(input, can_gc)
}
/// <https://html.spec.whatwg.org/multipage/#dom-outertext>
diff --git a/components/script/dom/htmliframeelement.rs b/components/script/dom/htmliframeelement.rs
index c5194c4527f..0fbff86e44a 100644
--- a/components/script/dom/htmliframeelement.rs
+++ b/components/script/dom/htmliframeelement.rs
@@ -162,8 +162,13 @@ impl HTMLIFrameElement {
if load_data.url.scheme() == "javascript" {
let window_proxy = self.GetContentWindow();
if let Some(window_proxy) = window_proxy {
+ if document
+ .global()
+ .should_navigation_request_be_blocked(&load_data)
+ {
+ return;
+ }
// Important re security. See https://github.com/servo/servo/issues/23373
- // TODO: check according to https://w3c.github.io/webappsec-csp/#should-block-navigation-request
if ScriptThread::check_load_origin(&load_data.load_origin, &document.url().origin())
{
ScriptThread::eval_js_url(&window_proxy.global(), &mut load_data, can_gc);
@@ -274,6 +279,7 @@ impl HTMLIFrameElement {
Some(document.insecure_requests_policy()),
document.has_trustworthy_ancestor_or_current_origin(),
);
+ load_data.policy_container = Some(window.as_global_scope().policy_container());
let element = self.upcast::<Element>();
load_data.srcdoc = String::from(element.get_string_attribute(&local_name!("srcdoc")));
self.navigate_or_reload_child_browsing_context(
@@ -356,7 +362,7 @@ impl HTMLIFrameElement {
None
};
- let load_data = LoadData::new(
+ let mut load_data = LoadData::new(
LoadOrigin::Script(document.origin().immutable().clone()),
url,
creator_pipeline_id,
@@ -373,6 +379,10 @@ impl HTMLIFrameElement {
let is_about_blank =
pipeline_id.is_some() && pipeline_id == self.about_blank_pipeline_id.get();
+ if is_about_blank {
+ load_data.policy_container = Some(window.as_global_scope().policy_container());
+ }
+
let history_handling = if is_about_blank {
NavigationHistoryBehavior::Replace
} else {
@@ -402,7 +412,7 @@ impl HTMLIFrameElement {
let document = self.owner_document();
let window = self.owner_window();
let pipeline_id = Some(window.pipeline_id());
- let load_data = LoadData::new(
+ let mut load_data = LoadData::new(
LoadOrigin::Script(document.origin().immutable().clone()),
url,
pipeline_id,
@@ -412,6 +422,7 @@ impl HTMLIFrameElement {
Some(document.insecure_requests_policy()),
document.has_trustworthy_ancestor_or_current_origin(),
);
+ load_data.policy_container = Some(window.as_global_scope().policy_container());
let browsing_context_id = BrowsingContextId::new();
let webview_id = window.window_proxy().webview_id();
self.pipeline_id.set(None);
diff --git a/components/script/dom/htmlmediaelement.rs b/components/script/dom/htmlmediaelement.rs
index c07f866ab41..361c22c1250 100644
--- a/components/script/dom/htmlmediaelement.rs
+++ b/components/script/dom/htmlmediaelement.rs
@@ -12,7 +12,6 @@ use std::{f64, mem};
use compositing_traits::{CrossProcessCompositorApi, ImageUpdate, SerializableImageData};
use content_security_policy as csp;
use dom_struct::dom_struct;
-use embedder_traits::resources::{self, Resource as EmbedderResource};
use embedder_traits::{MediaPositionState, MediaSessionEvent, MediaSessionPlaybackState};
use euclid::default::Size2D;
use headers::{ContentLength, ContentRange, HeaderMapExt};
@@ -110,6 +109,12 @@ use crate::realms::{InRealm, enter_realm};
use crate::script_runtime::CanGc;
use crate::script_thread::ScriptThread;
+/// A CSS file to style the media controls.
+static MEDIA_CONTROL_CSS: &str = include_str!("../resources/media-controls.css");
+
+/// A JS file to control the media controls.
+static MEDIA_CONTROL_JS: &str = include_str!("../resources/media-controls.js");
+
#[derive(PartialEq)]
enum FrameStatus {
Locked,
@@ -1949,14 +1954,13 @@ impl HTMLMediaElement {
ElementCreator::ScriptCreated,
can_gc,
);
- let mut media_controls_script = resources::read_string(EmbedderResource::MediaControlsJS);
// This is our hacky way to temporarily workaround the lack of a privileged
// JS context.
// The media controls UI accesses the document.servoGetMediaControls(id) API
// to get an instance to the media controls ShadowRoot.
// `id` needs to match the internally generated UUID assigned to a media element.
let id = document.register_media_controls(&shadow_root);
- let media_controls_script = media_controls_script.as_mut_str().replace("@@@id@@@", &id);
+ let media_controls_script = MEDIA_CONTROL_JS.replace("@@@id@@@", &id);
*self.media_controls_id.borrow_mut() = Some(id);
script
.upcast::<Node>()
@@ -1969,7 +1973,6 @@ impl HTMLMediaElement {
return;
}
- let media_controls_style = resources::read_string(EmbedderResource::MediaControlsCSS);
let style = HTMLStyleElement::new(
local_name!("script"),
None,
@@ -1980,7 +1983,7 @@ impl HTMLMediaElement {
);
style
.upcast::<Node>()
- .SetTextContent(Some(DOMString::from(media_controls_style)), can_gc);
+ .SetTextContent(Some(DOMString::from(MEDIA_CONTROL_CSS)), can_gc);
if let Err(e) = shadow_root
.upcast::<Node>()
diff --git a/components/script/dom/htmlscriptelement.rs b/components/script/dom/htmlscriptelement.rs
index 58853f600d2..9d0ca807748 100644
--- a/components/script/dom/htmlscriptelement.rs
+++ b/components/script/dom/htmlscriptelement.rs
@@ -32,6 +32,7 @@ use net_traits::{
};
use servo_config::pref;
use servo_url::{ImmutableOrigin, ServoUrl};
+use style::attr::AttrValue;
use style::str::{HTML_SPACE_CHARACTERS, StaticStringVec};
use stylo_atoms::Atom;
use uuid::Uuid;
@@ -44,7 +45,9 @@ use crate::dom::bindings::codegen::Bindings::DocumentBinding::DocumentMethods;
use crate::dom::bindings::codegen::Bindings::HTMLScriptElementBinding::HTMLScriptElementMethods;
use crate::dom::bindings::codegen::Bindings::NodeBinding::NodeMethods;
use crate::dom::bindings::codegen::GenericBindings::HTMLElementBinding::HTMLElement_Binding::HTMLElementMethods;
-use crate::dom::bindings::codegen::UnionTypes::TrustedScriptURLOrUSVString;
+use crate::dom::bindings::codegen::UnionTypes::{
+ TrustedScriptOrString, TrustedScriptURLOrUSVString,
+};
use crate::dom::bindings::error::Fallible;
use crate::dom::bindings::inheritance::Castable;
use crate::dom::bindings::refcounted::Trusted;
@@ -64,6 +67,8 @@ use crate::dom::globalscope::GlobalScope;
use crate::dom::htmlelement::HTMLElement;
use crate::dom::node::{ChildrenMutation, CloneChildrenFlag, Node, NodeTraits};
use crate::dom::performanceresourcetiming::InitiatorType;
+use crate::dom::trustedscript::TrustedScript;
+use crate::dom::trustedscripturl::TrustedScriptURL;
use crate::dom::virtualmethods::VirtualMethods;
use crate::fetch::create_a_potential_cors_request;
use crate::network_listener::{self, NetworkListener, PreInvoke, ResourceTimingListener};
@@ -667,7 +672,7 @@ impl HTMLScriptElement {
// Step 5. Let source text be el's child text content.
// Step 6. If el has no src attribute, and source text is the empty string, then return.
- let text = self.Text();
+ let text = self.text();
if text.is_empty() && !element.has_attribute(&local_name!("src")) {
return;
}
@@ -1272,6 +1277,15 @@ impl HTMLScriptElement {
let event = Event::new(window.upcast(), type_, bubbles, cancelable, can_gc);
event.fire(self.upcast(), can_gc)
}
+
+ fn text(&self) -> DOMString {
+ match self.Text() {
+ TrustedScriptOrString::String(value) => value,
+ TrustedScriptOrString::TrustedScript(trusted_script) => {
+ DOMString::from(trusted_script.to_string())
+ },
+ }
+ }
}
impl VirtualMethods for HTMLScriptElement {
@@ -1286,7 +1300,7 @@ impl VirtualMethods for HTMLScriptElement {
if *attr.local_name() == local_name!("src") {
if let AttributeMutation::Set(_) = mutation {
if !self.parser_inserted.get() && self.upcast::<Node>().is_connected() {
- self.prepare(CanGc::note());
+ self.prepare(can_gc);
}
}
}
@@ -1344,10 +1358,25 @@ impl VirtualMethods for HTMLScriptElement {
impl HTMLScriptElementMethods<crate::DomTypeHolder> for HTMLScriptElement {
// https://html.spec.whatwg.org/multipage/#dom-script-src
- make_trusted_type_url_getter!(Src, "src");
+ fn Src(&self) -> TrustedScriptURLOrUSVString {
+ let element = self.upcast::<Element>();
+ element.get_trusted_type_url_attribute(&local_name!("src"))
+ }
- // https://html.spec.whatwg.org/multipage/#dom-script-src
- make_trusted_type_url_setter!(SetSrc, "src");
+ /// <https://w3c.github.io/trusted-types/dist/spec/#the-src-idl-attribute>
+ fn SetSrc(&self, value: TrustedScriptURLOrUSVString, can_gc: CanGc) -> Fallible<()> {
+ let element = self.upcast::<Element>();
+ let local_name = &local_name!("src");
+ let value = TrustedScriptURL::get_trusted_script_url_compliant_string(
+ &element.owner_global(),
+ value,
+ "HTMLScriptElement",
+ local_name,
+ can_gc,
+ )?;
+ element.set_attribute(local_name, AttrValue::String(value), can_gc);
+ Ok(())
+ }
// https://html.spec.whatwg.org/multipage/#dom-script-type
make_getter!(Type, "type");
@@ -1416,14 +1445,77 @@ impl HTMLScriptElementMethods<crate::DomTypeHolder> for HTMLScriptElement {
// https://html.spec.whatwg.org/multipage/#dom-script-referrerpolicy
make_setter!(SetReferrerPolicy, "referrerpolicy");
- // https://html.spec.whatwg.org/multipage/#dom-script-text
- fn Text(&self) -> DOMString {
- self.upcast::<Node>().child_text_content()
+ /// <https://w3c.github.io/trusted-types/dist/spec/#dom-htmlscriptelement-innertext>
+ fn InnerText(&self, can_gc: CanGc) -> TrustedScriptOrString {
+ // Step 1: Return the result of running get the text steps with this.
+ TrustedScriptOrString::String(self.upcast::<HTMLElement>().get_inner_outer_text(can_gc))
}
- // https://html.spec.whatwg.org/multipage/#dom-script-text
- fn SetText(&self, value: DOMString, can_gc: CanGc) {
- self.upcast::<Node>().SetTextContent(Some(value), can_gc)
+ /// <https://w3c.github.io/trusted-types/dist/spec/#the-innerText-idl-attribute>
+ fn SetInnerText(&self, input: TrustedScriptOrString, can_gc: CanGc) -> Fallible<()> {
+ // Step 1: Let value be the result of calling Get Trusted Type compliant string with TrustedScript,
+ // this's relevant global object, the given value, HTMLScriptElement innerText, and script.
+ let value = TrustedScript::get_trusted_script_compliant_string(
+ &self.owner_global(),
+ input,
+ "HTMLScriptElement",
+ "innerText",
+ can_gc,
+ )?;
+ // Step 3: Run set the inner text steps with this and value.
+ self.upcast::<HTMLElement>()
+ .set_inner_text(DOMString::from(value), can_gc);
+ Ok(())
+ }
+
+ /// <https://html.spec.whatwg.org/multipage/#dom-script-text>
+ fn Text(&self) -> TrustedScriptOrString {
+ TrustedScriptOrString::String(self.upcast::<Node>().child_text_content())
+ }
+
+ /// <https://w3c.github.io/trusted-types/dist/spec/#the-text-idl-attribute>
+ fn SetText(&self, value: TrustedScriptOrString, can_gc: CanGc) -> Fallible<()> {
+ // Step 1: Let value be the result of calling Get Trusted Type compliant string with TrustedScript,
+ // this's relevant global object, the given value, HTMLScriptElement text, and script.
+ let value = TrustedScript::get_trusted_script_compliant_string(
+ &self.owner_global(),
+ value,
+ "HTMLScriptElement",
+ "text",
+ can_gc,
+ )?;
+ // Step 2: Set this's script text value to the given value.
+ // TODO: Implement for https://w3c.github.io/trusted-types/dist/spec/#prepare-script-text
+ // Step 3: String replace all with the given value within this.
+ Node::string_replace_all(DOMString::from(value), self.upcast::<Node>(), can_gc);
+ Ok(())
+ }
+
+ /// <https://w3c.github.io/trusted-types/dist/spec/#the-textContent-idl-attribute>
+ fn GetTextContent(&self) -> Option<TrustedScriptOrString> {
+ // Step 1: Return the result of running get text content with this.
+ Some(TrustedScriptOrString::String(
+ self.upcast::<Node>().GetTextContent()?,
+ ))
+ }
+
+ /// <https://w3c.github.io/trusted-types/dist/spec/#the-textContent-idl-attribute>
+ fn SetTextContent(&self, value: Option<TrustedScriptOrString>, can_gc: CanGc) -> Fallible<()> {
+ // Step 1: Let value be the result of calling Get Trusted Type compliant string with TrustedScript,
+ // this's relevant global object, the given value, HTMLScriptElement textContent, and script.
+ let value = TrustedScript::get_trusted_script_compliant_string(
+ &self.owner_global(),
+ value.unwrap_or(TrustedScriptOrString::String(DOMString::from(""))),
+ "HTMLScriptElement",
+ "textContent",
+ can_gc,
+ )?;
+ // Step 2: Set this's script text value to value.
+ // TODO: Implement for https://w3c.github.io/trusted-types/dist/spec/#prepare-script-text
+ // Step 3: Run set text content with this and value.
+ self.upcast::<Node>()
+ .SetTextContent(Some(DOMString::from(value)), can_gc);
+ Ok(())
}
}
diff --git a/components/script/dom/macros.rs b/components/script/dom/macros.rs
index 997341984c6..cc44497d0b9 100644
--- a/components/script/dom/macros.rs
+++ b/components/script/dom/macros.rs
@@ -122,32 +122,6 @@ macro_rules! make_url_setter(
);
#[macro_export]
-macro_rules! make_trusted_type_url_getter(
- ( $attr:ident, $htmlname:tt ) => (
- fn $attr(&self) -> TrustedScriptURLOrUSVString {
- use $crate::dom::bindings::inheritance::Castable;
- use $crate::dom::element::Element;
- let element = self.upcast::<Element>();
- element.get_trusted_type_url_attribute(&html5ever::local_name!($htmlname))
- }
- );
-);
-
-#[macro_export]
-macro_rules! make_trusted_type_url_setter(
- ( $attr:ident, $htmlname:tt ) => (
- fn $attr(&self, value: TrustedScriptURLOrUSVString, can_gc: CanGc) -> Fallible<()> {
- use $crate::dom::bindings::inheritance::Castable;
- use $crate::dom::element::Element;
- use $crate::script_runtime::CanGc;
- let element = self.upcast::<Element>();
- element.set_trusted_type_url_attribute(&html5ever::local_name!($htmlname),
- value, can_gc)
- }
- );
-);
-
-#[macro_export]
macro_rules! make_form_action_getter(
( $attr:ident, $htmlname:tt ) => (
fn $attr(&self) -> DOMString {
diff --git a/components/script/dom/messageport.rs b/components/script/dom/messageport.rs
index d70d3139b96..d9cd6c50768 100644
--- a/components/script/dom/messageport.rs
+++ b/components/script/dom/messageport.rs
@@ -338,10 +338,6 @@ impl MessagePortMethods<crate::DomTypeHolder> for MessagePort {
/// <https://html.spec.whatwg.org/multipage/#dom-messageport-close>
fn Close(&self, can_gc: CanGc) {
- if self.detached.get() {
- return;
- }
-
// Set this's [[Detached]] internal slot value to true.
self.detached.set(true);
diff --git a/components/script/dom/servointernals.rs b/components/script/dom/servointernals.rs
index 54516c9a5b0..eb7260b61be 100644
--- a/components/script/dom/servointernals.rs
+++ b/components/script/dom/servointernals.rs
@@ -43,7 +43,9 @@ impl ServoInternalsMethods<crate::DomTypeHolder> for ServoInternals {
fn ReportMemory(&self, comp: InRealm, can_gc: CanGc) -> Rc<Promise> {
let global = &self.global();
let promise = Promise::new_in_current_realm(comp, can_gc);
- let sender = route_promise(&promise, self);
+ let task_source = global.task_manager().dom_manipulation_task_source();
+ let sender = route_promise(&promise, self, task_source);
+
let script_to_constellation_chan = global.script_to_constellation_chan();
if script_to_constellation_chan
.send(ScriptToConstellationMessage::ReportMemory(sender))
diff --git a/components/script/dom/servoparser/mod.rs b/components/script/dom/servoparser/mod.rs
index 0650fde676e..3a1efdfb291 100644
--- a/components/script/dom/servoparser/mod.rs
+++ b/components/script/dom/servoparser/mod.rs
@@ -21,6 +21,7 @@ use html5ever::{Attribute, ExpandedName, LocalName, QualName, local_name, ns};
use hyper_serde::Serde;
use markup5ever::TokenizerResult;
use mime::{self, Mime};
+use net_traits::policy_container::PolicyContainer;
use net_traits::request::RequestId;
use net_traits::{
FetchMetadata, FetchResponseListener, Metadata, NetworkError, ResourceFetchTiming,
@@ -356,16 +357,14 @@ impl ServoParser {
}
/// Steps 6-8 of <https://html.spec.whatwg.org/multipage/#document.write()>
- pub(crate) fn write(&self, text: Vec<DOMString>, can_gc: CanGc) {
+ pub(crate) fn write(&self, text: DOMString, can_gc: CanGc) {
assert!(self.can_write());
if self.document.has_pending_parsing_blocking_script() {
// There is already a pending parsing blocking script so the
// parser is suspended, we just append everything to the
// script input and abort these steps.
- for chunk in text {
- self.script_input.push_back(String::from(chunk).into());
- }
+ self.script_input.push_back(String::from(text).into());
return;
}
@@ -375,9 +374,7 @@ impl ServoParser {
assert!(self.script_input.is_empty());
let input = BufferQueue::default();
- for chunk in text {
- input.push_back(String::from(chunk).into());
- }
+ input.push_back(String::from(text).into());
let profiler_chan = self
.document
@@ -813,6 +810,27 @@ impl ParserContext {
pushed_entry_index: None,
}
}
+
+ pub(crate) fn append_parent_to_csp_list(&self, policy_container: Option<&PolicyContainer>) {
+ let Some(policy_container) = policy_container else {
+ return;
+ };
+ let Some(parent_csp_list) = &policy_container.csp_list else {
+ return;
+ };
+ let Some(parser) = self.parser.as_ref().map(|p| p.root()) else {
+ return;
+ };
+ let new_csp_list = match parser.document.get_csp_list() {
+ None => parent_csp_list.clone(),
+ Some(original_csp_list) => {
+ let mut appended_csp_list = original_csp_list.clone();
+ appended_csp_list.append(parent_csp_list.clone());
+ appended_csp_list.to_owned()
+ },
+ };
+ parser.document.set_csp_list(Some(new_csp_list));
+ }
}
impl FetchResponseListener for ParserContext {
diff --git a/components/script/dom/trustedhtml.rs b/components/script/dom/trustedhtml.rs
index 07298601f2f..8508f28c150 100644
--- a/components/script/dom/trustedhtml.rs
+++ b/components/script/dom/trustedhtml.rs
@@ -2,13 +2,19 @@
* 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::fmt;
+
use dom_struct::dom_struct;
use crate::dom::bindings::codegen::Bindings::TrustedHTMLBinding::TrustedHTMLMethods;
+use crate::dom::bindings::codegen::UnionTypes::TrustedHTMLOrString;
+use crate::dom::bindings::error::Fallible;
use crate::dom::bindings::reflector::{Reflector, reflect_dom_object};
use crate::dom::bindings::root::DomRoot;
use crate::dom::bindings::str::DOMString;
use crate::dom::globalscope::GlobalScope;
+use crate::dom::trustedtypepolicy::TrustedType;
+use crate::dom::trustedtypepolicyfactory::TrustedTypePolicyFactory;
use crate::script_runtime::CanGc;
#[dom_struct]
@@ -30,6 +36,37 @@ impl TrustedHTML {
pub(crate) fn new(data: String, global: &GlobalScope, can_gc: CanGc) -> DomRoot<Self> {
reflect_dom_object(Box::new(Self::new_inherited(data)), global, can_gc)
}
+
+ pub(crate) fn get_trusted_script_compliant_string(
+ global: &GlobalScope,
+ value: TrustedHTMLOrString,
+ containing_class: &str,
+ field: &str,
+ can_gc: CanGc,
+ ) -> Fallible<String> {
+ match value {
+ TrustedHTMLOrString::String(value) => {
+ let sink = format!("{} {}", containing_class, field);
+ TrustedTypePolicyFactory::get_trusted_type_compliant_string(
+ TrustedType::TrustedHTML,
+ global,
+ value.as_ref().to_owned(),
+ &sink,
+ "'script'",
+ can_gc,
+ )
+ },
+
+ TrustedHTMLOrString::TrustedHTML(trusted_html) => Ok(trusted_html.to_string()),
+ }
+ }
+}
+
+impl fmt::Display for TrustedHTML {
+ #[inline]
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ f.write_str(&self.data)
+ }
}
impl TrustedHTMLMethods<crate::DomTypeHolder> for TrustedHTML {
diff --git a/components/script/dom/trustedscript.rs b/components/script/dom/trustedscript.rs
index 5ce51c24989..648fcc8c239 100644
--- a/components/script/dom/trustedscript.rs
+++ b/components/script/dom/trustedscript.rs
@@ -1,14 +1,19 @@
/* 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 std::fmt;
use dom_struct::dom_struct;
use crate::dom::bindings::codegen::Bindings::TrustedScriptBinding::TrustedScriptMethods;
+use crate::dom::bindings::codegen::UnionTypes::TrustedScriptOrString;
+use crate::dom::bindings::error::Fallible;
use crate::dom::bindings::reflector::{Reflector, reflect_dom_object};
use crate::dom::bindings::root::DomRoot;
use crate::dom::bindings::str::DOMString;
use crate::dom::globalscope::GlobalScope;
+use crate::dom::trustedtypepolicy::TrustedType;
+use crate::dom::trustedtypepolicyfactory::TrustedTypePolicyFactory;
use crate::script_runtime::CanGc;
#[dom_struct]
@@ -30,6 +35,37 @@ impl TrustedScript {
pub(crate) fn new(data: String, global: &GlobalScope, can_gc: CanGc) -> DomRoot<Self> {
reflect_dom_object(Box::new(Self::new_inherited(data)), global, can_gc)
}
+
+ pub(crate) fn get_trusted_script_compliant_string(
+ global: &GlobalScope,
+ value: TrustedScriptOrString,
+ containing_class: &str,
+ field: &str,
+ can_gc: CanGc,
+ ) -> Fallible<String> {
+ match value {
+ TrustedScriptOrString::String(value) => {
+ let sink = format!("{} {}", containing_class, field);
+ TrustedTypePolicyFactory::get_trusted_type_compliant_string(
+ TrustedType::TrustedScript,
+ global,
+ value.as_ref().to_owned(),
+ &sink,
+ "'script'",
+ can_gc,
+ )
+ },
+
+ TrustedScriptOrString::TrustedScript(trusted_script) => Ok(trusted_script.to_string()),
+ }
+ }
+}
+
+impl fmt::Display for TrustedScript {
+ #[inline]
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ f.write_str(&self.data)
+ }
}
impl TrustedScriptMethods<crate::DomTypeHolder> for TrustedScript {
diff --git a/components/script/dom/trustedscripturl.rs b/components/script/dom/trustedscripturl.rs
index ba1e0335abc..3f0aef248b3 100644
--- a/components/script/dom/trustedscripturl.rs
+++ b/components/script/dom/trustedscripturl.rs
@@ -7,10 +7,14 @@ use std::fmt;
use dom_struct::dom_struct;
use crate::dom::bindings::codegen::Bindings::TrustedScriptURLBinding::TrustedScriptURLMethods;
+use crate::dom::bindings::codegen::UnionTypes::TrustedScriptURLOrUSVString;
+use crate::dom::bindings::error::Fallible;
use crate::dom::bindings::reflector::{Reflector, reflect_dom_object};
use crate::dom::bindings::root::DomRoot;
use crate::dom::bindings::str::DOMString;
use crate::dom::globalscope::GlobalScope;
+use crate::dom::trustedtypepolicy::TrustedType;
+use crate::dom::trustedtypepolicyfactory::TrustedTypePolicyFactory;
use crate::script_runtime::CanGc;
#[dom_struct]
@@ -32,6 +36,31 @@ impl TrustedScriptURL {
pub(crate) fn new(data: String, global: &GlobalScope, can_gc: CanGc) -> DomRoot<Self> {
reflect_dom_object(Box::new(Self::new_inherited(data)), global, can_gc)
}
+
+ pub(crate) fn get_trusted_script_url_compliant_string(
+ global: &GlobalScope,
+ value: TrustedScriptURLOrUSVString,
+ containing_class: &str,
+ field: &str,
+ can_gc: CanGc,
+ ) -> Fallible<String> {
+ match value {
+ TrustedScriptURLOrUSVString::USVString(value) => {
+ let sink = format!("{} {}", containing_class, field);
+ TrustedTypePolicyFactory::get_trusted_type_compliant_string(
+ TrustedType::TrustedScriptURL,
+ global,
+ value.as_ref().to_owned(),
+ &sink,
+ "'script'",
+ can_gc,
+ )
+ },
+ TrustedScriptURLOrUSVString::TrustedScriptURL(trusted_script_url) => {
+ Ok(trusted_script_url.to_string())
+ },
+ }
+ }
}
impl fmt::Display for TrustedScriptURL {
diff --git a/components/script/dom/trustedtypepolicy.rs b/components/script/dom/trustedtypepolicy.rs
index 2ec5015eb88..d4def7269ed 100644
--- a/components/script/dom/trustedtypepolicy.rs
+++ b/components/script/dom/trustedtypepolicy.rs
@@ -7,6 +7,7 @@ use std::rc::Rc;
use dom_struct::dom_struct;
use js::jsapi::JSObject;
use js::rust::HandleValue;
+use strum_macros::IntoStaticStr;
use crate::dom::bindings::callback::ExceptionHandling;
use crate::dom::bindings::codegen::Bindings::TrustedTypePolicyBinding::TrustedTypePolicyMethods;
@@ -38,6 +39,13 @@ pub struct TrustedTypePolicy {
create_script_url: Option<Rc<CreateScriptURLCallback>>,
}
+#[derive(Clone, IntoStaticStr)]
+pub(crate) enum TrustedType {
+ TrustedHTML,
+ TrustedScript,
+ TrustedScriptURL,
+}
+
impl TrustedTypePolicy {
fn new_inherited(name: String, options: &TrustedTypePolicyOptions) -> Self {
Self {
@@ -59,51 +67,87 @@ impl TrustedTypePolicy {
reflect_dom_object(Box::new(Self::new_inherited(name, options)), global, can_gc)
}
- // TODO(36258): Remove when we refactor get_trusted_type_policy_value to take an enum
- // value to handle which callback to call. The callback should not be exposed outside
- // of the policy object, but is currently used in TrustedPolicyFactory::process_value_with_default_policy
- pub(crate) fn create_script_url(&self) -> Option<Rc<CreateScriptURLCallback>> {
- self.create_script_url.clone()
+ /// <https://w3c.github.io/trusted-types/dist/spec/#get-trusted-type-policy-value-algorithm>
+ fn check_callback_if_missing(throw_if_missing: bool) -> Fallible<Option<String>> {
+ // Step 3.1: If throwIfMissing throw a TypeError.
+ if throw_if_missing {
+ Err(Type("Cannot find type".to_owned()))
+ } else {
+ // Step 3.2: Else return null.
+ Ok(None)
+ }
}
- /// This does not take all arguments as specified. That's because the return type of the
- /// trusted type function and object are not the same. 2 of the 3 string callbacks return
- /// a DOMString, while the other one returns an USVString. Additionally, all three callbacks
- /// have a unique type signature in WebIDL.
- ///
- /// To circumvent these type problems, rather than implementing the full functionality here,
- /// part of the algorithm is implemented on the caller side. There, we only call the callback
- /// and create the object. The rest of the machinery is ensuring the right values pass through
- /// to the relevant callbacks.
- ///
/// <https://w3c.github.io/trusted-types/dist/spec/#get-trusted-type-policy-value-algorithm>
- pub(crate) fn get_trusted_type_policy_value<S, PolicyCallback>(
+ pub(crate) fn get_trusted_type_policy_value(
&self,
- policy_value_callback: PolicyCallback,
+ expected_type: TrustedType,
+ cx: JSContext,
+ input: DOMString,
+ arguments: Vec<HandleValue>,
throw_if_missing: bool,
- ) -> Fallible<Option<S>>
- where
- S: AsRef<str>,
- PolicyCallback: FnOnce() -> Option<Fallible<Option<S>>>,
- {
+ can_gc: CanGc,
+ ) -> Fallible<Option<String>> {
+ rooted!(in(*cx) let this_object: *mut JSObject);
// Step 1: Let functionName be a function name for the given trustedTypeName, based on the following table:
- // Step 2: Let function be policy’s options[functionName].
- let function = policy_value_callback();
- match function {
- // Step 3: If function is null, then:
- None => {
- // Step 3.1: If throwIfMissing throw a TypeError.
- if throw_if_missing {
- Err(Type("Cannot find type".to_owned()))
- } else {
- // Step 3.2: Else return null.
- Ok(None)
- }
+ match expected_type {
+ TrustedType::TrustedHTML => match &self.create_html {
+ // Step 3: If function is null, then:
+ None => TrustedTypePolicy::check_callback_if_missing(throw_if_missing),
+ // Step 2: Let function be policy’s options[functionName].
+ Some(callback) => {
+ // Step 4: Let policyValue be the result of invoking function with value as a first argument,
+ // items of arguments as subsequent arguments, and callback **this** value set to null,
+ // rethrowing any exceptions.
+ callback
+ .Call_(
+ &this_object.handle(),
+ input,
+ arguments,
+ ExceptionHandling::Rethrow,
+ can_gc,
+ )
+ .map(|result| result.map(|str| str.as_ref().to_owned()))
+ },
+ },
+ TrustedType::TrustedScript => match &self.create_script {
+ // Step 3: If function is null, then:
+ None => TrustedTypePolicy::check_callback_if_missing(throw_if_missing),
+ // Step 2: Let function be policy’s options[functionName].
+ Some(callback) => {
+ // Step 4: Let policyValue be the result of invoking function with value as a first argument,
+ // items of arguments as subsequent arguments, and callback **this** value set to null,
+ // rethrowing any exceptions.
+ callback
+ .Call_(
+ &this_object.handle(),
+ input,
+ arguments,
+ ExceptionHandling::Rethrow,
+ can_gc,
+ )
+ .map(|result| result.map(|str| str.as_ref().to_owned()))
+ },
+ },
+ TrustedType::TrustedScriptURL => match &self.create_script_url {
+ // Step 3: If function is null, then:
+ None => TrustedTypePolicy::check_callback_if_missing(throw_if_missing),
+ // Step 2: Let function be policy’s options[functionName].
+ Some(callback) => {
+ // Step 4: Let policyValue be the result of invoking function with value as a first argument,
+ // items of arguments as subsequent arguments, and callback **this** value set to null,
+ // rethrowing any exceptions.
+ callback
+ .Call_(
+ &this_object.handle(),
+ input,
+ arguments,
+ ExceptionHandling::Rethrow,
+ can_gc,
+ )
+ .map(|result| result.map(|str| str.as_ref().to_owned()))
+ },
},
- // Step 4: Let policyValue be the result of invoking function with value as a first argument,
- // items of arguments as subsequent arguments, and callback **this** value set to null,
- // rethrowing any exceptions.
- Some(policy_value) => policy_value,
}
}
@@ -118,27 +162,30 @@ impl TrustedTypePolicy {
/// to the relevant callbacks.
///
/// <https://w3c.github.io/trusted-types/dist/spec/#create-a-trusted-type-algorithm>
- pub(crate) fn create_trusted_type<R, S, PolicyCallback, TrustedTypeCallback>(
+ pub(crate) fn create_trusted_type<R, TrustedTypeCallback>(
&self,
- policy_value_callback: PolicyCallback,
+ expected_type: TrustedType,
+ cx: JSContext,
+ input: DOMString,
+ arguments: Vec<HandleValue>,
trusted_type_creation_callback: TrustedTypeCallback,
+ can_gc: CanGc,
) -> Fallible<DomRoot<R>>
where
R: DomObject,
- S: AsRef<str>,
- PolicyCallback: FnOnce() -> Option<Fallible<Option<S>>>,
TrustedTypeCallback: FnOnce(String) -> DomRoot<R>,
{
// Step 1: Let policyValue be the result of executing Get Trusted Type policy value
// with the same arguments as this algorithm and additionally true as throwIfMissing.
- let policy_value = self.get_trusted_type_policy_value(policy_value_callback, true);
+ let policy_value =
+ self.get_trusted_type_policy_value(expected_type, cx, input, arguments, true, can_gc);
match policy_value {
// Step 2: If the algorithm threw an error, rethrow the error and abort the following steps.
Err(error) => Err(error),
Ok(policy_value) => {
// Step 3: Let dataString be the result of stringifying policyValue.
let data_string = match policy_value {
- Some(value) => value.as_ref().into(),
+ Some(value) => value,
// Step 4: If policyValue is null or undefined, set dataString to the empty string.
None => "".to_owned(),
};
@@ -164,22 +211,12 @@ impl TrustedTypePolicyMethods<crate::DomTypeHolder> for TrustedTypePolicy {
can_gc: CanGc,
) -> Fallible<DomRoot<TrustedHTML>> {
self.create_trusted_type(
- || {
- self.create_html.clone().map(|callback| {
- rooted!(in(*cx) let this_object: *mut JSObject);
- // Step 4: Let policyValue be the result of invoking function with value as a first argument,
- // items of arguments as subsequent arguments, and callback **this** value set to null,
- // rethrowing any exceptions.
- callback.Call_(
- &this_object.handle(),
- input,
- arguments,
- ExceptionHandling::Rethrow,
- can_gc,
- )
- })
- },
+ TrustedType::TrustedHTML,
+ cx,
+ input,
+ arguments,
|data_string| TrustedHTML::new(data_string, &self.global(), can_gc),
+ can_gc,
)
}
/// <https://www.w3.org/TR/trusted-types/#dom-trustedtypepolicy-createscript>
@@ -191,22 +228,12 @@ impl TrustedTypePolicyMethods<crate::DomTypeHolder> for TrustedTypePolicy {
can_gc: CanGc,
) -> Fallible<DomRoot<TrustedScript>> {
self.create_trusted_type(
- || {
- self.create_script.clone().map(|callback| {
- rooted!(in(*cx) let this_object: *mut JSObject);
- // Step 4: Let policyValue be the result of invoking function with value as a first argument,
- // items of arguments as subsequent arguments, and callback **this** value set to null,
- // rethrowing any exceptions.
- callback.Call_(
- &this_object.handle(),
- input,
- arguments,
- ExceptionHandling::Rethrow,
- can_gc,
- )
- })
- },
+ TrustedType::TrustedScript,
+ cx,
+ input,
+ arguments,
|data_string| TrustedScript::new(data_string, &self.global(), can_gc),
+ can_gc,
)
}
/// <https://www.w3.org/TR/trusted-types/#dom-trustedtypepolicy-createscripturl>
@@ -218,22 +245,12 @@ impl TrustedTypePolicyMethods<crate::DomTypeHolder> for TrustedTypePolicy {
can_gc: CanGc,
) -> Fallible<DomRoot<TrustedScriptURL>> {
self.create_trusted_type(
- || {
- self.create_script_url.clone().map(|callback| {
- rooted!(in(*cx) let this_object: *mut JSObject);
- // Step 4: Let policyValue be the result of invoking function with value as a first argument,
- // items of arguments as subsequent arguments, and callback **this** value set to null,
- // rethrowing any exceptions.
- callback.Call_(
- &this_object.handle(),
- input,
- arguments,
- ExceptionHandling::Rethrow,
- can_gc,
- )
- })
- },
+ TrustedType::TrustedScriptURL,
+ cx,
+ input,
+ arguments,
|data_string| TrustedScriptURL::new(data_string, &self.global(), can_gc),
+ can_gc,
)
}
}
diff --git a/components/script/dom/trustedtypepolicyfactory.rs b/components/script/dom/trustedtypepolicyfactory.rs
index 0dcc78b7cd0..0927446b904 100644
--- a/components/script/dom/trustedtypepolicyfactory.rs
+++ b/components/script/dom/trustedtypepolicyfactory.rs
@@ -6,11 +6,9 @@ use std::cell::RefCell;
use content_security_policy::CheckResult;
use dom_struct::dom_struct;
use html5ever::{LocalName, Namespace, QualName, local_name, ns};
-use js::jsapi::JSObject;
use js::jsval::NullValue;
use js::rust::HandleValue;
-use crate::dom::bindings::callback::ExceptionHandling;
use crate::dom::bindings::codegen::Bindings::TrustedTypePolicyFactoryBinding::{
TrustedTypePolicyFactoryMethods, TrustedTypePolicyOptions,
};
@@ -23,7 +21,7 @@ use crate::dom::globalscope::GlobalScope;
use crate::dom::trustedhtml::TrustedHTML;
use crate::dom::trustedscript::TrustedScript;
use crate::dom::trustedscripturl::TrustedScriptURL;
-use crate::dom::trustedtypepolicy::TrustedTypePolicy;
+use crate::dom::trustedtypepolicy::{TrustedType, TrustedTypePolicy};
use crate::js::conversions::ToJSValConvertible;
use crate::script_runtime::{CanGc, JSContext};
@@ -144,50 +142,40 @@ impl TrustedTypePolicyFactory {
/// <https://w3c.github.io/trusted-types/dist/spec/#process-value-with-a-default-policy-algorithm>
#[allow(unsafe_code)]
pub(crate) fn process_value_with_default_policy(
+ expected_type: TrustedType,
global: &GlobalScope,
input: String,
sink: &str,
can_gc: CanGc,
- ) -> Fallible<Option<DomRoot<TrustedScriptURL>>> {
+ ) -> Fallible<Option<String>> {
// Step 1: Let defaultPolicy be the value of global’s trusted type policy factory's default policy.
let global_policy_factory = global.trusted_types(can_gc);
let default_policy = match global_policy_factory.default_policy.get() {
- None => return Ok(Some(TrustedScriptURL::new(input, global, can_gc))),
+ None => return Ok(None),
Some(default_policy) => default_policy,
};
let cx = GlobalScope::get_cx();
// Step 2: Let policyValue be the result of executing Get Trusted Type policy value,
// with the following arguments:
- let policy_value = default_policy.get_trusted_type_policy_value(
- || {
- // TODO(36258): support other trusted types as well by changing get_trusted_type_policy_value to accept
- // the trusted type as enum and call the appropriate callback based on that.
- default_policy.create_script_url().map(|callback| {
- rooted!(in(*cx) let this_object: *mut JSObject);
- rooted!(in(*cx) let mut trusted_type_name_value = NullValue());
- unsafe {
- "TrustedScriptURL".to_jsval(*cx, trusted_type_name_value.handle_mut());
- }
+ rooted!(in(*cx) let mut trusted_type_name_value = NullValue());
+ unsafe {
+ let trusted_type_name: &'static str = expected_type.clone().into();
+ trusted_type_name.to_jsval(*cx, trusted_type_name_value.handle_mut());
+ }
- rooted!(in(*cx) let mut sink_value = NullValue());
- unsafe {
- sink.to_jsval(*cx, sink_value.handle_mut());
- }
+ rooted!(in(*cx) let mut sink_value = NullValue());
+ unsafe {
+ sink.to_jsval(*cx, sink_value.handle_mut());
+ }
- let args = vec![trusted_type_name_value.handle(), sink_value.handle()];
- // Step 4: Let policyValue be the result of invoking function with value as a first argument,
- // items of arguments as subsequent arguments, and callback **this** value set to null,
- // rethrowing any exceptions.
- callback.Call_(
- &this_object.handle(),
- DOMString::from(input.to_owned()),
- args,
- ExceptionHandling::Rethrow,
- can_gc,
- )
- })
- },
+ let arguments = vec![trusted_type_name_value.handle(), sink_value.handle()];
+ let policy_value = default_policy.get_trusted_type_policy_value(
+ expected_type,
+ cx,
+ DOMString::from(input.to_owned()),
+ arguments,
false,
+ can_gc,
);
let data_string = match policy_value {
// Step 3: If the algorithm threw an error, rethrow the error and abort the following steps.
@@ -196,14 +184,15 @@ impl TrustedTypePolicyFactory {
// Step 4: If policyValue is null or undefined, return policyValue.
None => return Ok(None),
// Step 5: Let dataString be the result of stringifying policyValue.
- Some(policy_value) => policy_value.as_ref().into(),
+ Some(policy_value) => policy_value,
},
};
- Ok(Some(TrustedScriptURL::new(data_string, global, can_gc)))
+ Ok(Some(data_string))
}
/// Step 1 is implemented by the caller
/// <https://w3c.github.io/trusted-types/dist/spec/#get-trusted-type-compliant-string-algorithm>
pub(crate) fn get_trusted_type_compliant_string(
+ expected_type: TrustedType,
global: &GlobalScope,
input: String,
sink: &str,
@@ -224,6 +213,7 @@ impl TrustedTypePolicyFactory {
// Step 4: Let convertedInput be the result of executing Process value with a default policy
// with the same arguments as this algorithm.
let converted_input = TrustedTypePolicyFactory::process_value_with_default_policy(
+ expected_type,
global,
input.clone(),
sink,
@@ -252,7 +242,7 @@ impl TrustedTypePolicyFactory {
}
},
// Step 8: Return stringified convertedInput.
- Some(converted_input) => Ok((*converted_input).to_string()),
+ Some(converted_input) => Ok(converted_input),
}
// Step 7: Assert: convertedInput is an instance of expectedType.
// TODO(https://github.com/w3c/trusted-types/issues/566): Implement when spec is resolved
diff --git a/components/script/dom/webgpu/gpu.rs b/components/script/dom/webgpu/gpu.rs
index f02ae386772..20380e07bfb 100644
--- a/components/script/dom/webgpu/gpu.rs
+++ b/components/script/dom/webgpu/gpu.rs
@@ -56,7 +56,9 @@ impl GPUMethods<crate::DomTypeHolder> for GPU {
) -> Rc<Promise> {
let global = &self.global();
let promise = Promise::new_in_current_realm(comp, can_gc);
- let sender = route_promise(&promise, self);
+ let task_source = global.task_manager().dom_manipulation_task_source();
+ let sender = route_promise(&promise, self, task_source);
+
let power_preference = match options.powerPreference {
Some(GPUPowerPreference::Low_power) => PowerPreference::LowPower,
Some(GPUPowerPreference::High_performance) => PowerPreference::HighPerformance,
diff --git a/components/script/dom/webgpu/gpuadapter.rs b/components/script/dom/webgpu/gpuadapter.rs
index 16d5dfed4a2..e22eca173ca 100644
--- a/components/script/dom/webgpu/gpuadapter.rs
+++ b/components/script/dom/webgpu/gpuadapter.rs
@@ -117,7 +117,11 @@ impl GPUAdapterMethods<crate::DomTypeHolder> for GPUAdapter {
) -> Rc<Promise> {
// Step 2
let promise = Promise::new_in_current_realm(comp, can_gc);
- let sender = route_promise(&promise, self);
+ let sender = route_promise(
+ &promise,
+ self,
+ self.global().task_manager().dom_manipulation_task_source(),
+ );
let mut required_features = wgpu_types::Features::empty();
for &ext in descriptor.requiredFeatures.iter() {
if let Some(feature) = gpu_to_wgt_feature(ext) {
diff --git a/components/script/dom/webgpu/gpubuffer.rs b/components/script/dom/webgpu/gpubuffer.rs
index e8d5b8a16dd..0b41d386b4a 100644
--- a/components/script/dom/webgpu/gpubuffer.rs
+++ b/components/script/dom/webgpu/gpubuffer.rs
@@ -271,7 +271,11 @@ impl GPUBufferMethods<crate::DomTypeHolder> for GPUBuffer {
},
};
- let sender = route_promise(&promise, self);
+ let sender = route_promise(
+ &promise,
+ self,
+ self.global().task_manager().dom_manipulation_task_source(),
+ );
if let Err(e) = self.channel.0.send(WebGPURequest::BufferMapAsync {
sender,
buffer_id: self.buffer.0,
diff --git a/components/script/dom/webgpu/gpudevice.rs b/components/script/dom/webgpu/gpudevice.rs
index 17b4425275e..9fa9f044daa 100644
--- a/components/script/dom/webgpu/gpudevice.rs
+++ b/components/script/dom/webgpu/gpudevice.rs
@@ -470,7 +470,11 @@ impl GPUDeviceMethods<crate::DomTypeHolder> for GPUDevice {
can_gc: CanGc,
) -> Rc<Promise> {
let promise = Promise::new_in_current_realm(comp, can_gc);
- let sender = route_promise(&promise, self);
+ let sender = route_promise(
+ &promise,
+ self,
+ self.global().task_manager().dom_manipulation_task_source(),
+ );
GPUComputePipeline::create(self, descriptor, Some(sender));
promise
}
@@ -518,7 +522,11 @@ impl GPUDeviceMethods<crate::DomTypeHolder> for GPUDevice {
) -> Fallible<Rc<Promise>> {
let (implicit_ids, desc) = self.parse_render_pipeline(descriptor)?;
let promise = Promise::new_in_current_realm(comp, can_gc);
- let sender = route_promise(&promise, self);
+ let sender = route_promise(
+ &promise,
+ self,
+ self.global().task_manager().dom_manipulation_task_source(),
+ );
GPURenderPipeline::create(self, implicit_ids, desc, Some(sender))?;
Ok(promise)
}
@@ -549,7 +557,11 @@ impl GPUDeviceMethods<crate::DomTypeHolder> for GPUDevice {
/// <https://gpuweb.github.io/gpuweb/#dom-gpudevice-poperrorscope>
fn PopErrorScope(&self, comp: InRealm, can_gc: CanGc) -> Rc<Promise> {
let promise = Promise::new_in_current_realm(comp, can_gc);
- let sender = route_promise(&promise, self);
+ let sender = route_promise(
+ &promise,
+ self,
+ self.global().task_manager().dom_manipulation_task_source(),
+ );
if self
.channel
.0
diff --git a/components/script/dom/webgpu/gpuqueue.rs b/components/script/dom/webgpu/gpuqueue.rs
index bdcb2c53782..535e315e8c0 100644
--- a/components/script/dom/webgpu/gpuqueue.rs
+++ b/components/script/dom/webgpu/gpuqueue.rs
@@ -200,7 +200,9 @@ impl GPUQueueMethods<crate::DomTypeHolder> for GPUQueue {
fn OnSubmittedWorkDone(&self, can_gc: CanGc) -> Rc<Promise> {
let global = self.global();
let promise = Promise::new(&global, can_gc);
- let sender = route_promise(&promise, self);
+ let task_source = global.task_manager().dom_manipulation_task_source();
+ let sender = route_promise(&promise, self, task_source);
+
if let Err(e) = self
.channel
.0
diff --git a/components/script/dom/webgpu/gpushadermodule.rs b/components/script/dom/webgpu/gpushadermodule.rs
index fd9e65788c8..79d1325cf0f 100644
--- a/components/script/dom/webgpu/gpushadermodule.rs
+++ b/components/script/dom/webgpu/gpushadermodule.rs
@@ -95,7 +95,14 @@ impl GPUShaderModule {
promise.clone(),
can_gc,
);
- let sender = route_promise(&promise, &*shader_module);
+ let sender = route_promise(
+ &promise,
+ &*shader_module,
+ device
+ .global()
+ .task_manager()
+ .dom_manipulation_task_source(),
+ );
device
.channel()
.0
diff --git a/components/script/dom/webxr/xrhittestsource.rs b/components/script/dom/webxr/xrhittestsource.rs
index 0ec9560db6e..f73f8f79655 100644
--- a/components/script/dom/webxr/xrhittestsource.rs
+++ b/components/script/dom/webxr/xrhittestsource.rs
@@ -8,7 +8,7 @@ use webxr_api::HitTestId;
use crate::dom::bindings::codegen::Bindings::XRHitTestSourceBinding::XRHitTestSourceMethods;
use crate::dom::bindings::reflector::{Reflector, reflect_dom_object};
use crate::dom::bindings::root::{Dom, DomRoot};
-use crate::dom::globalscope::GlobalScope;
+use crate::dom::window::Window;
use crate::dom::xrsession::XRSession;
use crate::script_runtime::CanGc;
@@ -31,14 +31,14 @@ impl XRHitTestSource {
}
pub(crate) fn new(
- global: &GlobalScope,
+ window: &Window,
id: HitTestId,
session: &XRSession,
can_gc: CanGc,
) -> DomRoot<XRHitTestSource> {
reflect_dom_object(
Box::new(XRHitTestSource::new_inherited(id, session)),
- global,
+ window,
can_gc,
)
}
diff --git a/components/script/dom/webxr/xrinputsource.rs b/components/script/dom/webxr/xrinputsource.rs
index 009b210646a..e454e785424 100644
--- a/components/script/dom/webxr/xrinputsource.rs
+++ b/components/script/dom/webxr/xrinputsource.rs
@@ -17,6 +17,7 @@ use crate::dom::bindings::reflector::{DomGlobal, Reflector, reflect_dom_object};
use crate::dom::bindings::root::{Dom, DomRoot, MutNullableDom};
use crate::dom::gamepad::Gamepad;
use crate::dom::globalscope::GlobalScope;
+use crate::dom::window::Window;
use crate::dom::xrhand::XRHand;
use crate::dom::xrsession::XRSession;
use crate::dom::xrspace::XRSpace;
@@ -40,14 +41,14 @@ pub(crate) struct XRInputSource {
impl XRInputSource {
pub(crate) fn new_inherited(
- global: &GlobalScope,
+ window: &Window,
session: &XRSession,
info: InputSource,
can_gc: CanGc,
) -> XRInputSource {
// <https://www.w3.org/TR/webxr-gamepads-module-1/#gamepad-differences>
let gamepad = Gamepad::new(
- global,
+ window,
0,
"".into(),
"xr-standard".into(),
@@ -74,18 +75,18 @@ impl XRInputSource {
#[allow(unsafe_code)]
pub(crate) fn new(
- global: &GlobalScope,
+ window: &Window,
session: &XRSession,
info: InputSource,
can_gc: CanGc,
) -> DomRoot<XRInputSource> {
let source = reflect_dom_object(
- Box::new(XRInputSource::new_inherited(global, session, info, can_gc)),
- global,
+ Box::new(XRInputSource::new_inherited(window, session, info, can_gc)),
+ window,
can_gc,
);
- let _ac = enter_realm(global);
+ let _ac = enter_realm(window);
let cx = GlobalScope::get_cx();
unsafe {
rooted!(in(*cx) let mut profiles = UndefinedValue());
diff --git a/components/script/dom/webxr/xrinputsourcearray.rs b/components/script/dom/webxr/xrinputsourcearray.rs
index d7dcdfcbb6d..26a2c42f598 100644
--- a/components/script/dom/webxr/xrinputsourcearray.rs
+++ b/components/script/dom/webxr/xrinputsourcearray.rs
@@ -11,7 +11,7 @@ use crate::dom::bindings::inheritance::Castable;
use crate::dom::bindings::reflector::{DomGlobal, Reflector, reflect_dom_object};
use crate::dom::bindings::root::{Dom, DomRoot};
use crate::dom::event::Event;
-use crate::dom::globalscope::GlobalScope;
+use crate::dom::window::Window;
use crate::dom::xrinputsource::XRInputSource;
use crate::dom::xrinputsourceschangeevent::XRInputSourcesChangeEvent;
use crate::dom::xrsession::XRSession;
@@ -31,10 +31,10 @@ impl XRInputSourceArray {
}
}
- pub(crate) fn new(global: &GlobalScope, can_gc: CanGc) -> DomRoot<XRInputSourceArray> {
+ pub(crate) fn new(window: &Window, can_gc: CanGc) -> DomRoot<XRInputSourceArray> {
reflect_dom_object(
Box::new(XRInputSourceArray::new_inherited()),
- global,
+ window,
can_gc,
)
}
@@ -60,7 +60,7 @@ impl XRInputSourceArray {
.any(|i| i.id() == info.id),
"Should never add a duplicate input id!"
);
- let input = XRInputSource::new(&global, session, info.clone(), can_gc);
+ let input = XRInputSource::new(window, session, info.clone(), can_gc);
self.input_sources.borrow_mut().push(Dom::from_ref(&input));
added.push(input);
}
@@ -121,7 +121,7 @@ impl XRInputSourceArray {
&[]
};
self.input_sources.borrow_mut().retain(|i| i.id() != id);
- let input = XRInputSource::new(&global, session, info, can_gc);
+ let input = XRInputSource::new(window, session, info, can_gc);
self.input_sources.borrow_mut().push(Dom::from_ref(&input));
let added = [input];
diff --git a/components/script/dom/webxr/xrrenderstate.rs b/components/script/dom/webxr/xrrenderstate.rs
index 3f546c2353d..d114020e16e 100644
--- a/components/script/dom/webxr/xrrenderstate.rs
+++ b/components/script/dom/webxr/xrrenderstate.rs
@@ -14,7 +14,7 @@ use crate::dom::bindings::num::Finite;
use crate::dom::bindings::reflector::{DomGlobal, Reflector, reflect_dom_object};
use crate::dom::bindings::root::{Dom, DomRoot, MutNullableDom};
use crate::dom::bindings::utils::to_frozen_array;
-use crate::dom::globalscope::GlobalScope;
+use crate::dom::window::Window;
use crate::dom::xrlayer::XRLayer;
use crate::dom::xrwebgllayer::XRWebGLLayer;
use crate::script_runtime::{CanGc, JSContext};
@@ -49,7 +49,7 @@ impl XRRenderState {
}
pub(crate) fn new(
- global: &GlobalScope,
+ window: &Window,
depth_near: f64,
depth_far: f64,
inline_vertical_fov: Option<f64>,
@@ -65,14 +65,14 @@ impl XRRenderState {
layer,
layers,
)),
- global,
+ window,
can_gc,
)
}
pub(crate) fn clone_object(&self) -> DomRoot<Self> {
XRRenderState::new(
- &self.global(),
+ self.global().as_window(),
self.depth_near.get(),
self.depth_far.get(),
self.inline_vertical_fov.get(),
diff --git a/components/script/dom/webxr/xrsession.rs b/components/script/dom/webxr/xrsession.rs
index a171a769b71..6ead8f65445 100644
--- a/components/script/dom/webxr/xrsession.rs
+++ b/components/script/dom/webxr/xrsession.rs
@@ -54,8 +54,8 @@ use crate::dom::bindings::root::{Dom, DomRoot, MutDom, MutNullableDom};
use crate::dom::bindings::utils::to_frozen_array;
use crate::dom::event::Event;
use crate::dom::eventtarget::EventTarget;
-use crate::dom::globalscope::GlobalScope;
use crate::dom::promise::Promise;
+use crate::dom::window::Window;
use crate::dom::xrboundedreferencespace::XRBoundedReferenceSpace;
use crate::dom::xrframe::XRFrame;
use crate::dom::xrhittestsource::XRHitTestSource;
@@ -152,7 +152,7 @@ impl XRSession {
}
pub(crate) fn new(
- global: &GlobalScope,
+ window: &Window,
session: Session,
mode: XRSessionMode,
frame_receiver: IpcReceiver<Frame>,
@@ -163,8 +163,8 @@ impl XRSession {
} else {
None
};
- let render_state = XRRenderState::new(global, 0.1, 1000.0, ivfov, None, Vec::new(), can_gc);
- let input_sources = XRInputSourceArray::new(global, can_gc);
+ let render_state = XRRenderState::new(window, 0.1, 1000.0, ivfov, None, Vec::new(), can_gc);
+ let input_sources = XRInputSourceArray::new(window, can_gc);
let ret = reflect_dom_object(
Box::new(XRSession::new_inherited(
session,
@@ -172,7 +172,7 @@ impl XRSession {
&input_sources,
mode,
)),
- global,
+ window,
can_gc,
);
ret.attach_event_handler();
@@ -587,7 +587,7 @@ impl XRSession {
FrameUpdateEvent::HitTestSourceAdded(id) => {
if let Some(promise) = self.pending_hit_test_promises.borrow_mut().remove(&id) {
promise.resolve_native(
- &XRHitTestSource::new(&self.global(), id, self, can_gc),
+ &XRHitTestSource::new(self.global().as_window(), id, self, can_gc),
can_gc,
);
} else {
diff --git a/components/script/dom/webxr/xrsystem.rs b/components/script/dom/webxr/xrsystem.rs
index eabe7a72119..9963d92fa59 100644
--- a/components/script/dom/webxr/xrsystem.rs
+++ b/components/script/dom/webxr/xrsystem.rs
@@ -297,7 +297,13 @@ impl XRSystem {
return;
},
};
- let session = XRSession::new(&self.global(), session, mode, frame_receiver, CanGc::note());
+ let session = XRSession::new(
+ self.global().as_window(),
+ session,
+ mode,
+ frame_receiver,
+ CanGc::note(),
+ );
if mode == XRSessionMode::Inline {
self.active_inline_sessions
.borrow_mut()
diff --git a/components/script/dom/window.rs b/components/script/dom/window.rs
index 90782e217b7..b115add8611 100644
--- a/components/script/dom/window.rs
+++ b/components/script/dom/window.rs
@@ -32,8 +32,9 @@ use devtools_traits::{ScriptToDevtoolsControlMsg, TimelineMarker, TimelineMarker
use dom_struct::dom_struct;
use embedder_traits::user_content_manager::{UserContentManager, UserScript};
use embedder_traits::{
- AlertResponse, ConfirmResponse, EmbedderMsg, PromptResponse, SimpleDialog, Theme,
- ViewportDetails, WebDriverJSError, WebDriverJSResult,
+ AlertResponse, ConfirmResponse, EmbedderMsg, GamepadEvent, GamepadSupportedHapticEffects,
+ GamepadUpdateType, PromptResponse, SimpleDialog, Theme, ViewportDetails, WebDriverJSError,
+ WebDriverJSResult,
};
use euclid::default::{Point2D as UntypedPoint2D, Rect as UntypedRect};
use euclid::{Point2D, Rect, Scale, Size2D, Vector2D};
@@ -61,6 +62,8 @@ use num_traits::ToPrimitive;
use profile_traits::ipc as ProfiledIpc;
use profile_traits::mem::ProfilerChan as MemProfilerChan;
use profile_traits::time::ProfilerChan as TimeProfilerChan;
+use script_bindings::codegen::GenericBindings::NavigatorBinding::NavigatorMethods;
+use script_bindings::codegen::GenericBindings::PerformanceBinding::PerformanceMethods;
use script_bindings::interfaces::WindowHelpers;
use script_layout_interface::{
FragmentType, Layout, PendingImageState, QueryMsg, Reflow, ReflowGoal, ReflowRequest,
@@ -125,6 +128,8 @@ use crate::dom::document::{AnimationFrameCallback, Document, ReflowTriggerCondit
use crate::dom::element::Element;
use crate::dom::event::{Event, EventBubbles, EventCancelable, EventStatus};
use crate::dom::eventtarget::EventTarget;
+use crate::dom::gamepad::{Gamepad, contains_user_gesture};
+use crate::dom::gamepadevent::GamepadEventType;
use crate::dom::globalscope::GlobalScope;
use crate::dom::hashchangeevent::HashChangeEvent;
use crate::dom::history::History;
@@ -642,6 +647,126 @@ impl Window {
pub(crate) fn font_context(&self) -> &Arc<FontContext> {
&self.font_context
}
+
+ pub(crate) fn handle_gamepad_event(&self, gamepad_event: GamepadEvent) {
+ match gamepad_event {
+ GamepadEvent::Connected(index, name, bounds, supported_haptic_effects) => {
+ self.handle_gamepad_connect(
+ index.0,
+ name,
+ bounds.axis_bounds,
+ bounds.button_bounds,
+ supported_haptic_effects,
+ );
+ },
+ GamepadEvent::Disconnected(index) => {
+ self.handle_gamepad_disconnect(index.0);
+ },
+ GamepadEvent::Updated(index, update_type) => {
+ self.receive_new_gamepad_button_or_axis(index.0, update_type);
+ },
+ };
+ }
+
+ /// <https://www.w3.org/TR/gamepad/#dfn-gamepadconnected>
+ fn handle_gamepad_connect(
+ &self,
+ // As the spec actually defines how to set the gamepad index, the GilRs index
+ // is currently unused, though in practice it will almost always be the same.
+ // More infra is currently needed to track gamepads across windows.
+ _index: usize,
+ name: String,
+ axis_bounds: (f64, f64),
+ button_bounds: (f64, f64),
+ supported_haptic_effects: GamepadSupportedHapticEffects,
+ ) {
+ // TODO: 2. If document is not null and is not allowed to use the "gamepad" permission,
+ // then abort these steps.
+ let this = Trusted::new(self);
+ self.upcast::<GlobalScope>()
+ .task_manager()
+ .gamepad_task_source()
+ .queue(task!(gamepad_connected: move || {
+ let window = this.root();
+
+ let navigator = window.Navigator();
+ let selected_index = navigator.select_gamepad_index();
+ let gamepad = Gamepad::new(
+ &window,
+ selected_index,
+ name,
+ "standard".into(),
+ axis_bounds,
+ button_bounds,
+ supported_haptic_effects,
+ false,
+ CanGc::note(),
+ );
+ navigator.set_gamepad(selected_index as usize, &gamepad, CanGc::note());
+ }));
+ }
+
+ /// <https://www.w3.org/TR/gamepad/#dfn-gamepaddisconnected>
+ fn handle_gamepad_disconnect(&self, index: usize) {
+ let this = Trusted::new(self);
+ self.upcast::<GlobalScope>()
+ .task_manager()
+ .gamepad_task_source()
+ .queue(task!(gamepad_disconnected: move || {
+ let window = this.root();
+ let navigator = window.Navigator();
+ if let Some(gamepad) = navigator.get_gamepad(index) {
+ if window.Document().is_fully_active() {
+ gamepad.update_connected(false, gamepad.exposed(), CanGc::note());
+ navigator.remove_gamepad(index);
+ }
+ }
+ }));
+ }
+
+ /// <https://www.w3.org/TR/gamepad/#receiving-inputs>
+ fn receive_new_gamepad_button_or_axis(&self, index: usize, update_type: GamepadUpdateType) {
+ let this = Trusted::new(self);
+
+ // <https://w3c.github.io/gamepad/#dfn-update-gamepad-state>
+ self.upcast::<GlobalScope>().task_manager().gamepad_task_source().queue(
+ task!(update_gamepad_state: move || {
+ let window = this.root();
+ let navigator = window.Navigator();
+ if let Some(gamepad) = navigator.get_gamepad(index) {
+ let current_time = window.Performance().Now();
+ gamepad.update_timestamp(*current_time);
+ match update_type {
+ GamepadUpdateType::Axis(index, value) => {
+ gamepad.map_and_normalize_axes(index, value);
+ },
+ GamepadUpdateType::Button(index, value) => {
+ gamepad.map_and_normalize_buttons(index, value);
+ }
+ };
+ if !navigator.has_gamepad_gesture() && contains_user_gesture(update_type) {
+ navigator.set_has_gamepad_gesture(true);
+ navigator.GetGamepads()
+ .iter()
+ .filter_map(|g| g.as_ref())
+ .for_each(|gamepad| {
+ gamepad.set_exposed(true);
+ gamepad.update_timestamp(*current_time);
+ let new_gamepad = Trusted::new(&**gamepad);
+ if window.Document().is_fully_active() {
+ window.upcast::<GlobalScope>().task_manager().gamepad_task_source().queue(
+ task!(update_gamepad_connect: move || {
+ let gamepad = new_gamepad.root();
+ gamepad.notify_event(GamepadEventType::Connected, CanGc::note());
+ })
+ );
+ }
+ });
+ }
+ }
+ })
+ );
+ }
}
// https://html.spec.whatwg.org/multipage/#atob
diff --git a/components/script/dom/worker.rs b/components/script/dom/worker.rs
index 6ad56026db6..7a6b226cf07 100644
--- a/components/script/dom/worker.rs
+++ b/components/script/dom/worker.rs
@@ -21,12 +21,12 @@ use crate::dom::abstractworker::{SimpleWorkerErrorHandler, WorkerScriptMsg};
use crate::dom::bindings::cell::DomRefCell;
use crate::dom::bindings::codegen::Bindings::MessagePortBinding::StructuredSerializeOptions;
use crate::dom::bindings::codegen::Bindings::WorkerBinding::{WorkerMethods, WorkerOptions};
+use crate::dom::bindings::codegen::UnionTypes::TrustedScriptURLOrUSVString;
use crate::dom::bindings::error::{Error, ErrorResult, Fallible};
use crate::dom::bindings::inheritance::Castable;
use crate::dom::bindings::refcounted::Trusted;
use crate::dom::bindings::reflector::{DomGlobal, reflect_dom_object_with_proto};
use crate::dom::bindings::root::DomRoot;
-use crate::dom::bindings::str::USVString;
use crate::dom::bindings::structuredclone;
use crate::dom::bindings::trace::{CustomTraceable, RootedTraceableBox};
use crate::dom::dedicatedworkerglobalscope::{
@@ -35,6 +35,7 @@ use crate::dom::dedicatedworkerglobalscope::{
use crate::dom::eventtarget::EventTarget;
use crate::dom::globalscope::GlobalScope;
use crate::dom::messageevent::MessageEvent;
+use crate::dom::trustedscripturl::TrustedScriptURL;
use crate::dom::window::Window;
use crate::dom::workerglobalscope::prepare_workerscope_init;
use crate::realms::enter_realm;
@@ -162,11 +163,21 @@ impl WorkerMethods<crate::DomTypeHolder> for Worker {
global: &GlobalScope,
proto: Option<HandleObject>,
can_gc: CanGc,
- script_url: USVString,
+ script_url: TrustedScriptURLOrUSVString,
worker_options: &WorkerOptions,
) -> Fallible<DomRoot<Worker>> {
+ // Step 1: Let compliantScriptURL be the result of invoking the
+ // Get Trusted Type compliant string algorithm with TrustedScriptURL,
+ // this's relevant global object, scriptURL, "Worker constructor", and "script".
+ let compliant_script_url = TrustedScriptURL::get_trusted_script_url_compliant_string(
+ global,
+ script_url,
+ "Worker",
+ "constructor",
+ can_gc,
+ )?;
// Step 2-4.
- let worker_url = match global.api_base_url().join(&script_url) {
+ let worker_url = match global.api_base_url().join(&compliant_script_url) {
Ok(url) => url,
Err(_) => return Err(Error::Syntax),
};
diff --git a/components/script/dom/workerglobalscope.rs b/components/script/dom/workerglobalscope.rs
index 695119715e4..fa94dcc1d04 100644
--- a/components/script/dom/workerglobalscope.rs
+++ b/components/script/dom/workerglobalscope.rs
@@ -40,7 +40,9 @@ use crate::dom::bindings::codegen::Bindings::RequestBinding::RequestInit;
use crate::dom::bindings::codegen::Bindings::VoidFunctionBinding::VoidFunction;
use crate::dom::bindings::codegen::Bindings::WorkerBinding::WorkerType;
use crate::dom::bindings::codegen::Bindings::WorkerGlobalScopeBinding::WorkerGlobalScopeMethods;
-use crate::dom::bindings::codegen::UnionTypes::{RequestOrUSVString, StringOrFunction};
+use crate::dom::bindings::codegen::UnionTypes::{
+ RequestOrUSVString, StringOrFunction, TrustedScriptURLOrUSVString,
+};
use crate::dom::bindings::error::{Error, ErrorResult, Fallible, report_pending_exception};
use crate::dom::bindings::inheritance::Castable;
use crate::dom::bindings::reflector::DomObject;
@@ -53,6 +55,7 @@ use crate::dom::dedicatedworkerglobalscope::DedicatedWorkerGlobalScope;
use crate::dom::globalscope::GlobalScope;
use crate::dom::performance::Performance;
use crate::dom::promise::Promise;
+use crate::dom::trustedscripturl::TrustedScriptURL;
use crate::dom::trustedtypepolicyfactory::TrustedTypePolicyFactory;
#[cfg(feature = "webgpu")]
use crate::dom::webgpu::identityhub::IdentityHub;
@@ -281,9 +284,25 @@ impl WorkerGlobalScopeMethods<crate::DomTypeHolder> for WorkerGlobalScope {
error_event_handler!(error, GetOnerror, SetOnerror);
// https://html.spec.whatwg.org/multipage/#dom-workerglobalscope-importscripts
- fn ImportScripts(&self, url_strings: Vec<DOMString>, can_gc: CanGc) -> ErrorResult {
+ fn ImportScripts(
+ &self,
+ url_strings: Vec<TrustedScriptURLOrUSVString>,
+ can_gc: CanGc,
+ ) -> ErrorResult {
+ // Step 1: Let urlStrings be « ».
let mut urls = Vec::with_capacity(url_strings.len());
+ // Step 2: For each url of urls:
for url in url_strings {
+ // Step 3: Append the result of invoking the Get Trusted Type compliant string algorithm
+ // with TrustedScriptURL, this's relevant global object, url, "WorkerGlobalScope importScripts",
+ // and "script" to urlStrings.
+ let url = TrustedScriptURL::get_trusted_script_url_compliant_string(
+ self.upcast::<GlobalScope>(),
+ url,
+ "WorkerGlobalScope",
+ "importScripts",
+ can_gc,
+ )?;
let url = self.worker_url.borrow().join(&url);
match url {
Ok(url) => urls.push(url),
diff --git a/resources/media-controls.css b/components/script/resources/media-controls.css
index 62c39164747..62c39164747 100644
--- a/resources/media-controls.css
+++ b/components/script/resources/media-controls.css
diff --git a/resources/media-controls.js b/components/script/resources/media-controls.js
index b8f100c6f05..b8f100c6f05 100644
--- a/resources/media-controls.js
+++ b/components/script/resources/media-controls.js
diff --git a/components/script/routed_promise.rs b/components/script/routed_promise.rs
index 67e5edd7370..c3eea88ed71 100644
--- a/components/script/routed_promise.rs
+++ b/components/script/routed_promise.rs
@@ -10,9 +10,10 @@ use serde::Serialize;
use serde::de::DeserializeOwned;
use crate::dom::bindings::refcounted::{Trusted, TrustedPromise};
-use crate::dom::bindings::reflector::{DomGlobal, DomObject};
+use crate::dom::bindings::reflector::DomObject;
use crate::dom::promise::Promise;
use crate::script_runtime::CanGc;
+use crate::task_source::TaskSource;
pub(crate) trait RoutedPromiseListener<R: Serialize + DeserializeOwned + Send> {
fn handle_response(&self, response: R, promise: &Rc<Promise>, can_gc: CanGc);
@@ -44,13 +45,10 @@ pub(crate) fn route_promise<
>(
promise: &Rc<Promise>,
receiver: &T,
+ task_source: TaskSource,
) -> IpcSender<R> {
let (action_sender, action_receiver) = ipc::channel().unwrap();
- let task_source = receiver
- .global()
- .task_manager()
- .dom_manipulation_task_source()
- .to_sendable();
+ let task_source = task_source.to_sendable();
let mut trusted: Option<TrustedPromise> = Some(TrustedPromise::new(promise.clone()));
let trusted_receiver = Trusted::new(receiver);
ROUTER.add_typed_route(
diff --git a/components/script/script_thread.rs b/components/script/script_thread.rs
index 2129979ad42..6e192cc920c 100644
--- a/components/script/script_thread.rs
+++ b/components/script/script_thread.rs
@@ -598,7 +598,7 @@ impl ScriptThread {
with_script_thread(|script_thread| {
let is_javascript = load_data.url.scheme() == "javascript";
// If resource is a request whose url's scheme is "javascript"
- // https://html.spec.whatwg.org/multipage/#javascript-protocol
+ // https://html.spec.whatwg.org/multipage/#navigate-to-a-javascript:-url
if is_javascript {
let window = match script_thread.documents.borrow().find_window(pipeline_id) {
None => return,
@@ -612,8 +612,12 @@ impl ScriptThread {
.clone();
let task = task!(navigate_javascript: move || {
// Important re security. See https://github.com/servo/servo/issues/23373
- // TODO: check according to https://w3c.github.io/webappsec-csp/#should-block-navigation-request
if let Some(window) = trusted_global.root().downcast::<Window>() {
+ // Step 5: If the result of should navigation request of type be blocked by
+ // Content Security Policy? given request and cspNavigationType is "Blocked", then return. [CSP]
+ if trusted_global.root().should_navigation_request_be_blocked(&load_data) {
+ return;
+ }
if ScriptThread::check_load_origin(&load_data.load_origin, &window.get_url().origin()) {
ScriptThread::eval_js_url(&trusted_global.root(), &mut load_data, CanGc::note());
sender
@@ -622,6 +626,7 @@ impl ScriptThread {
}
}
});
+ // Step 19 of <https://html.spec.whatwg.org/multipage/#navigate>
global
.task_manager()
.dom_manipulation_task_source()
@@ -740,7 +745,9 @@ impl ScriptThread {
.senders
.pipeline_to_constellation_sender
.clone(),
- image_cache: script_thread.image_cache.clone(),
+ image_cache: script_thread
+ .image_cache
+ .create_new_image_cache(script_thread.compositor_api.clone()),
#[cfg(feature = "webgpu")]
gpu_id_hub: script_thread.gpu_id_hub.clone(),
inherited_secure_context: script_thread.inherited_secure_context,
@@ -1126,7 +1133,7 @@ impl ScriptThread {
document.dispatch_ime_event(ime_event, can_gc);
},
InputEvent::Gamepad(gamepad_event) => {
- window.as_global_scope().handle_gamepad_event(gamepad_event);
+ window.handle_gamepad_event(gamepad_event);
},
InputEvent::EditingAction(editing_action_event) => {
document.handle_editing_action(editing_action_event, can_gc);
@@ -2438,8 +2445,6 @@ impl ScriptThread {
let prefix = format!("url({urls})");
reports.extend(self.get_cx().get_reports(prefix.clone(), ops));
-
- reports.push(self.image_cache.memory_report(&prefix, ops));
});
reports_chan.send(ProcessReports::new(reports));
@@ -3140,13 +3145,17 @@ impl ScriptThread {
self.resource_threads.clone(),
));
+ let image_cache = self
+ .image_cache
+ .create_new_image_cache(self.compositor_api.clone());
+
let layout_config = LayoutConfig {
id: incomplete.pipeline_id,
webview_id: incomplete.webview_id,
url: final_url.clone(),
is_iframe: incomplete.parent_info.is_some(),
script_chan: self.senders.constellation_sender.clone(),
- image_cache: self.image_cache.clone(),
+ image_cache: image_cache.clone(),
font_context: font_context.clone(),
time_profiler_chan: self.senders.time_profiler_sender.clone(),
compositor_api: self.compositor_api.clone(),
@@ -3161,7 +3170,7 @@ impl ScriptThread {
self.layout_factory.create(layout_config),
font_context,
self.senders.image_cache_sender.clone(),
- self.image_cache.clone(),
+ image_cache.clone(),
self.resource_threads.clone(),
#[cfg(feature = "bluetooth")]
self.senders.bluetooth_sender.clone(),
@@ -3669,10 +3678,12 @@ impl ScriptThread {
None => vec![],
};
+ let policy_container = incomplete.load_data.policy_container.clone();
self.incomplete_loads.borrow_mut().push(incomplete);
let dummy_request_id = RequestId::default();
context.process_response(dummy_request_id, Ok(FetchMetadata::Unfiltered(meta)));
+ context.append_parent_to_csp_list(policy_container.as_ref());
context.process_response_chunk(dummy_request_id, chunk);
context.process_response_eof(
dummy_request_id,
@@ -3692,12 +3703,14 @@ impl ScriptThread {
let srcdoc = std::mem::take(&mut incomplete.load_data.srcdoc);
let chunk = srcdoc.into_bytes();
+ let policy_container = incomplete.load_data.policy_container.clone();
self.incomplete_loads.borrow_mut().push(incomplete);
let mut context = ParserContext::new(id, url);
let dummy_request_id = RequestId::default();
context.process_response(dummy_request_id, Ok(FetchMetadata::Unfiltered(meta)));
+ context.append_parent_to_csp_list(policy_container.as_ref());
context.process_response_chunk(dummy_request_id, chunk);
context.process_response_eof(
dummy_request_id,
diff --git a/components/script_bindings/codegen/Bindings.conf b/components/script_bindings/codegen/Bindings.conf
index 6396e3ced0c..36bb0c1b9f4 100644
--- a/components/script_bindings/codegen/Bindings.conf
+++ b/components/script_bindings/codegen/Bindings.conf
@@ -416,7 +416,7 @@ DOMInterfaces = {
},
'HTMLScriptElement': {
- 'canGc': ['SetAsync', 'SetCrossOrigin', 'SetSrc', 'SetText']
+ 'canGc': ['InnerText', 'SetAsync', 'SetCrossOrigin', 'SetInnerText', 'SetSrc', 'SetText', 'SetTextContent']
},
'HTMLSelectElement': {
diff --git a/components/script_bindings/webidls/Document.webidl b/components/script_bindings/webidls/Document.webidl
index 6131dbd15c7..4af7dcc2c7a 100644
--- a/components/script_bindings/webidls/Document.webidl
+++ b/components/script_bindings/webidls/Document.webidl
@@ -129,9 +129,9 @@ partial /*sealed*/ interface Document {
[CEReactions, Throws]
undefined close();
[CEReactions, Throws]
- undefined write(DOMString... text);
+ undefined write((TrustedHTML or DOMString)... text);
[CEReactions, Throws]
- undefined writeln(DOMString... text);
+ undefined writeln((TrustedHTML or DOMString)... text);
// user interaction
readonly attribute Window?/*Proxy?*/ defaultView;
diff --git a/components/script_bindings/webidls/HTMLScriptElement.webidl b/components/script_bindings/webidls/HTMLScriptElement.webidl
index 6f02bb3cf47..2c7b398b7e3 100644
--- a/components/script_bindings/webidls/HTMLScriptElement.webidl
+++ b/components/script_bindings/webidls/HTMLScriptElement.webidl
@@ -21,8 +21,12 @@ interface HTMLScriptElement : HTMLElement {
attribute boolean defer;
[CEReactions]
attribute DOMString? crossOrigin;
- [CEReactions, Pure]
- attribute DOMString text;
+ [CEReactions, SetterThrows]
+ attribute (TrustedScript or DOMString) innerText;
+ [CEReactions, Pure, SetterThrows]
+ attribute (TrustedScript or DOMString) text;
+ [CEReactions, SetterThrows]
+ attribute (TrustedScript or DOMString)? textContent;
[CEReactions]
attribute DOMString integrity;
[CEReactions]
diff --git a/components/script_bindings/webidls/Worker.webidl b/components/script_bindings/webidls/Worker.webidl
index ef535126606..5faa7a5ea3e 100644
--- a/components/script_bindings/webidls/Worker.webidl
+++ b/components/script_bindings/webidls/Worker.webidl
@@ -11,7 +11,7 @@ interface mixin AbstractWorker {
// https://html.spec.whatwg.org/multipage/#worker
[Exposed=(Window,Worker)]
interface Worker : EventTarget {
- [Throws] constructor(USVString scriptURL, optional WorkerOptions options = {});
+ [Throws] constructor((TrustedScriptURL or USVString) scriptURL, optional WorkerOptions options = {});
undefined terminate();
[Throws] undefined postMessage(any message, sequence<object> transfer);
diff --git a/components/script_bindings/webidls/WorkerGlobalScope.webidl b/components/script_bindings/webidls/WorkerGlobalScope.webidl
index 05301fb28e6..db02773392d 100644
--- a/components/script_bindings/webidls/WorkerGlobalScope.webidl
+++ b/components/script_bindings/webidls/WorkerGlobalScope.webidl
@@ -19,6 +19,6 @@ interface WorkerGlobalScope : GlobalScope {
[Exposed=Worker]
partial interface WorkerGlobalScope { // not obsolete
[Throws]
- undefined importScripts(DOMString... urls);
+ undefined importScripts((TrustedScriptURL or USVString)... urls);
readonly attribute WorkerNavigator navigator;
};
diff --git a/components/servo/Cargo.toml b/components/servo/Cargo.toml
index b49f60e742a..fa64638fa4c 100644
--- a/components/servo/Cargo.toml
+++ b/components/servo/Cargo.toml
@@ -141,3 +141,12 @@ libservo = { path = ".", features = ["tracing"] }
rustls = { version = "0.23", default-features = false, features = ["aws-lc-rs"] }
tracing = { workspace = true }
winit = "0.30.8"
+
+
+[[test]]
+name = "webview"
+harness = false
+
+[[test]]
+name = "servo"
+harness = false
diff --git a/components/servo/tests/common/mod.rs b/components/servo/tests/common/mod.rs
index 8c00826a0d8..de71361e9be 100644
--- a/components/servo/tests/common/mod.rs
+++ b/components/servo/tests/common/mod.rs
@@ -3,18 +3,52 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
use std::rc::Rc;
+use std::sync::Arc;
use std::sync::atomic::{AtomicBool, Ordering};
-use std::sync::{Arc, OnceLock};
use std::time::Duration;
use anyhow::Error;
use compositing_traits::rendering_context::{RenderingContext, SoftwareRenderingContext};
-use crossbeam_channel::{Receiver, Sender, unbounded};
use dpi::PhysicalSize;
use embedder_traits::EventLoopWaker;
-use parking_lot::Mutex;
use servo::{Servo, ServoBuilder};
+macro_rules! run_api_tests {
+ ($($test_function:ident), +) => {
+ let mut failed = false;
+
+ // Be sure that `servo_test` is dropped before exiting early.
+ {
+ let servo_test = ServoTest::new();
+ $(
+ common::run_test($test_function, stringify!($test_function), &servo_test, &mut failed);
+ )+
+ }
+
+ if failed {
+ std::process::exit(1);
+ }
+ }
+}
+
+pub(crate) use run_api_tests;
+
+pub(crate) fn run_test(
+ test_function: fn(&ServoTest) -> Result<(), Error>,
+ test_name: &str,
+ servo_test: &ServoTest,
+ failed: &mut bool,
+) {
+ match test_function(servo_test) {
+ Ok(_) => println!(" ✅ {test_name}"),
+ Err(error) => {
+ *failed = true;
+ println!(" ❌ {test_name}");
+ println!("{}", format!("\n{error:?}").replace("\n", "\n "));
+ },
+ }
+}
+
pub struct ServoTest {
servo: Servo,
}
@@ -30,7 +64,7 @@ impl Drop for ServoTest {
}
impl ServoTest {
- fn new() -> Self {
+ pub(crate) fn new() -> Self {
let rendering_context = Rc::new(
SoftwareRenderingContext::new(PhysicalSize {
width: 500,
@@ -63,58 +97,28 @@ impl ServoTest {
&self.servo
}
- /// Run a Servo test. All tests are run in a `ServoTestThread` and serially. Currently
- /// Servo does not support launching concurrent instances, in order to ensure
- /// isolation and allow for more than a single test per instance.
- pub fn run(
- test_function: impl FnOnce(&ServoTest) -> Result<(), anyhow::Error> + Send + Sync + 'static,
- ) {
- static SERVO_TEST_THREAD: Mutex<OnceLock<ServoTestThread>> = Mutex::new(OnceLock::new());
- let test_thread = SERVO_TEST_THREAD.lock();
- test_thread
- .get_or_init(ServoTestThread::new)
- .run_test(Box::new(test_function));
- }
-}
-
-type TestFunction =
- Box<dyn FnOnce(&ServoTest) -> Result<(), anyhow::Error> + Send + Sync + 'static>;
-
-struct ServoTestThread {
- test_function_sender: Sender<TestFunction>,
- result_receiver: Receiver<Result<(), Error>>,
-}
-
-impl ServoTestThread {
- fn new() -> Self {
- let (result_sender, result_receiver) = unbounded();
- let (test_function_sender, test_function_receiver) = unbounded();
-
- // Defined here rather than at the end of this method in order to take advantage
- // of Rust type inference.
- let thread = Self {
- test_function_sender,
- result_receiver,
- };
-
- let _ = std::thread::spawn(move || {
- let servo_test = ServoTest::new();
- while let Ok(incoming_test_function) = test_function_receiver.recv() {
- let _ = result_sender.send(incoming_test_function(&servo_test));
+ /// Spin the Servo event loop until one of:
+ /// - The given callback returns `Ok(false)`.
+ /// - The given callback returns an `Error`, in which case the `Error` will be returned.
+ /// - Servo has indicated that shut down is complete and we cannot spin the event loop
+ /// any longer.
+ // The dead code exception here is because not all test suites that use `common` also
+ // use `spin()`.
+ #[allow(dead_code)]
+ pub fn spin(&self, callback: impl Fn() -> Result<bool, Error> + 'static) -> Result<(), Error> {
+ let mut keep_going = true;
+ while keep_going {
+ std::thread::sleep(Duration::from_millis(1));
+ if !self.servo.spin_event_loop() {
+ return Ok(());
+ }
+ let result = callback();
+ match result {
+ Ok(result) => keep_going = result,
+ Err(error) => return Err(error),
}
- });
-
- thread
- }
-
- fn run_test(&self, test_function: TestFunction) {
- let _ = self.test_function_sender.send(Box::new(test_function));
- let result = self
- .result_receiver
- .recv()
- .expect("Servo test thread should always return a result.");
- if let Err(result) = result {
- unreachable!("{result}");
}
+
+ Ok(())
}
}
diff --git a/components/servo/tests/servo.rs b/components/servo/tests/servo.rs
index 2f71e909bee..6333b0af50a 100644
--- a/components/servo/tests/servo.rs
+++ b/components/servo/tests/servo.rs
@@ -4,7 +4,7 @@
//! Servo API unit tests.
//!
-//! Since all Servo tests must rust serially on the same thread, it is important
+//! Since all Servo tests must run serially on the same thread, it is important
//! that tests never panic. In order to ensure this, use `anyhow::ensure!` instead
//! of `assert!` for test assertions. `ensure!` will produce a `Result::Err` in
//! place of panicking.
@@ -12,21 +12,15 @@
mod common;
use anyhow::ensure;
-use common::*;
-use servo::WebViewBuilder;
+use common::{ServoTest, run_api_tests};
-#[test]
-fn test_simple_servo_is_not_animating_by_default() {
- ServoTest::run(|servo_test| {
- ensure!(!servo_test.servo().animating());
- Ok(())
- });
+fn test_simple_servo_is_not_animating_by_default(
+ servo_test: &ServoTest,
+) -> Result<(), anyhow::Error> {
+ ensure!(!servo_test.servo().animating());
+ Ok(())
}
-#[test]
-fn test_simple_servo_construct_webview() {
- ServoTest::run(|servo_test| {
- WebViewBuilder::new(servo_test.servo()).build();
- Ok(())
- });
+fn main() {
+ run_api_tests!(test_simple_servo_is_not_animating_by_default);
}
diff --git a/components/servo/tests/webview.rs b/components/servo/tests/webview.rs
new file mode 100644
index 00000000000..4ed06e412da
--- /dev/null
+++ b/components/servo/tests/webview.rs
@@ -0,0 +1,49 @@
+/* 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/. */
+
+//! WebView API unit tests.
+//!
+//! Since all Servo tests must run serially on the same thread, it is important
+//! that tests never panic. In order to ensure this, use `anyhow::ensure!` instead
+//! of `assert!` for test assertions. `ensure!` will produce a `Result::Err` in
+//! place of panicking.
+
+mod common;
+
+use std::cell::Cell;
+use std::rc::Rc;
+
+use anyhow::ensure;
+use common::{ServoTest, run_api_tests};
+use servo::{WebViewBuilder, WebViewDelegate};
+
+#[derive(Default)]
+struct WebViewDelegateImpl {
+ url_changed: Cell<bool>,
+}
+
+impl WebViewDelegate for WebViewDelegateImpl {
+ fn notify_url_changed(&self, _webview: servo::WebView, _url: url::Url) {
+ self.url_changed.set(true);
+ }
+}
+
+fn test_create_webview(servo_test: &ServoTest) -> Result<(), anyhow::Error> {
+ let delegate = Rc::new(WebViewDelegateImpl::default());
+ let webview = WebViewBuilder::new(servo_test.servo())
+ .delegate(delegate.clone())
+ .build();
+
+ servo_test.spin(move || Ok(!delegate.url_changed.get()))?;
+
+ let url = webview.url();
+ ensure!(url.is_some());
+ ensure!(url.unwrap().to_string() == "about:blank");
+
+ Ok(())
+}
+
+fn main() {
+ run_api_tests!(test_create_webview);
+}
diff --git a/components/shared/constellation/from_script_message.rs b/components/shared/constellation/from_script_message.rs
index ddc9f788617..21665c24e57 100644
--- a/components/shared/constellation/from_script_message.rs
+++ b/components/shared/constellation/from_script_message.rs
@@ -22,6 +22,7 @@ use euclid::default::Size2D as UntypedSize2D;
use http::{HeaderMap, Method};
use ipc_channel::Error as IpcError;
use ipc_channel::ipc::{IpcReceiver, IpcSender};
+use net_traits::policy_container::PolicyContainer;
use net_traits::request::{InsecureRequestsPolicy, Referrer, RequestBody};
use net_traits::storage_thread::StorageType;
use net_traits::{CoreResourceMsg, ReferrerPolicy, ResourceThreads};
@@ -97,6 +98,8 @@ pub struct LoadData {
pub referrer: Referrer,
/// The referrer policy.
pub referrer_policy: ReferrerPolicy,
+ /// The policy container.
+ pub policy_container: Option<PolicyContainer>,
/// The source to use instead of a network response for a srcdoc document.
pub srcdoc: String,
@@ -143,6 +146,7 @@ impl LoadData {
js_eval_result: None,
referrer,
referrer_policy,
+ policy_container: None,
srcdoc: "".to_string(),
inherited_secure_context,
crash: None,
diff --git a/components/shared/embedder/resources.rs b/components/shared/embedder/resources.rs
index 29e64bf9629..830a403698e 100644
--- a/components/shared/embedder/resources.rs
+++ b/components/shared/embedder/resources.rs
@@ -91,18 +91,6 @@ pub enum Resource {
/// The message can contain a placeholder `${reason}` for the error code.
/// It can be empty but then nothing will be displayed when an internal error occurs.
NetErrorHTML,
- /// A CSS file to style the user agent stylesheet.
- /// It can be empty but then there's simply no user agent stylesheet.
- UserAgentCSS,
- /// A CSS file to style the Servo browser.
- /// It can be empty but several features might not work as expected.
- ServoCSS,
- /// A CSS file to style the presentational hints.
- /// It can be empty but then presentational hints will not be styled.
- PresentationalHintsCSS,
- /// A CSS file to style the quirks mode.
- /// It can be empty but then quirks mode will not be styled.
- QuirksModeCSS,
/// A placeholder image to display if we couldn't get the requested image.
///
/// ## Panic
@@ -110,12 +98,6 @@ pub enum Resource {
/// If the resource is not provided, servo will fallback to a baked in default (See resources/rippy.png).
/// However, if the image is provided but invalid, Servo will crash.
RippyPNG,
- /// A CSS file to style the media controls.
- /// It can be empty but then media controls will not be styled.
- MediaControlsCSS,
- /// A JS file to control the media controls.
- /// It can be empty but then media controls will not work.
- MediaControlsJS,
/// A placeholder HTML page to display when the code responsible for rendering a page panics and the original
/// page can no longer be displayed.
/// The message can contain a placeholder `${details}` for the error details.
@@ -137,13 +119,7 @@ impl Resource {
Resource::HstsPreloadList => "hsts_preload.json",
Resource::BadCertHTML => "badcert.html",
Resource::NetErrorHTML => "neterror.html",
- Resource::UserAgentCSS => "user-agent.css",
- Resource::ServoCSS => "servo.css",
- Resource::PresentationalHintsCSS => "presentational-hints.css",
- Resource::QuirksModeCSS => "quirks-mode.css",
Resource::RippyPNG => "rippy.png",
- Resource::MediaControlsCSS => "media-controls.css",
- Resource::MediaControlsJS => "media-controls.js",
Resource::CrashHTML => "crash.html",
Resource::DirectoryListingHTML => "directory-listing.html",
Resource::AboutMemoryHTML => "about-memory.html",
@@ -183,21 +159,7 @@ fn resources_for_tests() -> Box<dyn ResourceReaderMethods + Sync + Send> {
},
Resource::BadCertHTML => &include_bytes!("../../../resources/badcert.html")[..],
Resource::NetErrorHTML => &include_bytes!("../../../resources/neterror.html")[..],
- Resource::UserAgentCSS => &include_bytes!("../../../resources/user-agent.css")[..],
- Resource::ServoCSS => &include_bytes!("../../../resources/servo.css")[..],
- Resource::PresentationalHintsCSS => {
- &include_bytes!("../../../resources/presentational-hints.css")[..]
- },
- Resource::QuirksModeCSS => {
- &include_bytes!("../../../resources/quirks-mode.css")[..]
- },
Resource::RippyPNG => &include_bytes!("../../../resources/rippy.png")[..],
- Resource::MediaControlsCSS => {
- &include_bytes!("../../../resources/media-controls.css")[..]
- },
- Resource::MediaControlsJS => {
- &include_bytes!("../../../resources/media-controls.js")[..]
- },
Resource::CrashHTML => &include_bytes!("../../../resources/crash.html")[..],
Resource::DirectoryListingHTML => {
&include_bytes!("../../../resources/directory-listing.html")[..]
diff --git a/components/shared/net/image_cache.rs b/components/shared/net/image_cache.rs
index 8fb329d304f..3f316388755 100644
--- a/components/shared/net/image_cache.rs
+++ b/components/shared/net/image_cache.rs
@@ -141,4 +141,10 @@ pub trait ImageCache: Sync + Send {
/// Inform the image cache about a response for a pending request.
fn notify_pending_response(&self, id: PendingImageId, action: FetchResponseMsg);
+
+ /// Create new image cache based on this one, while reusing the existing thread_pool.
+ fn create_new_image_cache(
+ &self,
+ compositor_api: CrossProcessCompositorApi,
+ ) -> Arc<dyn ImageCache>;
}
diff --git a/ports/servoshell/egl/android/resources.rs b/ports/servoshell/egl/android/resources.rs
index d39015aece1..0726d639f38 100644
--- a/ports/servoshell/egl/android/resources.rs
+++ b/ports/servoshell/egl/android/resources.rs
@@ -21,23 +21,11 @@ impl ResourceReaderMethods for ResourceReaderInstance {
},
Resource::BadCertHTML => &include_bytes!("../../../../resources/badcert.html")[..],
Resource::NetErrorHTML => &include_bytes!("../../../../resources/neterror.html")[..],
- Resource::UserAgentCSS => &include_bytes!("../../../../resources/user-agent.css")[..],
- Resource::ServoCSS => &include_bytes!("../../../../resources/servo.css")[..],
- Resource::PresentationalHintsCSS => {
- &include_bytes!("../../../../resources/presentational-hints.css")[..]
- },
- Resource::QuirksModeCSS => &include_bytes!("../../../../resources/quirks-mode.css")[..],
Resource::RippyPNG => &include_bytes!("../../../../resources/rippy.png")[..],
Resource::DomainList => &include_bytes!("../../../../resources/public_domains.txt")[..],
Resource::BluetoothBlocklist => {
&include_bytes!("../../../../resources/gatt_blocklist.txt")[..]
},
- Resource::MediaControlsCSS => {
- &include_bytes!("../../../../resources/media-controls.css")[..]
- },
- Resource::MediaControlsJS => {
- &include_bytes!("../../../../resources/media-controls.js")[..]
- },
Resource::CrashHTML => &include_bytes!("../../../../resources/crash.html")[..],
Resource::DirectoryListingHTML => {
&include_bytes!("../../../../resources/directory-listing.html")[..]
diff --git a/tests/wpt/meta/FileAPI/url/url-in-tags-revoke.window.js.ini b/tests/wpt/meta/FileAPI/url/url-in-tags-revoke.window.js.ini
index 745f3e84edb..62c2d998e8f 100644
--- a/tests/wpt/meta/FileAPI/url/url-in-tags-revoke.window.js.ini
+++ b/tests/wpt/meta/FileAPI/url/url-in-tags-revoke.window.js.ini
@@ -14,6 +14,3 @@
[Opening a blob URL in a new window by clicking an <a> tag works immediately before revoking the URL.]
expected: TIMEOUT
-
- [Fetching a blob URL immediately before revoking it works in <script> tags.]
- expected: TIMEOUT
diff --git a/tests/wpt/meta/FileAPI/url/url-with-fetch.any.js.ini b/tests/wpt/meta/FileAPI/url/url-with-fetch.any.js.ini
index b275cb58343..292dc852b9f 100644
--- a/tests/wpt/meta/FileAPI/url/url-with-fetch.any.js.ini
+++ b/tests/wpt/meta/FileAPI/url/url-with-fetch.any.js.ini
@@ -12,6 +12,3 @@
[Revoke blob URL after creating Request, then clone Request, will fetch]
expected: FAIL
-
- [Revoke blob URL after calling fetch, fetch should succeed]
- expected: FAIL
diff --git a/tests/wpt/meta/MANIFEST.json b/tests/wpt/meta/MANIFEST.json
index 2d18197596c..7b631710b77 100644
--- a/tests/wpt/meta/MANIFEST.json
+++ b/tests/wpt/meta/MANIFEST.json
@@ -1363,6 +1363,13 @@
{}
]
],
+ "nested-fixedpos-in-inline-003-crash.html": [
+ "88a042884644feff5eac8a367fbdc36326d2d4ef",
+ [
+ null,
+ {}
+ ]
+ ],
"nested-float-in-multicol-crash.html": [
"6878d384e54b0f3262cbbfb0552b9d19e707140d",
[
@@ -2794,6 +2801,13 @@
},
"css-grid": {
"abspos": {
+ "abspos-in-flexbox-in-grid-crash.html": [
+ "a2f71fb78e7f6fd82ea539e3af6c76d36f21e134",
+ [
+ null,
+ {}
+ ]
+ ],
"positioned-grid-items-crash.html": [
"228a6264df77fe82587a4116f231ff09537c8372",
[
@@ -124391,7 +124405,7 @@
]
],
"align-self-static-position-005.html": [
- "e148f0ebda37797d5573f4c3a2d4b7c52e5a2f2e",
+ "207a5443331e2f04f0d3b6e9e4fd8c55716af8de",
[
null,
[
@@ -186825,191 +186839,215 @@
]
]
},
- "tentative": {
- "multicol": {
- "multicol-gap-decorations-001.html": [
- "c3752156c7d54f6620ade9715b4562582c6135f6",
+ "multicol": {
+ "multicol-gap-decorations-001.html": [
+ "c3752156c7d54f6620ade9715b4562582c6135f6",
+ [
+ null,
[
- null,
[
- [
- "/css/css-gaps/tentative/multicol/multicol-gap-decorations-001-ref.html",
- "=="
- ]
- ],
- {}
- ]
- ],
- "multicol-gap-decorations-002.html": [
- "0b632fa94ace20a253f5f56079d29adbb7997135",
+ "/css/css-gaps/multicol/multicol-gap-decorations-001-ref.html",
+ "=="
+ ]
+ ],
+ {}
+ ]
+ ],
+ "multicol-gap-decorations-002.html": [
+ "0b632fa94ace20a253f5f56079d29adbb7997135",
+ [
+ null,
[
- null,
[
- [
- "/css/css-gaps/tentative/multicol/multicol-gap-decorations-002-ref.html",
- "=="
- ]
- ],
- {}
- ]
- ],
- "multicol-gap-decorations-003.html": [
- "2f2473fd04686283e120abd29b5f273da40c3ef3",
+ "/css/css-gaps/multicol/multicol-gap-decorations-002-ref.html",
+ "=="
+ ]
+ ],
+ {}
+ ]
+ ],
+ "multicol-gap-decorations-003.html": [
+ "2f2473fd04686283e120abd29b5f273da40c3ef3",
+ [
+ null,
[
- null,
[
- [
- "/css/css-gaps/tentative/multicol/multicol-gap-decorations-003-ref.html",
- "=="
- ]
- ],
- {}
- ]
- ],
- "multicol-gap-decorations-004.html": [
- "0dcbeef4df82f4d9dc6e2ed2215ee2fa39773052",
+ "/css/css-gaps/multicol/multicol-gap-decorations-003-ref.html",
+ "=="
+ ]
+ ],
+ {}
+ ]
+ ],
+ "multicol-gap-decorations-004.html": [
+ "0dcbeef4df82f4d9dc6e2ed2215ee2fa39773052",
+ [
+ null,
[
- null,
[
- [
- "/css/css-gaps/tentative/multicol/multicol-gap-decorations-004-ref.html",
- "=="
- ]
- ],
- {}
- ]
- ],
- "multicol-gap-decorations-005.html": [
- "daa65e904e71ee62c83ba2a16933d13311328539",
+ "/css/css-gaps/multicol/multicol-gap-decorations-004-ref.html",
+ "=="
+ ]
+ ],
+ {}
+ ]
+ ],
+ "multicol-gap-decorations-005.html": [
+ "daa65e904e71ee62c83ba2a16933d13311328539",
+ [
+ null,
[
- null,
[
- [
- "/css/css-gaps/tentative/multicol/multicol-gap-decorations-005-ref.html",
- "=="
- ]
- ],
- {}
- ]
- ],
- "multicol-gap-decorations-006.html": [
- "64b3b007ab5f6282c95bb79a39a3bcf89d10de88",
+ "/css/css-gaps/multicol/multicol-gap-decorations-005-ref.html",
+ "=="
+ ]
+ ],
+ {}
+ ]
+ ],
+ "multicol-gap-decorations-006.html": [
+ "64b3b007ab5f6282c95bb79a39a3bcf89d10de88",
+ [
+ null,
[
- null,
[
- [
- "/css/css-gaps/tentative/multicol/multicol-gap-decorations-006-ref.html",
- "=="
- ]
- ],
- {}
- ]
- ],
- "multicol-gap-decorations-007.html": [
- "1f23ed7f7ca34602f4310627edb5ae96885028b8",
+ "/css/css-gaps/multicol/multicol-gap-decorations-006-ref.html",
+ "=="
+ ]
+ ],
+ {}
+ ]
+ ],
+ "multicol-gap-decorations-007.html": [
+ "1f23ed7f7ca34602f4310627edb5ae96885028b8",
+ [
+ null,
[
- null,
[
- [
- "/css/css-gaps/tentative/multicol/multicol-gap-decorations-007-ref.html",
- "=="
- ]
- ],
- {}
- ]
- ],
- "multicol-gap-decorations-008.html": [
- "ed299b5d9f68e8560d99cdd58fcc9b3830929117",
+ "/css/css-gaps/multicol/multicol-gap-decorations-007-ref.html",
+ "=="
+ ]
+ ],
+ {}
+ ]
+ ],
+ "multicol-gap-decorations-008.html": [
+ "ed299b5d9f68e8560d99cdd58fcc9b3830929117",
+ [
+ null,
[
- null,
[
- [
- "/css/css-gaps/tentative/multicol/multicol-gap-decorations-008-ref.html",
- "=="
- ]
- ],
- {}
- ]
- ],
- "multicol-gap-decorations-009.html": [
- "b00c6a70f8abf9894e548d9e40882e396ed5b1f0",
+ "/css/css-gaps/multicol/multicol-gap-decorations-008-ref.html",
+ "=="
+ ]
+ ],
+ {}
+ ]
+ ],
+ "multicol-gap-decorations-009.html": [
+ "b00c6a70f8abf9894e548d9e40882e396ed5b1f0",
+ [
+ null,
[
- null,
[
- [
- "/css/css-gaps/tentative/multicol/multicol-gap-decorations-009-ref.html",
- "=="
- ]
- ],
- {}
- ]
- ],
- "multicol-gap-decorations-010.html": [
- "61bb4a9b93314bb7d96a90b98f67b175a4cf86c6",
+ "/css/css-gaps/multicol/multicol-gap-decorations-009-ref.html",
+ "=="
+ ]
+ ],
+ {}
+ ]
+ ],
+ "multicol-gap-decorations-010.html": [
+ "61bb4a9b93314bb7d96a90b98f67b175a4cf86c6",
+ [
+ null,
[
- null,
[
- [
- "/css/css-gaps/tentative/multicol/multicol-gap-decorations-010-ref.html",
- "=="
- ]
- ],
- {}
- ]
- ],
- "multicol-gap-decorations-011.html": [
- "cf588ded41ea3e811c241984ec8909e5fbcf14be",
+ "/css/css-gaps/multicol/multicol-gap-decorations-010-ref.html",
+ "=="
+ ]
+ ],
+ {}
+ ]
+ ],
+ "multicol-gap-decorations-011.html": [
+ "cf588ded41ea3e811c241984ec8909e5fbcf14be",
+ [
+ null,
[
- null,
[
- [
- "/css/css-gaps/tentative/multicol/multicol-gap-decorations-011-ref.html",
- "=="
- ]
- ],
- {}
- ]
- ],
- "multicol-gap-decorations-012.html": [
- "078b810cf8e608b16dd2a898136f4ce757325ed9",
+ "/css/css-gaps/multicol/multicol-gap-decorations-011-ref.html",
+ "=="
+ ]
+ ],
+ {}
+ ]
+ ],
+ "multicol-gap-decorations-012.html": [
+ "078b810cf8e608b16dd2a898136f4ce757325ed9",
+ [
+ null,
[
- null,
[
- [
- "/css/css-gaps/tentative/multicol/multicol-gap-decorations-012-ref.html",
- "=="
- ]
- ],
- {}
- ]
- ],
- "multicol-gap-decorations-013.html": [
- "d4170084f066688fd136b2abeb40da03b1243816",
+ "/css/css-gaps/multicol/multicol-gap-decorations-012-ref.html",
+ "=="
+ ]
+ ],
+ {}
+ ]
+ ],
+ "multicol-gap-decorations-013.html": [
+ "d4170084f066688fd136b2abeb40da03b1243816",
+ [
+ null,
[
- null,
[
- [
- "/css/css-gaps/tentative/multicol/multicol-gap-decorations-013-ref.html",
- "=="
- ]
- ],
- {}
- ]
- ],
- "multicol-gap-decorations-014.html": [
- "1dcd393d99aa19021684e42e9f835e17281fc6a4",
+ "/css/css-gaps/multicol/multicol-gap-decorations-013-ref.html",
+ "=="
+ ]
+ ],
+ {}
+ ]
+ ],
+ "multicol-gap-decorations-014.html": [
+ "1dcd393d99aa19021684e42e9f835e17281fc6a4",
+ [
+ null,
[
- null,
[
- [
- "/css/css-gaps/tentative/multicol/multicol-gap-decorations-014-ref.html",
- "=="
- ]
- ],
- {}
- ]
+ "/css/css-gaps/multicol/multicol-gap-decorations-014-ref.html",
+ "=="
+ ]
+ ],
+ {}
]
- }
+ ],
+ "multicol-gap-decorations-015.html": [
+ "65af5112097f1a2d2d80ee5779fe5e5adc8b58a6",
+ [
+ null,
+ [
+ [
+ "/css/css-gaps/multicol/multicol-gap-decorations-015-ref.html",
+ "=="
+ ]
+ ],
+ {}
+ ]
+ ],
+ "multicol-gap-decorations-016.html": [
+ "da205e0b88bf7f8d8ca0988a54f6ac1237bc1669",
+ [
+ null,
+ [
+ [
+ "/css/css-gaps/multicol/multicol-gap-decorations-016-ref.html",
+ "=="
+ ]
+ ],
+ {}
+ ]
+ ]
}
},
"css-grid": {
@@ -190821,6 +190859,19 @@
{}
]
],
+ "grid-auto-fit-with-calc.html": [
+ "4b655c1e1218923f2ddeb75293dfc87f5ce1c8a8",
+ [
+ null,
+ [
+ [
+ "/css/reference/ref-filled-green-100px-square-only.html",
+ "=="
+ ]
+ ],
+ {}
+ ]
+ ],
"grid-auto-repeat-aspect-ratio-001.html": [
"bd744cf0cb30fd3349dfa85460ec1dd9ff962c40",
[
@@ -196247,6 +196298,19 @@
{}
]
],
+ "line-names-015.html": [
+ "6f5479abf8932d1e8da9950c339b3c8a2314960b",
+ [
+ null,
+ [
+ [
+ "/css/reference/ref-filled-green-100px-square.xht",
+ "=="
+ ]
+ ],
+ {}
+ ]
+ ],
"orthogonal-writing-mode-001.html": [
"1cf99a73e2ef7b0e3fe42bbf8c188fa4d2733979",
[
@@ -225549,19 +225613,6 @@
{}
]
],
- "line-clamp-auto-025.tentative.html": [
- "ab741d3df4d9ba823897ee1bcff1de9118353ada",
- [
- null,
- [
- [
- "/css/css-overflow/line-clamp/reference/webkit-line-clamp-005-ref.html",
- "=="
- ]
- ],
- {}
- ]
- ],
"line-clamp-auto-027.tentative.html": [
"9ed461d8cfb4c2ee035987148e15b6dcce3cdffa",
[
@@ -225615,7 +225666,7 @@
]
],
"line-clamp-auto-031.tentative.html": [
- "a723430c83ed7f0ea8ae8f2966d971c5c56d3cff",
+ "737caff7775d59ba02320bf942d479f083a0041c",
[
null,
[
@@ -225783,8 +225834,21 @@
{}
]
],
- "line-clamp-with-abspos-001.tentative.html": [
- "79667f23fbdc3d941484c343b2cf0a04ec34363f",
+ "line-clamp-with-abspos-001.html": [
+ "fd261493f0653a2cceaac302ca74640b3ce91db3",
+ [
+ null,
+ [
+ [
+ "/css/css-overflow/line-clamp/reference/line-clamp-with-abspos-001-ref.html",
+ "=="
+ ]
+ ],
+ {}
+ ]
+ ],
+ "line-clamp-with-abspos-002.html": [
+ "233a345c927e7af439943144a0ee6c989835744e",
[
null,
[
@@ -225796,8 +225860,8 @@
{}
]
],
- "line-clamp-with-abspos-002.tentative.html": [
- "cecb9d52bc63ec161dd96dfadcef166edd9334ed",
+ "line-clamp-with-abspos-003.html": [
+ "8b5d681d97c24b180f5dea407b1b94747c1b393a",
[
null,
[
@@ -225809,8 +225873,99 @@
{}
]
],
- "line-clamp-with-abspos-003.tentative.html": [
- "e4bd1de222e2b75455ae50d4c8bfa5c62b0c47c2",
+ "line-clamp-with-abspos-004.html": [
+ "c079974ac5c134474e9d16cd0317f29957a773fa",
+ [
+ null,
+ [
+ [
+ "/css/css-overflow/line-clamp/reference/line-clamp-with-abspos-001-ref.html",
+ "=="
+ ]
+ ],
+ {}
+ ]
+ ],
+ "line-clamp-with-abspos-005.html": [
+ "58656135cf00e70846cb057a03414879f9bd25f2",
+ [
+ null,
+ [
+ [
+ "/css/css-overflow/line-clamp/reference/line-clamp-with-abspos-005-ref.html",
+ "=="
+ ]
+ ],
+ {}
+ ]
+ ],
+ "line-clamp-with-abspos-006.html": [
+ "39f1758fa18f30c72db2c27fb442041e8bc4fdd0",
+ [
+ null,
+ [
+ [
+ "/css/css-overflow/line-clamp/reference/line-clamp-with-abspos-005-ref.html",
+ "=="
+ ]
+ ],
+ {}
+ ]
+ ],
+ "line-clamp-with-abspos-007.html": [
+ "f5b4e6ce291681dd7adfa87302bb2e61ca693a1c",
+ [
+ null,
+ [
+ [
+ "/css/css-overflow/line-clamp/reference/line-clamp-with-abspos-005-ref.html",
+ "=="
+ ]
+ ],
+ {}
+ ]
+ ],
+ "line-clamp-with-abspos-008.html": [
+ "cd619d515383e2dc418b7e6ab1b1da30c076a3b4",
+ [
+ null,
+ [
+ [
+ "/css/css-overflow/line-clamp/reference/line-clamp-with-abspos-005-ref.html",
+ "=="
+ ]
+ ],
+ {}
+ ]
+ ],
+ "line-clamp-with-abspos-009.html": [
+ "b3d332811d6a6539ab9524c47b9eae3ffc09ea57",
+ [
+ null,
+ [
+ [
+ "/css/css-overflow/line-clamp/reference/line-clamp-with-abspos-009-ref.html",
+ "=="
+ ]
+ ],
+ {}
+ ]
+ ],
+ "line-clamp-with-abspos-010.html": [
+ "8a7c2790d6c997b62ccc1bdf7d2e051822798e8a",
+ [
+ null,
+ [
+ [
+ "/css/css-overflow/line-clamp/reference/line-clamp-with-abspos-009-ref.html",
+ "=="
+ ]
+ ],
+ {}
+ ]
+ ],
+ "line-clamp-with-abspos-011.html": [
+ "cb4ab0514809e8ce7b6569f922a985f2e429414c",
[
null,
[
@@ -225822,8 +225977,8 @@
{}
]
],
- "line-clamp-with-abspos-004.tentative.html": [
- "483e6d1da6dc739599e25f3172b0ad248ac23c1b",
+ "line-clamp-with-abspos-012.html": [
+ "ae2f0364f39550edbc1e2ccfe094167bd1551f79",
[
null,
[
@@ -225835,8 +225990,190 @@
{}
]
],
- "line-clamp-with-abspos-005.tentative.html": [
- "3dc77831a06ffd28df3a5a4dca6045cba30fe1dd",
+ "line-clamp-with-abspos-013.html": [
+ "66a615ddd1c9b32903447a3aa8332ad87d5536cb",
+ [
+ null,
+ [
+ [
+ "/css/css-overflow/line-clamp/reference/line-clamp-with-abspos-013-ref.html",
+ "=="
+ ]
+ ],
+ {}
+ ]
+ ],
+ "line-clamp-with-abspos-014.html": [
+ "e8257d1d40297ba0603d4c20d8fd79a97e08b714",
+ [
+ null,
+ [
+ [
+ "/css/css-overflow/line-clamp/reference/line-clamp-with-abspos-013-ref.html",
+ "=="
+ ]
+ ],
+ {}
+ ]
+ ],
+ "line-clamp-with-abspos-015.html": [
+ "273610e071dbc2e355b8dc03ba96fae3882a4801",
+ [
+ null,
+ [
+ [
+ "/css/css-overflow/line-clamp/reference/webkit-line-clamp-005-ref.html",
+ "=="
+ ]
+ ],
+ {}
+ ]
+ ],
+ "line-clamp-with-abspos-016.html": [
+ "0b329a7d734b048e563faf8dbcfe6fdc35b9e8ed",
+ [
+ null,
+ [
+ [
+ "/css/css-overflow/line-clamp/reference/line-clamp-with-abspos-016-ref.html",
+ "=="
+ ]
+ ],
+ {}
+ ]
+ ],
+ "line-clamp-with-abspos-017.tentative.html": [
+ "8ae9cc949c69b20a4227d66348c6a7c552de8748",
+ [
+ null,
+ [
+ [
+ "/css/css-overflow/line-clamp/reference/webkit-line-clamp-030-ref.html",
+ "=="
+ ]
+ ],
+ {}
+ ]
+ ],
+ "line-clamp-with-abspos-018.html": [
+ "27139b18b8dec8f18efee3fa6bb9dc198d61c122",
+ [
+ null,
+ [
+ [
+ "/css/css-overflow/line-clamp/reference/line-clamp-with-abspos-018-ref.html",
+ "=="
+ ]
+ ],
+ {}
+ ]
+ ],
+ "line-clamp-with-abspos-019.html": [
+ "237ed69b67d29458ebbf9881b97bc6f5c0abbea4",
+ [
+ null,
+ [
+ [
+ "/css/css-overflow/line-clamp/reference/line-clamp-with-abspos-019-ref.html",
+ "=="
+ ]
+ ],
+ {}
+ ]
+ ],
+ "line-clamp-with-abspos-020.html": [
+ "55fb07c2061593aa17f0404c1eedfaf550ce1dae",
+ [
+ null,
+ [
+ [
+ "/css/css-overflow/line-clamp/reference/webkit-line-clamp-005-ref.html",
+ "=="
+ ]
+ ],
+ {}
+ ]
+ ],
+ "line-clamp-with-abspos-021.html": [
+ "21a0e96eee3fef22f8c44ba418e438db6ea2f0cc",
+ [
+ null,
+ [
+ [
+ "/css/css-overflow/line-clamp/reference/webkit-line-clamp-005-ref.html",
+ "=="
+ ]
+ ],
+ {}
+ ]
+ ],
+ "line-clamp-with-abspos-022.html": [
+ "6599365883b6d0a8507c4de31d033caa153dc114",
+ [
+ null,
+ [
+ [
+ "/css/css-overflow/line-clamp/reference/webkit-line-clamp-005-ref.html",
+ "=="
+ ]
+ ],
+ {}
+ ]
+ ],
+ "line-clamp-with-fixed-pos-001.html": [
+ "7f69c970baa5d81de1f0cf005e073481d44a41d7",
+ [
+ null,
+ [
+ [
+ "/css/css-overflow/line-clamp/reference/line-clamp-with-abspos-001-ref.html",
+ "=="
+ ]
+ ],
+ {}
+ ]
+ ],
+ "line-clamp-with-fixed-pos-002.html": [
+ "90eecbd6af6a9b0e58413843ab9962ef194be16e",
+ [
+ null,
+ [
+ [
+ "/css/css-overflow/line-clamp/reference/line-clamp-with-abspos-001-ref.html",
+ "=="
+ ]
+ ],
+ {}
+ ]
+ ],
+ "line-clamp-with-fixed-pos-003.html": [
+ "c4bc8a64784fac808edc4e1249d9a0e3c0a7b19f",
+ [
+ null,
+ [
+ [
+ "/css/css-overflow/line-clamp/reference/line-clamp-with-abspos-001-ref.html",
+ "=="
+ ]
+ ],
+ {}
+ ]
+ ],
+ "line-clamp-with-fixed-pos-004.html": [
+ "673b7d8c9d811c31e0d8ef383c56512977d6be89",
+ [
+ null,
+ [
+ [
+ "/css/css-overflow/line-clamp/reference/line-clamp-with-abspos-001-ref.html",
+ "=="
+ ]
+ ],
+ {}
+ ]
+ ],
+ "line-clamp-with-fixed-pos-005.html": [
+ "22cf7e0c132c0159a256a9a503962ac23068ae5e",
[
null,
[
@@ -225848,47 +226185,73 @@
{}
]
],
- "line-clamp-with-abspos-006.tentative.html": [
- "f18fed6c2daea0ab6e1ab715c1257407067fa97b",
+ "line-clamp-with-fixed-pos-006.html": [
+ "46f2e0b2b3976325e178f545ba2e00d004faa111",
[
null,
[
[
- "/css/css-overflow/line-clamp/reference/line-clamp-with-abspos-006-ref.html",
+ "/css/css-overflow/line-clamp/reference/line-clamp-with-abspos-005-ref.html",
"=="
]
],
{}
]
],
- "line-clamp-with-abspos-007.tentative.html": [
- "f0a1f58c8d304aead5490db007f763d437e9c5ad",
+ "line-clamp-with-fixed-pos-007.html": [
+ "0197ecb6d4a40c2cecc5461667d77bccc653ef8f",
[
null,
[
[
- "/css/css-overflow/line-clamp/reference/line-clamp-with-abspos-007-ref.html",
+ "/css/css-overflow/line-clamp/reference/line-clamp-with-abspos-005-ref.html",
"=="
]
],
{}
]
],
- "line-clamp-with-abspos-008.tentative.html": [
- "9c62e44f3897b5868dde26a6d6c203c7ddea4b8a",
+ "line-clamp-with-fixed-pos-008.html": [
+ "b14856a417f3e621085eefa7d2fe1d6a72cc87b4",
[
null,
[
[
- "/css/css-overflow/line-clamp/reference/line-clamp-with-abspos-008-ref.html",
+ "/css/css-overflow/line-clamp/reference/line-clamp-with-abspos-005-ref.html",
"=="
]
],
{}
]
],
- "line-clamp-with-abspos-009.tentative.html": [
- "dce04d720cfc83d82e2228204b7f6d41e244aabf",
+ "line-clamp-with-fixed-pos-009.html": [
+ "93faeed3bb10e75fa5357d164bdf4e8f199203b9",
+ [
+ null,
+ [
+ [
+ "/css/css-overflow/line-clamp/reference/line-clamp-with-abspos-009-ref.html",
+ "=="
+ ]
+ ],
+ {}
+ ]
+ ],
+ "line-clamp-with-fixed-pos-010.html": [
+ "8bd64fee61575251b6682ce7e6ccb14d4e4e18d0",
+ [
+ null,
+ [
+ [
+ "/css/css-overflow/line-clamp/reference/line-clamp-with-abspos-009-ref.html",
+ "=="
+ ]
+ ],
+ {}
+ ]
+ ],
+ "line-clamp-with-fixed-pos-011.html": [
+ "70273b36cda05e585483c0f690e58c38504d00d0",
[
null,
[
@@ -225900,34 +226263,47 @@
{}
]
],
- "line-clamp-with-abspos-010.tentative.html": [
- "325278b3a0b44f480ea020c575b9427b33f2ec4e",
+ "line-clamp-with-fixed-pos-012.html": [
+ "0e5584db10ba179821e784ce8709beb8188edf0d",
[
null,
[
[
- "/css/css-overflow/line-clamp/reference/line-clamp-with-abspos-010-ref.html",
+ "/css/css-overflow/line-clamp/reference/webkit-line-clamp-005-ref.html",
"=="
]
],
{}
]
],
- "line-clamp-with-abspos-011.tentative.html": [
- "ab5102a7cf2ea75cdb4729092d7618882e9c6ddf",
+ "line-clamp-with-fixed-pos-013.html": [
+ "580619be41e76bd45fbcde4f5ddbcf64f909ad3d",
[
null,
[
[
- "/css/css-overflow/line-clamp/reference/line-clamp-with-abspos-011-ref.html",
+ "/css/css-overflow/line-clamp/reference/line-clamp-with-abspos-013-ref.html",
"=="
]
],
{}
]
],
- "line-clamp-with-abspos-012.tentative.html": [
- "bed065f38381a9b151cee045b37b45de8f7cd0fb",
+ "line-clamp-with-fixed-pos-014.html": [
+ "371fb5957024db34777a4383bb7d981715d51ecd",
+ [
+ null,
+ [
+ [
+ "/css/css-overflow/line-clamp/reference/line-clamp-with-abspos-013-ref.html",
+ "=="
+ ]
+ ],
+ {}
+ ]
+ ],
+ "line-clamp-with-fixed-pos-015.html": [
+ "a458c11c04ea4599982047c8c403eca1212ee955",
[
null,
[
@@ -225939,8 +226315,8 @@
{}
]
],
- "line-clamp-with-abspos-013.tentative.html": [
- "ccea125f7246cf526da15a469261c3e90d4d2609",
+ "line-clamp-with-fixed-pos-016.html": [
+ "07a6f4e4f0d518a270e51a5ee7343677c43f28e3",
[
null,
[
@@ -225952,8 +226328,8 @@
{}
]
],
- "line-clamp-with-abspos-014.tentative.html": [
- "ea2f531207084097c4ab0406a270b045894a0d5d",
+ "line-clamp-with-fixed-pos-017.html": [
+ "97c77429ee49e9d00f9e6b12b852ec22866b1c7d",
[
null,
[
@@ -226745,7 +227121,7 @@
{}
]
],
- "webkit-line-clamp-abspos-001.tentative.html": [
+ "webkit-line-clamp-abspos-001.html": [
"fb8e027740d7991015313d62df86fbd147aa2f8b",
[
null,
@@ -310360,6 +310736,19 @@
}
]
],
+ "snapshot-containing-block-static-iframe.html": [
+ "1903b9cacbd334c3d0d6be4e7083cb1ced9d9b92",
+ [
+ null,
+ [
+ [
+ "/css/css-view-transitions/snapshot-containing-block-static-iframe-ref.html",
+ "=="
+ ]
+ ],
+ {}
+ ]
+ ],
"snapshot-containing-block-static.html": [
"fcea95e6efdb5d156a3c940faeef3928a3640910",
[
@@ -310612,6 +311001,19 @@
{}
]
],
+ "view-transition-name-stacking-context-dynamic.html": [
+ "1a908e6f65949a0874bb8dc107156c0db22f783a",
+ [
+ null,
+ [
+ [
+ "/css/reference/ref-filled-green-100px-square-only.html",
+ "=="
+ ]
+ ],
+ {}
+ ]
+ ],
"view-transition-types-match-early-mutation.html": [
"24737d9050ef6d53be5a44c553faa2901d014928",
[
@@ -322311,6 +322713,19 @@
{}
]
],
+ "orthogonal-dynamic-size-001.html": [
+ "add7f1fc2aa8ac0ecaa6452c6a171c9781e9fd83",
+ [
+ null,
+ [
+ [
+ "/css/reference/ref-filled-green-100px-square.xht",
+ "=="
+ ]
+ ],
+ {}
+ ]
+ ],
"orthogonal-root-resize-icb-001.html": [
"5e7ff7aef51344e8fa6fafed85318da33a33397b",
[
@@ -360140,7 +360555,7 @@
]
],
"lengths-1.html": [
- "896f08d111907e62a23a146299ab20a8a5260c09",
+ "224bedc1efc1149ad0cad381fbd3a43e398d4e06",
[
null,
[
@@ -371988,7 +372403,7 @@
"language_detection": {
"resources": {
"iframe-helper.html": [
- "fe07de3f8abac59ddbd6ccfd706a5e69c5b8b4c4",
+ "35ba852558725ecf4adb9af92e4bc0abb1cf8c38",
[]
],
"util.js": [
@@ -396319,6 +396734,10 @@
"67ce1b2759ef661b04d267b748bef435fc33aaf0",
[]
],
+ "partitioned-cookies-samesite-attributes-embed.html": [
+ "c6f64639eac8b432677933d4e9a5c36f4259548b",
+ []
+ ],
"partitioned-cookies-top-level-redirect.html": [
"c94beff5285578dab643c2c330e864135742291b",
[]
@@ -414280,7 +414699,7 @@
[]
],
"align-self-static-position-005-ref.html": [
- "947bd2704481f757f3d1f4bf51105483978cc7ff",
+ "62597fba605b06b5b0240f808d85b633d763bbe3",
[]
],
"align-self-static-position-006-ref.html": [
@@ -431252,65 +431671,71 @@
[]
]
},
- "tentative": {
- "multicol": {
- "multicol-gap-decorations-001-ref.html": [
- "834c96ccd397fbc41abcfb80dbd298094cb929b1",
- []
- ],
- "multicol-gap-decorations-002-ref.html": [
- "d132f0ca6770be13d87ee66fb033f2f498d0e37b",
- []
- ],
- "multicol-gap-decorations-003-ref.html": [
- "cd26da243891f05c83c5d1eea17c747dcf390f05",
- []
- ],
- "multicol-gap-decorations-004-ref.html": [
- "002b1f2b594cf791b6d66613f48128e915517e01",
- []
- ],
- "multicol-gap-decorations-005-ref.html": [
- "6543021c97934a217568e567ac005166f7a9c0a0",
- []
- ],
- "multicol-gap-decorations-006-ref.html": [
- "4cb56d207fef4f801ec2063828103712267c030e",
- []
- ],
- "multicol-gap-decorations-007-ref.html": [
- "09973ddc690a899be9fb321e603b7831bfeb22a7",
- []
- ],
- "multicol-gap-decorations-008-ref.html": [
- "d49c2f50f1909d5b04be07798e62448d9b82ab72",
- []
- ],
- "multicol-gap-decorations-009-ref.html": [
- "124bf7eaeb1779d067d84f1c30560f45763add7c",
- []
- ],
- "multicol-gap-decorations-010-ref.html": [
- "9582ab4103d197d25823ed75dc8cafa83e0b1a7c",
- []
- ],
- "multicol-gap-decorations-011-ref.html": [
- "3387918d399cdbd3b39364ebe954a2a204a5145c",
- []
- ],
- "multicol-gap-decorations-012-ref.html": [
- "9fb5e85e920812d259e057c7538d35db56659b05",
- []
- ],
- "multicol-gap-decorations-013-ref.html": [
- "8e426d8ed32b25248e602e063e69678ca94b5e09",
- []
- ],
- "multicol-gap-decorations-014-ref.html": [
- "9d9674bd476896f0f1b03ec6835b069c97d9c8e5",
- []
- ]
- }
+ "multicol": {
+ "multicol-gap-decorations-001-ref.html": [
+ "834c96ccd397fbc41abcfb80dbd298094cb929b1",
+ []
+ ],
+ "multicol-gap-decorations-002-ref.html": [
+ "d132f0ca6770be13d87ee66fb033f2f498d0e37b",
+ []
+ ],
+ "multicol-gap-decorations-003-ref.html": [
+ "cd26da243891f05c83c5d1eea17c747dcf390f05",
+ []
+ ],
+ "multicol-gap-decorations-004-ref.html": [
+ "002b1f2b594cf791b6d66613f48128e915517e01",
+ []
+ ],
+ "multicol-gap-decorations-005-ref.html": [
+ "6543021c97934a217568e567ac005166f7a9c0a0",
+ []
+ ],
+ "multicol-gap-decorations-006-ref.html": [
+ "4cb56d207fef4f801ec2063828103712267c030e",
+ []
+ ],
+ "multicol-gap-decorations-007-ref.html": [
+ "09973ddc690a899be9fb321e603b7831bfeb22a7",
+ []
+ ],
+ "multicol-gap-decorations-008-ref.html": [
+ "d49c2f50f1909d5b04be07798e62448d9b82ab72",
+ []
+ ],
+ "multicol-gap-decorations-009-ref.html": [
+ "124bf7eaeb1779d067d84f1c30560f45763add7c",
+ []
+ ],
+ "multicol-gap-decorations-010-ref.html": [
+ "9582ab4103d197d25823ed75dc8cafa83e0b1a7c",
+ []
+ ],
+ "multicol-gap-decorations-011-ref.html": [
+ "3387918d399cdbd3b39364ebe954a2a204a5145c",
+ []
+ ],
+ "multicol-gap-decorations-012-ref.html": [
+ "9fb5e85e920812d259e057c7538d35db56659b05",
+ []
+ ],
+ "multicol-gap-decorations-013-ref.html": [
+ "8e426d8ed32b25248e602e063e69678ca94b5e09",
+ []
+ ],
+ "multicol-gap-decorations-014-ref.html": [
+ "9d9674bd476896f0f1b03ec6835b069c97d9c8e5",
+ []
+ ],
+ "multicol-gap-decorations-015-ref.html": [
+ "2fee77be84c105e2f1001d13152883c5a7dea6e4",
+ []
+ ],
+ "multicol-gap-decorations-016-ref.html": [
+ "8b2458fccce5a190c2c804b7e552dc0d85a8849a",
+ []
+ ]
}
},
"css-gcpm": {
@@ -438063,31 +438488,31 @@
[]
],
"line-clamp-with-abspos-001-ref.html": [
- "d756162dde0c54bd52646597b01bbff8a80f5fd8",
+ "ffa463369c1bcd592661c7d1bb8f8a9eed57a536",
[]
],
"line-clamp-with-abspos-005-ref.html": [
- "3b1f9218e887a7e50745f0c5e540c099475a59df",
+ "9825838e7b434d38c53cc49f830c7c9120a995ab",
[]
],
- "line-clamp-with-abspos-006-ref.html": [
- "4b55c37a033ea4d4a9d97b5fdf8035a60aace4bd",
+ "line-clamp-with-abspos-009-ref.html": [
+ "cc3a43df2386b26f6d3ff2de67961503c7700389",
[]
],
- "line-clamp-with-abspos-007-ref.html": [
- "e3dcc696e39684b47e1785968f29ec9adf8f9c0b",
+ "line-clamp-with-abspos-013-ref.html": [
+ "cae83ecc37c713b710c688d39c528cb2108bf48e",
[]
],
- "line-clamp-with-abspos-008-ref.html": [
- "373b2755c1d617e1716afe8060c28b246d52c33e",
+ "line-clamp-with-abspos-016-ref.html": [
+ "3c8011394d295ce65eca946b4c88255eefb24631",
[]
],
- "line-clamp-with-abspos-010-ref.html": [
+ "line-clamp-with-abspos-018-ref.html": [
"ecc2fcee1b5219b310ef15b28f0684b07d84baf6",
[]
],
- "line-clamp-with-abspos-011-ref.html": [
- "f08b0270e8d7aa8a389910319617528dac6a4240",
+ "line-clamp-with-abspos-019-ref.html": [
+ "f97a972532556b347c95cf5b10bdbd649b5335be",
[]
],
"line-clamp-with-floats-001-ref.html": [
@@ -453600,6 +454025,10 @@
"c219fb1edd4c24f29760aef7e18332f7362accf7",
[]
],
+ "snapshot-containing-block-static-iframe-ref.html": [
+ "188cefecd3d9b225b594e5604aeb68774762d442",
+ []
+ ],
"snapshot-containing-block-static-ref.html": [
"0bff68efb23da1a7bf2189f8bcea4a936faeba94",
[]
@@ -459501,21 +459930,25 @@
"d062affc1848e3f315ef4f7e1d30319545bc7992",
[]
],
- "dc-types.ts": [
- "30284e7fad68ea31854bef5e1a47364b11e46d19",
+ "create.disabled-by-permissions-policy.https.sub.html.headers": [
+ "9847d173eb6278152c83f719914f604375b4d151",
[]
],
- "disabled-by-permissions-policy.https.sub.html.headers": [
- "02a76b7c3f289bed45a44e7c949b4792fd798dbc",
+ "dc-types.ts": [
+ "83168f8a343469d479c5a11736e6e1e5ae35f6b1",
[]
],
"enabled-on-self-origin-by-permissions-policy.https.sub.html.headers": [
- "1207d9e29a111a46b920d27dd3188bae1e6cf8f4",
+ "4de358e6a4404c94768441ee20cfc9e7f6191b06",
+ []
+ ],
+ "get.disabled-by-permissions-policy.https.sub.html.headers": [
+ "5672154a42328b467a7cbf9e1ad94f3b2e7842d8",
[]
],
"support": {
"helper.js": [
- "71022432652c19ccb7272b02f723dcf748d9e7b3",
+ "5a9cda347888a2527ac059e332d6ad14331dc7ef",
[]
],
"iframe.html": [
@@ -462223,7 +462656,7 @@
[]
],
"event-timing-test-utils.js": [
- "7bd9782000f40d9f96d8c7074337e6dbaa7aaeeb",
+ "59c78ebf39c8a8e0f31aafa1eccd0809bea54376",
[]
],
"slow-image.py": [
@@ -466336,6 +466769,10 @@
"70f366a3d0b7ec891fc4041584a1ddea55b0bc42",
[]
],
+ "css-units.woff": [
+ "0957a2fc973700ac5bff6586bc60721b7d4142da",
+ []
+ ],
"fraction-axisheight7000-rulethickness1000.woff": [
"2a9d78cc9d430e9987e977ef83f4e47dfee6a99f",
[]
@@ -488500,7 +488937,7 @@
[]
],
"lengths-1-ref.html": [
- "9fca6f49632ca080ee1b2a32a9ce2d251241dfcc",
+ "74c1397ce62593293b1444dfd52c959856a9060e",
[]
],
"mathbackground-001-notref.html": [
@@ -488818,6 +489255,10 @@
"7640c4f789cc0248f450b2491b70da3510167c1f",
[]
],
+ "css-units.py": [
+ "cdf06bb77445c9b8fd2c2464d9725513b4eb3e35",
+ []
+ ],
"fractions.py": [
"bd39fc2fdbede519138e577269c6aacf802b303e",
[]
@@ -491384,6 +491825,10 @@
"56780cf6dc05879731bff0bbb1486c51b0b4141b",
[]
],
+ "digital-credentials-create.html": [
+ "aafd436282e8b740c713aaeeb6d28c0ab60cc324",
+ []
+ ],
"digital-credentials-get.html": [
"543417f230a59b3d09705b20775a38cbabaf7a22",
[]
@@ -498561,7 +499006,7 @@
],
"resources": {
"property-reflection-helper.js": [
- "79f1bd7f7483fd53d80fe4e0c824a80987656dfe",
+ "88b7f743831acbfd41ed4ae6a782733bde9875a6",
[]
]
}
@@ -499403,7 +499848,7 @@
[]
],
"soft-navigation-helper.js": [
- "d405adb4e7eb7690fe73f31db523d357a38734ee",
+ "a29978c8760495ffccbd6fc56d62f4625d89334d",
[]
]
}
@@ -499434,11 +499879,11 @@
},
"resources": {
"authenticate.py": [
- "ea0c546afffb5ab7701557ce9d7bf54aa8fbc95a",
+ "b2ca9c450e07278f654a54c868d42c90520451c1",
[]
],
"basic-service-worker.js": [
- "18432ed62eddb209488a5dd00f39e9c77e071498",
+ "17fccd448d2412287515f6176b0731189eb8eede",
[]
],
"conditional-status.py": [
@@ -499446,7 +499891,7 @@
[]
],
"cookies.py": [
- "54aaabee70e697283fddd5016358b0775bf9d0a6",
+ "1b56c674c0b6643ab1485500276582805ac8ec62",
[]
],
"counting-executor.py": [
@@ -499466,7 +499911,7 @@
[]
],
"prefetch_nvs_hint.py": [
- "223135dc8b82ea8f32b7abab8e1e3ed0d77d0bbd",
+ "f4ecb004bc1d6ec9e1eaa3199cd6d0bc54734afd",
[]
],
"random_redirect.py": [
@@ -499494,7 +499939,7 @@
[]
],
"utils.sub.js": [
- "a90459fdf03822446dc445b294e974587e507717",
+ "d4efc2dc7dce21e1da25842aceda4c3fc50227da",
[]
]
},
@@ -500209,6 +500654,16 @@
"9ab6e1284ad50d2982ea1f6fc78d7a519e796460",
[]
],
+ "WEB_FEATURES.yml": [
+ "d10bbe4a7d7012c197805bc997044989779d23ea",
+ []
+ ],
+ "piping": {
+ "WEB_FEATURES.yml": [
+ "8cf3517baf08a4611d43a4b0c8d1763835ef19fa",
+ []
+ ]
+ },
"readable-byte-streams": {
"WEB_FEATURES.yml": [
"a35508fc0dc65d5fcbf785289c5bd05674de7b32",
@@ -500216,7 +500671,15 @@
]
},
"readable-streams": {
+ "WEB_FEATURES.yml": [
+ "ad2cb549631fd2b1ab480db217c345d79998c215",
+ []
+ ],
"crashtests": {
+ "WEB_FEATURES.yml": [
+ "b5dbd1ff4199707f1ef59f40a7f5194ec8e5fa4a",
+ []
+ ],
"empty.js": [
"e69de29bb2d1d6434b8b29ae775ad8c2e48c5391",
[]
@@ -500296,6 +500759,18 @@
[]
]
}
+ },
+ "transform-streams": {
+ "WEB_FEATURES.yml": [
+ "f39dc16de4c73144c772133264f2691855fa2e4e",
+ []
+ ]
+ },
+ "writable-streams": {
+ "WEB_FEATURES.yml": [
+ "8cf3517baf08a4611d43a4b0c8d1763835ef19fa",
+ []
+ ]
}
},
"subapps": {
@@ -501957,7 +502432,7 @@
[]
],
"requirements_macos_color_profile.txt": [
- "cd3e785aa47963c00137c5c94d55c8f3cb692d8e",
+ "5b95e3357b806cc6edfcbc9aff7b78c341dc8732",
[]
],
"requirements_tc.txt": [
@@ -522363,7 +522838,7 @@
[]
],
"matchDepthViewValues.js": [
- "597f9734d3fe66c2600c291a643a6d70ec908a25",
+ "697f4deb8ffce83d29dfc0dde36ee4e6c8ec1e87",
[]
],
"pauseResumeTests.js": [
@@ -550778,10 +551253,13 @@
"ai": {
"language_detection": {
"detector-iframe.https.html": [
- "ddcf82bec684024f855217c649bb2da6cbd1f577",
+ "9dc39d44a007934715b181c0025cc885db33264e",
[
null,
- {}
+ {
+ "testdriver": true,
+ "timeout": "long"
+ }
]
],
"detector-locale.https.window.js": [
@@ -550824,7 +551302,7 @@
]
],
"detector.https.window.js": [
- "b0255bc552b0d2f7c71f8567bab9e0102702cd4c",
+ "379b87415347a1980209fb471d9b1ccb78ccd032",
[
"ai/language_detection/detector.https.window.html",
{
@@ -550899,67 +551377,10 @@
]
},
"summarizer": {
- "summarizer-abort.tentative.https.any.js": [
+ "summarizer-abort.tentative.https.window.js": [
"64595ea930c9e21b8044a281c2f9f4d467478772",
[
- "ai/summarizer/summarizer-abort.tentative.https.any.html",
- {
- "script_metadata": [
- [
- "title",
- "Summarizer Abort"
- ],
- [
- "global",
- "window,worker"
- ],
- [
- "script",
- "../resources/util.js"
- ]
- ]
- }
- ],
- [
- "ai/summarizer/summarizer-abort.tentative.https.any.serviceworker.html",
- {
- "script_metadata": [
- [
- "title",
- "Summarizer Abort"
- ],
- [
- "global",
- "window,worker"
- ],
- [
- "script",
- "../resources/util.js"
- ]
- ]
- }
- ],
- [
- "ai/summarizer/summarizer-abort.tentative.https.any.sharedworker.html",
- {
- "script_metadata": [
- [
- "title",
- "Summarizer Abort"
- ],
- [
- "global",
- "window,worker"
- ],
- [
- "script",
- "../resources/util.js"
- ]
- ]
- }
- ],
- [
- "ai/summarizer/summarizer-abort.tentative.https.any.worker.html",
+ "ai/summarizer/summarizer-abort.tentative.https.window.html",
{
"script_metadata": [
[
@@ -550978,30 +551399,10 @@
}
]
],
- "summarizer-availability-available.tentative.https.any.js": [
+ "summarizer-availability-available.tentative.https.window.js": [
"31c21ca777fb09fc8058b57d5d8230d3f3798410",
[
- "ai/summarizer/summarizer-availability-available.tentative.https.any.html",
- {
- "script_metadata": [
- [
- "title",
- "Summarizer Availability Available"
- ],
- [
- "script",
- "../resources/util.js"
- ],
- [
- "timeout",
- "long"
- ]
- ],
- "timeout": "long"
- }
- ],
- [
- "ai/summarizer/summarizer-availability-available.tentative.https.any.worker.html",
+ "ai/summarizer/summarizer-availability-available.tentative.https.window.html",
{
"script_metadata": [
[
@@ -551021,30 +551422,10 @@
}
]
],
- "summarizer-availability.tentative.https.any.js": [
+ "summarizer-availability.tentative.https.window.js": [
"8691765f6933a576711282750b0d7ebca99e98e8",
[
- "ai/summarizer/summarizer-availability.tentative.https.any.html",
- {
- "script_metadata": [
- [
- "title",
- "Summarizer Availability"
- ],
- [
- "script",
- "../resources/util.js"
- ],
- [
- "timeout",
- "long"
- ]
- ],
- "timeout": "long"
- }
- ],
- [
- "ai/summarizer/summarizer-availability.tentative.https.any.worker.html",
+ "ai/summarizer/summarizer-availability.tentative.https.window.html",
{
"script_metadata": [
[
@@ -551064,30 +551445,10 @@
}
]
],
- "summarizer-create-available.tentative.https.any.js": [
+ "summarizer-create-available.tentative.https.window.js": [
"c7e27d9766bee9b62d7b8463654dfea7536cb338",
[
- "ai/summarizer/summarizer-create-available.tentative.https.any.html",
- {
- "script_metadata": [
- [
- "title",
- "Summarizer Create Available"
- ],
- [
- "script",
- "../resources/util.js"
- ],
- [
- "timeout",
- "long"
- ]
- ],
- "timeout": "long"
- }
- ],
- [
- "ai/summarizer/summarizer-create-available.tentative.https.any.worker.html",
+ "ai/summarizer/summarizer-create-available.tentative.https.window.html",
{
"script_metadata": [
[
@@ -551107,30 +551468,10 @@
}
]
],
- "summarizer-create.tentative.https.any.js": [
+ "summarizer-create.tentative.https.window.js": [
"328cceefefb11dab0844cfee5773a5194aabd52e",
[
- "ai/summarizer/summarizer-create.tentative.https.any.html",
- {
- "script_metadata": [
- [
- "title",
- "Summarizer Create"
- ],
- [
- "script",
- "../resources/util.js"
- ],
- [
- "timeout",
- "long"
- ]
- ],
- "timeout": "long"
- }
- ],
- [
- "ai/summarizer/summarizer-create.tentative.https.any.worker.html",
+ "ai/summarizer/summarizer-create.tentative.https.window.html",
{
"script_metadata": [
[
@@ -551157,30 +551498,10 @@
{}
]
],
- "summarizer-measureInputUsage.tentative.https.any.js": [
+ "summarizer-measureInputUsage.tentative.https.window.js": [
"ce9745acf173c8d94a52427446460a47c6fbb378",
[
- "ai/summarizer/summarizer-measureInputUsage.tentative.https.any.html",
- {
- "script_metadata": [
- [
- "title",
- "Summarizer measureInputUsage"
- ],
- [
- "script",
- "../resources/util.js"
- ],
- [
- "timeout",
- "long"
- ]
- ],
- "timeout": "long"
- }
- ],
- [
- "ai/summarizer/summarizer-measureInputUsage.tentative.https.any.worker.html",
+ "ai/summarizer/summarizer-measureInputUsage.tentative.https.window.html",
{
"script_metadata": [
[
@@ -551200,30 +551521,10 @@
}
]
],
- "summarizer-summarize-streaming.tentative.https.any.js": [
+ "summarizer-summarize-streaming.tentative.https.window.js": [
"dbf41cdadbc679e68279886506660262952f0b5e",
[
- "ai/summarizer/summarizer-summarize-streaming.tentative.https.any.html",
- {
- "script_metadata": [
- [
- "title",
- "Summarizer Summarize Streaming"
- ],
- [
- "script",
- "../resources/util.js"
- ],
- [
- "timeout",
- "long"
- ]
- ],
- "timeout": "long"
- }
- ],
- [
- "ai/summarizer/summarizer-summarize-streaming.tentative.https.any.worker.html",
+ "ai/summarizer/summarizer-summarize-streaming.tentative.https.window.html",
{
"script_metadata": [
[
@@ -551243,30 +551544,10 @@
}
]
],
- "summarizer-summarize.tentative.https.any.js": [
+ "summarizer-summarize.tentative.https.window.js": [
"62a780a3fc7960f30b2f4ab6beab89f9e570699f",
[
- "ai/summarizer/summarizer-summarize.tentative.https.any.html",
- {
- "script_metadata": [
- [
- "title",
- "Summarizer Create Available"
- ],
- [
- "script",
- "../resources/util.js"
- ],
- [
- "timeout",
- "long"
- ]
- ],
- "timeout": "long"
- }
- ],
- [
- "ai/summarizer/summarizer-summarize.tentative.https.any.worker.html",
+ "ai/summarizer/summarizer-summarize.tentative.https.window.html",
{
"script_metadata": [
[
@@ -571748,7 +572029,7 @@
]
],
"eval-blocked-in-about-blank-iframe.html": [
- "054e75b52749b37530a02bc5ee0119ca5e76a474",
+ "b2286f56a234a515cddec0e02439f9768e3a2905",
[
null,
{}
@@ -573625,6 +573906,24 @@
{}
]
],
+ "serviceworker_cookiechange_eventhandler_already_expired.https.any.js": [
+ "c40fdbeb6f108db1ea6e100c833a03c3fedbfc19",
+ [
+ "cookie-store/serviceworker_cookiechange_eventhandler_already_expired.https.any.serviceworker.html",
+ {
+ "script_metadata": [
+ [
+ "title",
+ "Cookie Store API: cookiechange event in ServiceWorker with already-expired cookie."
+ ],
+ [
+ "global",
+ "serviceworker"
+ ]
+ ]
+ }
+ ]
+ ],
"serviceworker_cookiechange_eventhandler_mismatched_subscription.https.any.js": [
"30d8d70940dae248b3b5cba030056daac78b32a6",
[
@@ -573661,6 +573960,24 @@
}
]
],
+ "serviceworker_cookiechange_eventhandler_no_change.https.any.js": [
+ "fb2e2db7381fea7cbd3463576e126e1581a32d97",
+ [
+ "cookie-store/serviceworker_cookiechange_eventhandler_no_change.https.any.serviceworker.html",
+ {
+ "script_metadata": [
+ [
+ "title",
+ "Cookie Store API: cookiechange event in ServiceWorker with already-expired cookie."
+ ],
+ [
+ "global",
+ "serviceworker"
+ ]
+ ]
+ }
+ ]
+ ],
"serviceworker_cookiechange_eventhandler_overlapping_subscriptions.https.any.js": [
"f8b1c1b7aa96f13ec40df6dfdfef2c605c447468",
[
@@ -573952,6 +574269,16 @@
}
]
],
+ "partitioned-cookies-samesite-attribute.https.html": [
+ "323fb08236eb35b207ea72fa0db80fc6f20d7d6a",
+ [
+ null,
+ {
+ "testdriver": true,
+ "timeout": "long"
+ }
+ ]
+ ],
"partitioned-cookies-top-level-redirect.tentative.https.html": [
"e9dd82c1cec0d1bad55d4dbdd66ecdb01e9d2ed7",
[
@@ -596095,6 +596422,15 @@
}
]
],
+ "scroll-marker-active-unreached-target.html": [
+ "6a6bcc2891f56709aaaee6442f5abc6c0877c297",
+ [
+ null,
+ {
+ "testdriver": true
+ }
+ ]
+ ],
"scroll-marker-controls-scroll-tracking-001.html": [
"42dff1a7800176a6d5de9ecbf07d59dd47350e76",
[
@@ -607752,7 +608088,7 @@
]
],
"transform-valid.html": [
- "89a8b519b1b9c702d7bdedd3895e90c057a34dcb",
+ "b436fbdea30ec14b989bef19a747c67255fa2935",
[
null,
{}
@@ -613154,7 +613490,7 @@
],
"tree-counting": {
"calc-sibling-function-in-shadow-dom.html": [
- "92fb6ce3351b9c37b3616445b4f83969a5f30b63",
+ "ca8eb560ba13c8849a468442cc242a68398bbb9f",
[
null,
{}
@@ -613189,7 +613525,7 @@
]
],
"sibling-function-invalidation.html": [
- "3c75c78530dca4cfb30dfc0c17c0ad2049cfb087",
+ "74f4995f5f72413330e577a3a4c72ce095479225",
[
null,
{}
@@ -614234,6 +614570,20 @@
]
],
"scoped": {
+ "auto-name-on-descendant.html": [
+ "01d570e8bfced7cd702f42ed4def947b5f74e007",
+ [
+ null,
+ {}
+ ]
+ ],
+ "auto-name.html": [
+ "2d11985b3986b479304d5de0195eea1840148868",
+ [
+ null,
+ {}
+ ]
+ ],
"capture.html": [
"06f848d2de16d7a26defcc3279d24622ceb32f54",
[
@@ -614241,6 +614591,20 @@
{}
]
],
+ "display-none-during-transition.html": [
+ "f94d6f7fd76af7a889e5a9a1cf6fc6538377eb0e",
+ [
+ null,
+ {}
+ ]
+ ],
+ "document-element-start-view-transition.html": [
+ "42f87f93a07fac6715d422dea4d1e5835437858e",
+ [
+ null,
+ {}
+ ]
+ ],
"run_in_parallel.html": [
"1afdae2be9d8092953746d360d2a77ea1a538ba1",
[
@@ -614332,7 +614696,7 @@
]
],
"view-transition-types-mutable-no-document-element-crashtest.html": [
- "f1940c398695989d6cc569ffb25a03a83be1d064",
+ "d5c0abd652cd3c673a71979a458df8183ab057ba",
[
null,
{}
@@ -614353,7 +614717,7 @@
]
],
"window-resize-aborts-transition-before-ready.html": [
- "3c4ba37b26b0dff7f4e0d79ef55dd95f1a375ce1",
+ "09e6e6cc1c9c003237c280bf2612109f3b7f379f",
[
null,
{
@@ -614362,7 +614726,7 @@
]
],
"window-resize-aborts-transition.html": [
- "8d61a3e3c53998cf612ff544895cd0f34f96a6e8",
+ "966f23c0fdf98ba31fbfa8ce627460a50fa10b0b",
[
null,
{
@@ -621925,8 +622289,8 @@
]
},
"digital-credentials": {
- "allow-attribute.https.html": [
- "667b84bc704c23602b481538ea16f6f77f801902",
+ "allow-attribute-with-create.https.html": [
+ "4b1e96fec4cb62d336d3c1358a7c9781e6657f8d",
[
null,
{
@@ -621934,8 +622298,8 @@
}
]
],
- "create.tentative.https.html": [
- "299a240ced17f11c8d5249d65b54e873fe3362b3",
+ "allow-attribute-with-get.https.html": [
+ "15601d891f25c4c2d75dad2260d1b45a26a9344d",
[
null,
{
@@ -621943,8 +622307,8 @@
}
]
],
- "default-permissions-policy.https.sub.html": [
- "742a94ec4eb8ff079b1b24f17179962818fb3868",
+ "create.disabled-by-permissions-policy.https.sub.html": [
+ "52db2373f09596b01e2df28fdf14e34e540d3777",
[
null,
{
@@ -621952,15 +622316,17 @@
}
]
],
- "digital-credentials-static-methods.tentative.https.html": [
- "5e00861124fd1755f90f4107824c4f3aae3bf5b0",
+ "create.tentative.https.html": [
+ "3e17d5b0853b38b36cb640ee665a12c398eb4ed3",
[
null,
- {}
+ {
+ "testdriver": true
+ }
]
],
- "disabled-by-permissions-policy.https.sub.html": [
- "c32f73aa309b64e5785d67b3565077a8ac6b8424",
+ "default-permissions-policy.https.sub.html": [
+ "8041e25d33bd302fb6bcbf37f7111a00f5907fe2",
[
null,
{
@@ -621968,8 +622334,15 @@
}
]
],
+ "digital-credentials-static-methods.tentative.https.html": [
+ "5e00861124fd1755f90f4107824c4f3aae3bf5b0",
+ [
+ null,
+ {}
+ ]
+ ],
"enabled-on-self-origin-by-permissions-policy.https.sub.html": [
- "d530f4920a395b0a612964a32b60fec65833054e",
+ "261ebb0ce705329cf7fe54fa50cbb6e20179fe0c",
[
null,
{
@@ -621977,8 +622350,8 @@
}
]
],
- "get-user-activation.https.html": [
- "fbf2099dad37443c4522e3a838ab962f2c260004",
+ "get.disabled-by-permissions-policy.https.sub.html": [
+ "c32f73aa309b64e5785d67b3565077a8ac6b8424",
[
null,
{
@@ -621987,7 +622360,7 @@
]
],
"get.tentative.https.html": [
- "a090e1b14321bd31ea3e1d5470bbe9442a99dd08",
+ "b04a6e3a713e26f759cc62d81a6a439ea69e189e",
[
null,
{
@@ -622014,6 +622387,15 @@
"testdriver": true
}
]
+ ],
+ "user-activation.https.html": [
+ "facaf7bddbbd419801a9ffa470f4bb5bbc1ab07c",
+ [
+ null,
+ {
+ "testdriver": true
+ }
+ ]
]
},
"direct-sockets": {
@@ -646358,7 +646740,7 @@
]
],
"interactionid-orphan-pointerup.html": [
- "9c4a0ecf584e83f3efa531c19be82aecfaa42917",
+ "e08142f11bce202d852a93e88c4f33ac69c11e96",
[
null,
{
@@ -723848,6 +724230,21 @@
}
]
],
+ "tab-table-caption.html": [
+ "a26c8f0e7ed83827a385de5e351b2d90a4fad47b",
+ [
+ "html/interaction/focus/tab-table-caption.html?caption-side=bottom",
+ {
+ "testdriver": true
+ }
+ ],
+ [
+ "html/interaction/focus/tab-table-caption.html?caption-side=top",
+ {
+ "testdriver": true
+ }
+ ]
+ ],
"tabindex-focus-flag.html": [
"93fdb19a592ff632405c338256082043ae608002",
[
@@ -733381,7 +733778,7 @@
]
],
"select-parsing.tentative.html": [
- "cc6596b42fe80caa895e2997dcc86533558fb87a",
+ "0c6972bcab5b8d039bb1634d675276d2d7c8a28a",
[
null,
{}
@@ -733505,7 +733902,7 @@
},
"customizable-select-in-page": {
"customizable-select-in-page-keyboard-behavior.tentative.html": [
- "24e6e39ea48236fc7b72604860913247b5f5f05c",
+ "7040105c096d4b9f3512bf1cbbec7dfa05f5dd77",
[
null,
{
@@ -734185,8 +734582,18 @@
{}
]
],
+ "dialog-closedby-bounds-clicking.html": [
+ "584d4b306446c50c9d0c7c0a58849f9250b27956",
+ [
+ null,
+ {
+ "testdriver": true,
+ "timeout": "long"
+ }
+ ]
+ ],
"dialog-closedby-corner-cases.html": [
- "e25b9533b905f52decdcde07992ee587e41ca7c6",
+ "06a9084415410e208ea3d75bcf04547aad829072",
[
null,
{
@@ -734206,7 +734613,7 @@
]
],
"dialog-closedby.html": [
- "50d600219d202cb0e4df33fde899b287dc9a3edf",
+ "b67bc80765aded1bf376d967ebce989b2861cf12",
[
null,
{
@@ -753626,7 +754033,14 @@
]
],
"lengths-2.html": [
- "942611a8dada4dae5fcc133ff01993226c6941df",
+ "af5cae1368832d6f40d2cd68b73be1b0fb5e4385",
+ [
+ null,
+ {}
+ ]
+ ],
+ "lengths-vi-vb-units.html": [
+ "a01fd13b98fbc1c03ab087169d7f7c7919779ec6",
[
null,
{}
@@ -794567,6 +794981,15 @@
}
]
],
+ "property-reflection-idl-setters.html": [
+ "74f2e670915f894b2cc4d8b0443028900c0154c3",
+ [
+ null,
+ {
+ "testdriver": true
+ }
+ ]
+ ],
"property-reflection-imperative-setup.html": [
"44039295169999ce58f0b8904da6c64e718704f2",
[
@@ -796645,7 +797068,7 @@
]
],
"interaction-with-paint-before-back.tentative.html": [
- "b587411991383e47381e14fc6e00c0bcfc2dc447",
+ "7b884f2bdb38945a346c3b5a8b178c04e88989ad",
[
null,
{
@@ -797818,7 +798241,7 @@
"tentative": {
"service-worker": {
"basic.sub.https.html": [
- "bee8e2ff1f4515afa805fa37e86f25effe66c22e",
+ "98e089bcc660f24ba3e82425e2b23ef928a0f08a",
[
"speculation-rules/prefetch/tentative/service-worker/basic.sub.https.html?origin=cross-site&sw=fetch-handler",
{
@@ -818130,7 +818553,7 @@
]
],
"block-string-assignment-to-Document-write.html": [
- "0b16a9c4910070b2bcf829d15b1aba8b7be9d060",
+ "c774dca4390955b3b91f1648adb18ad22bd6e355",
[
null,
{}
@@ -823418,7 +823841,7 @@
]
],
"viewport-segments-env-variables.https.html": [
- "6004398b2ce20ca0580380b6bc570f6bf8108683",
+ "dce6757d49a39059d67433e1663813ce56b093eb",
[
null,
{
@@ -823427,7 +823850,7 @@
]
],
"viewport-segments-segments-property.https.html": [
- "e6c9d8b4e169ad061ae7aef5ca270894dbb1db2c",
+ "653e2bcb2530ef0bd86712981726f2df71ac093f",
[
null,
{
@@ -851961,7 +852384,7 @@
]
],
"dequantizeLinear.https.any.js": [
- "900bb57bacfd379bc81a24b1ec622d914a3e5455",
+ "7f1ed15cc4a36aba360daebda56a44da32620a5b",
[
"webnn/conformance_tests/dequantizeLinear.https.any.html?cpu",
{
@@ -928416,7 +928839,7 @@
},
"uninstall": {
"invalid.py": [
- "54fbb22cf5ebeb1cc633835ae8a1bb5523313d3d",
+ "228f0e57e52f67cd777fa1c7df96a22df4880235",
[
null,
{}
diff --git a/tests/wpt/meta/content-security-policy/generic/invalid-characters-in-policy.html.ini b/tests/wpt/meta/content-security-policy/generic/invalid-characters-in-policy.html.ini
index ccb770e00d4..395e5cf9f3f 100644
--- a/tests/wpt/meta/content-security-policy/generic/invalid-characters-in-policy.html.ini
+++ b/tests/wpt/meta/content-security-policy/generic/invalid-characters-in-policy.html.ini
@@ -1,18 +1,12 @@
[invalid-characters-in-policy.html]
- [Should not load image with 'none' CSP - meta tag]
- expected: FAIL
-
- [Should not load image with 'none' CSP - HTTP header]
- expected: FAIL
-
- [Non-ASCII character in directive value should not affect other directives. - meta tag]
+ [Non-ASCII character in directive value should not affect other directives. - HTTP header]
expected: FAIL
- [Non-ASCII character in directive value should not affect other directives. - HTTP header]
+ [Non-ASCII character in directive name should not affect other directives. - HTTP header]
expected: FAIL
- [Non-ASCII character in directive name should not affect other directives. - meta tag]
+ [Non-ASCII character in directive value should drop the whole directive. - meta tag]
expected: FAIL
- [Non-ASCII character in directive name should not affect other directives. - HTTP header]
+ [Non-ASCII quote character in directive value should drop the whole directive. - meta tag]
expected: FAIL
diff --git a/tests/wpt/meta/content-security-policy/generic/only-valid-whitespaces-are-allowed.html.ini b/tests/wpt/meta/content-security-policy/generic/only-valid-whitespaces-are-allowed.html.ini
index a8dd0149615..e3648061bc3 100644
--- a/tests/wpt/meta/content-security-policy/generic/only-valid-whitespaces-are-allowed.html.ini
+++ b/tests/wpt/meta/content-security-policy/generic/only-valid-whitespaces-are-allowed.html.ini
@@ -6,50 +6,5 @@
[U+000C FF should be properly parsed inside directive value - HTTP header]
expected: TIMEOUT
- [Should not load image with 'none' CSP - meta tag]
- expected: FAIL
-
- [Should not load image with 'none' CSP - HTTP header]
- expected: FAIL
-
- [U+0009 TAB should be properly parsed between directive name and value - meta tag]
- expected: FAIL
-
- [U+0009 TAB should be properly parsed between directive name and value - HTTP header]
- expected: FAIL
-
- [U+000C FF should be properly parsed between directive name and value - meta tag]
- expected: FAIL
-
- [U+000A LF should be properly parsed between directive name and value - meta tag]
- expected: FAIL
-
- [U+000D CR should be properly parsed between directive name and value - meta tag]
- expected: FAIL
-
- [U+0020 SPACE should be properly parsed between directive name and value - meta tag]
- expected: FAIL
-
- [U+0020 SPACE should be properly parsed between directive name and value - HTTP header]
- expected: FAIL
-
- [U+0009 TAB should be properly parsed inside directive value - meta tag]
- expected: FAIL
-
- [U+0009 TAB should be properly parsed inside directive value - HTTP header]
- expected: FAIL
-
- [U+000C FF should be properly parsed inside directive value - meta tag]
- expected: FAIL
-
- [U+000A LF should be properly parsed inside directive value - meta tag]
- expected: FAIL
-
- [U+000D CR should be properly parsed inside directive value - meta tag]
- expected: FAIL
-
- [U+0020 SPACE should be properly parsed inside directive value - meta tag]
- expected: FAIL
-
- [U+0020 SPACE should be properly parsed inside directive value - HTTP header]
+ [U+00A0 NBSP should not be parsed inside directive value - meta tag]
expected: FAIL
diff --git a/tests/wpt/meta/content-security-policy/inheritance/document-write-iframe.html.ini b/tests/wpt/meta/content-security-policy/inheritance/document-write-iframe.html.ini
deleted file mode 100644
index d93be0d40ea..00000000000
--- a/tests/wpt/meta/content-security-policy/inheritance/document-write-iframe.html.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[document-write-iframe.html]
- [document.open() keeps inherited CSPs on empty iframe.]
- expected: FAIL
diff --git a/tests/wpt/meta/content-security-policy/inheritance/history-iframe.sub.html.ini b/tests/wpt/meta/content-security-policy/inheritance/history-iframe.sub.html.ini
index d629ffef04f..73a32477504 100644
--- a/tests/wpt/meta/content-security-policy/inheritance/history-iframe.sub.html.ini
+++ b/tests/wpt/meta/content-security-policy/inheritance/history-iframe.sub.html.ini
@@ -16,9 +16,3 @@
[History navigation in iframe: data URL document is navigated back from history cross-origin.]
expected: FAIL
-
- [History navigation in iframe: srcdoc iframe is navigated back from history same-origin.]
- expected: FAIL
-
- [History navigation in iframe: srcdoc iframe is navigated back from history cross-origin.]
- expected: FAIL
diff --git a/tests/wpt/meta/content-security-policy/inheritance/iframe-all-local-schemes.sub.html.ini b/tests/wpt/meta/content-security-policy/inheritance/iframe-all-local-schemes.sub.html.ini
index 781468a1f16..fcd96aa7a47 100644
--- a/tests/wpt/meta/content-security-policy/inheritance/iframe-all-local-schemes.sub.html.ini
+++ b/tests/wpt/meta/content-security-policy/inheritance/iframe-all-local-schemes.sub.html.ini
@@ -1,11 +1,11 @@
[iframe-all-local-schemes.sub.html]
- [<iframe>'s about:blank inherits policy.]
+ [<iframe src='data:...'>'s inherits policy.]
expected: FAIL
- [window about:blank inherits policy.]
+ [<iframe sandbox src='blob:...'>'s inherits policy. (opaque origin sandbox)]
expected: FAIL
- [<iframe srcdoc>'s inherits policy.]
+ [window about:blank inherits policy.]
expected: FAIL
[<iframe src='blob:...'>'s inherits policy.]
@@ -14,17 +14,5 @@
[window url='blob:...' inherits policy.]
expected: FAIL
- [<iframe src='data:...'>'s inherits policy.]
- expected: FAIL
-
- [<iframe src='javascript:...'>'s inherits policy (static <img> is blocked)]
- expected: FAIL
-
[window url='javascript:...'>'s inherits policy (static <img> is blocked)]
expected: FAIL
-
- [<iframe src='javascript:...'>'s inherits policy (dynamically inserted <img> is blocked)]
- expected: FAIL
-
- [<iframe sandbox src='blob:...'>'s inherits policy. (opaque origin sandbox)]
- expected: FAIL
diff --git a/tests/wpt/meta/content-security-policy/inheritance/iframe-srcdoc-inheritance.html.ini b/tests/wpt/meta/content-security-policy/inheritance/iframe-srcdoc-inheritance.html.ini
deleted file mode 100644
index 61468867d57..00000000000
--- a/tests/wpt/meta/content-security-policy/inheritance/iframe-srcdoc-inheritance.html.ini
+++ /dev/null
@@ -1,7 +0,0 @@
-[iframe-srcdoc-inheritance.html]
- expected: TIMEOUT
- [First image should be blocked]
- expected: FAIL
-
- [Second image should be blocked]
- expected: NOTRUN
diff --git a/tests/wpt/meta/content-security-policy/inheritance/location-reload.html.ini b/tests/wpt/meta/content-security-policy/inheritance/location-reload.html.ini
index 4b0c78cb0d8..4efb1bf017b 100644
--- a/tests/wpt/meta/content-security-policy/inheritance/location-reload.html.ini
+++ b/tests/wpt/meta/content-security-policy/inheritance/location-reload.html.ini
@@ -1,9 +1,7 @@
[location-reload.html]
- [location.reload() of empty iframe.]
- expected: FAIL
+ expected: TIMEOUT
+ [location.reload() of srcdoc iframe.]
+ expected: TIMEOUT
[location.reload() of blob URL iframe.]
expected: FAIL
-
- [location.reload() of srcdoc iframe.]
- expected: FAIL
diff --git a/tests/wpt/meta/content-security-policy/navigation/to-javascript-parent-initiated-child-csp.html.ini b/tests/wpt/meta/content-security-policy/navigation/to-javascript-parent-initiated-child-csp.html.ini
index e09851b2685..3eb78514061 100644
--- a/tests/wpt/meta/content-security-policy/navigation/to-javascript-parent-initiated-child-csp.html.ini
+++ b/tests/wpt/meta/content-security-policy/navigation/to-javascript-parent-initiated-child-csp.html.ini
@@ -1,10 +1,7 @@
[to-javascript-parent-initiated-child-csp.html]
expected: TIMEOUT
- [Should not have executed the javascript URL for\n iframe.contentWindow.location.href with child's CSP "script-src 'none'"]
- expected: TIMEOUT
-
[Should not have executed the javascript URL for\n iframe.src with child's CSP "script-src 'none'"]
- expected: NOTRUN
+ expected: TIMEOUT
[Should not have executed the javascript URL for\n otherTabWithScriptSrcNone.location.href with child's CSP "script-src 'none'"]
expected: NOTRUN
diff --git a/tests/wpt/meta/content-security-policy/navigation/to-javascript-parent-initiated-parent-csp.html.ini b/tests/wpt/meta/content-security-policy/navigation/to-javascript-parent-initiated-parent-csp.html.ini
index bf7d79650ae..45056666dd3 100644
--- a/tests/wpt/meta/content-security-policy/navigation/to-javascript-parent-initiated-parent-csp.html.ini
+++ b/tests/wpt/meta/content-security-policy/navigation/to-javascript-parent-initiated-parent-csp.html.ini
@@ -1,13 +1,10 @@
[to-javascript-parent-initiated-parent-csp.html]
expected: TIMEOUT
[Should not have executed the javascript url for\n iframe.contentWindow.location.href]
- expected: FAIL
-
- [Should not have executed the javascript url for\n iframe.src]
- expected: FAIL
+ expected: TIMEOUT
[Should not have executed the javascript url for\n otherTab.location.href]
- expected: TIMEOUT
+ expected: NOTRUN
[Should not have executed the javascript url for\n area[target=iframe\].href]
expected: NOTRUN
@@ -20,3 +17,6 @@
[Should not have executed the javascript url for\n a[target=iframe\].href]
expected: NOTRUN
+
+ [Should not have executed the javascript url for\n iframe.src]
+ expected: NOTRUN
diff --git a/tests/wpt/meta/content-security-policy/script-src/script-src-strict_dynamic_javascript_uri.html.ini b/tests/wpt/meta/content-security-policy/script-src/script-src-strict_dynamic_javascript_uri.html.ini
deleted file mode 100644
index b16c3876c44..00000000000
--- a/tests/wpt/meta/content-security-policy/script-src/script-src-strict_dynamic_javascript_uri.html.ini
+++ /dev/null
@@ -1,4 +0,0 @@
-[script-src-strict_dynamic_javascript_uri.html]
- expected: TIMEOUT
- [Script injected via `javascript:` URIs are not allowed with `strict-dynamic`.]
- expected: TIMEOUT
diff --git a/tests/wpt/meta/content-security-policy/script-src/script-src-trusted_types_eval_with_require_trusted_types_eval.html.ini b/tests/wpt/meta/content-security-policy/script-src/script-src-trusted_types_eval_with_require_trusted_types_eval.html.ini
deleted file mode 100644
index 63f89f3c8fd..00000000000
--- a/tests/wpt/meta/content-security-policy/script-src/script-src-trusted_types_eval_with_require_trusted_types_eval.html.ini
+++ /dev/null
@@ -1,13 +0,0 @@
-[script-src-trusted_types_eval_with_require_trusted_types_eval.html]
- expected: ERROR
- [Script injected via direct `eval` is allowed with `trusted-types-eval` and `require-trusted-types-for 'script'`.]
- expected: FAIL
-
- [Script injected via indirect `eval` is allowed with `trusted-types-eval` and `require-trusted-types-for 'script'`.]
- expected: FAIL
-
- [Script injected via `new Function` is allowed with `trusted-types-eval` and `require-trusted-types-for 'script'`.]
- expected: FAIL
-
- [Script injected via `setTimeout` is allowed with `trusted-types-eval` and `require-trusted-types-for 'script'`.]
- expected: FAIL
diff --git a/tests/wpt/meta/content-security-policy/script-src/srcdoc-doesnt-bypass-script-src.sub.html.ini b/tests/wpt/meta/content-security-policy/script-src/srcdoc-doesnt-bypass-script-src.sub.html.ini
deleted file mode 100644
index d7dfbd73af7..00000000000
--- a/tests/wpt/meta/content-security-policy/script-src/srcdoc-doesnt-bypass-script-src.sub.html.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[srcdoc-doesnt-bypass-script-src.sub.html]
- [Expecting logs: ["violated-directive=script-src-elem"\]]
- expected: FAIL
diff --git a/tests/wpt/meta/content-security-policy/securitypolicyviolation/linenumber.tentative.html.ini b/tests/wpt/meta/content-security-policy/securitypolicyviolation/linenumber.tentative.html.ini
index e8114229ab9..fed78a0aa49 100644
--- a/tests/wpt/meta/content-security-policy/securitypolicyviolation/linenumber.tentative.html.ini
+++ b/tests/wpt/meta/content-security-policy/securitypolicyviolation/linenumber.tentative.html.ini
@@ -1,3 +1,4 @@
[linenumber.tentative.html]
+ expected: TIMEOUT
[linenumber]
- expected: FAIL
+ expected: NOTRUN
diff --git a/tests/wpt/meta/content-security-policy/unsafe-eval/eval-blocked-in-about-blank-iframe.html.ini b/tests/wpt/meta/content-security-policy/unsafe-eval/eval-blocked-in-about-blank-iframe.html.ini
deleted file mode 100644
index d47972783e3..00000000000
--- a/tests/wpt/meta/content-security-policy/unsafe-eval/eval-blocked-in-about-blank-iframe.html.ini
+++ /dev/null
@@ -1,4 +0,0 @@
-[eval-blocked-in-about-blank-iframe.html]
- expected: ERROR
- [eval-blocked-in-about-blank-iframe]
- expected: TIMEOUT
diff --git a/tests/wpt/meta/content-security-policy/unsafe-hashes/javascript_src_denied_missing_unsafe_hashes-href.html.ini b/tests/wpt/meta/content-security-policy/unsafe-hashes/javascript_src_denied_missing_unsafe_hashes-href.html.ini
deleted file mode 100644
index 4496339f476..00000000000
--- a/tests/wpt/meta/content-security-policy/unsafe-hashes/javascript_src_denied_missing_unsafe_hashes-href.html.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[javascript_src_denied_missing_unsafe_hashes-href.html]
- [javascript: navigation using <a href> should be refused due to missing unsafe-hashes]
- expected: FAIL
diff --git a/tests/wpt/meta/content-security-policy/unsafe-hashes/javascript_src_denied_missing_unsafe_hashes-window_location.html.ini b/tests/wpt/meta/content-security-policy/unsafe-hashes/javascript_src_denied_missing_unsafe_hashes-window_location.html.ini
deleted file mode 100644
index 5d8a7e6683b..00000000000
--- a/tests/wpt/meta/content-security-policy/unsafe-hashes/javascript_src_denied_missing_unsafe_hashes-window_location.html.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[javascript_src_denied_missing_unsafe_hashes-window_location.html]
- [Test that the javascript: src is not allowed to run]
- expected: FAIL
diff --git a/tests/wpt/meta/content-security-policy/unsafe-hashes/javascript_src_denied_wrong_hash-href.html.ini b/tests/wpt/meta/content-security-policy/unsafe-hashes/javascript_src_denied_wrong_hash-href.html.ini
deleted file mode 100644
index 6f785e1732f..00000000000
--- a/tests/wpt/meta/content-security-policy/unsafe-hashes/javascript_src_denied_wrong_hash-href.html.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[javascript_src_denied_wrong_hash-href.html]
- [javascript: navigation using <a href> should be refused due to wrong hash]
- expected: FAIL
diff --git a/tests/wpt/meta/content-security-policy/unsafe-hashes/javascript_src_denied_wrong_hash-window_location.html.ini b/tests/wpt/meta/content-security-policy/unsafe-hashes/javascript_src_denied_wrong_hash-window_location.html.ini
deleted file mode 100644
index 413b1198c61..00000000000
--- a/tests/wpt/meta/content-security-policy/unsafe-hashes/javascript_src_denied_wrong_hash-window_location.html.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[javascript_src_denied_wrong_hash-window_location.html]
- [Test that the javascript: src is not allowed to run]
- expected: FAIL
diff --git a/tests/wpt/meta/css/css-backgrounds/background-image-shared-stylesheet.html.ini b/tests/wpt/meta/css/css-backgrounds/background-image-shared-stylesheet.html.ini
deleted file mode 100644
index c4d14766411..00000000000
--- a/tests/wpt/meta/css/css-backgrounds/background-image-shared-stylesheet.html.ini
+++ /dev/null
@@ -1,2 +0,0 @@
-[background-image-shared-stylesheet.html]
- expected: TIMEOUT
diff --git a/tests/wpt/meta/css/css-gaps/tentative/multicol/multicol-gap-decorations-001.html.ini b/tests/wpt/meta/css/css-gaps/multicol/multicol-gap-decorations-001.html.ini
index 09b5c2407df..09b5c2407df 100644
--- a/tests/wpt/meta/css/css-gaps/tentative/multicol/multicol-gap-decorations-001.html.ini
+++ b/tests/wpt/meta/css/css-gaps/multicol/multicol-gap-decorations-001.html.ini
diff --git a/tests/wpt/meta/css/css-gaps/tentative/multicol/multicol-gap-decorations-002.html.ini b/tests/wpt/meta/css/css-gaps/multicol/multicol-gap-decorations-002.html.ini
index d3d6008a74d..d3d6008a74d 100644
--- a/tests/wpt/meta/css/css-gaps/tentative/multicol/multicol-gap-decorations-002.html.ini
+++ b/tests/wpt/meta/css/css-gaps/multicol/multicol-gap-decorations-002.html.ini
diff --git a/tests/wpt/meta/css/css-gaps/tentative/multicol/multicol-gap-decorations-003.html.ini b/tests/wpt/meta/css/css-gaps/multicol/multicol-gap-decorations-003.html.ini
index be28f9f62c3..be28f9f62c3 100644
--- a/tests/wpt/meta/css/css-gaps/tentative/multicol/multicol-gap-decorations-003.html.ini
+++ b/tests/wpt/meta/css/css-gaps/multicol/multicol-gap-decorations-003.html.ini
diff --git a/tests/wpt/meta/css/css-gaps/tentative/multicol/multicol-gap-decorations-004.html.ini b/tests/wpt/meta/css/css-gaps/multicol/multicol-gap-decorations-004.html.ini
index f2c19d9824a..f2c19d9824a 100644
--- a/tests/wpt/meta/css/css-gaps/tentative/multicol/multicol-gap-decorations-004.html.ini
+++ b/tests/wpt/meta/css/css-gaps/multicol/multicol-gap-decorations-004.html.ini
diff --git a/tests/wpt/meta/css/css-gaps/tentative/multicol/multicol-gap-decorations-005.html.ini b/tests/wpt/meta/css/css-gaps/multicol/multicol-gap-decorations-005.html.ini
index e63a9af4a63..e63a9af4a63 100644
--- a/tests/wpt/meta/css/css-gaps/tentative/multicol/multicol-gap-decorations-005.html.ini
+++ b/tests/wpt/meta/css/css-gaps/multicol/multicol-gap-decorations-005.html.ini
diff --git a/tests/wpt/meta/css/css-gaps/tentative/multicol/multicol-gap-decorations-006.html.ini b/tests/wpt/meta/css/css-gaps/multicol/multicol-gap-decorations-006.html.ini
index e9fd7c8f430..e9fd7c8f430 100644
--- a/tests/wpt/meta/css/css-gaps/tentative/multicol/multicol-gap-decorations-006.html.ini
+++ b/tests/wpt/meta/css/css-gaps/multicol/multicol-gap-decorations-006.html.ini
diff --git a/tests/wpt/meta/css/css-gaps/tentative/multicol/multicol-gap-decorations-007.html.ini b/tests/wpt/meta/css/css-gaps/multicol/multicol-gap-decorations-007.html.ini
index f0da110b11d..f0da110b11d 100644
--- a/tests/wpt/meta/css/css-gaps/tentative/multicol/multicol-gap-decorations-007.html.ini
+++ b/tests/wpt/meta/css/css-gaps/multicol/multicol-gap-decorations-007.html.ini
diff --git a/tests/wpt/meta/css/css-gaps/tentative/multicol/multicol-gap-decorations-008.html.ini b/tests/wpt/meta/css/css-gaps/multicol/multicol-gap-decorations-008.html.ini
index fecb739fed1..fecb739fed1 100644
--- a/tests/wpt/meta/css/css-gaps/tentative/multicol/multicol-gap-decorations-008.html.ini
+++ b/tests/wpt/meta/css/css-gaps/multicol/multicol-gap-decorations-008.html.ini
diff --git a/tests/wpt/meta/css/css-gaps/tentative/multicol/multicol-gap-decorations-009.html.ini b/tests/wpt/meta/css/css-gaps/multicol/multicol-gap-decorations-009.html.ini
index 15809ab6be8..15809ab6be8 100644
--- a/tests/wpt/meta/css/css-gaps/tentative/multicol/multicol-gap-decorations-009.html.ini
+++ b/tests/wpt/meta/css/css-gaps/multicol/multicol-gap-decorations-009.html.ini
diff --git a/tests/wpt/meta/css/css-gaps/tentative/multicol/multicol-gap-decorations-010.html.ini b/tests/wpt/meta/css/css-gaps/multicol/multicol-gap-decorations-010.html.ini
index 087a090d25e..087a090d25e 100644
--- a/tests/wpt/meta/css/css-gaps/tentative/multicol/multicol-gap-decorations-010.html.ini
+++ b/tests/wpt/meta/css/css-gaps/multicol/multicol-gap-decorations-010.html.ini
diff --git a/tests/wpt/meta/css/css-gaps/tentative/multicol/multicol-gap-decorations-011.html.ini b/tests/wpt/meta/css/css-gaps/multicol/multicol-gap-decorations-011.html.ini
index 39cd43f8d3f..39cd43f8d3f 100644
--- a/tests/wpt/meta/css/css-gaps/tentative/multicol/multicol-gap-decorations-011.html.ini
+++ b/tests/wpt/meta/css/css-gaps/multicol/multicol-gap-decorations-011.html.ini
diff --git a/tests/wpt/meta/css/css-gaps/tentative/multicol/multicol-gap-decorations-012.html.ini b/tests/wpt/meta/css/css-gaps/multicol/multicol-gap-decorations-012.html.ini
index c60637403c8..c60637403c8 100644
--- a/tests/wpt/meta/css/css-gaps/tentative/multicol/multicol-gap-decorations-012.html.ini
+++ b/tests/wpt/meta/css/css-gaps/multicol/multicol-gap-decorations-012.html.ini
diff --git a/tests/wpt/meta/css/css-gaps/tentative/multicol/multicol-gap-decorations-013.html.ini b/tests/wpt/meta/css/css-gaps/multicol/multicol-gap-decorations-013.html.ini
index 319ec1ea8c7..319ec1ea8c7 100644
--- a/tests/wpt/meta/css/css-gaps/tentative/multicol/multicol-gap-decorations-013.html.ini
+++ b/tests/wpt/meta/css/css-gaps/multicol/multicol-gap-decorations-013.html.ini
diff --git a/tests/wpt/meta/css/css-gaps/tentative/multicol/multicol-gap-decorations-014.html.ini b/tests/wpt/meta/css/css-gaps/multicol/multicol-gap-decorations-014.html.ini
index 7baae0182e4..7baae0182e4 100644
--- a/tests/wpt/meta/css/css-gaps/tentative/multicol/multicol-gap-decorations-014.html.ini
+++ b/tests/wpt/meta/css/css-gaps/multicol/multicol-gap-decorations-014.html.ini
diff --git a/tests/wpt/meta/css/css-gaps/multicol/multicol-gap-decorations-015.html.ini b/tests/wpt/meta/css/css-gaps/multicol/multicol-gap-decorations-015.html.ini
new file mode 100644
index 00000000000..c5f1c0f943e
--- /dev/null
+++ b/tests/wpt/meta/css/css-gaps/multicol/multicol-gap-decorations-015.html.ini
@@ -0,0 +1,2 @@
+[multicol-gap-decorations-015.html]
+ expected: FAIL
diff --git a/tests/wpt/meta/css/css-gaps/multicol/multicol-gap-decorations-016.html.ini b/tests/wpt/meta/css/css-gaps/multicol/multicol-gap-decorations-016.html.ini
new file mode 100644
index 00000000000..63d5d357009
--- /dev/null
+++ b/tests/wpt/meta/css/css-gaps/multicol/multicol-gap-decorations-016.html.ini
@@ -0,0 +1,2 @@
+[multicol-gap-decorations-016.html]
+ expected: FAIL
diff --git a/tests/wpt/meta/css/css-grid/subgrid/line-names-015.html.ini b/tests/wpt/meta/css/css-grid/subgrid/line-names-015.html.ini
new file mode 100644
index 00000000000..d7cb6aaa099
--- /dev/null
+++ b/tests/wpt/meta/css/css-grid/subgrid/line-names-015.html.ini
@@ -0,0 +1,2 @@
+[line-names-015.html]
+ expected: FAIL
diff --git a/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-auto-025.tentative.html.ini b/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-auto-025.tentative.html.ini
deleted file mode 100644
index c1786082c26..00000000000
--- a/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-auto-025.tentative.html.ini
+++ /dev/null
@@ -1,2 +0,0 @@
-[line-clamp-auto-025.tentative.html]
- expected: FAIL
diff --git a/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-001.html.ini b/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-001.html.ini
new file mode 100644
index 00000000000..40c36b3c6f0
--- /dev/null
+++ b/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-001.html.ini
@@ -0,0 +1,2 @@
+[line-clamp-with-abspos-001.html]
+ expected: FAIL
diff --git a/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-001.tentative.html.ini b/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-001.tentative.html.ini
deleted file mode 100644
index 96277819670..00000000000
--- a/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-001.tentative.html.ini
+++ /dev/null
@@ -1,2 +0,0 @@
-[line-clamp-with-abspos-001.tentative.html]
- expected: FAIL
diff --git a/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-002.html.ini b/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-002.html.ini
new file mode 100644
index 00000000000..4d369b695f3
--- /dev/null
+++ b/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-002.html.ini
@@ -0,0 +1,2 @@
+[line-clamp-with-abspos-002.html]
+ expected: FAIL
diff --git a/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-002.tentative.html.ini b/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-002.tentative.html.ini
deleted file mode 100644
index 21efb29c1f9..00000000000
--- a/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-002.tentative.html.ini
+++ /dev/null
@@ -1,2 +0,0 @@
-[line-clamp-with-abspos-002.tentative.html]
- expected: FAIL
diff --git a/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-003.html.ini b/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-003.html.ini
new file mode 100644
index 00000000000..000eb27ddfd
--- /dev/null
+++ b/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-003.html.ini
@@ -0,0 +1,2 @@
+[line-clamp-with-abspos-003.html]
+ expected: FAIL
diff --git a/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-003.tentative.html.ini b/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-003.tentative.html.ini
deleted file mode 100644
index 189ac0f3620..00000000000
--- a/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-003.tentative.html.ini
+++ /dev/null
@@ -1,2 +0,0 @@
-[line-clamp-with-abspos-003.tentative.html]
- expected: FAIL
diff --git a/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-004.html.ini b/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-004.html.ini
new file mode 100644
index 00000000000..db488a0f5ef
--- /dev/null
+++ b/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-004.html.ini
@@ -0,0 +1,2 @@
+[line-clamp-with-abspos-004.html]
+ expected: FAIL
diff --git a/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-004.tentative.html.ini b/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-004.tentative.html.ini
deleted file mode 100644
index 4e4d8534002..00000000000
--- a/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-004.tentative.html.ini
+++ /dev/null
@@ -1,2 +0,0 @@
-[line-clamp-with-abspos-004.tentative.html]
- expected: FAIL
diff --git a/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-005.html.ini b/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-005.html.ini
new file mode 100644
index 00000000000..e669d29133f
--- /dev/null
+++ b/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-005.html.ini
@@ -0,0 +1,2 @@
+[line-clamp-with-abspos-005.html]
+ expected: FAIL
diff --git a/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-005.tentative.html.ini b/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-005.tentative.html.ini
deleted file mode 100644
index 4a2b7b2ba98..00000000000
--- a/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-005.tentative.html.ini
+++ /dev/null
@@ -1,2 +0,0 @@
-[line-clamp-with-abspos-005.tentative.html]
- expected: FAIL
diff --git a/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-006.html.ini b/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-006.html.ini
new file mode 100644
index 00000000000..a2f619fdde4
--- /dev/null
+++ b/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-006.html.ini
@@ -0,0 +1,2 @@
+[line-clamp-with-abspos-006.html]
+ expected: FAIL
diff --git a/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-006.tentative.html.ini b/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-006.tentative.html.ini
deleted file mode 100644
index bd697fabf3f..00000000000
--- a/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-006.tentative.html.ini
+++ /dev/null
@@ -1,2 +0,0 @@
-[line-clamp-with-abspos-006.tentative.html]
- expected: FAIL
diff --git a/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-007.html.ini b/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-007.html.ini
new file mode 100644
index 00000000000..45df20f22d9
--- /dev/null
+++ b/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-007.html.ini
@@ -0,0 +1,2 @@
+[line-clamp-with-abspos-007.html]
+ expected: FAIL
diff --git a/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-007.tentative.html.ini b/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-007.tentative.html.ini
deleted file mode 100644
index b63c81cd54e..00000000000
--- a/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-007.tentative.html.ini
+++ /dev/null
@@ -1,2 +0,0 @@
-[line-clamp-with-abspos-007.tentative.html]
- expected: FAIL
diff --git a/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-008.html.ini b/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-008.html.ini
new file mode 100644
index 00000000000..039fa6a2145
--- /dev/null
+++ b/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-008.html.ini
@@ -0,0 +1,2 @@
+[line-clamp-with-abspos-008.html]
+ expected: FAIL
diff --git a/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-008.tentative.html.ini b/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-008.tentative.html.ini
deleted file mode 100644
index 834446721a7..00000000000
--- a/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-008.tentative.html.ini
+++ /dev/null
@@ -1,2 +0,0 @@
-[line-clamp-with-abspos-008.tentative.html]
- expected: FAIL
diff --git a/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-009.html.ini b/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-009.html.ini
new file mode 100644
index 00000000000..e4fd4f2a7f8
--- /dev/null
+++ b/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-009.html.ini
@@ -0,0 +1,2 @@
+[line-clamp-with-abspos-009.html]
+ expected: FAIL
diff --git a/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-009.tentative.html.ini b/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-009.tentative.html.ini
deleted file mode 100644
index 24f8b5bded3..00000000000
--- a/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-009.tentative.html.ini
+++ /dev/null
@@ -1,2 +0,0 @@
-[line-clamp-with-abspos-009.tentative.html]
- expected: FAIL
diff --git a/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-010.html.ini b/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-010.html.ini
new file mode 100644
index 00000000000..613c6b90cfd
--- /dev/null
+++ b/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-010.html.ini
@@ -0,0 +1,2 @@
+[line-clamp-with-abspos-010.html]
+ expected: FAIL
diff --git a/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-010.tentative.html.ini b/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-010.tentative.html.ini
deleted file mode 100644
index b4d85b57450..00000000000
--- a/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-010.tentative.html.ini
+++ /dev/null
@@ -1,2 +0,0 @@
-[line-clamp-with-abspos-010.tentative.html]
- expected: FAIL
diff --git a/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-011.html.ini b/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-011.html.ini
new file mode 100644
index 00000000000..26644e02bb8
--- /dev/null
+++ b/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-011.html.ini
@@ -0,0 +1,2 @@
+[line-clamp-with-abspos-011.html]
+ expected: FAIL
diff --git a/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-011.tentative.html.ini b/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-011.tentative.html.ini
deleted file mode 100644
index b399afd2326..00000000000
--- a/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-011.tentative.html.ini
+++ /dev/null
@@ -1,2 +0,0 @@
-[line-clamp-with-abspos-011.tentative.html]
- expected: FAIL
diff --git a/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-012.html.ini b/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-012.html.ini
new file mode 100644
index 00000000000..4c8f049422c
--- /dev/null
+++ b/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-012.html.ini
@@ -0,0 +1,2 @@
+[line-clamp-with-abspos-012.html]
+ expected: FAIL
diff --git a/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-012.tentative.html.ini b/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-012.tentative.html.ini
deleted file mode 100644
index 2f746ad56f3..00000000000
--- a/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-012.tentative.html.ini
+++ /dev/null
@@ -1,2 +0,0 @@
-[line-clamp-with-abspos-012.tentative.html]
- expected: FAIL
diff --git a/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-013.html.ini b/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-013.html.ini
new file mode 100644
index 00000000000..c541770ea3f
--- /dev/null
+++ b/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-013.html.ini
@@ -0,0 +1,2 @@
+[line-clamp-with-abspos-013.html]
+ expected: FAIL
diff --git a/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-013.tentative.html.ini b/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-013.tentative.html.ini
deleted file mode 100644
index f710874fa75..00000000000
--- a/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-013.tentative.html.ini
+++ /dev/null
@@ -1,2 +0,0 @@
-[line-clamp-with-abspos-013.tentative.html]
- expected: FAIL
diff --git a/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-014.html.ini b/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-014.html.ini
new file mode 100644
index 00000000000..c97b27d5dab
--- /dev/null
+++ b/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-014.html.ini
@@ -0,0 +1,2 @@
+[line-clamp-with-abspos-014.html]
+ expected: FAIL
diff --git a/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-014.tentative.html.ini b/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-014.tentative.html.ini
deleted file mode 100644
index a7e0e7a16ad..00000000000
--- a/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-014.tentative.html.ini
+++ /dev/null
@@ -1,2 +0,0 @@
-[line-clamp-with-abspos-014.tentative.html]
- expected: FAIL
diff --git a/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-015.html.ini b/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-015.html.ini
new file mode 100644
index 00000000000..5d9f5c960a0
--- /dev/null
+++ b/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-015.html.ini
@@ -0,0 +1,2 @@
+[line-clamp-with-abspos-015.html]
+ expected: FAIL
diff --git a/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-016.html.ini b/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-016.html.ini
new file mode 100644
index 00000000000..1c1e4761713
--- /dev/null
+++ b/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-016.html.ini
@@ -0,0 +1,2 @@
+[line-clamp-with-abspos-016.html]
+ expected: FAIL
diff --git a/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-017.tentative.html.ini b/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-017.tentative.html.ini
new file mode 100644
index 00000000000..39d8ecfca89
--- /dev/null
+++ b/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-017.tentative.html.ini
@@ -0,0 +1,2 @@
+[line-clamp-with-abspos-017.tentative.html]
+ expected: FAIL
diff --git a/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-018.html.ini b/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-018.html.ini
new file mode 100644
index 00000000000..9e1f2f984cc
--- /dev/null
+++ b/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-018.html.ini
@@ -0,0 +1,2 @@
+[line-clamp-with-abspos-018.html]
+ expected: FAIL
diff --git a/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-019.html.ini b/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-019.html.ini
new file mode 100644
index 00000000000..93fb1dcbd7a
--- /dev/null
+++ b/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-019.html.ini
@@ -0,0 +1,2 @@
+[line-clamp-with-abspos-019.html]
+ expected: FAIL
diff --git a/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-020.html.ini b/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-020.html.ini
new file mode 100644
index 00000000000..4196c262fb6
--- /dev/null
+++ b/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-020.html.ini
@@ -0,0 +1,2 @@
+[line-clamp-with-abspos-020.html]
+ expected: FAIL
diff --git a/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-021.html.ini b/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-021.html.ini
new file mode 100644
index 00000000000..f49c1642115
--- /dev/null
+++ b/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-021.html.ini
@@ -0,0 +1,2 @@
+[line-clamp-with-abspos-021.html]
+ expected: FAIL
diff --git a/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-022.html.ini b/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-022.html.ini
new file mode 100644
index 00000000000..2a41664d203
--- /dev/null
+++ b/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-abspos-022.html.ini
@@ -0,0 +1,2 @@
+[line-clamp-with-abspos-022.html]
+ expected: FAIL
diff --git a/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-001.html.ini b/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-001.html.ini
new file mode 100644
index 00000000000..4d8f7292069
--- /dev/null
+++ b/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-001.html.ini
@@ -0,0 +1,2 @@
+[line-clamp-with-fixed-pos-001.html]
+ expected: FAIL
diff --git a/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-002.html.ini b/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-002.html.ini
new file mode 100644
index 00000000000..67cbf86b0b8
--- /dev/null
+++ b/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-002.html.ini
@@ -0,0 +1,2 @@
+[line-clamp-with-fixed-pos-002.html]
+ expected: FAIL
diff --git a/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-003.html.ini b/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-003.html.ini
new file mode 100644
index 00000000000..3af9a89c950
--- /dev/null
+++ b/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-003.html.ini
@@ -0,0 +1,2 @@
+[line-clamp-with-fixed-pos-003.html]
+ expected: FAIL
diff --git a/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-004.html.ini b/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-004.html.ini
new file mode 100644
index 00000000000..0d12a1bc36c
--- /dev/null
+++ b/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-004.html.ini
@@ -0,0 +1,2 @@
+[line-clamp-with-fixed-pos-004.html]
+ expected: FAIL
diff --git a/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-005.html.ini b/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-005.html.ini
new file mode 100644
index 00000000000..31e359cfb5f
--- /dev/null
+++ b/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-005.html.ini
@@ -0,0 +1,2 @@
+[line-clamp-with-fixed-pos-005.html]
+ expected: FAIL
diff --git a/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-006.html.ini b/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-006.html.ini
new file mode 100644
index 00000000000..807db673371
--- /dev/null
+++ b/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-006.html.ini
@@ -0,0 +1,2 @@
+[line-clamp-with-fixed-pos-006.html]
+ expected: FAIL
diff --git a/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-007.html.ini b/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-007.html.ini
new file mode 100644
index 00000000000..4d4c697e1f5
--- /dev/null
+++ b/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-007.html.ini
@@ -0,0 +1,2 @@
+[line-clamp-with-fixed-pos-007.html]
+ expected: FAIL
diff --git a/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-008.html.ini b/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-008.html.ini
new file mode 100644
index 00000000000..2934b89a2cf
--- /dev/null
+++ b/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-008.html.ini
@@ -0,0 +1,2 @@
+[line-clamp-with-fixed-pos-008.html]
+ expected: FAIL
diff --git a/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-009.html.ini b/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-009.html.ini
new file mode 100644
index 00000000000..bc33c225d01
--- /dev/null
+++ b/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-009.html.ini
@@ -0,0 +1,2 @@
+[line-clamp-with-fixed-pos-009.html]
+ expected: FAIL
diff --git a/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-010.html.ini b/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-010.html.ini
new file mode 100644
index 00000000000..2fc6d12eade
--- /dev/null
+++ b/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-010.html.ini
@@ -0,0 +1,2 @@
+[line-clamp-with-fixed-pos-010.html]
+ expected: FAIL
diff --git a/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-011.html.ini b/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-011.html.ini
new file mode 100644
index 00000000000..097bc0d8876
--- /dev/null
+++ b/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-011.html.ini
@@ -0,0 +1,2 @@
+[line-clamp-with-fixed-pos-011.html]
+ expected: FAIL
diff --git a/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-012.html.ini b/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-012.html.ini
new file mode 100644
index 00000000000..d9c19a6bbdb
--- /dev/null
+++ b/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-012.html.ini
@@ -0,0 +1,2 @@
+[line-clamp-with-fixed-pos-012.html]
+ expected: FAIL
diff --git a/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-013.html.ini b/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-013.html.ini
new file mode 100644
index 00000000000..4565a34841e
--- /dev/null
+++ b/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-013.html.ini
@@ -0,0 +1,2 @@
+[line-clamp-with-fixed-pos-013.html]
+ expected: FAIL
diff --git a/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-014.html.ini b/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-014.html.ini
new file mode 100644
index 00000000000..cabd27df9d6
--- /dev/null
+++ b/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-014.html.ini
@@ -0,0 +1,2 @@
+[line-clamp-with-fixed-pos-014.html]
+ expected: FAIL
diff --git a/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-015.html.ini b/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-015.html.ini
new file mode 100644
index 00000000000..8577c169df2
--- /dev/null
+++ b/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-015.html.ini
@@ -0,0 +1,2 @@
+[line-clamp-with-fixed-pos-015.html]
+ expected: FAIL
diff --git a/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-016.html.ini b/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-016.html.ini
new file mode 100644
index 00000000000..55bcad299ec
--- /dev/null
+++ b/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-016.html.ini
@@ -0,0 +1,2 @@
+[line-clamp-with-fixed-pos-016.html]
+ expected: FAIL
diff --git a/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-017.html.ini b/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-017.html.ini
new file mode 100644
index 00000000000..1ea3d4e7833
--- /dev/null
+++ b/tests/wpt/meta/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-017.html.ini
@@ -0,0 +1,2 @@
+[line-clamp-with-fixed-pos-017.html]
+ expected: FAIL
diff --git a/tests/wpt/meta/css/css-sizing/dynamic-available-size-iframe.html.ini b/tests/wpt/meta/css/css-sizing/dynamic-available-size-iframe.html.ini
deleted file mode 100644
index 35256741d38..00000000000
--- a/tests/wpt/meta/css/css-sizing/dynamic-available-size-iframe.html.ini
+++ /dev/null
@@ -1,2 +0,0 @@
-[dynamic-available-size-iframe.html]
- expected: FAIL
diff --git a/tests/wpt/meta/css/css-transforms/parsing/transform-valid.html.ini b/tests/wpt/meta/css/css-transforms/parsing/transform-valid.html.ini
new file mode 100644
index 00000000000..b13de1bd254
--- /dev/null
+++ b/tests/wpt/meta/css/css-transforms/parsing/transform-valid.html.ini
@@ -0,0 +1,30 @@
+[transform-valid.html]
+ [e.style['transform'\] = "scaleX(7)" should set the property value]
+ expected: FAIL
+
+ [e.style['transform'\] = "scaleX(720%)" should set the property value]
+ expected: FAIL
+
+ [e.style['transform'\] = "scaleY(-8)" should set the property value]
+ expected: FAIL
+
+ [e.style['transform'\] = "scaleY(-85%)" should set the property value]
+ expected: FAIL
+
+ [e.style['transform'\] = "scaleZ(4)" should set the property value]
+ expected: FAIL
+
+ [e.style['transform'\] = "scaleZ(25%)" should set the property value]
+ expected: FAIL
+
+ [e.style['transform'\] = "skewX(0)" should set the property value]
+ expected: FAIL
+
+ [e.style['transform'\] = "skewX(90deg)" should set the property value]
+ expected: FAIL
+
+ [e.style['transform'\] = "skewY(0)" should set the property value]
+ expected: FAIL
+
+ [e.style['transform'\] = "skewY(-90deg)" should set the property value]
+ expected: FAIL
diff --git a/tests/wpt/meta/css/css-values/tree-counting/calc-sibling-function-in-shadow-dom.html.ini b/tests/wpt/meta/css/css-values/tree-counting/calc-sibling-function-in-shadow-dom.html.ini
index 078fc209a02..4616880e9d8 100644
--- a/tests/wpt/meta/css/css-values/tree-counting/calc-sibling-function-in-shadow-dom.html.ini
+++ b/tests/wpt/meta/css/css-values/tree-counting/calc-sibling-function-in-shadow-dom.html.ini
@@ -1,3 +1,6 @@
[calc-sibling-function-in-shadow-dom.html]
[Host children have sibling-index() and sibling-count() based on assignedNodes order]
expected: FAIL
+
+ [Host children have sibling-index() and sibling-count() based on the DOM tree order]
+ expected: FAIL
diff --git a/tests/wpt/meta/fetch/stale-while-revalidate/stale-image.html.ini b/tests/wpt/meta/fetch/stale-while-revalidate/stale-image.html.ini
index e95e391fd91..2a23c41e9d8 100644
--- a/tests/wpt/meta/fetch/stale-while-revalidate/stale-image.html.ini
+++ b/tests/wpt/meta/fetch/stale-while-revalidate/stale-image.html.ini
@@ -1,4 +1,3 @@
[stale-image.html]
- expected: TIMEOUT
[Cache returns stale resource]
- expected: TIMEOUT
+ 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
new file mode 100644
index 00000000000..c253f779d78
--- /dev/null
+++ b/tests/wpt/meta/html/browsers/browsing-the-web/navigating-across-documents/008.html.ini
@@ -0,0 +1,3 @@
+[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/initial-empty-document/iframe-nosrc.html.ini b/tests/wpt/meta/html/browsers/browsing-the-web/navigating-across-documents/initial-empty-document/iframe-nosrc.html.ini
index d5f4fa2f799..2241163d563 100644
--- a/tests/wpt/meta/html/browsers/browsing-the-web/navigating-across-documents/initial-empty-document/iframe-nosrc.html.ini
+++ b/tests/wpt/meta/html/browsers/browsing-the-web/navigating-across-documents/initial-empty-document/iframe-nosrc.html.ini
@@ -4,3 +4,6 @@
[form submission]
expected: FAIL
+
+ [link click]
+ expected: FAIL
diff --git a/tests/wpt/meta/html/browsers/browsing-the-web/navigating-across-documents/navigation-unload-same-origin.window.js.ini b/tests/wpt/meta/html/browsers/browsing-the-web/navigating-across-documents/navigation-unload-same-origin.window.js.ini
new file mode 100644
index 00000000000..7dc346632a4
--- /dev/null
+++ b/tests/wpt/meta/html/browsers/browsing-the-web/navigating-across-documents/navigation-unload-same-origin.window.js.ini
@@ -0,0 +1,3 @@
+[navigation-unload-same-origin.window.html]
+ [Same-origin navigation started from unload handler must be ignored]
+ expected: FAIL
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-invalid-args.html.ini b/tests/wpt/meta/html/canvas/element/manual/imagebitmap/createImageBitmap-invalid-args.html.ini
index 673fc1e4ffd..8daf97ba765 100644
--- a/tests/wpt/meta/html/canvas/element/manual/imagebitmap/createImageBitmap-invalid-args.html.ini
+++ b/tests/wpt/meta/html/canvas/element/manual/imagebitmap/createImageBitmap-invalid-args.html.ini
@@ -1,5 +1,5 @@
[createImageBitmap-invalid-args.html]
- expected: ERROR
+ expected: TIMEOUT
[createImageBitmap with a vector HTMLImageElement source and sw set to 0]
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 5d2657041d1..7e036a1c4e4 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,5 +1,5 @@
[createImageBitmap-transfer.html]
- expected: ERROR
+ expected: TIMEOUT
[Transfer ImageBitmap created from a vector HTMLImageElement]
expected: FAIL
diff --git a/tests/wpt/meta/html/infrastructure/urls/base-url/document-base-url-window-initiator-is-not-opener.https.window.js.ini b/tests/wpt/meta/html/infrastructure/urls/base-url/document-base-url-window-initiator-is-not-opener.https.window.js.ini
index 2ef0896e3b3..8b8af2b9c2e 100644
--- a/tests/wpt/meta/html/infrastructure/urls/base-url/document-base-url-window-initiator-is-not-opener.https.window.js.ini
+++ b/tests/wpt/meta/html/infrastructure/urls/base-url/document-base-url-window-initiator-is-not-opener.https.window.js.ini
@@ -1,4 +1,3 @@
[document-base-url-window-initiator-is-not-opener.https.window.html]
- expected: TIMEOUT
[window.open() gets base url from initiator not opener.]
expected: [FAIL, PASS, TIMEOUT]
diff --git a/tests/wpt/meta/html/interaction/focus/the-autofocus-attribute/supported-elements.html.ini b/tests/wpt/meta/html/interaction/focus/the-autofocus-attribute/supported-elements.html.ini
index ddd65fdcec8..2adc9aa86db 100644
--- a/tests/wpt/meta/html/interaction/focus/the-autofocus-attribute/supported-elements.html.ini
+++ b/tests/wpt/meta/html/interaction/focus/the-autofocus-attribute/supported-elements.html.ini
@@ -1,15 +1,16 @@
[supported-elements.html]
+ expected: TIMEOUT
[Contenteditable element should support autofocus]
expected: FAIL
[Host element with delegatesFocus including no focusable descendants should be skipped]
- expected: FAIL
+ expected: NOTRUN
[Element with tabindex should support autofocus]
expected: FAIL
[Area element should support autofocus]
- expected: FAIL
+ expected: NOTRUN
[Host element with delegatesFocus should support autofocus]
- expected: FAIL
+ expected: NOTRUN
diff --git a/tests/wpt/meta/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_escaping-3.html.ini b/tests/wpt/meta/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_escaping-3.html.ini
index 7da2bc5ac80..6a420504feb 100644
--- a/tests/wpt/meta/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_escaping-3.html.ini
+++ b/tests/wpt/meta/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_escaping-3.html.ini
@@ -1,4 +1,3 @@
[iframe_sandbox_popups_escaping-3.html]
- expected: TIMEOUT
[Check that popups from a sandboxed iframe escape the sandbox if\n allow-popups-to-escape-sandbox is used]
- expected: TIMEOUT
+ expected: FAIL
diff --git a/tests/wpt/meta/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_nonescaping-2.html.ini b/tests/wpt/meta/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_nonescaping-2.html.ini
index a6591b318dc..c6f1e5d7d84 100644
--- a/tests/wpt/meta/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_nonescaping-2.html.ini
+++ b/tests/wpt/meta/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_nonescaping-2.html.ini
@@ -1,4 +1,4 @@
[iframe_sandbox_popups_nonescaping-2.html]
expected: TIMEOUT
[Check that popups from a sandboxed iframe do not escape the sandbox]
- expected: FAIL
+ expected: NOTRUN
diff --git a/tests/wpt/meta/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_nonescaping-3.html.ini b/tests/wpt/meta/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_nonescaping-3.html.ini
index ccdaf8d61b2..d5fd800f09d 100644
--- a/tests/wpt/meta/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_nonescaping-3.html.ini
+++ b/tests/wpt/meta/html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_nonescaping-3.html.ini
@@ -1,3 +1,4 @@
[iframe_sandbox_popups_nonescaping-3.html]
+ expected: TIMEOUT
[Check that popups from a sandboxed iframe do not escape the sandbox]
expected: NOTRUN
diff --git a/tests/wpt/meta/html/semantics/forms/form-submission-0/text-plain.window.js.ini b/tests/wpt/meta/html/semantics/forms/form-submission-0/text-plain.window.js.ini
index 9158a253170..1abe0eb8b88 100644
--- a/tests/wpt/meta/html/semantics/forms/form-submission-0/text-plain.window.js.ini
+++ b/tests/wpt/meta/html/semantics/forms/form-submission-0/text-plain.window.js.ini
@@ -167,9 +167,6 @@
[text/plain: \\n in name (normal form)]
expected: FAIL
- [text/plain: 0x00 in name (normal form)]
- expected: FAIL
-
[text/plain: double quote in value (normal form)]
expected: FAIL
diff --git a/tests/wpt/meta/html/semantics/forms/the-select-element/customizable-select/select-parsing.tentative.html.ini b/tests/wpt/meta/html/semantics/forms/the-select-element/customizable-select/select-parsing.tentative.html.ini
index 43a361b7721..85f3d8d4da6 100644
--- a/tests/wpt/meta/html/semantics/forms/the-select-element/customizable-select/select-parsing.tentative.html.ini
+++ b/tests/wpt/meta/html/semantics/forms/the-select-element/customizable-select/select-parsing.tentative.html.ini
@@ -43,3 +43,6 @@
[textarea tags should parse inside select instead of closing the select]
expected: FAIL
+
+ [Input tags should parse inside select if nested in another tag]
+ expected: FAIL
diff --git a/tests/wpt/meta/html/semantics/scripting-1/the-script-element/module/dynamic-import/blob-url.any.js.ini b/tests/wpt/meta/html/semantics/scripting-1/the-script-element/module/dynamic-import/blob-url.any.js.ini
index bdba8dadafa..095b97aa5a0 100644
--- a/tests/wpt/meta/html/semantics/scripting-1/the-script-element/module/dynamic-import/blob-url.any.js.ini
+++ b/tests/wpt/meta/html/semantics/scripting-1/the-script-element/module/dynamic-import/blob-url.any.js.ini
@@ -5,6 +5,9 @@
[Different blob URLs pointing to the same blob resolve to different modules]
expected: FAIL
+ [Revoking a blob URL immediately after calling import will not fail]
+ expected: FAIL
+
[blob-url.any.worker-module.html]
expected: TIMEOUT
@@ -15,6 +18,3 @@
[blob-url.any.html]
[Different blob URLs pointing to the same blob resolve to different modules]
expected: FAIL
-
- [Revoking a blob URL immediately after calling import will not fail]
- expected: FAIL
diff --git a/tests/wpt/meta/quirks/line-height-calculation.html.ini b/tests/wpt/meta/quirks/line-height-calculation.html.ini
index 248da212174..42e4c8c0007 100644
--- a/tests/wpt/meta/quirks/line-height-calculation.html.ini
+++ b/tests/wpt/meta/quirks/line-height-calculation.html.ini
@@ -7,3 +7,6 @@
[The line height calculation quirk, <table><tr><td id=test><img src="{png}"> <img src="{png}"><tr><td id=ref>x<tr><td id=s_ref>x</table>]
expected: FAIL
+
+ [The line height calculation quirk, #test img { padding:1px }<div id=test><img src="{png}"></div><img id=ref src="{png}" height=3><div id=s_ref>x</div>]
+ expected: FAIL
diff --git a/tests/wpt/meta/quirks/table-cell-width-calculation.html.ini b/tests/wpt/meta/quirks/table-cell-width-calculation.html.ini
index 3d66c4f26ac..8bdfbfb0a63 100644
--- a/tests/wpt/meta/quirks/table-cell-width-calculation.html.ini
+++ b/tests/wpt/meta/quirks/table-cell-width-calculation.html.ini
@@ -1,18 +1,3 @@
[table-cell-width-calculation.html]
- [The table cell width calculation quirk, basic]
- expected: FAIL
-
- [The table cell width calculation quirk, inline-block]
- expected: FAIL
-
- [The table cell width calculation quirk, img in span]
- expected: FAIL
-
- [The table cell width calculation quirk, the don't-wrap rule is only for the purpose of calculating the width of the cell]
- expected: FAIL
-
- [The table cell width calculation quirk, display:table-cell on span]
- expected: FAIL
-
- [The table cell width calculation quirk, display:table-cell on span, wbr]
+ [The table cell width calculation quirk, the quirk shouldn't apply for <video poster>]
expected: FAIL
diff --git a/tests/wpt/meta/trusted-types/DedicatedWorker-constructor-from-DedicatedWorker.html.ini b/tests/wpt/meta/trusted-types/DedicatedWorker-constructor-from-DedicatedWorker.html.ini
deleted file mode 100644
index 87e1655ef2a..00000000000
--- a/tests/wpt/meta/trusted-types/DedicatedWorker-constructor-from-DedicatedWorker.html.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[DedicatedWorker-constructor-from-DedicatedWorker.html]
- [Creating a Worker from a string should throw (dedicated worker scope)]
- expected: FAIL
diff --git a/tests/wpt/meta/trusted-types/DedicatedWorker-constructor.https.html.ini b/tests/wpt/meta/trusted-types/DedicatedWorker-constructor.https.html.ini
deleted file mode 100644
index aee3766a47f..00000000000
--- a/tests/wpt/meta/trusted-types/DedicatedWorker-constructor.https.html.ini
+++ /dev/null
@@ -1,6 +0,0 @@
-[DedicatedWorker-constructor.https.html]
- [Block Worker creation via string]
- expected: FAIL
-
- [Create Worker via string with default policy.]
- expected: FAIL
diff --git a/tests/wpt/meta/trusted-types/DedicatedWorker-importScripts.html.ini b/tests/wpt/meta/trusted-types/DedicatedWorker-importScripts.html.ini
deleted file mode 100644
index 65db633f602..00000000000
--- a/tests/wpt/meta/trusted-types/DedicatedWorker-importScripts.html.ini
+++ /dev/null
@@ -1,18 +0,0 @@
-[DedicatedWorker-importScripts.html]
- [importScripts with untrusted URLs throws in dedicated worker]
- expected: FAIL
-
- [null is not a trusted script URL throws in dedicated worker]
- expected: FAIL
-
- [importScripts with two URLs, both strings, in dedicated worker]
- expected: FAIL
-
- [importScripts with two URLs, one trusted, in dedicated worker]
- expected: FAIL
-
- [importScripts with untrusted URLs and default policy works in dedicated worker]
- expected: FAIL
-
- [importScripts with one trusted and one untrusted URLs and default policy works in dedicated worker]
- expected: FAIL
diff --git a/tests/wpt/meta/trusted-types/Document-write-exception-order.xhtml.ini b/tests/wpt/meta/trusted-types/Document-write-exception-order.xhtml.ini
deleted file mode 100644
index b779a38f615..00000000000
--- a/tests/wpt/meta/trusted-types/Document-write-exception-order.xhtml.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[Document-write-exception-order.xhtml]
- [`document.write(string)` throws TypeError]
- expected: FAIL
diff --git a/tests/wpt/meta/trusted-types/HTMLElement-generic.html.ini b/tests/wpt/meta/trusted-types/HTMLElement-generic.html.ini
index 13fbd908f76..8ed1a875db3 100644
--- a/tests/wpt/meta/trusted-types/HTMLElement-generic.html.ini
+++ b/tests/wpt/meta/trusted-types/HTMLElement-generic.html.ini
@@ -1,10 +1,4 @@
[HTMLElement-generic.html]
- [TT enabled: script.src\n = String on a\n connected element\n ]
- expected: FAIL
-
- [TT enabled: script.src\n = String on a\n non-connected element\n ]
- expected: FAIL
-
[TT enabled: div.innerHTML\n = String on a\n connected element\n ]
expected: FAIL
@@ -17,30 +11,6 @@
[TT enabled: iframe.srcdoc\n = String on a\n non-connected element\n ]
expected: FAIL
- [TT enabled: script.text\n = String on a\n connected element\n ]
- expected: FAIL
-
- [TT enabled: script.text\n = String on a\n non-connected element\n ]
- expected: FAIL
-
- [TT enabled: script.innerText\n = String on a\n connected element\n ]
- expected: FAIL
-
- [TT enabled: script.innerText\n = String on a\n non-connected element\n ]
- expected: FAIL
-
- [TT enabled: script.textContent\n = String on a\n connected element\n ]
- expected: FAIL
-
- [TT enabled: script.textContent\n = String on a\n non-connected element\n ]
- expected: FAIL
-
- [TT enabled: script.src\n = String on a\n connected element\n after removing the "require-trusted-types-for 'script' directive]
- expected: FAIL
-
- [TT enabled: script.src\n = String on a\n non-connected element\n after removing the "require-trusted-types-for 'script' directive]
- expected: FAIL
-
[TT enabled: div.innerHTML\n = String on a\n connected element\n after removing the "require-trusted-types-for 'script' directive]
expected: FAIL
@@ -52,33 +22,3 @@
[TT enabled: iframe.srcdoc\n = String on a\n non-connected element\n after removing the "require-trusted-types-for 'script' directive]
expected: FAIL
-
- [TT enabled: script.text\n = String on a\n connected element\n after removing the "require-trusted-types-for 'script' directive]
- expected: FAIL
-
- [TT enabled: script.text\n = String on a\n non-connected element\n after removing the "require-trusted-types-for 'script' directive]
- expected: FAIL
-
- [TT enabled: script.innerText\n = String on a\n connected element\n after removing the "require-trusted-types-for 'script' directive]
- expected: FAIL
-
- [TT enabled: script.innerText\n = String on a\n non-connected element\n after removing the "require-trusted-types-for 'script' directive]
- expected: FAIL
-
- [TT enabled: script.textContent\n = String on a\n connected element\n after removing the "require-trusted-types-for 'script' directive]
- expected: FAIL
-
- [TT enabled: script.textContent\n = String on a\n non-connected element\n after removing the "require-trusted-types-for 'script' directive]
- expected: FAIL
-
- [TT enabled: script.src\n = TrustedScript on a\n connected element\n ]
- expected: FAIL
-
- [TT enabled: script.src\n = TrustedScript on a\n non-connected element\n ]
- expected: FAIL
-
- [TT enabled: script.src\n = TrustedScript on a\n connected element\n after removing the "require-trusted-types-for 'script' directive]
- expected: FAIL
-
- [TT enabled: script.src\n = TrustedScript on a\n non-connected element\n after removing the "require-trusted-types-for 'script' directive]
- expected: FAIL
diff --git a/tests/wpt/meta/trusted-types/block-string-assignment-to-Document-write.html.ini b/tests/wpt/meta/trusted-types/block-string-assignment-to-Document-write.html.ini
deleted file mode 100644
index 78fec0f216a..00000000000
--- a/tests/wpt/meta/trusted-types/block-string-assignment-to-Document-write.html.ini
+++ /dev/null
@@ -1,42 +0,0 @@
-[block-string-assignment-to-Document-write.html]
- [`document.write(string)` throws]
- expected: FAIL
-
- [`document.write(string, string)` throws]
- expected: FAIL
-
- [`document.write(string, TrustedHTML)` throws]
- expected: FAIL
-
- [`document.writeln(string)` throws]
- expected: FAIL
-
- [`document.writeln(string, string)` throws]
- expected: FAIL
-
- [`document.writeln(string, TrustedHTML)` throws]
- expected: FAIL
-
- [`document.write(null)` throws]
- expected: FAIL
-
- [`document.writeln(null)` throws]
- expected: FAIL
-
- [`document.write(string)` observes default policy]
- expected: FAIL
-
- [`document.write(string, string)` observes default policy]
- expected: FAIL
-
- [`document.write(string, TrustedHTML)` observes default policy]
- expected: FAIL
-
- [`document.writeln(string)` observes default policy]
- expected: FAIL
-
- [`document.writeln(string, string)` observes default policy]
- expected: FAIL
-
- [`document.writeln(string, TrustedHTML)` observes default policy]
- expected: FAIL
diff --git a/tests/wpt/meta/trusted-types/block-string-assignment-to-HTMLElement-generic.html.ini b/tests/wpt/meta/trusted-types/block-string-assignment-to-HTMLElement-generic.html.ini
index deb942557bf..ed3a70b31ab 100644
--- a/tests/wpt/meta/trusted-types/block-string-assignment-to-HTMLElement-generic.html.ini
+++ b/tests/wpt/meta/trusted-types/block-string-assignment-to-HTMLElement-generic.html.ini
@@ -1,7 +1,4 @@
[block-string-assignment-to-HTMLElement-generic.html]
- [script.src accepts only TrustedScriptURL]
- expected: FAIL
-
[div.innerHTML accepts only TrustedHTML]
expected: FAIL
@@ -13,12 +10,3 @@
[iframe.srcdoc accepts string and null after default policy was created]
expected: FAIL
-
- [script.text accepts only TrustedScript]
- expected: FAIL
-
- [script.innerText accepts only TrustedScript]
- expected: FAIL
-
- [script.textContent accepts only TrustedScript]
- expected: FAIL
diff --git a/tests/wpt/meta/trusted-types/block-string-assignment-to-text-and-url-sinks.html.ini b/tests/wpt/meta/trusted-types/block-string-assignment-to-text-and-url-sinks.html.ini
index 01b68adab9e..1e9f6e44f44 100644
--- a/tests/wpt/meta/trusted-types/block-string-assignment-to-text-and-url-sinks.html.ini
+++ b/tests/wpt/meta/trusted-types/block-string-assignment-to-text-and-url-sinks.html.ini
@@ -7,12 +7,3 @@
[Setting SVGScriptElement.innerHTML to a plain string]
expected: FAIL
-
- [Setting HTMLScriptElement.innerText to a plain string]
- expected: FAIL
-
- [Setting HTMLScriptElement.textContent to a plain string]
- expected: FAIL
-
- [Setting HTMLScriptElement.text to a plain string]
- expected: FAIL
diff --git a/tests/wpt/meta/trusted-types/default-policy.html.ini b/tests/wpt/meta/trusted-types/default-policy.html.ini
index ae7c1cae260..15588646951 100644
--- a/tests/wpt/meta/trusted-types/default-policy.html.ini
+++ b/tests/wpt/meta/trusted-types/default-policy.html.ini
@@ -3,15 +3,9 @@
[Count SecurityPolicyViolation events.]
expected: TIMEOUT
- [script.src no default policy]
- expected: FAIL
-
[div.innerHTML no default policy]
expected: FAIL
- [script.text no default policy]
- expected: FAIL
-
[div.innerHTML default]
expected: FAIL
@@ -26,18 +20,3 @@
[div.innerHTML typeerror]
expected: FAIL
-
- [script.text default]
- expected: FAIL
-
- [script.text null]
- expected: FAIL
-
- [script.text throw]
- expected: FAIL
-
- [script.text undefined]
- expected: FAIL
-
- [script.text typeerror]
- expected: FAIL
diff --git a/tests/wpt/meta/trusted-types/empty-default-policy.html.ini b/tests/wpt/meta/trusted-types/empty-default-policy.html.ini
index 123f9ae5aab..4f06e4c971f 100644
--- a/tests/wpt/meta/trusted-types/empty-default-policy.html.ini
+++ b/tests/wpt/meta/trusted-types/empty-default-policy.html.ini
@@ -5,6 +5,3 @@
[div.innerHTML default]
expected: FAIL
-
- [script.text default]
- expected: FAIL
diff --git a/tests/wpt/meta/trusted-types/require-trusted-types-for-report-only.html.ini b/tests/wpt/meta/trusted-types/require-trusted-types-for-report-only.html.ini
index 33b34fe9928..39ec281d5f2 100644
--- a/tests/wpt/meta/trusted-types/require-trusted-types-for-report-only.html.ini
+++ b/tests/wpt/meta/trusted-types/require-trusted-types-for-report-only.html.ini
@@ -1,9 +1,3 @@
[require-trusted-types-for-report-only.html]
[Require trusted types for 'script' block create HTML.]
expected: FAIL
-
- [Require trusted types for 'script' block create script.]
- expected: FAIL
-
- [Require trusted types for 'script' block create script URL.]
- expected: FAIL
diff --git a/tests/wpt/meta/trusted-types/require-trusted-types-for.html.ini b/tests/wpt/meta/trusted-types/require-trusted-types-for.html.ini
index 9299429a74c..38d5f9eb35a 100644
--- a/tests/wpt/meta/trusted-types/require-trusted-types-for.html.ini
+++ b/tests/wpt/meta/trusted-types/require-trusted-types-for.html.ini
@@ -1,9 +1,3 @@
[require-trusted-types-for.html]
[Require trusted types for 'script' block create HTML.]
expected: FAIL
-
- [Require trusted types for 'script' block create script.]
- expected: FAIL
-
- [Require trusted types for 'script' block create script URL.]
- expected: FAIL
diff --git a/tests/wpt/meta/trusted-types/trusted-types-createHTMLDocument.html.ini b/tests/wpt/meta/trusted-types/trusted-types-createHTMLDocument.html.ini
index 242959acbb3..cca7dc42f2b 100644
--- a/tests/wpt/meta/trusted-types/trusted-types-createHTMLDocument.html.ini
+++ b/tests/wpt/meta/trusted-types/trusted-types-createHTMLDocument.html.ini
@@ -1,25 +1,13 @@
[trusted-types-createHTMLDocument.html]
- [Trusted Type assignment is blocked. (document)]
- expected: FAIL
-
[Trusted Type instances created in the main doc can be used. (document)]
expected: FAIL
- [Trusted Type assignment is blocked. (createHTMLDocument)]
- expected: FAIL
-
[Trusted Type instances created in the main doc can be used. (createHTMLDocument)]
expected: FAIL
- [Trusted Type assignment is blocked. (DOMParser)]
- expected: FAIL
-
[Trusted Type instances created in the main doc can be used. (DOMParser)]
expected: FAIL
- [Trusted Type assignment is blocked. (XHR)]
- expected: FAIL
-
[Trusted Type instances created in the main doc can be used. (XHR)]
expected: FAIL
diff --git a/tests/wpt/meta/trusted-types/trusted-types-report-only.html.ini b/tests/wpt/meta/trusted-types/trusted-types-report-only.html.ini
index 89c8c2d46d3..253b126c18f 100644
--- a/tests/wpt/meta/trusted-types/trusted-types-report-only.html.ini
+++ b/tests/wpt/meta/trusted-types/trusted-types-report-only.html.ini
@@ -1,15 +1,6 @@
[trusted-types-report-only.html]
- [Trusted Type violation report-only: assign string to script url]
- expected: FAIL
-
[Trusted Type violation report-only: assign string to html]
expected: FAIL
- [Trusted Type violation report-only: assign string to script.src]
- expected: FAIL
-
[Trusted Type violation report-only: assign string to script content]
expected: FAIL
-
- [Trusted Type violation report: check report contents]
- expected: FAIL
diff --git a/tests/wpt/meta/trusted-types/trusted-types-reporting-for-DedicatedWorker-DedicatedWorker-constructor.html.ini b/tests/wpt/meta/trusted-types/trusted-types-reporting-for-DedicatedWorker-DedicatedWorker-constructor.html.ini
deleted file mode 100644
index 316b249d12a..00000000000
--- a/tests/wpt/meta/trusted-types/trusted-types-reporting-for-DedicatedWorker-DedicatedWorker-constructor.html.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[trusted-types-reporting-for-DedicatedWorker-DedicatedWorker-constructor.html]
- [Violation report for Worker constructor with plain string.]
- expected: FAIL
diff --git a/tests/wpt/meta/trusted-types/trusted-types-reporting-for-DedicatedWorker-importScripts.html.ini b/tests/wpt/meta/trusted-types/trusted-types-reporting-for-DedicatedWorker-importScripts.html.ini
deleted file mode 100644
index d4731f55e66..00000000000
--- a/tests/wpt/meta/trusted-types/trusted-types-reporting-for-DedicatedWorker-importScripts.html.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[trusted-types-reporting-for-DedicatedWorker-importScripts.html]
- [Violation report for importScripts with plain string.]
- expected: FAIL
diff --git a/tests/wpt/meta/trusted-types/trusted-types-reporting-for-Document-write.html.ini b/tests/wpt/meta/trusted-types/trusted-types-reporting-for-Document-write.html.ini
deleted file mode 100644
index fa2ca7fa336..00000000000
--- a/tests/wpt/meta/trusted-types/trusted-types-reporting-for-Document-write.html.ini
+++ /dev/null
@@ -1,6 +0,0 @@
-[trusted-types-reporting-for-Document-write.html]
- [Violation report for plain string for write() with at least one plain string argument.]
- expected: FAIL
-
- [Violation report for plain string for writeln() with at least one plain string argument.]
- expected: FAIL
diff --git a/tests/wpt/meta/trusted-types/trusted-types-reporting-for-HTMLScriptElement.html.ini b/tests/wpt/meta/trusted-types/trusted-types-reporting-for-HTMLScriptElement.html.ini
deleted file mode 100644
index d374cd0978e..00000000000
--- a/tests/wpt/meta/trusted-types/trusted-types-reporting-for-HTMLScriptElement.html.ini
+++ /dev/null
@@ -1,12 +0,0 @@
-[trusted-types-reporting-for-HTMLScriptElement.html]
- [Violation report for plain string (innerText)]
- expected: FAIL
-
- [Violation report for plain string (textContent)]
- expected: FAIL
-
- [Violation report for plain string (src)]
- expected: FAIL
-
- [Violation report for plain string (text)]
- expected: FAIL
diff --git a/tests/wpt/meta/trusted-types/trusted-types-reporting-for-Window-DedicatedWorker-constructor.html.ini b/tests/wpt/meta/trusted-types/trusted-types-reporting-for-Window-DedicatedWorker-constructor.html.ini
deleted file mode 100644
index 05216e2b116..00000000000
--- a/tests/wpt/meta/trusted-types/trusted-types-reporting-for-Window-DedicatedWorker-constructor.html.ini
+++ /dev/null
@@ -1,3 +0,0 @@
-[trusted-types-reporting-for-Window-DedicatedWorker-constructor.html]
- [Violation report for Worker constructor with plain string.]
- expected: FAIL
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 3bfb92e671a..590f4ee6a07 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
@@ -772,3 +772,15 @@
[X SNR (-349.0959218623025 dB) is not greater than or equal to 65.737. Got -349.0959218623025.]
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\]\t-2.9403580000000000e+7\t8.6956524848937988e-1\t2.9403580869565248e+7\t3.3814116790712982e+7\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 2.9403580869565248e+7 at index of 14650.\n\tMax RelError of 3.3814116790712982e+7 at index of 14650.\n]
+ expected: FAIL
+
+ [X SNR (-105.93391852623517 dB) is not greater than or equal to 65.737. Got -105.93391852623517.]
+ 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\]\t-2.5247278509648089e-39\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 SNR (42.96525288004425 dB) is not greater than or equal to 65.737. Got 42.96525288004425.]
+ expected: FAIL
diff --git a/tests/wpt/tests/ai/language_detection/detector-iframe.https.html b/tests/wpt/tests/ai/language_detection/detector-iframe.https.html
index ddcf82bec68..9dc39d44a00 100644
--- a/tests/wpt/tests/ai/language_detection/detector-iframe.https.html
+++ b/tests/wpt/tests/ai/language_detection/detector-iframe.https.html
@@ -1,4 +1,7 @@
<!DOCTYPE html>
+<meta name="timeout" content="long">
+<script src="/resources/testdriver.js"></script>
+<script src="/resources/testdriver-vendor.js"></script>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/common/get-host-info.sub.js"></script>
@@ -10,11 +13,21 @@ const { HTTPS_ORIGIN, HTTPS_NOTSAMESITE_ORIGIN } = get_host_info();
const PATH = location.pathname.substring(0, location.pathname.lastIndexOf('/') + 1);
const IFRAME_PATH = PATH + 'resources/iframe-helper.html';
+const getId = (() => {
+ let idCount = 0;
+ return () => idCount++;
+})();
+
function run_iframe_test(iframe, test_name) {
- iframe.contentWindow.postMessage({type: test_name}, '*');
+ const id = getId();
+ iframe.contentWindow.postMessage({id, type: test_name}, '*');
const {promise, resolve, reject} = Promise.withResolvers();
window.onmessage = message => {
+ if (message.data.id !== id){
+ return;
+ }
+
if (message.data.success) {
resolve(message.data.success);
} else {
@@ -27,19 +40,18 @@ function run_iframe_test(iframe, test_name) {
function load_iframe(src, permission_policy) {
let iframe = document.createElement('iframe');
- return new Promise((resolve, reject) => {
- iframe.onload = () => {
- resolve(iframe);
- }
- iframe.src = src;
- iframe.allow = permission_policy;
- document.body.appendChild(iframe);
- });
+ const {promise, resolve} = Promise.withResolvers();
+
+ iframe.onload = () => {
+ resolve(iframe);
+ }
+ iframe.src = src;
+ iframe.allow = permission_policy;
+ document.body.appendChild(iframe);
+
+ return promise;
}
-// TODO(crbug.com/414428433): Tests in this file intermittently crash.
-// Re-enable once potential causes in Permissions Policy implementation
-// and test setup are addressed.
promise_test(async t => {
const src = HTTPS_NOTSAMESITE_ORIGIN + IFRAME_PATH;
const iframe = await load_iframe(src, /*permission_policy=*/"");
@@ -49,7 +61,7 @@ promise_test(async t => {
promise_test(async t => {
const src = HTTPS_NOTSAMESITE_ORIGIN + IFRAME_PATH;
- const iframe = await load_iframe(src, "languageDetector");
+ const iframe = await load_iframe(src, "language-detector");
assert_equals(
await run_iframe_test(iframe, "LanguageDetectorCreate"), 'Success');
@@ -73,7 +85,7 @@ promise_test(async t => {
promise_test(async t => {
const src = HTTPS_NOTSAMESITE_ORIGIN + IFRAME_PATH;
- const iframe = await load_iframe(src, "languageDetector");
+ const iframe = await load_iframe(src, "language-detector");
assert_in_array(
await run_iframe_test(iframe, "LanguageDetectorAvailability"),
diff --git a/tests/wpt/tests/ai/language_detection/detector.https.window.js b/tests/wpt/tests/ai/language_detection/detector.https.window.js
index b0255bc552b..379b8741534 100644
--- a/tests/wpt/tests/ai/language_detection/detector.https.window.js
+++ b/tests/wpt/tests/ai/language_detection/detector.https.window.js
@@ -185,6 +185,11 @@ promise_test(async t => {
}, 'Aborting LanguageDetector.measureInputUsage().');
promise_test(async () => {
+ const detector = await createLanguageDetector({expectedInputLanguages: []});
+ assert_equals(detector.expectedInputLanguages, null);
+}, 'Creating LanguageDetector with empty expectedInputLanguages array');
+
+promise_test(async () => {
const detector = await createLanguageDetector();
assert_equals(detector.expectedInputLanguages, null);
}, 'Creating LanguageDetector without expectedInputLanguages');
diff --git a/tests/wpt/tests/ai/language_detection/resources/iframe-helper.html b/tests/wpt/tests/ai/language_detection/resources/iframe-helper.html
index fe07de3f8ab..35ba8525587 100644
--- a/tests/wpt/tests/ai/language_detection/resources/iframe-helper.html
+++ b/tests/wpt/tests/ai/language_detection/resources/iframe-helper.html
@@ -1,18 +1,28 @@
<!DOCTYPE HTML>
<meta charset="utf-8">
+<script src="/resources/testdriver.js"></script>
+<script src="/resources/testdriver-vendor.js"></script>
+<body></body>
<script>
+test_driver.set_test_context(parent);
+
window.onmessage = async message => {
- switch (message.data.type) {
- case 'LanguageDetectorCreate':
- LanguageDetector.create()
- .then(t => parent.postMessage({success: 'Success'}))
- .catch(err => parent.postMessage({err}));
- break;
- case 'LanguageDetectorAvailability':
- LanguageDetector.availability()
- .then(t => parent.postMessage({success: availability}))
- .catch(err => parent.postMessage({err}));
- break;
- };
+ const {id, type} = message.data;
+ try {
+ switch (type) {
+ case 'LanguageDetectorCreate':
+ await test_driver.bless("Create LanguageDetector", null, window);
+ await LanguageDetector.create();
+ parent.postMessage({id, success: 'Success'}, '*');
+ break;
+ case 'LanguageDetectorAvailability':
+ await test_driver.bless("Check LanguageDetector Availability", null, window);
+ const availability = await LanguageDetector.availability();
+ parent.postMessage({id, success: availability}, '*');
+ break;
+ }
+ } catch (err) {
+ parent.postMessage({id, err: err}, '*');
+ }
};
</script>
diff --git a/tests/wpt/tests/ai/summarizer/summarizer-abort.tentative.https.any.js b/tests/wpt/tests/ai/summarizer/summarizer-abort.tentative.https.window.js
index 64595ea930c..64595ea930c 100644
--- a/tests/wpt/tests/ai/summarizer/summarizer-abort.tentative.https.any.js
+++ b/tests/wpt/tests/ai/summarizer/summarizer-abort.tentative.https.window.js
diff --git a/tests/wpt/tests/ai/summarizer/summarizer-availability-available.tentative.https.any.js b/tests/wpt/tests/ai/summarizer/summarizer-availability-available.tentative.https.window.js
index 31c21ca777f..31c21ca777f 100644
--- a/tests/wpt/tests/ai/summarizer/summarizer-availability-available.tentative.https.any.js
+++ b/tests/wpt/tests/ai/summarizer/summarizer-availability-available.tentative.https.window.js
diff --git a/tests/wpt/tests/ai/summarizer/summarizer-availability.tentative.https.any.js b/tests/wpt/tests/ai/summarizer/summarizer-availability.tentative.https.window.js
index 8691765f693..8691765f693 100644
--- a/tests/wpt/tests/ai/summarizer/summarizer-availability.tentative.https.any.js
+++ b/tests/wpt/tests/ai/summarizer/summarizer-availability.tentative.https.window.js
diff --git a/tests/wpt/tests/ai/summarizer/summarizer-create-available.tentative.https.any.js b/tests/wpt/tests/ai/summarizer/summarizer-create-available.tentative.https.window.js
index c7e27d9766b..c7e27d9766b 100644
--- a/tests/wpt/tests/ai/summarizer/summarizer-create-available.tentative.https.any.js
+++ b/tests/wpt/tests/ai/summarizer/summarizer-create-available.tentative.https.window.js
diff --git a/tests/wpt/tests/ai/summarizer/summarizer-create.tentative.https.any.js b/tests/wpt/tests/ai/summarizer/summarizer-create.tentative.https.window.js
index 328cceefefb..328cceefefb 100644
--- a/tests/wpt/tests/ai/summarizer/summarizer-create.tentative.https.any.js
+++ b/tests/wpt/tests/ai/summarizer/summarizer-create.tentative.https.window.js
diff --git a/tests/wpt/tests/ai/summarizer/summarizer-measureInputUsage.tentative.https.any.js b/tests/wpt/tests/ai/summarizer/summarizer-measureInputUsage.tentative.https.window.js
index ce9745acf17..ce9745acf17 100644
--- a/tests/wpt/tests/ai/summarizer/summarizer-measureInputUsage.tentative.https.any.js
+++ b/tests/wpt/tests/ai/summarizer/summarizer-measureInputUsage.tentative.https.window.js
diff --git a/tests/wpt/tests/ai/summarizer/summarizer-summarize-streaming.tentative.https.any.js b/tests/wpt/tests/ai/summarizer/summarizer-summarize-streaming.tentative.https.window.js
index dbf41cdadbc..dbf41cdadbc 100644
--- a/tests/wpt/tests/ai/summarizer/summarizer-summarize-streaming.tentative.https.any.js
+++ b/tests/wpt/tests/ai/summarizer/summarizer-summarize-streaming.tentative.https.window.js
diff --git a/tests/wpt/tests/ai/summarizer/summarizer-summarize.tentative.https.any.js b/tests/wpt/tests/ai/summarizer/summarizer-summarize.tentative.https.window.js
index 62a780a3fc7..62a780a3fc7 100644
--- a/tests/wpt/tests/ai/summarizer/summarizer-summarize.tentative.https.any.js
+++ b/tests/wpt/tests/ai/summarizer/summarizer-summarize.tentative.https.window.js
diff --git a/tests/wpt/tests/content-security-policy/unsafe-eval/eval-blocked-in-about-blank-iframe.html b/tests/wpt/tests/content-security-policy/unsafe-eval/eval-blocked-in-about-blank-iframe.html
index 054e75b5274..b2286f56a23 100644
--- a/tests/wpt/tests/content-security-policy/unsafe-eval/eval-blocked-in-about-blank-iframe.html
+++ b/tests/wpt/tests/content-security-policy/unsafe-eval/eval-blocked-in-about-blank-iframe.html
@@ -19,18 +19,27 @@
const document_loaded = new Promise(resolve => window.onload = resolve);
await document_loaded;
- const eval_error = new Promise(resolve => {
- window.addEventListener('message', function(e) {
- assert_not_equals(e.data, 'FAIL', 'eval was executed in the frame');
- if (e.data === 'PASS')
- resolve();
+ const eval_error = new Promise((resolve, reject) => {
+ window.addEventListener('message', function(event) {
+ try {
+ assert_not_equals(event.data, 'FAIL', 'eval was executed in the frame');
+ if (event.data === 'PASS') {
+ resolve();
+ }
+ } catch (e) {
+ reject(e);
+ }
});
});
- const csp_violation_report = new Promise(resolve => {
- window.addEventListener('message', function(e) {
- if (e.data["violated-directive"]) {
- assert_equals(e.data["violated-directive"], "script-src");
- resolve();
+ const csp_violation_report = new Promise((resolve, reject) => {
+ window.addEventListener('message', function(event) {
+ try {
+ if (event.data["violated-directive"]) {
+ assert_equals(event.data["violated-directive"], "script-src");
+ resolve();
+ }
+ } catch (e) {
+ reject(e);
}
});
});
diff --git a/tests/wpt/tests/cookie-store/serviceworker_cookiechange_eventhandler_already_expired.https.any.js b/tests/wpt/tests/cookie-store/serviceworker_cookiechange_eventhandler_already_expired.https.any.js
new file mode 100644
index 00000000000..c40fdbeb6f1
--- /dev/null
+++ b/tests/wpt/tests/cookie-store/serviceworker_cookiechange_eventhandler_already_expired.https.any.js
@@ -0,0 +1,86 @@
+// META: title=Cookie Store API: cookiechange event in ServiceWorker with already-expired cookie.
+// META: global=serviceworker
+
+'use strict';
+
+const kScope = '/cookie-store/does/not/exist';
+
+function WorkerActivationPromise() {
+ return new Promise((resolve) => {
+ if (registration.active) {
+ resolve();
+ return;
+ }
+ self.addEventListener('activate', () => { resolve(); });
+ });
+}
+
+function RunOnceCookieChangeReceivedPromise() {
+ return new Promise(resolve => {
+ const listener = ev => {
+ resolve(ev);
+ self.removeEventListener('cookiechange', listener);
+ };
+ self.addEventListener('cookiechange', listener);
+ });
+}
+
+promise_test(async t => {
+ await WorkerActivationPromise();
+
+ const subscriptions = [{url: `${kScope}/path`}];
+ await registration.cookies.subscribe(subscriptions);
+ t.add_cleanup(() => registration.cookies.unsubscribe(subscriptions));
+
+ const eventPromise = RunOnceCookieChangeReceivedPromise();
+
+ await cookieStore.set({
+ name: 'cookie-name',
+ value: 'already-expired',
+ expires: new Date(new Date() - 10_000),
+ });
+
+ await cookieStore.set('another-cookie-name', 'ignore');
+ t.add_cleanup(() => cookieStore.delete('another-cookie-name'));
+
+ const event = await eventPromise;
+ assert_equals(event.type, 'cookiechange');
+ assert_equals(event.changed.length, 1);
+ assert_equals(event.changed[0].name, 'another-cookie-name');
+ assert_equals(event.changed[0].value, 'ignore');
+ assert_equals(event.deleted.length, 0);
+});
+
+promise_test(async t => {
+ await WorkerActivationPromise();
+
+ const subscriptions = [{url: `${kScope}/path`}];
+ await registration.cookies.subscribe(subscriptions);
+ t.add_cleanup(() => registration.cookies.unsubscribe(subscriptions));
+
+ const eventPromise = RunOnceCookieChangeReceivedPromise();
+
+ await cookieStore.set({
+ name: 'cookie-name',
+ value: 'already-expired',
+ expires: new Date(new Date() - 10_000),
+ partitioned: true,
+ });
+
+ await cookieStore.set({
+ name: 'another-cookie-name',
+ value: 'ignore',
+ partitioned: true,
+ });
+ t.add_cleanup(() => cookieStore.delete({
+ name: 'another-cookie-name',
+ partitioned: true,
+ }));
+
+ const event = await eventPromise;
+ assert_equals(event.type, 'cookiechange');
+ assert_equals(event.changed.length, 1);
+ assert_equals(event.changed[0].name, 'another-cookie-name');
+ assert_equals(event.changed[0].value, 'ignore');
+ assert_equals(event.deleted.length, 0);
+});
diff --git a/tests/wpt/tests/cookie-store/serviceworker_cookiechange_eventhandler_no_change.https.any.js b/tests/wpt/tests/cookie-store/serviceworker_cookiechange_eventhandler_no_change.https.any.js
new file mode 100644
index 00000000000..fb2e2db7381
--- /dev/null
+++ b/tests/wpt/tests/cookie-store/serviceworker_cookiechange_eventhandler_no_change.https.any.js
@@ -0,0 +1,128 @@
+// META: title=Cookie Store API: cookiechange event in ServiceWorker with already-expired cookie.
+// META: global=serviceworker
+
+'use strict';
+
+const kScope = '/cookie-store/does/not/exist';
+
+// Resolves when the service worker receives the 'activate' event.
+function WorkerActivationPromise() {
+ return new Promise((resolve) => {
+ if (registration.active) {
+ resolve();
+ return;
+ }
+ self.addEventListener('activate', () => { resolve(); });
+ });
+}
+
+// Resolves when a cookiechange event is received.
+function RunOnceCookieChangeReceivedPromise() {
+ return new Promise(resolve => {
+ const listener = ev => {
+ resolve(ev);
+ self.removeEventListener('cookiechange', listener);
+ };
+ self.addEventListener('cookiechange', listener);
+ });
+}
+
+promise_test(async t => {
+ await WorkerActivationPromise();
+
+ const subscriptions = [{url: `${kScope}/path`}];
+ await registration.cookies.subscribe(subscriptions);
+ t.add_cleanup(() => registration.cookies.unsubscribe(subscriptions));
+
+ let cookie_change_promise = RunOnceCookieChangeReceivedPromise();
+
+ await cookieStore.set('cookie-name', 'value');
+ t.add_cleanup(async () => {
+ await cookieStore.delete('cookie-name');
+ });
+
+ // Observes original cookie.
+ let event = await cookie_change_promise;
+ assert_equals(event.type, 'cookiechange');
+ assert_equals(event.changed.length, 1);
+ assert_equals(event.changed[0].name, 'cookie-name');
+ assert_equals(event.changed[0].value, 'value');
+ assert_equals(event.deleted.length, 0);
+
+ cookie_change_promise = RunOnceCookieChangeReceivedPromise();
+
+ // Duplicate overwrite should not be observed.
+ await cookieStore.set('cookie-name', 'value');
+
+ // This cookie should be observed instead.
+ await cookieStore.set('alternate-cookie-name', 'ignore');
+ t.add_cleanup(async () => {
+ await cookieStore.delete('alternate-cookie-name');
+ });
+
+ event = await cookie_change_promise;
+ assert_equals(event.type, 'cookiechange');
+ assert_equals(event.changed.length, 1);
+ assert_equals(event.changed[0].name, 'alternate-cookie-name');
+ assert_equals(event.changed[0].value, 'ignore');
+ assert_equals(event.deleted.length, 0);
+});
+
+promise_test(async t => {
+ await WorkerActivationPromise();
+
+ const subscriptions = [{url: `${kScope}/path`}];
+ await registration.cookies.subscribe(subscriptions);
+ t.add_cleanup(() => registration.cookies.unsubscribe(subscriptions));
+
+ let cookie_change_promise = RunOnceCookieChangeReceivedPromise();
+
+ await cookieStore.set({
+ name: 'cookie-name',
+ value: 'value',
+ partitioned: true,
+ });
+ t.add_cleanup(async () => {
+ await cookieStore.delete({
+ name: 'cookie-name',
+ partitioned: true,
+ });
+ });
+
+ // Observes original cookie.
+ let event = await cookie_change_promise;
+ assert_equals(event.type, 'cookiechange');
+ assert_equals(event.changed.length, 1);
+ assert_equals(event.changed[0].name, 'cookie-name');
+ assert_equals(event.changed[0].value, 'value');
+ assert_equals(event.deleted.length, 0);
+
+ cookie_change_promise = RunOnceCookieChangeReceivedPromise();
+
+ // Duplicate overwrite should not be observed.
+ await cookieStore.set({
+ name: 'cookie-name',
+ value: 'value',
+ partitioned: true,
+ });
+
+ // This cookie should instead.
+ await cookieStore.set({
+ name: 'alternate-cookie-name',
+ value: 'ignore',
+ partitioned: true,
+ });
+ t.add_cleanup(async () => {
+ await cookieStore.delete({
+ name: 'alternate-cookie-name',
+ partitioned: true,
+ });
+ });
+
+ event = await cookie_change_promise;
+ assert_equals(event.type, 'cookiechange');
+ assert_equals(event.changed.length, 1);
+ assert_equals(event.changed[0].name, 'alternate-cookie-name');
+ assert_equals(event.changed[0].value, 'ignore');
+ assert_equals(event.deleted.length, 0);
+});
diff --git a/tests/wpt/tests/cookies/partitioned-cookies/partitioned-cookies-samesite-attribute.https.html b/tests/wpt/tests/cookies/partitioned-cookies/partitioned-cookies-samesite-attribute.https.html
new file mode 100644
index 00000000000..323fb08236e
--- /dev/null
+++ b/tests/wpt/tests/cookies/partitioned-cookies/partitioned-cookies-samesite-attribute.https.html
@@ -0,0 +1,59 @@
+<!doctype html>
+<head>
+ <meta charset="utf-8" />
+ <meta name="timeout" content="long" />
+ <meta
+ name="help"
+ href="https://github.com/WICG/CHIPS#chips-cookies-having-independent-partitioned-state"
+ />
+ <script src="/common/get-host-info.sub.js"></script>
+ <script src="/resources/testharness.js"></script>
+ <script src="/resources/testharnessreport.js"></script>
+ <script src="/cookies/resources/testharness-helpers.js"></script>
+ <script src="/resources/testdriver.js"></script>
+ <script src="/resources/testdriver-vendor.js"></script>
+ <title>Test SameSite attribute behavior for partitioned cookies</title>
+</head>
+<body>
+ <script>
+ document.body.onload = async () => {
+ const iframe = document.createElement("iframe");
+ iframe.src = new URL(
+ "resources/partitioned-cookies-samesite-attributes-embed.html",
+ get_host_info().HTTPS_NOTSAMESITE_ORIGIN + self.location.pathname,
+ );
+ document.body.appendChild(iframe);
+ await new Promise(r => iframe.onload = r);
+ await fetch_tests_from_window(iframe.contentWindow);
+ };
+
+ promise_test(async (t) => {
+ t.add_cleanup(test_driver.delete_all_cookies);
+
+ document.cookie = "testPartitioned=0; Secure; Partitioned;";
+ document.cookie = "testUnpartitioned=1; Secure;";
+ const partitionedCookie = await test_driver.get_named_cookie("testPartitioned");
+ const unpartitionedCookie = await test_driver.get_named_cookie("testUnpartitioned");
+
+ // Browsers have not aligned on a common SameSite attribute default yet.
+ assert_any(assert_equals, partitionedCookie["sameSite"], ["Strict", "Lax", "None"]);
+ assert_equals(partitionedCookie["sameSite"], unpartitionedCookie["sameSite"]);
+ }, "In top-level contexts, partitioned cookies default to the same SameSite attribute as unpartitioned cookies.");
+
+ promise_test(async (t) => {
+ t.add_cleanup(test_driver.delete_all_cookies);
+
+ document.cookie = "testStrict=0; Secure; Partitioned; SameSite=Strict;";
+ let cookie = await test_driver.get_named_cookie("testStrict");
+ assert_equals(cookie["sameSite"], "Strict");
+
+ document.cookie = "testLax=0; Secure; Partitioned; SameSite=Lax;";
+ cookie = await test_driver.get_named_cookie("testLax");
+ assert_equals(cookie["sameSite"], "Lax");
+
+ document.cookie = "testNone=0; Secure; Partitioned; SameSite=None;";
+ cookie = await test_driver.get_named_cookie("testNone");
+ assert_equals(cookie["sameSite"], "None");
+ }, "In top-level contexts, partitioned cookies can be set with all SameSite attributes.");
+ </script>
+</body>
diff --git a/tests/wpt/tests/cookies/partitioned-cookies/resources/partitioned-cookies-samesite-attributes-embed.html b/tests/wpt/tests/cookies/partitioned-cookies/resources/partitioned-cookies-samesite-attributes-embed.html
new file mode 100644
index 00000000000..c6f64639eac
--- /dev/null
+++ b/tests/wpt/tests/cookies/partitioned-cookies/resources/partitioned-cookies-samesite-attributes-embed.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<meta charset="utf-8"/>
+<meta name="timeout" content="long" />
+<title>Partitioned cookie SameSite test site embedded in a cross-site context</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testdriver.js"></script>
+<script src="/resources/testdriver-vendor.js"></script>
+<script src="/common/get-host-info.sub.js"></script>
+<body>
+<script>
+promise_test(async t => {
+ test_driver.set_test_context(window.top);
+ t.add_cleanup(test_driver.delete_all_cookies);
+
+ document.cookie = "testUnset=0; Secure; Partitioned;";
+ document.cookie = "testStrict=0; Secure; Partitioned; SameSite=Strict;";
+ document.cookie = "testLax=0; Secure; Partitioned; SameSite=Lax;";
+ let cookies = await test_driver.get_all_cookies();
+ assert_equals(cookies.length, 0);
+
+ document.cookie = "testNone=0; Secure; Partitioned; SameSite=None;";
+ cookies = await test_driver.get_all_cookies();
+ assert_equals(cookies.length, 1);
+ const cookie = cookies[0];
+ assert_equals(cookie["name"], "testNone");
+ assert_equals(cookie["value"], "0");
+ assert_equals(cookie["sameSite"], "None");
+
+}, "In embedded cross-site contexts, partitioned cookies can only be set with explicit SameSite=None");
+</script>
+</body>
diff --git a/tests/wpt/tests/css/css-align/abspos/align-self-static-position-005-ref.html b/tests/wpt/tests/css/css-align/abspos/align-self-static-position-005-ref.html
index 947bd270448..62597fba605 100644
--- a/tests/wpt/tests/css/css-align/abspos/align-self-static-position-005-ref.html
+++ b/tests/wpt/tests/css/css-align/abspos/align-self-static-position-005-ref.html
@@ -14,7 +14,7 @@
}
</style>
<div class="container">
- <span style="font: 20px Ahem;">hello
+ <span style="font: 20px/1 Ahem;">hello
<span class="abs">hello</span>
<span style="vertical-align: top; font-size: 50px;">world</span>
</span>
diff --git a/tests/wpt/tests/css/css-align/abspos/align-self-static-position-005.html b/tests/wpt/tests/css/css-align/abspos/align-self-static-position-005.html
index e148f0ebda3..207a5443331 100644
--- a/tests/wpt/tests/css/css-align/abspos/align-self-static-position-005.html
+++ b/tests/wpt/tests/css/css-align/abspos/align-self-static-position-005.html
@@ -22,7 +22,7 @@
}
</style>
<div class="container">
- <span style="font: 20px Ahem;">hello
+ <span style="font: 20px/1 Ahem;">hello
<span class="abs">hello</span>
<span style="vertical-align: top; font-size: 50px;">world</span>
</span>
diff --git a/tests/wpt/tests/css/css-break/nested-fixedpos-in-inline-003-crash.html b/tests/wpt/tests/css/css-break/nested-fixedpos-in-inline-003-crash.html
new file mode 100644
index 00000000000..88a04288464
--- /dev/null
+++ b/tests/wpt/tests/css/css-break/nested-fixedpos-in-inline-003-crash.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html>
+<link rel="help" href="https://issuetracker.google.com/issues/406053621">
+<div style="column-count: 1;">
+ <div style="filter: blur(0px); display: inline;">
+ <div style="filter: blur(0px); display: inline">
+ <div style="position: relative;">
+ <div style="position: absolute;">
+ <div style="position: fixed;"></div>
+ </div>
+ </div>
+ </div>
+ </div>
+</div>
diff --git a/tests/wpt/tests/css/css-gaps/tentative/multicol/multicol-gap-decorations-001-ref.html b/tests/wpt/tests/css/css-gaps/multicol/multicol-gap-decorations-001-ref.html
index 834c96ccd39..834c96ccd39 100644
--- a/tests/wpt/tests/css/css-gaps/tentative/multicol/multicol-gap-decorations-001-ref.html
+++ b/tests/wpt/tests/css/css-gaps/multicol/multicol-gap-decorations-001-ref.html
diff --git a/tests/wpt/tests/css/css-gaps/tentative/multicol/multicol-gap-decorations-001.html b/tests/wpt/tests/css/css-gaps/multicol/multicol-gap-decorations-001.html
index c3752156c7d..c3752156c7d 100644
--- a/tests/wpt/tests/css/css-gaps/tentative/multicol/multicol-gap-decorations-001.html
+++ b/tests/wpt/tests/css/css-gaps/multicol/multicol-gap-decorations-001.html
diff --git a/tests/wpt/tests/css/css-gaps/tentative/multicol/multicol-gap-decorations-002-ref.html b/tests/wpt/tests/css/css-gaps/multicol/multicol-gap-decorations-002-ref.html
index d132f0ca677..d132f0ca677 100644
--- a/tests/wpt/tests/css/css-gaps/tentative/multicol/multicol-gap-decorations-002-ref.html
+++ b/tests/wpt/tests/css/css-gaps/multicol/multicol-gap-decorations-002-ref.html
diff --git a/tests/wpt/tests/css/css-gaps/tentative/multicol/multicol-gap-decorations-002.html b/tests/wpt/tests/css/css-gaps/multicol/multicol-gap-decorations-002.html
index 0b632fa94ac..0b632fa94ac 100644
--- a/tests/wpt/tests/css/css-gaps/tentative/multicol/multicol-gap-decorations-002.html
+++ b/tests/wpt/tests/css/css-gaps/multicol/multicol-gap-decorations-002.html
diff --git a/tests/wpt/tests/css/css-gaps/tentative/multicol/multicol-gap-decorations-003-ref.html b/tests/wpt/tests/css/css-gaps/multicol/multicol-gap-decorations-003-ref.html
index cd26da24389..cd26da24389 100644
--- a/tests/wpt/tests/css/css-gaps/tentative/multicol/multicol-gap-decorations-003-ref.html
+++ b/tests/wpt/tests/css/css-gaps/multicol/multicol-gap-decorations-003-ref.html
diff --git a/tests/wpt/tests/css/css-gaps/tentative/multicol/multicol-gap-decorations-003.html b/tests/wpt/tests/css/css-gaps/multicol/multicol-gap-decorations-003.html
index 2f2473fd046..2f2473fd046 100644
--- a/tests/wpt/tests/css/css-gaps/tentative/multicol/multicol-gap-decorations-003.html
+++ b/tests/wpt/tests/css/css-gaps/multicol/multicol-gap-decorations-003.html
diff --git a/tests/wpt/tests/css/css-gaps/tentative/multicol/multicol-gap-decorations-004-ref.html b/tests/wpt/tests/css/css-gaps/multicol/multicol-gap-decorations-004-ref.html
index 002b1f2b594..002b1f2b594 100644
--- a/tests/wpt/tests/css/css-gaps/tentative/multicol/multicol-gap-decorations-004-ref.html
+++ b/tests/wpt/tests/css/css-gaps/multicol/multicol-gap-decorations-004-ref.html
diff --git a/tests/wpt/tests/css/css-gaps/tentative/multicol/multicol-gap-decorations-004.html b/tests/wpt/tests/css/css-gaps/multicol/multicol-gap-decorations-004.html
index 0dcbeef4df8..0dcbeef4df8 100644
--- a/tests/wpt/tests/css/css-gaps/tentative/multicol/multicol-gap-decorations-004.html
+++ b/tests/wpt/tests/css/css-gaps/multicol/multicol-gap-decorations-004.html
diff --git a/tests/wpt/tests/css/css-gaps/tentative/multicol/multicol-gap-decorations-005-ref.html b/tests/wpt/tests/css/css-gaps/multicol/multicol-gap-decorations-005-ref.html
index 6543021c979..6543021c979 100644
--- a/tests/wpt/tests/css/css-gaps/tentative/multicol/multicol-gap-decorations-005-ref.html
+++ b/tests/wpt/tests/css/css-gaps/multicol/multicol-gap-decorations-005-ref.html
diff --git a/tests/wpt/tests/css/css-gaps/tentative/multicol/multicol-gap-decorations-005.html b/tests/wpt/tests/css/css-gaps/multicol/multicol-gap-decorations-005.html
index daa65e904e7..daa65e904e7 100644
--- a/tests/wpt/tests/css/css-gaps/tentative/multicol/multicol-gap-decorations-005.html
+++ b/tests/wpt/tests/css/css-gaps/multicol/multicol-gap-decorations-005.html
diff --git a/tests/wpt/tests/css/css-gaps/tentative/multicol/multicol-gap-decorations-006-ref.html b/tests/wpt/tests/css/css-gaps/multicol/multicol-gap-decorations-006-ref.html
index 4cb56d207fe..4cb56d207fe 100644
--- a/tests/wpt/tests/css/css-gaps/tentative/multicol/multicol-gap-decorations-006-ref.html
+++ b/tests/wpt/tests/css/css-gaps/multicol/multicol-gap-decorations-006-ref.html
diff --git a/tests/wpt/tests/css/css-gaps/tentative/multicol/multicol-gap-decorations-006.html b/tests/wpt/tests/css/css-gaps/multicol/multicol-gap-decorations-006.html
index 64b3b007ab5..64b3b007ab5 100644
--- a/tests/wpt/tests/css/css-gaps/tentative/multicol/multicol-gap-decorations-006.html
+++ b/tests/wpt/tests/css/css-gaps/multicol/multicol-gap-decorations-006.html
diff --git a/tests/wpt/tests/css/css-gaps/tentative/multicol/multicol-gap-decorations-007-ref.html b/tests/wpt/tests/css/css-gaps/multicol/multicol-gap-decorations-007-ref.html
index 09973ddc690..09973ddc690 100644
--- a/tests/wpt/tests/css/css-gaps/tentative/multicol/multicol-gap-decorations-007-ref.html
+++ b/tests/wpt/tests/css/css-gaps/multicol/multicol-gap-decorations-007-ref.html
diff --git a/tests/wpt/tests/css/css-gaps/tentative/multicol/multicol-gap-decorations-007.html b/tests/wpt/tests/css/css-gaps/multicol/multicol-gap-decorations-007.html
index 1f23ed7f7ca..1f23ed7f7ca 100644
--- a/tests/wpt/tests/css/css-gaps/tentative/multicol/multicol-gap-decorations-007.html
+++ b/tests/wpt/tests/css/css-gaps/multicol/multicol-gap-decorations-007.html
diff --git a/tests/wpt/tests/css/css-gaps/tentative/multicol/multicol-gap-decorations-008-ref.html b/tests/wpt/tests/css/css-gaps/multicol/multicol-gap-decorations-008-ref.html
index d49c2f50f19..d49c2f50f19 100644
--- a/tests/wpt/tests/css/css-gaps/tentative/multicol/multicol-gap-decorations-008-ref.html
+++ b/tests/wpt/tests/css/css-gaps/multicol/multicol-gap-decorations-008-ref.html
diff --git a/tests/wpt/tests/css/css-gaps/tentative/multicol/multicol-gap-decorations-008.html b/tests/wpt/tests/css/css-gaps/multicol/multicol-gap-decorations-008.html
index ed299b5d9f6..ed299b5d9f6 100644
--- a/tests/wpt/tests/css/css-gaps/tentative/multicol/multicol-gap-decorations-008.html
+++ b/tests/wpt/tests/css/css-gaps/multicol/multicol-gap-decorations-008.html
diff --git a/tests/wpt/tests/css/css-gaps/tentative/multicol/multicol-gap-decorations-009-ref.html b/tests/wpt/tests/css/css-gaps/multicol/multicol-gap-decorations-009-ref.html
index 124bf7eaeb1..124bf7eaeb1 100644
--- a/tests/wpt/tests/css/css-gaps/tentative/multicol/multicol-gap-decorations-009-ref.html
+++ b/tests/wpt/tests/css/css-gaps/multicol/multicol-gap-decorations-009-ref.html
diff --git a/tests/wpt/tests/css/css-gaps/tentative/multicol/multicol-gap-decorations-009.html b/tests/wpt/tests/css/css-gaps/multicol/multicol-gap-decorations-009.html
index b00c6a70f8a..b00c6a70f8a 100644
--- a/tests/wpt/tests/css/css-gaps/tentative/multicol/multicol-gap-decorations-009.html
+++ b/tests/wpt/tests/css/css-gaps/multicol/multicol-gap-decorations-009.html
diff --git a/tests/wpt/tests/css/css-gaps/tentative/multicol/multicol-gap-decorations-010-ref.html b/tests/wpt/tests/css/css-gaps/multicol/multicol-gap-decorations-010-ref.html
index 9582ab4103d..9582ab4103d 100644
--- a/tests/wpt/tests/css/css-gaps/tentative/multicol/multicol-gap-decorations-010-ref.html
+++ b/tests/wpt/tests/css/css-gaps/multicol/multicol-gap-decorations-010-ref.html
diff --git a/tests/wpt/tests/css/css-gaps/tentative/multicol/multicol-gap-decorations-010.html b/tests/wpt/tests/css/css-gaps/multicol/multicol-gap-decorations-010.html
index 61bb4a9b933..61bb4a9b933 100644
--- a/tests/wpt/tests/css/css-gaps/tentative/multicol/multicol-gap-decorations-010.html
+++ b/tests/wpt/tests/css/css-gaps/multicol/multicol-gap-decorations-010.html
diff --git a/tests/wpt/tests/css/css-gaps/tentative/multicol/multicol-gap-decorations-011-ref.html b/tests/wpt/tests/css/css-gaps/multicol/multicol-gap-decorations-011-ref.html
index 3387918d399..3387918d399 100644
--- a/tests/wpt/tests/css/css-gaps/tentative/multicol/multicol-gap-decorations-011-ref.html
+++ b/tests/wpt/tests/css/css-gaps/multicol/multicol-gap-decorations-011-ref.html
diff --git a/tests/wpt/tests/css/css-gaps/tentative/multicol/multicol-gap-decorations-011.html b/tests/wpt/tests/css/css-gaps/multicol/multicol-gap-decorations-011.html
index cf588ded41e..cf588ded41e 100644
--- a/tests/wpt/tests/css/css-gaps/tentative/multicol/multicol-gap-decorations-011.html
+++ b/tests/wpt/tests/css/css-gaps/multicol/multicol-gap-decorations-011.html
diff --git a/tests/wpt/tests/css/css-gaps/tentative/multicol/multicol-gap-decorations-012-ref.html b/tests/wpt/tests/css/css-gaps/multicol/multicol-gap-decorations-012-ref.html
index 9fb5e85e920..9fb5e85e920 100644
--- a/tests/wpt/tests/css/css-gaps/tentative/multicol/multicol-gap-decorations-012-ref.html
+++ b/tests/wpt/tests/css/css-gaps/multicol/multicol-gap-decorations-012-ref.html
diff --git a/tests/wpt/tests/css/css-gaps/tentative/multicol/multicol-gap-decorations-012.html b/tests/wpt/tests/css/css-gaps/multicol/multicol-gap-decorations-012.html
index 078b810cf8e..078b810cf8e 100644
--- a/tests/wpt/tests/css/css-gaps/tentative/multicol/multicol-gap-decorations-012.html
+++ b/tests/wpt/tests/css/css-gaps/multicol/multicol-gap-decorations-012.html
diff --git a/tests/wpt/tests/css/css-gaps/tentative/multicol/multicol-gap-decorations-013-ref.html b/tests/wpt/tests/css/css-gaps/multicol/multicol-gap-decorations-013-ref.html
index 8e426d8ed32..8e426d8ed32 100644
--- a/tests/wpt/tests/css/css-gaps/tentative/multicol/multicol-gap-decorations-013-ref.html
+++ b/tests/wpt/tests/css/css-gaps/multicol/multicol-gap-decorations-013-ref.html
diff --git a/tests/wpt/tests/css/css-gaps/tentative/multicol/multicol-gap-decorations-013.html b/tests/wpt/tests/css/css-gaps/multicol/multicol-gap-decorations-013.html
index d4170084f06..d4170084f06 100644
--- a/tests/wpt/tests/css/css-gaps/tentative/multicol/multicol-gap-decorations-013.html
+++ b/tests/wpt/tests/css/css-gaps/multicol/multicol-gap-decorations-013.html
diff --git a/tests/wpt/tests/css/css-gaps/tentative/multicol/multicol-gap-decorations-014-ref.html b/tests/wpt/tests/css/css-gaps/multicol/multicol-gap-decorations-014-ref.html
index 9d9674bd476..9d9674bd476 100644
--- a/tests/wpt/tests/css/css-gaps/tentative/multicol/multicol-gap-decorations-014-ref.html
+++ b/tests/wpt/tests/css/css-gaps/multicol/multicol-gap-decorations-014-ref.html
diff --git a/tests/wpt/tests/css/css-gaps/tentative/multicol/multicol-gap-decorations-014.html b/tests/wpt/tests/css/css-gaps/multicol/multicol-gap-decorations-014.html
index 1dcd393d99a..1dcd393d99a 100644
--- a/tests/wpt/tests/css/css-gaps/tentative/multicol/multicol-gap-decorations-014.html
+++ b/tests/wpt/tests/css/css-gaps/multicol/multicol-gap-decorations-014.html
diff --git a/tests/wpt/tests/css/css-gaps/multicol/multicol-gap-decorations-015-ref.html b/tests/wpt/tests/css/css-gaps/multicol/multicol-gap-decorations-015-ref.html
new file mode 100644
index 00000000000..2fee77be84c
--- /dev/null
+++ b/tests/wpt/tests/css/css-gaps/multicol/multicol-gap-decorations-015-ref.html
@@ -0,0 +1,70 @@
+<!DOCTYPE html>
+<link rel="help" href="https://drafts.csswg.org/css-gaps-1/">
+<link rel="author" title="Javier Contreras" href="mailto:javiercon@microsoft.com">
+<style>
+ body {
+ margin: 0px;
+ }
+
+ .outer {
+ columns: 4;
+ orphans: 1;
+ widows: 1;
+ border: dotted 2px black;
+ width: 500px;
+ }
+
+ .col-box {
+ background: cyan;
+ height: 20px;
+ /* keep each box whole */
+ break-inside: avoid;
+ }
+
+ .spanner {
+ column-span: all;
+ background: grey;
+ opacity: 0.5;
+ height: 20px;
+ }
+
+ .pink-box {
+ column-span: all;
+ background: hotpink;
+ height: 20px;
+ width: 100px;
+ }
+
+ .first-column-gaps {
+ position: absolute;
+ top: 82px;
+ display: flex;
+ height: 20px;
+ left: 123px;
+ column-gap: 128px;
+ }
+
+ .column-gap {
+ background: black;
+ width: 1px;
+ }
+</style>
+<div class="first-column-gaps">
+ <div class="column-gap"></div>
+ <div class="column-gap"></div>
+ <div class="column-gap"></div>
+</div>
+<div class="column-gap" style="position: absolute; left: 123px; height: 20px; top:2px;"></div>
+<div class="outer">
+ <div class="col-box"></div>
+ <div class="col-box"></div>
+
+ <div class="spanner"></div>
+ <div class="pink-box"></div>
+ <div class="spanner"></div>
+
+ <div class="col-box"></div>
+ <div class="col-box"></div>
+ <div class="col-box"></div>
+ <div class="col-box"></div>
+</div>
diff --git a/tests/wpt/tests/css/css-gaps/multicol/multicol-gap-decorations-015.html b/tests/wpt/tests/css/css-gaps/multicol/multicol-gap-decorations-015.html
new file mode 100644
index 00000000000..65af5112097
--- /dev/null
+++ b/tests/wpt/tests/css/css-gaps/multicol/multicol-gap-decorations-015.html
@@ -0,0 +1,55 @@
+<!DOCTYPE html>
+<title>
+ CSS Gap Decorations: Multicolumn gap decorations painted with different num of columns per row.
+</title>
+<link rel="help" href="https://drafts.csswg.org/css-gaps-1/">
+<link rel="match" href="multicol-gap-decorations-015-ref.html">
+<link rel="author" title="Javier Contreras" href="mailto:javiercon@microsoft.com">
+<style>
+ body {
+ margin: 0px;
+ }
+
+ .outer {
+ columns: 4;
+ column-rule: solid 1px black;
+ orphans: 1;
+ widows: 1;
+ border: dotted 2px black;
+ width: 500px;
+ }
+
+ .col-box {
+ background: cyan;
+ height: 20px;
+ /* keep each box whole */
+ break-inside: avoid;
+ }
+
+ .spanner {
+ column-span: all;
+ background: grey;
+ opacity: 0.5;
+ height: 20px;
+ }
+
+ .pink-box {
+ column-span: all;
+ background: hotpink;
+ height: 20px;
+ width: 100px;
+ }
+</style>
+<div class="outer">
+ <div class="col-box"></div>
+ <div class="col-box"></div>
+
+ <div class="spanner"></div>
+ <div class="pink-box"></div>
+ <div class="spanner"></div>
+
+ <div class="col-box"></div>
+ <div class="col-box"></div>
+ <div class="col-box"></div>
+ <div class="col-box"></div>
+</div>
diff --git a/tests/wpt/tests/css/css-gaps/multicol/multicol-gap-decorations-016-ref.html b/tests/wpt/tests/css/css-gaps/multicol/multicol-gap-decorations-016-ref.html
new file mode 100644
index 00000000000..8b2458fccce
--- /dev/null
+++ b/tests/wpt/tests/css/css-gaps/multicol/multicol-gap-decorations-016-ref.html
@@ -0,0 +1,70 @@
+<!DOCTYPE html>
+<link rel="help" href="https://drafts.csswg.org/css-gaps-1/">
+<link rel="author" title="Javier Contreras" href="mailto:javiercon@microsoft.com">
+<style>
+ body {
+ margin: 0px;
+ }
+
+ .outer {
+ columns: 4;
+ orphans: 1;
+ widows: 1;
+ border: dotted 2px black;
+ width: 500px;
+ }
+
+ .col-box {
+ background: cyan;
+ height: 20px;
+ /* keep each box whole */
+ break-inside: avoid;
+ }
+
+ .spanner {
+ column-span: all;
+ background: grey;
+ opacity: 0.5;
+ height: 20px;
+ }
+
+ .pink-box {
+ column-span: all;
+ background: hotpink;
+ height: 20px;
+ width: 100px;
+ }
+
+ .first-column-gaps {
+ position: absolute;
+ top: 2px;
+ display: flex;
+ height: 20px;
+ left: 123px;
+ column-gap: 128px;
+ }
+
+ .column-gap {
+ background: black;
+ width: 1px;
+ }
+</style>
+<div class="first-column-gaps">
+ <div class="column-gap"></div>
+ <div class="column-gap"></div>
+ <div class="column-gap"></div>
+</div>
+<div class="column-gap" style="position: absolute; left: 123px; height: 20px; top:82px;"></div>
+<div class="outer">
+ <div class="col-box"></div>
+ <div class="col-box"></div>
+ <div class="col-box"></div>
+ <div class="col-box"></div>
+
+ <div class="spanner"></div>
+ <div class="pink-box"></div>
+ <div class="spanner"></div>
+
+ <div class="col-box"></div>
+ <div class="col-box"></div>
+</div>
diff --git a/tests/wpt/tests/css/css-gaps/multicol/multicol-gap-decorations-016.html b/tests/wpt/tests/css/css-gaps/multicol/multicol-gap-decorations-016.html
new file mode 100644
index 00000000000..da205e0b88b
--- /dev/null
+++ b/tests/wpt/tests/css/css-gaps/multicol/multicol-gap-decorations-016.html
@@ -0,0 +1,55 @@
+<!DOCTYPE html>
+<title>
+ CSS Gap Decorations: Multicolumn gap decorations painted with different num of columns per row.
+</title>
+<link rel="help" href="https://drafts.csswg.org/css-gaps-1/">
+<link rel="match" href="multicol-gap-decorations-016-ref.html">
+<link rel="author" title="Javier Contreras" href="mailto:javiercon@microsoft.com">
+<style>
+ body {
+ margin: 0px;
+ }
+
+ .outer {
+ columns: 4;
+ column-rule: solid 1px black;
+ orphans: 1;
+ widows: 1;
+ border: dotted 2px black;
+ width: 500px;
+ }
+
+ .col-box {
+ background: cyan;
+ height: 20px;
+ /* keep each box whole */
+ break-inside: avoid;
+ }
+
+ .spanner {
+ column-span: all;
+ background: grey;
+ opacity: 0.5;
+ height: 20px;
+ }
+
+ .pink-box {
+ column-span: all;
+ background: hotpink;
+ height: 20px;
+ width: 100px;
+ }
+</style>
+<div class="outer">
+ <div class="col-box"></div>
+ <div class="col-box"></div>
+ <div class="col-box"></div>
+ <div class="col-box"></div>
+
+ <div class="spanner"></div>
+ <div class="pink-box"></div>
+ <div class="spanner"></div>
+
+ <div class="col-box"></div>
+ <div class="col-box"></div>
+</div>
diff --git a/tests/wpt/tests/css/css-grid/abspos/abspos-in-flexbox-in-grid-crash.html b/tests/wpt/tests/css/css-grid/abspos/abspos-in-flexbox-in-grid-crash.html
new file mode 100644
index 00000000000..a2f71fb78e7
--- /dev/null
+++ b/tests/wpt/tests/css/css-grid/abspos/abspos-in-flexbox-in-grid-crash.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<link rel="help" href="https://github.com/servo/servo/issues/36696">
+
+<div style="display: flex; position: relative">
+ <div style="display:grid">
+ <div>
+ <div style="display: flex">
+ <div style="position: absolute"></div>
+ </div>
+ </div>
+ </div>
+</div>
diff --git a/tests/wpt/tests/css/css-grid/grid-definition/grid-auto-fit-with-calc.html b/tests/wpt/tests/css/css-grid/grid-definition/grid-auto-fit-with-calc.html
new file mode 100644
index 00000000000..4b655c1e121
--- /dev/null
+++ b/tests/wpt/tests/css/css-grid/grid-definition/grid-auto-fit-with-calc.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<html>
+<head>
+<link rel="author" title="Sammy Gill" href="mailto:sammy.gill@apple.com">
+<link rel="help" href="https://drafts.csswg.org/css-grid-2/#auto-repeat">
+<link rel="match" href="../../reference/ref-filled-green-100px-square-only.html">
+<style>
+ .grid {
+ display: grid;
+ width: 100px;
+ grid-template-columns: repeat(auto-fit, minmax(calc(100% - 10px), calc(100% - 100px)));
+ background-color: green;
+ }
+</style>
+</head>
+<body>
+<p>Test passes if there is a filled green square.</p>
+<div class="grid">
+ <div style="height: 50px;"></div>
+ <div style="height: 50px;"></div>
+</div>
+</body>
+</html>
diff --git a/tests/wpt/tests/css/css-grid/subgrid/line-names-015.html b/tests/wpt/tests/css/css-grid/subgrid/line-names-015.html
new file mode 100644
index 00000000000..6f5479abf89
--- /dev/null
+++ b/tests/wpt/tests/css/css-grid/subgrid/line-names-015.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Grid Test: Clamping a nested subgrid's grid-template-areas in one dimension</title>
+<link rel="author" title="Kurt Catti-Schmidt" href="mailto:kschmi@microsoft.com">
+<link rel="help" href="https://drafts.csswg.org/css-grid-2/#grid-template-areas-property">
+<link rel="match" href="../../reference/ref-filled-green-100px-square.xht">
+<style>
+.grid {
+ background: green;
+ display: grid;
+ height: 100px;
+ width: 100px;
+ grid-template: 50px 50px / 50px 50px;
+ grid-template-areas: "item item"
+ "item item";
+}
+.subgrid {
+ display: grid;
+ grid-template-columns: subgrid;
+ grid-template-rows: 50px 50px;
+ grid-column: span 2;
+ grid-row: span 2;
+}
+.item {
+ background: red;
+ grid-area: item;
+}
+</style>
+<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
+<div class="grid">
+ <div class="subgrid">
+ <div class="item"></div>
+ </div>
+</div>
diff --git a/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-auto-031.tentative.html b/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-auto-031.tentative.html
index a723430c83e..737caff7775 100644
--- a/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-auto-031.tentative.html
+++ b/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-auto-031.tentative.html
@@ -20,6 +20,9 @@
.collapse-through {
margin: 10px;
}
+.rel {
+ position: relative;
+}
.abspos {
position: absolute;
right: 0;
@@ -32,7 +35,8 @@
<!--
The bottom margin of the first `.inner` ends at the clamp boundary, and the
bottom margin of `.collapse-through` ends after it. The clamp point therefore
- is before `.collapse-through`, and so `.abpos` won't be visible.
+ is before `.collapse-through`, so `.rel` will be after the clamp point and
+ `.abpos` won't be visible.
-->
<div class="clamp">
@@ -41,7 +45,7 @@ Line 2
Line 3
Line 4</div>
<div class="collapse-through"></div>
-<div class="abspos"></div>
+<div class="rel"><div class="abspos"></div></div>
<div class="inner">Line 5
Line 6
Line 7
diff --git a/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-001.tentative.html b/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-001.html
index 79667f23fbd..fd261493f06 100644
--- a/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-001.tentative.html
+++ b/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-001.html
@@ -1,10 +1,10 @@
<!DOCTYPE html>
<meta charset="utf-8">
-<title>CSS Overflow: abspos at the start of a line-clamp</title>
+<title>CSS Overflow: abspos whose containing block is outside the line-clamp container gets painted</title>
<link rel="author" title="Andreu Botella" href="mailto:abotella@igalia.com">
<link rel="help" href="https://drafts.csswg.org/css-overflow-4/#line-clamp">
<link rel="match" href="reference/line-clamp-with-abspos-001-ref.html">
-<meta name="assert" content="Absolute positioned boxes in an inline formatting context inside a line-clamp container are not hidden if they are in the box tree before the clamp point.">
+<meta name="assert" content="Absolute positioned boxes in a line-clamp container are hidden if and only if their containing block precedes or contains the clamp point. In this case, the containing block is the initial containing block, so the abspos gets shown.">
<style>
.clamp {
line-clamp: 4;
@@ -15,10 +15,10 @@
}
.abspos {
position: absolute;
- right: 0;
- width: 50px;
- height: 50px;
- margin: 4px;
+ top: 0;
+ left: 0;
+ width: 20px;
+ height: 20px;
background-color: skyblue;
}
</style>
diff --git a/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-002.tentative.html b/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-002.html
index cecb9d52bc6..233a345c927 100644
--- a/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-002.tentative.html
+++ b/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-002.html
@@ -1,10 +1,10 @@
<!DOCTYPE html>
<meta charset="utf-8">
-<title>CSS Overflow: abspos at the start of a line-clamp</title>
+<title>CSS Overflow: abspos whose containing block is outside the line-clamp container gets painted</title>
<link rel="author" title="Andreu Botella" href="mailto:abotella@igalia.com">
<link rel="help" href="https://drafts.csswg.org/css-overflow-4/#line-clamp">
<link rel="match" href="reference/line-clamp-with-abspos-001-ref.html">
-<meta name="assert" content="Absolute positioned boxes in a block formatting context inside a line-clamp container are not hidden if they are in the box tree before the clamp point.">
+<meta name="assert" content="Absolute positioned boxes in a line-clamp container are hidden if and only if their containing block precedes or contains the clamp point. In this case, the containing block is the initial containing block, so the abspos gets shown.">
<style>
.clamp {
line-clamp: 4;
@@ -14,10 +14,10 @@
}
.abspos {
position: absolute;
- right: 0;
- width: 50px;
- height: 50px;
- margin: 4px;
+ top: 0;
+ left: 0;
+ width: 20px;
+ height: 20px;
background-color: skyblue;
}
.pre {
diff --git a/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-003.html b/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-003.html
new file mode 100644
index 00000000000..8b5d681d97c
--- /dev/null
+++ b/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-003.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Overflow: abspos whose containing block is outside the line-clamp container gets painted</title>
+<link rel="author" title="Andreu Botella" href="mailto:abotella@igalia.com">
+<link rel="help" href="https://drafts.csswg.org/css-overflow-4/#line-clamp">
+<link rel="match" href="reference/line-clamp-with-abspos-001-ref.html">
+<meta name="assert" content="Absolute positioned boxes in a line-clamp container are hidden if and only if their containing block precedes or contains the clamp point. In this case, the containing block is the initial containing block, so the abspos gets shown, even if its static position is after the clamp point.">
+<style>
+.clamp {
+ line-clamp: 4;
+ font: 16px / 32px serif;
+ padding: 0 4px;
+ white-space: pre;
+ background-color: yellow;
+}
+.abspos {
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 20px;
+ height: 20px;
+ background-color: skyblue;
+}
+</style>
+<div class="clamp">Line 1
+Line 2
+Line 3
+Line 4
+<div class="abspos"></div>Line 5</div>
diff --git a/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-003.tentative.html b/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-003.tentative.html
deleted file mode 100644
index e4bd1de222e..00000000000
--- a/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-003.tentative.html
+++ /dev/null
@@ -1,29 +0,0 @@
-<!DOCTYPE html>
-<meta charset="utf-8">
-<title>CSS Overflow: abspos in line-clamp after clamp point</title>
-<link rel="author" title="Andreu Botella" href="mailto:abotella@igalia.com">
-<link rel="help" href="https://drafts.csswg.org/css-overflow-4/#line-clamp">
-<link rel="match" href="reference/webkit-line-clamp-005-ref.html">
-<meta name="assert" content="Absolute positioned boxes in an inline formatting context inside a line-clamp container are always hidden if they are in the box tree after the clamp point.">
-<style>
-.clamp {
- line-clamp: 4;
- font: 16px / 32px serif;
- padding: 0 4px;
- white-space: pre;
- background-color: yellow;
-}
-.abspos {
- position: absolute;
- right: 0;
- width: 50px;
- height: 50px;
- margin: 4px;
- background-color: skyblue;
-}
-</style>
-<div class="clamp">Line 1
-Line 2
-Line 3
-Line 4
-<div class="abspos"></div>Line 5</div>
diff --git a/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-004.html b/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-004.html
new file mode 100644
index 00000000000..c079974ac5c
--- /dev/null
+++ b/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-004.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Overflow: abspos whose containing block is outside the line-clamp container gets painted</title>
+<link rel="author" title="Andreu Botella" href="mailto:abotella@igalia.com">
+<link rel="help" href="https://drafts.csswg.org/css-overflow-4/#line-clamp">
+<link rel="match" href="reference/line-clamp-with-abspos-001-ref.html">
+<meta name="assert" content="Absolute positioned boxes in a line-clamp container are hidden if and only if their containing block precedes or contains the clamp point. In this case, the containing block is the initial containing block, so the abspos gets shown, even if its static position is after the clamp point.">
+<style>
+.clamp {
+ line-clamp: 4;
+ font: 16px / 32px serif;
+ padding: 0 4px;
+ background-color: yellow;
+}
+.abspos {
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 20px;
+ height: 20px;
+ background-color: skyblue;
+}
+.pre {
+ white-space: pre;
+}
+</style>
+<div class="clamp">
+<div class="pre">Line 1
+Line 2
+Line 3
+Line 4</div>
+<div class="abspos"></div>
+<div>Line 5</div>
+</div>
diff --git a/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-004.tentative.html b/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-004.tentative.html
deleted file mode 100644
index 483e6d1da6d..00000000000
--- a/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-004.tentative.html
+++ /dev/null
@@ -1,34 +0,0 @@
-<!DOCTYPE html>
-<meta charset="utf-8">
-<title>CSS Overflow: abspos in line-clamp after clamp point</title>
-<link rel="author" title="Andreu Botella" href="mailto:abotella@igalia.com">
-<link rel="help" href="https://drafts.csswg.org/css-overflow-4/#line-clamp">
-<link rel="match" href="reference/webkit-line-clamp-005-ref.html">
-<meta name="assert" content="Absolute positioned boxes in a block formatting context inside a line-clamp container are always hidden if they are in the box tree after the clamp point.">
-<style>
-.clamp {
- line-clamp: 4;
- font: 16px / 32px serif;
- padding: 0 4px;
- background-color: yellow;
-}
-.abspos {
- position: absolute;
- right: 0;
- width: 50px;
- height: 50px;
- margin: 4px;
- background-color: skyblue;
-}
-.pre {
- white-space: pre;
-}
-</style>
-<div class="clamp">
-<div class="pre">Line 1
-Line 2
-Line 3
-Line 4</div>
-<div class="abspos"></div>
-<div>Line 5</div>
-</div>
diff --git a/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-008.tentative.html b/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-005.html
index 9c62e44f389..58656135cf0 100644
--- a/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-008.tentative.html
+++ b/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-005.html
@@ -1,26 +1,25 @@
<!DOCTYPE html>
<meta charset="utf-8">
-<title>CSS Overflow: bottom: 0 abspos in line-clamp before clamp point</title>
+<title>CSS Overflow: abspos whose containing block is the line-clamp container gets painted</title>
<link rel="author" title="Andreu Botella" href="mailto:abotella@igalia.com">
<link rel="help" href="https://drafts.csswg.org/css-overflow-4/#line-clamp">
-<link rel="match" href="reference/line-clamp-with-abspos-008-ref.html">
-<meta name="assert" content="Absolute positioned boxes inside a line-clamp container are not hidden if they are in the box tree before the clamp point.">
+<link rel="match" href="reference/line-clamp-with-abspos-005-ref.html">
+<meta name="assert" content="Absolute positioned boxes in a line-clamp container are hidden if and only if their containing block precedes or contains the clamp point. In this case, the containing block is the line-clamp container, so the abspos gets shown.">
<style>
.clamp {
line-clamp: 4;
- position: relative;
font: 16px / 32px serif;
padding: 0 4px;
white-space: pre;
background-color: yellow;
+ position: relative;
}
.abspos {
position: absolute;
- bottom: 0;
- right: 0;
- width: 50px;
- height: 50px;
- margin: 4px;
+ top: 0;
+ left: 0;
+ width: 20px;
+ height: 20px;
background-color: skyblue;
}
</style>
diff --git a/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-005.tentative.html b/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-005.tentative.html
deleted file mode 100644
index 3dc77831a06..00000000000
--- a/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-005.tentative.html
+++ /dev/null
@@ -1,29 +0,0 @@
-<!DOCTYPE html>
-<meta charset="utf-8">
-<title>CSS Overflow: abspos in line-clamp before clamp point which overflows</title>
-<link rel="author" title="Andreu Botella" href="mailto:abotella@igalia.com">
-<link rel="help" href="https://drafts.csswg.org/css-overflow-4/#line-clamp">
-<link rel="match" href="reference/line-clamp-with-abspos-005-ref.html">
-<meta name="assert" content="Absolute positioned boxes in an inline formatting context inside a line-clamp container are not hidden if they are in the box tree before the clamp point, even if they visually extend beyond that point">
-<style>
-.clamp {
- line-clamp: 4;
- font: 16px / 32px serif;
- padding: 0 4px;
- white-space: pre;
- background-color: yellow;
-}
-.abspos {
- position: absolute;
- right: 0;
- width: 50px;
- height: 50px;
- margin: 4px;
- background-color: skyblue;
-}
-</style>
-<div class="clamp">Line 1
-Line 2
-Line 3
-Line 4<div class="abspos"></div>
-Line 5</div>
diff --git a/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-006.html b/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-006.html
new file mode 100644
index 00000000000..39f1758fa18
--- /dev/null
+++ b/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-006.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Overflow: abspos whose containing block is the line-clamp container gets painted</title>
+<link rel="author" title="Andreu Botella" href="mailto:abotella@igalia.com">
+<link rel="help" href="https://drafts.csswg.org/css-overflow-4/#line-clamp">
+<link rel="match" href="reference/line-clamp-with-abspos-005-ref.html">
+<meta name="assert" content="Absolute positioned boxes in a line-clamp container are hidden if and only if their containing block precedes or contains the clamp point. In this case, the containing block is the line-clamp container, so the abspos gets shown.">
+<style>
+.clamp {
+ line-clamp: 4;
+ font: 16px / 32px serif;
+ padding: 0 4px;
+ background-color: yellow;
+ position: relative;
+}
+.abspos {
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 20px;
+ height: 20px;
+ background-color: skyblue;
+}
+.pre {
+ white-space: pre;
+}
+</style>
+<div class="clamp">
+<div class="abspos"></div>
+<div class="pre">Line 1
+Line 2
+Line 3
+Line 4
+Line 5</div>
+</div>
diff --git a/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-006.tentative.html b/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-006.tentative.html
deleted file mode 100644
index f18fed6c2da..00000000000
--- a/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-006.tentative.html
+++ /dev/null
@@ -1,34 +0,0 @@
-<!DOCTYPE html>
-<meta charset="utf-8">
-<title>CSS Overflow: abspos in line-clamp before clamp point which overflows</title>
-<link rel="author" title="Andreu Botella" href="mailto:abotella@igalia.com">
-<link rel="help" href="https://drafts.csswg.org/css-overflow-4/#line-clamp">
-<link rel="match" href="reference/line-clamp-with-abspos-006-ref.html">
-<meta name="assert" content="Absolute positioned boxes in a block formatting context inside a line-clamp container are not hidden if they are in the box tree before the clamp point, even if they visually extend beyond that point">
-<style>
-.clamp {
- line-clamp: 4;
- font: 16px / 32px serif;
- padding: 0 4px;
- background-color: yellow;
-}
-.abspos {
- position: absolute;
- right: 0;
- width: 50px;
- height: 75px;
- margin: 4px;
- background-color: skyblue;
-}
-.pre {
- white-space: pre;
-}
-</style>
-<div class="clamp">
-<div class="pre">Line 1
-Line 2
-Line 3</div>
-<div class="abspos"></div>
-<div class="pre">Line 4
-Line 5</div>
-</div>
diff --git a/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-007.html b/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-007.html
new file mode 100644
index 00000000000..f5b4e6ce291
--- /dev/null
+++ b/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-007.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Overflow: abspos whose containing block is the line-clamp container gets painted</title>
+<link rel="author" title="Andreu Botella" href="mailto:abotella@igalia.com">
+<link rel="help" href="https://drafts.csswg.org/css-overflow-4/#line-clamp">
+<link rel="match" href="reference/line-clamp-with-abspos-005-ref.html">
+<meta name="assert" content="Absolute positioned boxes in a line-clamp container are hidden if and only if their containing block precedes or contains the clamp point. In this case, the containing block is the line-clamp container, so the abspos gets shown, even if its static position is after the clamp point.">
+<style>
+.clamp {
+ line-clamp: 4;
+ font: 16px / 32px serif;
+ padding: 0 4px;
+ white-space: pre;
+ background-color: yellow;
+ position: relative;
+}
+.abspos {
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 20px;
+ height: 20px;
+ background-color: skyblue;
+}
+</style>
+<div class="clamp">Line 1
+Line 2
+Line 3
+Line 4
+<div class="abspos"></div>Line 5</div>
diff --git a/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-007.tentative.html b/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-007.tentative.html
deleted file mode 100644
index f0a1f58c8d3..00000000000
--- a/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-007.tentative.html
+++ /dev/null
@@ -1,30 +0,0 @@
-<!DOCTYPE html>
-<meta charset="utf-8">
-<title>CSS Overflow: abspos in line-clamp before clamp point positioned after it</title>
-<link rel="author" title="Andreu Botella" href="mailto:abotella@igalia.com">
-<link rel="help" href="https://drafts.csswg.org/css-overflow-4/#line-clamp">
-<link rel="match" href="reference/line-clamp-with-abspos-007-ref.html">
-<meta name="assert" content="Absolute positioned boxes inside a line-clamp container are not hidden if they are in the box tree before the clamp point, even if they are positioned after that point">
-<style>
-.clamp {
- line-clamp: 4;
- font: 16px / 32px serif;
- padding: 0 4px;
- white-space: pre;
- background-color: yellow;
-}
-.abspos {
- position: absolute;
- top: 148px;
- right: 0;
- width: 50px;
- height: 50px;
- margin: 4px;
- background-color: skyblue;
-}
-</style>
-<div class="clamp"><div class="abspos"></div>Line 1
-Line 2
-Line 3
-Line 4
-Line 5</div>
diff --git a/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-008.html b/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-008.html
new file mode 100644
index 00000000000..cd619d51538
--- /dev/null
+++ b/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-008.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Overflow: abspos whose containing block is the line-clamp container gets painted</title>
+<link rel="author" title="Andreu Botella" href="mailto:abotella@igalia.com">
+<link rel="help" href="https://drafts.csswg.org/css-overflow-4/#line-clamp">
+<link rel="match" href="reference/line-clamp-with-abspos-005-ref.html">
+<meta name="assert" content="Absolute positioned boxes in a line-clamp container are hidden if and only if their containing block precedes or contains the clamp point. In this case, the containing block is the line-clamp container, so the abspos gets shown, even if its static position is after the clamp point.">
+<style>
+.clamp {
+ line-clamp: 4;
+ font: 16px / 32px serif;
+ padding: 0 4px;
+ background-color: yellow;
+ position: relative;
+}
+.abspos {
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 20px;
+ height: 20px;
+ background-color: skyblue;
+}
+.pre {
+ white-space: pre;
+}
+</style>
+<div class="clamp">
+<div class="pre">Line 1
+Line 2
+Line 3
+Line 4</div>
+<div class="abspos"></div>
+<div>Line 5</div>
+</div>
diff --git a/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-009.html b/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-009.html
new file mode 100644
index 00000000000..b3d332811d6
--- /dev/null
+++ b/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-009.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Overflow: abspos whose containing block is fully before the clamp point gets painted</title>
+<link rel="author" title="Andreu Botella" href="mailto:abotella@igalia.com">
+<link rel="help" href="https://drafts.csswg.org/css-overflow-4/#line-clamp">
+<link rel="match" href="reference/line-clamp-with-abspos-009-ref.html">
+<meta name="assert" content="Absolute positioned boxes in a line-clamp container are hidden if and only if their containing block precedes or contains the clamp point. In this case, the containing block is fully before the clamp point, so the abspos gets painted.">
+<style>
+.clamp {
+ line-clamp: 4;
+ font: 16px / 32px serif;
+ padding: 0 4px;
+ white-space: pre;
+ background-color: yellow;
+}
+.rel {
+ position: relative;
+}
+.abspos {
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 20px;
+ height: 20px;
+ background-color: skyblue;
+}
+</style>
+<div class="clamp">Line 1
+<div class="rel"><div class="abspos"></div>Line 2
+Line 3</div>Line 4
+Line 5</div>
diff --git a/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-010.html b/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-010.html
new file mode 100644
index 00000000000..8a7c2790d6c
--- /dev/null
+++ b/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-010.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Overflow: abspos whose containing block is fully before the clamp point gets painted</title>
+<link rel="author" title="Andreu Botella" href="mailto:abotella@igalia.com">
+<link rel="help" href="https://drafts.csswg.org/css-overflow-4/#line-clamp">
+<link rel="match" href="reference/line-clamp-with-abspos-009-ref.html">
+<meta name="assert" content="Absolute positioned boxes in a line-clamp container are hidden if and only if their containing block precedes or contains the clamp point. In this case, the containing block is fully before the clamp point, so the abspos gets painted.">
+<style>
+.clamp {
+ line-clamp: 4;
+ font: 16px / 32px serif;
+ padding: 0 4px;
+ background-color: yellow;
+}
+.rel {
+ position: relative;
+}
+.abspos {
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 20px;
+ height: 20px;
+ background-color: skyblue;
+}
+</style>
+<div class="clamp">
+ <div>Line 1</div>
+ <div class="rel">
+ <div class="abspos"></div>
+ <div>Line 2</div>
+ <div>Line 3</div>
+ </div>
+ <div>Line 4</div>
+ <div>Line 5</div>
+</div>
diff --git a/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-009.tentative.html b/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-011.html
index dce04d720cf..cb4ab051480 100644
--- a/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-009.tentative.html
+++ b/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-011.html
@@ -1,26 +1,27 @@
<!DOCTYPE html>
<meta charset="utf-8">
-<title>CSS Overflow: abspos in line-clamp after clamp point positioned before it</title>
+<title>CSS Overflow: abspos whose containing block is fully after the clamp point is hidden</title>
<link rel="author" title="Andreu Botella" href="mailto:abotella@igalia.com">
<link rel="help" href="https://drafts.csswg.org/css-overflow-4/#line-clamp">
<link rel="match" href="reference/webkit-line-clamp-005-ref.html">
-<meta name="assert" content="Absolute positioned boxes inside a line-clamp container are hidden if they are in the box tree after the clamp point, even if they are positioned before that point">
+<meta name="assert" content="Absolute positioned boxes in a line-clamp container are hidden if and only if their containing block precedes or contains the clamp point. In this case, the containing block is fully after the clamp point, so the abspos is hidden.">
<style>
.clamp {
line-clamp: 4;
- position: relative;
font: 16px / 32px serif;
padding: 0 4px;
white-space: pre;
background-color: yellow;
}
+.rel {
+ position: relative;
+}
.abspos {
position: absolute;
top: 0;
- right: 0;
- width: 50px;
- height: 50px;
- margin: 4px;
+ left: 0;
+ width: 20px;
+ height: 20px;
background-color: skyblue;
}
</style>
@@ -28,4 +29,5 @@
Line 2
Line 3
Line 4
-Line 5<div class="abspos"></div></div>
+<div class="rel"><div class="abspos"></div>Line 5
+Line 6</div></div>
diff --git a/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-012.html b/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-012.html
new file mode 100644
index 00000000000..ae2f0364f39
--- /dev/null
+++ b/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-012.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Overflow: abspos whose containing block is fully after the clamp point gets painted</title>
+<link rel="author" title="Andreu Botella" href="mailto:abotella@igalia.com">
+<link rel="help" href="https://drafts.csswg.org/css-overflow-4/#line-clamp">
+<link rel="match" href="reference/webkit-line-clamp-005-ref.html">
+<meta name="assert" content="Absolute positioned boxes in a line-clamp container are hidden if and only if their containing block precedes or contains the clamp point. In this case, the containing block is fully after the clamp point, so the abspos is hidden.">
+<style>
+.clamp {
+ line-clamp: 4;
+ font: 16px / 32px serif;
+ padding: 0 4px;
+ background-color: yellow;
+}
+.rel {
+ position: relative;
+}
+.abspos {
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 20px;
+ height: 20px;
+ background-color: skyblue;
+}
+</style>
+<div class="clamp">
+ <div>Line 1</div>
+ <div>Line 2</div>
+ <div>Line 3</div>
+ <div>Line 4</div>
+ <div class="rel">
+ <div class="abspos"></div>
+ <div>Line 5</div>
+ <div>Line 6</div>
+ </div>
+</div>
diff --git a/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-013.html b/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-013.html
new file mode 100644
index 00000000000..66a615ddd1c
--- /dev/null
+++ b/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-013.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Overflow: abspos whose containing block contains the clamp point gets painted</title>
+<link rel="author" title="Andreu Botella" href="mailto:abotella@igalia.com">
+<link rel="help" href="https://drafts.csswg.org/css-overflow-4/#line-clamp">
+<link rel="match" href="reference/line-clamp-with-abspos-013-ref.html">
+<meta name="assert" content="Absolute positioned boxes in a line-clamp container are hidden if and only if their containing block precedes or contains the clamp point. In this case, the containing block contains the clamp point, so the abspos gets painted, even if its static position is after the clamp point.">
+<style>
+.clamp {
+ line-clamp: 4;
+ font: 16px / 32px serif;
+ padding: 0 4px;
+ white-space: pre;
+ background-color: yellow;
+}
+.rel {
+ position: relative;
+}
+.abspos {
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 20px;
+ height: 20px;
+ background-color: skyblue;
+}
+</style>
+<div class="clamp">Line 1
+Line 2
+Line 3
+<div class="rel">Line 4
+Line 5<div class="abspos"></div></div></div>
diff --git a/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-014.html b/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-014.html
new file mode 100644
index 00000000000..e8257d1d402
--- /dev/null
+++ b/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-014.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Overflow: abspos whose containing block contains the clamp point gets painted</title>
+<link rel="author" title="Andreu Botella" href="mailto:abotella@igalia.com">
+<link rel="help" href="https://drafts.csswg.org/css-overflow-4/#line-clamp">
+<link rel="match" href="reference/line-clamp-with-abspos-013-ref.html">
+<meta name="assert" content="Absolute positioned boxes in a line-clamp container are hidden if and only if their containing block precedes or contains the clamp point. In this case, the containing block contains the clamp point, so the abspos gets painted, even if its static position is after the clamp point.">
+<style>
+.clamp {
+ line-clamp: 4;
+ font: 16px / 32px serif;
+ padding: 0 4px;
+ background-color: yellow;
+}
+.rel {
+ position: relative;
+}
+.abspos {
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 20px;
+ height: 20px;
+ background-color: skyblue;
+}
+</style>
+<div class="clamp">
+ <div>Line 1</div>
+ <div>Line 2</div>
+ <div>Line 3</div>
+ <div class="rel">
+ <div>Line 4</div>
+ <div>Line 5</div>
+ <div class="abspos"></div>
+ </div>
+</div>
diff --git a/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-015.html b/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-015.html
new file mode 100644
index 00000000000..273610e071d
--- /dev/null
+++ b/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-015.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Overflow: abspos whose containing block is an inline fully after the clamp point is hidden</title>
+<link rel="author" title="Andreu Botella" href="mailto:abotella@igalia.com">
+<link rel="help" href="https://drafts.csswg.org/css-overflow-4/#line-clamp">
+<link rel="match" href="reference/webkit-line-clamp-005-ref.html">
+<meta name="assert" content="Absolute positioned boxes in a line-clamp container are hidden if and only if their containing block precedes or contains the clamp point. In this case, the containing block is fully after the clamp point, so the abspos is hidden. This happens even when the containing block is an inline.">
+<style>
+.clamp {
+ line-clamp: 4;
+ font: 16px / 32px serif;
+ padding: 0 4px;
+ white-space: pre;
+ background-color: yellow;
+}
+.rel {
+ position: relative;
+}
+.abspos {
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 20px;
+ height: 20px;
+ background-color: skyblue;
+}
+</style>
+<div class="clamp">Line 1
+Line 2
+Line 3
+Line 4
+<span class="rel"><div class="abspos"></div>Line 5</span></div>
diff --git a/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-016.html b/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-016.html
new file mode 100644
index 00000000000..0b329a7d734
--- /dev/null
+++ b/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-016.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Overflow: abspos whose containing block is an inline that contains the clamp point gets painted</title>
+<link rel="author" title="Andreu Botella" href="mailto:abotella@igalia.com">
+<link rel="help" href="https://drafts.csswg.org/css-overflow-4/#line-clamp">
+<link rel="match" href="reference/line-clamp-with-abspos-016-ref.html">
+<meta name="assert" content="Absolute positioned boxes in a line-clamp container are hidden if and only if their containing block precedes or contains the clamp point. In this case, the containing block contains the clamp point, so the abspos gets painted. This happens even when the containing block is an inline, and even when the static position of the abspos is after the clamp point.">
+<style>
+.clamp {
+ line-clamp: 4;
+ font: 16px / 32px serif;
+ padding: 0 4px;
+ white-space: pre;
+ background-color: yellow;
+}
+.rel {
+ position: relative;
+}
+.abspos {
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 20px;
+ height: 20px;
+ background-color: skyblue;
+}
+</style>
+<div class="clamp">Line 1
+Line 2
+Line 3
+<span class="rel">Line 4
+<div class="abspos"></div>Line 5</span></div>
diff --git a/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-017.tentative.html b/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-017.tentative.html
new file mode 100644
index 00000000000..8ae9cc949c6
--- /dev/null
+++ b/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-017.tentative.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Overflow: abspos whose containing block is an inline that gets displaced by the ellipsis</title>
+<link rel="author" title="Andreu Botella" href="mailto:abotella@igalia.com">
+<link rel="help" href="https://drafts.csswg.org/css-overflow-4/#line-clamp">
+<link rel="match" href="reference/webkit-line-clamp-030-ref.html">
+<meta name="assert" content="Absolute positioned boxes in a line-clamp container are hidden if and only if their containing block precedes or contains the clamp point. In this case, the containing block is an inline whose start gets displaced by the ellipsis. Therefore, it counts as being all after the clamp point, and the abspos is hidden.">
+<style>
+.clamp {
+ line-clamp: 3;
+ background-color: yellow;
+}
+.child {
+ font: 16px / 32px monospace;
+ white-space: pre;
+ width: 7.1ch;
+}
+.rel {
+ position: relative;
+}
+.abspos {
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 20px;
+ height: 20px;
+ background-color: skyblue;
+}
+</style>
+<div class="clamp">
+<div class="child">Line 1
+Line 2
+Line 3 <span class="rel">hidden
+fdgdgjldsfg
+<div class="abspos"></div></span></div>
+</div>
+<p>Following content.</p>
diff --git a/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-010.tentative.html b/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-018.html
index 325278b3a0b..27139b18b8d 100644
--- a/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-010.tentative.html
+++ b/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-018.html
@@ -3,7 +3,7 @@
<title>CSS Overflow: line-clamp doesn't propagate to abspos</title>
<link rel="author" title="Andreu Botella" href="mailto:abotella@igalia.com">
<link rel="help" href="https://drafts.csswg.org/css-overflow-4/#line-clamp">
-<link rel="match" href="reference/line-clamp-with-abspos-010-ref.html">
+<link rel="match" href="reference/line-clamp-with-abspos-018-ref.html">
<meta name="assert" content="Absolute positioned boxes create a new BFC, and line-clamp does not propagate into independent BFCs">
<style>
.clamp {
diff --git a/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-011.tentative.html b/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-019.html
index ab5102a7cf2..237ed69b67d 100644
--- a/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-011.tentative.html
+++ b/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-019.html
@@ -3,7 +3,7 @@
<title>CSS Overflow: line-clamp hidden abspos should count as ink overflow</title>
<link rel="author" title="Andreu Botella" href="mailto:abotella@igalia.com">
<link rel="help" href="https://drafts.csswg.org/css-overflow-4/#line-clamp">
-<link rel="match" href="reference/line-clamp-with-abspos-011-ref.html">
+<link rel="match" href="reference/line-clamp-with-abspos-019-ref.html">
<meta name="assert" content="Any overflowing content hidden from paint by line-clamp is treated as ink overflow, including absolute positioned boxes, and therefore doesn't cause the scrollable overflow rectangle to grow. Meanwhile, non-hidden abspos count as scrollable overflow.">
<style>
#scrollContainer {
@@ -16,7 +16,6 @@
.clamp {
line-clamp: 4;
padding: 0 4px;
- white-space: pre;
background-color: yellow;
}
.abspos {
@@ -27,21 +26,26 @@
margin: 4px;
background-color: skyblue;
}
+.rel {
+ position: relative;
+}
#abspos1 {
- top: 4.5lh;
+ top: 1lh;
}
#abspos2 {
- top: 6lh;
+ top: 2lh;
}
</style>
<div id="scrollContainer">
-<div class="clamp">Line 1
-Line 2
-Line 3
-Line 4<div class="abspos" id="abspos1"></div>
-Line 5
-Line 6<div class="abspos" id="abspos2"></div></div>
+ <div class="clamp">
+ <div>Line 1</div>
+ <div>Line 2</div>
+ <div>Line 3</div>
+ <div class="rel">Line 4<div class="abspos" id="abspos1"></div></div>
+ <div>Line 5</div>
+ <div class="rel">Line 6<div class="abspos" id="abspos2"></div></div>
+ </div>
</div>
<script>
diff --git a/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-012.tentative.html b/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-020.html
index bed065f3838..55fb07c2061 100644
--- a/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-012.tentative.html
+++ b/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-020.html
@@ -4,7 +4,7 @@
<link rel="author" title="Andreu Botella" href="mailto:abotella@igalia.com">
<link rel="help" href="https://drafts.csswg.org/css-overflow-4/#line-clamp">
<link rel="match" href="reference/webkit-line-clamp-005-ref.html">
-<meta name="assert" content="Block-level abspos should still be hidden if it is after the clamp point with line-clamp: auto">
+<meta name="assert" content="Block-level abspos should be hidden if its containing block is after the clamp point with line-clamp: auto">
<style>
.clamp {
line-clamp: auto;
@@ -13,8 +13,8 @@
padding: 0 4px;
background-color: yellow;
}
-.inner {
- white-space: pre;
+.rel {
+ position: relative;
}
.abspos {
position: absolute;
@@ -25,11 +25,13 @@
</style>
<div class="clamp">
-<div class="inner">Line 1
-Line 2
-Line 3
-Line 4
-Line 5</div>
-<div class="inner">Line 6</div>
-<div class="abspos"></div>
+ <div>Line 1</div>
+ <div>Line 2</div>
+ <div>Line 3</div>
+ <div>Line 4</div>
+ <div>Line 5</div>
+ <div class="rel">
+ <div>Line 6</div>
+ <div class="abspos"></div>
+ </div>
</div>
diff --git a/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-013.tentative.html b/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-021.html
index ccea125f724..21a0e96eee3 100644
--- a/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-013.tentative.html
+++ b/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-021.html
@@ -4,7 +4,7 @@
<link rel="author" title="Andreu Botella" href="mailto:abotella@igalia.com">
<link rel="help" href="https://drafts.csswg.org/css-overflow-4/#line-clamp">
<link rel="match" href="reference/webkit-line-clamp-005-ref.html">
-<meta name="assert" content="Block-level abspos should still be hidden if it is after the clamp point with line-clamp: auto, even if it lies on the boundary because the automatic size of previous boxes was adjusted.">
+<meta name="assert" content="Block-level abspos should still be hidden if its containing block is after the clamp point with line-clamp: auto, even if it lies on the boundary because the automatic size of previous boxes was adjusted.">
<style>
.clamp {
line-clamp: auto;
@@ -16,6 +16,9 @@
.inner {
white-space: pre;
}
+.rel {
+ position: relative;
+}
.abspos {
position: absolute;
width: 100px;
@@ -30,7 +33,6 @@ Line 2
Line 3
Line 4
Line 5
-Line 6
-</div>
-<div class="abspos"></div>
+Line 6</div>
+<div class="rel"><div class="abspos"></div></div>
</div>
diff --git a/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-014.tentative.html b/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-022.html
index ea2f5312070..6599365883b 100644
--- a/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-014.tentative.html
+++ b/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-abspos-022.html
@@ -4,7 +4,7 @@
<link rel="author" title="Andreu Botella" href="mailto:abotella@igalia.com">
<link rel="help" href="https://drafts.csswg.org/css-overflow-4/#line-clamp">
<link rel="match" href="reference/webkit-line-clamp-005-ref.html">
-<meta name="assert" content="Absolute positioned boxes in an inline formatting context inside a line-clamp container are always hidden if they are in the box tree after the clamp point. This test specifically tests that this is the case even when they don't have a set height.">
+<meta name="assert" content="Absolute positioned boxes inside a line-clamp container are always hidden if their containing block is after the clamp point. This test specifically tests that this is the case even when they don't have a set height.">
<style>
.clamp {
line-clamp: 4;
@@ -13,6 +13,9 @@
white-space: pre;
background-color: yellow;
}
+.rel {
+ position: relative;
+}
.abspos {
position: absolute;
right: 0;
@@ -27,4 +30,4 @@
Line 2
Line 3
Line 4
-<div class="abspos">This abspos shouldn't be visible</div>Line 5</div>
+<div class="rel"><div class="abspos">This abspos shouldn't be visible</div>Line 5</div></div>
diff --git a/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-001.html b/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-001.html
new file mode 100644
index 00000000000..7f69c970baa
--- /dev/null
+++ b/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-001.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Overflow: fixed pos whose containing block is outside the line-clamp container gets painted</title>
+<link rel="author" title="Andreu Botella" href="mailto:abotella@igalia.com">
+<link rel="help" href="https://drafts.csswg.org/css-overflow-4/#line-clamp">
+<link rel="match" href="reference/line-clamp-with-abspos-001-ref.html">
+<meta name="assert" content="Fixed positioned boxes in a line-clamp container are hidden if and only if their fixed positioning containing block precedes or contains the clamp point. In this case, the containing block is the layout viewport, so the fixed-pos gets shown.">
+<style>
+.clamp {
+ line-clamp: 4;
+ font: 16px / 32px serif;
+ padding: 0 4px;
+ white-space: pre;
+ background-color: yellow;
+}
+.fixed {
+ position: fixed;
+ top: 0;
+ left: 0;
+ width: 20px;
+ height: 20px;
+ background-color: skyblue;
+}
+</style>
+<div class="clamp"><div class="fixed"></div>Line 1
+Line 2
+Line 3
+Line 4
+Line 5</div>
diff --git a/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-002.html b/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-002.html
new file mode 100644
index 00000000000..90eecbd6af6
--- /dev/null
+++ b/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-002.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Overflow: fixed pos whose containing block is outside the line-clamp container gets painted</title>
+<link rel="author" title="Andreu Botella" href="mailto:abotella@igalia.com">
+<link rel="help" href="https://drafts.csswg.org/css-overflow-4/#line-clamp">
+<link rel="match" href="reference/line-clamp-with-abspos-001-ref.html">
+<meta name="assert" content="Fixed positioned boxes in a line-clamp container are hidden if and only if their fixed positioning containing block precedes or contains the clamp point. In this case, the containing block is the layout viewport, so the fixed-pos gets shown.">
+<style>
+.clamp {
+ line-clamp: 4;
+ font: 16px / 32px serif;
+ padding: 0 4px;
+ background-color: yellow;
+}
+.fixed {
+ position: fixed;
+ top: 0;
+ left: 0;
+ width: 20px;
+ height: 20px;
+ background-color: skyblue;
+}
+.pre {
+ white-space: pre;
+}
+</style>
+<div class="clamp">
+<div class="fixed"></div>
+<div class="pre">Line 1
+Line 2
+Line 3
+Line 4
+Line 5</div>
+</div>
diff --git a/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-003.html b/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-003.html
new file mode 100644
index 00000000000..c4bc8a64784
--- /dev/null
+++ b/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-003.html
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Overflow: fixed pos whose containing block is outside the line-clamp container gets painted</title>
+<link rel="author" title="Andreu Botella" href="mailto:abotella@igalia.com">
+<link rel="help" href="https://drafts.csswg.org/css-overflow-4/#line-clamp">
+<link rel="match" href="reference/line-clamp-with-abspos-001-ref.html">
+<meta name="assert" content="Fixed positioned boxes in a line-clamp container are hidden if and only if their fixed positioning containing block precedes or contains the clamp point. In this case, the containing block is the layout viewport, so the fixed-pos gets shown, even if its static position is after the clamp point.">
+<style>
+.clamp {
+ line-clamp: 4;
+ font: 16px / 32px serif;
+ padding: 0 4px;
+ white-space: pre;
+ background-color: yellow;
+}
+.fixed {
+ position: fixed;
+ top: 0;
+ left: 0;
+ width: 20px;
+ height: 20px;
+ background-color: skyblue;
+}
+</style>
+<div class="clamp">Line 1
+Line 2
+Line 3
+Line 4
+<div class="fixed"></div>Line 5</div>
diff --git a/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-004.html b/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-004.html
new file mode 100644
index 00000000000..673b7d8c9d8
--- /dev/null
+++ b/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-004.html
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Overflow: fixed pos whose containing block is outside the line-clamp container gets painted</title>
+<link rel="author" title="Andreu Botella" href="mailto:abotella@igalia.com">
+<link rel="help" href="https://drafts.csswg.org/css-overflow-4/#line-clamp">
+<link rel="match" href="reference/line-clamp-with-abspos-001-ref.html">
+<meta name="assert" content="Fixed positioned boxes in a line-clamp container are hidden if and only if their fixed positioning containing block precedes or contains the clamp point. In this case, the containing block is the layout viewport, so the fixed-pos gets shown, even if its static position is after the clamp point.">
+<style>
+.clamp {
+ line-clamp: 4;
+ font: 16px / 32px serif;
+ padding: 0 4px;
+ background-color: yellow;
+}
+.fixed {
+ position: fixed;
+ top: 0;
+ left: 0;
+ width: 20px;
+ height: 20px;
+ background-color: skyblue;
+}
+.pre {
+ white-space: pre;
+}
+</style>
+<div class="clamp">
+<div class="pre">Line 1
+Line 2
+Line 3
+Line 4</div>
+<div class="fixed"></div>
+<div>Line 5</div>
+</div>
diff --git a/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-005.html b/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-005.html
new file mode 100644
index 00000000000..22cf7e0c132
--- /dev/null
+++ b/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-005.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Overflow: fixed pos whose containing block is the line-clamp container gets painted</title>
+<link rel="author" title="Andreu Botella" href="mailto:abotella@igalia.com">
+<link rel="help" href="https://drafts.csswg.org/css-overflow-4/#line-clamp">
+<link rel="match" href="reference/line-clamp-with-abspos-005-ref.html">
+<meta name="assert" content="Fixed positioned boxes in a line-clamp container are hidden if and only if their fixed positioning containing block precedes or contains the clamp point. In this case, the containing block is the line-clamp container, so the fixed-pos gets shown.">
+<style>
+.clamp {
+ line-clamp: 4;
+ font: 16px / 32px serif;
+ padding: 0 4px;
+ white-space: pre;
+ background-color: yellow;
+ transform: scale(1); /* Makes it a fixed-pos containing block */
+}
+.fixed {
+ position: fixed;
+ top: 0;
+ left: 0;
+ width: 20px;
+ height: 20px;
+ background-color: skyblue;
+}
+</style>
+<div class="clamp"><div class="fixed"></div>Line 1
+Line 2
+Line 3
+Line 4
+Line 5</div>
diff --git a/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-006.html b/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-006.html
new file mode 100644
index 00000000000..46f2e0b2b39
--- /dev/null
+++ b/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-006.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Overflow: fixed pos whose containing block is the line-clamp container gets painted</title>
+<link rel="author" title="Andreu Botella" href="mailto:abotella@igalia.com">
+<link rel="help" href="https://drafts.csswg.org/css-overflow-4/#line-clamp">
+<link rel="match" href="reference/line-clamp-with-abspos-005-ref.html">
+<meta name="assert" content="Fixed positioned boxes in a line-clamp container are hidden if and only if their fixed positioning containing block precedes or contains the clamp point. In this case, the containing block is the line-clamp container, so the fixed-pos gets shown.">
+<style>
+.clamp {
+ line-clamp: 4;
+ font: 16px / 32px serif;
+ padding: 0 4px;
+ background-color: yellow;
+ transform: scale(1); /* Makes it a fixed-pos containing block */
+}
+.fixed {
+ position: fixed;
+ top: 0;
+ left: 0;
+ width: 20px;
+ height: 20px;
+ background-color: skyblue;
+}
+.pre {
+ white-space: pre;
+}
+</style>
+<div class="clamp">
+<div class="fixed"></div>
+<div class="pre">Line 1
+Line 2
+Line 3
+Line 4
+Line 5</div>
+</div>
diff --git a/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-007.html b/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-007.html
new file mode 100644
index 00000000000..0197ecb6d4a
--- /dev/null
+++ b/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-007.html
@@ -0,0 +1,30 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Overflow: fixed pos whose containing block is the line-clamp container gets painted</title>
+<link rel="author" title="Andreu Botella" href="mailto:abotella@igalia.com">
+<link rel="help" href="https://drafts.csswg.org/css-overflow-4/#line-clamp">
+<link rel="match" href="reference/line-clamp-with-abspos-005-ref.html">
+<meta name="assert" content="Fixed positioned boxes in a line-clamp container are hidden if and only if their fixed positioning containing block precedes or contains the clamp point. In this case, the containing block is the line-clamp container, so the fixed-pos gets shown, even if its static position is after the clamp point.">
+<style>
+.clamp {
+ line-clamp: 4;
+ font: 16px / 32px serif;
+ padding: 0 4px;
+ white-space: pre;
+ background-color: yellow;
+ transform: scale(1); /* Makes it a fixed-pos containing block */
+}
+.fixed {
+ position: fixed;
+ top: 0;
+ left: 0;
+ width: 20px;
+ height: 20px;
+ background-color: skyblue;
+}
+</style>
+<div class="clamp">Line 1
+Line 2
+Line 3
+Line 4
+<div class="fixed"></div>Line 5</div>
diff --git a/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-008.html b/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-008.html
new file mode 100644
index 00000000000..b14856a417f
--- /dev/null
+++ b/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-008.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Overflow: fixed pos whose containing block is the line-clamp container gets painted</title>
+<link rel="author" title="Andreu Botella" href="mailto:abotella@igalia.com">
+<link rel="help" href="https://drafts.csswg.org/css-overflow-4/#line-clamp">
+<link rel="match" href="reference/line-clamp-with-abspos-005-ref.html">
+<meta name="assert" content="Fixed positioned boxes in a line-clamp container are hidden if and only if their fixed positioning containing block precedes or contains the clamp point. In this case, the containing block is the line-clamp container, so the fixed-pos gets shown, even if its static position is after the clamp point.">
+<style>
+.clamp {
+ line-clamp: 4;
+ font: 16px / 32px serif;
+ padding: 0 4px;
+ background-color: yellow;
+ transform: scale(1); /* Makes it a fixed-pos containing block */
+}
+.fixed {
+ position: fixed;
+ top: 0;
+ left: 0;
+ width: 20px;
+ height: 20px;
+ background-color: skyblue;
+}
+.pre {
+ white-space: pre;
+}
+</style>
+<div class="clamp">
+<div class="pre">Line 1
+Line 2
+Line 3
+Line 4</div>
+<div class="fixed"></div>
+<div>Line 5</div>
+</div>
diff --git a/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-009.html b/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-009.html
new file mode 100644
index 00000000000..93faeed3bb1
--- /dev/null
+++ b/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-009.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Overflow: fixed pos whose containing block is fully before the clamp point gets painted</title>
+<link rel="author" title="Andreu Botella" href="mailto:abotella@igalia.com">
+<link rel="help" href="https://drafts.csswg.org/css-overflow-4/#line-clamp">
+<link rel="match" href="reference/line-clamp-with-abspos-009-ref.html">
+<meta name="assert" content="Fixed positioned boxes in a line-clamp container are hidden if and only if their fixed positioning containing block precedes or contains the clamp point. In this case, the containing block is fully before the clamp point, so the fixed-pos gets painted.">
+<style>
+.clamp {
+ line-clamp: 4;
+ font: 16px / 32px serif;
+ padding: 0 4px;
+ white-space: pre;
+ background-color: yellow;
+}
+.transformed {
+ transform: scale(1); /* Makes it a fixed-pos containing block */
+}
+.fixed {
+ position: fixed;
+ top: 0;
+ left: 0;
+ width: 20px;
+ height: 20px;
+ background-color: skyblue;
+}
+</style>
+<div class="clamp">Line 1
+<div class="transformed"><div class="fixed"></div>Line 2
+Line 3</div>Line 4
+Line 5</div>
diff --git a/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-010.html b/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-010.html
new file mode 100644
index 00000000000..8bd64fee615
--- /dev/null
+++ b/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-010.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Overflow: fixed pos whose containing block is fully before the clamp point gets painted</title>
+<link rel="author" title="Andreu Botella" href="mailto:abotella@igalia.com">
+<link rel="help" href="https://drafts.csswg.org/css-overflow-4/#line-clamp">
+<link rel="match" href="reference/line-clamp-with-abspos-009-ref.html">
+<meta name="assert" content="Fixed positioned boxes in a line-clamp container are hidden if and only if their fixed positioning containing block precedes or contains the clamp point. In this case, the containing block is fully before the clamp point, so the fixed-pos gets painted.">
+<style>
+.clamp {
+ line-clamp: 4;
+ font: 16px / 32px serif;
+ padding: 0 4px;
+ background-color: yellow;
+}
+.transformed {
+ transform: scale(1); /* Makes it a fixed-pos containing block */
+}
+.fixed {
+ position: fixed;
+ top: 0;
+ left: 0;
+ width: 20px;
+ height: 20px;
+ background-color: skyblue;
+}
+</style>
+<div class="clamp">
+ <div>Line 1</div>
+ <div class="transformed">
+ <div class="fixed"></div>
+ <div>Line 2</div>
+ <div>Line 3</div>
+ </div>
+ <div>Line 4</div>
+ <div>Line 5</div>
+</div>
diff --git a/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-011.html b/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-011.html
new file mode 100644
index 00000000000..70273b36cda
--- /dev/null
+++ b/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-011.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Overflow: fixed pos whose containing block is fully after the clamp point is hidden</title>
+<link rel="author" title="Andreu Botella" href="mailto:abotella@igalia.com">
+<link rel="help" href="https://drafts.csswg.org/css-overflow-4/#line-clamp">
+<link rel="match" href="reference/webkit-line-clamp-005-ref.html">
+<meta name="assert" content="Fixed positioned boxes in a line-clamp container are hidden if and only if their fixed positioning containing block precedes or contains the clamp point. In this case, the containing block is fully after the clamp point, so the fixed-pos is hidden.">
+<style>
+.clamp {
+ line-clamp: 4;
+ font: 16px / 32px serif;
+ padding: 0 4px;
+ white-space: pre;
+ background-color: yellow;
+}
+.transformed {
+ transform: scale(1); /* Makes it a fixed-pos containing block */
+}
+.fixed {
+ position: fixed;
+ top: 0;
+ left: 0;
+ width: 20px;
+ height: 20px;
+ background-color: skyblue;
+}
+</style>
+<div class="clamp">Line 1
+Line 2
+Line 3
+Line 4
+<div class="transformed"><div class="fixed"></div>Line 5
+Line 6</div></div>
diff --git a/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-012.html b/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-012.html
new file mode 100644
index 00000000000..0e5584db10b
--- /dev/null
+++ b/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-012.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Overflow: fixed pos whose containing block is fully after the clamp point gets painted</title>
+<link rel="author" title="Andreu Botella" href="mailto:abotella@igalia.com">
+<link rel="help" href="https://drafts.csswg.org/css-overflow-4/#line-clamp">
+<link rel="match" href="reference/webkit-line-clamp-005-ref.html">
+<meta name="assert" content="Fixed positioned boxes in a line-clamp container are hidden if and only if their fixed positioning containing block precedes or contains the clamp point. In this case, the containing block is fully after the clamp point, so the fixed-pos is hidden.">
+<style>
+.clamp {
+ line-clamp: 4;
+ font: 16px / 32px serif;
+ padding: 0 4px;
+ background-color: yellow;
+}
+.transformed {
+ transform: scale(1); /* Makes it a fixed-pos containing block */
+}
+.fixed {
+ position: fixed;
+ top: 0;
+ left: 0;
+ width: 20px;
+ height: 20px;
+ background-color: skyblue;
+}
+</style>
+<div class="clamp">
+ <div>Line 1</div>
+ <div>Line 2</div>
+ <div>Line 3</div>
+ <div>Line 4</div>
+ <div class="transformed">
+ <div class="fixed"></div>
+ <div>Line 5</div>
+ <div>Line 6</div>
+ </div>
+</div>
diff --git a/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-013.html b/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-013.html
new file mode 100644
index 00000000000..580619be41e
--- /dev/null
+++ b/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-013.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Overflow: fixed pos whose containing block contains the clamp point gets painted</title>
+<link rel="author" title="Andreu Botella" href="mailto:abotella@igalia.com">
+<link rel="help" href="https://drafts.csswg.org/css-overflow-4/#line-clamp">
+<link rel="match" href="reference/line-clamp-with-abspos-013-ref.html">
+<meta name="assert" content="Fixed positioned boxes in a line-clamp container are hidden if and only if their fixed positioning containing block precedes or contains the clamp point. In this case, the containing block contains the clamp point, so the fixed-pos gets painted, even if its static position is after the clamp point.">
+<style>
+.clamp {
+ line-clamp: 4;
+ font: 16px / 32px serif;
+ padding: 0 4px;
+ white-space: pre;
+ background-color: yellow;
+}
+.transformed {
+ transform: scale(1); /* Makes it a fixed-pos containing block */
+}
+.fixed {
+ position: fixed;
+ top: 0;
+ left: 0;
+ width: 20px;
+ height: 20px;
+ background-color: skyblue;
+}
+</style>
+<div class="clamp">Line 1
+Line 2
+Line 3
+<div class="transformed">Line 4
+Line 5<div class="fixed"></div></div></div>
diff --git a/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-014.html b/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-014.html
new file mode 100644
index 00000000000..371fb595702
--- /dev/null
+++ b/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-014.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Overflow: fixed pos whose containing block contains the clamp point gets painted</title>
+<link rel="author" title="Andreu Botella" href="mailto:abotella@igalia.com">
+<link rel="help" href="https://drafts.csswg.org/css-overflow-4/#line-clamp">
+<link rel="match" href="reference/line-clamp-with-abspos-013-ref.html">
+<meta name="assert" content="Fixed positioned boxes in a line-clamp container are hidden if and only if their fixed positioning containing block precedes or contains the clamp point. In this case, the containing block contains the clamp point, so the fixed-pos gets painted, even if its static position is after the clamp point.">
+<style>
+.clamp {
+ line-clamp: 4;
+ font: 16px / 32px serif;
+ padding: 0 4px;
+ background-color: yellow;
+}
+.transformed {
+ transform: scale(1); /* Makes it a fixed-pos containing block */
+}
+.fixed {
+ position: fixed;
+ top: 0;
+ left: 0;
+ width: 20px;
+ height: 20px;
+ background-color: skyblue;
+}
+</style>
+<div class="clamp">
+ <div>Line 1</div>
+ <div>Line 2</div>
+ <div>Line 3</div>
+ <div class="transformed">
+ <div>Line 4</div>
+ <div>Line 5</div>
+ <div class="fixed"></div>
+ </div>
+</div>
diff --git a/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-015.html b/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-015.html
new file mode 100644
index 00000000000..a458c11c04e
--- /dev/null
+++ b/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-015.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Overflow: line-clamp: auto hidden block-level fixed pos</title>
+<link rel="author" title="Andreu Botella" href="mailto:abotella@igalia.com">
+<link rel="help" href="https://drafts.csswg.org/css-overflow-4/#line-clamp">
+<link rel="match" href="reference/webkit-line-clamp-005-ref.html">
+<meta name="assert" content="Block-level fixed-pos should be hidden if its fixed positioning containing block is after the clamp point with line-clamp: auto">
+<style>
+.clamp {
+ line-clamp: auto;
+ max-height: 4lh;
+ font: 16px / 32px serif;
+ padding: 0 4px;
+ background-color: yellow;
+}
+.transformed {
+ transform: scale(1); /* Makes it a fixed-pos containing block */
+}
+.fixed {
+ position: fixed;
+ width: 100px;
+ height: 100px;
+ background-color: skyblue;
+}
+</style>
+
+<div class="clamp">
+ <div>Line 1</div>
+ <div>Line 2</div>
+ <div>Line 3</div>
+ <div>Line 4</div>
+ <div>Line 5</div>
+ <div class="transformed">
+ <div>Line 6</div>
+ <div class="fixed"></div>
+ </div>
+</div>
diff --git a/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-auto-025.tentative.html b/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-016.html
index ab741d3df4d..07a6f4e4f0d 100644
--- a/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-auto-025.tentative.html
+++ b/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-016.html
@@ -1,10 +1,10 @@
<!DOCTYPE html>
<meta charset="utf-8">
-<title>CSS Overflow: abspos exactly at the clamp point is hidden</title>
+<title>CSS Overflow: line-clamp: auto hidden block-level fixed pos</title>
<link rel="author" title="Andreu Botella" href="mailto:abotella@igalia.com">
<link rel="help" href="https://drafts.csswg.org/css-overflow-4/#line-clamp">
<link rel="match" href="reference/webkit-line-clamp-005-ref.html">
-<meta name="assert" content="The chosen clamp point with line-clamp: auto is at the last line where the box size doesn't overflow. An immediately following box, even if it's an abspos that takes up no block size, should still be hidden.">
+<meta name="assert" content="Block-level fixed-pos should still be hidden if its fixed positioning containing block is after the clamp point with line-clamp: auto, even if it lies on the boundary because the automatic size of previous boxes was adjusted.">
<style>
.clamp {
line-clamp: auto;
@@ -14,10 +14,13 @@
background-color: yellow;
}
.inner {
- white-space: pre-wrap;
+ white-space: pre;
}
-.abspos {
- position: absolute;
+.transformed {
+ transform: scale(1); /* Makes it a fixed-pos containing block */
+}
+.fixed {
+ position: fixed;
width: 100px;
height: 100px;
background-color: skyblue;
@@ -29,8 +32,7 @@
Line 2
Line 3
Line 4
-</div>
-<div class="abspos"></div>
-<div class="inner">Line 5
+Line 5
Line 6</div>
+<div class="transformed"><div class="fixed"></div></div>
</div>
diff --git a/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-017.html b/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-017.html
new file mode 100644
index 00000000000..97c77429ee4
--- /dev/null
+++ b/tests/wpt/tests/css/css-overflow/line-clamp/line-clamp-with-fixed-pos-017.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<title>CSS Overflow: fixed pos in line-clamp after clamp point</title>
+<link rel="author" title="Andreu Botella" href="mailto:abotella@igalia.com">
+<link rel="help" href="https://drafts.csswg.org/css-overflow-4/#line-clamp">
+<link rel="match" href="reference/webkit-line-clamp-005-ref.html">
+<meta name="assert" content="Fixed positioned boxes inside a line-clamp container are always hidden if their fixed positioning containing block is after the clamp point. This test specifically tests that this is the case even when they don't have a set height.">
+<style>
+.clamp {
+ line-clamp: 4;
+ font: 16px / 32px serif;
+ padding: 0 4px;
+ white-space: pre;
+ background-color: yellow;
+}
+.transformed {
+ transform: scale(1); /* Makes it a fixed-pos containing block */
+}
+.fixed {
+ position: fixed;
+ right: 0;
+ width: 100px;
+ /* No height! */
+ margin: 4px;
+ white-space: normal;
+ background-color: red;
+}
+</style>
+<div class="clamp">Line 1
+Line 2
+Line 3
+Line 4
+<div class="transformed"><div class="fixed">This fixed pos shouldn't be visible</div>Line 5</div></div>
diff --git a/tests/wpt/tests/css/css-overflow/line-clamp/reference/line-clamp-with-abspos-001-ref.html b/tests/wpt/tests/css/css-overflow/line-clamp/reference/line-clamp-with-abspos-001-ref.html
index d756162dde0..ffa463369c1 100644
--- a/tests/wpt/tests/css/css-overflow/line-clamp/reference/line-clamp-with-abspos-001-ref.html
+++ b/tests/wpt/tests/css/css-overflow/line-clamp/reference/line-clamp-with-abspos-001-ref.html
@@ -10,10 +10,10 @@
}
.abspos {
position: absolute;
- right: 0;
- width: 50px;
- height: 50px;
- margin: 4px;
+ top: 0;
+ left: 0;
+ width: 20px;
+ height: 20px;
background-color: skyblue;
}
</style>
diff --git a/tests/wpt/tests/css/css-overflow/line-clamp/reference/line-clamp-with-abspos-005-ref.html b/tests/wpt/tests/css/css-overflow/line-clamp/reference/line-clamp-with-abspos-005-ref.html
index 3b1f9218e88..9825838e7b4 100644
--- a/tests/wpt/tests/css/css-overflow/line-clamp/reference/line-clamp-with-abspos-005-ref.html
+++ b/tests/wpt/tests/css/css-overflow/line-clamp/reference/line-clamp-with-abspos-005-ref.html
@@ -7,17 +7,18 @@
padding: 0 4px;
white-space: pre;
background-color: yellow;
+ position: relative;
}
.abspos {
position: absolute;
- right: 0;
- width: 50px;
- height: 50px;
- margin: 4px;
+ top: 0;
+ left: 0;
+ width: 20px;
+ height: 20px;
background-color: skyblue;
}
</style>
-<div class="clamp">Line 1
+<div class="clamp"><div class="abspos"></div>Line 1
Line 2
Line 3
-Line 4…<div class="abspos"></div></div>
+Line 4…</div>
diff --git a/tests/wpt/tests/css/css-overflow/line-clamp/reference/line-clamp-with-abspos-006-ref.html b/tests/wpt/tests/css/css-overflow/line-clamp/reference/line-clamp-with-abspos-009-ref.html
index 4b55c37a033..cc3a43df238 100644
--- a/tests/wpt/tests/css/css-overflow/line-clamp/reference/line-clamp-with-abspos-006-ref.html
+++ b/tests/wpt/tests/css/css-overflow/line-clamp/reference/line-clamp-with-abspos-009-ref.html
@@ -5,24 +5,21 @@
.clamp {
font: 16px / 32px serif;
padding: 0 4px;
+ white-space: pre;
background-color: yellow;
}
+.rel {
+ position: relative;
+}
.abspos {
position: absolute;
- right: 0;
- width: 50px;
- height: 75px;
- margin: 4px;
+ top: 0;
+ left: 0;
+ width: 20px;
+ height: 20px;
background-color: skyblue;
}
-.pre {
- white-space: pre;
-}
</style>
-<div class="clamp">
-<div class="pre">Line 1
-Line 2
-Line 3</div>
-<div class="abspos"></div>
-<div class="pre">Line 4…</div>
-</div>
+<div class="clamp">Line 1
+<div class="rel"><div class="abspos"></div>Line 2
+Line 3</div>Line 4…</div>
diff --git a/tests/wpt/tests/css/css-overflow/line-clamp/reference/line-clamp-with-abspos-008-ref.html b/tests/wpt/tests/css/css-overflow/line-clamp/reference/line-clamp-with-abspos-013-ref.html
index 373b2755c1d..cae83ecc37c 100644
--- a/tests/wpt/tests/css/css-overflow/line-clamp/reference/line-clamp-with-abspos-008-ref.html
+++ b/tests/wpt/tests/css/css-overflow/line-clamp/reference/line-clamp-with-abspos-013-ref.html
@@ -3,23 +3,24 @@
<title>CSS Reference</title>
<style>
.clamp {
- position: relative;
font: 16px / 32px serif;
padding: 0 4px;
white-space: pre;
background-color: yellow;
}
+.rel {
+ position: relative;
+}
.abspos {
position: absolute;
- bottom: 0;
- right: 0;
- width: 50px;
- height: 50px;
- margin: 4px;
+ top: 0;
+ left: 0;
+ width: 20px;
+ height: 20px;
background-color: skyblue;
}
</style>
-<div class="clamp"><div class="abspos"></div>Line 1
+<div class="clamp">Line 1
Line 2
Line 3
-Line 4…</div>
+<div class="rel"><div class="abspos"></div>Line 4…</div></div>
diff --git a/tests/wpt/tests/css/css-overflow/line-clamp/reference/line-clamp-with-abspos-007-ref.html b/tests/wpt/tests/css/css-overflow/line-clamp/reference/line-clamp-with-abspos-016-ref.html
index e3dcc696e39..3c8011394d2 100644
--- a/tests/wpt/tests/css/css-overflow/line-clamp/reference/line-clamp-with-abspos-007-ref.html
+++ b/tests/wpt/tests/css/css-overflow/line-clamp/reference/line-clamp-with-abspos-016-ref.html
@@ -8,17 +8,19 @@
white-space: pre;
background-color: yellow;
}
+.rel {
+ position: relative;
+}
.abspos {
position: absolute;
- top: 148px;
- right: 0;
- width: 50px;
- height: 50px;
- margin: 4px;
+ top: 0;
+ left: 0;
+ width: 20px;
+ height: 20px;
background-color: skyblue;
}
</style>
-<div class="clamp"><div class="abspos"></div>Line 1
+<div class="clamp">Line 1
Line 2
Line 3
-Line 4…</div>
+<span class="rel"><div class="abspos"></div>Line 4…</span></div>
diff --git a/tests/wpt/tests/css/css-overflow/line-clamp/reference/line-clamp-with-abspos-010-ref.html b/tests/wpt/tests/css/css-overflow/line-clamp/reference/line-clamp-with-abspos-018-ref.html
index ecc2fcee1b5..ecc2fcee1b5 100644
--- a/tests/wpt/tests/css/css-overflow/line-clamp/reference/line-clamp-with-abspos-010-ref.html
+++ b/tests/wpt/tests/css/css-overflow/line-clamp/reference/line-clamp-with-abspos-018-ref.html
diff --git a/tests/wpt/tests/css/css-overflow/line-clamp/reference/line-clamp-with-abspos-011-ref.html b/tests/wpt/tests/css/css-overflow/line-clamp/reference/line-clamp-with-abspos-019-ref.html
index f08b0270e8d..f97a9725325 100644
--- a/tests/wpt/tests/css/css-overflow/line-clamp/reference/line-clamp-with-abspos-011-ref.html
+++ b/tests/wpt/tests/css/css-overflow/line-clamp/reference/line-clamp-with-abspos-019-ref.html
@@ -11,25 +11,30 @@
}
.clamp {
padding: 0 4px;
- white-space: pre;
background-color: yellow;
}
.abspos {
position: absolute;
- top: 4.5lh;
+ top: 1lh;
right: 0;
width: 50px;
height: 50px;
margin: 4px;
background-color: skyblue;
}
+.rel {
+ position: relative;
+}
</style>
<div id="scrollContainer">
-<div class="clamp">Line 1
-Line 2
-Line 3
-Line 4…<div class="abspos"></div></div>
+ <div class="clamp">
+ <div>Line 1</div>
+ <div>Line 2</div>
+ <div>Line 3</div>
+ <div class="rel">Line 4…<div class="abspos"></div></div>
+ </div>
+</div>
<script>
window.addEventListener("load", () => {
diff --git a/tests/wpt/tests/css/css-overflow/line-clamp/webkit-line-clamp-abspos-001.tentative.html b/tests/wpt/tests/css/css-overflow/line-clamp/webkit-line-clamp-abspos-001.html
index fb8e027740d..fb8e027740d 100644
--- a/tests/wpt/tests/css/css-overflow/line-clamp/webkit-line-clamp-abspos-001.tentative.html
+++ b/tests/wpt/tests/css/css-overflow/line-clamp/webkit-line-clamp-abspos-001.html
diff --git a/tests/wpt/tests/css/css-overflow/scroll-marker-active-unreached-target.html b/tests/wpt/tests/css/css-overflow/scroll-marker-active-unreached-target.html
new file mode 100644
index 00000000000..6a6bcc2891f
--- /dev/null
+++ b/tests/wpt/tests/css/css-overflow/scroll-marker-active-unreached-target.html
@@ -0,0 +1,113 @@
+<!DOCTYPE html>
+<html>
+
+<head>
+ <meta charset="utf-8">
+ <title>CSS Test: test that the scroll-marker of a target whose target position
+ has not been reached only gets selected when it is within half a scroll
+ port's distance from the current scroll offset</title>
+ <link rel="help" href="https://drafts.csswg.org/css-overflow-5/#example-d2ca6884">
+ <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="support/scroll-marker-support.js"></script>
+ <script src="/dom/events/scrolling/scroll_support.js"></script>
+</head>
+
+<body>
+ <style>
+ .wrapper {
+ display: grid;
+ justify-content: center;
+ position: relative;
+ }
+
+ .carousel {
+ width: 600px;
+ height: 512px;
+ overflow-x: scroll;
+ scroll-snap-type: x mandatory;
+ list-style-type: none;
+ scroll-behavior: smooth;
+ border: solid 2px grey;
+ padding-left: 0px;
+ white-space: nowrap;
+ position: relative;
+
+ &>.item {
+ height: 80%;
+ width: 120px;
+ border: 1px solid;
+ place-content: center;
+ background-color: white;
+ margin-right: 1200px;
+ display: inline-block;
+
+ &::scroll-marker {
+ content: ' ';
+ width: 35px;
+ height: 35px;
+ border: 3px solid gray;
+ border-radius: 50%;
+ margin: 3px;
+ background-color:red;
+ }
+
+ &::scroll-marker:target-current {
+ background-color: green;
+ }
+ }
+
+ scroll-marker-group: after;
+ &::scroll-marker-group {
+ height: 45px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ border: solid 1px black;
+ border-radius: 30px;
+ }
+ }
+
+ </style>
+ <div id="wrapper" class="wrapper">
+ <div class="carousel" id="carousel">
+ <div class="item" id="item1" tabindex=0>1</div>
+ <div class="item" id="item2" tabindex=0>2</div>
+ </div>
+ </div>
+ <script>
+ RED = "rgb(255, 0, 0)";
+ GREEN = "rgb(0, 128, 0)";
+
+ promise_test(async (t) => {
+ await waitForCompositorCommit();
+ const items = carousel.querySelectorAll(".item");
+
+ assert_equals(carousel.scrollLeft, 0, "carousel is not scrolled");
+ verifySelectedMarker(0, items, GREEN, RED);
+
+ // Scroll a bit, but not enough to bring item2 into view. Item1 should
+ // still be selected.
+ let pos = item2.offsetLeft - carousel.clientWidth - 10;
+ await waitForScrollReset(t, carousel, pos);
+ verifySelectedMarker(0, items, GREEN, RED);
+
+ // Scroll a bit more; bring item2 into view but only into the second half
+ // of the scroll port. Item1 should still be selected.
+ pos = item2.offsetLeft - carousel.clientWidth + item2.offsetWidth;
+ await waitForScrollReset(t, carousel, pos);
+ verifySelectedMarker(0, items, GREEN, RED);
+
+ // Scroll to place item2 within the half a scroll port's width from the
+ // current scroll offset. Item2 should now be selected.
+ pos += carousel.clientWidth / 2;
+ await waitForScrollReset(t, carousel, pos);
+ verifySelectedMarker(1, items, GREEN, RED);
+ }, "target whose target position is not yet reached only get selected " +
+ "when its less than half a scroll port away.");
+ </script>
+</body>
+
+</html>
diff --git a/tests/wpt/tests/css/css-transforms/parsing/transform-valid.html b/tests/wpt/tests/css/css-transforms/parsing/transform-valid.html
index 89a8b519b1b..b436fbdea30 100644
--- a/tests/wpt/tests/css/css-transforms/parsing/transform-valid.html
+++ b/tests/wpt/tests/css/css-transforms/parsing/transform-valid.html
@@ -38,14 +38,14 @@ test_valid_value("transform", "scale(1, 200%)", "scale(1, 2)");
test_valid_value("transform", "scale(-250%)", "scale(-2.5)");
test_valid_value("transform", "scale(-500%, -620%)", "scale(-5, -6.2)");
-test_valid_value("transform", "scaleX(7)");
-test_valid_value("transform", "scaleX(720%)", "scaleX(7.2)");
+test_valid_value("transform", "scaleX(7)", "scalex(7)");
+test_valid_value("transform", "scaleX(720%)", "scalex(7.2)");
-test_valid_value("transform", "scaleY(-8)");
-test_valid_value("transform", "scaleY(-85%)", "scaleY(-0.85)");
+test_valid_value("transform", "scaleY(-8)", "scaley(-8)");
+test_valid_value("transform", "scaleY(-85%)", "scaley(-0.85)");
-test_valid_value("transform", "scaleZ(4)");
-test_valid_value("transform", "scaleZ(25%)", "scaleZ(0.25)");
+test_valid_value("transform", "scaleZ(4)", "scalez(4)");
+test_valid_value("transform", "scaleZ(25%)", "scalez(0.25)");
test_valid_value("transform", "scale3d(0.5, 2.5, 3)");
test_valid_value("transform", "scale3d(50%, 250%, 300%)", "scale3d(0.5, 2.5, 3)");
@@ -62,11 +62,11 @@ test_valid_value("transform", "skew(90deg)");
test_valid_value("transform", "skew(0, -90deg)", "skew(0deg, -90deg)");
test_valid_value("transform", "skew(90deg, 0)", ["skew(90deg)", "skew(90deg, 0deg)"]);
-test_valid_value("transform", "skewX(0)", "skewX(0deg)");
-test_valid_value("transform", "skewX(90deg)");
+test_valid_value("transform", "skewX(0)", "skewx(0deg)");
+test_valid_value("transform", "skewX(90deg)", "skewx(90deg)");
-test_valid_value("transform", "skewY(0)", "skewY(0deg)");
-test_valid_value("transform", "skewY(-90deg)");
+test_valid_value("transform", "skewY(0)", "skewy(0deg)");
+test_valid_value("transform", "skewY(-90deg)", "skewy(-90deg)");
test_valid_value("transform", "perspective(10px)");
test_valid_value("transform", "perspective(none)");
diff --git a/tests/wpt/tests/css/css-values/tree-counting/calc-sibling-function-in-shadow-dom.html b/tests/wpt/tests/css/css-values/tree-counting/calc-sibling-function-in-shadow-dom.html
index 92fb6ce3351..ca8eb560ba1 100644
--- a/tests/wpt/tests/css/css-values/tree-counting/calc-sibling-function-in-shadow-dom.html
+++ b/tests/wpt/tests/css/css-values/tree-counting/calc-sibling-function-in-shadow-dom.html
@@ -33,9 +33,9 @@
<slot></slot>
</div>
`;
- assert_equals(getComputedStyle(target).zIndex, '3');
- assert_equals(getComputedStyle(target).order, '3');
- assert_equals(getComputedStyle(target).orphans, '3');
- assert_equals(getComputedStyle(target).widows, '3');
- }, 'Host children have sibling-index() and sibling-count() based on assignedNodes order');
+ assert_equals(getComputedStyle(target).zIndex, '4');
+ assert_equals(getComputedStyle(target).order, '4');
+ assert_equals(getComputedStyle(target).orphans, '4');
+ assert_equals(getComputedStyle(target).widows, '4');
+ }, 'Host children have sibling-index() and sibling-count() based on the DOM tree order');
</script>
diff --git a/tests/wpt/tests/css/css-values/tree-counting/sibling-function-invalidation.html b/tests/wpt/tests/css/css-values/tree-counting/sibling-function-invalidation.html
index 3c75c78530d..74f4995f5f7 100644
--- a/tests/wpt/tests/css/css-values/tree-counting/sibling-function-invalidation.html
+++ b/tests/wpt/tests/css/css-values/tree-counting/sibling-function-invalidation.html
@@ -48,55 +48,3 @@
assert_equals(t2.offsetHeight, 50);
}, "5 siblings after removal");
</script>
-
-<style>
- #t3 {
- width: calc(10px * sibling-index());
- height: 50px;
- background: teal;
- }
-</style>
-<div>
- <template shadowrootmode="open">
- <slot></slot>
- </template>
- <div id="rm3"></div>
- <div></div>
- <div></div>
- <div></div>
- <div></div>
- <div id="t3"></div>
-</div>
-<script>
- test(() => assert_equals(t3.offsetWidth, 60), "Initially 6th slotted sibling");
- test(() => {
- rm3.slot = "null";
- assert_equals(t3.offsetWidth, 50);
- }, "5th sibling after slot change");
-</script>
-
-<style>
- #t4 {
- width: 50px;
- height: calc(10px * sibling-count());
- background: teal;
- }
-</style>
-<div>
- <template shadowrootmode="open">
- <slot></slot>
- </template>
- <div id="t4"></div>
- <div></div>
- <div></div>
- <div></div>
- <div></div>
- <div id="rm4"></div>
-</div>
-<script>
- test(() => assert_equals(t4.offsetHeight, 60), "Initially 6 slotted siblings");
- test(() => {
- rm4.slot = "null";
- assert_equals(t4.offsetHeight, 50);
- }, "5 siblings after slot change");
-</script>
diff --git a/tests/wpt/tests/css/css-view-transitions/scoped/auto-name-on-descendant.html b/tests/wpt/tests/css/css-view-transitions/scoped/auto-name-on-descendant.html
new file mode 100644
index 00000000000..01d570e8bfc
--- /dev/null
+++ b/tests/wpt/tests/css/css-view-transitions/scoped/auto-name-on-descendant.html
@@ -0,0 +1,110 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1">
+ <!-- TODO update link -->
+ <link rel="help" href="https://www.w3.org/TR/css-view-transitions-2/">
+ <title>Scoped element with name auto on descendant</title>
+</head>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<style>
+ #container {
+ display: flex;
+ flex-direction: row;
+ position: relative;
+ /* Currently needed to force a stacking context in the absence of an
+ animation-name.
+ */
+ will-change: opacity;
+ }
+
+ .item {
+ background-color: teal;
+ color: white;
+ text-align: center;
+ line-height: 50px;
+ width: 50px;
+ height: 50px;
+ margin: 5px;
+ position: relative;
+ will-change: opacity;
+ view-transition-name: auto;
+ }
+
+ #item1.active {
+ background-color: orange;
+ transform: scale(1.2);
+ }
+
+ #item2.active {
+ background-color: salmon;
+ transform: scale(0.9);
+ }
+
+ #item3.active {
+ background-color: hotpink;
+ transform: scale(0.8) translateX(-10px);
+ }
+
+ ::view-transition-group(*) {
+ animation-duration: 2s;
+ }
+
+ ::view-transition-old(*) {
+ animation-name: -ua-view-transition-fade-out;
+ }
+
+ ::view-transition-new(*) {
+ animation-name: -ua-view-transition-fade-in;
+ }
+
+</style>
+<body>
+ <div id="container">
+ <div id="item1" class="item">A</div>
+ <div id="item2" class="item">B</div>
+ <div id="item3" class="item">C</div>
+ </div>
+</body>
+<script>
+ function assert_has_animations_with_name(name, count, message) {
+ const results =
+ document.getAnimations().filter(a => a.animationName == name);
+ assert_equals(results.length, count, message);
+ }
+
+ promise_test(async t => {
+ const element = document.getElementById("container");
+ const vt = element.startViewTransition(() => {
+ element.querySelectorAll('.item').forEach(el => {
+ el.classList.toggle('active');
+ });
+ });
+ await vt.ready;
+ const results =
+ document.getAnimations().map((a) => {
+ return `${a.effect.target.id}${a.effect.pseudoElement}`;
+ }).sort();
+ const expected = [
+ 'container::view-transition-group(match-element)',
+ 'container::view-transition-group(match-element)',
+ 'container::view-transition-group(match-element)',
+ 'container::view-transition-new(match-element)',
+ 'container::view-transition-new(match-element)',
+ 'container::view-transition-new(match-element)',
+ 'container::view-transition-old(match-element)',
+ 'container::view-transition-old(match-element)',
+ 'container::view-transition-old(match-element)',
+ ];
+
+ assert_array_equals(results, expected, 'Matched pseudo-elements');
+
+ assert_has_animations_with_name('-ua-view-transition-fade-in', 3,
+ 'Fade in animation');
+ assert_has_animations_with_name('-ua-view-transition-fade-out', 3,
+ 'Fade out animation');
+ }, 'Scoped view transition with name auto on the scoped element');
+</script>
+</html>
diff --git a/tests/wpt/tests/css/css-view-transitions/scoped/auto-name.html b/tests/wpt/tests/css/css-view-transitions/scoped/auto-name.html
new file mode 100644
index 00000000000..2d11985b398
--- /dev/null
+++ b/tests/wpt/tests/css/css-view-transitions/scoped/auto-name.html
@@ -0,0 +1,81 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1">
+ <!-- TODO update link -->
+ <link rel="help" href="https://www.w3.org/TR/css-view-transitions-2/">
+ <title>Scoped element with name auto</title>
+</head>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<style>
+ #container {
+ display: flex;
+ flex-direction: row;
+ view-transition-name: auto;
+ position: relative;
+ }
+
+ .item {
+ background-color: teal;
+ color: white;
+ text-align: center;
+ line-height: 50px;
+ width: 50px;
+ height: 50px;
+ margin: 5px;
+ display: inline-block;
+ }
+
+ ::view-transition-group(*) {
+ animation-duration: 2s;
+ }
+
+ ::view-transition-old(*) {
+ animation-name: -ua-view-transition-fade-out;
+ }
+
+ ::view-transition-new(*) {
+ animation-name: -ua-view-transition-fade-in;
+ }
+</style>
+<body>
+ <div id="container">
+ <div class="item">A</div>
+ <div class="item">B</div>
+ <div class="item">C</div>
+ </div>
+</body>
+<script>
+ function assert_has_animation_with_name(name, message) {
+ const results =
+ document.getAnimations().filter(a => a.animationName == name);
+ assert_equals(results.length, 1, message);
+ }
+
+ promise_test(async t => {
+ const element = document.getElementById("container");
+ const vt = element.startViewTransition(() => {
+ element.style.flexDirection = 'column';
+ });
+ await vt.ready;
+ const results =
+ document.getAnimations().map((a) => {
+ return `${a.effect.target.id}${a.effect.pseudoElement}`;
+ }).sort();
+ const expected = [
+ 'container::view-transition-group(match-element)',
+ 'container::view-transition-new(match-element)',
+ 'container::view-transition-old(match-element)',
+ ];
+
+ assert_array_equals(results, expected, 'Matched pseudo-elements');
+
+ assert_has_animation_with_name('-ua-view-transition-fade-in',
+ 'Fade in animation');
+ assert_has_animation_with_name('-ua-view-transition-fade-out',
+ 'Fade out animation');
+ }, 'Scoped view transition with name auto on the scoped element');
+</script>
+</html>
diff --git a/tests/wpt/tests/css/css-view-transitions/scoped/display-none-during-transition.html b/tests/wpt/tests/css/css-view-transitions/scoped/display-none-during-transition.html
new file mode 100644
index 00000000000..f94d6f7fd76
--- /dev/null
+++ b/tests/wpt/tests/css/css-view-transitions/scoped/display-none-during-transition.html
@@ -0,0 +1,74 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1">
+ <!-- TODO update link -->
+ <link rel="help" href="https://www.w3.org/TR/css-view-transitions-2/">
+ <title>Display none during transition</title>
+</head>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<style>
+ #target {
+ background-color: teal;
+ height: 100px;
+ width: 100px;
+ position: relative;
+ view-transition-name: target;
+ }
+
+ .hidden {
+ display: none;
+ }
+
+ ::view-transition-group(*) {
+ animation: unset;
+ }
+
+ ::view-transition-old(target) {
+ animation: -ua-view-transition-fade-out 300s;
+ }
+
+ ::view-transition-new(target) {
+ animation: -ua-view-transition-fade-in 300s;
+ }
+
+</style>
+<body>
+ <div id="target")></div>
+</body>
+<script>
+ function animationsCanceledPromise() {
+ const animations = document.getAnimations();
+ const promises = animations.map(a => a.finished);
+ return new Promise(async (resolve) => {
+ const values = await Promise.allSettled(promises);
+ values.forEach((result) => {
+ assert_equals(result.status, 'rejected');
+ });
+ resolve();
+ });
+ }
+
+ promise_test(async t => {
+ const target = document.getElementById('target');
+ const vt = target.startViewTransition(() => {
+ target.style.backgroundColor = 'orange';
+ });
+ await vt.ready;
+ const animations = document.getAnimations();
+ assert_equals(animations.length, 2,
+ 'View transition has running animations');
+ // wait for all animations to start running before hiding target.
+ await Promise.all([...animations.map(a => a.ready)]);
+ target.classList.toggle('hidden');
+ // Verify that the finished promise is rejected for each of the started
+ // animations.
+ await animationsCanceledPromise();
+ // Verify finished promise is resolved even though the transition did not
+ // run to completion.
+ return vt.finished;
+ }, 'Display none during a view transition skips the transition.');
+</script>
+</html>
diff --git a/tests/wpt/tests/css/css-view-transitions/scoped/document-element-start-view-transition.html b/tests/wpt/tests/css/css-view-transitions/scoped/document-element-start-view-transition.html
new file mode 100644
index 00000000000..42f87f93a07
--- /dev/null
+++ b/tests/wpt/tests/css/css-view-transitions/scoped/document-element-start-view-transition.html
@@ -0,0 +1,91 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1">
+ <!-- TODO update link -->
+ <link rel="help" href="https://www.w3.org/TR/css-view-transitions-2/">
+ <title>startViewTransition on document.documentElement</title>
+ <link rel="help" href="https://www.w3.org/TR/css-view-transitions-1/">
+</head>
+
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+
+<style>
+ :root {
+ view-transition-name: none;
+ }
+ #target {
+ width: 100px;
+ height: 100px;
+ background: blue;
+ contain: paint;
+ view-transition-name: target;
+ }
+ #target.update-1 {
+ height: 150px;
+ }
+ #target.update-2 {
+ height: 200px;
+ }
+</style>
+
+<body>
+ <div id="target"></div>
+</body>
+<script>
+ function run_view_transtiion_test(scope1, scope2, message) {
+ promise_test(async t => {
+ let rejected_promise_tally = 0;
+ const target = document.getElementById("target");
+ assert_implements(document.startViewTransition,
+ "Missing document.startViewTransition");
+
+ const verifyAbortedTransition = (promise) => {
+ return promise.then(
+ () => { assert_not_reached('transition aborted') },
+ (reason) => {
+ assert_true(reason instanceof DOMException);
+ assert_equals(reason.code, DOMException.ABORT_ERR);
+ rejected_promise_tally++;
+ });
+ };
+
+ const vt1 = scope1.startViewTransition(() => {
+ target.className = 'update-1';
+ });
+ const vt2 = scope2.startViewTransition(() => {
+ assert_equals(target.className, 'update-1');
+ target.className = 'update-2';
+ });
+
+ await verifyAbortedTransition(vt1.ready);
+ await vt2.ready;
+
+ assert_equals(rejected_promise_tally, 1,
+ 'first transition is skipped');
+ const sizeTransformAnimations = document.getAnimations().filter(a => {
+ return 'height' in a.effect.getKeyframes()[0];
+ });
+ assert_equals(sizeTransformAnimations.length, 1);
+ const startingHeight =
+ sizeTransformAnimations[0].effect.getKeyframes()[0].height;
+
+ assert_equals(startingHeight, '150px',
+ 'Height change applied before capture');
+ }, message);
+ }
+
+ run_view_transtiion_test(
+ document, document.documentElement,
+ 'Synchronously starting a view transition on document.documentElement ' +
+ 'skips the previously active document view transition.');
+
+ run_view_transtiion_test(
+ document.documentElement, document,
+ 'Synchronously starting a view transition on document skips the ' +
+ 'previously active view transition on document.documentElement.');
+
+</script>
+</html>
diff --git a/tests/wpt/tests/css/css-view-transitions/snapshot-containing-block-static-iframe-ref.html b/tests/wpt/tests/css/css-view-transitions/snapshot-containing-block-static-iframe-ref.html
new file mode 100644
index 00000000000..188cefecd3d
--- /dev/null
+++ b/tests/wpt/tests/css/css-view-transitions/snapshot-containing-block-static-iframe-ref.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html>
+<title>View transitions: use snapshot containing block for static position in iframe (ref)</title>
+<link rel="help" href="https://drafts.csswg.org/css-view-transitions-1/#snapshot-containing-block-concept/">
+
+<style>
+#inner {
+ width: 400px;
+ height: 200px;
+}
+</style>
+<iframe id="inner" srcdoc="
+ <style>
+ body {
+ height: 200vh;
+ background: limegreen;
+ overflow: hidden;
+ }
+ </style>
+ <body></body>
+"></iframe>
+
+<script>
+onload = () => {
+ inner.contentWindow.scrollTo(0, 100);
+};
+</script>
diff --git a/tests/wpt/tests/css/css-view-transitions/snapshot-containing-block-static-iframe.html b/tests/wpt/tests/css/css-view-transitions/snapshot-containing-block-static-iframe.html
new file mode 100644
index 00000000000..1903b9cacbd
--- /dev/null
+++ b/tests/wpt/tests/css/css-view-transitions/snapshot-containing-block-static-iframe.html
@@ -0,0 +1,55 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<title>View transitions: use snapshot containing block for static position in iframe</title>
+<link rel="help" href="https://drafts.csswg.org/css-view-transitions-1/#snapshot-containing-block-concept/">
+<link rel="match" href="snapshot-containing-block-static-iframe-ref.html">
+
+<script src="/common/reftest-wait.js"></script>
+<script src="/common/rendering-utils.js"></script>
+
+<style>
+#inner {
+ width: 400px;
+ height: 200px;
+}
+</style>
+<iframe id="inner" srcdoc="
+ <style>
+ body {
+ height: 200vh;
+ overflow: hidden;
+ }
+ ::view-transition {
+ position: static;
+ display: block;
+ width: 100%;
+ height: 100%;
+ background: limegreen;
+ }
+ ::view-transition-group(*),
+ ::view-transition-image-pair(*),
+ ::view-transition-old(*),
+ ::view-transition-new(*) {
+ animation-play-state: paused;
+ }
+
+ </style>
+ <body></body>
+"></iframe>
+<script>
+failIfNot(document.startViewTransition, "Missing document.startViewTransition");
+
+async function runTest() {
+ // Start the view transition at a scroll offset so that the snapshot
+ // containing block differs from the initial containing block.
+ inner.contentWindow.scrollTo(0, 100);
+ await waitForAtLeastOneFrame();
+
+ const contentDocument = inner.contentDocument;
+ let vt = inner.contentDocument.startViewTransition();
+ await vt.ready;
+ takeScreenshot();
+}
+
+onload = () => requestAnimationFrame(() => requestAnimationFrame(runTest));
+</script>
diff --git a/tests/wpt/tests/css/css-view-transitions/view-transition-name-stacking-context-dynamic.html b/tests/wpt/tests/css/css-view-transitions/view-transition-name-stacking-context-dynamic.html
new file mode 100644
index 00000000000..1a908e6f659
--- /dev/null
+++ b/tests/wpt/tests/css/css-view-transitions/view-transition-name-stacking-context-dynamic.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+<meta charset="utf-8">
+<title>CSS will-change: 'will-change: view-transition-name' creates a stacking context dynamically</title>
+<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1962862">
+<link rel="help" href="https://drafts.csswg.org/css-view-transitions-1/#named-and-transitioning">
+<link rel="match" href="/css/reference/ref-filled-green-100px-square-only.html">
+<style>
+div { width: 100px; height: 100px }
+#wc { background: red; position: relative; }
+#child { position: absolute; top: 0; left: 0; z-index: -1; background: green }
+</style>
+<p>Test passes if there is a filled green square.</p>
+<div id="wc">
+ <div id="child"></div>
+</div>
+<script>
+window.addEventListener("TestRendered", function() {
+ wc.style.viewTransitionName = "something";
+ document.documentElement.removeAttribute("class");
+});
+</script>
diff --git a/tests/wpt/tests/css/css-view-transitions/view-transition-types-mutable-no-document-element-crashtest.html b/tests/wpt/tests/css/css-view-transitions/view-transition-types-mutable-no-document-element-crashtest.html
index f1940c39869..d5c0abd652c 100644
--- a/tests/wpt/tests/css/css-view-transitions/view-transition-types-mutable-no-document-element-crashtest.html
+++ b/tests/wpt/tests/css/css-view-transitions/view-transition-types-mutable-no-document-element-crashtest.html
@@ -3,6 +3,15 @@
<link rel="help" href="https://www.w3.org/TR/css-transitions-2/">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
+
+<style>
+::view-transition-group(*),
+::view-transition-image-pair(*),
+::view-transition-old(*),
+::view-transition-new(*) {
+ animation-play-state: paused;
+}
+</style>
<script>
test(() => {
diff --git a/tests/wpt/tests/css/css-view-transitions/window-resize-aborts-transition-before-ready.html b/tests/wpt/tests/css/css-view-transitions/window-resize-aborts-transition-before-ready.html
index 3c4ba37b26b..09e6e6cc1c9 100644
--- a/tests/wpt/tests/css/css-view-transitions/window-resize-aborts-transition-before-ready.html
+++ b/tests/wpt/tests/css/css-view-transitions/window-resize-aborts-transition-before-ready.html
@@ -37,9 +37,11 @@ promise_test(async t => {
// Wait until the popup window is loaded to make sure the document we start
// the view transitions is the right one.
- await new Promise(resolve => {
- popup_win.addEventListener('load', resolve, { once: true });
- });
+ if (!popup_win.document || popup_win.document.readyState != 'complete') {
+ await new Promise(resolve => {
+ popup_win.addEventListener('load', resolve, { once: true });
+ });
+ }
if (popup_win.document.visibilityState == "hidden") {
await new Promise((resolve) => {
diff --git a/tests/wpt/tests/css/css-view-transitions/window-resize-aborts-transition.html b/tests/wpt/tests/css/css-view-transitions/window-resize-aborts-transition.html
index 8d61a3e3c53..966f23c0fdf 100644
--- a/tests/wpt/tests/css/css-view-transitions/window-resize-aborts-transition.html
+++ b/tests/wpt/tests/css/css-view-transitions/window-resize-aborts-transition.html
@@ -37,9 +37,11 @@ promise_test(async t => {
// Wait until the popup window is loaded to make sure the document we update
// below is the right one.
- await new Promise(resolve => {
- popupWin.addEventListener('load', resolve, { once: true });
- });
+ if (!popupWin.document || popupWin.document.readyState != 'complete') {
+ await new Promise(resolve => {
+ popupWin.addEventListener('load', resolve, { once: true });
+ });
+ }
let popupDoc = popupWin.document;
popupDoc.documentElement.innerHTML = `
diff --git a/tests/wpt/tests/css/css-writing-modes/orthogonal-dynamic-size-001.html b/tests/wpt/tests/css/css-writing-modes/orthogonal-dynamic-size-001.html
new file mode 100644
index 00000000000..add7f1fc2aa
--- /dev/null
+++ b/tests/wpt/tests/css/css-writing-modes/orthogonal-dynamic-size-001.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+
+<link rel="author" title="Jonathan Kew" href="mailto:jkew@mozilla.com" />
+<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1954866" />
+<link rel="match" href="../reference/ref-filled-green-100px-square.xht" />
+
+<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
+
+<div id="container" style="width: 100px; height: 50px; background-color: red">
+ <div style="height: 100%; width: 100px; writing-mode: vertical-lr; background-color: green;">
+ </div>
+</div>
+
+<script>
+container.offsetHeight;
+container.style.height = "100px";
+</script>
diff --git a/tests/wpt/tests/digital-credentials/allow-attribute-with-create.https.html b/tests/wpt/tests/digital-credentials/allow-attribute-with-create.https.html
new file mode 100644
index 00000000000..4b1e96fec4c
--- /dev/null
+++ b/tests/wpt/tests/digital-credentials/allow-attribute-with-create.https.html
@@ -0,0 +1,138 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>
+ Test allow attribute with "digital-credentials-create" and
+ CredentialsContainer's .create() method
+ </title>
+ <script src="/common/get-host-info.sub.js"></script>
+ <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>
+ const hostInfo = get_host_info();
+ const iframeDetails = [
+ {
+ policy: null,
+ crossOrigin: false,
+ expectIsAllowed: true,
+ },
+ {
+ policy: null,
+ crossOrigin: true,
+ expectIsAllowed: false,
+ },
+ {
+ policy: "digital-credentials-create",
+ crossOrigin: false,
+ expectIsAllowed: true,
+ },
+ {
+ policy: "digital-credentials-create",
+ crossOrigin: true,
+ expectIsAllowed: true,
+ },
+ {
+ policy: "digital-credentials-create *",
+ crossOrigin: false,
+ expectIsAllowed: true,
+ },
+ {
+ policy: "digital-credentials-create *",
+ crossOrigin: true,
+ expectIsAllowed: true,
+ },
+ {
+ policy: "digital-credentials-create 'none'",
+ crossOrigin: false,
+ expectIsAllowed: false,
+ },
+ {
+ policy: "digital-credentials-create 'none'",
+ crossOrigin: true,
+ expectIsAllowed: false,
+ },
+ {
+ policy: "digital-credentials-create 'self'",
+ crossOrigin: false,
+ expectIsAllowed: true,
+ },
+ {
+ policy: "digital-credentials-create 'self'",
+ crossOrigin: true,
+ expectIsAllowed: false,
+ },
+ {
+ policy: `digital-credentials-create ${hostInfo.HTTPS_REMOTE_ORIGIN}`,
+ crossOrigin: false,
+ expectIsAllowed: false,
+ },
+ {
+ policy: `digital-credentials-create ${hostInfo.HTTPS_REMOTE_ORIGIN}`,
+ crossOrigin: true,
+ expectIsAllowed: true,
+ },
+ ];
+
+ async function loadIframe({ policy, crossOrigin, expectIsAllowed }) {
+ const iframe = document.createElement("iframe");
+ if (policy !== null) {
+ iframe.allow = policy;
+ }
+
+ await new Promise((resolve) => {
+ iframe.onload = resolve;
+ iframe.src = new URL(
+ "/digital-credentials/support/iframe.html",
+ crossOrigin
+ ? hostInfo.HTTPS_REMOTE_ORIGIN
+ : location.origin
+ ).href;
+ iframe.dataset.expectIsAllowed = expectIsAllowed;
+ document.body.appendChild(iframe);
+ });
+ iframe.focus();
+ return iframe;
+ }
+
+ function runTests() {
+ for (const details of iframeDetails) {
+ promise_test(async (test) => {
+ const iframe = await loadIframe(details);
+ const { expectIsAllowed } = details;
+ const action = "create";
+ const options = {
+ digital: {
+ // Results in TypeError when allowed, NotAllowedError when disallowed
+ requests: [],
+ },
+ mediation: "required",
+ };
+ const { data } = await new Promise((resolve) => {
+ window.addEventListener("message", resolve, {
+ once: true,
+ });
+ iframe.contentWindow.postMessage(
+ { action, options, needsActivation: true },
+ "*"
+ );
+ });
+ const { name, message } = data;
+ const fullMessage = `${iframe.outerHTML} - ${message}`;
+ if (expectIsAllowed) {
+ assert_true(
+ name == "TypeError" || name == "NotAllowedError",
+ fullMessage
+ );
+ } else {
+ assert_equals(name, "NotAllowedError", fullMessage);
+ }
+ iframe.remove();
+ }, `With Create: Policy to use: ${details.policy}, is cross-origin: ${details.crossOrigin}, is allowed by policy: ${details.expectIsAllowed}`);
+ }
+ }
+ </script>
+ </head>
+ <body onload="runTests()"></body>
+</html>
diff --git a/tests/wpt/tests/digital-credentials/allow-attribute.https.html b/tests/wpt/tests/digital-credentials/allow-attribute-with-get.https.html
index 667b84bc704..15601d891f2 100644
--- a/tests/wpt/tests/digital-credentials/allow-attribute.https.html
+++ b/tests/wpt/tests/digital-credentials/allow-attribute-with-get.https.html
@@ -129,7 +129,7 @@
assert_equals(name, "NotAllowedError", fullMessage);
}
iframe.remove();
- }, `Policy to use: ${details.policy}, is cross-origin: ${details.crossOrigin}, is allowed by policy: ${details.expectIsAllowed}`);
+ }, `With Get: Policy to use: ${details.policy}, is cross-origin: ${details.crossOrigin}, is allowed by policy: ${details.expectIsAllowed}`);
}
}
</script>
diff --git a/tests/wpt/tests/digital-credentials/create.disabled-by-permissions-policy.https.sub.html b/tests/wpt/tests/digital-credentials/create.disabled-by-permissions-policy.https.sub.html
new file mode 100644
index 00000000000..52db2373f09
--- /dev/null
+++ b/tests/wpt/tests/digital-credentials/create.disabled-by-permissions-policy.https.sub.html
@@ -0,0 +1,49 @@
+<!DOCTYPE html>
+<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="/permissions-policy/resources/permissions-policy.js"></script>
+<script src="/common/get-host-info.sub.js"></script>
+<body></body>
+<script type="module">
+ import { makeCreateOptions } from "/digital-credentials/support/helper.js";
+ const { HTTPS_REMOTE_ORIGIN } = get_host_info();
+ const same_origin_src =
+ "/permissions-policy/resources/digital-credentials-create.html";
+ const cross_origin_src = new URL(same_origin_src, HTTPS_REMOTE_ORIGIN).href;
+
+ promise_test(async (test) => {
+ await test_driver.bless("user activation");
+ await promise_rejects_dom(
+ test,
+ "NotAllowedError",
+ navigator.credentials.create(makeCreateOptions([]))
+ );
+ }, "Permissions-Policy header digital-credentials-create=() disallows the top-level document.");
+
+ promise_test(async (test) => {
+ await test_feature_availability({
+ feature_description: "Digital Credential API",
+ test,
+ src: same_origin_src,
+ expect_feature_available: expect_feature_unavailable_default,
+ is_promise_test: true,
+ needs_focus: true,
+ });
+ }, "Permissions-Policy header digital-credentials-create=() disallows same-origin iframes.");
+
+ promise_test(async (test) => {
+ await test_feature_availability({
+ feature_description: "Digital Credential API",
+ test,
+ src: cross_origin_src,
+ expect_feature_available: expect_feature_unavailable_default,
+ feature_name: "digital-credentials-create",
+ is_promise_test: true,
+ needs_focus: true,
+ });
+ }, "Permissions-Policy header digital-credentials-create=() cannot be overridden using the allow attribute.");
+
+</script>
diff --git a/tests/wpt/tests/digital-credentials/create.disabled-by-permissions-policy.https.sub.html.headers b/tests/wpt/tests/digital-credentials/create.disabled-by-permissions-policy.https.sub.html.headers
new file mode 100644
index 00000000000..9847d173eb6
--- /dev/null
+++ b/tests/wpt/tests/digital-credentials/create.disabled-by-permissions-policy.https.sub.html.headers
@@ -0,0 +1 @@
+Permissions-Policy: digital-credentials-create=()
diff --git a/tests/wpt/tests/digital-credentials/create.tentative.https.html b/tests/wpt/tests/digital-credentials/create.tentative.https.html
index 299a240ced1..3e17d5b0853 100644
--- a/tests/wpt/tests/digital-credentials/create.tentative.https.html
+++ b/tests/wpt/tests/digital-credentials/create.tentative.https.html
@@ -13,7 +13,7 @@
</body>
<script type="module">
- import { sendMessage, loadIframe } from "./support/helper.js";
+ import { makeCreateOptions, sendMessage, loadIframe } from "./support/helper.js";
const iframeSameOrigin = document.querySelector("iframe#same-origin");
const iframeCrossOrigin = document.querySelector("iframe#cross-origin");
@@ -31,83 +31,170 @@
});
promise_test(async (t) => {
- const result = await navigator.credentials.create();
- assert_equals(result, null);
- }, "navigator.credentials.create() frame just returns null.");
+ iframeSameOrigin.focus();
+ for (const global of [window, iframeSameOrigin.contentWindow]) {
+ await promise_rejects_dom(
+ t,
+ "NotSupportedError",
+ global.DOMException,
+ global.navigator.credentials.create()
+ );
- promise_test(async (t) => {
- const { contentWindow: iframeWindow } = iframeSameOrigin;
- const result = await iframeWindow.navigator.credentials.create();
- assert_equals(result, null);
- }, "navigator.credentials.create() same-origin iframe just returns null.");
+ await promise_rejects_dom(
+ t,
+ "NotSupportedError",
+ global.DOMException,
+ global.navigator.credentials.create({})
+ );
- promise_test(async (t) => {
- const result = await sendMessage(iframeCrossOrigin, {
- action: "create",
- });
- assert_equals(result, null);
- }, "navigator.credentials.create() cross-origin iframe results in null.");
+ await promise_rejects_dom(
+ t,
+ "NotSupportedError",
+ global.DOMException,
+ global.navigator.credentials.create({ x: "y" })
+ );
- promise_test(async () => {
- for (const mediation of mediations) {
- const result = await navigator.credentials.create({ mediation });
- assert_equals(result, null);
+ await promise_rejects_dom(
+ t,
+ "NotSupportedError",
+ global.DOMException,
+ global.navigator.credentials.create({ x: "y", y: "z" })
+ );
+
+ await promise_rejects_dom(
+ t,
+ "NotSupportedError",
+ global.DOMException,
+ global.navigator.credentials.create({ mediation: "required" })
+ );
+
+ const abortController = new AbortController();
+ const { signal } = abortController;
+
+ await promise_rejects_dom(
+ t,
+ "NotSupportedError",
+ global.DOMException,
+ global.navigator.credentials.create({ signal })
+ );
+
+ await promise_rejects_dom(
+ t,
+ "NotSupportedError",
+ global.DOMException,
+ global.navigator.credentials.create({ signal, mediation: "required" })
+ );
}
- }, "navigator.credentials.create() ignores mediations.");
+ }, "Calling navigator.credentials.create() without a digital member same origin.");
- promise_test(async () => {
- for (const mediation of mediations) {
- const result = await navigator.credentials.create({ mediation });
- assert_equals(result, null);
+ promise_test(async (t) => {
+ for (const request of [undefined, []]) {
+ const options = makeCreateOptions(request);
+ await test_driver.bless("user activation");
+ await promise_rejects_js(t, TypeError, navigator.credentials.create(options));
}
- }, "navigator.credentials.create() ignores mediations in same-origin iframe.");
+ }, "navigator.credentials.create() API rejects if there are no credential request.");
- promise_test(async () => {
- for (const mediation of mediations) {
+ promise_test(async (t) => {
+ iframeSameOrigin.focus();
+ const { contentWindow: iframeWindow } = iframeSameOrigin;
+ for (const request of [undefined, []]) {
+ const options = makeCreateOptions(request);
+ await test_driver.bless("user activation");
+ await promise_rejects_js(
+ t,
+ iframeWindow.TypeError,
+ iframeWindow.navigator.credentials.create(options)
+ );
+ }
+ }, "navigator.credentials.create() API rejects if there are no credential request for same-origin iframe.");
+
+ promise_test(async (t) => {
+ iframeCrossOrigin.focus();
+ for (const request of [undefined, []]) {
+ const options = makeCreateOptions(request);
const result = await sendMessage(iframeCrossOrigin, {
action: "create",
- request: { mediation },
+ options,
});
- assert_equals(result, null);
+ assert_equals(result.constructor, "TypeError");
}
- }, "navigator.credentials.create() ignores mediations in cross-origin iframe.");
+ }, "navigator.credentials.create() API rejects if there are no credential request in cross-origin iframe.");
promise_test(async (t) => {
const abortController = new AbortController();
const { signal } = abortController;
abortController.abort();
- await promise_rejects_dom(
- t,
- "AbortError",
- navigator.credentials.create({
- signal,
- })
- );
- }, "navigator.credentials.create() rejects if called with an aborted controller.");
+ for (const options of [{ signal }, { signal, ...makeCreateOptions([]) }]) {
+ await promise_rejects_dom(
+ t,
+ "AbortError",
+ navigator.credentials.create(options)
+ );
+ }
+ }, "navigator.credentials.create() promise is rejected if called with an aborted controller.");
promise_test(async (t) => {
+ iframeSameOrigin.focus();
const { contentWindow: iframeWindow } = iframeSameOrigin;
const abortController = new iframeWindow.AbortController();
const { signal } = abortController;
abortController.abort();
- await promise_rejects_dom(
+ for (const options of [{ signal }, { signal, ...makeCreateOptions([]) }]) {
+ await test_driver.bless("user activation");
+ await promise_rejects_dom(
+ t,
+ "AbortError",
+ iframeWindow.DOMException,
+ iframeWindow.navigator.credentials.create(options)
+ );
+ assert_true(
+ navigator.userActivation.isActive,
+ "User activation is still active."
+ );
+ }
+ }, "navigator.credentials.create() promise is rejected if called with an aborted controller in same-origin iframe.");
+
+ promise_test(async (t) => {
+ iframeCrossOrigin.focus();
+ for (const options of [undefined, {}, makeCreateOptions([])]) {
+ const result = await sendMessage(iframeCrossOrigin, {
+ abort: "before",
+ action: "create",
+ options,
+ });
+ assert_equals(result.constructor, "DOMException");
+ assert_equals(result.name, "AbortError");
+ }
+ }, "navigator.credentials.create() promise is rejected if called with an aborted signal in cross-origin iframe.");
+
+ promise_test(async (t) => {
+ const abortController = new AbortController();
+ const { signal } = abortController;
+ const options = makeCreateOptions("openid4vci");
+ options.signal = signal;
+ await test_driver.bless("user activation");
+ const promise = promise_rejects_dom(
t,
"AbortError",
- iframeWindow.DOMException,
- iframeWindow.navigator.credentials.create({
- signal,
- })
+ DOMException,
+ navigator.credentials.create(options)
);
- }, "navigator.credentials.create() rejects if called with an aborted controller in same-origin iframe.");
+ abortController.abort();
+ await promise;
+ }, "navigator.credentials.create() promise is rejected if abort controller is aborted after call to create().");
promise_test(async (t) => {
+ iframeCrossOrigin.focus();
const result = await sendMessage(iframeCrossOrigin, {
+ abort: "after",
action: "create",
- abort: "before",
+ needsActivation: true,
+ options: makeCreateOptions("openid4vci"),
});
assert_equals(result.constructor, "DOMException");
assert_equals(result.name, "AbortError");
- }, "navigator.credentials.create() rejects if called with an aborted controller in cross-origin iframe.");
+ }, "navigator.credentials.create() promise is rejected if abort controller is aborted after call to create() in cross-origin iframe.");
promise_test(async (t) => {
const abortController = new AbortController();
@@ -121,4 +208,13 @@
await promise_rejects_dom(t, "AbortError", requestPromise);
}
}, "Adding mediations together with abort signal respects the abort signal.");
+
+ promise_test(async (t) => {
+ /** @type sequence<CredentialMediationRequirement> */
+ const disallowedMediations = [ "conditional", "optional", "silent"];
+ for (const mediation of disallowedMediations) {
+ const options = makeCreateOptions("default", mediation);
+ await promise_rejects_js(t, TypeError, navigator.credentials.create(options));
+ }
+ }, "Mediation is required to create a DigitalCredential.");
</script>
diff --git a/tests/wpt/tests/digital-credentials/dc-types.ts b/tests/wpt/tests/digital-credentials/dc-types.ts
index 30284e7fad6..83168f8a343 100644
--- a/tests/wpt/tests/digital-credentials/dc-types.ts
+++ b/tests/wpt/tests/digital-credentials/dc-types.ts
@@ -1,4 +1,6 @@
-export type Protocol = "default" | "openid4vp";
+export type GetProtocol = "default" | "openid4vp";
+export type CreateProtocol = "default" | "openid4vci";
+
export type CredentialMediationRequirement =
| "conditional"
| "optional"
@@ -8,7 +10,7 @@ export type CredentialMediationRequirement =
/**
* @see https://wicg.github.io/digital-credentials/#dom-digitalcredentialrequest
*/
-export interface DigitalCredentialRequest {
+export interface DigitalCredentialGetRequest {
protocol: string;
data: object;
}
@@ -20,7 +22,7 @@ export interface DigitalCredentialRequestOptions {
/**
* The list of credential requests.
*/
- requests: DigitalCredentialRequest[] | any;
+ requests: DigitalCredentialGetRequest[] | any;
}
/**
@@ -31,6 +33,23 @@ export interface CredentialRequestOptions {
mediation: CredentialMediationRequirement;
}
+export interface DigitalCredentialCreateRequest {
+ protocol: string;
+ data: object;
+}
+
+export interface DigitalCredentialCreationOptions {
+ /**
+ * The list of credential requests.
+ */
+ requests: DigitalCredentialCreateRequest[] | any;
+}
+
+export interface CredentialCreationOptions {
+ digital: DigitalCredentialCreationOptions;
+ mediation: CredentialMediationRequirement;
+}
+
/**
* The actions that can be performed on the API via the iframe.
*/
diff --git a/tests/wpt/tests/digital-credentials/default-permissions-policy.https.sub.html b/tests/wpt/tests/digital-credentials/default-permissions-policy.https.sub.html
index 742a94ec4eb..8041e25d33b 100644
--- a/tests/wpt/tests/digital-credentials/default-permissions-policy.https.sub.html
+++ b/tests/wpt/tests/digital-credentials/default-permissions-policy.https.sub.html
@@ -8,11 +8,15 @@
<script src="/common/get-host-info.sub.js"></script>
<body></body>
<script type="module">
- import { makeGetOptions } from "./support/helper.js";
+ import { makeGetOptions, makeCreateOptions } from "./support/helper.js";
const { HTTPS_REMOTE_ORIGIN } = get_host_info();
- const same_origin_src =
+ const get_same_origin_src =
"/permissions-policy/resources/digital-credentials-get.html";
- const cross_origin_src = new URL(same_origin_src, HTTPS_REMOTE_ORIGIN).href;
+ const get_cross_origin_src = new URL(get_same_origin_src, HTTPS_REMOTE_ORIGIN).href;
+
+ const create_same_origin_src =
+ "/permissions-policy/resources/digital-credentials-create.html";
+ const create_cross_origin_src = new URL(create_same_origin_src, HTTPS_REMOTE_ORIGIN).href;
promise_test(async (test) => {
await test_driver.bless("user activation");
@@ -25,7 +29,7 @@
await test_feature_availability({
feature_description: "Digital Credential API",
test,
- src: same_origin_src,
+ src: get_same_origin_src,
expect_feature_available: expect_feature_available_default,
is_promise_test: true,
});
@@ -33,10 +37,36 @@
await test_feature_availability({
feature_description: "Digital Credential API",
test,
- src: cross_origin_src,
+ src: get_cross_origin_src,
expect_feature_available: expect_feature_unavailable_default,
feature_name: "digital-credentials-get",
is_promise_test: true,
});
- }, "Permissions-Policy is by default 'self'.");
+ }, "Permissions-Policy is by default 'self' for get().");
+
+ promise_test(async (test) => {
+ await test_driver.bless("user activation");
+ await promise_rejects_js(
+ test,
+ TypeError,
+ navigator.credentials.create(makeCreateOptions([]))
+ );
+
+ await test_feature_availability({
+ feature_description: "Digital Credential API",
+ test,
+ src: create_same_origin_src,
+ expect_feature_available: expect_feature_available_default,
+ is_promise_test: true,
+ });
+
+ await test_feature_availability({
+ feature_description: "Digital Credential API",
+ test,
+ src: create_cross_origin_src,
+ expect_feature_available: expect_feature_unavailable_default,
+ feature_name: "digital-credentials-create",
+ is_promise_test: true,
+ });
+ }, "Permissions-Policy is by default 'self' for create().");
</script>
diff --git a/tests/wpt/tests/digital-credentials/disabled-by-permissions-policy.https.sub.html.headers b/tests/wpt/tests/digital-credentials/disabled-by-permissions-policy.https.sub.html.headers
deleted file mode 100644
index 02a76b7c3f2..00000000000
--- a/tests/wpt/tests/digital-credentials/disabled-by-permissions-policy.https.sub.html.headers
+++ /dev/null
@@ -1 +0,0 @@
-Permissions-Policy: digital-credentials-get=()
diff --git a/tests/wpt/tests/digital-credentials/enabled-on-self-origin-by-permissions-policy.https.sub.html b/tests/wpt/tests/digital-credentials/enabled-on-self-origin-by-permissions-policy.https.sub.html
index d530f4920a3..261ebb0ce70 100644
--- a/tests/wpt/tests/digital-credentials/enabled-on-self-origin-by-permissions-policy.https.sub.html
+++ b/tests/wpt/tests/digital-credentials/enabled-on-self-origin-by-permissions-policy.https.sub.html
@@ -10,9 +10,13 @@
<script type="module">
import { makeGetOptions } from "./support/helper.js";
const { HTTPS_REMOTE_ORIGIN } = get_host_info();
- const same_origin_src =
+ const get_same_origin_src =
"/permissions-policy/resources/digital-credentials-get.html";
- const cross_origin_src = new URL(same_origin_src, HTTPS_REMOTE_ORIGIN).href;
+ const get_cross_origin_src = new URL(get_same_origin_src, HTTPS_REMOTE_ORIGIN).href;
+
+ const create_same_origin_src =
+ "/permissions-policy/resources/digital-credentials-create.html";
+ const create_cross_origin_src = new URL(create_same_origin_src, HTTPS_REMOTE_ORIGIN).href;
promise_test(async (test) => {
await test_driver.bless("user activation");
@@ -27,7 +31,7 @@
await test_feature_availability({
feature_description: "Digital Credential API",
test,
- src: same_origin_src,
+ src: get_same_origin_src,
expect_feature_available: expect_feature_available_default,
is_promise_test: true,
needs_focus: true,
@@ -38,7 +42,7 @@
await test_feature_availability({
feature_description: "Digital Credential API",
test,
- src: cross_origin_src,
+ src: get_cross_origin_src,
expect_feature_available: expect_feature_unavailable_default,
is_promise_test: true,
needs_focus: true,
@@ -49,11 +53,54 @@
await test_feature_availability({
feature_description: "Digital Credential API",
test,
- src: cross_origin_src,
+ src: get_cross_origin_src,
expect_feature_available: expect_feature_unavailable_default,
feature_name: "digital-credentials-get",
is_promise_test: true,
needs_focus: true,
});
}, "Permissions-Policy header explicitly set to digital-credentials-get=(self) cannot be overridden by allow attribute.");
+
+ promise_test(async (test) => {
+ await test_driver.bless("user activation");
+ await promise_rejects_js(
+ test,
+ TypeError,
+ navigator.credentials.create(makeCreateOptions([]))
+ );
+ }, "Permissions-Policy header digital-credentials-create=(self) allows the top-level document.");
+
+ promise_test(async (test) => {
+ await test_feature_availability({
+ feature_description: "Digital Credential API",
+ test,
+ src: create_same_origin_src,
+ expect_feature_available: expect_feature_available_default,
+ is_promise_test: true,
+ needs_focus: true,
+ });
+ }, "Permissions-Policy header digital-credentials-create=(self) allows same-origin iframes.");
+
+ promise_test(async (test) => {
+ await test_feature_availability({
+ feature_description: "Digital Credential API",
+ test,
+ src: create_cross_origin_src,
+ expect_feature_available: expect_feature_unavailable_default,
+ is_promise_test: true,
+ needs_focus: true,
+ });
+ }, "Permissions-Policy header digital-credentials-create=(self) disallows cross-origin iframes.");
+
+ promise_test(async (test) => {
+ await test_feature_availability({
+ feature_description: "Digital Credential API",
+ test,
+ src: create_cross_origin_src,
+ expect_feature_available: expect_feature_unavailable_default,
+ feature_name: "digital-credentials-create",
+ is_promise_test: true,
+ needs_focus: true,
+ });
+ }, "Permissions-Policy header explicitly set to digital-credentials-create=(self) cannot be overridden by allow attribute.");
</script>
diff --git a/tests/wpt/tests/digital-credentials/enabled-on-self-origin-by-permissions-policy.https.sub.html.headers b/tests/wpt/tests/digital-credentials/enabled-on-self-origin-by-permissions-policy.https.sub.html.headers
index 1207d9e29a1..4de358e6a44 100644
--- a/tests/wpt/tests/digital-credentials/enabled-on-self-origin-by-permissions-policy.https.sub.html.headers
+++ b/tests/wpt/tests/digital-credentials/enabled-on-self-origin-by-permissions-policy.https.sub.html.headers
@@ -1 +1 @@
-Permissions-Policy: digital-credentials-get=(self)
+Permissions-Policy: digital-credentials-get=(self), digital-credentials-create=(self)
diff --git a/tests/wpt/tests/digital-credentials/disabled-by-permissions-policy.https.sub.html b/tests/wpt/tests/digital-credentials/get.disabled-by-permissions-policy.https.sub.html
index c32f73aa309..c32f73aa309 100644
--- a/tests/wpt/tests/digital-credentials/disabled-by-permissions-policy.https.sub.html
+++ b/tests/wpt/tests/digital-credentials/get.disabled-by-permissions-policy.https.sub.html
diff --git a/tests/wpt/tests/digital-credentials/get.disabled-by-permissions-policy.https.sub.html.headers b/tests/wpt/tests/digital-credentials/get.disabled-by-permissions-policy.https.sub.html.headers
new file mode 100644
index 00000000000..5672154a423
--- /dev/null
+++ b/tests/wpt/tests/digital-credentials/get.disabled-by-permissions-policy.https.sub.html.headers
@@ -0,0 +1 @@
+Permissions-Policy: digital-credentials-get=() \ No newline at end of file
diff --git a/tests/wpt/tests/digital-credentials/get.tentative.https.html b/tests/wpt/tests/digital-credentials/get.tentative.https.html
index a090e1b1432..b04a6e3a713 100644
--- a/tests/wpt/tests/digital-credentials/get.tentative.https.html
+++ b/tests/wpt/tests/digital-credentials/get.tentative.https.html
@@ -83,7 +83,7 @@
global.navigator.credentials.get({ signal, mediation: "required" })
);
}
- }, "Calling navigator.credentials.get() without an digital member same origin.");
+ }, "Calling navigator.credentials.get() without a digital member same origin.");
promise_test(async (t) => {
for (const request of [undefined, []]) {
diff --git a/tests/wpt/tests/digital-credentials/support/helper.js b/tests/wpt/tests/digital-credentials/support/helper.js
index 71022432652..5a9cda34788 100644
--- a/tests/wpt/tests/digital-credentials/support/helper.js
+++ b/tests/wpt/tests/digital-credentials/support/helper.js
@@ -1,49 +1,129 @@
// @ts-check
// Import the types from the TypeScript file
/**
- * @typedef {import('../dc-types').Protocol} protocol
- * @typedef {import('../dc-types').DigitalCredentialRequest} DigitalCredentialRequest
+ * @typedef {import('../dc-types').GetProtocol} GetProtocol
+ * @typedef {import('../dc-types').DigitalCredentialGetRequest} DigitalCredentialGetRequest
* @typedef {import('../dc-types').DigitalCredentialRequestOptions} DigitalCredentialRequestOptions
* @typedef {import('../dc-types').CredentialRequestOptions} CredentialRequestOptions
+ * @typedef {import('../dc-types').CreateProtocol} CreateProtocol
+ * @typedef {import('../dc-types').DigitalCredentialCreateRequest} DigitalCredentialCreateRequest
+ * @typedef {import('../dc-types').CredentialCreationOptions} CredentialCreationOptions
+ * @typedef {import('../dc-types').DigitalCredentialCreationOptions} DigitalCredentialCreationOptions
* @typedef {import('../dc-types').SendMessageData} SendMessageData
*/
/**
- * @param {protocol | protocol[]} [requestsToUse=["default"]]
- * @param {CredentialMediationRequirement} [mediation="required"]
- * @returns {CredentialRequestOptions}
+ * Internal helper to build the request array from validated input.
+ * Assumes requestsInputArray is a non-empty array of strings.
+ * @private
+ * @param {string[]} requestsInputArray - An array of request type strings.
+ * @param {string} mediation - The mediation requirement.
+ * @param {object} requestMapping - The specific mapping object for the operation type.
+ * @returns {{ digital: { requests: any[] }, mediation: string }} - The final options structure.
+ * @throws {Error} If an unknown request type string is encountered within the array.
*/
-export function makeGetOptions(requestsToUse, mediation = "required") {
- if (typeof requestsToUse === "string") {
- if (requestsToUse === "default" || requestsToUse === "openid4vp") {
- return makeGetOptions([requestsToUse], mediation);
+function _makeOptionsInternal(requestsInputArray, mediation, requestMapping) {
+ const requests = [];
+ for (const request of requestsInputArray) {
+ const factoryFunction = requestMapping[request];
+ if (factoryFunction) {
+ requests.push(factoryFunction()); // Call the mapped function
+ } else {
+ // This error means a string *within the array* was unknown
+ throw new Error(`Unknown request type within array: ${request}`);
}
}
- if (!Array.isArray(requestsToUse) || !requestsToUse?.length) {
- return { digital: { requests: requestsToUse }, mediation };
+ return { digital: { requests }, mediation };
+}
+
+const allMappings = {
+ get: {
+ "openid4vp": () => makeOID4VPDict(),
+ "default": () => makeDigitalCredentialGetRequest(undefined, undefined),
+ },
+ create: {
+ "openid4vci": () => makeOID4VCIDict(),
+ "default": () => makeDigitalCredentialCreateRequest(),
+ },
+};
+
+/**
+ * Internal unified function to handle option creation logic.
+ * Routes calls from specific public functions.
+ * @private
+ * @param {'get' | 'create'} type - The type of operation.
+ * @param {string | string[]} [requestsToUse] - Raw input for request types from public function.
+ * @param {string} mediation - Mediation requirement (default handled by public function).
+ * @returns {{ digital: { requests: any[] }, mediation: string }}
+ * @throws {Error} If type is invalid internally, or input strings are invalid.
+ */
+function _makeOptionsUnified(type, requestsToUse, mediation) {
+ // 1. Get mapping (Type validation primarily happens via caller)
+ const mapping = allMappings[type];
+ // Added safety check, though public functions should prevent this.
+ if (!mapping) {
+ throw new Error(`Internal error: Invalid options type specified: ${type}`);
}
- const requests = [];
- for (const request of requestsToUse) {
- switch (request) {
- case "openid4vp":
- requests.push(makeOID4VPDict());
- break;
- case "default":
- requests.push(makeDigitalCredentialRequest(undefined, undefined));
- break;
- default:
- throw new Error(`Unknown request type: ${request}`);
+
+ // 2. Handle default for requestsToUse
+ const actualRequestsToUse = requestsToUse === undefined ? ["default"] : requestsToUse;
+
+ // 3. Handle single string input
+ if (typeof actualRequestsToUse === 'string') {
+ if (mapping[actualRequestsToUse]) {
+ // Valid single string: Pass as array to the core array helper
+ return _makeOptionsInternal([actualRequestsToUse], mediation, mapping);
+ } else {
+ // Invalid single string for this type
+ throw new Error(`Unknown request type string '${actualRequestsToUse}' provided for operation type '${type}'`);
}
}
- return { digital: { requests }, mediation };
+
+ // 4. Handle array input
+ if (Array.isArray(actualRequestsToUse)) {
+ if (actualRequestsToUse.length === 0) {
+ // Handle empty array explicitly
+ return { digital: { requests: [] }, mediation };
+ }
+ // Pass valid non-empty array to the core array helper
+ return _makeOptionsInternal(actualRequestsToUse, mediation, mapping);
+ }
+
+ // 5. Handle invalid input types (neither string nor array)
+ return { digital: { requests: [] }, mediation };
}
+
+/**
+ * Creates options for getting credentials.
+ * @export
+ * @param {string | string[]} [requestsToUse] - Request types ('default', 'openid4vp', or an array). Defaults to ['default'].
+ * @param {string} [mediation="required"] - Credential mediation requirement ("required", "optional", "silent").
+ * @returns {{ digital: { requests: any[] }, mediation: string }}
+ */
+export function makeGetOptions(requestsToUse, mediation = "required") {
+ // Pass type 'get', the user's input, and the final mediation value
+ return _makeOptionsUnified('get', requestsToUse, mediation);
+}
+
+/**
+ * Creates options for creating credentials.
+ * @export
+ * @param {string | string[]} [requestsToUse] - Request types ('default', 'openid4vci', or an array). Defaults to ['default'].
+ * @param {string} [mediation="required"] - Credential mediation requirement ("required", "optional", "silent").
+ * @returns {{ digital: { requests: any[] }, mediation: string }} // Adjust inner array type if known
+ */
+export function makeCreateOptions(requestsToUse, mediation = "required") {
+ // Pass type 'create', the user's input, and the final mediation value
+ return _makeOptionsUnified('create', requestsToUse, mediation);
+}
+
/**
*
* @param {string} protocol
* @param {object} data
- * @returns {DigitalCredentialRequest}
+ * @returns {DigitalCredentialGetRequest}
*/
-function makeDigitalCredentialRequest(protocol = "protocol", data = {}) {
+function makeDigitalCredentialGetRequest(protocol = "protocol", data = {}) {
return {
protocol,
data,
@@ -53,15 +133,39 @@ function makeDigitalCredentialRequest(protocol = "protocol", data = {}) {
/**
* Representation of an OpenID4VP request.
*
- * @returns {DigitalCredentialRequest}
+ * @returns {DigitalCredentialGetRequest}
**/
function makeOID4VPDict() {
- return makeDigitalCredentialRequest("openid4vp", {
+ return makeDigitalCredentialGetRequest("openid4vp", {
// Canonical example of an OpenID4VP request coming soon.
});
}
/**
+ *
+ * @param {string} protocol
+ * @param {object} data
+ * @returns {DigitalCredentialCreateRequest}
+ */
+function makeDigitalCredentialCreateRequest(protocol = "protocol", data = {}) {
+ return {
+ protocol,
+ data,
+ };
+}
+
+/**
+ * Representation of an OpenID4VCI request.
+ *
+ * @returns {DigitalCredentialCreateRequest}
+ **/
+function makeOID4VCIDict() {
+ return makeDigitalCredentialCreateRequest("openid4vci", {
+ // Canonical example of an OpenID4VCI request coming soon.
+ });
+}
+
+/**
* Sends a message to an iframe and return the response.
*
* @param {HTMLIFrameElement} iframe - The iframe element to send the message to.
diff --git a/tests/wpt/tests/digital-credentials/get-user-activation.https.html b/tests/wpt/tests/digital-credentials/user-activation.https.html
index fbf2099dad3..facaf7bddbb 100644
--- a/tests/wpt/tests/digital-credentials/get-user-activation.https.html
+++ b/tests/wpt/tests/digital-credentials/user-activation.https.html
@@ -7,7 +7,7 @@
<script src="support/helper.js" type="module"></script>
<body></body>
<script type="module">
- import { makeGetOptions } from "./support/helper.js";
+ import { makeGetOptions, makeCreateOptions } from "./support/helper.js";
promise_test(async (t) => {
assert_false(
@@ -35,4 +35,31 @@
"User activation should be consumed after navigator.credentials.get()."
);
}, "navigator.credentials.get() consumes user activation.");
+
+ promise_test(async (t) => {
+ assert_false(
+ navigator.userActivation.isActive,
+ "User activation should not be active"
+ );
+ const options = makeCreateOptions([]);
+ await promise_rejects_dom(
+ t,
+ "NotAllowedError",
+ navigator.credentials.create(options)
+ );
+ }, "navigator.credentials.create() calling the API without user activation should reject with NotAllowedError.");
+
+ promise_test(async (t) => {
+ await test_driver.bless();
+ assert_true(
+ navigator.userActivation.isActive,
+ "User activation should be active after test_driver.bless()."
+ );
+ const options = makeCreateOptions([]);
+ await promise_rejects_js(t, TypeError, navigator.credentials.create(options));
+ assert_false(
+ navigator.userActivation.isActive,
+ "User activation should be consumed after navigator.credentials.create()."
+ );
+ }, "navigator.credentials.create() consumes user activation.");
</script>
diff --git a/tests/wpt/tests/event-timing/interactionid-orphan-pointerup.html b/tests/wpt/tests/event-timing/interactionid-orphan-pointerup.html
index 9c4a0ecf584..e08142f11bc 100644
--- a/tests/wpt/tests/event-timing/interactionid-orphan-pointerup.html
+++ b/tests/wpt/tests/event-timing/interactionid-orphan-pointerup.html
@@ -13,7 +13,8 @@
<script>
let observedEntries = [];
const map = new Map();
- const events = ['pointerup'];
+ // keydown is being sent right after a pointerup to see if pointerup is present.
+ const events = ['pointerup', 'keydown'];
promise_test(async t => {
assert_implements(window.PerformanceEventTiming, 'Event Timing is not supported.');
@@ -23,9 +24,13 @@
const observerPromise = createPerformanceObserverPromise(['event'], callback, readyToResolve);
await interactAndObserve('orphan-pointerup', document.getElementById('testButtonId'), observerPromise);
- assert_equals(map.get('pointerup'), 0, 'Should have a trivial interactionId for orphan pointerup event.');
+
+ // This test passes when either:
+ // - There is no orphan pointerup triggered by the browser.
+ // - The orphan pointerup doesn't have an interactionId.
+ assert_true(!map.has('pointerup') || map.get('pointerup') === 0, 'Should either have no triggered orphan pointerup event or have a trivial interactionId for orphan pointerup event.');
}, "Event Timing: Orphan pointerup should not be measured as an interaction.");
</script>
-</html> \ No newline at end of file
+</html>
diff --git a/tests/wpt/tests/event-timing/resources/event-timing-test-utils.js b/tests/wpt/tests/event-timing/resources/event-timing-test-utils.js
index 7bd9782000f..59c78ebf39c 100644
--- a/tests/wpt/tests/event-timing/resources/event-timing-test-utils.js
+++ b/tests/wpt/tests/event-timing/resources/event-timing-test-utils.js
@@ -357,13 +357,20 @@ async function pointerdown(target) {
.send();
}
-async function pointerup(target) {
+async function orphanPointerup(target) {
const actions = new test_driver.Actions();
- return actions.addPointer("mousePointer", "mouse")
+ await actions.addPointer("mousePointer", "mouse")
.pointerMove(0, 0, { origin: target })
.pointerUp()
.send();
+
+ // Orphan pointerup doesn't get triggered in some browsers. Sending a
+ // non-pointer related event to make sure that at least an event gets handled.
+ // If a browsers sends an orphan pointerup, it will always be before the
+ // keydown, so the test will correctly handle it.
+ await pressKey(target, 'a');
}
+
async function auxPointerdown(target) {
const actions = new test_driver.Actions();
return actions.addPointer("mousePointer", "mouse")
@@ -525,8 +532,8 @@ async function interactAndObserve(interactionType, target, observerPromise, key
break;
}
case 'orphan-pointerup': {
- addListeners(target, ['pointerup']);
- interactionPromise = pointerup(target);
+ addListeners(target, ['pointerup', 'keydown']);
+ interactionPromise = orphanPointerup(target);
break;
}
case 'space-key-simulated-click': {
diff --git a/tests/wpt/tests/fonts/math/css-units.woff b/tests/wpt/tests/fonts/math/css-units.woff
new file mode 100644
index 00000000000..0957a2fc973
--- /dev/null
+++ b/tests/wpt/tests/fonts/math/css-units.woff
Binary files differ
diff --git a/tests/wpt/tests/html/interaction/focus/tab-table-caption.html b/tests/wpt/tests/html/interaction/focus/tab-table-caption.html
new file mode 100644
index 00000000000..a26c8f0e7ed
--- /dev/null
+++ b/tests/wpt/tests/html/interaction/focus/tab-table-caption.html
@@ -0,0 +1,57 @@
+<!doctype html>
+<meta charset="utf-8">
+<meta name="variant" content="?caption-side=top">
+<meta name="variant" content="?caption-side=bottom">
+<title>Tab navigation around table with caption</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 src="/resources/testdriver-actions.js"></script>
+<script>
+ "use strict";
+
+ const searchParams = new URLSearchParams(document.location.search);
+ const captionSide = searchParams.get("caption-side");
+
+ addEventListener("DOMContentLoaded", () => {
+ document.querySelector("table").style.captionSide = captionSide;
+ const tabKey = "\uE004";
+ const shiftKey = "\uE008";
+ const firstTabbable = document.querySelector("body > span");
+ const lastTabbable = document.querySelector("table ~ span");
+ const tabbableInCaption = document.querySelector("caption > span");
+ const tabbableInCell = document.querySelector("td > span");
+ for (const data of [
+ {init: firstTabbable, prev: null, next: tabbableInCell },
+ {init: tabbableInCaption, prev: tabbableInCell, next: lastTabbable },
+ {init: tabbableInCell, prev: firstTabbable, next: tabbableInCaption },
+ {init: lastTabbable, prev: tabbableInCaption, next: null},
+ ]) {
+ if (data.prev) {
+ promise_test(async () => {
+ data.init.focus();
+ await new test_driver.Actions().keyDown(shiftKey).keyDown(tabKey).keyUp(tabKey).keyUp(shiftKey).send();
+ assert_equals(document.activeElement, data.prev);
+ }, `Shift+Tab on ${data.init.outerHTML} should move focus to ${data.prev.outerHTML}`);
+ }
+ if (data.next) {
+ promise_test(async () => {
+ data.init.focus();
+ await new test_driver.Actions().keyDown(tabKey).keyUp(tabKey).send();
+ assert_equals(document.activeElement, data.next);
+ }, `Tab on ${data.init.outerHTML} should move focus to ${data.next.outerHTML}`);
+ }
+ }
+ });
+</script>
+<span tabindex="0">First tabbable span</span>
+<table>
+ <tbody>
+ <tr>
+ <td><span tabindex="0">Tabbable in cell<span></td>
+ </tr>
+ </tbody>
+ <caption><span tabindex="0">Tabbable in caption</span></caption>
+</table>
+<span tabindex="0">Last tabbable span</span>
diff --git a/tests/wpt/tests/html/semantics/forms/the-select-element/customizable-select-in-page/customizable-select-in-page-keyboard-behavior.tentative.html b/tests/wpt/tests/html/semantics/forms/the-select-element/customizable-select-in-page/customizable-select-in-page-keyboard-behavior.tentative.html
index 24e6e39ea48..7040105c096 100644
--- a/tests/wpt/tests/html/semantics/forms/the-select-element/customizable-select-in-page/customizable-select-in-page-keyboard-behavior.tentative.html
+++ b/tests/wpt/tests/html/semantics/forms/the-select-element/customizable-select-in-page/customizable-select-in-page-keyboard-behavior.tentative.html
@@ -27,6 +27,15 @@ select {
<option class=disabled disabled>disabled</option>
</select>
+<button id=aftersize>button after size=4</button>
+
+<select multiple disabled>
+ <option>one</option>
+ <option>two</option>
+</select>
+
+<button id=afterdisabled>button after select disabled</button>
+
<script>
const tabKey = '\uE004';
const enterKey = '\uE007';
@@ -111,6 +120,10 @@ promise_test(async () => {
'One option should be selected after arrow up.');
assert_equals(select.selectedOptions[0], optionOne,
'First option should stay selected after arrow up.');
+
+ await pressKey(tabKey);
+ assert_equals(document.activeElement, beforesize,
+ 'Pressing tab key should focus the next element after <select>.');
}, 'Keyboard behavior for base appearance <select multiple>');
promise_test(async () => {
@@ -174,6 +187,14 @@ promise_test(async () => {
'First option should be focused after arrow up.');
assert_equals(select.selectedOptions.length, 0,
'No options should be selected after arrow up.');
+
+ await pressKey(tabKey);
+ assert_equals(document.activeElement, aftersize,
+ 'Pressing tab should focus the next element after <select>.');
+
+ await pressKey(tabKey);
+ assert_equals(document.activeElement, afterdisabled,
+ 'Pressing tab key should skip over <select disabled>.');
}, 'Keyboard behavior for base appearance <select size=4>');
promise_test(async () => {
diff --git a/tests/wpt/tests/html/semantics/forms/the-select-element/customizable-select/select-parsing.tentative.html b/tests/wpt/tests/html/semantics/forms/the-select-element/customizable-select/select-parsing.tentative.html
index cc6596b42fe..0c6972bcab5 100644
--- a/tests/wpt/tests/html/semantics/forms/the-select-element/customizable-select/select-parsing.tentative.html
+++ b/tests/wpt/tests/html/semantics/forms/the-select-element/customizable-select/select-parsing.tentative.html
@@ -96,6 +96,14 @@
<textarea></textarea>
</select>
+<select class=test
+ data-description='Input tags should parse inside select if nested in another tag'
+ data-expect='<div><input></div>'>
+ <div>
+ <input>
+ </div>
+</select>
+
<div id=afterlast>
keep this div after the last test case
</div>
diff --git a/tests/wpt/tests/html/semantics/interactive-elements/the-dialog-element/dialog-closedby-bounds-clicking.html b/tests/wpt/tests/html/semantics/interactive-elements/the-dialog-element/dialog-closedby-bounds-clicking.html
new file mode 100644
index 00000000000..584d4b30644
--- /dev/null
+++ b/tests/wpt/tests/html/semantics/interactive-elements/the-dialog-element/dialog-closedby-bounds-clicking.html
@@ -0,0 +1,100 @@
+<!DOCTYPE html>
+<meta charset="utf-8">
+<meta name="timeout" content="long">
+<link rel="author" href="mailto:wpt@keithcirkel.co.uk">
+<link rel=help href="https://html.spec.whatwg.org/multipage/interactive-elements.html#dialog-light-dismiss">
+<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>
+
+<dialog id="dialog">
+ <div id="box"></div>
+</dialog>
+
+<style>
+ dialog { inset: 0 auto auto 0; width: 100px; height: 100px; overflow: visible; }
+ #box { height:200px; width:200px; margin:20px; background:blue; }
+</style>
+
+<script>
+for (const method of ['show', 'showModal']) {
+ promise_test(async (t) => {
+ dialog.setAttribute('closedby','any');
+ dialog[method]();
+ const actions = new test_driver.Actions();
+ await actions.pointerMove(1, 1, {origin:"viewport"})
+ .pointerDown()
+ .pointerUp()
+ .send();
+ assert_true(dialog.open, "Dialog should be open after clicking 1px-1px");
+ },`Dialog ${method} will not light dismiss if clicked inside of the dialog bounds`);
+
+ promise_test(async (t) => {
+ dialog.setAttribute('closedby','any');
+ dialog[method]();
+ const actions = new test_driver.Actions();
+ await actions.pointerMove(99, 99, {origin:"viewport"})
+ .pointerDown()
+ .pointerUp()
+ .send();
+ assert_true(dialog.open, "Dialog should be open after clicking 99px-99px");
+ },`Dialog ${method} will not light dismiss if clicked inside of the dialog bounds (bottom right)`);
+
+ promise_test(async (t) => {
+ dialog.setAttribute('closedby','any');
+ dialog[method]();
+ const actions = new test_driver.Actions();
+ await actions.pointerMove(150, 150, {origin:"viewport"})
+ .pointerDown()
+ .pointerUp()
+ .send();
+ assert_true(dialog.open, "Dialog should be open after clicking 150px-150px");
+ },`Dialog ${method} will not light dismiss if clicked inside the overflowing div bounds (center)`);
+
+ promise_test(async (t) => {
+ dialog.setAttribute('closedby','any');
+ dialog[method]();
+ const actions = new test_driver.Actions();
+ await actions.pointerMove(199, 199, {origin:"viewport"})
+ .pointerDown()
+ .pointerUp()
+ .send();
+ assert_true(dialog.open, "Dialog should be open after clicking 199px-199px");
+ },`Dialog ${method} will not light dismiss if clicked inside the overflowing div bounds (bottom right)`);
+
+ promise_test(async (t) => {
+ dialog.setAttribute('closedby','any');
+ dialog[method]();
+ const actions = new test_driver.Actions();
+ await actions.pointerMove(250, 250, {origin:"viewport"})
+ .pointerDown()
+ .pointerUp()
+ .send();
+ assert_false(dialog.open, "Dialog should be closed after clicking 250px-250px");
+ },`Dialog ${method} light dismisses when clicked outside of the bounds of both the dialog and the div`);
+
+ promise_test(async (t) => {
+ dialog.setAttribute('closedby','any');
+ dialog[method]();
+ const actions = new test_driver.Actions();
+ await actions.pointerMove(150, 1, {origin:"viewport"})
+ .pointerDown()
+ .pointerUp()
+ .send();
+ assert_false(dialog.open, "Dialog should be closed after clicking 150px-1px");
+ },`Dialog ${method} light dismisses when clicked outside of the bounds of the dialog - where the Y direction is in-line with the div still`);
+
+ promise_test(async (t) => {
+ dialog.setAttribute('closedby','any');
+ dialog[method]();
+ const actions = new test_driver.Actions();
+ await actions.pointerMove(1, 150, {origin:"viewport"})
+ .pointerDown()
+ .pointerUp()
+ .send();
+ assert_false(dialog.open, "Dialog should be closed after clicking 1px-150px");
+ },`Dialog ${method} light dismisses when clicked outside of the bounds of the dialog - where the X direction is in-line with the div still`);
+}
+</script>
diff --git a/tests/wpt/tests/html/semantics/interactive-elements/the-dialog-element/dialog-closedby-corner-cases.html b/tests/wpt/tests/html/semantics/interactive-elements/the-dialog-element/dialog-closedby-corner-cases.html
index e25b9533b90..06a90844154 100644
--- a/tests/wpt/tests/html/semantics/interactive-elements/the-dialog-element/dialog-closedby-corner-cases.html
+++ b/tests/wpt/tests/html/semantics/interactive-elements/the-dialog-element/dialog-closedby-corner-cases.html
@@ -14,7 +14,7 @@
<script>
const dialog = document.getElementById('dialog');
- async function openDialog(openMethod) {
+ function openDialog(openMethod) {
dialog.close();
if (!dialog.open) {
assert_false(dialog.matches(':open'),'Should be closed to start');
@@ -32,7 +32,6 @@
assert_unreached('Invalid open method');
}
}
- await waitForRender();
assert_true(dialog.open,'Should be open now');
assert_true(dialog.matches(':open'),'Should be open now (pseudo)');
}
@@ -122,18 +121,25 @@
const expectResponds = changeMethod.setup(openMethod,controller.signal) ?? true;
// Open the dialog
- await openDialog(openMethod);
+ openDialog(openMethod);
// Try hitting ESC
const ESC = '\uE00C';
+ const close_fired = new Promise(resolve => {
+ dialog.addEventListener('close', resolve, { once: true })
+ });
await test_driver.send_keys(document.documentElement,ESC);
- await waitForRender();
+ if (expectResponds) {
+ await close_fired;
+ } else {
+ await waitForRender();
+ }
const respondsToEsc = !dialog.open;
assert_equals(!dialog.matches(':open'),respondsToEsc,':open should match dialog.open');
dialog.close();
// Try clicking outside
- await openDialog(openMethod);
+ openDialog(openMethod);
await clickOn(outside);
const respondsToLightDismiss = !dialog.open;
assert_equals(!dialog.matches(':open'),respondsToLightDismiss,':open should match dialog.open');
diff --git a/tests/wpt/tests/html/semantics/interactive-elements/the-dialog-element/dialog-closedby.html b/tests/wpt/tests/html/semantics/interactive-elements/the-dialog-element/dialog-closedby.html
index 50d600219d2..b67bc80765a 100644
--- a/tests/wpt/tests/html/semantics/interactive-elements/the-dialog-element/dialog-closedby.html
+++ b/tests/wpt/tests/html/semantics/interactive-elements/the-dialog-element/dialog-closedby.html
@@ -29,7 +29,7 @@
<dialog data-behavior="auto"></dialog>
<script>
- async function openDialog(dialog,openMethod) {
+ function openDialog(dialog,openMethod) {
assert_false(dialog.open,'Should be closed to start');
assert_equals(dialog.matches(':open'),dialog.open,':open should match .open');
switch (openMethod) {
@@ -45,7 +45,6 @@
default:
assert_unreached('Invalid open method');
}
- await waitForRender();
assert_true(dialog.open,'Should be open now');
assert_equals(dialog.matches(':open'),dialog.open,':open should match .open');
}
@@ -99,22 +98,30 @@
assert_false(dialog.open,'setup');
assert_false(dialog.matches(':open'));
t.add_cleanup(() => dialog.close());
+ let expectations = getDefaultExpectations(dialog.dataset.behavior, openMethod);
// Open the dialog
- await openDialog(dialog,openMethod);
+ openDialog(dialog,openMethod);
assert_equals(dialog.matches(':modal'),openMethod === 'modal',':modal incorrect');
const closedByReflectionWhileOpen = dialog.closedBy;
// Try hitting ESC
const ESC = '\uE00C';
+ const close_fired = new Promise(resolve => {
+ dialog.addEventListener('close', resolve, { once: true })
+ });
await test_driver.send_keys(document.documentElement,ESC);
- await waitForRender();
+ if (expectations.respondsToEsc) {
+ await close_fired;
+ } else {
+ await waitForRender();
+ }
const respondsToEsc = !dialog.open;
assert_equals(!dialog.matches(':open'),respondsToEsc,':open should match dialog.open');
dialog.close();
// Try clicking outside
- await openDialog(dialog,openMethod);
+ openDialog(dialog,openMethod);
assert_equals(dialog.matches(':modal'),openMethod === 'modal',':modal incorrect');
await clickOn(outside);
const respondsToLightDismiss = !dialog.open;
@@ -122,7 +129,6 @@
dialog.close();
// See if expectations match
- let expectations = getDefaultExpectations(dialog.dataset.behavior, openMethod);
assert_equals(respondsToEsc,expectations.respondsToEsc,`Dialog ${expectations.respondsToEsc ? "should" : "should NOT"} respond to ESC`);
assert_equals(respondsToLightDismiss,expectations.respondsToLightDismiss,`Dialog ${expectations.respondsToLightDismiss ? "should" : "should NOT"} respond to light dismiss`);
assert_equals(closedByReflectionWhileOpen,expectations.expectedReflectionWhileOpen,'Reflection should be limited to known values (open)');
diff --git a/tests/wpt/tests/mathml/relations/css-styling/lengths-1-ref.html b/tests/wpt/tests/mathml/relations/css-styling/lengths-1-ref.html
index 9fca6f49632..74c1397ce62 100644
--- a/tests/wpt/tests/mathml/relations/css-styling/lengths-1-ref.html
+++ b/tests/wpt/tests/mathml/relations/css-styling/lengths-1-ref.html
@@ -3,11 +3,16 @@
<head>
<meta charset="utf-8"/>
<title>MathML lengths (reference)</title>
+<style>
+ html {
+ line-height: 17px;
+ }
+</style>
</head>
<body>
<p>Test passes if there is a green square and no red.</p>
<div>
- <div id="red" style="position: absolute; width: 200px; height: 200px; background: green;">
+ <div id="red" style="position: absolute; width: 340px; height: 340px; background: green;">
</div>
</div>
</body>
diff --git a/tests/wpt/tests/mathml/relations/css-styling/lengths-1.html b/tests/wpt/tests/mathml/relations/css-styling/lengths-1.html
index 896f08d1119..224bedc1efc 100644
--- a/tests/wpt/tests/mathml/relations/css-styling/lengths-1.html
+++ b/tests/wpt/tests/mathml/relations/css-styling/lengths-1.html
@@ -7,12 +7,13 @@
<link rel="help" href="https://w3c.github.io/mathml-core/#types-for-mathml-attribute-values">
<link rel="help" href="https://w3c.github.io/mathml-core/#legacy-mathml-style-attributes">
<link rel="help" href="https://w3c.github.io/mathml-core/#space-mspace">
+<link rel="help" href="https://www.w3.org/TR/css-values-4/#relative-lengths">
<link rel="match" href="lengths-1-ref.html"/>
<meta name="assert" content="Verify whether the different units are accepted for MathML lengths.">
<style>
@font-face {
font-family: TestFont;
- src: url("/fonts/math/xheight500.woff");
+ src: url("/fonts/math/css-units.woff");
}
span, math {
font-family: TestFont;
@@ -29,12 +30,18 @@
#green > span {
background: green;
}
+ /* For lh and rlh. */
+ html {
+ line-height: 17px;
+ }
</style>
</head>
<body>
<p>Test passes if there is a green square and no red.</p>
+
+ <!-- Omitted units: vw, vh, vi, vb, vmin, vmax -->
<div>
- <div id="red" style="position: absolute; width: 200px; height: 200px; background: green;">
+ <div id="red" style="position: absolute; width: 340px; height: 340px; background: green;">
<!-- px -->
<span style="top: 0px"><math><mspace width="200px"/></math></span>
<span style="top: 10px; width: 200px"></span>
@@ -71,12 +78,40 @@
<span style="top: 160px"><math><mstyle mathsize="2000%"><mspace width="1em"/></mstyle></math></span>
<span style="top: 170px; width: 200px"></span>
+ <!-- q -->
+ <span style="top: 180px"><math><mspace width="203.2q"/></math></span>
+ <span style="top: 190px; width: 192px"></span>
+
+ <!-- ch -->
+ <span style="top: 200px"><math><mspace width="20ch"/></math></span>
+ <span style="top: 210px; width: 20ch"></span>
+
+ <!-- cap -->
+ <span style="top: 220px"><math><mspace width="30cap"/></math></span>
+ <span style="top: 230px; width: 30cap"></span>
+
+ <!-- ic -->
+ <span style="top: 240px"><math><mspace width="20ic"/></math></span>
+ <span style="top: 250px; width: 200px"></span>
+
+ <!-- rem -->
+ <span style="top: 260px"><math><mspace width="10rem"/></math></span>
+ <span style="top: 270px; width: 160px"></span>
+
+ <!-- lh -->
+ <span style="top: 280px"><math><mspace width="13lh" style="line-height: 15px;"/></math></span>
+ <span style="top: 290px; width: 195px"></span>
+
+ <!-- rlh -->
+ <span style="top: 300px"><math><mspace width="11rlh"/></math></span>
+ <span style="top: 310px; width: 187px"></span>
+
<!-- unitless nonzero values should be ignored -->
- <span style="top: 180px"><math><mstyle mathsize="20.0"><mspace width="1em"/></mstyle></math></span>
- <span style="top: 190px; width: 10px"></span>
+ <span style="top: 320px"><math><mstyle mathsize="20.0"><mspace width="1em"/></mstyle></math></span>
+ <span style="top: 330px; width: 10px"></span>
</div>
- <div id="green" style="position: absolute; width: 200px; height: 200px;">
+ <div id="green" style="position: absolute; width: 340px; height: 340px;">
<!-- px -->
<span style="top: 10px"><math><mspace width="200px"/></math></span>
<span style="top: 0px; width: 200px"></span>
@@ -113,9 +148,37 @@
<span style="top: 170px"><math><mstyle mathsize="2000%"><mspace width="1em"/></mstyle></math></span>
<span style="top: 160px; width: 200px"></span>
+ <!-- q -->
+ <span style="top: 190px"><math><mspace width="203.2q"/></math></span>
+ <span style="top: 180px; width: 192px"></span>
+
+ <!-- ch -->
+ <span style="top: 210px"><math><mspace width="20ch"/></math></span>
+ <span style="top: 200px; width: 20ch"></span>
+
+ <!-- cap -->
+ <span style="top: 230px"><math><mspace width="30cap"/></math></span>
+ <span style="top: 220px; width: 30cap"></span>
+
+ <!-- ic -->
+ <span style="top: 250px"><math><mspace width="20ic"/></math></span>
+ <span style="top: 240px; width: 200px"></span>
+
+ <!-- rem -->
+ <span style="top: 270px"><math><mspace width="10rem"/></math></span>
+ <span style="top: 260px; width: 160px"></span>
+
+ <!-- lh -->
+ <span style="top: 290px"><math><mspace width="13lh" style="line-height: 15px;"/></math></span>
+ <span style="top: 280px; width: 195px"></span>
+
+ <!-- rlh -->
+ <span style="top: 310px"><math><mspace width="11rlh"/></math></span>
+ <span style="top: 300px; width: 187px"></span>
+
<!-- unitless nonzero values should be ignored -->
- <span style="top: 190px"><math><mstyle mathsize="20.0"><mspace width="1em"/></mstyle></math></span>
- <span style="top: 180px; width: 10px"></span>
+ <span style="top: 330px"><math><mstyle mathsize="20.0"><mspace width="1em"/></mstyle></math></span>
+ <span style="top: 320px; width: 10px"></span>
</div>
</div>
</body>
diff --git a/tests/wpt/tests/mathml/relations/css-styling/lengths-2.html b/tests/wpt/tests/mathml/relations/css-styling/lengths-2.html
index 942611a8dad..af5cae13688 100644
--- a/tests/wpt/tests/mathml/relations/css-styling/lengths-2.html
+++ b/tests/wpt/tests/mathml/relations/css-styling/lengths-2.html
@@ -7,6 +7,7 @@
<link rel="help" href="https://w3c.github.io/mathml-core/#types-for-mathml-attribute-values">
<link rel="help" href="https://w3c.github.io/mathml-core/#legacy-mathml-style-attributes">
<link rel="help" href="https://w3c.github.io/mathml-core/#space-mspace">
+<link rel="help" href="https://www.w3.org/TR/css-values-4/#relative-lengths">
<meta name="assert" content="Verify various cases of the MathML length syntax.">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
@@ -15,14 +16,20 @@
<style>
@font-face {
font-family: TestFont;
- src: url("/fonts/math/xheight500.woff");
+ src: url("/fonts/math/css-units.woff");
}
math {
font-family: TestFont;
font-size: 10px;
}
+ /* For rlh. */
+ html {
+ line-height: 17px;
+ }
</style>
<script>
+ // Omitted units: vi, vb
+
var epsilon = .5;
function getBox(aId) {
@@ -44,6 +51,17 @@
assert_equals(getBox("unitPercentage").width, 60, "%");
assert_equals(getBox("unitPt").width, 96, "pt");
assert_equals(getBox("unitPx").width, 123, "px");
+ assert_equals(getBox("unitQ").width, 192, "q");
+ assert_equals(getBox("unitCh").width, 100, "ch");
+ assert_equals(getBox("unitCap").width, 140, "cap");
+ assert_equals(getBox("unitIc").width, 90, "ic");
+ assert_approx_equals(getBox("unitVw").width, window.innerWidth*0.35, epsilon, "vw");
+ assert_approx_equals(getBox("unitVh").width, window.innerHeight*0.54, epsilon, "vh");
+ assert_approx_equals(getBox("unitVmin").width, Math.min(window.innerWidth, window.innerHeight)*0.27, epsilon, "vmin");
+ assert_approx_equals(getBox("unitVmax").width, Math.max(window.innerWidth, window.innerHeight)*0.34, epsilon, "vmax");
+ assert_equals(getBox("unitRem").width, 128, "rem");
+ assert_equals(getBox("unitLh").width, 60, "lh");
+ assert_equals(getBox("unitRlh").width, 102, "rlh");
}, "Units");
test(function() {
@@ -57,6 +75,17 @@
assert_equals(getBox("spacePercentage").width, 60, "%");
assert_equals(getBox("spacePt").width, 96, "pt");
assert_equals(getBox("spacePx").width, 123, "px");
+ assert_equals(getBox("spaceQ").width, 192, "q");
+ assert_equals(getBox("spaceCh").width, 100, "ch");
+ assert_equals(getBox("spaceCap").width, 140, "cap");
+ assert_equals(getBox("spaceIc").width, 90, "ic");
+ assert_approx_equals(getBox("spaceVw").width, window.innerWidth*0.35, epsilon, "vw");
+ assert_approx_equals(getBox("spaceVh").width, window.innerHeight*0.54, epsilon, "vh");
+ assert_approx_equals(getBox("spaceVmin").width, Math.min(window.innerWidth, window.innerHeight)*0.27, epsilon, "vmin");
+ assert_approx_equals(getBox("spaceVmax").width, Math.max(window.innerWidth, window.innerHeight)*0.34, epsilon, "vmax");
+ assert_equals(getBox("spaceRem").width, 128, "rem");
+ assert_equals(getBox("spaceLh").width, 60, "lh");
+ assert_equals(getBox("spaceRlh").width, 102, "rlh");
}, "Trimming of space");
test(function() {
@@ -139,6 +168,19 @@
<mstyle mathsize="200%"><mspace id="unitPercentage" width="3em"/></mstyle>
<mspace id="unitPt" width="72pt"/>
<mspace id="unitPx" width="123px"/>
+ <mspace id="unitQ" width="203.2q"/>
+ <mspace id="unitCh" width="10ch"/>
+ <mspace id="unitCap" width="14ch"/>
+ <mspace id="unitIc" width="9ic"/>
+ <mspace id="unitVw" width="35vw"/>
+ <mspace id="unitVh" width="54vh"/>
+ <mspace id="unitVi" width="11vi"/>
+ <mspace id="unitVb" width="4vb"/>
+ <mspace id="unitVmin" width="27vmin"/>
+ <mspace id="unitVmax" width="34vmax"/>
+ <mspace id="unitRem" width="8rem" style="font-size: 3px;"/>
+ <mspace id="unitLh" width="5lh" style="line-height: 12px;"/>
+ <mspace id="unitRlh" width="6rlh" style="line-height: 12px;"/>
<mstyle mathsize="5"><mspace id="unitNone" width="3em"/></mstyle>
</math>
</p>
@@ -153,6 +195,19 @@
<mstyle mathsize="200%"><mspace id="spacePercentage" width="&#x20;&#x9;&#xA;&#xD;&#x20;&#x9;&#xA;&#xD;3em&#x20;&#x9;&#xA;&#xD;&#x20;&#x9;&#xA;&#xD;"/></mstyle>
<mspace id="spacePt" width="&#x20;&#x9;&#xA;&#xD;&#x20;&#x9;&#xA;&#xD;72pt&#x20;&#x9;&#xA;&#xD;&#x20;&#x9;&#xA;&#xD;"/>
<mspace id="spacePx" width="&#x20;&#x9;&#xA;&#xD;&#x20;&#x9;&#xA;&#xD;123px&#x20;&#x9;&#xA;&#xD;&#x20;&#x9;&#xA;&#xD;"/>
+ <mspace id="spaceQ" width="&#x20;&#x9;&#xA;&#xD;&#x20;&#x9;&#xA;&#xD;203.2q&#x20;&#x9;&#xA;&#xD;&#x20;&#x9;&#xA;&#xD;"/>
+ <mspace id="spaceCh" width="&#x20;&#x9;&#xA;&#xD;&#x20;&#x9;&#xA;&#xD;10ch&#x20;&#x9;&#xA;&#xD;&#x20;&#x9;&#xA;&#xD;"/>
+ <mspace id="spaceCap" width="&#x20;&#x9;&#xA;&#xD;&#x20;&#x9;&#xA;&#xD;14ch&#x20;&#x9;&#xA;&#xD;&#x20;&#x9;&#xA;&#xD;"/>
+ <mspace id="spaceIc" width="&#x20;&#x9;&#xA;&#xD;&#x20;&#x9;&#xA;&#xD;9ic&#x20;&#x9;&#xA;&#xD;&#x20;&#x9;&#xA;&#xD;"/>
+ <mspace id="spaceVw" width="&#x20;&#x9;&#xA;&#xD;&#x20;&#x9;&#xA;&#xD;35vw&#x20;&#x9;&#xA;&#xD;&#x20;&#x9;&#xA;&#xD;"/>
+ <mspace id="spaceVh" width="&#x20;&#x9;&#xA;&#xD;&#x20;&#x9;&#xA;&#xD;54vh&#x20;&#x9;&#xA;&#xD;&#x20;&#x9;&#xA;&#xD;"/>
+ <mspace id="spaceVi" width="&#x20;&#x9;&#xA;&#xD;&#x20;&#x9;&#xA;&#xD;11vi&#x20;&#x9;&#xA;&#xD;&#x20;&#x9;&#xA;&#xD;"/>
+ <mspace id="spaceVb" width="&#x20;&#x9;&#xA;&#xD;&#x20;&#x9;&#xA;&#xD;4vb&#x20;&#x9;&#xA;&#xD;&#x20;&#x9;&#xA;&#xD;"/>
+ <mspace id="spaceVmin" width="&#x20;&#x9;&#xA;&#xD;&#x20;&#x9;&#xA;&#xD;27vmin&#x20;&#x9;&#xA;&#xD;&#x20;&#x9;&#xA;&#xD;"/>
+ <mspace id="spaceVmax" width="&#x20;&#x9;&#xA;&#xD;&#x20;&#x9;&#xA;&#xD;34vmax&#x20;&#x9;&#xA;&#xD;&#x20;&#x9;&#xA;&#xD;"/>
+ <mspace id="spaceRem" width="&#x20;&#x9;&#xA;&#xD;&#x20;&#x9;&#xA;&#xD;8rem&#x20;&#x9;&#xA;&#xD;&#x20;&#x9;&#xA;&#xD;" style="font-size: 3px;"/>
+ <mspace id="spaceLh" width="&#x20;&#x9;&#xA;&#xD;&#x20;&#x9;&#xA;&#xD;5lh&#x20;&#x9;&#xA;&#xD;&#x20;&#x9;&#xA;&#xD;" style="line-height: 12px;"/>
+ <mspace id="spaceRlh" width="&#x20;&#x9;&#xA;&#xD;&#x20;&#x9;&#xA;&#xD;6rlh&#x20;&#x9;&#xA;&#xD;&#x20;&#x9;&#xA;&#xD;" style="line-height: 12px;"/>
</math>
</p>
<p>
diff --git a/tests/wpt/tests/mathml/relations/css-styling/lengths-vi-vb-units.html b/tests/wpt/tests/mathml/relations/css-styling/lengths-vi-vb-units.html
new file mode 100644
index 00000000000..a01fd13b98f
--- /dev/null
+++ b/tests/wpt/tests/mathml/relations/css-styling/lengths-vi-vb-units.html
@@ -0,0 +1,50 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>MathML lengths (vi, vb)</title>
+<link rel="help" href="https://w3c.github.io/mathml-core/#css-styling">
+<link rel="help" href="https://w3c.github.io/mathml-core/#types-for-mathml-attribute-values">
+<link rel="help" href="https://www.w3.org/TR/css-values-4/#relative-lengths">
+<link rel="help" href="https://www.w3.org/TR/css-values-4/#viewport-relative-units">
+<meta name="assert" content="Verify that vi and vb correctly take this element's inline and block axes/writing mode into consideration in MathML.">
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="/mathml/support/feature-detection.js"></script>
+</head>
+<body>
+ <div id="log"></div>
+ <iframe id="iframe" width="800" height="500"></iframe>
+ <script>
+ const epsilon = 0.5;
+ const percent = 8;
+
+ const doc = document.querySelector("#iframe").contentDocument;
+ const win = document.querySelector("#iframe").contentWindow;
+ const vw = win.innerWidth*percent*0.01;
+ const vh = win.innerHeight*percent*0.01;
+ ["horizontal-tb", "vertical-rl"].forEach(wm => {
+ test(function(t) {
+ t.add_cleanup(() => { doc.body.innerHTML = ""; });
+ doc.body.innerHTML = `
+ <style>html { writing-mode: ${wm}; }</style>
+ <math>
+ <mspace id="unitVi" width="${percent}vi"/>
+ <mspace id="unitVb" width="${percent}vb"/>
+ </math>
+ `.trim();
+ const vi = doc.querySelector("#unitVi").getBoundingClientRect().width;
+ const vb = doc.querySelector("#unitVb").getBoundingClientRect().width;
+
+ if (wm === "horizontal-tb") {
+ assert_approx_equals(vi, vw, epsilon, "vi in horizontal writing modes");
+ assert_approx_equals(vb, vh, epsilon, "vb in horizontal writing modes");
+ } else if (wm === "vertical-rl") {
+ assert_approx_equals(vi, vh, epsilon, "vi in vertical writing modes");
+ assert_approx_equals(vb, vw, epsilon, "vb in vertical writing modes");
+ }
+ }, `vi/vb in ${wm} writing modes`);
+ });
+ </script>
+</body>
+</html>
diff --git a/tests/wpt/tests/mathml/tools/css-units.py b/tests/wpt/tests/mathml/tools/css-units.py
new file mode 100644
index 00000000000..cdf06bb7744
--- /dev/null
+++ b/tests/wpt/tests/mathml/tools/css-units.py
@@ -0,0 +1,19 @@
+#!/usr/bin/env python3
+
+from utils import mathfont
+
+# Create a font with glyphs for all the font-relative CSS units
+# (so that they all have length 1em).
+# See https://drafts.csswg.org/css-values-4/#lengths
+f = mathfont.create("css-units",
+ "Copyright (c) 2025 Igalia S.L.")
+
+mathfont.drawRectangleGlyph(f.createChar(ord("x")), mathfont.em, mathfont.em // 2) # ex = 0.5em
+mathfont.createSquareGlyph(f, ord("O")) # cap = 1em
+mathfont.createSquareGlyph(f, ord("0")) # ch = 1em
+mathfont.createSquareGlyph(f, ord("水")) # ic = 1em
+
+assert f.capHeight == 1000
+assert f.xHeight == 500
+
+mathfont.save(f)
diff --git a/tests/wpt/tests/permissions-policy/resources/digital-credentials-create.html b/tests/wpt/tests/permissions-policy/resources/digital-credentials-create.html
new file mode 100644
index 00000000000..aafd436282e
--- /dev/null
+++ b/tests/wpt/tests/permissions-policy/resources/digital-credentials-create.html
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<meta charset="utf-8" />
+<script src="/resources/testdriver.js"></script>
+<script src="/resources/testdriver-vendor.js"></script>
+<script type="module">
+ import { makeCreateOptions } from "/digital-credentials/support/helper.js";
+ const type = "availability-result";
+ async function notify() {
+ if (!navigator.userActivation.isActive) {
+ await test_driver.bless("user activation", null, window);
+ }
+ let enabled = undefined;
+ try {
+ await navigator.credentials.create(makeCreateOptions([]));
+ } catch (e) {
+ switch (e.name) {
+ case "NotAllowedError":
+ enabled = false;
+ break;
+ case "TypeError":
+ enabled = true;
+ break;
+ default:
+ throw e;
+ }
+ } finally {
+ window.parent.postMessage({ type, enabled }, "*");
+ }
+ }
+ test_driver.set_test_context(parent);
+ window.onload = notify;
+</script>
+<body>
+ <h1>Digital Credentials iframe</h1>
+</body>
diff --git a/tests/wpt/tests/shadow-dom/reference-target/tentative/property-reflection-idl-setters.html b/tests/wpt/tests/shadow-dom/reference-target/tentative/property-reflection-idl-setters.html
new file mode 100644
index 00000000000..74f2e670915
--- /dev/null
+++ b/tests/wpt/tests/shadow-dom/reference-target/tentative/property-reflection-idl-setters.html
@@ -0,0 +1,30 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <script src="/html/resources/common.js"></script>
+ <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/testdriver-actions.js"></script>
+ <script src="/wai-aria/scripts/aria-utils.js"></script>
+ <script src="resources/property-reflection-helper.js"></script>
+</head>
+<body>
+ <div id="host-container"></div>
+ <script>
+ function append_test_declaratively_with_invalid_ref_target(host_container, referenced_element_type) {
+ host_container.setHTMLUnsafe(`
+ <div id="host-id">
+ <template shadowrootmode="open" shadowrootreferencetarget="invalid">
+ <${referenced_element_type} id="target"></${referenced_element_type}>
+ </template>
+ </div>`);
+ const host = host_container.firstElementChild;
+ return host;
+ }
+
+ run_test_for_all_reflecting_properties(append_test_declaratively_with_invalid_ref_target, test_idl_setter, "");
+ </script>
+</body>
+</html>
diff --git a/tests/wpt/tests/shadow-dom/reference-target/tentative/resources/property-reflection-helper.js b/tests/wpt/tests/shadow-dom/reference-target/tentative/resources/property-reflection-helper.js
index 79f1bd7f748..88b7f743831 100644
--- a/tests/wpt/tests/shadow-dom/reference-target/tentative/resources/property-reflection-helper.js
+++ b/tests/wpt/tests/shadow-dom/reference-target/tentative/resources/property-reflection-helper.js
@@ -1,5 +1,6 @@
const Behavior = Object.freeze({
ReflectsHost: 'ReflectsHost',
+ ReflectsHostReadOnly: 'ReflectsHostReadOnly',
ReflectsHostInArray: 'ReflectsHostInArray',
IsNull: 'IsNull',
ReflectsHostID: 'ReflectsHostID',
@@ -30,7 +31,7 @@ function test_property_reflection(element_creation_method, test_name_suffix, ref
referencing_element.setAttribute(attribute, "host-id");
const host_container = document.querySelector("#host-container");
const host = element_creation_method(host_container, referenced_element_type);
- if (expected_behavior === Behavior.ReflectsHost) {
+ if (expected_behavior === Behavior.ReflectsHost || expected_behavior === Behavior.ReflectsHostReadOnly) {
assert_equals(referencing_element[reflected_property], host);
} else if (expected_behavior === Behavior.ReflectsHostInArray) {
assert_array_equals(referencing_element[reflected_property], [host]);
@@ -47,6 +48,82 @@ function test_property_reflection(element_creation_method, test_name_suffix, ref
}, `${referencing_element_type}.${reflected_property} has reflection behavior ${expected_behavior} when pointing to ${referenced_element_type} with reference target${test_name_suffix}`);
}
+function test_idl_setter(element_creation_method, test_name_suffix, referencing_element_type, referenced_element_type, attribute, reflected_property, expected_behavior) {
+ // There's nothing to test if the referencing element type doesn't have the reflecting
+ // property.
+ if (!(reflected_property in document.createElement(referencing_element_type))) {
+ return;
+ }
+
+ test(function () {
+ const referencing_element = document.createElement(referencing_element_type);
+ document.body.appendChild(referencing_element);
+ const host_container = document.querySelector("#host-container");
+ const host = element_creation_method(host_container, referenced_element_type);
+
+ if (reflected_property === "ariaOwnsElements") {
+ // It's undetermined whether reference target should work with aria-owns or not; see
+ // https://github.com/WICG/webcomponents/issues/1091 and
+ // https://github.com/w3c/aria/issues/2266
+ return;
+ }
+
+ if (expected_behavior === Behavior.ReflectsHost) {
+ referencing_element[reflected_property] = host;
+ // For element reflecting properties, the IDL getter should return null when the explicitly
+ // set element has an invalid reference target.
+ assert_equals(referencing_element[reflected_property], null);
+ } else if (expected_behavior === Behavior.ReflectsHostReadOnly) {
+ referencing_element[reflected_property] = host;
+ // Setting a read-only property has no effect.
+ assert_equals(referencing_element[reflected_property], null);
+ } else if (expected_behavior === Behavior.ReflectsHostInArray) {
+ referencing_element[reflected_property] = [ host ];
+ // For element reflecting properties, the IDL getter should not return explicitly set elements
+ // if they have an invalid reference target.
+ assert_array_equals(referencing_element[reflected_property], []);
+ } else if (expected_behavior === Behavior.IsNull) {
+ referencing_element[reflected_property] = host;
+ assert_equals(referencing_element[reflected_property], null);
+ } else if (expected_behavior === Behavior.ReflectsHostID) {
+ referencing_element[reflected_property] = "host-id";
+ // Properties reflecting the host ID return the ID even if it points to an element with
+ // an invalid reference target.
+ assert_equals(referencing_element[reflected_property], "host-id");
+ } else if (expected_behavior === Behavior.ReflectsHostIDInDOMTokenList) {
+ // Properties reflecting a DOMTokenList of IDs returns the IDs even if they point to an
+ // element with an invalid reference target.
+ referencing_element[reflected_property] = [ "host-id" ];
+ assert_true(referencing_element[reflected_property] instanceof DOMTokenList);
+ assert_array_equals(Array.from(referencing_element[reflected_property]), [ "host-id" ]);
+ }
+
+ // Set the reference target to a valid value.
+ host.shadowRoot.referenceTarget = host.shadowRoot.querySelector(referenced_element_type).id;
+
+ if (expected_behavior === Behavior.ReflectsHost) {
+ // For element reflecting properties, if the reference target becomes valid for the explicitly
+ // set element, we should start returning that element.
+ assert_equals(referencing_element[reflected_property], host);
+ } else if (expected_behavior === Behavior.ReflectsHostReadOnly) {
+ assert_equals(referencing_element[reflected_property], null);
+ } else if (expected_behavior === Behavior.ReflectsHostInArray) {
+ // For element reflecting properties, if the reference target becomes valid for any of the
+ // explicitly set elements, we should start returning that element.
+ assert_array_equals(referencing_element[reflected_property], [host]);
+ } else if (expected_behavior === Behavior.IsNull) {
+ assert_equals(referencing_element[reflected_property], null);
+ } else if (expected_behavior === Behavior.ReflectsHostID) {
+ assert_equals(referencing_element[reflected_property], "host-id");
+ } else if (expected_behavior === Behavior.ReflectsHostIDInDOMTokenList) {
+ assert_array_equals(Array.from(referencing_element[reflected_property]), [ "host-id" ]);
+ }
+
+ referencing_element.remove();
+ host_container.setHTMLUnsafe("");
+ }, `${referencing_element_type}.${reflected_property} has IDL setter behavior ${expected_behavior} when pointing to ${referenced_element_type} with reference target${test_name_suffix}`);
+}
+
function run_test_for_all_reflecting_properties(setup_function, test_function, test_name_suffix) {
for(let referencing_element_type of element_types) {
for(let referenced_element_type of element_types) {
@@ -73,13 +150,13 @@ function run_test_for_all_reflecting_properties(setup_function, test_function, t
const expected_form_property_behavior = (referenced_element_type == 'form' &&
referencing_element_type != "label" &&
referencing_element_type != "legend" &&
- referencing_element_type != "option") ? Behavior.ReflectsHost : Behavior.IsNull;
- test_function(setup_function, test_name_suffix, referencing_element_type, referenced_element_type, "form", "form", expected_form_property_behavior);
+ referencing_element_type != "option") ? Behavior.ReflectsHostReadOnly : Behavior.IsNull;
+ test_function(setup_function, test_name_suffix, referencing_element_type, referenced_element_type, "form", "form", expected_form_property_behavior);
- const expected_list_property_behavior = (referenced_element_type == 'datalist') ? Behavior.ReflectsHost : Behavior.IsNull;
+ const expected_list_property_behavior = (referenced_element_type == 'datalist') ? Behavior.ReflectsHostReadOnly : Behavior.IsNull;
test_function(setup_function, test_name_suffix, referencing_element_type, referenced_element_type, "list", "list", expected_list_property_behavior);
- const expected_control_property_behavior = HTML5_LABELABLE_ELEMENTS.includes(referenced_element_type) ? Behavior.ReflectsHost : Behavior.IsNull;
+ const expected_control_property_behavior = HTML5_LABELABLE_ELEMENTS.includes(referenced_element_type) ? Behavior.ReflectsHostReadOnly : Behavior.IsNull;
test_function(setup_function, test_name_suffix, referencing_element_type, referenced_element_type, "for", "control", expected_control_property_behavior);
}
}
diff --git a/tests/wpt/tests/soft-navigation-heuristics/interaction-with-paint-before-back.tentative.html b/tests/wpt/tests/soft-navigation-heuristics/interaction-with-paint-before-back.tentative.html
index b5874119913..7b884f2bdb3 100644
--- a/tests/wpt/tests/soft-navigation-heuristics/interaction-with-paint-before-back.tentative.html
+++ b/tests/wpt/tests/soft-navigation-heuristics/interaction-with-paint-before-back.tentative.html
@@ -47,10 +47,11 @@
history.back();
});
promise_test(async t => {
+ const soft_nav_promise = waitOnSoftNav();
if (test_driver) {
test_driver.click(link);
}
- await waitOnSoftNav();
+ await soft_nav_promise;
assert_equals(
document.softNavigations, 1,
'Single Soft Navigation detected');
@@ -70,7 +71,3 @@
</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 d405adb4e7e..a29978c8760 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
@@ -33,9 +33,10 @@ const testSoftNavigation =
let paint_entries_promise =
waitOnPaintEntriesPromise(firstClick);
interacted = false;
+ const soft_nav_promise = waitOnSoftNav();
interact(link, interactionFunc);
- const navigation_id = await waitOnSoftNav();
+ const navigation_id = await soft_nav_promise;
if (!first_navigation_id) {
first_navigation_id = navigation_id;
}
@@ -63,8 +64,9 @@ const testNavigationApi = (testName, navigateEventHandler, link) => {
await waitInitialLCP();
const preClickLcp = await getLcpEntries();
let paint_entries_promise = waitOnPaintEntriesPromise();
+ const soft_nav_promise = waitOnSoftNav();
interact(link);
- const first_navigation_id = await waitOnSoftNav();
+ const first_navigation_id = await soft_nav_promise;
await navigated;
await paint_entries_promise;
assert_equals(document.softNavigations, 1, 'Soft Navigation detected');
diff --git a/tests/wpt/tests/speculation-rules/prefetch/resources/authenticate.py b/tests/wpt/tests/speculation-rules/prefetch/resources/authenticate.py
index ea0c546afff..b2ca9c450e0 100644
--- a/tests/wpt/tests/speculation-rules/prefetch/resources/authenticate.py
+++ b/tests/wpt/tests/speculation-rules/prefetch/resources/authenticate.py
@@ -1,3 +1,4 @@
+# TODO(https://crbug.com/406819294): Simplify relative import for util.
import importlib
util = importlib.import_module("speculation-rules.prefetch.resources.util")
diff --git a/tests/wpt/tests/speculation-rules/prefetch/resources/basic-service-worker.js b/tests/wpt/tests/speculation-rules/prefetch/resources/basic-service-worker.js
index 18432ed62ed..17fccd448d2 100644
--- a/tests/wpt/tests/speculation-rules/prefetch/resources/basic-service-worker.js
+++ b/tests/wpt/tests/speculation-rules/prefetch/resources/basic-service-worker.js
@@ -1,5 +1,13 @@
const swOption = new URL(location.href).searchParams.get('sw');
+const interceptedRequests = [];
+
+self.addEventListener('message', event => {
+ if (event.data === 'getInterceptedRequests') {
+ event.source.postMessage(interceptedRequests);
+ }
+});
+
if (swOption !== 'no-fetch-handler') {
self.addEventListener('fetch', event => {
@@ -9,6 +17,19 @@ if (swOption !== 'no-fetch-handler') {
return;
}
+ const headers = {};
+ event.request.headers.forEach((value, key) => {
+ headers[key] = value;
+ });
+ interceptedRequests.push({
+ request: {
+ url: event.request.url,
+ headers: headers,
+ },
+ clientId: event.clientId,
+ resultingClientId: event.resultingClientId
+ });
+
if (swOption === 'fetch-handler') {
event.respondWith(fetch(event.request));
} else if (swOption === 'fetch-handler-modify-url') {
diff --git a/tests/wpt/tests/speculation-rules/prefetch/resources/cookies.py b/tests/wpt/tests/speculation-rules/prefetch/resources/cookies.py
index 54aaabee70e..1b56c674c0b 100644
--- a/tests/wpt/tests/speculation-rules/prefetch/resources/cookies.py
+++ b/tests/wpt/tests/speculation-rules/prefetch/resources/cookies.py
@@ -1,5 +1,6 @@
import json
+# TODO(https://crbug.com/406819294): Simplify relative import for util.
import importlib
util = importlib.import_module("speculation-rules.prefetch.resources.util")
diff --git a/tests/wpt/tests/speculation-rules/prefetch/resources/prefetch_nvs_hint.py b/tests/wpt/tests/speculation-rules/prefetch/resources/prefetch_nvs_hint.py
index 223135dc8b8..f4ecb004bc1 100644
--- a/tests/wpt/tests/speculation-rules/prefetch/resources/prefetch_nvs_hint.py
+++ b/tests/wpt/tests/speculation-rules/prefetch/resources/prefetch_nvs_hint.py
@@ -1,5 +1,6 @@
import time
+# TODO(https://crbug.com/406819294): Simplify relative import for util.
import importlib
util = importlib.import_module("speculation-rules.prefetch.resources.util")
diff --git a/tests/wpt/tests/speculation-rules/prefetch/resources/utils.sub.js b/tests/wpt/tests/speculation-rules/prefetch/resources/utils.sub.js
index a90459fdf03..d4efc2dc7dc 100644
--- a/tests/wpt/tests/speculation-rules/prefetch/resources/utils.sub.js
+++ b/tests/wpt/tests/speculation-rules/prefetch/resources/utils.sub.js
@@ -216,6 +216,28 @@ function assert_prefetched_without_sec_purpose(requestHeaders, description) {
assert_equals(requestHeaders['sec-purpose'], undefined, description);
}
+// For ServiceWorker tests.
+// `interceptedRequest` is an element of `interceptedRequests` in
+// `resources/basic-service-worker.js`.
+
+// The ServiceWorker fetch handler intercepted a prefetching request.
+function assert_intercept_prefetch(interceptedRequest, expectedUrl) {
+ assert_equals(interceptedRequest.request.url, expectedUrl.toString(),
+ "intercepted request URL.");
+
+ assert_prefetched(interceptedRequest.request.headers,
+ "Prefetch request should be intercepted.");
+}
+
+// The ServiceWorker fetch handler intercepted a non-prefetching request.
+function assert_intercept_non_prefetch(interceptedRequest, expectedUrl) {
+ assert_equals(interceptedRequest.request.url, expectedUrl.toString(),
+ "intercepted request URL.");
+
+ assert_not_prefetched(interceptedRequest.request.headers,
+ "Non-prefetch request should be intercepted.");
+}
+
// Use nvs_header query parameter to ask the wpt server
// to populate No-Vary-Search response header.
function addNoVarySearchHeaderUsingQueryParam(url, value){
diff --git a/tests/wpt/tests/speculation-rules/prefetch/tentative/service-worker/basic.sub.https.html b/tests/wpt/tests/speculation-rules/prefetch/tentative/service-worker/basic.sub.https.html
index bee8e2ff1f4..98e089bcc66 100644
--- a/tests/wpt/tests/speculation-rules/prefetch/tentative/service-worker/basic.sub.https.html
+++ b/tests/wpt/tests/speculation-rules/prefetch/tentative/service-worker/basic.sub.https.html
@@ -47,8 +47,8 @@ promise_test(async t => {
if (swOption !== 'no-controller') {
const reg = await service_worker_unregister_and_register(
t, swUrl, nextUrl);
- await wait_for_state(t, reg.installing, 'activated');
sw = reg.installing;
+ await wait_for_state(t, sw, 'activated');
}
// Start speculation rules prefetch and navigate to the URL.
@@ -74,6 +74,17 @@ promise_test(async t => {
assert_equals(controllerUrl, swUrl);
}
+ let interceptedRequests = [];
+ if (sw) {
+ const messagePromise = new Promise(resolve => {
+ navigator.serviceWorker.addEventListener('message', (event) => {
+ resolve(event.data);
+ }, {once: true});
+ });
+ sw.postMessage('getInterceptedRequests');
+ interceptedRequests = await messagePromise;
+ }
+
// Current Chromium's expected behavior:
// prefetch works when
// - there are no controlling service worker, or
@@ -89,6 +100,13 @@ promise_test(async t => {
assert_equals(requestCount.nonPrefetch, 0,
'non-prefetch requests should not be sent to the server.');
assert_prefetched(headers, "Prefetched result should be served.");
+
+ if (swOption === 'no-controller' || swOption === 'no-fetch-handler') {
+ assert_equals(interceptedRequests.length, 0);
+ } else {
+ assert_equals(interceptedRequests.length, 1);
+ assert_intercept_prefetch(interceptedRequests[0], nextUrl);
+ }
} else if (originOption === 'same-site' &&
(swOption === 'fetch-handler-modify-url' ||
swOption === 'fetch-handler-modify-referrer')) {
@@ -119,12 +137,23 @@ promise_test(async t => {
new URL('/intercepted', location.href).href,
'Referrer should be modified by ServiceWorker');
}
+
+ assert_equals(interceptedRequests.length, 1);
+ assert_intercept_prefetch(interceptedRequests[0], nextUrl);
} else {
assert_not_prefetched(headers, "Prefetched result should not be served.");
assert_equals(requestCount.nonPrefetch, 1,
'a non-prefetch request should be sent to the server.');
assert_equals(requestCount.prefetch, 0,
'prefetch requests should not be sent to the server.');
+
+ if (swOption === 'no-fetch-handler') {
+ assert_equals(interceptedRequests.length, 0);
+ } else {
+ assert_equals(interceptedRequests.length, 1);
+ assert_intercept_non_prefetch(interceptedRequests[0], nextUrl);
+ }
}
+
}, "Prefetch with ServiceWorker (" + swOption + ")");
</script>
diff --git a/tests/wpt/tests/streams/WEB_FEATURES.yml b/tests/wpt/tests/streams/WEB_FEATURES.yml
new file mode 100644
index 00000000000..d10bbe4a7d7
--- /dev/null
+++ b/tests/wpt/tests/streams/WEB_FEATURES.yml
@@ -0,0 +1,5 @@
+features:
+- name: streams
+ files:
+ # Top-level only. Subdirectories have their own mapping.
+ - "*"
diff --git a/tests/wpt/tests/streams/piping/WEB_FEATURES.yml b/tests/wpt/tests/streams/piping/WEB_FEATURES.yml
new file mode 100644
index 00000000000..8cf3517baf0
--- /dev/null
+++ b/tests/wpt/tests/streams/piping/WEB_FEATURES.yml
@@ -0,0 +1,3 @@
+features:
+- name: streams
+ files: "**"
diff --git a/tests/wpt/tests/streams/readable-streams/WEB_FEATURES.yml b/tests/wpt/tests/streams/readable-streams/WEB_FEATURES.yml
new file mode 100644
index 00000000000..ad2cb549631
--- /dev/null
+++ b/tests/wpt/tests/streams/readable-streams/WEB_FEATURES.yml
@@ -0,0 +1,14 @@
+features:
+- name: streams
+ files:
+ - "*"
+ - "!async-iterator.any.js"
+ - "!from.any.js"
+ # 'owning' type is not yet standardized
+ - "!owning-type*"
+- name: async-iterable-streams
+ files:
+ - async-iterator.any.js
+- name: readablestream-from
+ files:
+ - from.any.js
diff --git a/tests/wpt/tests/streams/readable-streams/crashtests/WEB_FEATURES.yml b/tests/wpt/tests/streams/readable-streams/crashtests/WEB_FEATURES.yml
new file mode 100644
index 00000000000..b5dbd1ff419
--- /dev/null
+++ b/tests/wpt/tests/streams/readable-streams/crashtests/WEB_FEATURES.yml
@@ -0,0 +1,7 @@
+features:
+- name: streams
+ files:
+ - strategy-worker.js
+- name: readablestream-from
+ files:
+ - from-cross-realm.https.html
diff --git a/tests/wpt/tests/streams/transform-streams/WEB_FEATURES.yml b/tests/wpt/tests/streams/transform-streams/WEB_FEATURES.yml
new file mode 100644
index 00000000000..f39dc16de4c
--- /dev/null
+++ b/tests/wpt/tests/streams/transform-streams/WEB_FEATURES.yml
@@ -0,0 +1,8 @@
+features:
+- name: streams
+ files:
+ - "*"
+ - "!cancel.any.js"
+- name: transformstream-transformer-cancel
+ files:
+ - cancel.any.js
diff --git a/tests/wpt/tests/streams/writable-streams/WEB_FEATURES.yml b/tests/wpt/tests/streams/writable-streams/WEB_FEATURES.yml
new file mode 100644
index 00000000000..8cf3517baf0
--- /dev/null
+++ b/tests/wpt/tests/streams/writable-streams/WEB_FEATURES.yml
@@ -0,0 +1,3 @@
+features:
+- name: streams
+ files: "**"
diff --git a/tests/wpt/tests/tools/ci/requirements_macos_color_profile.txt b/tests/wpt/tests/tools/ci/requirements_macos_color_profile.txt
index cd3e785aa47..5b95e3357b8 100644
--- a/tests/wpt/tests/tools/ci/requirements_macos_color_profile.txt
+++ b/tests/wpt/tests/tools/ci/requirements_macos_color_profile.txt
@@ -1,4 +1,14 @@
-pyobjc-core==10.3.1
-pyobjc-framework-Cocoa==9.2
-pyobjc-framework-ColorSync==9.2
-pyobjc-framework-Quartz==9.2
+--only-binary pyobjc-core
+--only-binary pyobjc-framework-cocoa
+--only-binary pyobjc-framework-colorsync
+--only-binary pyobjc-framework-quartz
+
+pyobjc-core==10.3.2 ; python_full_version < '3.9'
+pyobjc-framework-cocoa==10.3.2 ; python_full_version < '3.9'
+pyobjc-framework-colorsync==10.3.2 ; python_full_version < '3.9'
+pyobjc-framework-quartz==10.3.2 ; python_full_version < '3.9'
+
+pyobjc-core==11.0 ; python_full_version >= '3.9'
+pyobjc-framework-cocoa==11.0 ; python_full_version >= '3.9'
+pyobjc-framework-colorsync==11.0 ; python_full_version >= '3.9'
+pyobjc-framework-quartz==11.0 ; python_full_version >= '3.9'
diff --git a/tests/wpt/tests/trusted-types/block-string-assignment-to-Document-write.html b/tests/wpt/tests/trusted-types/block-string-assignment-to-Document-write.html
index 0b16a9c4910..c774dca4390 100644
--- a/tests/wpt/tests/trusted-types/block-string-assignment-to-Document-write.html
+++ b/tests/wpt/tests/trusted-types/block-string-assignment-to-Document-write.html
@@ -124,6 +124,9 @@
assert_equals(sink, "Document write");
} else if (html === "assertSinkEqualsDocumentWriteLn") {
assert_equals(sink, "Document writeln");
+ } else if (html === "assertSinkEqualsDocumentWriteLn\n") {
+ // Ensure that new line characters aren't incorrectly added prior to processing
+ assert_unreached(`Should not process any other HTML, but got "${html}"`);
}
return html.replace("Hi", "Quack")
diff --git a/tests/wpt/tests/viewport-segments/viewport-segments-env-variables.https.html b/tests/wpt/tests/viewport-segments/viewport-segments-env-variables.https.html
index 6004398b2ce..dce6757d49a 100644
--- a/tests/wpt/tests/viewport-segments/viewport-segments-env-variables.https.html
+++ b/tests/wpt/tests/viewport-segments/viewport-segments-env-variables.https.html
@@ -77,18 +77,19 @@ promise_test(async (t) => {
{ once: true }
);
});
+ const leftOffset =
+ Math.round(window.innerWidth / 2 - displayFeatureLength / 2);
await test_driver.set_display_features([{
orientation: 'vertical',
maskLength: displayFeatureLength,
- offset: window.innerWidth / 2 - displayFeatureLength / 2
+ offset: leftOffset
}]);
assert_true(await promise);
assert_equals(targetComputedStyle.marginTop, '0px');
assert_equals(targetComputedStyle.marginRight,
- window.innerWidth / 2 + displayFeatureLength / 2 + 'px');
+ Math.round(window.innerWidth / 2 + displayFeatureLength / 2) + 'px');
assert_equals(targetComputedStyle.marginBottom, window.innerHeight + 'px');
- assert_equals(targetComputedStyle.marginLeft,
- window.innerWidth / 2 - displayFeatureLength / 2 + 'px');
+ assert_equals(targetComputedStyle.marginLeft, leftOffset + 'px');
assert_equals(targetComputedStyle.width, displayFeatureLength + 'px');
assert_equals(targetComputedStyle.height, window.innerHeight + 'px');
assert_equals(targetComputedStyle.opacity, '0.2');
@@ -102,17 +103,18 @@ promise_test(async (t) => {
{ once: true }
);
});
+ const topOffset =
+ Math.round(window.innerHeight / 2 - displayFeatureLength / 2);
await test_driver.set_display_features([{
orientation: 'horizontal',
maskLength: displayFeatureLength,
- offset: window.innerHeight / 2 - displayFeatureLength / 2
+ offset: topOffset
}]);
assert_true(await promise);
- assert_equals(targetComputedStyle.marginTop,
- window.innerHeight / 2 - displayFeatureLength / 2 + 'px');
+ assert_equals(targetComputedStyle.marginTop, topOffset + 'px');
assert_equals(targetComputedStyle.marginRight, window.innerWidth + 'px');
assert_equals(targetComputedStyle.marginBottom,
- window.innerHeight / 2 + displayFeatureLength / 2 + 'px');
+ Math.round(window.innerHeight / 2 + displayFeatureLength / 2) + 'px');
assert_equals(targetComputedStyle.marginLeft, '0px');
assert_equals(targetComputedStyle.width, window.innerWidth + 'px');
assert_equals(targetComputedStyle.height, displayFeatureLength + 'px');
diff --git a/tests/wpt/tests/viewport-segments/viewport-segments-segments-property.https.html b/tests/wpt/tests/viewport-segments/viewport-segments-segments-property.https.html
index e6c9d8b4e16..653e2bcb253 100644
--- a/tests/wpt/tests/viewport-segments/viewport-segments-segments-property.https.html
+++ b/tests/wpt/tests/viewport-segments/viewport-segments-segments-property.https.html
@@ -35,22 +35,26 @@ promise_test(async (t) => {
{ once: true }
);
});
+ const leftOffset =
+ Math.round(window.innerWidth / 2 - displayFeatureLength / 2);
await test_driver.set_display_features([{
orientation: 'vertical',
maskLength: displayFeatureLength,
- offset: window.innerWidth / 2 - displayFeatureLength / 2
+ offset: leftOffset
}]);
assert_true(await promise);
assert_equals(viewport.segments.length, 2);
const segmentLeft = viewport.segments[0];
+ const epsilon = 1;
assert_equals(segmentLeft.x, 0);
assert_equals(segmentLeft.y, 0);
- assert_equals(segmentLeft.width, window.innerWidth / 2 - displayFeatureLength / 2);
+ assert_approx_equals(segmentLeft.width, leftOffset, epsilon);
assert_equals(segmentLeft.height, window.innerHeight);
const segmentRight = viewport.segments[1];
- assert_equals(segmentRight.x, window.innerWidth / 2 + displayFeatureLength / 2);
+ assert_approx_equals(segmentRight.x,
+ Math.round(window.innerWidth / 2 + displayFeatureLength / 2), epsilon);
assert_equals(segmentRight.y, 0);
- assert_equals(segmentRight.width, window.innerWidth / 2 - displayFeatureLength / 2);
+ assert_approx_equals(segmentRight.width, leftOffset, epsilon);
assert_equals(segmentRight.height, window.innerHeight);
// iframes do not receive segments information.
assert_equals(window.frames[0].viewport.segments, null);
@@ -64,10 +68,12 @@ promise_test(async (t) => {
{ once: true }
);
});
+ const topOffset =
+ Math.round(window.innerHeight / 2 - displayFeatureLength / 2);
await test_driver.set_display_features([{
orientation: 'horizontal',
maskLength: displayFeatureLength,
- offset: window.innerHeight / 2 - displayFeatureLength / 2
+ offset: topOffset
}]);
assert_true(await promise);
assert_equals(viewport.segments.length, 2);
@@ -75,12 +81,13 @@ promise_test(async (t) => {
assert_equals(segmentTop.x, 0);
assert_equals(segmentTop.y, 0);
assert_equals(segmentTop.width, window.innerWidth);
- assert_equals(segmentTop.height, window.innerHeight / 2 - displayFeatureLength / 2);
+ assert_approx_equals(segmentTop.height, topOffset, epsilon);
const segmentBottom = viewport.segments[1];
assert_equals(segmentBottom.x, 0);
- assert_equals(segmentBottom.y, window.innerHeight / 2 + displayFeatureLength / 2);
+ assert_approx_equals(segmentBottom.y,
+ Math.round(window.innerHeight / 2 + displayFeatureLength / 2), epsilon);
assert_equals(segmentBottom.width, window.innerWidth);
- assert_equals(segmentBottom.height, window.innerHeight / 2 - displayFeatureLength / 2);
+ assert_approx_equals(segmentBottom.height, topOffset, epsilon);
// iframes do not receive segments information.
assert_equals(window.frames[0].viewport.segments, null);
diff --git a/tests/wpt/tests/webdriver/tests/bidi/web_extension/uninstall/invalid.py b/tests/wpt/tests/webdriver/tests/bidi/web_extension/uninstall/invalid.py
index 54fbb22cf5e..228f0e57e52 100644
--- a/tests/wpt/tests/webdriver/tests/bidi/web_extension/uninstall/invalid.py
+++ b/tests/wpt/tests/webdriver/tests/bidi/web_extension/uninstall/invalid.py
@@ -6,21 +6,16 @@ pytestmark = pytest.mark.asyncio
async def test_uninstall_missing_extension(bidi_session):
with pytest.raises(error.NoSuchWebExtensionException):
- await bidi_session.web_extension.uninstall(
- extension="test"
- )
+ await bidi_session.web_extension.uninstall(extension="test")
@pytest.mark.parametrize("value", [None, False, 42, {}, []])
async def test_params_extension_invalid_type(bidi_session, value):
with pytest.raises(error.InvalidArgumentException):
- await bidi_session.web_extension.uninstall(
- extension=value
- )
+ await bidi_session.web_extension.uninstall(extension=value)
-async def test_params_extension_invalid_value(bidi_session):
+@pytest.mark.parametrize("value", ["", "unknown-ext"], ids=["empty", "unknown"])
+async def test_params_extension_invalid_value(bidi_session, value):
with pytest.raises(error.NoSuchWebExtensionException):
- await bidi_session.web_extension.uninstall(
- extension=""
- )
+ await bidi_session.web_extension.uninstall(extension=value)
diff --git a/tests/wpt/tests/webnn/conformance_tests/dequantizeLinear.https.any.js b/tests/wpt/tests/webnn/conformance_tests/dequantizeLinear.https.any.js
index 900bb57bacf..7f1ed15cc4a 100644
--- a/tests/wpt/tests/webnn/conformance_tests/dequantizeLinear.https.any.js
+++ b/tests/wpt/tests/webnn/conformance_tests/dequantizeLinear.https.any.js
@@ -689,9 +689,14 @@ const dequantizeLinearTests = [
'outputs': 'transposeOutput'
},
{
+ 'name': 'reshape',
+ 'arguments': [{'input': 'transposeOutput'}, {'newShape': [1, 1, 2]}],
+ 'outputs': 'reshapeOutput'
+ },
+ {
'name': 'dequantizeLinear',
'arguments': [
- {'input': 'transposeOutput'}, {'scale': 'dequantizeLinearScale'},
+ {'input': 'reshapeOutput'}, {'scale': 'dequantizeLinearScale'},
{'zeroPoint': 'dequantizeLinearZeroPoint'}
],
'outputs': 'dequantizeLinearOutput'
@@ -700,7 +705,7 @@ const dequantizeLinearTests = [
'expectedOutputs': {
'dequantizeLinearOutput': {
'data': [-1.1202747821807861, 13.163229942321777],
- 'descriptor': {shape: [1, 2], dataType: 'float32'}
+ 'descriptor': {shape: [1, 1, 2], dataType: 'float32'}
}
}
}
diff --git a/tests/wpt/tests/webxr/depth-sensing/matchDepthViewValues.js b/tests/wpt/tests/webxr/depth-sensing/matchDepthViewValues.js
index 597f9734d3f..697f4deb8ff 100644
--- a/tests/wpt/tests/webxr/depth-sensing/matchDepthViewValues.js
+++ b/tests/wpt/tests/webxr/depth-sensing/matchDepthViewValues.js
@@ -18,8 +18,8 @@ const depthViewGeometryTestGenerator = function(isCpuOptimized) {
const depthInformation = isCpuOptimized ? frame.getDepthInformation(view)
: glBinding.getDepthInformation(view);
t.step(()=> {
- assert_matrix_approx_equals(IDENTITY_MATRIX, depthInformation.projectionMatrix);
- assert_transform_approx_equals(IDENTITY_TRANSFORM, depthInformation.transform);
+ assert_matrix_approx_equals(view.projectionMatrix, depthInformation.projectionMatrix);
+ assert_transform_approx_equals(view.transform, depthInformation.transform);
});
}
resolve();