Cómo insertar secuencias de comandos en la pestaña activa

En este instructivo, se compila una extensión que simplifica el diseño de las páginas de documentación de la extensión de Chrome y Chrome Web Store para que sean más fáciles de leer.

En esta guía, explicamos cómo hacer lo siguiente:

  • Usa el service worker de la extensión como coordinador de eventos.
  • Preserva la privacidad del usuario a través del permiso "activeTab".
  • Ejecuta código cuando el usuario hace clic en el ícono de la barra de herramientas de la extensión.
  • Inserta y quita una hoja de diseño con la API de Scripting.
  • Usa una combinación de teclas para ejecutar el código.

Antes de comenzar

En esta guía, se da por sentado que tienes experiencia básica en desarrollo web. Consulta Hello World para obtener una introducción al flujo de trabajo de desarrollo de extensiones.

Compila la extensión

Para comenzar, crea un directorio nuevo llamado focus-mode para alojar los archivos de extensión. Puedes descargar el código fuente completo en GitHub.

Paso 1: Agrega los datos y los íconos de la extensión

Crea un archivo manifest.json. Copia y pega el siguiente código:

{
  "manifest_version": 3,
  "name": "Focus Mode",
  "description": "Enable focus mode on Chrome's official Extensions and Chrome Web Store documentation.",
  "version": "1.0",
  "icons": {
    "16": "images/icon-16.png",
    "32": "images/icon-32.png",
    "48": "images/icon-48.png",
    "128": "images/icon-128.png"
  }
}

Crea una carpeta images y, luego, descarga los íconos en ella.

Paso 2: Inicializa la extensión

Las extensiones pueden supervisar los eventos del navegador en segundo plano con el service worker de la extensión. Los service workers son entornos especiales de JavaScript que controlan eventos y finalizan cuando no son necesarios.

Comienza por registrar el service worker en el archivo manifest.json:

{
  ...
  "background": {
    "service_worker": "background.js"
  },
  ...
}

Crea un archivo llamado background.js y agrega el siguiente código:

chrome.runtime.onInstalled.addListener(() => {
  chrome.action.setBadgeText({
    text: "OFF",
  });
});

El primer evento que escuchará nuestro service worker es runtime.onInstalled(). Este método permite que la extensión establezca un estado inicial o complete algunas tareas durante la instalación. Las extensiones pueden usar la API de Storage y IndexedDB para almacenar el estado de la aplicación. En este caso, como solo controlamos dos estados, usamos el texto de la insignia de la acción para hacer un seguimiento de si la extensión está "ACTIVADA" o "DESACTIVADA".

Paso 3: Habilita la acción de la extensión

La acción de extensión controla el ícono de la extensión en la barra de herramientas. Cuando el usuario selecciona el ícono de la extensión, se ejecuta código (como en este ejemplo) o se muestra una ventana emergente.

Agrega el siguiente código para declarar la acción de extensión en el archivo manifest.json:

{
  ...
  "action": {
    "default_icon": {
      "16": "images/icon-16.png",
      "32": "images/icon-32.png",
      "48": "images/icon-48.png",
      "128": "images/icon-128.png"
    }
  },
  ...
}

Usa el permiso activeTab para proteger la privacidad del usuario

El permiso activeTab otorga a la extensión la capacidad temporal de ejecutar código en la pestaña activa. También permite el acceso a propiedades sensibles de la pestaña actual.

Este permiso se habilita cuando el usuario invoca la extensión. En este caso, el usuario invoca la extensión haciendo clic en la acción de extensión.

💡 ¿Qué otras interacciones del usuario habilitan el permiso activeTab en mi propia extensión?

  • Presionar una combinación de teclas
  • Seleccionar un elemento del menú contextual
  • Aceptar una sugerencia de la barra de direcciones
  • Abre una ventana emergente de extensión.

El permiso "activeTab" permite que los usuarios elijan intencionalmente ejecutar la extensión en la pestaña enfocada, lo que protege la privacidad del usuario. Otro beneficio es que no activa una advertencia de permiso.

Para usar el permiso "activeTab", agrégalo al array de permisos del manifiesto:

{
  ...
  "permissions": ["activeTab"],
  ...
}

Paso 4: Haz un seguimiento del estado de la pestaña actual

Después de que el usuario haga clic en la acción de la extensión, esta verificará si la URL coincide con una página de documentación. A continuación, verificará el estado de la pestaña actual y establecerá el siguiente estado. Agrega el siguiente código a background.js:

const extensions = 'https://developer.chrome.com/docs/extensions';
const webstore = 'https://developer.chrome.com/docs/webstore';

chrome.action.onClicked.addListener(async (tab) => {
  if (tab.url.startsWith(extensions) || tab.url.startsWith(webstore)) {
    // Retrieve the action badge to check if the extension is 'ON' or 'OFF'
    const prevState = await chrome.action.getBadgeText({ tabId: tab.id });
    // Next state will always be the opposite
    const nextState = prevState === 'ON' ? 'OFF' : 'ON';

    // Set the action badge to the next state
    await chrome.action.setBadgeText({
      tabId: tab.id,
      text: nextState,
    });
  }
});

Paso 5: Agrega o quita la hoja de diseño

Ahora es momento de cambiar el diseño de la página. Crea un archivo llamado focus-mode.css y agrega el siguiente código:

* {
  display: none !important;
}

html,
body,
*:has(article),
article,
article * {
  display: revert !important;
}

[role='navigation'] {
  display: none !important;
}

article {
  margin: auto;
  max-width: 700px;
}

Inserta o quita la hoja de diseño con la API de Scripting. Comienza por declarar el permiso "scripting" en el manifiesto:

{
  ...
  "permissions": ["activeTab", "scripting"],
  ...
}

Por último, en background.js, agrega el siguiente código para cambiar el diseño de la página:

  ...
    if (nextState === "ON") {
      // Insert the CSS file when the user turns the extension on
      await chrome.scripting.insertCSS({
        files: ["focus-mode.css"],
        target: { tabId: tab.id },
      });
    } else if (nextState === "OFF") {
      // Remove the CSS file when the user turns the extension off
      await chrome.scripting.removeCSS({
        files: ["focus-mode.css"],
        target: { tabId: tab.id },
      });
    }
  }
});

Asigna una combinación de teclas (opcional)

Solo por diversión, agrega un acceso directo para que sea más fácil habilitar o inhabilitar el modo sin distracciones. Agrega la clave "commands" al manifiesto.

{
  ...
  "commands": {
    "_execute_action": {
      "suggested_key": {
        "default": "Ctrl+B",
        "mac": "Command+B"
      }
    }
  }
}

La tecla "_execute_action" ejecuta el mismo código que el evento action.onClicked(), por lo que no se necesita código adicional.

Prueba si funciona

Verifica que la estructura de archivos de tu proyecto se vea de la siguiente manera:

Contenido de la carpeta del modo de enfoque: manifest.json, background.js, focus-mode.css y la carpeta de imágenes

Carga tu extensión de forma local

Para cargar una extensión sin empaquetar en el modo de desarrollador, sigue los pasos que se indican en Hello World.

Prueba la extensión

Abre cualquiera de las siguientes páginas:

Luego, haz clic en la acción de extensión. Si configuras una combinación de teclas, puedes probarla presionando Ctrl + B o Cmd + B.

Debería pasar de esto:

Extensión del Modo sin distracciones DESACTIVADA
Extensión del Modo sin distracciones desactivada

A esto:

La extensión del Modo sin distracciones está ACTIVADA
Extensión del Modo sin distracciones activada

Posibles mejoras

Según lo que aprendiste hoy, intenta lograr cualquiera de los siguientes objetivos:

  • Mejora la hoja de estilo CSS.
  • Asigna una combinación de teclas diferente.
  • Cambiar el diseño de tu blog o sitio de documentación favorito

Sigue creando

¡Felicitaciones por completar este instructivo 🎉! Sigue mejorando tus habilidades completando otros instructivos de esta serie:

Extensión Qué aprenderás
Tiempo de lectura Insertar un elemento en un conjunto específico de páginas de forma automática
Administrador de pestañas Crea una ventana emergente que administre las pestañas del navegador.

Sigue explorando

Esperamos que hayas disfrutado la creación de esta extensión de Chrome y que te entusiasme continuar tu recorrido de aprendizaje sobre el desarrollo de extensiones. Te recomendamos los siguientes programas de aprendizaje: