A bit confused about the "agenda" of a Chrome extension - javascript

So, I wrote a few extensions, most disposable and one hopefully viable.
I'm still a bit confused about the "agenda", of "schedule" or whatchacallit, i.e. the order in which things happen, and the places where they live.
For example, I am writing a new one that shall do the following :
a browser action presents the user with a menu of 3 items
two of those items trigger actions to be executed immediately, while the third lauches a process that is to run undercover for an extended period (namely polling a certain web page at an interval, said web page needing not to be loaded in any visible tab or window).
Naturally I'd be tempted to assume that the long-term is to live in the background.js.
Now, I understand that the pop-up menu is an HTML document in its own right, living its life in its own bubble. It shall disappear right after the user cliked on an item, thereby taking its context with it to its grave. Right now I'm at a bit of a loss trying to figure out how it can trigger a background process.
Notwithstanding, I don't quite grasp what brings the background.js to life, even less so when it is specified as non persistent as is recommended.
Naturally, I'll RTFM again, but if you fellows could dumb this down to my poor level of understanding, I'd be so happy ...

Maybe as you said, you would need to RTFM again..
Background Page runs in the extension process and exists for the lifetime of your extension, until your extension is removed or the browser process terminates.
While Event Page, what chrome has recommended to use, is loaded only when they are needed. Take a look at Lifetime part, the following are some example that will cause the event page to load:
The app or extension is first installed or is updated to a new version (in order to register for events).
The event page was listening for an event, and the event is dispatched.
A content script or other extension sends a message.
Another view in the extension (for example, a popup) calls runtime.getBackgroundPage.
As for your question, 'how it can trigger a background process', if there are no events to catch or message to pass, you can just call runtime.getBackgroundPage to load the event page.

Related

Firefox cannot create iframes within a limited time?

Related to this question, the workaround to launching a custom protocol after starting a websocket (so as to keep the socket open and polling) is to use an iframe element and set the src to be the custom protocol. But, if a user clicks the button that sets the src too quickly (i.e. they trigger the custom protocol too frequently), FF logs this warning:
"Iframe with external protocol was blocked due to lack of user activation, or because not enough time has passed since the last such iframe was loaded."
I can't seem to find any documentation on:
What constitutes user activation
How much time "enough time has passed" actually is
Does anyone know what exactly that warning means or what either of those bullet points are and how we can get around the limitation to allow launching a custom protocol (without refreshing the page or causing a popup) from within FF?
I've tried both having the iframe exist on the page beforehand and dynamically setting the src, as well as, dynamically creating the iframe with the src at the same time, but both end with the same warning being logged.
User activation means an event triggered by the user, such as mouse or keyboard events. This is similar to the way popup blockers work.
I doubt you'll find the "enough time" limit documented -- the programmers don't want to tell malware writers how to work around the restriction.
You say you're doing this when the user clicks on a button, so that should fit the "user activation" requirement. Are you doing it in a callback function that runs asynchronously from the event listener? That disconnects it from the user interaction -- it has to be directly in the listener function.

Detect Page Refresh or Navigation in Browser

I have a web app where a parent page displaying a list of records opens up a new tab ('child') to edit a clicked-on record. I want to track who has a page open, so I can display a message if more than one person is editing a unique record. This means reporting when a page is closed. I have assigned each page a GUID to facilitate recognition of the page instance.
So javascript in the browser needs to detect several scenarios:
browser tab closed
browser refresh
browser navigation to hyperlink
browser navigation forward/back
At the moment, all of these appear to trigger the window.onbeforeunload event. However I use this event to warn of changes in the underlying data, which means the event returns the confirmation text, and there is no way of knowing in this event if the user subsequently confirms or cancels the page unload. So I can't use this event to track page closure.
According to a number of sources the window.onunload event should be triggered in all of the above scenarios (and if it was, I could use it), but testing under Chrome on Windows is only triggering this event in scenario 1 (when the tab is closed). It works fine for that.
I'm pretty surprised by the lack of information around this - surely it's a bread and butter requirement in modern sites?
Has window.onunload been deprecated lately in some scenarios, or in some scenarios in some browsers? Without a reliable hook that takes place when the page is about to be replaced with some other information, it's impossible to monitor closing of a page. Any other workarounds?
I know that the two unload events suppress blocking functions (such as alerts) in the handler. However they appear to do hit breakpoints, do a console.log and allow Ajax calls just fine. I'm pretty sure they are not being fired in events 2,3 and 4 - it's not just that my debugging is being blocked.
While there appear to be answers on SO already (most of which don't work or are deprecated), I posted this because browser events are a shifting-sands scenario as security issues evolve, so I wanted to find out where we are in 2021.
Actually, it looks as if this might be the solution: https://developers.google.com/web/updates/2018/07/page-lifecycle-api#the-unload-event
Google discourages use of the unload event because it is (a) unreliable on mobiles and (b) blocks the caching of pages. It is also advised to only add the beforeunload event just before it is used, and to remove it afterwards, because it also blocks the caching of pages (I note that this is not really practical for me, however, as I use it to guard against unintentional closing of a page after a possibly significant amount of data has been entered, and this could happen at any moment).
So as of July 2018, and still best practice as of July 2021, this would be the recommended way to detect the unloading of a page:
const terminationEvent = 'onpagehide' in self ? 'pagehide' : 'unload';
addEventListener(terminationEvent, function(event) {
// handler code here ...
}, { capture: true });
This has been tested in a small ASP NET Core project using an AJAX callback to report the page termination, and appears to work reliably in Chrome and Edge. Also works in IE11 as long as
<meta http-equiv="x-ua-compatible" content="IE=edge">
is present.

Vaadin onbeforeunload event

Is there any Out Of the Box Vaadin 10 (and higher) event similar to window.onbeforeunload in JavaScript?
I've tried to use onDetach() or beforeLeave(), but it only works inside UI, and when user reloads the page or closes the page it's not working.
You can use the approach described in https://vaadin.com/forum/thread/17523194/unsaved-changes-detect-page-exit-or-reload that was already suggested in a comment.
At the same time, I'd urge you to be really careful with beforeunload events since they are in some situations fired even though the user is actually not navigating away from the page.
The most common case is if the user clicks a link that starts a download. In that case the browser will fire the event immediately when the user clicks the link. Slightly later when the browser receives the response headers, it will discover that it's a download and not a new HTML page to display. The end result is then that beforeunload has been fired but the previous page is still kept running.
If you want to use the event for cleanup, then the best approach today is probably a combination of the unload event and then using the new-ish Beacon API for notifying the server that the user has actually navigated away. Integrating this into a Vaadin application will require slightly more JavaScript, but it has the benefit that it will actually work.

Implications of using multiple interactive popup windows

I'm coming up with the idea of detaching elements onto popup windows. Make a popup with window.open(), set up some elements in that document and add event listeners to serve the original purpose, but as a popup window component. All of this works, and it seems that the created window is handled by the same thread.
Is this "technique" bug-prone by any chance? I.g: If I create a canvas in the popup window and get a WebGL context from it, will it work flawlessly? If I set a bunch of event listeners there, will I get callbacks from them without any delay?
I couldn't do my research on this one because almost no one does this. Through my life, I've seen many sites use popup windows for user inputs but not for interactive or real timey stuff. I'm building a web app that's complex that utilising multiple monitors would benefit in user experience. You know, at least I know how painful it is to have two monitors and be unable to use both of them because all the component of the app is cramped in a single window. Just imagine using an MDI version of Photoshop where all the toolbox is within the MDI area and you can't get them out of the app window. A web page is exactly that.
Although this is non-conventional it definitely seems to suit the requirement you mentioned. I don't see any issues when it comes to the browser support for handling rendition or communication across the windows, it's just that you will need to be more careful with your code. Something like make frequent checks in case user has closed one of your pop-ups(or register a window close callback so that you can make necessary adjustments).
Eventing across the windows should also be fine. Refer http://help.dottoro.com/ljrwrqew.php which has exactly same example of attaching the event callback from one window to another.
Another good read is http://www.infimum.dk/HTML/JSwindows.html
One possible drawback could be that the popup can be blocked by the browser popup blocker (but yes, you could inform the user to don't block the popup coming from your web application)
Another one could be that the dimensions of the popup that you specify on your javascript code could be not respected (this is at the discretion of the browser), so for example one browser could open anytime the popup in a new tab or a new maximized window.
Here you will find some ready made experiments with multi-window: https://experiments.withgoogle.com/chrome?tag=Multi-Window
For data sharing between your main window and your popup you shouldn't have any problem.
Something to keep in mind is that not every browser use the same threading model, so you must do some performance tests as well on all the browser you will want to support and see the differences.

Can I reliably detect whether a web page can be seen by a user?

I am trying to decide whether to do a somewhat expensive javascript-ajaxing-to-the-server operation, but it is only worth doing if the user can see the web page, so I'm trying to detect that.
I was initially excited to find the "visibilitychange" API, but it looks like that only detects if the web page is in a hidden tab. If the user opens up a new browser window instead of a new tab, the event isn't called. Nor is it called when the user changes to a different app.
I also think I'd like to slow down the operation if the browser isn't in the foreground, so there are really three states:
"request-every-5-seconds" Does the browser have the input focus?
"request-every-minute" Is any part of the page actually on the user's display?
"don't-request" the browser is buried under another window.
That way, a user who goes to my webpage and leaves the browser open won't be using resources either on the server or their computer.
For the first state monitoring "onfocus" mostly works, but the focus can get lost to the developer tools. That's a little annoying, but it isn't typical of a customer, so I can live with that.
For the second state, I have no idea where to start. One idea I had was to detect whether the browser is actually "painting", but I haven't found any way to detect that.
How do you decide whether it is worth checking for updates?
[note: I'm using jQuery already, so a jQuery-based answer is fine.]
Thanks.

Categories