Is it possible to use workers in a Greasemonkey script?

I would like to use the Web Worker tool introduced in Firefox 3.5 to improve the Greasemonkey script I'm working on.

Is it possible?

I did some experimentation, but I can not get around the problem of loading a working script from an arbitrary domain.

For example, this does not work:

var myWorker = new Worker("http://dl.getdropbox.com/u/93604/js/worker.js"); 

This code generates an error message in my Firebug console:

Failed to load script: http://dl.getdropbox.com/u/93604/js/worker.js (nsresult = 0x805303f4)

Apparently, there is a restriction that prevents you from starting work with a URL that is not related to the base URL of the calling script. You can load a working script with a relative url, as this is just fine:

 var myWorker = new Worker("worker.js"); 

But I don’t have the opportunity to get a working script in the user’s file system so that it can be on the path relative to the calling script.

Am I screwed here? Should I give up trying to use workers in my Greasemonkey script?

+4
source share
2 answers

For many years, I thought it was impossible to use web workers at GM. Of course, the first idea was to use link data. But the Worker designer did not seem to accept them.

Today I tried again, and at first it worked without problems. Only when I started using the GM API features did the Worker constructor stop working.

It looks like Firefox has a bug that prevents the Worker from accessing the sandbox using an X-ray image. Even a typeof Worker evaluation throws an exception. Thus, the only way to use workers is to get the expanded version from the expanded window:

 var echoWorker = new unsafeWindow.Worker("data:text/javascript," + "self.onmessage = function(e) {\n" + " self.postMessage(e.data);\n" + "};" ); 

Of course, you have to be careful with special characters. Best to encode a script with base64:

 var dataURL = 'data:text/javascript;base64,' + btoa(script); var worker = unsafeWindow.Worker(dataURL); 

Alternatively, you can also use blob-urls:

 var blob = new Blob([script], {type: 'text/javascript'}); var blobURL = URL.createObjectURL(blob); var worker = new unsafeWindow.Worker(blobURL); URL.revokeObjectURL(blobURL); 

If you really want to use a script hosted in a different domain, this is not a problem because the same origin policy does not apply for GM_xmlhttpRequest :

 function createWorkerFromExternalURL(url, callback) { GM_xmlhttpRequest({ method: 'GET', url: url, onload: function(response) { var script, dataURL, worker = null; if (response.status === 200) { script = response.responseText; dataURL = 'data:text/javascript;base64,' + btoa(script); worker = new unsafeWindow.Worker(dataURL); } callback(worker); }, onerror: function() { callback(null); } }); } 
+7
source

All Articles