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

Notify page that "find in page" is being used #2858

Open
mitar opened this issue Jul 21, 2017 · 16 comments
Open

Notify page that "find in page" is being used #2858

mitar opened this issue Jul 21, 2017 · 16 comments
Labels
addition/proposal New features or enhancements needs implementer interest Moving the issue forward requires implementers to express interest

Comments

@mitar
Copy link

mitar commented Jul 21, 2017

(Migrating from https://www.w3.org/Bugs/Public/show_bug.cgi?id=27186)

Some Web apps don't load all their data. This makes "find in page" not work. We should have the browser tell the page that "find in page" is being used, and what is being searched for, so that the page can load in relevant content.

Examples: Google Docs, ACE editor used by GitHub, PDF.js, Discourse.

Currently, those apps intercept ctrl-f keyboard stroke and do their own search, but that means that search does not work well if you invoke it through browser's menu (like on mobile phones).

@domenic domenic added addition/proposal New features or enhancements needs implementer interest Moving the issue forward requires implementers to express interest labels Jul 21, 2017
@mitar
Copy link
Author

mitar commented Aug 7, 2017

Facebook and Tumblr are for example the same. They do not render the whole feed. The do not override in-browser search though, but that makes it ineffective. You scroll a long feed down and then you want to search something, and you can find things only among last few posts.

@trusktr
Copy link

trusktr commented Dec 12, 2017

This would be super useful for custom elements that have custom-rendering.

For example, imagine some custom elements that render to WebGL:

<threedee-scene>
  <text-node rotation="30 30 30" material="phong" cast-shadow="true">
    This is some text rendered with WebGL shaders.
  </text-node>
</threedee-scene>

It'd be neat to be able to get find-in-page to be able to show custom-rendered results somehow. It would open up a LOT of opportunities.

@js-choi
Copy link

js-choi commented Dec 12, 2017

Related to this is the discontinued FindText API draft by Doug Schepers (@shepazu), @AFBarstow, and @plehegar, which in 2015 attempted to standardize finding text selections in DOM.

@domenic
Copy link
Member

domenic commented Jan 14, 2018

I've been trying to think about what a minimal (i.e. not FindText) API along these lines would look like. I think we'd want to support two use cases:

  1. Replacing the default search experience entirely. People do this today by intercepting Ctrl+F, but as noted that doesn't work on e.g. mobile.
  2. Customizing the default search experience by getting notifications and reacting to them by loading data appropriately. I'd think this would be notifications for:
    • Search string/options change (e.g. the user types more, or the user checks/unchecks "case insensitive" or "whole words")
    • Next result
    • Previous result

I'd do this as:

// Use case (1)
window.addEventListener("findinpage", e => {
  e.preventDefault();
  showCustomUI();
});
// Use case (2)
window.addEventListener("findinginpage", e => {
  console.log(e.searchString);
  console.log(e.caseSensitive);
  console.log(e.wholeWordsOnly);
  
  // or maybe instead or in addition to:
  console.log(e.searchRegex);
  
  // Show some kind of indicator in the default search experience
  // that more data is loading; once the promise settles, do the
  // search again
  e.waitUntil(loadMoreDataIntoDOM());
});

window.addEventListener("findinginpagenext", e => {
  e.waitUntil(loadMoreDataIntoDOM());
});

window.addEventListener("findinginpageprevious", e => {
  e.waitUntil(loadMoreDataIntoDOM());
});

This seems like the right direction. I'm especially unsure about the next/previous design though. Maybe those should be in a single event, with some kind of "currently highlighted index" property on e or something? Dunno.

@js-choi
Copy link

js-choi commented Jan 15, 2018

I’m just a student, so whatever I say may be ill-informed—but I think it’s a great idea to decouple the interception of user-initiated-find events away from a general DOM-text search API (i.e., FindText, RangeFinder, etc.). The two problems are, in retrospect, pretty orthogonal.

However, the second use case in particular brings up some other questions: namely abortions and errors.

  1. Many, if not all, modern browsers implement a live, “instant” incremental search as you type. With each new keystroke, the browser may quickly jump to another part of the page.

    Asynchrony complicates this: It becomes possible for searches to take long periods of time, and a user might have already switched to another task after waiting too long. It would be annoying for the user to start an asynchronously loading search, then initiate another gesture, then see their browser suddenly jump because the original search finally loaded.

    It may therefore be useful to cancel and abort pending finds, preventing unexpected late jumps during another user task. It may be also reasonable to allow the user agent to have a timeout and cancel a long-running jump on its own. The same goes for cancelling finds after other user gestures such as user buttons. This cancellation might also be an event worth firing, but I don’t know.

    It might furthermore be useful to distinguish cancellation of a find from unexpected failure of a find. I know that I would value granular feedback from the browser’s UI, such as a little message in its search bar, when the connection suddenly drops and my loading search unexpectedly fails.

    I think that this latent-jump problem is important enough to usability such that it falls this issue’s scope. Hopefully its solution—whether it uses AbortSignal or something else—would not complicate things too badly.

  2. Seperately, it would also be useful to update the default search UI’s displayed match index and total number of matches, if those values are determinable by the server or a worker, before the matched content itself finishes loading.

Out of scope of this issue but hypothetically nice to have for both use cases: Being able to read and set the default browser search input à la the Clipboard API; and being able to highlight arbitrary DOM selections/ranges, in the same manner that browsers already do when they find text (though this might depend on pending issues such as #2424 and WICG/webcomponents#79).

@keithamus
Copy link
Contributor

@js-choi raises a good point, it would be nice to somehow interact with the list of search results the browser finds. It would be useful for certain usecases to also provide a list of matches that the browser should use as the search results. I would imagine most people disabling find are just looking to implement that UI themselves, so providing hooks to keep the default UI, but modify the results could be useful.

@domenic
Copy link
Member

domenic commented Jan 15, 2018

I'm very cautious about scope creep on the API to customize the default search. I think the more features we propose to add to it, the less likely it will get implemented at all. That said, providing an e.abortSignal to know when a search has been aborted makes sense.

@ojanvafai
Copy link

@js-choi's second point also seems important to me. I'm not sure about other browsers, but in chromium, we iteratively walk through the entire document to find all the results that match (with yield points to avoid jank). This is how we get the scrollbar highlighting of the matches and the count of matches in the find bar. How would that work in this case?

Also, that would mean that you'd have to load all the data into the DOM for find in page to work. For example, imagine the github code viewer. They'd have to load and render the DOM for the entire source file to get all the matches. That would be untenable for particularly large files.

Not that I have a better proposal. :)

@domenic
Copy link
Member

domenic commented Jan 19, 2018

Also, that would mean that you'd have to load all the data into the DOM for find in page to work. For example, imagine the github code viewer. They'd have to load and render the DOM for the entire source file to get all the matches. That would be untenable for particularly large files.

My intent was that you'd load enough data for the next match, and perhaps even automatically scroll to it. Then, when you get a "findinginpagenext" or "findinginpageprevious" event, you'd load enough data to make that available. Etc.

@ojanvafai
Copy link

So you'd be giving up on being able to see the number of matches and seeing the match location in the scrollbar. Maybe that's the best we can do, but it's def suboptimal.

@domenic
Copy link
Member

domenic commented Jan 30, 2018

One thing I'm noting so far is that almost all web apps seem to just want to hijack the default search. GitHub wants to add regexp matching since it's targeted at developers. Discourse gives a very different search results display in its search box, with the option of expanding its search beyond just the current topic. Docs and Sheets have no extra features, but hijack it anyway; maybe they are our best use cases for people who would want the browser's built-in UI?

@annevk
Copy link
Member

annevk commented Jan 30, 2018

An alternative API could be based on streams, where you push scroll offsets and the browser consumes them and updates its counters based on that and is able to scroll with that information as well. That would be a little closer to how browsers do it internally I think and would allow for the same kind of UI throughout.

@rakina
Copy link
Member

rakina commented Mar 12, 2018

Hi there, we (@domenic and I) are working on possible Find-in-page APIs. We've put together an explainer here.

We separated the explainer into two parts, with the main part focusing more on the simpler API that allows webpages to completely replace the UI with their own. The other explainer contains proposal for APIs like allowing the webpage to redo the browser's find-in-page, make the browser wait for something before finding, etc.

Please take a look at the explainer and share any thoughts you have on it! 😄

@rakina
Copy link
Member

rakina commented Apr 13, 2018

Pinging @annevk & @marcoscaceres as we are curious about what other browser vendors think about the APIs we proposed :)

@annevk
Copy link
Member

annevk commented Apr 13, 2018

Thanks for the ping, I filed mozilla/standards-positions#83 to get some thoughts from Mozilla.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
addition/proposal New features or enhancements needs implementer interest Moving the issue forward requires implementers to express interest
8 participants