This repository was archived by the owner on Feb 25, 2025. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 6k
[web] Render in custom target #37738
Merged
Merged
Changes from 1 commit
Commits
Show all changes
58 commits
Select commit
Hold shift + click to select a range
0c265d1
Introduce FullScreenApplicationDom, and wire it to meta viewport, eve…
ditman 87f1c91
Move internal stylesheet to HostNode from ViewEmbedder.
ditman 9dd964b
Add setHostStyles and Attribute to ApplicationDom. Use it in the embe…
ditman 48ddb1b
Move HotRestartCacheHandler to its own file.
ditman ca8db3e
Remove Safari hack for visualViewport.
ditman 9b88880
No need to keep a ref to the viewport meta in full-screen.
ditman 7cc8cf3
Add applicationDom.attachGlassPane and use it in the Embedder.
ditman 10cf86e
Remove empty method bodies.
ditman 58fb7d5
Add attachResourcesHost and use it from the embedder.
ditman 769b4b6
Removed some unused code.
ditman eac7d73
Some more cleanup.
ditman b43417d
Add ResizeObserver JS interop API.
ditman 140d7cf
Add the CustomElementApplicationDom and wire it to the ViewEmbedder.
ditman ddc9c9c
Add the DimensionsProvider classes.
ditman f798750
Reimplement engine.window using the DimensionsProvider.
ditman 1064d64
Delegate window metrics to engine window in html scene object.
ditman 8d618d7
Wire DimensionsProvider into engine.window.
ditman d40ecb4
Moved ApplicationDom into its own subdir.
ditman 77cd76a
Make DimensionsProvider also an Observer. Expose onResize Stream.
ditman 0c9d2c0
Delegate onResize and dpr from window to DimensionsObserver object.
ditman 6fba209
Remove or make most ApplicationDom methods private. Expose single ini…
ditman 86d1c74
Hook the new API.
ditman c30f13e
dart format
ditman 6fbdbd3
ApplicationDom -> EmbeddingStrategy.
ditman 19b5cf2
Attach pointer move events to glassPaneElement
ditman 641bba7
Use offset positions for mouse events (relative to host element) rath…
ditman f773333
Update TouchAdapter to understand scrolling (simulate offsetX/Y)
ditman d3cf9d3
Remove locale change handling from the embedding strategy.
ditman 5a180db
Move locale handling from the embedder to the platform dispatcher
ditman 74f639f
Move some styles from host to glassPane so we are more friendly with …
ditman dee3f54
Make analyzer fixes
ditman 1811c17
Ensure DimensionsProvider is available in tests.
ditman 0d89e8e
Initialize the view DimensionsProvider next to where the EmbeddingStr…
ditman 44725be
Bring back the logic to support Firefox 83.
ditman 649116a
Fix pointer_binding test for new anchor point in the DOM.
ditman 9d3c903
Fix pointer_binding_test in Firefox.
ditman 3b69e0b
Add an iterable way of accessing 'rules'
ditman f217f9d
Merge latest changes to host_node stylesheet.
ditman 5d469b1
Format test
ditman 4cc8ce6
Try to use insertRule for -ms-reveal, and fallback in tests.
ditman 264e3a4
Test hot_restart_cache_handler
ditman be99c2a
Test dimensions_provider.
ditman 3eb9321
Test full_page_dimensions_provider
ditman 9019df4
Test custom_element_dimensions_provider
ditman 8834630
Test embedding_strategy. Make getDomCache util public.
ditman 079d201
Fixes and tests for *_embedding_strategy.
ditman 9a6702b
Move default text colors to our innermost style inside host_node (app…
ditman f4ff288
Safari expands shorthand properties in CSSOM.
ditman 42e4298
Add computeEventOffsetToTarget function, and use it.
ditman a7447ac
Address PR comments.
ditman d1b93ba
Update licenses_flutter.
ditman 5e48d3d
Remove DomCSSRuleList class and instead use Iterable of DomCSSRule
ditman 53de810
Make the embeddingStrategy final instead of late
ditman 0a817a6
Attach mouse/pointermove events to domWindow.
ditman b293d36
Rename DimensionsProvider.onHotRestart to .close, and slightly improv…
ditman 76cec66
Fix compute physicalX/Y for TalkBack events.
ditman b48b397
Clarify what does (and does not) support 3D transforms in the event_p…
ditman 57dc432
Update licenses file
ditman File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
113 changes: 113 additions & 0 deletions
113
lib/web_ui/lib/src/engine/pointer_binding/event_position_helper.dart
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,113 @@ | ||
| // Copyright 2013 The Flutter Authors. All rights reserved. | ||
| // Use of this source code is governed by a BSD-style license that can be | ||
| // found in the LICENSE file. | ||
|
|
||
| import 'package:ui/ui.dart' as ui show Offset; | ||
|
|
||
| import '../dom.dart'; | ||
| import '../semantics.dart' show EngineSemanticsOwner; | ||
|
|
||
| /// Returns an [ui.Offset] of the position of [event], relative to the position of [actualTarget]. | ||
| /// | ||
| /// The offset is *not* multiplied by DPR or anything else, it's the closest | ||
| /// to what the DOM would return if we had currentTarget readily available. | ||
| /// | ||
| /// This needs an `actualTarget`, because the `event.currentTarget` (which is what | ||
| /// this would really need to use) gets lost when the `event` comes from a "coalesced" | ||
| /// event. | ||
| /// | ||
| /// It also takes into account semantics being enabled to fix the case where | ||
| /// offsetX, offsetY == 0 (TalkBack events). | ||
| // | ||
| // TODO(dit): Make this understand 3D transforms in the platform view case, https://github.com/flutter/flutter/issues/117091 | ||
ditman marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| ui.Offset computeEventOffsetToTarget(DomMouseEvent event, DomElement actualTarget) { | ||
| // On top of a platform view | ||
| if (event.target != actualTarget) { | ||
| return _computeOffsetOnPlatformView(event, actualTarget); | ||
| } | ||
| // On a TalkBack event | ||
| if (EngineSemanticsOwner.instance.semanticsEnabled && event.offsetX == 0 && event.offsetY == 0) { | ||
| return _computeOffsetForTalkbackEvent(event, actualTarget); | ||
| } | ||
| // Return the offsetX/Y in the normal case. | ||
| return ui.Offset(event.offsetX, event.offsetY); | ||
| } | ||
|
|
||
| /// Computes the event offset when hovering over a platformView. | ||
| /// | ||
| /// This still uses offsetX/Y, but adds the offset from the top/left corner of the | ||
| /// platform view to the glass pane (`actualTarget`). | ||
| /// | ||
| /// ×--FlutterView(actualTarget)--------------+ | ||
| /// |\ | | ||
| /// | x1,y1 | | ||
| /// | | | ||
| /// | | | ||
| /// | ×-PlatformView(target)---------+ | | ||
| /// | |\ | | | ||
| /// | | x2,y2 | | | ||
| /// | | | | | ||
| /// | | × (event) | | | ||
| /// | | \ | | | ||
| /// | | offsetX, offsetY | | | ||
| /// | | (Relative to PlatformView) | | | ||
| /// | +------------------------------+ | | ||
| /// +-----------------------------------------+ | ||
| /// | ||
| /// Offset between PlatformView and FlutterView (xP, yP) = (x2 - x1, y2 - y1) | ||
| /// | ||
| /// Event offset relative to FlutterView = (offsetX + xP, offsetY + yP) | ||
| ui.Offset _computeOffsetOnPlatformView(DomMouseEvent event, DomElement actualTarget) { | ||
| final DomElement target = event.target! as DomElement; | ||
| final DomRect targetRect = target.getBoundingClientRect(); | ||
| final DomRect actualTargetRect = actualTarget.getBoundingClientRect(); | ||
| final double offsetTop = targetRect.y - actualTargetRect.y; | ||
| final double offsetLeft = targetRect.x - actualTargetRect.x; | ||
| return ui.Offset(event.offsetX + offsetLeft, event.offsetY + offsetTop); | ||
| } | ||
|
|
||
| /// Computes the event offset when TalkBack is firing the event. | ||
| /// | ||
| /// In this case, we need to use the clientX/Y position of the event (which are | ||
| /// relative to the absolute top-left corner of the page, including scroll), then | ||
| /// deduct the offsetLeft/Top from every offsetParent of the `actualTarget`. | ||
| /// | ||
| /// ×-Page----║-------------------------------+ | ||
| /// | ║ | | ||
| /// | ×-------║--------offsetParent(s)-----+ | | ||
| /// | |\ | | | ||
| /// | | offsetLeft, offsetTop | | | ||
| /// | | | | | ||
| /// | | | | | ||
| /// | | ×-----║-------------actualTarget-+ | | | ||
| /// | | | | | | | ||
| /// ═════ × ─ (scrollLeft, scrollTop)═ ═ ═ | ||
| /// | | | | | | | ||
| /// | | | × | | | | ||
| /// | | | \ | | | | ||
| /// | | | clientX, clientY | | | | ||
| /// | | | (Relative to Page + Scroll) | | | | ||
| /// | | +-----║--------------------------+ | | | ||
| /// | +-------║----------------------------+ | | ||
| /// +---------║-------------------------------+ | ||
| /// | ||
| /// Computing the offset of the event relative to the actualTarget requires to | ||
| /// compute the clientX, clientY of the actualTarget. To do that, we iterate | ||
| /// up the offsetParent elements of actualTarget adding their offset and scroll | ||
| /// positions. Finally, we deduct that from clientX, clientY of the event. | ||
|
|
||
| ui.Offset _computeOffsetForTalkbackEvent(DomMouseEvent event, DomElement actualTarget) { | ||
| assert(EngineSemanticsOwner.instance.semanticsEnabled); | ||
| // Use clientX/clientY as the position of the event (this is relative to | ||
| // the top left of the page, including scroll) | ||
| double offsetX = event.clientX; | ||
| double offsetY = event.clientY; | ||
| // Compute the scroll offset of actualTarget | ||
| DomHTMLElement parent = actualTarget as DomHTMLElement; | ||
| while(parent.offsetParent != null){ | ||
| offsetX -= parent.offsetLeft - parent.scrollLeft; | ||
| offsetY -= parent.offsetTop - parent.scrollTop; | ||
| parent = parent.offsetParent!; | ||
| } | ||
| return ui.Offset(offsetX, offsetY); | ||
| } | ||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do logics in this file work if the host page has a non-zero scroll offset? I think scroll offset doesn't affect clientX/Y, but it will affect the position of the cursor relative to the elements.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, methods that only use offsetX/Y are relative to the glassPane/platformView, so the scroll position does not matter there.
The one that requires scroll handling is the pageX/Y one, because that gives us positions from the top left position of the page (with all its scroll position added).
See the pageY docs: https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/pageY