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); } }); }