scripting / Scripting-News

I'm starting to use GitHub for work on my blog. Why not? It's got good communication and collaboration tools. Why not hook it up to a blog?
121 stars 10 forks source link

How can a browser-based app quit on its own? #154

Closed scripting closed 4 years ago

scripting commented 4 years ago

I have a JavaScript app running in the browser. I want it to quit when another copy of the same app is opened in another tab.

used to do this with a localStorage value. Set it to a random string of 25 characters. Every second compare the string in localStorage with the one I set at startup. If it's different I know another copy of myself is running, and I (used to) exit via window.close.

This no longer works, there's an error from the browser, "Scripts may close only the windows that were opened by it."

So is there no way for an app to quit on its own without a user interaction?

ttepasse commented 4 years ago

I don't think so, no. window.close in it's original variation is a security risk – Javascript in any loaded page could close every other of the user's windows or tabs which practically gives every web page the possibility to create havoc on a user's system.

Riffing a little bit on your use case:

If you're less interested in tab management but more in resource management the Page Visibility API could be of interest. The old copy of the app is presumably not visible. By listening on the visibilitychange event the old copy can deactivate its running processes and uses less system resources. The new copy is visible, runs functions and such and when being forgotten becomes a new old copy. That concept doesn't help with window management, of course, but uses less resources.

Another possibility – which would need heavy architectural reengineering of the app – would be splitting it up in two or more threads with the Web Workers API. As I understand it – I have no own experience – you would centralise storage, longrunning tasks and HTTP requests in the Worker thread (SharedWorker or ServiceWorker) and use the open pages just for UI. Worker and page then communicate over a message interface. The benefit is that data and state of the app are always in sync, because they only live in one place, the Worker thread, whereas there could be hundreds of open copies of the UI in different tabs. The web app of Twitter seems to work that way, iirc. Drawback: It's a big task. And still no control over tab management, sorry.

benzado commented 4 years ago

Instead of closing the window, why not load a new page?

window.location = "anotherCopyDetected.html";

Upside, you get to explain to the user that this window stopped running because it detected another window running the app.

scripting commented 4 years ago

@ttepasse -- thanks for the suggestions. this isn't about resources. having more than one copy of an editor open is invitation to losing work.

@benzado -- thank you, for some reason i forgot that. I'm going to use that approach but I'll send it to scripting.com or something like that, because people aren't even aware they do this, so explaining it would just be confusing. maybe i should send them to isrssdead.com? ;-)

tdanner commented 4 years ago

Note that instead of polling localStorage every second to see if the value has changed, you can register to be notified using code like this:

window.addEventListener('storage', function(e) {  
  console.log('key ' + e.key + ' changed from ' + e.oldValue + ' to ' + e.newValue);
}

https://developer.mozilla.org/en-US/docs/Web/API/Web_Storage_API/Using_the_Web_Storage_API#Responding_to_storage_changes_with_the_StorageEvent