You pass any function to the plugin as an argument and get result in callback. You also can "outsource" object's methods, function with dependecies, anonymous function and lambda. Enjoy.
You can create a web worker using the following syntax: const worker = new Worker("<worker_file>. js"); Worker is an API interface that lets you create a thread in the background.
A web worker is a JavaScript that runs in the background, independently of other scripts, without affecting the performance of the page. You can continue to do whatever you want: clicking, selecting things, etc., while the web worker runs in the background.
A shared worker can work with multiple connections. It posts messages to ports to allow communication between various scripts. A dedicated worker on the other hand is simply tied to its main connection and cannot post messages to other scripts (workers).
You can use fetch()
, response.blob()
to create an Blob URL
of type application/javascript
from returned Blob
; set SharedWorker()
parameter to Blob URL
created by URL.createObjectURL()
; utilize window.open()
, load
event of newly opened window
to define same SharedWorker
previously defined at original window
, attach message
event to original SharedWorker
at newly opened window
s.
javascript
was tried at console
at How to clear the contents of an iFrame from another iFrame, where current Question URL should be loaded at new tab
with message
from opening window
through worker.port.postMessage()
event handler logged at console
.
Opening window
should also log message
event when posted from newly opened window
using worker.postMessage(/* message */)
, similarly at opening window
window.worker = void 0, window.so = void 0;
fetch("https://cdn.rawgit.com/viziionary/Nacho-Bot/master/webworker.js")
.then(response => response.blob())
.then(script => {
console.log(script);
var url = URL.createObjectURL(script);
window.worker = new SharedWorker(url);
console.log(worker);
worker.port.addEventListener("message", (e) => console.log(e.data));
worker.port.start();
window.so = window.open("https://stackoverflow.com/questions/"
+ "38810002/"
+ "how-can-i-load-a-shared-web-worker-"
+ "with-a-user-script", "_blank");
so.addEventListener("load", () => {
so.worker = worker;
so.console.log(so.worker);
so.worker.port.addEventListener("message", (e) => so.console.log(e.data));
so.worker.port.start();
so.worker.port.postMessage("hi from " + so.location.href);
});
so.addEventListener("load", () => {
worker.port.postMessage("hello from " + location.href)
})
});
At console
at either tab
you can then use, e.g.; at How to clear the contents of an iFrame from another iFrame worker.postMessage("hello, again")
at new window
of current URL How can I load a shared web worker with a user-script?, worker.port.postMessage("hi, again");
where message
events attached at each window
, communication between the two window
s can be achieved using original SharedWorker
created at initial URL.
SharedWorker
's URL is subject to the Same Origin Policy.Worker
's URL.GM_worker
support is now a WONT_FIX, and
seems close enough to impossible to implement due to changes in Firefox.
There's also a note that sandboxed Worker
(as opposed to
unsafeWindow.Worker
) doesn't work either.What I suppose you want to achieve is a @include *
userscript that will collect some statistics or create some global UI what will appear everywhere. And thus you want to have a worker to maintain some state or statistic aggregates in runtime (which will be easy to access from every instance of user-script), and/or you want to do some computation-heavy routine (because otherwise it will slow target sites down).
The solution I want to propose is to replace SharedWorker
design with an alternative.
GM_setValue
and friends). It's shared among all userscript instances (SQLite behide the scenes).unsafeWindow.Worker
and put result back in Greasemonkey storage.localStorage
but Greasemomkey's has the same API, so it shouldn't be hard to write an adapter to it). Thus you can acquire a lock in one userscript instance and run your routines in it. Like, IWC or ByTheWay (likely used here on Stack Exchange; post about it).I'm not sure but there may be some ingenious response spoofing, made from ServiceWorker
to make SharedWorker
work as you would like to. Starting point is in this answer's edit.
I am pretty sure you want a different answer, but sadly this is what it boils down to.
Browsers implement same-origin-policies to protect internet users, and although your intentions are clean, no legit browser allows you to change the origin of a sharedWorker.
All browsing contexts in a sharedWorker
must share the exact same origin
You cannot hack around this issue, I've trying using iframes in addition to your methods, but non will work.
Maybe you can put it your javascript file on github and use their raw.
service to get the file, this way you can have it running without much efforts.
I was reading chrome updates and I remembered you asking about this. Cross-origin service workers arrived on chrome!
To do this, add the following to the install event for the SW:
self.addEventListener('install', event => {
event.registerForeignFetch({
scopes: [self.registration.scope], // or some sub-scope
origins: ['*'] // or ['https://example.com']
});
});
Some other considerations are needed aswell, check it out:
Full link: https://developers.google.com/web/updates/2016/09/foreign-fetch?hl=en?utm_campaign=devshow_series_crossoriginserviceworkers_092316&utm_source=gdev&utm_medium=yt-desc
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With