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

Possibility to add event listener in the reader #36

Open
Scarsniik opened this issue Mar 26, 2019 · 8 comments
Open

Possibility to add event listener in the reader #36

Scarsniik opened this issue Mar 26, 2019 · 8 comments

Comments

@Scarsniik
Copy link

Is it possible to provide a way to give event listener to the reader ?

For exemple I need to know when I click on the reader but I can't add a listener.

@danielweck
Copy link
Member

danielweck commented Mar 28, 2019

Hello, good question. Yes it is possible in principle, albeit with some limitations due to the sandboxed nature of iframes/webviews. So, the "devil is in the detail".
The "r2-glue-js" subproject has been looking into this very problem space, Juan Corona and the EvidentPoint developers have been experimenting with a RPC framework to handle this type of communication across runtimes.

What information do you need in the event payload, and what event targets are you interested in listening for? For example, mouse clicks can occur inside one of the webviews currently rendering publication documents (one or two in the case of fixed layout / pre-paginates EPUBs), but such event can also occur outside of webviews (yet, still inside the rectangular area reserved for the "navigator").

@danielweck
Copy link
Member

danielweck commented Mar 28, 2019

Just to clear a doubt: if all you need to know is that a mouse click occurred outside of a chrome/UI control (for example, to dismiss a modal slider panel / interactive dialog), then you should not need to rely on events from the navigator. This would be a UI design anti-pattern.
I am assuming that you actually need to listen to specific events from publication documents, right? Like when the user clicks on an image, or creates a text selection?

@danielweck
Copy link
Member

Also note that there is a notion of "competition" regarding the consumers of DOM events, and the use of useCapture, preventDefault etc. determines precedence / priority.
Concrete example: the navigator consumes user interaction events such as mouse clicks and keyboard strokes in order to narrow-down the reading location (which results in notifications sent to the host app). A tab navigation is captured to redirect the pagination state to the column that contains the focused DOM element. A hyperlink click is immediately handled for publication- internal and external links, or for popup footnotes which are rendered inline with the same document styles. Same with TTS readaloud. Text selection/annotation will involve much more back-and-forth communication between the navigator and the host app (because there is a lot of UI interaction), but in practice there will be navigator-specific events, not raw DOM events (this is why I asked about the detailed functional requirements in my previous comment).
In other words, some non-trivial behaviour is wired at the level of the navigator itself, without host app intervention. The typical preventDefault logic does not apply easily (or even technically, due to sandboxed runtimes) in isolated contexts.

@Scarsniik Scarsniik changed the title Possibility to ad event listener in the reader Possibility to add event listener in the reader Apr 1, 2019
@Scarsniik
Copy link
Author

I need to know when someone click on the reader. Not only a link but just click. Like when you had a onclick listener on an element. Because the reader is on a webview, it don't seems to accept listener like onclick. I tried a lot of things but I didn't succed. But maybe you know how to do that ? Maybe I forget something

@danielweck
Copy link
Member

danielweck commented Apr 2, 2019

So, based on a separate discussion on Slack, if I understand correctly you need to detect "pointing device" / "pointer event" user interaction (mouse click or touch), when it occurs outside of a dedicated higher-z-index / overlay UI control (such as a modal dialog or a slide-out menu), in order to trigger the discard / dismiss / close action on the said control. In that case ; like I said in my original comment(s) ; it would be a UI design anti-pattern (frankly, a hack) to expect specific notifications from webviews (or other nested iframes possibly hiding underneath the UI control's obscured area).

As I mentioned before, the "navigator" component does not necessarily consist in a single Electron webview spanning the entire rectangular dimensions of the visible viewport, it can for example consist in two webviews + blank areas around them in order to lay out the document (pages) of fixed-layout publications.

Furthermore, there can be nested iframe widgets inside navigator webviews, and these would typically implement combinations of useCapture, preventDefault and stopPropagation in order to handle user interactions inside sandboxed experiences (see also my previous comment regarding "competition" and precedence/priority in event handling, with respect to user interactions built into the navigator logic).

So, I think you are trying to solve a (real) UI problem using the wrong technique. For example, r2-testapp-js utilises a UI library that perfectly handles "dismiss" actions without having to explicitly listen to any navigator/webview-originating event. I haven't checked the details, but the UI framework probably detects focus/blur cycles, and in some cases a modal background obscuring overlay is interlaced to capture user interaction with a higher priority than DOM content underneath.

Do you see what I mean?

@danielweck
Copy link
Member

As mentioned above, there are well-established technical UI design patterns to achieve the "dismiss" actions without explicitly querying events from the underlying DOM objects.

For example, the concept of "scrim" is used for dialogs in this UI library:
https://material.io/develop/web/components/dialogs/

Same with slide-in/out panels (aka drawers):
https://material.io/develop/web/components/drawers/

@danielweck
Copy link
Member

danielweck commented Apr 2, 2019

Just to clarify please: are you using a UI library, or are you writing UI components from scratch? If the latter, I think you will have to implement all the tricky edge cases (especially layering / z-index / nested modals) for mouse/touch/keyboard interactions. Such as: a popup menu over a modal confirmation dialog over a slider panel over the main UI.

EDIT: I intentionally stretched the above example :) The main point is that unless you can guarantee that your UI will only ever generate a single dissmissable modal overlay at any given time, then you are going to deal with layering complications in the event subsystem of your custom/ad-hoc UI lib.

@llemeurfr
Copy link

llemeurfr commented Apr 2, 2019

In the list of https://material.io/develop/web/components/drawers/, the modal drawer is the one we need IMO. As it adds a "layer" upon the navigator view, isn't it simplifying the discussion?

Note: "scrim" means "voile léger" in French -> the semi-transparent layer upon the navigator view.

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

3 participants