2009-10-11 6 views
4

Je voudrais utiliser la fonction Web Worker introduite dans Firefox 3.5 pour améliorer un script Greasemonkey sur lequel je travaille.Est-il possible d'utiliser des travailleurs dans un script Greasemonkey?

Est-ce encore possible?

J'ai fait quelques expérimentations, mais je ne peux pas surmonter le problème du chargement d'un script de travail à partir d'un domaine arbitraire.

Par exemple, cela ne fonctionne pas:

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

Ce code génère un message d'erreur dans ma console Firebug:

Impossible de charger le script: http://dl.getdropbox.com/u/93604/js/worker.js (nsresult = 0x805303f4)

Apparemment, il y a une limitation qui ne vous permet pas de démarrer aw orker à partir d'une URL qui n'est pas relative à l'URL de base du script appelant. Vous pouvez charger un script de travail à une URL relative comme celui-ci très bien:

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

Mais il n'y a aucun moyen pour moi d'obtenir le script de travail sur le système de fichiers de l'utilisateur afin qu'il puisse être à un chemin relatif au script d'appel .

Suis-je foutu ici? Devrais-je renoncer à essayer d'utiliser les travailleurs dans mon script Greasemonkey?

Répondre

3
+0

Le contexte de Greasemonkey fait unique, à mon avis. Greasemonkey est connu pour activer des scénarios qui ne sont généralement pas possibles, comme les requêtes Ajax inter-domaines.Peut-être que d'autres utilisateurs de Greasemonkey sont au courant des trucs qui pourraient m'aider. – mattblodgett

+0

Il y a quelques hacks que les gens ont écrit pour le code Gears WorkerPool (Consultez l'indicateur d'origine croisée: http://code.google.com/apis/gears/api_workerpool.html#cross_origin). Greasemonkey fonctionne également dans le domaine d'une extension dans Firefox, de sorte que le guide sur les travaux à l'intérieur des extensions sur l'archive MDC pourrait aider. Peut être capable de charger un JS via le chrome :: url. –

+0

La seule façon dont greasemonkey peut le rendre unique est si greasemonkey ajoute du code pour qu'il soit unique. Le script greasemonkey va seulement pouvoir charger des scripts de la même origine, c'est pourquoi il échoue. – sdwilsh

7

Pendant des années, je pensais qu'il était impossible d'utiliser les travailleurs web dans GM. Bien sûr, la première idée était d'utiliser des URL de données. Mais le constructeur Worker ne semblait pas les accepter. Aujourd'hui, j'ai essayé à nouveau et cela a fonctionné sans aucun problème au début. Ce n'est que lorsque j'ai commencé à utiliser les fonctions de l'API GM que le constructeur Worker a cessé de fonctionner.

Apparemment Firefox a un bug qui vous empêche d'accéder à Worker à partir d'un bac à sable avec vision par rayons X. Même l'évaluation typeof Worker lève une exception. La seule façon d'utiliser des travailleurs est d'obtenir la version non emballé de la fenêtre non emballé:

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

Bien sûr, vous devez faire attention à des caractères spéciaux. Il est préférable de coder le script avec base64:

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

Sinon, vous pouvez également utiliser blob-urls:

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

Si vous voulez vraiment utiliser un script hébergé sur un autre domaine qui est pas un problème car règle d'origine ne demande pas 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); 
     } 
    }); 
} 
Questions connexes