Usando la nueva API de tematización en Firefox

11 agosto, 2018 19:20 por

Esta es una traducción del artículo original publicado en el blog de Mozilla Hacks.

Desde las poderosas extensiones como Stratiform o FT Deep Dark hasta los sencillos temas ligeros, los temas han sido bastantes populares dentro de Firefox. Ahora que Firefox Quantum (57) se ha lanzado con muchas mejoras de desempeño y una nueva interfaz brillante, queremos cerrar la brecha con una nueva API de tematización que te permita ir más allá de los básicos temas de peso ligero.

Theme API

Demostración por John Gruen

¿Qué puedes tematizar?

Antes del lanzamiento de Quantum, los temas ligeros tenían un limitado conjunto de propiedades que podían ser tematizadas: sólo podías agregar una imagen de cabecera y establecer el color de texto y el color de fondo del marco. La nueva API de tematización introduce algunas nuevas propiedades. La lista completa puede ser encontrada en MDN. Un objeto Theme básico luce como esto:

{
  "colors": {
    "accentcolor": "tomato",
    "textcolor": "white",
    "toolbar": "#444",
    "toolbar_text": "lightgray",
    "toolbar_field": "black",
    "toolbar_field_text": "white"
  },
  "images": {
    "headerURL": ""
  }
}

Así es como se muestra el tema anterior:

Nota cómo la propiedad images.headerURL es establecida con una cadena de texto vacía. Esto es porque es una de las tres propiedades obligatorias: images.headerURL, colors.accentcolor y colors.textcolor.

Finalmente, otra mejora sobre los temas ligeros es el soporte para múltiples imágenes, usando el campo images.additional_backgrounds que toma una matriz de rutas de imágenes. Las alineaciones y mosaicos de estas imágenes se logran usando properties.additional_backgrounds_alignment y properties.additional_backgrounds_tiling, que toman una matriz de valores background-position y background-repeat respectivamente. Puedes revisar esto en la MDN para un ejemplo. Puedes usar múltiples fondos para mostrar cortinas en ambos lados de la interfaz del navegador, o como una forma de agregar varios indicadores temáticos (deportes/clima/navegación privada) en la interfaz.

Temas dinámicos

Digamos que te gustaría introducir un modo noche a tu tema. Los temas dinámicos te permiten hacer esto. Éstos tienen el poder completo de una extensión normal de navegador. Para usar la tematización dinámica, necesitas agregar el permiso de theme en tu archivo manifest.

El método browser.theme.update() es el núcleo de este tipo de tematización. Éste toma un objeto Theme como parámetro. El método puede ser llamada en cualquier lugar de tus scripts en segundo plano.

Para este ejemplo, vamos a crear una extensión que cambie el tema dependiendo de si es de noche o de día. El primer paso es crear una función en tu script de background que cambie tu tema al tema de día o al tema de noche:

var currentTheme = '';

const themes = {
    'day': {
        images: {
            headerURL: 'sun.jpg',
        },
        colors: {
            accentcolor: '#CF723F',
            textcolor: '#111',
        }
    },
    'night': {
        images: {
            headerURL: 'moon.jpg',
        },
        colors: {
            accentcolor: '#000',
            textcolor: '#fff',
        }
    }
};

function setTheme(theme) {
    if (currentTheme === theme) {
        // No se cambia el tema si ya ha sido cambiado
        return;
    }

    currentTheme = theme;
    browser.theme.update(themes[theme]);
}

El código anterior define dos temas: El tema de día y el tema de noche, la función setTheme usa browser.theme.update() para establecer el tema. El siguiente paso ahora es usar esta función setTheme y verificar periódicamente si la extensión debe intercambiar los temas. Puedes hacer esto usando la API de alarmas. El código anterior verifica periódicamente y establece el tema de acuerdo a:

function checkTime() {
    let date = new Date();
    let hours = date.getHours();
    // Se establecerá el tema de día entre las 8am y 8pm.
    if (hours > 8 && hours < 20) {
        setTheme('day');
    } else {
        setTheme('night');
    }
}

// Al inicio, verificar el tiempo para ver qué tema mostrar.
checkTime();

// Configurar la alarma para verificar esto regularmente.
browser.alarms.onAlarm.addListener(checkTime);
browser.alarms.create('checkTime', {periodInMinutes: 5});

¡Eso es todo para este ejemplo! El ejemplo completo está disponible en el repositorio de GitHub de webextension-examples.

Otros método que no es cubierto por el ejemplo es browser.theme.reset(). Este método simplemente reinicia el tema al tema predeterminado del navegador.

Temas por ventana

La API de tematización es muy poderosa, ¿pero qué pasa si necesitas aplicar un tema diferente para ventanas privadas o ventanas inactivas? Desde Firefox 57 en adelante, es posible especificar un parámetro windowId tanto a browser.theme.update() como browser.theme.reset(). El windowId es el mismo ID retornado por la API de ventanas.

Vamos a hacer un ejemplo sencillo que agrega un tema oscuro a ventanas privadas y mantiene las otras ventanas con el tema predeterminado

Empezamos definiendo la función themeWindow:

function themeWindow(window) {
    // Verifica si la ventana está en navegación privada
    if (window.incognito) {
        browser.theme.update(window.id, {
            images: {
                headerURL: "",
            },
            colors: {
                accentcolor: "black",
                textcolor: "white",
                toolbar: "#333",
                toolbar_text: "white"
            }
        });
    }
    // De otra forma, reinicia al tema predeterminado
    else {
        browser.theme.reset(window.id);
    }
}

Una vez que está hecho, podemos conectar esto con la API de ventanas:

browser.windows.onCreated.addListener(themeWindow);

// Tematizar todas las ventanas abiertas actualmente
browser.windows.getAll().then(wins => wins.forEach(themeWindow));

Bastante sencillo, ¿verdad? El ejemplo completo lo puedes encontrar aquí. Así es como se ve el ejemplo:

Otro complemento que hace uso de estas capacidades es Containers Theme por Jonathan Kingston, que establece el tema de cada ventana según el contenedor de la pestaña seleccionada. El código fuente de este complemento lo puedes encontrar aquí.

El complemento VivaldiFox también hace uso de esta capacidad para mostrar diferentes temas de sitios web en diferentes ventanas.

Obtener información sobre el tema actual

Desde Firefox 58 en adelante, puedes obtener información sobre el tema actual y vigilar actualizaciones del tema. He aquí por qué esto importa:

Esto permite a los complementos integrar su interfaz de usuario sin problemas con el actual tema instalado por el usuario. Un ejemplo de esto sería coincidir los colores de tu barra lateral con los colores de tu tema actual.

Para hacerlo, Firefox 58 provee dos nuevas API: browser.theme.getCurrent() y browser.theme.onUpdate.

Aquí está un ejemplo que aplica algunas de las propiedades del tema actual al estilo de un sidebar_action:

function setSidebarStyle(theme) {
    const myElement = document.getElementById("myElement");

    // colors.frame y colors.accentcolor son alias
    if (theme.colors && (theme.colors.accentcolor || theme.colors.frame)) {
        document.body.style.backgroundColor = theme.colors.accentcolor || theme.colors.frame;
    } else {
        document.body.style.backgroundColor = "white";
    }

    if (theme.colors && theme.colors.toolbar) {
        myElement.style.backgroundColor = theme.colors.toolbar;
    } else {
        myElement.style.backgroundColor = "#ebebeb";
    }

    if (theme.colors && theme.colors.toolbar_text) {
        myElement.style.color = theme.colors.toolbar_text;
    } else {
        myElement.style.color = "black";
    }
}

// Establecer los estilos cuando la página de la extensión se carga
browser.theme.getCurrent().then(setSidebarStyle);

// Observar cambios de tema
browser.theme.onUpdated.addListener(async ({ theme, windowId }) => {
    const sidebarWindow = await browser.windows.getCurrent();
    /*
     Solo actualiza el tema si aplica a la ventana donde está la barra lateral.
     Si se pasa un windowId en una actualización, el tema solo se aplica a esa ventana.
     Sino, el tema se aplica globalmente a todas las ventanas.
    */
    if (!windowId || windowId == sidebarWindow.id) {
        setSidebarStyle(theme);
    }
});

El ejemplo completo puede ser encontrado en Github. Como puedes ver en la siguiente captura de pantalla, la barra lateral usa los colores del tema del navegador aplicado actualmente:

Otro ejemplo es el complemento Tree Style Tab que hace uso de estas API para integrar su interfaz con el tema usado actualmente. Este es un ejemplo real del complemento funcionando junto con VivaldiFox:

Vivaldi fox

¿Qué sigue?

¡Hay más APIs llegando! Tenemos planeado expandir el conjunto de propiedades soportadas y pulir algunas asperezas a la forma en cómo los temas son aplicados. El registro de bug para el API puede ser encontrado en Bugzilla.

Por mientras, no podemos esperar para ver de lo que serás capaz de hacer con la nueva API de tematización. Por favor, déjanos saber qué mejoras te gustaría ver.

The following two tabs change content below.

AngelFQC

Web Developer at BeezNest Latino
Ingeniero de Sistemas y Computación. Desarrollador PHP. Mozilla Peru. Chamilo LMS Developer.

Compartir artículo:

Start the discussion at foro.mozilla-hispano.org

  • ¡Participa!

    Firefox Friends »
    Agrega botones de Firefox en tu sitio web y comparte tu amor por Mozilla Firefox.
    Ayuda a otros usuarios en Twitter.
    Colabora con la comunidad »
    En Mozilla lo importante son las personas. Descubre cómo puedes colaborar.

    Boletín Firefox

    Suscríbete al boletín de novedades de Firefox.

  • Descargas

    Descarga los programas de Mozilla.

    Lo más visto

    cc-by-sa