04 mayo, 2023

Un bookmarklet para integrar imágenes en un único archivo HTML

Tengo por costumbre leer libros en formato EPUB con la app Moon+ reader, tanto en el móvil (amoled con fondo negro y filtro de pantalla antireflejos) como en mi ebook de 10". Sin embargo, en ocasiones el libro que quiero leer no está disponible ese formato. Un caso que ya me ha ocurrido en ocasiones es que el libro esté online para ser leido en el navegador, como éste en el que se han preocupado incluso de dejarlo en un único archivo. Existen conversores online que reciben un único archivo HTML y genera un EPUB, como éste o éste. Sin embargo, las imágenes enlazadas no se convierten, por lo que el libro generado no está completo.

 He pensado en incrustar las imágenes enlazadas en el propio documento HTML convirtiéndolas a DATA-URIs. Para ello he creado el siguiente bookmarklet: imgs2dataurl (puedes arrastrarlo a la barra de marcadores para poder ejecutarlo sobre cualquier página que tengas cargada). Al acabar el proceso, si guardas la página como archivo HTML único, las imágenes se guardarán también en el mismo archivo, lo que permite que sean adjuntadas al convertirlo a EPUB.

javascript: (async function(){
  [...document.querySelectorAll('[loading=lazy]')].forEach(a=>a.removeAttribute('loading'));
  const imgs=[...document.querySelectorAll("img[src$='.jpg'],img[src$='.png']")];
  imgs.forEach(i=>{
      if (i.src.startsWith("data:")) return;
    const canvas=document.createElement("canvas");
    canvas.width=i.naturalWidth;
    canvas.height=i.naturalHeight;
    const ctx=canvas.getContext("2d");
    ctx.drawImage(i,0,0);
    const src= canvas.toDataURL();
    if (src!='data:,') i.src= src; else console.log(i.naturalWidth,i.naturalHeight,canvas.width);
  });
  const svgs= [...document.querySelectorAll("img[src$='.svg']")];
  svgs.forEach(async i=>{
    const t= await fetch(i.src);
    const text= await t.text();
    i.src='data:image/svg+xml,'+encodeURIComponent(text)
  });
})();

El código tiene tres partes. La primera se asegura de cargar todas las imágenes que especifiquen una carga lazy, o sea que se vayan cargando conforme se visualizan en el navegador. Así me aseguro de que todas las imágenes estén cargadas. De lo contrario la conversión a Data-uris fallaría al no tener imagen disponible.

A continuación realizo la conversión de las imágenes PNG y JPG usando un elemento canvas que incluye una función toDataURL para hacer la conversión directa. El resultado de esa función se guarda directamente en el img.src sustituyendo efectivamente la referencia a la imagen a cargar por la misma imagen ya codificada. Y por último hago el mismo proceso con los SVG.

Enjoy!

30 septiembre, 2021

Introducción a Petite Vue

 Hace tiempo que no publico en este blog. Aprovecho para crear una pequeña introducción a la nueva librería Petite Vue del mismo autor de Vue pero de tamaño mucho más reducido (6kB).


Veremos qué hace, cómo funciona, cómo compararlo con Vue y con Alpine.js y cómo empezar a usarlo.

petite-vue está optimizado para pequeñas interacciones sobre páginas HTML existentes generadas por un una plataforma de servidor, y con ello simplificando la mejora progresiva.

Características fundamentales

No necesita proceso de build

Puedes incluir simplemente petite-vue en una etiqueta script para conseguir sus ventajas en una página HTML:

<script src="https://unpkg.com/petite-vue" defer init></script>

<!-- en cualquier lugar de la página: -->
<div v-scope="{ count: 0 }">
  {{ count }}
  <button @click="count++">inc</button>
</div>

Pequeño tamaño

Las últimas versiones de Vue y de Alpine ocupan 22.9kB y 9.9kB minificadas y comprimidas lo que contrasta con los 6.4kB de petite-vue.

Sintaxis de templates compatible con Vue

Un desarrollador familiarizado con la sintaxis de templates de Vue encontrará muy fácil moverse entre Vue y petite-vue.

Como subconjunto de Vue, petite-vue usa la mayoría de la sintaxis familiar de Vue. Por ejemplo, petite-vue usa interpolación de templates del tipo {{cuenta}} y escuchadores de eventos de templates como @click.

Sin DOM virtual

A diferencia de Vue, React y de la mayoría de otras librerías y plataformas de frontend, petite-vue no usa virtual DOM. En su lugar, muta el DOM in situ. Como resultado, petite-vue no necesita un compilador decrementando su tamaño.

Dirigido por @vue/reactivity

El paquete @vue/reactivity es el responsable de la reactividad de ambos, Vue y Alpine. petite-vue usa la misma técnica de reactividad.

Cómo se compara petite-vue con Vue estándar

petite-vue es similar a Vue en muchas formas. Como se ha mencionado, ofrece la misma sintaxis de templates y modelo @vue/reactivity provisto por Vue estándar. Pero la diferencia más significativa es que petite-vue se ha creado para la mejora progresiva.

Vue estándar se diseñó para usar un paso de generación o build para crear aplicaciones de una página (SPAs) con fuertes interacciones. Utiliza funciones de renderizado que reemplazan los templates existentes en DOM. petite-vue, por otro lado, recorre el DOM existente y lo muta in situ, por lo que no requiere de un paso de generación.

Características exclusivas de petite-vue 

petite-vue introduce algunas características que no están disponibles en el Vue estándar y que ayudan a optimizar la mejora progresiva:

v-scope

En petite-vue, v-scope es una directiva que marca la región de la página controlada por petite-vue. También puedes usar la directiva v-scope para pasar estados a los que una región particular de la página tendrá acceso.

v-effect

v-effect es una directiva usada para ejecutar declaraciones reactivas inline con petite-vue. En  el código siguiente, la variable cuenta es reactiva , así que el v-effect se reejecutará cuando cambie la cuenta, entonces actualizar el div con el valor actual de cuenta

<div v-scope="{ count: 0 }">
  <div v-effect="$el.textContent = count"></div>
  <button @click="count++">++</button>
</div>

Eventos de ciclo de vida

petite-vue viene con dos eventos de ciclo de vida, @mounted y @unmounted que te permiten escuchar cuando petite-vue se monta o desmonta en la página.

Características compatibles con Vue

Ahora que hemos visto las nuevas características que petite-vue trae, veamos las que ya existían en Vue:

  • {{ }}: vinculaciones de texto
  • v-bind y : : manejo especial de estilos y clases
  • v-on y @ : manejo de eventos
  • v-model: representa todos los tipos de entradas y vinculaciones :value no cadenas
  • v-if/ v-else / v-else-if
  • v-for
  • v-show
  • v-hmtl
  • v-pre
  • v-once
  • v-cloak
  • reactive()
  • nextTick()
  • Template refs

Características exclusivas de Vue

Dado su ámbito reducido, petite-vue ha descartado algunas de las características de Vue estándar:

  • ref() ycomputed()
  • Funciones de renderizado: petite-vue no tiene virtual DOM
  • Reactividad para tipos de colección: Map, Set, etc.
  • Componentes Transition, keep-alive, <teleport>, y <suspense
  • v-for: desestructuración profunda
  • v-on="object"
  • v-is y <component :is="newComponent">
  • v-bind:style auto-prefijado

 

Cómo se compara petite-vue con Alpine

Aunque petite-vue está inspirado por Alpine y resuelve problemas similares, difiere de Alpine debido a su minimalismo y a su compatibilidad con Vue.

petite-vue ocupa unos dos tercios del tamaño de Alpine. A diferencia de Alpine, no trae un sistema de transiciones.

Alpine y petite-vue tienen diferentes diseños. Aunque Alpine se parece a la estructura de Vue de alguna forma, peite-vue está más alineado con el Vue estándar, minimizando el coste den cambios que tendrás si quieres pasar entre petite-vue y Vue.

Empezar con petite-vue

Para empezar con petite-vue, necesitas incluir una etiqueta script que apunte al paquete de petite-vue. Creemos una simple aplicación de votación impulsada por petite-vue.

Primero creemos un archivo index.html. En su cuerpo, añade el siguiente código:

 <script src="https://unpkg.com/petite-vue" defer init></script>
  <div v-scope="{ votosPositivos: 0, votosNegativos: 0 }">
    <p>
      {{ votosPositivos }} <button @click="votosPositivos++">&#128077;</button>
    </p>
    <p>
      {{ votosNegativos }} <button @click="votosNegativos++">&#128078;</button>
    </p>
  </div>

 El atributo defer de la etiqueta script hace que la carga del código de petite-vue se posponga hasta que el contenido HTML se haya parseado por el navegador.

El atributo init le dice a petite-vue que automáticamente consulte e inicialice todos los elementos que tengan v-scope.

El v-scope le dice a petite-vue que región de la página gestionar. También pasamos los estados votosPositivos y votosNegativos para que estén disponibles en esa región.

Inicialización manual

Si no quieres que petite-vue inicialice automáticamente todos los elementos que tengan el atributo v-scope, puedes inicializarlos manualmente cambiando el script:

<script src="https://unpkg.com/petite-vue"></script>
<script>
  PetiteVue.createApp().mount()
</script>

 Alternativamente puedes usar la distribución de petite-vue compatible con módulos ES.

<script type="module">
  import { createApp } from 'https://unpkg.com/petite-vue?module'
  createApp().mount()
</script>

URL de CDN de producción de petite-vue

Estamos accediendo a petite-vue mediante una URL de CDN (red de distribución de contenidos). Estamos usando una URL reducida https://unpkg.com/petite-vue que es perfecta para prototipos pero no para producción. Queremos evitar costes de resolución y de redirección, así que usaremos las URLs completas.

La URL de distribución en producción global https://unpkg.com/petite-vue@0.2.2/dist/petite-vue.iife.js expone PetiteVue global y también soporta autoinicialización.

La URL de distribución en producción ESM (módulos) https://unpkg.com/petite-vue@0.2.2/dist/petite-vue.es.js debe usarse en un bloque <script type="module">.

Cuándo usar petite-vue

Hemos aprendido las características de petite-vue y lo que puede hacer. Veamos las mejores situaciones para las que petite-vue está diseñado:

  • Prototipado rápido cuando no necesitas una herramienta de generación/build
  • Agregar funcionalidad Vue en plataformas de servidor como Sails, Laravel o Rails
  • Construir páginas landing o de marketing que sean estáticas con pocas interacciones
  • En cualquier lugar donde usarías Alpine normalmente

Conclusión

 peitet-vue es una versión más ligera de Vue que añade interaciones eficientes a las páginas. petite-vue es aún nuevo (2021) e incluye un aviso sobre errores potenciales. En cualquier caso, petite-vue ya es una opción funcional con una utilidad y potencial fuertes. Es especialmente útil para el prototipado rápido, rociando funcionalidad Vue en plataformas de servidor, y construyendo páginas estáticas.

04 enero, 2017

Aprender Javascript en 2016

http://www.etnassoft.com/2017/01/03/aprender-javascript-en-2016/

Interesante traducción de un artículo que da justo en el clavo. Programar en Javascript actualmente siguiendo las tendencias del mercado implica aprender una cantidad absurda de tecnologías. Simplemente recordar el principio KISS (Keep It Simple, Stupid), algo así como "Hazlo fácil, estúpido"... Complicarse la vida por intentar seguir las tendencias nunca ha sido tan fácil...

08 enero, 2013

Couchbase Server

Acaba de ser publicado para varias plataformas la versión 2.0 del Couchbase Server. Una interesante base de datos que sigue el paradigma NoSQL que se basa en un modelo flexible sobre JSON que facilitar modificar aplicaciones sin las restricciones de tener esquemas de datos fijos. Además posee un rendimiento elevado gracias a liberarse de las restricciones propias de las bases de datos relacionales, lo que ofrece una velocidad muy elevada en comparación con aquellas. Y otra ventaja es la escalabilidad, ya que la tecnología se ha diseñado con la idea de soportar cambios de topología sin necesidad de detener el servicio en ningún momento.

24 octubre, 2012

plv8js es un añadido de lenguaje procedural para PostgreSQL, lo que significa que puedes definir funciones JavaScript que se ejecutan en un servidor PostgreSQL usando el google V8 Engine. Una pareja perfecta para los recientes campos JSON de PostgreSQL.

15 octubre, 2012

QuirksBlog ha publicado los resultados de una encuesta sobre uso de librería en Javascript, según el cuál, el 80% de desarrolladores usa frecuentemente jQuery, el 35% Modernizr, el 16% Underscore, y el 11% Backbone

18 julio, 2012

Este artículo en inglés explica magistralmente la necesidad de mantener actualizado el navegador de Internet. Una referencia interesante orientada a realizar una labor pedagógica hacia los usuarios de productos basados en la web.

31 mayo, 2012

Stabilizing Couchbase Server 2.0. Sólo notificar el avance en el desarrollo de una nueva base de datos de documentos distribuida, fiable, eficiente y de alto rendimiento. Está basada en el conocido proyecto de "NoSQL" CouchDB...

14 mayo, 2012

Firebase es un servicio/nube que automáticamente sincroniza datos entre tus clientes y sus servidores. Libera a los desarrolladores de preocuparse por cómo sus datos serán transmitidos y almacenados, y les permite centrarse en la lógica de la aplicación. Las aplicaciones que usan Firebase pueden escribirse enteramente con Javascript en el navegador, actualizarse directamente en tiempo real, son inherentemente escalables e interoperan con servicios existentes.

Dataset es una librería JS de gestión y transformación de datos en el lado del cliente. Dataset facilita la gestión de datos en el lado del cliente gestionando la carga, proceso, ordenación, consulta y manipulación de datos desde todo tipo de fuentes. http://misoproject.com/dataset/

25 abril, 2012

Gracias a un mensaje de Google al respecto de Codejam, descubro ideone.com, un IDE (editor) para programar online con prácticamente cualquier lenguaje. Interesante.

17 abril, 2012

Los lenguajes más usados según libros vendidos

Me he encontrado con una curiosa gráfica que calcula los lenguajes de programación más usados a partir de la venta de libros en o'Reilly.



Según ella, Java y Javascript son las que más han crecido. Junto con C++. Por otro lado, han habido descensos en C#, Objective C, PHP o Visual Basic.

via readwriteweb



Últimos links en indiza.com