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

Find-in-page API(s) #236

Closed
1 of 3 tasks
rakina opened this issue Mar 14, 2018 · 18 comments
Closed
1 of 3 tasks

Find-in-page API(s) #236

rakina opened this issue Mar 14, 2018 · 18 comments

Comments

@rakina
Copy link

rakina commented Mar 14, 2018

こんにちはTAG!

I'm requesting a TAG review of:

You should also know that...

We have a main explainer that contains one simple API and an extended explainer that contains more complicated APIs. We are specifically looking for reviews on openfind (the API in the main explainer), but thoughts on the extended APIs are also welcome.

We'd prefer the TAG provide feedback as (please select one):

  • open issues in our Github repo for each point of feedback
  • open a single issue in our Github repo for the entire review
  • leave review feedback as a comment in this issue and @-notify [github usernames]
@dbaron
Copy link
Member

dbaron commented Mar 20, 2018

I'm a little worried the main use of this API will be for webpages to disable find-in-page. Is this work going to attempt to defend against that?

@plinss plinss added this to the 2018-04-10-telcon milestone Mar 20, 2018
@rakina
Copy link
Author

rakina commented Mar 22, 2018

I'm a little worried the main use of this API will be for webpages to disable find-in-page. Is this work going to attempt to defend against that?

The browser should allow the browser user to choose browser's find-in-page UI over the web page's own UI (the "power user" mechanism discussed in the explainer). Maybe we also need to give some kind of notification that the browser's find-in-page UI is being prevented so users know what's happening when no UI shows up?

@dbaron
Copy link
Member

dbaron commented Mar 22, 2018

Complicating the UI seems likely to be more confusing than helpful.

An alternative might be structuring the API so that it can only add to what the browser would find by default, rather than replacing what the browser would find by default.

@rakina
Copy link
Author

rakina commented Mar 22, 2018

An alternative might be structuring the API so that it can only add to what the browser would find by default, rather than replacing what the browser would find by default.

Hmm, so when the web page is using its own UI they should still receive the browser's results and show them as well? I'm not sure how we can guarantee that they will do that.

@travisleithead
Copy link
Contributor

Here's some early thoughts after reading through the spec (these may not be consensus positions):

I totally understand the use case from the individual site developer's experience--when the site wants to customize the Find-on-page experience to tailor it to the site's specific use-case, it is useful to be able to universally recognize the user's intent to start a "find" action, and try to take ownership of this.

Another perspective to be considered is the end-user, who appreciates a consistent experience coming from their browser UI. When an action is taken in the UI, but the browser doesn't respond as expected, this erodes the user's confidence in the browsing experience. This happens not only with Ctrl+F, but also with other similar browser actions for which web sites provide an alternate experience (e.g., Printing, Context Menus, Save As). Other sites take the approach that a Browser's native experience is "broken" and try to suppress it; or view some Browser UI features as too revealing (e.g., suppressing context menus due to Developer Tool's View Source or Inspect options). In all of these cases, (via the keyboard) the website has the option to block the user experience. Sadly, sites can not be expected to always provide some equivalent functionality, which leads to user frustration (e.g., e.preventDefault() in your example, but no other code to enable a site-specific find + focus--or worse, the code is there, but doesn't work properly).

I like the concept of the event as a way to centralize all the entry-points by which a user can invoke the find-on-page UI, and because it allows a site to setup and expose a more rich 'find' service to the user in a consistent way. However, I disagree with the premise that the site should be able to hijack the browser's UI. When there is visible text on the screen, and the user activates find-on-page, they expect to use the Browser's find service to locate that visible text.

Furthermore, the use of an event, while the appropriate metaphor, is also a synchronous construct--I imagine while the event handler code is running, the expectation is that the browser would delay showing it's UI. This is intensely problematic as this enables a user-experience hang if the web page takes too long to respond (e.g., the code in the event handler is too slow/complicated). A non-blocking or asynchronous solution would be needed (but is also tricky assuming you want a "before"-style event).

Another potential problem with the design is figuring out what the timing of the event should be. Naively, it seems that the event would fire when the user invokes the find-on-page UI and that UI is not previously showing. However, often the UI is persistent and the key combinations for find-on-page (Ctrl+f) is used to re-focus the browser's "find" input box for follow-on searches. Should the event fire in these cases? What happens when the persistent UI is enabled, and the user switches tabs? Does the event fire immediately after tab-switch in the new tab? Is another event needed when the UI is disabled/cancelled, in order to keep the experience consistent with the browser's UI?

I prefer a model where the Browser's find-on-page and the web page's find service can work together without having to compete. While a complicated form of that scenario is out-of-scope (as noted in the explainer) a much simpler design could still be in-scope. For example, the web application could use the openfind event both as a trigger to enable page-specific find services, and also as a mechanism for the Browser UI to discover that the web page has a find service and, at a minimum, advertise this fact in it's UI. This, coupled with the inability to block the browser's UI, will ensure a consistency of user experience from the browser POV, and enable a service-discovery entry-point for the page's find service. Would love to see more exploration of something along these lines...

@rakina
Copy link
Author

rakina commented Apr 9, 2018

Thanks for the comment!

In all of these cases, (via the keyboard) the website has the option to block the user experience. Sadly, sites can not be expected to always provide some equivalent functionality, which leads to user frustration (e.g., e.preventDefault() in your example, but no other code to enable a site-specific find + focus--or worse, the code is there, but doesn't work properly).

I don't quite understand this part. Do you mean that some site's custom find-in-page features might not offer the same functionality as other sites?

However, I disagree with the premise that the site should be able to hijack the browser's UI.

We are not allowing the site to hijack the browser's UI (power users can choose to force usage of browser's UI). Instead, we're saying that the browser's default find-in-page UI should become similar to the browser's default back button UI, where (due to the introduction of APIs like the HTML History API) there's a default behavior, but also a way to interpose your own behavior when the default behavior doesn't make sense for your page's content.

When there is visible text on the screen, and the user activates find-on-page, they expect to use the Browser's find service to locate that visible text.

Our API is specifically targeted at cases where that's not currently possible. There are a lot of sites today for which the browser UI is broken and not a consistent experience. Any site where the user's notion of the page's content doesn't map 1:1 to the web developer's notion of the DOM is like this. That includes sites that use virtualization, load contents lazily, or display text on a canvas, etc.

Furthermore, the use of an event, while the appropriate metaphor, is also a synchronous construct--I imagine while the event handler code is running, the expectation is that the browser would delay showing it's UI. This is intensely problematic as this enables a user-experience hang if the web page takes too long to respond (e.g., the code in the event handler is too slow/complicated). A non-blocking or asynchronous solution would be needed (but is also tricky assuming you want a "before"-style event).

We don't intend to hang the page in any way, at least, no more than normal JavaScript is able to at any time (without involving events at all).

Another potential problem with the design is figuring out what the timing of the event should be. Naively, it seems that the event would fire when the user invokes the find-on-page UI and that UI is not previously showing. However, often the UI is persistent and the key combinations for find-on-page (Ctrl+f) is used to re-focus the browser's "find" input box for follow-on searches. Should the event fire in these cases? What happens when the persistent UI is enabled, and the user switches tabs? Does the event fire immediately after tab-switch in the new tab? Is another event needed when the UI is disabled/cancelled, in order to keep the experience consistent with the browser's UI?

These are good questions and we are going to think about these questions, though some of them seems to be more of a browser-specific UI concern, which we don't want to constrain from the spec.

I prefer a model where the Browser's find-on-page and the web page's find service can work together without having to compete. While a complicated form of that scenario is out-of-scope (as noted in the explainer) a much simpler design could still be in-scope. For example, the web application could use the openfind event both as a trigger to enable page-specific find services, and also as a mechanism for the Browser UI to discover that the web page has a find service and, at a minimum, advertise this fact in it's UI. This, coupled with the inability to block the browser's UI, will ensure a consistency of user experience from the browser POV, and enable a service-discovery entry-point for the page's find service. Would love to see more exploration of something along these lines...

This model is interesting, but this is more related to Browser's UI. Some browsers may want to use them in that way, or maybe some other way by utilizing the APIs, but we shouldn't have the spec constrain browsers and how they implement their UI.

cc @domenic

@travisleithead
Copy link
Contributor

In all of these cases, (via the keyboard) the website has the option to block the user experience. Sadly, sites can not be expected to always provide some equivalent functionality, which leads to user frustration (e.g., e.preventDefault() in your example, but no other code to enable a site-specific find + focus--or worse, the code is there, but doesn't work properly).

I don't quite understand this part. Do you mean that some site's custom find-in-page features might not offer the same functionality as other sites?

No, I mean the site's custom find-in-page feature might have bugs and not work. If the site has hijacked the browser UI's find-in-page (by preventDefault-ing it), then you're left with nothing. :( This happened at the TAG meeting when using CryptPad, which tries to do this, but it's site-specific find feature was broken in the browser we were using. Oops.

We are not allowing the site to hijack the browser's UI (power users can choose to force usage of browser's UI).

Oh, then perhaps I was misunderstanding this use case from the explainer?

A web page has a completely custom way of loading data, and they want to provide a completely custom search UI. They can do this by adding an event listener for openfind Event, and calling preventDefault() on it, and then show their search UI instead.

I presumed "instead" meant in place of the browsers native UI. If you don't intend to prevent the browser UI from hiding, then I suppose many of my follow-on comments are invalid. If invoking preventDefault() is not for that purpose, what is it for?

@domenic
Copy link
Member

domenic commented Apr 11, 2018

I think one key thing that was missed in your review was the second paragraph of https://github.com/rakina/find-in-page-api/blob/master/README.md#openfind-event . Because of that, there shouldn't be any situation in which you're left with nothing, or "hijacked".

In general, there's nothing in the spec that prevents the browser from displaying whatever UI it wants. The preventDefault() is just a signal that the page intends to supply its own UI, and so the browser might want to make the default API hidden behind a power-user mode (like holding down shift, or performing some gesture, or an icon in the URL bar...). Perhaps that could be made clearer? But in general I think it's understood that specs don't proscribe UI, and browsers are free to innovate. Some might hide it; some might show both; some might use machine learning to detect when the page-provided one is a good experience and dynamically swap them out...

@travisleithead
Copy link
Contributor

If I pursue your suggestion of what the browser might want to do, then taking:

and so the browser might want to make the default API hidden behind a power-user mode

If the browser might want to do anything that involves hiding UI (and this is a very likely outcome and seems to express the semantic intent of preventDefault()) then it must wait for this signal, which means this event will block the user experience because the browser won't know whether that signal might come in until the event has been fully dispatched.

That's the part I'm having trouble with.

@domenic
Copy link
Member

domenic commented Apr 11, 2018

I think "blocking" is very strong. Would you say that the existence of the click event causes us to "block the user experience" every time someone clicks?

In general, you can always execute JavaScript code that "blocks" the user experience---whether it be via an openfind event, a click event, or with no event involved at all. This event doesn't give you any additional opportunities to block that weren't present already.

@travisleithead
Copy link
Contributor

travisleithead commented Apr 11, 2018

You are correct, of course, all these things block, or rather reduce throughput capability of the platform (e.g., if lots of code runs in the pointer move handler, you can't process as many moves and the input becomes "janky".)

This is not just an inconvenience--we created a whole new feature (passive event listeners) to try and address this problem for scrolling performance. Now, perhaps Find-on-page is not in the same performance-sensitive class as scrolling, but "Find-in-page" is an action that end-users take and expect to see the UI show feedback within a reasonable amount of time. If the event was a "notify after the fact" then I wouldn't have a problem, but because it allows for cancelability, I am concerned.

Hypothetically, a UA could just always ignore the preventDefault() and always show its own UI regardless. If a UA did this, I suspect you'd be disappointed because it wouldn't be enabling some of the scenarios proposed in the spec, right?

The workaround, for me, is to express to the platform the intent to cancel the find UI before the user actually invokes the action. This takes out the blocking aspect. Something like:

// crappy example
navigator.commandeerFindInPage( { showui: false }, () => { /* show your own fancy find-in-page */ } );
// callback executed every-time user tries to bring up find UI.

@domenic
Copy link
Member

domenic commented Apr 11, 2018

That's an interesting suggestion, but I'm not quite sure it's justified. It seems like you have a fully general argument against ever using event cancelation. But I don't think that holds: there are gradations in user expectations, and scrolling is a very special case. If event cancelation works for clicks and keypresses, it surely can work for find in page, as I'm not aware of any UI that allows invoking find and page without a click or keypress.

@torgo
Copy link
Member

torgo commented Jul 25, 2018

As discussed at TAG f2f: We would like to see there be an opt-out mechanism. A way for the user agent to opt out of the feature.

@eeeps
Copy link

eeeps commented Aug 9, 2018

Would it make sense to make this a policy-controlled feature?

@lknik
Copy link
Member

lknik commented Aug 9, 2018

I've got a question here. Why not make find-in-page API only working for Ctrl+Shift+F, and leave CTRL-F intact? In other words, no change with respect to the current operation. In other words, make it an opt-in so the users aren't surprising.

Another issue is privacy. I did not find any considerations.

@torgo
Copy link
Member

torgo commented Oct 30, 2018

@rakina what is the current status? Did you see Lukasz's question about privacy considerations above? Thanks!

@rakina
Copy link
Author

rakina commented Oct 30, 2018

Hi, sorry for not keeping up with the thread. After considering some issues, including those mentioned above, we've decided to not actively work on this API at this time. Thank you TAG + other people for the issues raised.

@cynthia
Copy link
Member

cynthia commented Oct 30, 2018

Thanks for letting us know. It would be helpful to know where this eventually progresses, as the publishing folks are interested in such functionality.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

10 participants