Este articulo necesita una revisión editorial. Cómo puedes ayudar.
jpm
(Firefox 38 en adelante) o cfx
.Para modificar cualquier página que coincida con un patrón en particular (por ejemplo, "https://example.org/") mientras es cargada, se usa el módulo page-mod
.
Para crear un page-mod, es necesario especificar dos cosas:
- Uno o más scripts de contenido para ser ejecutados cuyo trabajo es interactuar con el contenido web.
- Uno o más patrones para hacer coincidir con las URLs de las páginas que se desea modificar.
El siguiente es un fragmento de código donde el script de contenido es provisto como una opción de contentScript
y el patrón de URL es dado como una opción de include
:
// Import the page-mod API var pageMod = require("sdk/page-mod"); // Create a page-mod // It will run a script whenever a ".org" URL is loaded // The script replaces the page contents with a message pageMod.PageMod({ include: "*.org", contentScript: 'document.body.innerHTML = ' + ' "<h1>Page matches ruleset</h1>";' });
Haga lo siguiente:
- Cree un nuevo directorio e ingrese en el.
- Ejecute
jpm init
ocfx init
- Abra el archivo
index.js
y agregue el código anterior (si usacfx, lib/main.js
) - Ejecute
jpm run
ocfx run
. - Abra en el navegador la página ietf.org.
Abajo se muestra lo que debe poder ver.
Especificar el Patrón de Coincidencia
El patrón de coincidencia usa la sintaxis match-pattern
. Se puede definir un patrón de coincidencia como una única cadena o una matriz.
Mantener el Script de Contenido en un Archivo Separado
En el ejemplo anterior, se definió el script de contenido como una cadena de caracteres.
A menos que el script sea muy simple, se debe mantener el script en un archivo separado. Esto hace al código más fácil de mantener, depurar, y revisar. Para hacer esto es necesario:
- Guardar el script en el directorio
data
del add-on. - Usar la opción
contentScriptFile
en vez decontentScript
y pasar ls URL del script la cual puede ser obtenida usandoself.data.url("my-script.js")
. Para Firefox 34 en adelante, se puede usar"./my-script.js"
.
Por ejemplo, si se guarda el script anterior en un archivo llamado my-script.js
bajo el directorio data
del add-on:
// Import the page-mod API var pageMod = require("sdk/page-mod"); // Import the self API var self = require("sdk/self"); // Create a page-mod // It will run a script whenever a ".org" URL is loaded // The script replaces the page contents with a message pageMod.PageMod({ include: "*.org", contentScriptFile: self.data.url("my-script.js") });
O para Firefox 34 en adelante:
// Import the page-mod API var pageMod = require("sdk/page-mod"); // Create a page-mod // It will run a script whenever a ".org" URL is loaded // The script replaces the page contents with a message pageMod.PageMod({ include: "*.org", contentScriptFile: "./my-script.js" });
Cargar Múltiples Scripts de Contenido
Es posible cargar mas de un script, y los scripts pueden interactuar directamente.
Por ejemplo, se puede reescribir my-script.js
para usar jQuery.
$("body").html("<h1>Page matches ruleset</h1>");
Luego se descarga jQuery al directorio data
del add-on, y se carga conjuntamente el script y el jQuery (asegurándose de cargar primero el jQuery).
// Import the page-mod API var pageMod = require("sdk/page-mod"); // Import the self API var self = require("sdk/self"); // Create a page mod // It will run a script whenever a ".org" URL is loaded // The script replaces the page contents with a message pageMod.PageMod({ include: "*.org", contentScriptFile: [self.data.url("jquery-1.7.min.js"), self.data.url("my-script.js")] });
Se puede usar contentScript
y contentScriptFile
juntos en el mismo page-mod. Si se hace esto, los script cargados usando contentScriptFile
son cargados primero.
// Import the page-mod API var pageMod = require("sdk/page-mod"); // Import the self API var self = require("sdk/self"); // Create a page-mod // It will run a script whenever a ".org" URL is loaded // The script replaces the page contents with a message pageMod.PageMod({ include: "*.org", contentScriptFile: self.data.url("jquery-1.7.min.js"), contentScript: '$("body").html("<h1>Page matches ruleset</h1>");' });
Note, sin embargo, que no es posible cargar un script desde un sitio web. El script debe ser cargado desde el directorio data
.
Comunicarse con el Script de Contenido
El script del add-on y los scripts de contenido no pueden acceder directamente a las variables o llamar a las funciones de los demás, pero pueden enviar mensajes.
Para enviar un mensaje de un lado a otro, el emisor llama a port.emit()
y el receptor escucha usando port.on()
.
- En el script de contenido,
port
es una propiedad del objeto globalself
. - En el script del add-on, es necesario escuchar al evento
onAttach
para conseguir pasar un objeto de trabajo que contenga aport
.
Se reescribe el ejemplo anterior para pasar un mensaje desde el add-on al script de contenido. El mensaje contendrá el nuevo contenido para ser insertado en el documento.
El script de contenido ahora necesita lucir de esta manera:
// "self" is a global object in content scripts // Listen for a message, and replace the document's // contents with the message payload. self.port.on("replacePage", function(message) { document.body.innerHTML = "<h1>" + message + "</h1>"; });
En el script del add-on, se enviará al script de contenido un mensaje desde onAttach
.
// Import the page-mod API var pageMod = require("sdk/page-mod"); // Import the self API var self = require("sdk/self"); // Create a page-mod // It will run a script whenever a ".org" URL is loaded // The script replaces the page contents with a message pageMod.PageMod({ include: "*.org", contentScriptFile: self.data.url("my-script.js"), // Send the content script a message inside onAttach onAttach: function(worker) { worker.port.emit("replacePage", "Page matches ruleset"); } });
El mensaje replacePage
no es un mensaje ya definido: es un mensaje definido por el add-on en la llamada port.emit()
.
Inyectar CSS
Note que la característica descrita en esta sección es experimental por los momentos. Se continuará dando soporte a esta característica, pero los detalles dela API pueden cambiar.
En vez de inyectar JavaScript en una página, es posible inyectar CSS configurando la opción contentStyle
del page-mod.
var pageMod = require("sdk/page-mod").PageMod({ include: "*", contentStyle: "body {" + " border: 5px solid green;" + "}" });
Como con el contentScript
, hay una opción correspondiente a contentStyleFile
que toma una URL de un archivo CSS en el directorio "data" ; es una buena practica usar esta opción en vez de contentStyle
si el CSS un poco complejo.
var pageMod = require("sdk/page-mod").PageMod({ include: "*", contentStyleFile: require("sdk/self").data.url("my-style.css") });
O, para Firefox 34, se puede usar una versión más simple:
var pageMod = require("sdk/page-mod").PageMod({ include: "*", contentStyleFile: "./my-style.css" });
Conociendo más
Para conocer más sobre page-mod
, puede dirigirse a la página de referencia de la API. En particular, el constructor de PageMod
toma algunas opciones adicionales para tomar el control de este comportamiento:
-
De forma predeterminada, los scripts de contenido no están fijados a ninguna pestaña que este ya abierta cuando el page-mod es creado, y son fijados a iframes como a documentos de alto nivel. Para controlar este comportamiento se usa la opción
attachTo
. -
Define valores de solo lectura accesibles a los scripts de contenido usando la opción
contentScriptOptions
. -
De forma predeterminada, los scripts de contenido son adjuntados después que todo el contenido (DOM, JS, CSS, imagenes) de la página ha sido cargado, al mismo tiempo se activa el evento window.onload. Para controlar este comportamiento, se usa la opción
contentScriptWhen
.
Para conocer más sobre los scripts de contenido en general, puede dirigirse a la guía de scripts de contenido.