Skip to content
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

LibWeb: Unbreak (help://) links in the Help app #25662

Open
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

MacDue
Copy link
Member

@MacDue MacDue commented Jan 19, 2025

See commits for details.

Fixes #25288 (note: this did not just affect "see also" links, but any help:// link)

@github-actions github-actions bot added the 👀 pr-needs-review PR needs review from a maintainer or community member label Jan 19, 2025
@MacDue MacDue force-pushed the help_links branch 2 times, most recently from debdd48 to 80bd342 Compare January 19, 2025 11:35
The switch to using navigables to load links in c7a6d41 and 38461a7
started the breakage of `help://` URLs. The old FrameLoader (now gone)
used to just do nothing when presented with a `help://`, navigables
(while attempting to follow the spec) crash. Supporting `help://` URLS
(in the Help app) does not need the complexity of navigables, so we can
just bail out at a reasonable point.

Note that 38461a7 removed sending the `page_did_click_link` to the
client, without this event the Help app does not know about any link
clicks, so can't handle the navigation itself (which is needed for
custom schemes).
d0e18b8 revived sending the `page_did_click_link` event, but only for
a chrome feature where ctrl is also clicked. For the Help app to work
normally (not just when pressing ctrl), we need this event to be sent
no matter the modifier. The modifiers are sent as part of the event so
chromes can ignore non-control clicks.
@nico
Copy link
Contributor

nico commented Jan 19, 2025

@trflynn89 Does this look like a good approach?

@@ -333,8 +333,7 @@ EventResult EventHandler::handle_mouseup(CSSPixelPoint viewport_position, CSSPix
JS::NonnullGCPtr<DOM::Document> document = *m_navigable->active_document();
auto href = link->href();
auto url = document->parse_url(href);

if (button == UIEvents::MouseButton::Primary && (modifiers & UIEvents::Mod_PlatformCtrl) != 0) {
if (button == UIEvents::MouseButton::Primary) {
m_navigable->page().client().page_did_click_link(url, link->target().to_byte_string(), modifiers);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happens now when we click a normal link? IIRC non-ctrl clicks go through the anchor element's activation behavior, so does this cause that navigation to happen twice?

Copy link
Member Author

@MacDue MacDue Jan 19, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It does navigate twice, though I don't think for the reason you mention here. The problem is all the chromes still call load_url (when ctrl is not set) within there handler for on_link_click, which has been (partially) dead code for a while now. It's made slightly awkward by some questionable reuse of the on_link_click callback too (it's called by places other than the web content client, which means in some places may still needs the load_url behaviour.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've pushed a fix for Ladybird and Browser (can't really do the macOS stuff, since I don't have mac).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I were to do the mac bits, what would I do to test I haven't broken anything (or rather, that I fixed something)?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the changes needed are just:

The on_link_click callback should only do anything when the control modifier is set (to match that previously LibWeb only sent this event when control is held).

m_web_view_bridge->on_link_click = [weak_self](auto const& url, auto const& target, unsigned modifiers) {
LadybirdWebView* self = weak_self;
if (self == nil) {
return;
}
if (modifiers == Web::UIEvents::KeyModifier::Mod_Super) {
[self.observer onCreateNewTab:url activateTab:Web::HTML::ActivateTab::No];
} else if (target == "_blank"sv) {
[self.observer onCreateNewTab:url activateTab:Web::HTML::ActivateTab::Yes];
} else {
[self.observer loadURL:url];
}
};

This openLink function should direly call loadURL rather than reuse the on_link_click callback.

- (void)openLink:(id)sender
{
m_web_view_bridge->on_link_click(m_context_menu_url, {}, 0);
}


Then to check if "openLink" works, try a context menu event (like "Open Image"). For the on_link_click callback, just try clicking any link (and check it opens without requesting the page twice).

The `on_link_click` callback has not been called from LibWeb for
anything other than control clicks for a while now. So to avoid double
loads, now that this event has been restored for all link clicks, this
callback should ignore anything other than control clicks.

Other (slightly improper) uses of the callback have been updated to use
the underlying methods to preserve the correct behaviour.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
👀 pr-needs-review PR needs review from a maintainer or community member
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Help: Clicking "See also" links doesn't work
3 participants