StarCitizenTools / mediawiki-extensions-TabberNeue

A MediaWiki extension that allows wiki to create tabs.
https://www.mediawiki.org/wiki/Extension:TabberNeue
GNU General Public License v3.0
13 stars 15 forks source link

Browser search finds text from all tabs instead of only active one #80

Open Vishkujo opened 1 year ago

Vishkujo commented 1 year ago

When searching on your browser with Ctrl F, it shows results from all tabs instead of only the currently active one. As a result, it highlights hidden content from the other tabs. Since the tab doesn't change, you can't see what was found unless you manually switch the tabs. Users reported that the older Tabber extension did not do this and only showed results from the current tab.

Ideally I think it should either show only the current tab's results, or if possible, automatically switch the tab if it highlights text from a different tab.

Example of where you can see this happening (try searching for any month like January, and you'll see there's 100 results instead of only 12 for the first tab).

alistair3149 commented 1 year ago

This is definitely a bug. Ideally tabber should switch to the tab where the text is highlighted. I am not sure how to achieve that though. If anyone knows how, any help is appreciated!

ferdnyc commented 12 months ago

@alistair3149 It might be possible to handle this by placing a focus event listener on all of the content panes for the tabber, and switching to whichever one gains focus anytime the event fires. (I assume that the browser's search highlighting moves focus to the current search match, as it's cycling through them.)

alistair3149 commented 4 months ago

This is tricky.

Browsers do not fire any event or do any DOM modifications when a match is found. It is quite difficult to exclude HTML from Find in text. I am not sure if it is even fixable...

ferdnyc commented 4 months ago

Hmm. That's unfortunate.

I guess the old tabber must've only populated the current tab with content, and left all the other tabs empty until it performed an AJAX request when they were switched to. (And/or deleted the content when they were switched away from). That's the only other way I can think of, that it would've avoided matching text from other tabs.

(EDIT: Actually it wouldn't need to use AJAX, just store the content for the other tabs outside of the DOM somewhere locally, and only insert it into the DOM when a tab becomes active.)

alistair3149 commented 4 months ago

Hmm. That's unfortunate.

I guess the old tabber must've only populated the current tab with content, and left all the other tabs empty until it performed an AJAX request when they were switched to. (And/or deleted the content when they were switched away from). That's the only other way I can think of, that it would've avoided matching text from other tabs.

(EDIT: Actually it wouldn't need to use AJAX, just store the content for the other tabs outside of the DOM somewhere locally, and only insert it into the DOM when a tab becomes active.)

The old Tabber applies a display:none directly on the whole panel, which effectively hides the whole tab from everything, including screen readers. Lazy loading from AJAX or attribute might not be a good idea too because it takes the content away from the DOM, which means web crawlers can't get them.

ferdnyc commented 4 months ago

(!) According to Chrome, there is an event that fires on matches: beforematch. At least, in supporting browsers.

(There's also an HTML attribute, hidden=until-found, that can be combined with the event to make collapsed content auto-expand when there's an inner search match, tho it's not immediately clear how that would help tabbed content.)

MDN lists beforematch as supported in recent Chrome, Edge, and Opera, but not Firefox or Safari.

ferdnyc commented 4 months ago

Ah, here's the rub, from MDN:

An element receives a beforematch event when it is in the hidden until found state and the browser is about to reveal its content because the user has found the content through the "find in page" feature or through fragment navigation.

So, even in supporting browsers, beforematch only works when combined with hidden=until-found.

It's also kind of strange, how it works in practice.

In the example they give at the end of the article, in Firefox (which doesn't support hidden=until-found / beforematch), the second <div> is completely hidden at all times, and the example doesn't work:

image

In Chrome (which purports to support hidden=until-found and beforematch), the second <div> is actually visible even before the navigation event causes the beforematch handler to fire. The event then inserts content into the already-visible <div>:

Before

image

After

image

ferdnyc commented 4 months ago

It seems that, even in Chrome, you also have to style the hidden="until-found" content as hidden, in order to actually hide it. Then, you can update the styling in the onbeforematch handler to reveal it. AFAICT hidden="until-found" only affects the receivability of beforematch, not the content's actual visibility. It's very odd.