Open
delan
opened this issue 2 years ago
•
52 comments
This patch improves support for multiple top-level browsing contexts aka “browsers”.
We add several messages that allow the embedder to show, hide, move, and resize browsers in the compositor, focus and unfocus browsers in the constellation, and notify the embedder when painting order and focus changes.
These changes can be used to create a multiple-document interface, like we do in #30785.
Parts of this patch have been broken out into:
[ ] #30767
[ ] #30840
[ ] #30841
[ ] #30842
limitations
desktop-style page zoom is still global
browsers with transparent or translucent content will misbehave
compositor
BrowserManager (new) manages browser-related storage and painting order
it allows the compositor to store arbitrary data for each browser id
it keeps track of which browsers are visible, and what order to paint them in
we now use the iframe-in-dummy-root-pipeline technique to composite the browsers together, not just when we have a non-unity pinch zoom
constellation
BrowserManager (new) manages browser-related storage and focus order
it allows the constellation to store arbitrary data for each browser id
it keeps track of which browser is focused, or whether no browser is focused
it can refocus the last-focused browser when a browser is removed (currently unused)
we now send BrowserClosed directly when a browser is closed rather than relying on script to do it, so that the event gets sent even if the browser was not closed by script
servoshell
BrowserManager (was Browser) keeps a copy of the browser rects, focus, and painting order
but for now, we always focus and show the newest browser only
messages
embedder → compositor (no ipc)
WindowResize (was Resize) no longer affects the viewport of individual browsers
Zoom (existing) no longer affects the viewport of individual browsers
ResetZoom (existing) no longer affects the viewport of individual browsers
MoveResizeBrowser (new) updates a browser’s rect, and sends new viewport to script in descendant pipelines
embedder →* constellation → compositor
ShowBrowser (new) adds a browser to painting order, and notifies embedder of the new painting order
HideBrowser (new) removes a browser from painting order, and notifies embedder of the new painting order
RaiseBrowserToTop (new) moves a browser to the top of the painting order, and notifies embedder accordingly
embedder →* constellation
FocusBrowser (new) makes a browser focused for keyboard events
UnfocusBrowser (new) makes no browser focused for keyboard events
ForwardEvent (existing) also notifies embedder when an event was hit-tested to a browser
WindowVisibility (was ChangeBrowserVisibility) now notifies all browsers at once
constellation → compositor
UpdateBrowser (was SetFrameTree) adds or updates a browser without clobbering others
RemoveBrowser (new) removes a browser from .browser and .pipeline_details
MoveResizeBrowser (new) updates a browser’s rect, and sends new viewport to script in descendant pipelines
embedder ← constellation ←* compositor
BrowserPaintingOrder (new) notifies embedder of a new painting order
embedder ← constellation
BrowserOpened (was BrowserCreated) notifies embedder that a browser was opened
BrowserClosed (was CloseBrowser) notifies embedder that a browser was closed
BrowserFocused (new) notifies embedder that a browser gained focus for keyboard events
BrowserUnfocused (new) notifies embedder that all browsers lost focus for keyboard events
HitTestedEvent (new) notifies embedder that an event was hit-tested to a browser
* all of these are in the same enum ConstellationMsg (components/shared/compositing/constellation_msg.rs), which is a very confusing design that conflates the embedder with the compositor
[x] painting
[x] egui then servo, naïve
[x] ~~egui then servo or servo then egui, with stencil~~ — may need egui and webrender modifications
[x] interleave egui and servo
future: separate webrender documents and partial present?
TIMEOUT [expected PASS] subtest: Autofocus elements queued in another top-level browsing context's documents should be skipped. Test timed out
OK /html/semantics/forms/form-submission-0/form-submit-iframe-then-location-navigate.html (#29634)
FAIL [expected PASS] subtest: Verifies that location navigations take precedence when following form submissions. assert_equals: expected "/html/semantics/forms/form-submission-0/resources/location.html" but got "/html/semantics/forms/form-submission-0/resources/form.html"
OK /html/syntax/parsing/DOMContentLoaded-defer.html (#21550)
FAIL [expected PASS] subtest: The end: DOMContentLoaded and defer scripts assert_false: DOMContentLoaded should not have fired before executing a task queued from a defer script expected false got true
TIMEOUT [expected FAIL] subtest: Fulfillment handler on pending-then-fulfilled promise Test timed out
TIMEOUT [expected FAIL] subtest: Rejection handler on pending-then-rejected promise Test timed out
OK [expected TIMEOUT] /html/webappapis/scripting/processing-model-2/unhandled-promise-rejections/promise-rejection-events.html (#26371)
FAIL [expected TIMEOUT] subtest: delayed handling: delaying handling rejected promise created from createImageBitmap will cause both events to fire assert_array_equals: expected property 0 to be "InvalidStateError" but got "NotSupportedError" (expected array ["InvalidStateError"] got ["NotSupportedError"])
OK [expected TIMEOUT] /webaudio/the-audio-api/the-audiocontext-interface/audiocontext-not-fully-active.html (#27664)
Stable unexpected results that are known to be intermittent (26)
OK /css/cssom-view/CaretPosition-001.html (#21338)
FAIL [expected PASS] subtest: Element at (400, 100) assert_equals: Expected value for element id is 'box2' expected Element node <div id="box2" class="box"></div> but got null
OK /html/browsers/browsing-the-web/navigating-across-documents/initial-empty-document/load-pageshow-events-iframe-contentWindow.html (#28681)
FAIL [expected PASS] subtest: load & pageshow events do not fire on contentWindow of <iframe> element created with src='' assert_unreached: load should not be fired Reached unreachable code
FAIL [expected PASS] subtest: load & pageshow events do not fire on contentWindow of <iframe> element created with src='about:blank' assert_unreached: load should not be fired Reached unreachable code
OK /html/browsers/browsing-the-web/navigating-across-documents/javascript-url-return-value-handling-dynamic.html (#28066)
FAIL [expected PASS] subtest: 0041 set in href="" targeting a frame and clicked assert_equals: expected "A" but got ""
FAIL [expected PASS] subtest: 0080 00FF set in href="" targeting a frame and clicked assert_equals: expected "ÿ" but got ""
FAIL [expected PASS] subtest: 0080 00FF 0100 set in href="" targeting a frame and clicked assert_equals: expected "ÿĀ" but got ""
FAIL [expected PASS] subtest: D83D DE0D set in href="" targeting a frame and clicked assert_equals: expected "😍" but got ""
OK /html/browsers/history/the-history-interface/traverse_the_history_1.html (#21383)
PASS [expected FAIL] subtest: Multiple history traversals from the same task
OK [expected TIMEOUT] /html/canvas/element/pixel-manipulation/2d.imageData.get.large.crash.html (#29086)
FAIL [expected PASS] subtest: Test that canvas crash when image data cannot be allocated. assert_throws_js: function "function() { ctx.getImageData(10, 0xffffffff, 2147483647, 10); }" threw object "IndexSizeError: The index is not in the allowed range." ("IndexSizeError") expected instance of function "function TypeError() {
[native code]
}" ("TypeError")
FAIL [expected TIMEOUT] subtest: The entry settings object while executing the compiled callback via Web IDL's invoke must be that of the node document assert_equals: expected "/html/webappapis/scripting/events/resources/open-window.html" but got "blank"
FAIL [expected PASS] subtest: Test: Hit testing works well with nested stacking contexts assert_true: Should report at least one element expected true got false
OK /css/CSS2/normal-flow/block-in-inline-hittest-float-002.html
FAIL [expected PASS] subtest: with background assert_equals: expected Element node <div class="float"></div> but got Element node <div class="float"></div>
FAIL [expected PASS] subtest: with padding assert_equals: expected Element node <div class="float"></div> but got Element node <div class="float"></div>
FAIL [expected PASS] subtest: floats before block-in-inline assert_equals: expected Element node <div class="float"></div> but got Element node <div class="float"></div>
FAIL [expected PASS] subtest: floats before block-in-inline with background assert_equals: expected Element node <div class="float"></div> but got Element node <div class="float"></div>
OK /css/css-position/animations/bottom-interpolation.html
PASS [expected FAIL] subtest: CSS Transitions: property <bottom> from neutral to [20px] at (1.5) should be [25px]
PASS [expected FAIL] subtest: CSS Transitions with transition: all: property <bottom> from neutral to [20px] at (1.5) should be [25px]
PASS [expected FAIL] subtest: CSS Animations: property <bottom> from neutral to [20px] at (1.5) should be [25px]
PASS [expected FAIL] subtest: CSS Transitions with transition-behavior:allow-discrete: property <bottom> from [initial] to [20px] at (0.6) should be [20px]
PASS [expected FAIL] subtest: CSS Transitions with transition-property:all and transition-behavor:allow-discrete: property <bottom> from [initial] to [20px] at (0.6) should be [20px]
PASS [expected FAIL] subtest: CSS Transitions: property <bottom> from [initial] to [20px] at (0.6) should be [20px]
PASS [expected FAIL] subtest: CSS Transitions with transition: all: property <bottom> from [initial] to [20px] at (0.6) should be [20px]
PASS [expected FAIL] subtest: CSS Transitions: property <bottom> from [inherit] to [20px] at (1.5) should be [15px]
PASS [expected FAIL] subtest: CSS Transitions with transition: all: property <bottom> from [inherit] to [20px] at (1.5) should be [15px]
PASS [expected FAIL] subtest: CSS Animations: property <bottom> from [inherit] to [20px] at (1.5) should be [15px]
OK /css/cssom-view/HTMLBody-ScrollArea_quirksmode.html
FAIL [expected PASS] subtest: When body not potentially scrollable, document.body.scrollHeight always equals window.innerHeight in quirks. (cond. visible, scroll) assert_greater_than: Window not large enough for valid test run. expected a number greater than 400 but got 240
FAIL [expected PASS] subtest: When body not potentially scrollable, document.body.scrollHeight always equals window.innerHeight in quirks. (cond. scroll, visible) assert_greater_than: Window not large enough for valid test run. expected a number greater than 400 but got 240
FAIL [expected PASS] subtest: When body not potentially scrollable, document.body.scrollHeight always equals window.innerHeight in quirks. (cond. visible, visible) assert_greater_than: Window not large enough for valid test run. expected a number greater than 400 but got 240
OK /css/cssom-view/elementFromPoint-subpixel.html
FAIL [expected PASS] subtest: Hit test top left corner of box assert_equals: expected Element node <div class="box" id="box">
<div class="child"></div... but got null
FAIL [expected PASS] subtest: Hit test top right corner of box assert_equals: expected Element node <div class="box" id="box">
<div class="child"></div... but got null
FAIL [expected PASS] subtest: Hit test bottom left corner of box assert_equals: expected Element node <div class="box" id="box">
<div class="child"></div... but got null
FAIL [expected PASS] subtest: Hit test lower left corner of box assert_equals: expected Element node <div class="box" id="box">
<div class="child"></div... but got null
OK /css/cssom-view/elementsFromPoint-simple.html
FAIL [expected PASS] subtest: elementsFromPoint for each corner of a div that has a margin assert_equals: document.elementsFromPoint(1,384) expected "DIV#withMargin, BODY, HTML" but got ""
FAIL [expected PASS] subtest: elementsFromPoint for each corner of a div with pointer-events:none assert_equals: document.elementsFromPoint(51,349) expected "DIV#withMargin, BODY, HTML" but got ""
OK /css/cssom-view/elementsFromPoint.html
FAIL [expected PASS] subtest: no hit target at x,y assert_array_equals: Should have returned the sequence [body, html] lengths differ, expected array [Element node <body>
<div id="purple" class="size purple"> </div..., Element node <html><head><title>cssom-view - elementsFromPoint</title>...] length 2, got [] length 0
TIMEOUT [expected PASS] subtest: Test that crossorigin iframe navigations are not observable by the parent, even after history navigations by the parent Test timed out
NOTRUN [expected PASS] subtest: Test that cross-site iframe navigations are not observable by the parent, even after history navigations by the parent
NOTRUN [expected PASS] subtest: Test that iframe navigations are not observable by the parent
NOTRUN [expected PASS] subtest: Test that crossorigin iframe navigations are not observable by the parent
NOTRUN [expected PASS] subtest: Test that cross-site iframe navigations are not observable by the parent
NOTRUN [expected TIMEOUT] subtest: Test that iframe refreshes are not observable by the parent
OK /css/css-fonts/variations/at-font-face-font-matching.html (#20684)
FAIL [expected PASS] subtest: Matching font-weight: '430' should prefer '420 440' over '450 460' assert_not_equals: Sanity test: different family get different width got disallowed value 304
FAIL [expected PASS] subtest: Matching font-weight: '430' should prefer '450 460' over '500' assert_not_equals: Sanity test: different family get different width got disallowed value 304
FAIL [expected PASS] subtest: Matching font-weight: '430' should prefer '501 550' over '502 560' assert_not_equals: Sanity test: different family get different width got disallowed value 304
FAIL [expected PASS] subtest: Matching font-weight: '500' should prefer '500' over '450 460' assert_not_equals: Sanity test: different family get different width got disallowed value 304
FAIL [expected PASS] subtest: Matching font-weight: '500' should prefer '400' over '350 399' assert_not_equals: Sanity test: different family get different width got disallowed value 304
FAIL [expected PASS] subtest: Matching font-weight: '501' should prefer '502 510' over '503 520' assert_not_equals: Sanity test: different family get different width got disallowed value 304
FAIL [expected PASS] subtest: Matching font-weight: '501' should prefer '500' over '450 460' assert_not_equals: Sanity test: different family get different width got disallowed value 304
FAIL [expected PASS] subtest: Matching font-stretch: '90%' should prefer '110% 140%' over '120% 130%' assert_not_equals: Sanity test: different family get different width got disallowed value 304
FAIL [expected PASS] subtest: Matching font-style: 'italic' should prefer 'italic' over 'oblique 20deg' assert_not_equals: Sanity test: different family get different width got disallowed value 304
FAIL [expected PASS] subtest: Matching font-style: 'italic' should prefer 'normal' over 'oblique 0deg' assert_not_equals: Sanity test: different family get different width got disallowed value 304
OK /css/cssom-view/CaretPosition-001.html (#21338)
FAIL [expected PASS] subtest: Element at (400, 100) assert_equals: Expected value for element id is 'box2' expected Element node <div id="box2" class="box"></div> but got null
OK /css/cssom-view/elementsFromPoint-invalid-cases.html (#21338)
FAIL [expected PASS] subtest: The root element is the last element returned for otherwise empty queries within the viewport assert_equals: document.elementsFromPoint(300,300) expected "HTML" but got ""
FAIL [expected PASS] subtest: sec-fetch-site - Not sent to non-trustworthy same-origin destination, no attributes promise_test: Unhandled rejection with value: object "Error: Failed to query for recorded headers."
OK [expected TIMEOUT] /html/browsers/browsing-the-web/history-traversal/srcdoc/consecutive-srcdoc.html (#29084)
FAIL [expected TIMEOUT] subtest: changing srcdoc to about:srcdoc#yo then another srcdoc does two push navigations and we can navigate back promise_test: Unhandled rejection with value: object "TypeError: iframe is null"
OK /html/browsers/browsing-the-web/navigating-across-documents/replace-before-load/a-click.html (#28697)
FAIL [expected PASS] subtest: aElement.click() before the load event must NOT replace assert_equals: expected "http://web-platform.test:8000/common/blank.html?thereplacement" but got "http://web-platform.test:8000/html/browsers/browsing-the-web/navigating-across-documents/replace-before-load/resources/code-injector.html?pipe=sub(none)&code=%0A%20%20%20%20const%20a%20%3D%20document.createElement(%22a%22)%3B%0A%20%20%20%20a.href%20%3D%20%22%2Fcommon%2Fblank.html%3Fthereplacement%22%3B%0A%20%20%20%20document.currentScript.before(a)%3B%0A%20%20%20%20a.click()%3B%0A%20%20"
OK /workers/dedicated-worker-from-blob-url.window.html (#22286)
FAIL [expected PASS] subtest: Creating a dedicated worker from a blob URL works immediately before revoking. promise_test: Unhandled rejection with value: object "[object Event]"
FAIL [expected PASS] subtest: Test: Hit testing works well with nested stacking contexts assert_true: Should report at least one element expected true got false
OK /css/cssom-view/HTMLBody-ScrollArea_quirksmode.html
FAIL [expected PASS] subtest: When body not potentially scrollable, document.body.scrollHeight always equals window.innerHeight in quirks. (cond. visible, scroll) assert_greater_than: Window not large enough for valid test run. expected a number greater than 400 but got 240
FAIL [expected PASS] subtest: When body not potentially scrollable, document.body.scrollHeight always equals window.innerHeight in quirks. (cond. scroll, visible) assert_greater_than: Window not large enough for valid test run. expected a number greater than 400 but got 240
FAIL [expected PASS] subtest: When body not potentially scrollable, document.body.scrollHeight always equals window.innerHeight in quirks. (cond. visible, visible) assert_greater_than: Window not large enough for valid test run. expected a number greater than 400 but got 240
OK /css/cssom-view/elementsFromPoint-simple.html
FAIL [expected PASS] subtest: elementsFromPoint for each corner of a div that has a margin assert_equals: document.elementsFromPoint(1,384) expected "DIV#withMargin, BODY, HTML" but got ""
FAIL [expected PASS] subtest: elementsFromPoint for each corner of a div with pointer-events:none assert_equals: document.elementsFromPoint(51,349) expected "DIV#withMargin, BODY, HTML" but got ""
OK /css/cssom-view/elementsFromPoint.html
FAIL [expected PASS] subtest: no hit target at x,y assert_array_equals: Should have returned the sequence [body, html] lengths differ, expected array [Element node <body>
<div id="purple" class="size purple"> </div..., Element node <html><head><title>cssom-view - elementsFromPoint</title>...] length 2, got [] length 0
OK /css/cssom/getComputedStyle-insets-relpos-inline.html
FAIL [expected PASS] subtest: OOF with left fixed right auto in relpos inline container assert_equals: expected "140px" but got "20px"
FAIL [expected PASS] subtest: OOF with left auto right fixed in relpos inline container assert_equals: expected "140px" but got "20px"
FAIL [expected PASS] subtest: OOF with left fixed right auto in relpos inline container with mixed directions assert_equals: expected "140px" but got "20px"
FAIL [expected PASS] subtest: OOF with left auto right fixed in relpos inline container with mixed directions assert_equals: expected "140px" but got "20px"
OK /html/browsers/browsing-the-web/navigating-across-documents/navigation-unload-same-origin-fragment.html (#20768)
FAIL [expected PASS] subtest: Tests that a fragment navigation in the unload handler will not block the initial navigation assert_equals: expected "" but got "#fragment"
OK /html/browsers/browsing-the-web/navigating-across-documents/navigation-unload-same-origin.window.html (#29049)
PASS [expected FAIL] subtest: Same-origin navigation started from unload handler must be ignored
OK /css/css-fonts/variations/at-font-face-font-matching.html (#20684)
FAIL [expected PASS] subtest: Matching font-weight: '430' should prefer '420 440' over '450 460' assert_equals: Unexpected font on test element expected 487 but got 532
FAIL [expected PASS] subtest: Matching font-weight: '430' should prefer '450 460' over '500' assert_equals: Unexpected font on test element expected 487 but got 532
FAIL [expected PASS] subtest: Matching font-weight: '430' should prefer '501 550' over '502 560' assert_equals: Unexpected font on test element expected 487 but got 532
FAIL [expected PASS] subtest: Matching font-weight: '500' should prefer '500' over '450 460' assert_equals: Unexpected font on test element expected 487 but got 532
FAIL [expected PASS] subtest: Matching font-weight: '500' should prefer '400' over '350 399' assert_equals: Unexpected font on test element expected 487 but got 532
FAIL [expected PASS] subtest: Matching font-weight: '501' should prefer '502 510' over '503 520' assert_equals: Unexpected font on test element expected 487 but got 532
FAIL [expected PASS] subtest: Matching font-weight: '501' should prefer '500' over '450 460' assert_equals: Unexpected font on test element expected 487 but got 532
FAIL [expected PASS] subtest: Matching font-stretch: '90%' should prefer '110% 140%' over '120% 130%' assert_equals: Unexpected font on test element expected 487 but got 532
FAIL [expected PASS] subtest: Matching font-style: 'italic' should prefer 'italic' over 'oblique 20deg' assert_equals: Unexpected font on test element expected 487 but got 532
FAIL [expected PASS] subtest: Matching font-style: 'italic' should prefer 'normal' over 'oblique 0deg' assert_equals: Unexpected font on test element expected 487 but got 532
OK [expected TIMEOUT] /html/browsers/browsing-the-web/history-traversal/srcdoc/consecutive-srcdoc.html (#29084)
FAIL [expected TIMEOUT] subtest: changing srcdoc to about:srcdoc#yo then another srcdoc does two push navigations and we can navigate back promise_test: Unhandled rejection with value: object "TypeError: iframe is null"
OK /html/browsers/browsing-the-web/navigating-across-documents/javascript-url-return-value-handling-dynamic.html (#28066)
PASS [expected FAIL] subtest: 0041 set in href="" targeting a frame and clicked
PASS [expected FAIL] subtest: 0080 00FF set in href="" targeting a frame and clicked
PASS [expected FAIL] subtest: 0080 00FF 0100 set in href="" targeting a frame and clicked
OK /html/browsers/the-window-object/open-close/creating_browsing_context_test_01.html (#29046)
PASS [expected FAIL] subtest: first argument: absolute url
TIMEOUT [expected FAIL] subtest: Autofocus elements in top-level browsing context's documents with non-existent fragments should work. Test timed out
OK [expected TIMEOUT] /html/semantics/embedded-content/the-iframe-element/iframe_sandbox_popups_nonescaping-1.html (#24066)
FAIL [expected NOTRUN] subtest: Check that popups from a sandboxed iframe do not escape the sandbox assert_equals: It came from a sandboxed iframe expected "null" but got "http://web-platform.test:8000"
OK /html/semantics/embedded-content/the-img-element/non-active-document.html (#21544)
PASS [expected FAIL] subtest: createHTMLDocument
PASS [expected FAIL] subtest: <template>
OK /html/semantics/forms/form-submission-0/text-plain.window.html (#28687)
FAIL [expected PASS] subtest: text/plain: 0x00 in value (normal form) assert_equals: expected "a=b\0c\r\n" but got ""
OK /html/semantics/forms/form-submission-0/urlencoded2.window.html (#28687)
FAIL [expected PASS] subtest: application/x-www-form-urlencoded: single quote in name (normal form) assert_equals: expected "a%27b=c" but got ""
OK /html/semantics/scripting-1/the-script-element/execution-timing/077.html (#22139)
PASS [expected FAIL] subtest: adding several types of scripts through the DOM and removing some of them confuses scheduler
OK /workers/dedicated-worker-from-blob-url.window.html (#22286)
FAIL [expected PASS] subtest: Creating a dedicated worker from a blob URL works immediately before revoking. promise_test: Unhandled rejection with value: object "[object Event]"