New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[url_launcher][web] Fix Link issues when Semantics are enabled #6579
base: main
Are you sure you want to change the base?
Conversation
static bool followLinkTriggered = false; | ||
|
||
/// Keeps track of the last mouse event captured from our global click handler. | ||
static html.MouseEvent? triggeredMouseEvent; |
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.
Suggestion:
static html.MouseEvent? triggeredMouseEvent; | |
static html.MouseEvent? lastMouseEvent; |
triggeredMouseEvent = event; | ||
|
||
if (followLinkTriggered) { | ||
final int? viewId = getViewIdFromTarget(event) ?? _hitTestedViewId; | ||
|
||
_instances[viewId]?._triggerLink(event: event, isKeyboardEvent: false); | ||
// After the DOM click event has been received, clean up the hit test state | ||
// so we can start fresh on the next event. | ||
unregisterHitTest(); | ||
} |
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.
We have to do the same thing for keyboard events too.
@@ -222,11 +262,26 @@ class LinkViewController extends PlatformViewController { | |||
/// `click` from the browser. | |||
static void registerHitTest(LinkViewController controller) { | |||
_hitTestedViewId = controller.viewId; | |||
followLinkTriggered = true; | |||
|
|||
if (triggeredMouseEvent != null) { |
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.
We should do the same for keyboard events (we probably don't need a triggeredKeyboardEvent
, but we need a boolean at least).
Here's how I would do it, but feel free to adjust/modify it to how you see fit:
// Set to true in registerHitTest()
static bool followLinkTriggered = false;
// Set to true in _onGlobalClick() and _onGlobalKeydown()
static bool domEventTriggered = false;
// Set only in _onGlobalClick()
static html.Event? triggeredEvent;
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.
Based on my testing, the keyboard event path doesn't deviate from hit test -> global keydown. Do you think this boolean is necessary because there would be a case where the browser keydown handler executes before the framework handles it?
I had to be pretty careful about this in the click handler because we were running into issues where the dom event trigger was being set to true for arbitrary clicks (e.g. clicking elsewhere on the app). This led to issues where we would trigger the link twice if the event path went hit test -> global click
// We only want to cache the mouse event if its target is a link, so that | ||
// we can later prevent its default behavior and handle how it should | ||
// open the link ourselves. | ||
if(isLinkElement(targetElement) || isSemanticLinkElement(targetElement)) { |
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.
@mdebbar I had to add this to fix the issue of caching mouse events that aren't relevant to us (since the global handler captures every mouse event).
I added isSemanticLinkElement
which just checks if the target element is a semantic node that's wrapped within an <a>
tag. Is this robust enough to handle the semantic link case? Or should we find a way to associate a platform view's viewId
to the generated semantic nodes?
DRAFT PR - will add tests shortly.
This PR fixes an issue where Links break in Semantics mode (clicking links does nothing) because the Link's child semantics obscure the platform view.
The fix:
PlatformViewLink
so we can consolidate all of the link information in a single place. Also exclude it from the focus tree to fix the "double tabbing" issue.<a>
tag to enable the context menu and provide link preview info. This requires a separate engine PR.stopPropagation
being called in the engine), so we have to handle click events in thecapture
phase.For keydown events, things remain the same:
followLink
, registers a hit test view idviewId
For click events, things are slightly different depending on if the node that's clicked is a semantic node or a platform view link.
Clicking platform view links will behave similarly to keydown events.
Clicking the generated semantic node of a link (specifically its children) will behave as follows:
followLink
, registers a hit test view id. Triggers link behavior using the registeredviewId
Fixes flutter/flutter#143164
Pre-launch Checklist
dart format
.)[shared_preferences]
pubspec.yaml
with an appropriate new version according to the [pub versioning philosophy], or this PR is [exempt from version changes].CHANGELOG.md
to add a description of the change, [following repository CHANGELOG style].///
).