Administrar pestañas

Crea tu primer administrador de pestañas.

Descripción general

En este instructivo, se crea un administrador de pestañas para organizar tu extensión de Chrome y las pestañas de la documentación de Chrome Web Store.

Ventana emergente de la extensión del Administrador de pestañas
Extensión del Administrador de pestañas

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

  • Crea una ventana emergente de extensión con la API de Action.
  • Realiza consultas sobre pestañas específicas con la API de Tabs.
  • Preservación de la privacidad del usuario mediante permisos de host limitados.
  • Cambiar el enfoque de la pestaña
  • Mover pestañas a la misma ventana y agruparlas
  • Cambia el nombre de los grupos de pestañas con la API de TabGroups.

Antes de comenzar

En esta guía, se da por sentado que tienes experiencia básica en desarrollo web. Te recomendamos consultar 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 tabs-manager que contenga los archivos de la extensión. Si lo prefieres, puedes descargar el código fuente completo en GitHub.

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

Crea un archivo llamado manifest.json y agrega el siguiente código:

{
  "manifest_version": 3,
  "name": "Tab Manager for Chrome Dev Docs",
  "version": "1.0",
  "icons": {
    "16": "images/icon-16.png",
    "32": "images/icon-32.png",
    "48": "images/icon-48.png",
    "128": "images/icon-128.png"
  }
}

Para obtener más información sobre estas claves de manifiesto, consulta el instructivo Tiempo de lectura, en el que se explican los metadatos y los íconos de la extensión con más detalle.

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

Paso 2: Crea la ventana emergente y aplícale un estilo

La API de Action controla la acción de la extensión (ícono de la barra de herramientas). Cuando el usuario haga clic en la acción de la extensión, se ejecutará parte del código o se abrirá una ventana emergente, como en este caso. Comienza por declarar la ventana emergente en manifest.json:

{
  "action": {
    "default_popup": "popup.html"
  }
}

Una ventana emergente es similar a una página web, con una excepción: no puede ejecutar JavaScript intercalado. Crea un archivo popup.html y agrega el siguiente código:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <link rel="stylesheet" href="./popup.css" />
  </head>
  <body>
    <template id="li_template">
      <li>
        <a>
          <h3 class="title">Tab Title</h3>
          <p class="pathname">Tab Pathname</p>
        </a>
      </li>
    </template>

    <h1>Google Dev Docs</h1>
    <button>Group Tabs</button>
    <ul></ul>

    <script src="./popup.js" type="module"></script>
  </body>
</html>

A continuación, definirás el estilo de la ventana emergente. Crea un archivo popup.css y agrega el siguiente código:

body {
  width: 20rem;
}

ul {
  list-style-type: none;
  padding-inline-start: 0;
  margin: 1rem 0;
}

li {
  padding: 0.25rem;
}
li:nth-child(odd) {
  background: #80808030;
}
li:nth-child(even) {
  background: #ffffff;
}

h3,
p {
  margin: 0;
}

Paso 3: Administra las pestañas

La API de Tabs permite que una extensión cree, consulte, modifique y reorganice pestañas en el navegador.

Cómo solicitar un permiso

Muchos métodos de la API de Tabs se pueden usar sin solicitar ningún permiso. Sin embargo, necesitamos acceso al title y al URL de las pestañas; estas propiedades sensibles requieren permiso. Podríamos solicitar el permiso "tabs", pero esto brindaría acceso a las propiedades sensibles de todas las pestañas. Dado que solo administramos pestañas de un sitio específico, solicitaremos permisos de host limitados.

Los permisos de host limitados nos permiten proteger la privacidad del usuario otorgando permisos elevados a sitios específicos. Esto otorgará acceso a las propiedades title y URL, así como funciones adicionales. Agrega el código destacado al archivo manifest.json:

{
  "host_permissions": [
    "https://developer.chrome.com/*"
  ]
}

💡 ¿Cuáles son las principales diferencias entre los permisos de las pestañas y los permisos del host?

El permiso "tabs" y los permisos de host tienen desventajas.

El permiso "tabs" otorga a una extensión la capacidad de leer datos sensibles en todas las pestañas. Con el tiempo, esta información podría usarse para recopilar el historial de navegación de un usuario. Por lo tanto, si solicitas este permiso, Chrome mostrará el siguiente mensaje de advertencia al momento de la instalación:

Diálogo de advertencia sobre permisos de pestañas

Los permisos de host permiten que una extensión lea y consulte las propiedades sensibles de una pestaña coincidente, además de insertar secuencias de comandos en estas pestañas. Los usuarios verán el siguiente mensaje de advertencia al momento de la instalación:

Diálogo de advertencia de permiso de host

Esta advertencia puede ser alarmante para los usuarios. Para una mejor experiencia de integración, recomendamos implementar los permisos opcionales.

Consultar las pestañas

Puedes recuperar las pestañas de URLs específicas con el método tabs.query(). Crea un archivo popup.js y agrega el siguiente código:

const tabs = await chrome.tabs.query({
  url: [
    "https://developer.chrome.com/docs/webstore/*",
    "https://developer.chrome.com/docs/extensions/*",
  ]
});

💡 ¿Puedo usar las APIs de Chrome directamente en la ventana emergente?

Una ventana emergente y otras páginas de extensión pueden llamar a cualquier API de Chrome porque se entregan desde el esquema de Chrome. Por ejemplo, chrome-extension://EXTENSION_ID/popup.html.

Enfocar una pestaña

Primero, la extensión ordenará alfabéticamente los nombres de las pestañas (los títulos de las páginas HTML contenidas). Luego, cuando se haga clic en un elemento de la lista, este se enfocará en esa pestaña mediante tabs.update() y se enfocará en la ventana con windows.update(). Agrega el siguiente código al archivo popup.js:

...
const collator = new Intl.Collator();
tabs.sort((a, b) => collator.compare(a.title, b.title));

const template = document.getElementById("li_template");
const elements = new Set();
for (const tab of tabs) {
  const element = template.content.firstElementChild.cloneNode(true);

  const title = tab.title.split("-")[0].trim();
  const pathname = new URL(tab.url).pathname.slice("/docs".length);

  element.querySelector(".title").textContent = title;
  element.querySelector(".pathname").textContent = pathname;
  element.querySelector("a").addEventListener("click", async () => {
    // need to focus window as well as the active tab
    await chrome.tabs.update(tab.id, { active: true });
    await chrome.windows.update(tab.windowId, { focused: true });
  });

  elements.add(element);
}
document.querySelector("ul").append(...elements);
...

💡 Se usa JavaScript interesante en este código

  • Collator que se usa para ordenar el array de pestañas según el idioma preferido del usuario.
  • La etiqueta de plantilla que se usa para definir un elemento HTML que se puede clonar, en lugar de usar document.createElement() para crear cada elemento.
  • El constructor de URL que se usa para crear y analizar las URLs.
  • La sintaxis de distribución que se usa para convertir el conjunto de elementos en argumentos en la llamada append().

Agrupa las pestañas

La API de TabGroups permite que la extensión asigne un nombre al grupo y elija un color de fondo. Para agregar el permiso "tabGroups" al manifiesto, incluye el código destacado:

{
  "permissions": [
    "tabGroups"
  ]
}

En popup.js, agrega el siguiente código para crear un botón que agrupe todas las pestañas con tabs.group() y las mueva a la ventana actual.

const button = document.querySelector("button");
button.addEventListener("click", async () => {
  const tabIds = tabs.map(({ id }) => id);
  if (tabIds.length) {
    const group = await chrome.tabs.group({ tabIds });
    await chrome.tabGroups.update(group, { title: "DOCS" });
  }
});

Prueba que funcione

Verifica que la estructura de archivos de tu proyecto coincida con el siguiente árbol de directorios:

El contenido de la carpeta del administrador de pestañas: manifest.json, ventana emergente.js, ventana emergente.css, ventana emergente.html y carpeta de imágenes

Carga la extensión de forma local

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

Abre algunas páginas de documentación

Abre los siguientes documentos en otras ventanas:

Haz clic en la ventana emergente. Se verá de la siguiente manera:

Ventana emergente de la extensión del Administrador de pestañas
Ventana emergente de la extensión del Administrador de pestañas

Haz clic en el botón "Agrupar pestañas". Se verá de la siguiente manera:

Pestañas agrupadas en el Administrador de pestañas
Pestañas agrupadas con la extensión Administrador de pestañas

🎯 Posibles mejoras

En función de lo que aprendiste hoy, intenta implementar cualquiera de las siguientes opciones:

  • Personalizar la hoja de estilo emergente
  • Cambia el color y el título del grupo de pestañas.
  • Administrar las pestañas de otro sitio de documentación
  • Agrega compatibilidad para desagrupar las pestañas agrupadas.

Sigue creando

Felicitaciones por terminar este instructivo 🎉. Para seguir desarrollando tus habilidades, completa otros instructivos de esta serie:

Extensión Qué aprenderás
Tiempo de lectura Para insertar un elemento en cada página automáticamente.
Modo sin distracciones Para ejecutar el código en la página actual después de hacer clic en la acción de la extensión.

Sigue explorando

Esperamos que hayas disfrutado de crear esta extensión de Chrome y nos entusiasma continuar tu recorrido de aprendizaje sobre el desarrollo de Chrome. Recomendamos la siguiente ruta de aprendizaje:

  • La guía para desarrolladores contiene decenas de vínculos adicionales a documentación relevante para la creación avanzada de extensiones.
  • Las extensiones tienen acceso a APIs potentes más allá de lo que está disponible en la Web abierta. En la documentación de las API de Chrome se explica cada API.