Greasemonkey: Prise en charge de l'exécution du script de démarrage du document

Créé le 25 juil. 2017  ·  17Commentaires  ·  Source: greasemonkey/greasemonkey

Prend en charge document-start pour @run-at .

Voir #2483 pour plus de détails. Cela peut être "impossible".

Tous les 17 commentaires

Vous pouvez utiliser la propriété run_at de la clé de manifeste content_scripts .

J'ai partagé la pitié de Chrome avec vous il y a 4 ans. Maintenant encore pour Firefox. ??

Je voudrais reformuler ma suggestion dans https://bugs.chromium.org/p/chromium/issues/detail?id=257956

tabs.insertCSS/executeScript doit insérer CSS/JS jusqu'à ce que l'URL de l'onglet soit définie non vide (non nulle, non définie, non vide chaîne ""), et être annulée si l'onglet est supprimé/modifié

Les API WebExtension devraient être améliorées.

@iology pourquoi avez-vous voté contre ma suggestion ? C'est parfaitement valable. De plus, on peut simplement utiliser le script de contenu pour insérer des balises de script dans le document qui contiennent les scripts utilisateur.

Ce qui suit devrait expliquer comment le faire en utilisant ma méthode : (devrait fonctionner de manière fiable)

/**
 * <strong i="8">@typedef</strong> UserScript
 * <strong i="9">@property</strong> {Object} header The parsed header of a script
 * <strong i="10">@property</strong> {String} script The raw script data
 * <strong i="11">@property</strong> {String} type The script media type (in case a script is WebAssembly
 *                         or something other than JavaScript)
 */

/** The load state of this script. Used by the `matches()` function */
const READY_STATE = document.readyState;

(async () => {
    (await (browser.storage.local.get({scripts: []}) // Excuse this horrible code style
        .then(ret => ret.scripts)))                  // of combining `await` and `.then()`
        .forEach(/* <strong i="12">@param</strong> {UserScript} script */ script => {
            if (matches(script.header)) {
                let scriptTag = document.createElement("script");
                scriptTag.setAttribute("type", script.type)
                scriptTag.textContent = script.script;
                document.appendChild(scriptTag);
            }
        });
})();

/**
 * Checks if this script matches this page and @run-at property.
 * 
 * <strong i="13">@param</strong> {Object} scriptHeader The parsed header of a script
 * <strong i="14">@return</strong> {boolean} `true` if this page matches, `false` otherwise
 */
function matches(scriptHeader) {
    // Uses window.location and READY_STATE.
    // TODO: Implement
}

@ExE-Boss Au moment où vous récupérez les scripts du stockage d'extension, une partie de la page serait déjà chargée.

J'en suis conscient, mais je ne vois pas vraiment d'autre moyen de le faire en raison du fait que les WebExtensions sont intrinsèquement asynchrones.

@ExE-Boss, il y a un bugzilla, https://bugzilla.mozilla.org/show_bug.cgi?id=1332273 , qui semble bien progresser et devrait aider à résoudre le problème @document-start. S'il atterrira pour FF57, je ne suis pas sûr.

J'en suis conscient, mais je ne vois pas vraiment d'autre moyen de le faire en raison du fait que les WebExtensions sont intrinsèquement asynchrones.

@ExE-Boss C'est littéralement le problème que nous essayons de résoudre.

J'essaie également de le résoudre, mais ma solution ne fonctionne vraiment bien que pour le #2525, car à ce stade, la page entière est complètement chargée.

Violentmonkey a également ce problème, pas sûr de la magie noire utilisée par Tampermonkey, mais il est capable d'injecter un script de manière fiable sur le vrai document-start .

Tampermonkey 2.9 et versions antérieures était GPL-3.0 et publié sur GitHub . J'ai essayé de l'examiner, et au début, je pensais qu'il utilisait la synchronisation XHR , mais après y avoir réfléchi un peu, je ne sais pas comment il y parvient, mais il le fait d'une manière ou d'une autre parce que la prise en charge de cela a été ajoutée dans la version 2.6 .2767 .

Découvrez ici pourquoi Tampermonekey est devenu source fermée :

Le piratage ne m'intéresse pas, il ne sera pas trop difficile d'inverser la logique de Tampermonkey mais ce n'est pas légal de le faire.

@Sxderp C'est uniquement pour Firefox 57, ce bogue peut toujours être résolu dans 58+.

Pour info, Tampermonkey n'est pas non plus fiable au démarrage du document. Il existe une option d'injection "instantanée" (qui est extrêmement bidon) qui accélère les choses, mais sur des pages simples comme xkcd.com, j'obtiens toujours un flash avant que mon CSS (qui est toujours injecté au démarrage du document) ne se charge. Je reçois aussi occasionnellement un flash sur d'autres sites.

Inverser le code de Tampermonkey n'est pas un moyen de comprendre cela. De plus, eh bien, les méthodes réelles qu'ils utilisent peuvent être trouvées dans leurs forums, suggérées par d'autres utilisateurs. Copier une méthode n'est pas une copie-vio, il suffit de copier le code lui-même.

Mais nous savons que c'est une solution imparfaite, et nous voulons une solution parfaite.

Si une méthode est trouvée pour que cela fonctionne, pourrait-il y avoir un moyen pour qu'un script lise au moins un sous-ensemble de ses options de configuration de manière synchrone ? Comme exemple du type de problèmes que cela résoudrait, voir https://github.com/ccd0/4chan-x/issues/1627. Ici, je dois désactiver du code sur la page, mais je veux aussi avoir une option pour ne pas désactiver le code. Et de nombreux utilisateurs effacent localStorage à la fin de chaque session de navigateur.

Si une méthode est trouvée pour que cela fonctionne, pourrait-il y avoir un moyen pour qu'un script lise au moins un sous-ensemble de ses options de configuration de manière synchrone ?

Pas à court terme. Il n'y a aucun moyen de communiquer avec le stockage (get|set)Value de manière synchrone. Peut-être une sorte d'injection de la part de GM dans laquelle des variables avec des valeurs de configuration sont injectées dans la portée globale du script. C'est le mieux que je puisse imaginer, et ce n'est pas très agréable.

Peut-être une sorte d'injection de la part de GM dans laquelle des variables avec des valeurs de configuration sont injectées dans la portée globale du script. C'est le mieux que je puisse imaginer, et ce n'est pas très agréable.

Vraisemblablement, cela ferait partie de l'objet GM . Quelque chose comme GM.initValues.yourVariable .

Cette page vous a été utile?
0 / 5 - 0 notes