hand Inicio
hand JSBloqs
hand GutenBloqs
Qu茅?
noched铆a

DESARROLLO WEB con
REACT y WORDPRESS

Ap煤ntate a la newsletter (escribo algo de tanto en cuanto)
Wallpaper)

JavaScript Aplicado con una extensi贸n de Chrome y Unsplash

1200 palabras
5 minutos
July 14, 2020
cursosjavascriptbasico

Vamos a utilizar JavaScript sin ning煤n tipo de framework, s贸lo con JavaScript "vainilla", para escribir una extensi贸n para Chrome que nos muestre im谩genes de unsplash

Pr贸logo

Las extensiones de Chrome son herramientas potentes que sin embargo no han conseguido convertir en t茅rminos de monetizaci贸n lo que uno podr铆a esperar

En cualquier caso se utilizan much铆simo

En este curso vamos a ver un ejemplo simple y sin complicarnos, s贸lo con pure JavaScript o tambi茅n conocido con JavaScript vainilla

Y qu茅 har谩?

Simplemente mostrarnos una imagen de unsplash en cuanto abrimos una nueva pesta帽a

Vamos all谩

  1. Pr贸logo
  2. manifest.json
  3. kw-unsplash.html
  4. Chrome://extensions
  5. Mostrar un background de unsplash
  6. A帽adiendo un cach茅
  7. Renovar la imagen cada dia
  8. Bot贸n para cambiar la imagen
  9. Publicando la extensi贸n
  10. C贸digo final

manifest.json

脡ste es el primer archivo que tendremos que crear, un archivo JSON que no es m谩s que un archivo en forma de objeto de JavaScript, donde incluiremos informaci贸n que Chrome nos pide

json
{
"manifest_version": 2,
"name": "KUW-Chrome-Unsplash",
"description": "Unsplash images on your new tab",
"version": "1",
"author": "KUWorking",
"browser_action": {
"default_icon": "kuw-chrome-unsplash.png",
"default_title": "KUWorking"
},
"chrome_url_overrides": {
"newtab": "kw-unsplash.html"
},
"permissions": ["activeTab"]
}

Recuerda que en los archivos json las propiedades van con comillas s铆 o s铆, y no juegues con las comas

Puedes ver todas las opciones que aplican en developer.chrome.com

Con nuestro manifest lo que hemos hecho es aparte de definir los n煤meros de versiones, descripciones y dem谩s, definir las acciones y los permisos de nuestra extensi贸n

  • La versi贸n del manifiesto tiene que ser 2 ya que es el formato de manifiesto que Chrome espera

  • En chrome_url_overrides estamos sustituyendo la p谩gina de nueva pesta帽a que es newtab y que la dirigimos hacia kw-unsplash.html

  • Y para hacer esta sustituci贸n necesitamos los permisos, que apuntamos en permissions, de activeTab que es lo que nos permite interceder cuando el usuario abre una nueva pesta帽a (y se le pedir谩 que acepte este permiso al instalar la extensi贸n)

kw-unsplash.html

Para crear una p谩gina html b谩sica (que es la que Chrome ejecutar谩 como nueva pesta帽a) utilizaremos una estructura como la siguiente

html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<meta name="author" content="kuworking" />
<meta name="description" content="Unsplash images on your new tab" />
<meta name="keywords" content="chrome,extension,unsplash,new tab" />
<title>kuworking.com</title>
<link rel="stylesheet" href="//fonts.googleapis.com/css?family=font1|font2|etc" type="text/css" />
<style type="text/css"></style>
<script src="kw-unsplash.js"></script>
</head>
<body></body>
</html>

P谩sate por los cursos de html y css si quieres profundizar, los tienes aqu铆 y aqu铆

A destacar, importo las fuentes directamente de Google (tienes una herramienta para verlas font-inspiration)

html
<head>
<link rel="stylesheet" href="//fonts.googleapis.com/css?family=Didact+Gothic" type="text/css" />
</head>

Y preparo el terreno para a帽adir las normas css y el JavaScript

html
<head>
<style type="text/css"></style>
<script src="kw-unsplash.js"></script>
</head>

Con esto ya tenemos nuestra extensi贸n lista (lo que vendr铆a a ser el esqueleto de la extensi贸n) y ya podemos ver qu茅 tal se comporta

Chrome://extensions

Para probar la extensi贸n nos vamos a chrome://extensions (lo ponemos en nuestro Chrome como si fuera una direcci贸n web, o accedemos a ella a trav茅s de los men煤s) y all铆 accionamos el Developer mode para poder luego clicar el Load unpacked y seleccionar el directorio donde tenemos estos dos archivos (el manifest y el html)

Pero para que funcione necesitamos el icono, b谩jate cualquier imagen en formato .png, ponle el nombre que has puesto en el manifest, y listos, ya tenemos el esqueleto de la extensi贸n

Mostrar un background de unsplash

Utilizamos la API de unsplash, y generamos la imagen con JavaScript, por lo que lo primero es a帽adir el ancla donde pondremos la imagen que ser谩 simplemente un <div>

html
<body>
<div id="imagen"></div>
</body>
</html>

Y luego, creamos el archivo kw-unsplash.js que es donde le hemos dicho al documento que tendr铆amos nuestro script

js
const start = () => {
const keywords = 'coding,apple'
const url = `https://source.unsplash.com/random/?${keywords}`
const htmlCode = `<img src="${url}" />`
document.getElementById('imagen').innerHTML = htmlCode
}
document.addEventListener('DOMContentLoaded', start, true)

Lo primero es la 煤ltima l铆nea, donde le digo que cuando el DOM est茅 cargado (lo que viene a ser que todo el documento haya sido interpretado por el navegador) ejecute la funci贸n que se llama start

Luego defino la funci贸n start, y lo hago utilizando JavaScript moderno con las fat arrows

Esto representa un problema puesto que hay muchos navegadores (antiguos) que no entienden este JavaScript

Por eso necesitar铆amos utilizar alg煤n proceso de compilaci贸n para transformar ese JavaScript en una versi贸n m谩s antiguo y compatible

La mejor manera (normalmente) de conseguir esto es trabajar con alg煤n framework concreto que ya nos lo integre

Pero aqu铆 no haremos ni una cosa ni la otra, pero que lo sepas

A partir de aqu铆, la funci贸n start construye la url con la que pediremos la imagen mediante el elemento html <img>

Pero esto, que nos funcionar铆a en una p谩gina normal, no nos funciona en una extensi贸n por sus limitaciones particulares (lo puedes leer aqu铆)

El c贸digo que s铆 funciona es el siguiente:

js
const start = () => {
const keywords = 'coding,apple'
const url = `https://source.unsplash.com/random/?${keywords}`
const htmlCode = `<img src="${url}" />`
document.getElementById('imagen').innerHTML = htmlCode
}
chrome.tabs.getCurrent(start)

En lugar de utilizar una imagen lo que haremos ser谩 cambiar el fondo del elemento <body>

El c贸digo css ser铆a el siguiente

css
<style type="text/css">
body {
background-image: url('');
background-size: cover;
background-repeat: no-repeat;
background-position-x: center;
background-position-y: center;
background-attachment: fixed;
}
</style>

Y en el JavaScript lo que har铆amos ser铆a modificar el elemento <body> y dejaremos de lado la imagen

js
const start = () => {
const keywords = 'coding,apple'
const url = `https://source.unsplash.com/random/?${keywords}`
document.body.style.backgroundImage = `url('${url}')`
}
chrome.tabs.getCurrent(start)

A帽adiendo un cach茅

El cach茅 nos sirve para que si la imagen ya se ha descargado con anterioridad no se vuelva a descargar

Una manera de hacerlo es a帽adiendo el header correspondiente

html
<meta http-equiv="Cache-control" content="public" />

Otra manera de hacerlo y asegurarse es la siguiente

js
/**
* funci贸n para
* - generar la url de unsplash
* - descargar la imagen con fetch
* - almacenar la url en localStorage
*/
const get_image_url = async keywords => {
const response = await fetch(`https://source.unsplash.com/random/?${keywords}`)
const image_url = response.url
window.localStorage.setItem('kw-wallpaper', image_url)
return image_url
}
/**
* funci贸n para
* - pedir la imagen con la url en la cach茅 del navegador
* - descargarla de esa cach茅, y si no est谩 a帽adirla al cach茅
* - devolver la url original o la del cach茅 si esta existe
*/
const get_image = async image_url => {
const request = new Request(image_url)
const cache = await caches.open('kw-cache')
const cached_image = await cache.match(request)
cached_image || cache.add(request)
return cached_image ? cached_image.url : image_url
}
/**
* funci贸n general que recoge la url que est谩 en localStorage, o si no hay ninguna la genera de nuevo
* .. para luego descargarla y a帽adirla como fondo de <body>
*/
const start = async () => {
const keywords = 'coding,apple'
const image_url = window.localStorage.getItem('kw-wallpaper') || get_image_url(keywords)
const image = get_image(image_url)
document.body.style.backgroundImage = `url('${image}')`
}
chrome.tabs.getCurrent(start)

Aqu铆 hemos utilizado la cach茅 del navegador (que nos la proporciona el propio navegador) y localStorage para recordar la url que hemos pedido

Renovar la imagen cada dia

Tal y como est谩 el c贸digo, una vez pedimos una imagen, 茅sta se almacena en localStorage y ya nunca m谩s la actualizaremos, y queremos que esto sea as铆 pero s贸lo durante un d铆a

Una manera de hacerlo es almacenar la fecha de la imagen tambi茅n en localStorage y as铆 podremos comprobar si estamos dentro del mismo d铆a o no

js
// funci贸n para determinar si lo almacenado en localStorage es de hoy o no
const is_this_a_new_day = () => {
const last_date = Number(window.localStorage.getItem('kw-date')) || ''
const today = Number(new Date().getDay())
window.localStorage.setItem('kw-date', today)
return today === Number(last_date) ? false : true
// convertimos a number el last_date que en localStorage ser谩 un string
}

Y ahora con esta funci贸n podemos decidir si miramos si hay una imagen en localStorage o si por el contrario descargamos una nueva imagen s铆 o s铆

js
const start = async () => {
const keywords = 'coding,apple'
const new_day = is_this_a_new_day()
const image_url = new_day
? await get_image_url(keywords)
: window.localStorage.getItem('kw-wallpaper') || (await get_image_url(keywords))
const image = await get_image(image_url)
document.body.style.backgroundImage = `url('${image}')`
}

Bot贸n para cambiar la imagen

Pero nos falta algo, qu茅 pasa si la imagen descargada no nos gusta?

Necesitamos un bot贸n para poder cambiarla

html
<body>
<div id="change_wallpaper"></div>
</body>

Lo estilamos con css

css
#change_wallpaper {
cursor: pointer;
width: 25px;
height: 25px;
border-radius: 2px;
background-color: #79a2ff85;
transition: background-color 0.1s;
}
#change_wallpaper:hover {
background-color: #79a2ff;
}

Y controlamos con JavaScript cu谩ndo se aprieta para ejecutar la funci贸n start con un argumento que lo definimos como un string con un texto sem谩ntico cualquiera

js
document.getElementById('change_wallpaper').addEventListener('click', () => start('refresh'), true)

Luego lo que haremos es que si existe ese argumento entonces pediremos una nueva imagen s铆 o s铆

js
const start = async refresh => {
//...
const new_day = refresh ? true : is_this_a_new_day()
//...
}

Pero hay un 煤ltimo problema y es que si apretamos el bot贸n muy seguido unsplash nos devolver谩 la misma imagen repetida

La documentaci贸n de unsplash nos dice c贸mo evitarlo

js
const different_number = new Date().getMilliseconds()
const url = `https://source.unsplash.com/random/?sig=${different_number}&&${keywords}`

Y listos

Nos faltar铆an dos cosas

  • Poner una respuesta gr谩fica cuando apretamos el bot贸n de cambio de imagen, y anular el bot贸n mientras la imagen se est谩 cargando
  • Poner un <input> para poder cambiar las keywords ya que ahora est谩n en el c贸digo

Pero vamos, el grueso de la extensi贸n ya estar铆a hecho

Publicando la extensi贸n

Este paso es el m谩s sencillo, necesitar谩s 5 USD para abrirte cuenta de desarrollador en Google (un 煤nico pago) y ya podr谩s subir tu extensi贸n de Chrome

Abrir cuenta de developers

Tienes que visitar chrome.google.com/webstore/developer/dashboard y all铆 te pedir谩n la one-time developer registration fee, piensa antes con qu茅 cuenta personal quieres abrir esta cuenta developer ya que despu茅s no podr谩s cambiar

Subir la extensi贸n

Una vez dentro te pedir谩n subir la extensi贸n en formato .zip, por lo que coge el directorio donde est茅 todo tu c贸digo, lo empaquetas con cualquier programa de compresi贸n compatible con zip y ya lo puedes subir

All铆 te pedir谩n m谩s informaci贸n, en concreto de la extensi贸n del curso nos dice que no hemos a帽adido un short name en el manifiesto, nos pide que a帽adamos una descripci贸n del mismo, un icono, y pantallazos (screenshots) que servir谩n para convencer al usuario de que se instale la extensi贸n, incluso podemos tener un v铆deo YouTube para a帽adir m谩s argumentos de compra

Piensa que la mitad del trabajo es programaci贸n, y la otra mitad es marketing!

Tienes m谩s informaci贸n sobre c贸mo publicar tu extensi贸n en la documentaci贸n de Google aqu铆

Entre otras cosas podr谩s acotar en qu茅 pa铆ses quieres publicar tu extensi贸n y a qu茅 precio quieres venderla si es que quieres monetizarla

En realidad el proceso es bastante sencillo aunque generar todo el apartado gr谩fico y de texto para la extensi贸n es m谩s laborioso (me refiero a lo que ver谩 el usuario en la tienda de extensiones)

C贸digo final

Si quieres testear el c贸digo final, aqu铆 lo tienes en versi贸n no-extensi贸n para poder probarlo en codesandbox (sin el bot贸n)

js
const is_this_a_new_day = () => {
const last_date = Number(window.localStorage.getItem('kw-date')) || ''
const today = Number(new Date().getDay())
window.localStorage.setItem('kw-date', today)
return today === Number(last_date) ? false : true
}
const get_image_url = async keywords => {
const different_number = new Date().getMilliseconds()
const response = await fetch(`https://source.unsplash.com/random/?sig=${different_number}&&${keywords}`)
const image_url = response.url
window.localStorage.setItem('kw-wallpaper', image_url)
return image_url
}
const get_image = async image_url => {
const request = new Request(image_url)
const cache = await caches.open('kw-cache')
const cached_image = await cache.match(request)
cached_image || cache.add(request)
return cached_image ? cached_image.url : image_url
}
const start = async () => {
const keywords = 'coding,apple'
const new_day = is_this_a_new_day()
const image_url = new_day
? await get_image_url(keywords)
: window.localStorage.getItem('kw-wallpaper') || (await get_image_url(keywords))
const image = await get_image(image_url)
document.getElementById('app').style.backgroundImage = `url('${image}')`
document.getElementById('app').style.backgroundSize = 'cover'
document.getElementById('app').style.backgroundRepeat = 'no-repeat'
document.getElementById('app').style.backgroundPositionX = 'center'
document.getElementById('app').style.backgroundPositionY = 'center'
document.getElementById('app').style.backgroundAttachment = 'fixed'
document.getElementById('app').style.width = '100%'
document.getElementById('app').style.height = '100vh'
}
if (document.readyState !== 'loading') start()
else document.addEventListener('DOMContentLoaded', start, true)
Ver en CodeSandBox

馃檵鈥嶁檪锔

Qu茅 tal el curso?

馃憣 Bien 馃檶馃檶
馃憤 Bien, pero algunas cosas podr铆an explicarse mejor 馃槵
馃し鈥嶁檪锔 Da por sentadas demasiadas cosas 馃槖
馃し鈥嶁檪锔 A ver, hay poca chicha 馃槵
馃し鈥嶁檪锔 Los ejemplos no son muy claros 馃檱鈥嶁檪锔
馃し鈥嶁檪锔 No se entiende, est谩 mal escrito 馃憥
鉁嶏笍 Hay errores, rev铆salo en cuanto puedas 馃檹
Enviar Feedback 鉁嶏笍
El texto est谩 en blanco!
Gracias por enviarme tu opini贸n
馃憤

Si quieres explorar m谩s cursos y m谩s entradas en el blog, los tienes todos en la p谩gina principal, y si el contenido te ha ayudado dame las gracias por ejemplo por twitter con este enlace 馃憤

Privacidad
by kuworking.com
[ 2020 >> kuworking ]