Modificar páginas web basándose en el URL

Este articulo necesita una revisión editorial. Cómo puedes ayudar.

Para realizar los pasos que se describen a continuación es necesario tener instalado el SDK y conocimientos básicos de jpm (Firefox 38 en adelante) o cfx.

Para modificar cualquier página que coincida con un patrón en particular (por ejemplo, "http://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 o cfx init
  • Abra el archivo index.js y agregue el código anterior (si usa  cfx, lib/main.js)
  • Ejecute jpm run o cfx 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 de contentScript y pasar ls URL del script la cual puede ser obtenida usando self.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 global self.
  • En el script del add-on, es necesario escuchar al evento onAttach para conseguir pasar un objeto de trabajo que contenga a port.

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.

Etiquetas y colaboradores del documento

Etiquetas: 
 Colaboradores en esta página: goliveira
 Última actualización por: goliveira,