¿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"
}
]