iframe greasemonkey userscripts tampermonkey

¿Aplicar un Greasemonkey/Tampermonkey/userscript a un iframe?



userscripts (3)

En Greasemonkey (y Tampermonkey y la mayoría de los motores de script de usuario), un script se activará automáticamente en un iframe si cumple con las @exclude @include , @exclude y / o @match .
Y, una pregunta popular es cómo evitar que Greasemonkey dispare en iframes .

Entonces, si su script tenía una coincidencia como:

@match https://fiddle.jshell.net/*

Se dispararía en las páginas de "salida" de jsFiddle si aparecían o no en un iframe.

Si desea disparar a un contenido iframed SOLO:

Entonces verificaría la propiedad window.self .
Por ejemplo, suponga que tiene una página de destino como:

<body> <h1>I''m some webpage, either same-domain or not.</h1> <iframe src="//domain_B.com/somePath/somePage.htm"> ...

Entonces podrías usar un script como:

// ==UserScript== // @name _Fires specially on domain_B.com iframes // @match *://domain_B.com/somePath/* // ==/UserScript== if (window.top === window.self) { //--- Script is on domain_B.com when/if it is the MAIN PAGE. } else { //--- Script is on domain_B.com when/if it is IN AN IFRAME. // DO YOUR STUFF HERE. }

Importante:

Con el lanzamiento de Greasemonkey 4, el manejo de iframes se ve gravemente dañado (y muchas otras cosas se rompen, además).
Todavía funciona correctamente con Tampermonkey, Violentmonkey y casi cualquier otro motor de script de usuario.
Se recomienda encarecidamente ( incluso por parte de Greasemonkey ) que no use Greasemonkey 4 o posterior.

El título es más o menos la pregunta:

¿Es posible agregar un script de Greasemonkey a un sitio web iframed?

¿Si es así, cómo?

Gracias.


Esta es una solución para casos en los que el iframe no tiene una ubicación para activar @include o @match .

Esto funciona con Greasemonkey 4.

Debemos esperar a que se cargue cada cuadro antes de poder operar en él. Hago esto usando waitForKeyElements.js , que espera elementos que coincidan con un selector CSS determinado, al igual que recorrer las coincidencias en document.querySelectorAll("selector") , y luego aplica una función dada a la respuesta:

// ==UserScript== // @include https://blah.example.com/* // @require https://git.io/waitForKeyElements.js // ==/UserScript== function main(where) { // do stuff here with where instead of document // e.g. use where.querySelector() in place of document.querySelector() // and add stylesheets with where.head.appendChild(stylesheet) } main(document); // run it on the top level document (as normal) waitForKeyElements("iframe, frame", function(elem) { elem.removeAttribute("wfke_found"); // cheat wfke''s been_there, use our own for (let f=0; f < frames.length; f++) { if (!frames[f].document.body.getAttribute("been_there")) { main(frames[f].document); frames[f].document.body.setAttribute("been_there", 1); } } });

Tenga en cuenta que el elemento seleccionado es solo un marcador de posición que indica que se ha cargado un iframe . waitForKeyElements rastreador "estado allí" de waitForKeyElements porque el marco puede cargarse nuevamente más tarde (no podemos usar ese iframe simplemente porque su contenido se carga en otro lugar).

Cuando sabemos que se ha cargado un marco, recorremos cada marco y buscamos nuestro marcador, un atributo HTML en el body del marco llamado been_there (como <body been_there="1"> ). Si falta, podemos ejecutar nuestra función main() en el documento del marco. Cuando terminamos, agregamos el atributo been_there para que no se been_there nuevamente.


Tenga en cuenta que si está creando una extensión de Chrome para su script de usuario, también debe agregar "all_frames": true a su manifiesto o su extensión no funcionará en iframes.

Ejemplo:

"content_scripts": [ { "matches": ["*://*/*"], "all_frames": true, "js":["dont.js"], "run_at":"document_start" } ]