55
Trabajo de Fin de Grado ETSIT UPM UNIVERSIDAD POLITÉCNICA DE MADRID ESCUELA TÉCNICA SUPERIOR DE INGENIEROS DE TELECOMUNICACIÓN Grado en Ingeniería de Tecnologías y Servicios de Telecomunicación TRABAJO DE FIN DE GRADO Tutorial/Curso Web Components Nombre del Alumno: Sangeap, Doris Ana Nombre del Tutor: Pavón Gómez, Santiago Tribunal: Presidente : Pavón Gómez, Santiago Vocal : Salvachúa Rodríguez, Joaquín Luciano Secretario : Huecas FernándezToribio, Gabriel Suplente : Fernández Cambronero, David Fecha de lectura y defensa: Calificación obtenida: 1

UNIVERSIDAD POLITÉCNICA DE MADRID - oa.upm.esoa.upm.es/37770/7/PFC_ANA_SANGEAP_DORIS_2015.pdf · Trabajo de Fin de Grado ETSIT UPM TRABAJO DE FIN DE GRADO TÍTULO: Tutorial/Curso

  • Upload
    hadan

  • View
    213

  • Download
    0

Embed Size (px)

Citation preview

Trabajo de Fin de Grado ­ ETSIT UPM

UNIVERSIDAD POLITÉCNICA DE MADRID

ESCUELA TÉCNICA SUPERIOR DE INGENIEROS DE TELECOMUNICACIÓN

Grado en Ingeniería de Tecnologías y Servicios de Telecomunicación

TRABAJO DE FIN DE GRADO

Tutorial/Curso Web Components

Nombre del Alumno: Sangeap, Doris Ana

Nombre del Tutor: Pavón Gómez, Santiago

Tribunal:

Presidente: Pavón Gómez, Santiago Vocal: Salvachúa Rodríguez, Joaquín Luciano Secretario: Huecas Fernández­Toribio, Gabriel Suplente: Fernández Cambronero, David

Fecha de lectura y defensa:

Calificación obtenida:

1

Trabajo de Fin de Grado ­ ETSIT UPM

TRABAJO DE FIN DE GRADO

TÍTULO: Tutorial/Curso Web Components

ALUMNO: Sangeap, Doris Ana

TUTOR: Pavón Gómez, Santiago

DEPARTAMENTO: Ingeniería de Sistemas Telemáticos

TRIBUNAL

PRESIDENTE: Pavón Gómez, Santiago

VOCAL: Salvachúa Rodríguez, Joaquín Luciano

SECRETARIO: Huecas Fernández-Toribio, Gabriel

SUPLENTE: Fernández Cambronero, David

Fecha de lectura y defensa:

CALIFICACIÓN OBTENIDA:

2

Trabajo de Fin de Grado ­ ETSIT UPM

Resumen del Trabajo Hoy en día, Internet juega un papel muy importante en nuestras vidas y las páginas web

son el embalaje de todo aquello que nos ofrece. Sin embargo, existen muchos dominios inactivos o abandonados, muchas veces debido bien a la dificultad que supone crear uno mismo su propia página web y mantenerla actualizada a lo largo del tiempo, bien al gran coste que conlleva contratar a alguien para que lo haga, ya que muchas veces se requieren conocimientos expertos de HTML, JavaScript y CSS para construir una página web de calidad.

Por tanto, lo que necesitan tanto diseñadores web expertos como aquellos que no lo son, es una técnica que les permita facilitar tanto el proceso de creación de páginas web como su mantenimiento; Web Components es una tecnología HTML novedosa que nos ayuda en este sentido, siendo el objetivo de este documento exponer los principios básicos de su funcionamiento. El punto principal de este Proyecto es realizar un tutorial, que por un lado explique los fundamentos de Web Components, y que por otro lado muestre un ejemplo más elaborado de uso de esta tecnología a nivel de producción, todo ello empleando las cuatro especificaciones de Web Components: Custom Elements, HTML Templates, HTML Imports y Shadow DOM.

Nowadays, Internet represents a very important part of our lives and websites are the wrapping of all that it has to offer. Nevertheless, there are many inactive or abandoned domains, and many times it happens due to the difficulty that involves creating a website by himself and maintaining it updated over the time, or due to the high cost that means hiring someone to do it, given the fact that most of the times expert knowledge about HTML, JavaScript and CSS is required to develop a quality website.

Therefore, what expert web designers and common people need is a technique to help them with the building process of websites and their maintenance; Web Components is a new HTML technology that helps us with these problems, so that the purpose of this document is to expose the basic principles of how it works. The main part of this Project is to make a tutorial, that on the one hand explains the basis of Web Components, and on the other hand shows a more elaborated example of use of this technology at a production level, all of it done using the four specifications of Web Components: Custom Elements, HTML Templates, HTML Imports y Shadow DOM.

Palabras clave Web Components, Custom Elements, HTML Imports, HTML Templates, Shadow DOM, Polymer, desarrollo web, tecnología HTML, estándar HTML, tutorial, curso, ejemplos, página web, especificaciones, CSS, JavaScript, catálogo

3

Trabajo de Fin de Grado ­ ETSIT UPM

Índice Trabajo de Fin de Grado - Tutorial/Curso Web Components

Resumen del Trabajo ………………………………………………………………………….. 3

Palabras clave ……………………………………………………………………………...….. 3

Introducción …………………………………………………………………………………….. 6

Objetivos ……………………………………………………………………………………...… 8

Descripción y características de los Web Components ……………....………………….... 9

Custom Elements ……………………………………………………………………. 10

HTML Templates …………………………………………………………………….. 13

Shadow DOM …………………………………………………...………………….... 16

HTML Imports ………………………………………………………………………... 21

Tutorial/Curso Web Components …………………………………………………………… 25

¿Cuáles son las características de un Web Component y cómo funciona? ...... 25

¿Con qué navegadores son compatibles los Web Components? …………...… 27

¿Cómo importar los Web Components que se desea utilizar? ……………….... 28

¿Cómo poblar un Web Component con elementos “hijos”? ………………….… 29

¿Cómo se pueden personalizar los Web Components? ………………………... 30

¿Es compatible combinar Web Components de diferentes fuentes/tipos? ….... 32

¿Cómo conectar entre sí web Components sin escribir código? ………………. 33

¿Cómo crear mis propios Web Components? ……………………………………. 35

¿Cómo evitar conflictos CSS a la hora de utilizar Web Components? ……...… 36

¿Se pueden sobrescribir las reglas CSS de los Web Components? ………….. 38

Cosas interesantes que se pueden hacer con componentes invisibles ……….. 39

¿Cómo utilizar los Web Components a nivel de producción? …..……………… 41

Instalación de nodejs y npm en Linux (Ubuntu) …………………………. 41

Instalación de los módulos Express y Bower ……………………………. 42

Creación del proyecto y la aplicación con Express ……………………… 42

Instalación estándar de un Web Component con Bower ……………….. 42

Uso del Web Component instalado en la página ……………………...… 43

Desarrollo de la página web ……………………………………………….. 45

¿Cómo crear Web Components y compartirlos en Internet? ………………….... 46

4

Trabajo de Fin de Grado ­ ETSIT UPM

Desventajas de los Web Components ……………………………………………………... 50

Herramientas y librerías ……………………………………………………………………… 51

Nodejs ……………………………………………………………………………….... 51

Express ……………………………………………………………………………….. 51

Bower …………………………………………………………………………………. 51

Heroku ……………………………………………………………………………….... 52

Polymer Element Collections (Polymer 0.5) …………………………………….... 52

Polymer Catalog (Polymer 1.0) …………………………………………………….. 52

CustomElement.io y Component Kitchen Catalog ……………………………….. 52

Conclusión …………………………………………………………………………………….. 53

Bibliografía …………………………………………………………………………………….. 55

5

Trabajo de Fin de Grado ­ ETSIT UPM

Trabajo de Fin de Grado - Tutorial/Curso Web Components

Introducción Hoy en día, Internet es una parte fundamental de nuestras vidas, ya que está presente

en todos sus aspectos. Los más destacables podrían ser las telecomunicaciones, el trabajo o el ocio, entre otros. Al escuchar la palabra Internet, a cada persona le lleva a pensar en cosas muy variadas, sin embargo, el 90% las podríamos incluir en algunas de las siguientes categorías: aplicaciones web, juegos, tanto visualización como descarga de contenidos de vídeo, música o aplicaciones, y por último, pero desde luego no menos importante es la gran cantidad de redes sociales.

Ahora, si nos paramos a pensar qué es lo que tienen todas estas cosas en común, a parte de que Internet está en la base de su funcionamiento, es que todas ellas vienen alojadas en páginas web, que son el embalaje de prácticamente todo aquello presente en Internet. Para hacernos una idea de la importancia y el peso de las páginas web en Internet vamos a intentar ofrecer una visión clara sobre la evolución de su número a lo largo del tiempo mediante la siguiente gráfica:

Si nos paramos a analizar, observamos cómo a medida que el uso de Internet cobra cada vez más importancia en nuestra sociedad, de igual manera aparecen cada vez más páginas web, de forma que se ha pasado de una única página web en 1991 a casi mil millones en 2014. A esto es a lo que podríamos llamar una evolución exponencial en los últimos 23 años.

6

Trabajo de Fin de Grado ­ ETSIT UPM

Comparando la importancia del contenido sobre la presentación y viceversa, por un lado, está muy claro que una página web, por muy atractiva que sea su apariencia a primera vista, si no tiene algo que ofrecer o aquello que ofrece no es de calidad, seguramente no tendrá ningún éxito. Por otro lado, se puede dar la situación contraria, es decir, que el contenido o aquello que se ofrezca tenga un gran potencial o un valor excepcional pero que la presentación tenga tantas carencias que ese potencial quede oculto.

Sin embargo, si lo pensamos más detenidamente, puede resultar mucho más frustrante la segunda situación. En esta situación puede encontrarse cualquier persona que tiene una idea, producto, etc., que la desarrolla y que a pesar de tener un gran valor no consigue dar a conocer ni vender esa idea o producto porque su página web no muestra adecuadamente ese potencial. Esas personas se encuentran en desventaja ante un competidor que puede que teniendo un producto de una calidad algo inferior, lo venda antes porque sepa promocionarse mejor en su página web.

Muchas veces este problema se soluciona contratando a un diseñador web que haga este trabajo, sin embargo, suele resultar muy costoso. Además, como cualquier cosa de Internet, requiere una constante actualización o mantenimiento, que también cuesta dinero. De hecho, una muestra de esta situación es que de las casi mil millones de páginas web existentes a día de hoy, aproximadamente un 75% está compuesto de dominios inactivos o abandonados.

Otra solución sería no contratar este servicio, y ponerse uno mismo a crear su propia página web. Es cierto que hoy en día hay muchas soluciones y muchas facilidades para ello, sin embargo, puede que estas soluciones no satisfagan completamente lo que uno busca, y especialmente requisitos tales como tener una interfaz que represente adecuadamente aquello que queremos ofrecer, que resulte muy atractiva, interactiva y en igual medida muy intuitiva y fácil de manejar por los usuarios. Y no nos olvidemos de la necesidad de mantenimiento y adaptación a las necesidades que van surgiendo de una forma sencilla.

Sin embargo, las aplicaciones de hoy en día no son solo difíciles de diseñar sino también difíciles de desarrollar, sobre todo debido tanto a la gran complejidad de las herramientas y librerías empleadas, como a la cantidad de pruebas necesarias para asegurar el funcionamiento óptimo, la compatibilidad y la interoperabilidad. Por todo lo dicho, los requisitos de los que hablábamos suelen ser difíciles de conseguir, y mucho más cuando uno no es experto en HTML, CSS y JavaScript. Además, uno solo dispone de una serie de componentes predefinidos con los que tiene que construir todo y muchas veces hasta la incorporación más sencilla de un nuevo elemento en la página web puede resultar de lo más tediosa.

HTML tiene un conjunto estándar de alrededor de 100 elementos que hasta ahora, eran los componentes con los que estaba creada cualquier página o aplicación web. Aunque 100 puedan parecer muchos, esta lista de elementos resulta insuficiente a la hora de abarcar la gran variedad de componentes que constituyen una página web. Esto lleva a que solo un conjunto reducido de estos sea el que se utiliza de manera frecuente, debido a que en cualquier página web existen demasiados componentes que son muy similares y acaban

7

Trabajo de Fin de Grado ­ ETSIT UPM

perteneciendo a la misma estructura semántica. Por tanto, para diferenciarlos entre sí, se utilizan las clases, IDs u otros atributos. Por otra parte, una de las cosas que tampoco ayudan a solucionar esta situación es que los cambios de este conjunto estándar se dan de forma muy lenta, pudiendo llevar incluso años para que la gente se ponga de acuerdo en la introducción de cualquier elemento nuevo.

Actualmente, hay un nuevo conjunto de estándares HTML que definen aquello que se conoce con el nombre de Web Components. Web Components es una nueva tecnología HTML que facilita en gran medida el desarrollo de páginas web y aplicaciones. Esta tecnología acelera el ritmo de diseño y desarrollo web permitiendo que cualquiera cree y use sus propios elementos HTML. Estos elementos HTML “personalizados” tienen el mismo aspecto y funcionan de la misma manera que los convencionales. La principal diferencia es que estos nuevos elementos se pueden poner en uso sin necesidad de que todo el mundo se ponga de acuerdo de forma unánime sobre su introducción en el conjunto de elementos HTML, ni tampoco sobre cómo debería funcionar. Por tanto, Web Components acelera el ritmo de evolución del HTML.

En resumen, lo que necesitan tanto diseñadores web expertos como aquellos que no lo sean, es una técnica que les permita facilitar tanto el proceso de diseño y desarrollo de páginas web como su mantenimiento, y Web Components es una tecnología que cumple con estas expectativas. Con Web Components, surge una variedad de posibilidades mucho más amplia, donde se conciben componentes para cualquier tipo de interfaz con la cual el usuario pueda interactuar como menús, animaciones, etc…

Objetivos El objetivo de este documento es exponer los principios básicos de funcionamiento de

esta nueva tecnología HTML conocida con el nombre de Web Components, que facilita el trabajo tanto a aquellos diseñadores web expertos, como a aquellas personas que han decidido crear y mantener su página web ellas mismas. Para ello, el punto principal del Proyecto de Fin de Grado será realizar un tutorial, que por un lado explique los fundamentos de Web Components, y que por otro lado muestre un ejemplo más elaborado que utilice esta tecnología a nivel de producción. A continuación aparecen listados los puntos principales a desarrollar:

Introducción ­ sitúa al lector en el contexto del desarrollo web a día de hoy Objetivos ­ da a conocer al lector los objetivos que se persiguen con este documento Descripción y características de los Web Components ­ describe los principios de

esta tecnología y de las cuatro especificaciones en las que se basa Tutorial Web Components ­ detalla ejemplos de uso de los Web Components, tanto a

nivel introductorio, como a nivel de producción Herramientas y librerías ­ lista de las principales herramientas y librerías utilizadas Desventajas ­ presenta las principales desventajas con las que cuenta esta tecnología Conclusión ­ da una visión global del trabajo realizado y del futuro de esta tecnología

8

Trabajo de Fin de Grado ­ ETSIT UPM

Descripción y características de los Web Components La manera en la que construimos páginas web hoy en día puede resultar muchas veces

ineficiente. Bien copiamos y pegamos trozos de HTML de librerías de CSS como Bootstrap, bien cargamos el código de nuestras páginas web con todo tipo de plugins y frameworks de JavaScript. Además, reutilizar componentes provenientes de diferentes frameworks en la misma página no es siempre posible. Muchas veces nuestras páginas acaban sobrecargadas de CSS, JavaScript o ambas.

Web Components es una colección de especificaciones que abre a los desarrolladores la posibilidad de crear aplicaciones web con un conjunto de componentes reciclables. Web Components constituye un cambio revolucionario que rompe con el enfoque de tradicional del desarrollo web, y lo hace a base de cambiar el concepto que tenemos sobre construir y crear aplicaciones web. Cada componente vive encapsulado en la propia unidad que lo define con su parte correspondiente de estilo CSS y lógica de comportamiento y funcionamiento. Estos componentes no solo pueden utilizarse repetidas veces por toda una aplicación web sino que también pueden distribuirse en la web para su uso por otros desarrolladores.

Web Components se componen de un conjunto de cuatro especificaciones diferentes:

Custom Elements ­ permiten a los desarrolladores crear sus propias etiquetas HTML personalizadas, utilizar esas etiquetas en sus páginas y aplicaciones web, y facilitar su reciclado y uso en otras aplicaciones.

HTML Templates ­ nos dan la posibilidad de definir fragmentos de marcado que mantienen su consistencia en las páginas y permiten inyectar contenido dinámico utilizando JavaScript.

Shadow DOM ­ diseñado para abstraer todas las complejidades del marcado definiendo barreras funcionales entre el árbol DOM y los subárboles escondidos tras la página raíz.

HTML Imports ­ similares a importar una hoja de estilos CSS dentro de otra, pero en este caso permiten incluir y reutilizar documentos HTML dentro de otros documentos HTML.

Cada una de estas especificaciones es útil de manera individual, pero cuando se utilizan conjuntamente ofrecen:

Componibilidad ­ ser capaz de crear páginas y aplicaciones web completas juntando diferentes elementos;

Encapsulado ­ ser capaz de aislar marcado, estilo y lógica de comportamiento y funcionamiento de forma que no interfieran en el resto de la página web;

9

Trabajo de Fin de Grado ­ ETSIT UPM

Reciclado ­ ser capaz de extender elementos existentes con el fin de crear nuevos elementos, dando la posibilidad de dejar de empezar cada vez de cero;

Esto significa que finalmente podemos cubrir cualquier aspecto de la plataforma de una manera eficiente. Esto también nos abre la posibilidad de un ecosistema menos fragmentado, donde los componentes puedan realmente interoperar entre sí sin dificultades.

--------------------------------- Custom Elements ---------------------------------

Hoy en día, en la web hay mucha falta de “expresividad”. Para entender a lo que esto se refiere, podríamos coger cualquier aplicación web moderna e inspeccionar la estructura de su código HTML. Lo que vamos a observar en cualquiera de ellas es un apilamiento sin fin de etiquetas <div>. Podríamos decir que no hay nada moderno en esta forma de construir aplicaciones web, ya que en la mayoría de los casos el código resulta prácticamente ilegible y difícil de seguir.

HTML nos ofrece una herramienta excelente para la estructuración de un documento, sin embargo, su vocabulario se encuentra limitado a los elementos estándar que define HTML. Pero, ¿cómo sería si la estructura de las aplicaciones tuviera sentido, fuera fácil de seguir y entender y lo más importante fácil de modificar y mantener?

Los Custom Elements permiten a los desarrolladores web definir nuevos tipos de elementos HTML. Esta especificación es una de las nuevas APIs que nacen dentro del mundo de los Web Components, y quizás sea la más importante, ya que los Web Components no podrían existir sin las funcionalidades que los Custom Elements ofrecen:

Definición de elementos HTML/DOM nuevos

Creación de elementos nuevos a partir de la extensión de otros elementos

Unión lógica de todas las funcionalidades de Custom Elements en una sola etiqueta

Extensión de la API de los elementos DOM ya existentes

Los Custom Elements se crean utilizando document.registerElement(), y es lo que enseña al navegador sobre la existencia del nuevo elemento y devuelve un constructor para crear instancias de <mi-componente>. El primer argumento de esta función es el nombre de la etiqueta del nuevo elemento y este siempre debe contener un guión, que es lo que permite al navegador distinguir los Custom Elements de los elementos HTML estándar y asegurar su futura compatibilidad. El segundo argumento es opcional y describe el prototipo del elemento. Por defecto, los Custom Elements heredan de HTMLElement y es en el prototipo donde se añade la funcionalidad que nosotros deseemos al elemento:

var MiComponente = document.registerElement(‘mi-componente’, prototype: Object.create(HTMLElement.prototype));

10

Trabajo de Fin de Grado ­ ETSIT UPM

document.body.appendChild(new MiComponente());

Custom Elements también ofrece la posibilidad de extender elementos HTML estándar

u otros Custom Elements. En este caso, para extender un elemento, es necesario facilitarle a la función registerElement()igual que antes, el nombre del nuevo elemento y el prototipo, que en este caso será el mismo que el del elemento al que extiende. Los Custom Elements que extienden elementos HTML estándar reciben el nombre de Type Extension Custom Elements y tienen una forma especial de utilizarse, igual que en el siguiente ejemplo:

<script> var MegaBoton = document.registerElement(‘mega-boton’, prototype: Object.create(HTMLButtonElement.prototype), extends: ‘button’); </script> <button is=“mega-boton”>¡Hola!</button>

Para extender otro Custom Element lo único que habría que cambiar a parte del nombre

del nuevo elemento sería HTMLButtonElementpor HTMLElement, ya que todos los Custom Elements que no extienden un elemento HTML estándar tienen este prototipo. Además, ‘button’ habría que sustituirlo por el nombre del elemento a extender, por ejemplo ‘mi-componente’.

Los Custom Elements se pueden instanciar de tres maneras, bien declarándolos, bien creando un DOM en JavaScript, bien utilizando el operador new seguido del nombre de la variable con la que lo registramos. En el caso de los Type Extension Custom Elements, se emplean las mismas tres maneras pero con ciertas modificaciones:

<mi-componente> … </mi-componente> // Ordinary Custom Element <button is=“mega-boton”> … </button> // Type Extension Custom Element

var miComponente = document.createElement(‘mi-componente’); // OCE var megaBoton = document.createElement(‘button’, ‘mega-boton’); // TECE

var miComponente = new MiComponente(); // OCE var megaBoton = new MegaBoton(); // TECE

Sin embargo, lo realmente interesante de los Custom Elements es poder añadirles

métodos y propiedades antes de registrarlos, y para ello hay distintas variantes, pero en este caso vamos a ver una variante más extendida y otra más compacta:

var ProtoMiComponente = Object.create(HTMLElement.prototype); ProtoMiComponente.info = function() alert(‘info() ejecutada’); ; Object.defineProperty(ProtoMiComponente, “version”, value: 5 );

11

Trabajo de Fin de Grado ­ ETSIT UPM

var MiComponente = document.registerElement(‘mi-componente’, prototype: ProtoMiComponente);

var MiComponente = document.registerElement(‘mi-componente’, prototype: Object.create(HTMLElement.prototype, version: get: function() return 5; , info: value: function() alert(‘info() ejecutada’); ));

Los Custom Elements también poseen unos métodos predefinidos especiales

mediante los cuales se puede acceder a momentos interesantes de su existencia, y es por eso que reciben el nombre de lifecycle callbacks o métodos de ciclo de vida. Todos estos métodos son opcionales pero hay veces que conviene definirlos. A continuación aparece una tabla resumen de estos métodos y sus características:

Nombre del método Se llama cuando...

createdCallback se crea una instancia del elemento

attachedCallback se inserta una instancia en el documento

detachedCallback se elimina una instancia del documento

attributeChangedCallback(attrName, oldVal, newVal)

se añade, se elimina o se actualiza un atributo

Una opción muy acertada es utilizar los Custom Elements en combinación con

Shadow DOM y los HTML Templates. Por una parte, Shadow DOM es muy útil porque nos permite esconder la complejidad que hay detrás de ese elemento y nos ofrece encapsulación y aislamiento del estilo de dicho elemento con respecto al resto de la página. Por otra parte, el elemento <template>nos permite declarar fragmentos de DOM, inertes al cargarse la página y que se pueden activar más tarde, fragmentos que nos ayudan a declarar la estructura del nuevo elemento. A continuación tenemos un ejemplo de cómo se haría:

<template id=“miplantilla”> <style> p color: red; </style> <p>Custom Element que utiliza Shadow DOM y &lt;template&gt;.</p> </template> <script> var MiComponenteProto = Object.create(HTMLElement.prototype, createdCallback: value: function() var t = document.querySelector(‘#miplantilla’); var c = document.importNode(t.content, true); this.createShadowRoot().appendChild(c); ); document.registerElement(‘mi-componente’, prototype: MiComponenteProto);

12

Trabajo de Fin de Grado ­ ETSIT UPM

</script>

En resumen, los Custom Elements nos proporcionan una herramienta con la que

extender el vocabulario HTML, sacarle el mayor partido y utilizarlo para suplir todas los defectos que pueda presentar la plataforma web actual. Además, utilizándolos conjuntamente con otros nuevos APIs de Web Components como Shadow DOM y HTML Templates podemos conseguir que la estructura de los elementos HTML se convierta en una mucho más legible y más fácil de mantener.

--------------------------------- HTML Templates ---------------------------------

El concepto de seguir una plantilla no es nuevo en el mundo del desarrollo web. De hecho, en el lado del servidor los lenguajes/máquinas que hacen posible el seguimiento de una plantilla como Django (Python), ERB/Haml (Ruby) o Smarty (PHP) se ha estado utilizando desde hace mucho tiempo. Sin embargo, en los últimos dos años hemos sido testigos de la explosión de frameworks que siguen el patrón MVC. Todos ellos son ligeramente distintos, aunque la mayoría comparten una mecánica de renderización común de su capa de presentación: los templates o plantillas.

Para convencernos de la utilidad de los templates, podríamos dirigir nuestra mirada a su definición:

“template ­ documento o archivo que presenta un formato predeterminado, y que se utiliza como punto de inicio para una determinada aplicación de manera que el formato no tenga que crearse desde cero cada vez que se vuelva a utilizar”

Incluso según esta definición, los templates nos ayudan a evitar trabajar en exceso, y por tanto nos ayudan a ahorrar tiempo, cosa que siempre viene bien, ya que se trata de un recurso muy escaso y valioso. Pero entonces, ¿por qué carece la plataforma web actual de soporte nativo para algo que a los desarrolladores les interesa tanto?

La solución a este problema es el la especificación de Web Components conocida con el nombre de HTML Templates. Esta define un nuevo elemento <template>que describe un enfoque basado en el estándar DOM para seguir una plantilla en el lado del cliente. Las plantillas nos permiten declarar fragmentos de marcado que son tratados como HTML y permanecen sin leer al cargarse la página, pero pueden ejecutarse más tarde.

El elemento HTML <template>representa una plantilla en nuestro marcado. Esta contiene trozos inertes de DOM que se pueden replicar. Podríamos pensar en las plantillas como en piezas de lego que se pueden usar una y otra vez a lo largo del desarrollo de una aplicación. Además, el hecho de envolver contenido con una etiqueta <template> le proporciona las siguientes propiedades:

13

Trabajo de Fin de Grado ­ ETSIT UPM

El contenido es efectivamente inerte hasta el momento de ser activado. Es decir, ese marcado es DOM escondido que no se renderiza.

Cualquier contenido dentro de una plantilla no desencadenará efectos colaterales, es decir, el script no se ejecuta, las imágenes no se cargan, el audio no se reproduce, etc… y no lo hace hasta que esa plantilla no se utiliza posteriormente.

El contenido se considera como si no existiera en el documento. Una prueba de ello, es que al utilizar document.getElementById() o querySelector() en la página principal, no devolverá los nodos hijos de una plantilla.

Las plantillas pueden colocarse en cualquier lugar dentro de las etiquetas <head>, <body>o <frameset> y pueden alojar en su interior cualquier tipo de contenido permitido en el interior de dichos elementos. Con cualquier lugar, nos referimos a que la etiqueta <template>se puede utilizar sin problema en sitios donde el analizador de HTML deshabilita todo excepto los hijos de modelo de contenido.

Para utilizar una plantilla, es necesario activarla, ya que tal como acabamos de decir su contenido es inerte, y en caso contrario este nunca se renderizará. La forma más simple de manipular, modificar y actualizar su contenido es creando primero una copia de su .content utilizando document.importNode(). Trás ello, el contenido modificado se clona y se renderiza, igual que en el ejemplo que sigue:

var p = document.querySelector(‘#miplantilla’); p.content.querySelector(‘img’).src = ‘icono.png’; var clone = document.importNode(p.content, true); document.body.appendChild(clone);

En otras ocasiones, muchos desarrolladores adjuntan Shadow DOM a un host

directamente modificando el marcado utilizando .innerHTML de la siguiente forma:

<div id=“host”></div> <script> var s = document.querySelector(‘#host’).createShadowRoot(); s.innerHTML = ‘<span>Nodo del host</span>’; </script>

Pero esta práctica tiene un problema, ya que cuanto más complejo se vuelva el Shadow

DOM, más concatenación de Strings hay que hacer, cosa que puede dar lugar a un código muy desordenado y expuesto a fallos. Es por eso que en este caso <template>vuelve a sernos útil ya que permite trabajar con el DOM directamente añadiendo el contenido de la plantilla a un shadow root:

14

Trabajo de Fin de Grado ­ ETSIT UPM

<template> … </template> <div id=“host”> … </div> <script> var s = document.querySelector(‘#host’).createShadowRoot(); s.appendChild(document.querySelector(‘template’).content); </script>

Pero no nos olvidemos de que el camino hasta llegar al elemento <template>que

acabamos de presentar fue uno muy largo. Para ello vamos a explicar dos de los métodos que más se utilizaban antes de su existencia para realizar las mismas funciones:

Un enfoque consistía en crear un DOM que se escondía utilizando el atributo hiddeno la regla CSS display:none. Aunque esta técnica funcionaba, tenía sus ventajas y desventajas; el hecho de utilizar DOM es muy conveniente, ya que se puede clonar fácilmente. Además, no se renderiza nada, ya que hiddenimpide que se muestre nada. Sin embargo, aunque no se muestre nada, el contenido no es inerte y por tanto se ejecuta. Además, tenía el típico problema de los estilos, donde si un ID de la plantilla coincidía con algún ID de la página se producía un solapamiento de las reglas de CSS para el mismo ID.

La otra técnica consistía en sobrecargar <script>y manipular su contenido como String. Nuevamente nada se renderiza, ya que <script>por defecto tiene display:

none. El contenido tampoco se ejecuta, es decir permanece inerte ya que nos encargamos de cambiar el tipo a algo distinto de “text/javascript”. No obstante, el problema más importante que muestra es que en cierta manera promociona el uso de .innerHTML que puede llevar a problemas de vulnerabilidades XSS.

Si volvemos atrás en el tiempo, al momento en el cual jQuery convirtió el trabajo conjunto con DOM en uno muy simple, el resultado fue la introducción a la plataforma web del querySelector()/querySelectorAll(). Una librería popularizó el funcionamiento conjunto de DOM con selectores de CSS y el estándar acabó adoptándolo algo más tarde.

En esta ocasión, se trata de un caso similar al anterior. Este estandariza la manera en la que seguimos una plantilla en el lado del cliente y hace del proceso de creación de páginas web un proceso más sano, más fácil de mantener y más rico en nuevas funcionalidades.

15

Trabajo de Fin de Grado ­ ETSIT UPM

----------------------------------- Shadow DOM -----------------------------------

Tal y como lo hemos dicho antes, Web Components es un conjunto de estándares HTML nuevos que permiten crear nuevos elementos HTML, elementos que se pueden reciclar y que no descolocan nada en la página si la siguiente versión del componente cambia los detalles internos de su implementación.

Sin embargo, ¿quiere decir esto que tenemos que decidir cuándo utilizar HTML/JavaScript y cuándo utilizar Web Components? La respuesta es clara: con HTML y JavaScript se pueden construir elementos visuales interactivos, y la mayoría de las veces eso es lo que los Web Components son; así que no.

Pero hay un problema fundamental que hace que los componentes construidos con la ayuda de HTML y JavaScript se vuelvan complicados de utilizar: el árbol DOM interno de un componente de este tipo no viene aislado del resto de la página. Esta falta de encapsulamiento puede dar lugar a que la hoja de estilos de la propia página web accidentalmente modifique partes del interior del componente debido a que los IDs de las diferentes etiquetas presentes en la página y en el componente acaben solapándose, por ejemplo.

En este caso Shadow DOM es la especificación de Web Components que se encarga de resolver este molesto problema. Con Shadow DOM, los elementos son capaces de tener asociados un nuevo tipo de nodos conocido con el nombre de shadow root (Shadow DOM). Un elemento que tiene asociado este tipo de nodos recibe el nombre de shadow host (Light DOM) y no es su contenido el que se renderiza sino el del shadow root. Un ejemplo de su uso sería:

<div id=“tagNombre”>Miguel</div> <template id=“tagPlantillaNombre”> <style> … </style> <div id=“saludo”>¡Hola! Mi nombre es</div> <div id=“nombre”>Miguel</div> </template> <script> var s = document.querySelector(‘#tagNombre’).createShadowRoot(); var t = document.querySelector(‘#tagPlantillaNombre’); var c = document.importNode(t.content, true); s.appendChild(c); </script>

Hasta el momento hemos conseguido esconder los detalles de presentación a la página

pero no separar presentación de contenido, porque aunque el contenido “¡Hola!Minombre

esMiguel” aparece en la página, este contenido es el del interior del root (Shadow DOM) y no del host (Light DOM). Por tanto si quisiéramos cambiar el nombre que se muestra tendríamos que modificar el contenido de <template>, cosa que no resulta ni dinámica ni natural. La

16

Trabajo de Fin de Grado ­ ETSIT UPM

solución a este problema es el uso de una composición entre el estilo aplicado, el saludo, que queremos que siempre permanezca igual y el nombre que es el que queremos poder modificar.

Para ello dentro de <template>en vez de poner directamente el nombre vamos a sustituir Miguelpor el marcador de posición o placeholder <content></content>. Esto crea un punto de inserción en la presentación mediante el cual el contenido que aparezca en tagNombresustituya el placeholder anterior y sea el que se muestre en la página. Y con esto hemos conseguido separar contenido, que se encuentra en el Light DOM, de la presentación, que se encuentra en el Shadow DOM, cosa que suele ayudar a simplificar el código que manipula el contenido.

Pero lo más normal es que haya más de un campo que queramos poder modificar dinámicamente y que por tanto tengamos que utilizar más de una etiqueta <content>dentro del código del shadow root (Shadow DOM). Pero para distinguirlos y asociarles a cada uno su contenido correspondiente tenemos que utilizar su atributo selectque acepta como valores selectores CSS pertenecientes a los “hijos” del shadow host (Light DOM). A continuación podemos ver un ejemplo:

<div id=“tagNombre”> <div class=“nom”>Miguel</div> <div class=“ape”> López</div> </div> <template id=“tagPlantillaNombre”> <div id=“saludo”>¡Hola! Mi nombre es</div> <div id=“nombre”> <div style=“color: red;”><content select=“.nom”></content></div> <div style=“color: blue;”><content select=“div”></content></div> <div style=“color: green;”><content select=“.ape”></content></div> </div> </template>

Hay que tener en cuenta que todo contenido que hay dentro de un shadow host (Light

DOM) no se mostrará a menos que tenga asociada una etiqueta <content>en el shadow root (Shadow DOM). En este caso elegimos dar diferentes colores a los distintos contenidos porque nos resulta más ilustrativo para la explicación, pero con tal contenido se podría hacer cualquier otra cosa. El resultado de dicho código en la pantalla sería “¡Hola!MinombreesMiguel

López”. Esto debería sorprendernos porque si miramos el código, al contenido correspondiente al apellido se le ha asociado el color verde, sin embargo aparece en azul.

Esto se debe a que en el mundo de renderización de Shadow DOM las diferentes reglas de CSS se ejecutan en orden, pero además si una etiqueta <content>hace referencia a varios contenidos porque su atributo select tiene como valor un selector CSS más generalizado, las reglas de CSS se van a aplicar a todos los contenidos que se vean afectados por dicho selector y que no se les haya aplicado todavía ninguna regla. La reglas CSS de un

17

Trabajo de Fin de Grado ­ ETSIT UPM

<content>posterior no se le podrán aplicar a un elemento del shadow host que ya haya coincidido con un selector anterior. Por ese motivo, si la línea cuyo select=“div”estuviera encima de las otras dos, tanto el nombre como el apellido aparecerían en azul. Si la misma línea fuera al final, el nombre aparecería en rojo y el apellido en verde.

Por tanto, para obtener el resultado deseado a la hora de renderizar dicho contenido en una página, hay que tener en cuenta el orden en el que manipulamos los <content>y los valores de su atributo select. Como en cualquier lenguaje de programación sería recomendable ir de lo más específico a lo más general, y utilizar select=“div”al final como regla por defecto para “todo lo demás”.

Otra de las ventajas que ofrece Shadow DOM es la encapsulación de estilos, ya que toda regla CSS presente dentro del código de un shadow root se aplica solo a los elementos de su interior y no al resto de la página. El aislamiento también se da en sentido contrario, es decir las reglas CSS de la página no afectan los elementos del interior del shadow root.

Si lo que queremos es modificar las reglas de CSS del elemento que es shadow host y/o de sus posibles elementos “hijos” desde el interior del shadow root, :host(selectorCSS) es el que nos lo permite en función de si dichos elementos se ven afectados o no por el selector CSS utilizado. Si en cambio, utilizamos :host-context(selectorCSS), las reglas CSS que escribamos se aplicarán dentro del elemento que hace de shadow host a todos los elementos que se vean afectados por el selector CSS empleado y automáticamente a sus elementos “hijos” también. A continuación tenemos un ejemplo de su uso, que hará que tanto el texto del botón como el texto de un elemento hijo de un <div> aparezcan en mayúsculas:

<button class=“ejem1”>Mi botón</button> <div class=“ejem2”><span>Mi texto</span></div> <script> var r1 = document.querySelector(‘.ejem1’).createShadowRoot(); var r2 = document.querySelector(‘.ejem2’).createShadowRoot(); r1.innerHTML = ‘<style>’ + ‘:host(‘.ejem1’) text-transform: uppercase; ’ + ‘</style>’ + ‘<content></content>’ ; r2.innerHTML = ‘<style>’ + ‘:host-context(‘.ejem2’) text-transform: uppercase; ’ + ‘</style>’ + ‘<content></content>’ ; </script>

Si por el contrario queremos poder modificar las reglas de CSS de un elemento que es

shadow host y/o de sus posibles “hijos”, pero esta vez desde fuera del shadow root, es decir desde la página, selectorCSS::shadowselectorCSSnos ayudará a conseguirlo. El selector del principio es el que identifica al elemento que hace de shadow host y el selector del final

18

Trabajo de Fin de Grado ­ ETSIT UPM

identifica a que elemento/s “hijo/s” afectará en concreto. A continuación tenemos un ejemplo de su uso, siendo el resultado “Sombra Luz”:

<style> #host::shadow span color: red; </style> <div id=“host”><span>Luz</span></div> <script> var r = document.querySelector(‘div’).createShadowRoot(); r.innerHTML = “<span>Sombra</span><content></content>”; </script>

Pero hay casos tales como el de los Custom Elements, donde ocurre que existen varios

niveles de Shadow DOM contenidos uno dentro de otro. Con la expresión que hemos visto antes solo conseguimos traspasar un único nivel Shadow DOM. Para traspasar más niveles, habría que concatenar otro ::shadowselectorCSSpor cada nivel, y cuando hay más de dos niveles, la expresión suele quedar demasiado larga y un poco difícil de manipular. Pero hay una solución adecuada para esos casos, y es el uso de selectorCSS/deep/selectorCSS. Este operador es mucho más potente, ya que permite ignorar por completo todas las barreras y atravesar cualquier número de niveles Shadow DOM con el fin de llegar al nodo deseado.

Una herramienta muy potente para la creación de temas es crear placeholders de estilo CSS. Para entenderlo vamos a considerar un Custom Element que utiliza placeholders para cambiar la fuente de un botón y otra para su color. A continuación se definen los valores de dichos placeholders de la manera deseada. A continuación aparece el código de lo descrito:

<style> #host --botton-text-color: green; --button-font: “Comic Sans MS”, “Comic Sans”, cursive; </style> <div id=“host”>Nodo del host</div> <script> var r = document.querySelector(‘#host’).createShadowRoot(); r.innerHTML = ‘<style>’ + ‘button color: var(--button-text-color);’ + ‘font-family: var(--button-font); ’ + ‘</style>’ + ‘<content></content>’; </script>

Los nodos distribuidos son elementos que se renderizan en un punto de inserción,

es decir donde en el shadow root aparece una etiqueta <content>. Como ya hemos visto, esta etiqueta nos permite seleccionar nodos del shadow host (Light DOM) y renderizarlos en lugares predefinidos del shadow root (Shadow DOM). Los nodos distribuidos no están presentes lógicamente dentro del Shadow DOM, sino que siguen siendo “hijos” del shadow host y por tanto heredan el estilo del documento principal.

19

Trabajo de Fin de Grado ­ ETSIT UPM

No obstante, si lo que queremos es aplicar reglas de CSS a los nodos distribuidos desde el interior de Shadow DOM el pseoudo elemento ::contentselectorCSSnos ayudará a conseguirlo, ya que es la manera de apuntar a nodos del Light DOM que pasan a través de un punto de inserción.

Otro aspecto importante de destacar es qué pasa si añadimos varios shadow roots al mismo shadow host. En ese caso el árbol DOM que se renderiza es el más joven, es decir el último que se le añade al shadow host. Esto podría hacernos pensar que no presenta ninguna utilidad, y así es excepto si lo utilizamos en combinación con puntos de inserción de shadow. Estos son similares a los que había para contenido, pero en este caso sirven para árboles DOM y tienen la forma <shadow></shadow>. A continuación podemos ver un ejemplo de su uso:

<div id=“ejemplo”>Light DOM</div> <script> var h = document.querySelector(‘#ejemplo’); var r1 = h.createShadowRoot(); var r2 = h.createShadowRoot(); r1.innerHTML = ‘<div>Root 1</div><content></content>’; r2.innerHTML = ‘<div>Root 2</div><shadow></shadow>’; </script>

En este caso lo que se mostrará como resultado de este código será: “Root2Root1

LightDOM”. El orden depende de donde situemos la etiqueta <shadow>y en este caso está invertido porque aparece detrás de <div>Root 2</div>. Lo que sustituye a la etiqueta <shadow>es el árbol DOM más antiguo. “Light DOM” aparece también al estar incluido en el primer shadow root mediante un <content>. Si hubiera múltiples puntos de inserción <shadow>en un mismo árbol DOM, solo el primero se tendría en cuenta y el resto se ignorarían.

Como conclusión, Shadow DOM es una herramienta muy potente que nos ofrece encapsulación de estilos específica y una manera de controlar en qué medida el estilo de la página influye en el estilo de los componentes que hay presentes dentro de ella. Definiendo Custom Pseudo Elements o incluyendo placeholders de variables CSS, los desarrolladores pueden manejar de una forma más dinámica el estilo del contenido de sus páginas y prepararlo para ser más fácil de modificar en caso de necesidad. Por tanto, Shadow DOM permite a los desarrolladores tener el control completo sobre la representación del contenido de su página.

20

Trabajo de Fin de Grado ­ ETSIT UPM

---------------------------------- HTML Imports ----------------------------------

Si nos paramos a pensar a las diferentes formas de cargar recursos en la red, para JavaScript tenemos <script src>, para CSS usamos normalmente <link

rel=“stylesheet”>, para imágenes, video y audio empleamos <img>, <video>y <audio>, respectivamente. Podríamos continuar, pero la idea es que la mayoría de contenidos de la red tienen una manera simple de cargarse, y HTML no es uno de ellos. Para HTML las opciones posibles son:

<iframe> ­ su contenido vive enteramente en un contexto diferente al de la página. Esto puede ser una ventaja, pero también puede dar lugar a nuevos desafíos como el de ajustar el envoltorio del contenido al tamaño de este, el de tener que acceder al contenido mediante JavaScript o el de darle un estilo, que suele resultar muy complicado.

AJAX ­ es necesario utilizar JavaScript para cargar el HTML a la página, cosa que no resulta muy cómoda de utilizar.

CrazyHacks ­ empleo de métodos como embebido en strings, escondido dentro de comentarios…

Visto lo anterior, el contenido más básico en la red, HTML, es el que mayor esfuerzo requiere para trabajar con él, sin embargo Web Components tiene la solución. HTML Imports, es la especificación de Web Components que permite incluir documentos HTML en otros documentos HTML. HTML Imports no viene con ningún tipo de limitaciones, en el sentido de que puede importar sin problema cualquier cosa que pueda contener un fichero .html, es decir HTML, CSS y JavaScript. A continuación podemos ver un ejemplo de su uso tanto para importar ficheros .html de forma local desde una ruta dentro del proyecto, como de forma no local, desde un URL o import location. En el segundo caso, para cargar contenido proveniente de otro dominio es necesario que el import location tenga el permiso CORS habilitado.

<head> <link rel=“import” href=“/ruta/al/fichero/a/importar/fichero.html”> <link rel=“import” href=“http://ejemplo.com/fichero.html”> </head>

Además, HTML Imports utiliza una característica muy importante que es aquella de

eliminar duplicados, es decir, si hay varios componentes que necesitan importar el mismo fichero .html, este se importará una sola vez. No obstante, esta característica sí que viene con una limitación, y es aquella de que cuando la ruta o import location no es idéntica no se sabe distinguir que en realidad se trata del mismo fichero a importar; en este caso dicho fichero se importa múltiples veces y causa problemas de funcionamiento de la página web.

21

Trabajo de Fin de Grado ­ ETSIT UPM

Los HTML Imports proporcionan una manera de empaquetar HTML, CSS y JavaScript en un único entregable. Puede ser de ayuda para crear un tema, librería o simplemente para partir una aplicación en segmentos. Si así lo deseamos, podemos incluso importar una aplicación entera de golpe a nuestra página web. Un ejemplo de ello podría ser Bootstrap, un framework compuesto de ficheros independientes, que requiere jQuery para sus plugins, y proporciona ejemplos de uso. Este framework permite a los desarrolladores utilizar solo aquellas partes que les interesa, por eso el uso de HTML Imports cobra mucho sentido en este caso. Con su ayuda se pasa de la necesidad de importar cada librería y CSS por separado a hacerlo todo mediante un único HTML Import como el que vimos antes.

Aún así, utilizar HTML Imports no nos hace todo el trabajo; solo nos importa el fichero que queremos usar pero para realmente usar su contenido tenemos que utilizar JavaScript. En este sentido, para acceder al contenido de un HTML Import tenemos que utilizar la propiedad .importdel elemento <link>. Con el uso de jQuery podemos incluso utilizar solo partes específicas del fichero importado. Vamos a verlo en el siguiente ejemplo y para ello vamos a considerar que el nombre del primer ficheros es mensajes.html:

<head> … </head> <body> <div class=“construccion”> <style> … </style> <h1>Atención</h1> <p>La página se encuentra en construcción</p> </div> <div class=“desactualizado”> … </div> </body>

<head> <link rel=“import” href=“mensajes.html”> </head> <body> <script> var link = document.querySelector(‘link[rel=“import”]’); var contenido = link.import; var const = content.querySelector(‘.construccion’); document.body.appendChild(cont.cloneNode(true)); </script> </body>

Para aclarar el funcionamiento de los HTML Imports vamos a entrar más en detalle

sobre el comportamiento del JavaScript presente en el documento importado:

El Script del documento importado se ejecuta en el contexto de la ventana que contiene el documento principal. Por tanto, las funciones definidas en el documento importado acaban siempre ejecutándose en la ventana principal y es por eso que no es necesario hacer nada para ello.

22

Trabajo de Fin de Grado ­ ETSIT UPM

Los HTML Imports no bloquean el parseo de la página principal, sin embargo, los scripts que hay en el interior de estos se procesan en orden.

Los HTML Imports también son una herramienta muy útil a la hora de cargar contenido reciclable en la web, y en concreto, Web Components creados utilizando la especificación de Custom Elements en combinación con Shadow DOM y HTML Template. Envolver el contenido del documento a importar en un <template>ayuda en este caso a que el script de su interior permanezca inerte hasta el momento de uso.

También nos podemos encontrar con casos en los cuales el Web Component que importemos a nuestra página sea extensión de otro Web Component, por lo que el primero importará a su vez el segundo con el fin de extenderlo. Lo que tenemos en este caso es un HTML Import dentro de otro y se conoce con el nombre de HTML­Subimport.

Los HTML Imports son una herramienta extremadamente útil pero como en el caso de cualquier tecnología web novedosa, es necesario entender completamente su funcionamiento y usarlos de manera sabia, por eso a continuación aparecen una serie de pautas a tener en cuenta a la hora de utilizarlos:

Concatenamiento de HTML Imports ­ La reducción del número de peticiones hechas a la red es siempre importante. Por eso, si es necesario importar muchos recursos, hay una forma de combinarlos en uno solo con ayuda de Vulcanize. Se trata de una herramienta de desarrollo de npm del equipo de Polymer que compacta recursivamente una serie de HTML Imports en un único fichero, y que es el que tendríamos que importar.

Uso de la caché del navegador ­ una cosa muy a tener en cuenta es que el funcionamiento y las características de la caché de los navegadores se ha ido mejorando mucho a lo largo de los últimos años y los HTML Imports y Subimports también hacen uso de sus ventajas.

Utilidad del contenido solo al añadirlo ­ los documentos importados a nuestra página empiezan a ser útiles solo cuando nosotros comenzamos a añadir a la página los trozos de su código que nos interesan; en caso contrario, tal como hemos visto, lo único que se ejecutará será el script de dicho documento, a menos que venga dentro de un <template>, caso en el cual el script se mantendría inerte hasta ser activado.

Optimización para carga asíncrona ­ los HTML Imports pueden bloquear la renderización de la página principal; al importar hojas de estilo, el navegador deja de renderizar la página durante un período de tiempo, y lo hace con el fin de minimizar el FOUC o tiempo en el cual el contenido de la página web se muestra con los estilos por defecto del navegador. En el caso de los HTML Imports ocurre también porque los documentos que importamos pueden contener a su vez hojas de estilos. Para un funcionamiento completamente asíncrono se puede utilizar el atributo async:

<link rel=“import” href=“/ruta/que/tarda/en/cargar/doc.html” async>

23

Trabajo de Fin de Grado ­ ETSIT UPM

La razón por la cual async no es un atributo por defecto dentro de los HTML Imports es porque requiere más trabajo por parte de los desarrolladores. La opción síncrona implica que a aquellos HTML Imports que contengan definiciones de Custom Elements se les garantiza la carga y actualización en orden. Hacerlo de manera asíncrona implicaría que los desarrolladores tuvieran que preocuparse de dichos tiempos para mantener el orden.

Por otra parte, los HTML Imports no bloquean el parseo de la página principal, es decir, los scripts del documento importado se procesan en orden pero sin bloquearla. Una ventaja de importar los documentos en el <head>de la página es que permite al analizador empezar a trabajar en el contenido lo antes posible. Aún así, es importante recordar que la presencia de scripts en la página principal puede producir el bloqueo de esta en el caso de que los documentos importados también tengan scripts que se estén ejecutando antes.

Una manera de reducir la probabilidad de bloqueo de la página es evitar emplear scripts en la página principal justo a continuación de los HTML Imports. Lo mejor es retrasar el uso de los scripts en el documento principal todo lo posible, y así lo más probable es que los scripts que pudiese haber en los documentos importados ya se hayan acabado de ejecutar. Otra variante que ayuda a reducir la cantidad de scripts en la página principal, es hacer que los documentos que vayamos a importar añadan ellos mismos el contenido que nos interesa a la página principal una vez importados, sin necesidad de que nosotros escribamos script alguno para ello.

Como conclusión, los HTML Imports permiten empaquetar HTML, CSS y JavaScript en un único recurso. Esta herramienta es extremadamente útil por sí sola, pero donde más fuerza y sentido cobra es en el mundo de los Web Components, ya que permite a los desarrolladores crear componentes reciclables y compartirlos en la web para que otras personas los puedan utilizar en su propia página web simplemente realizando un HTML Import.

24

Trabajo de Fin de Grado ­ ETSIT UPM

Tutorial/Curso Web Components Este es uno de los puntos más importantes de este documento y consiste en hacer un

tutorial mediante el cual exponer ante todo aquel que lo siga, los principios básicos de funcionamiento de Web Components, siempre acompañado de ejemplos que reflejen claramente lo expuesto. Para ello nos vamos a basar en el tutorial de Component Kitchen, ya que nos proporciona unos ejemplos muy ilustrativos y sencillos. A lo largo del tutorial, se intentará en la medida de lo posible, explicar muy detalladamente la manera de proceder, de forma que un nivel básico de conocimiento de las tecnologías empleadas (HTML, CSS y JavaScript) sea más que suficiente para seguir fácilmente este tutorial. No es necesario escribir a mano el código de los ejemplos expuestos a continuación ya que viene almacenado en un repositorio de GitHub en la dirección https://github.com/dori5/wcejsim.

------¿Cuáles son las características de un Web Component y cómo funciona? -------

En primer lugar, vamos a ver el aspecto básico de un Web Component. Para ello, abrimos un editor de texto, Sublime Text por ejemplo y escribimos el siguiente código. Guardamos el documento como .html y lo abrimos en un navegador de forma local. 1

Y este es el aspecto del código anterior:

1 cuadro.html

25

Trabajo de Fin de Grado ­ ETSIT UPM

Como podemos ver, en primer lugar tenemos un textarea convencional, perteneciente a

los 100 elementos HTML estándar de los que hablábamos en la introducción. Como la mayoría de estos elementos, tiene bastantes limitaciones, de forma que al escribir en su interior, el texto deja de verse al superar el tamaño del cuadro. En cambio, el segundo cuadro de texto modifica automáticamente su tamaño, de forma que el texto siempre pueda leerse completamente sin necesidad de utilizar scroll. En este caso se trata de un Web Component.

Fijándonos en la etiqueta <basic-autosize-textarea>vemos que se trata de una etiqueta HTML “personalizada”, definida por un nuevo Web Component. Igual que una etiqueta HTML convencional consta de una apertura <basic-autosize-textarea>y un cierre </basic-autosize-textarea>. La principal diferencia viene en el nombre de esta, que es siempre un nombre compuesto y más largo que de costumbre, con el fin de identificar de forma única a cada elemento “personalizado”, ya que se espera que el mundo de los Web Components sea uno mucho más extenso que el de los elementos HTML estándar. Además de esto, la inclusión de al menos un guión es un requisito ya que permite a los navegadores diferenciar entre elementos estándar y elementos “personalizados”.

Los usuarios de Internet hoy en día esperan cada vez más comodidades y facilidades para interactuar con las aplicaciones web, de manera que limitaciones como la mostrada anteriormente podrían decepcionarlos. Sin embargo, muchas veces, incluso para hacer que un cuadro de texto cambie automáticamente de tamaño puede requerir gran cantidad de CSS o JavaScript muy complejo. El problema es que cada desarrollador que quiera un cuadro de texto con estas características tendrá que pelearse con el código por su cuenta, lo que ralentiza el proceso de desarrollo. Este es el motivo por el cual Web Components es una solución ideal ya que permite a los desarrolladores crear nuevos elementos HTML y compartirlos en Internet de forma que otros desarrolladores puedan a su vez aprovecharlos, y así ahorrarles tiempo y esfuerzo.

26

Trabajo de Fin de Grado ­ ETSIT UPM

----------- ¿Con qué navegadores son compatibles los Web Components? ------------

La imagen a la izquierda nos

resume este aspecto mediante un esquema que indica cuáles de las especificaciones de Web Components funcionan en qué navegadores. El color verde representa un estado Estable, el amarillo indica En espera y por último el naranja está asociado con un estado de No implementado o Bajo Consideración.

Para comprobar la veracidad de esto podemos abrir el documento

.html descrito en el apartado anterior y observar su correcto funcionamiento en los siguientes 2

navegadores:

Google Chrome y Chrome para Android Mozilla Firefox Apple Safari y Mobile Safari Microsoft Internet Explorer, décima versión y superiores

Como ya se mencionó, Web Components se basa en un nuevo conjunto de estándares que todavía están en proceso de adoptarse a nivel global, sin embargo, comparado con el tiempo que llevaba cualquier cambio en el mundo de los elementos HTML estándar, en este caso se trata de un cambio mucho más rápido que apenas requiere cambios software en los navegadores.

Esto se debe principalmente a que Google ha desarrollado una librería de compatibilidad con el nombre de webcomponents.js que permite que la tecnología de Web Components funcione en cualquier navegador moderno tanto de PC como móvil. Mediante el término “moderno” se hace referencia a cualquier navegador con capacidad de actualizarse. De esta manera, uno de los requisitos para empezar a utilizar los Web Components en una página web es incluir en su cabecera la librería de compatibilidad webcomponents.js.

2 cuadro.html

27

Trabajo de Fin de Grado ­ ETSIT UPM

------------ ¿Cómo importar los Web Components que se desea utilizar? ------------

Vamos a verlo nuevamente en este código , muy similar al anterior pero esta vez 3

mostrando un Web Component diferente, en este caso el calendario del mes actual:

Como sabemos, en primer lugar es necesario importar la librería de compatibilidad webcomponents.js. A continuación tenemos que dar a conocer al navegador el Web Component que deseamos utilizar, que la mayoría de las veces consiste en un documento .html independiente. Lo más adecuado es tener tanto la librería webcomponents.js como el documento en el que se define el Web Component alojados en el mismo servidor que la página web en sí o alternativamente en un otro servidor con permiso de CORS habilitado. Por eso, en este caso utilizamos los recursos directamente desde sus repositorios de GitHub ya que facilitan nuestra tarea por el momento. De lo contrario para poder ver el funcionamiento de los Web Components deberíamos crear un proyecto con nodejs, desplegarlo y almacenar los documentos de los Web Components que se vayan a utilizar en el mismo servidor, ya que no se pueden importar los recursos necesarios de forma local debido a problemas de Cross­Origin Resource Sharing.

Por tanto, una vez que tenemos clara la localización del documento del Web Component lo único que nos queda es importarlo al código de la página, bien mediante el path en caso de encontrarse en el mismo servidor, bien mediante la ruta de Internet si se encuentra alojado en otro servidor como por ejemplo en nuestro caso. Para importar el documento se utiliza la etiqueta HTML estándar <link>que hasta ahora se utilizaba para importar hojas de estilo CSS entre otras cosas, pero actualmente también puede utilizarse para importar HTML, que es nuestro caso. La importación tanto de librerías como de Web Components se debe hacer en la cabecera de la página HTML, y a continuación se hará uso de los elementos importados dentro del cuerpo de la página.

Por último, a continuación podemos ver el aspecto del código anterior completo en un navegador:

3 calendario.html

28

Trabajo de Fin de Grado ­ ETSIT UPM

------------- ¿Cómo poblar un Web Component con elementos “hijos”? --------------

Como bien sabemos, gran parte de los elementos HTML estándar como <div>o <p> (“padres”) ofrecen la posibilidad de añadir elementos “hijos” entre su etiqueta de apertura y cierre, que es lo que permite la construcción de una página web compleja y atractiva. Como siempre, hay elementos que no aceptan “hijos” y en el caso de aquellos que los aceptan, aquello que hace el “padre” con sus elementos “hijos” y los tipos de estos que acepta depende de cada elemento “padre” en parte.

Este este caso tenemos el código de una página web que contiene dos tipos de galería de fotografías: una para pasar las fotos de forma manual <basic-carousel>y otra que las pasa automáticamente cada cierto tiempo <basic-slideshow>. Además, cada uno de estos Web Components aceptan como elementos “hijos” las imágenes que van pasando y a su vez son elementos “hijos” de <basic-framed-content>, otro Web Component que lo que hace es limitar el tamaño de las galerías a su tamaño para evitar de esa manera interferencias con otros componentes de la página.

29

Trabajo de Fin de Grado ­ ETSIT UPM

Para saber cuáles son las características y comportamiento de un Web Component o las opciones que ofrece siempre se debe consultar la documentación, bien la que viene publicada en el catálogo en el que aparece, bien en el repositorio donde se encuentra alojado, bien en el mismo documento .html en el que se define dicho Web Component.

En la imagen a continuación podemos ver el aspecto del código anterior completo en 4

un navegador:

--------------- ¿Cómo se pueden personalizar los Web Components? ----------------

De la misma manera que con los elementos HTML estándar, la forma de personalizar o configurar el comportamiento de un Web Component es proporcionándole valores a los atributos que este soporta dentro de la apertura de la etiqueta de la forma

4 galeria.html

30

Trabajo de Fin de Grado ­ ETSIT UPM

atributo=”valor/es”. Los atributos concretos que soporta cada Web Component dependen de cada uno, por eso lo más recomendable es leer su documentación o buscar ejemplos de su uso para entender con mayor profundidad su funcionamiento. Puede que haya veces que busquemos y encontremos un Web Component que tendrá un determinado comportamiento por defecto y que no se adecúe completamente a lo que queremos, pero que mediante la configuración de sus atributos se solucione nuestro problema.

Todo lo expuesto anteriormente quedará ilustrado mediante un ejemplo muy parecido al anterior, donde lo que vamos a hacer es dar diferentes valores al atributo effectde la galería de fotografías manual <basic-carousel>con el fin de variar el efecto mediante el cual se hace el cambio de imagen. A continuación se puede ver la parte del código que difiere con 5

respecto al apartado anterior:

Para notar la diferencia hay que abrir el documento .html en un navegador e interactuar con las galerías:

5 galeria1.html

31

Trabajo de Fin de Grado ­ ETSIT UPM

------ ¿Es compatible combinar Web Components de diferentes fuentes/tipos? ------

Una de las mejores cosas de Web Components es que nadie debe ponerse de acuerdo en el funcionamiento de los nuevos componentes que se crean, sino que simplemente creándose siguiendo los estándares de esta nueva tecnología HTML e importando todos los recursos que comparten de la misma fuente, el uso conjunto de cualquiera de ellos es perfectamente compatible. De esta manera nos evitamos los típicos problemas de interoperabilidad entre componentes que se daban hasta ahora al intentar hacer trabajar conjuntamente distintos recursos.

Para comprobar la veracidad de lo dicho anteriormente vamos a incluir como “hijos” de un <basic-carousel>una serie de calendarios de tipo <basic-calendar-month>que son el Web Component ya visto en uno de los apartados anteriores. Cualquiera pensaría que una galería solo sirve para imágenes pero en este caso vemos cómo combinando ambos componentes podemos obtener un calendario perfectamente funcional como aquellos con los que estamos acostumbrados.

A continuación aparecen las partes más importantes del código necesario para obtener 6

el calendario del que hablábamos antes. Como sabemos, como siempre, en primer lugar se necesita importar la librería de compatibilidad webcomponents.js y los Web Components que vamos a utilizar a continuación en el cuerpo del documento .html. Además, se puede ver que tenemos un botón que muestra u oculta el calendario basándose en la propiedad style.display=“none/block”. Podría pensarse que es su única funcionalidad, sin embargo, es necesario para poder pasar al primer calendario y al último (anterior y siguiente al mes actual) el valor del atributo date, que debe ser de tipo Date. Como se trata de un atributo con valor diferente de un String, este no se puede pasar directamente en la etiqueta <basic-calendar-month>sino que debe hacerse a continuación mediante una función de JavaScript, función que se llama al pulsar el botón del que hablábamos anteriormente:

6 galería2.html

32

Trabajo de Fin de Grado ­ ETSIT UPM

----------- ¿Cómo conectar entre sí Web Components sin escribir código? -----------

En prácticamente cualquier interfaz de usuario, es muy común que la interacción del usuario con un elemento de la página afecte a otra cosa de la misma página. Como ejemplo, podríamos imaginar un botón que al ser pulsado expande o contrae una sección de la página. Frecuentemente, el establecimiento de una conexión como esta requiere gran cantidad de JavaScript detrás. Sin embargo, los Web Components ofrecen la posibilidad de establecer este tipo de conexiones, o al menos parte de ellas utilizando únicamente el lenguaje HTML.

Esto se puede llevar a cabo mediante un nuevo elemento HTML llamado <template>. Por sí solo, este elemento puede ser muy útil para los programadores de JavaScript, pero Google le ha asociado otra funcionalidad conocida con el nombre de “auto-binding”que también permite su uso por parte de los programadores de HTML. En resumen, el elemento <template>permite establecer conexiones entre los elementos HTML utilizados entre sus

33

Trabajo de Fin de Grado ­ ETSIT UPM

etiquetas de apertura y cierre, es decir, permite que el valor de un elemento modifique y actualice automáticamente otro elemento.

A continuación podemos ver las partes más importantes del código que implementa 7

este ejemplo. Dentro de las etiquetas de apertura y cierre de <template>, lo que permite el conexionado de los elementos que hay en su interior son los placeholders o marcadores de posición y como podemos ver en el código se representan mediante nombrePlaceholder.

En este caso, tenemos que importar la librería polymer.js por nuestra cuenta, al no utilizar ningún Web Component en la página que ya lo haga. Esta librería es la que permite dotar a <template>de la funcionalidad explicada anteriormente. Como ya se ha dicho, no es necesario utilizar JavaScript para aquellos elementos HTML que se pueden modificar dando a sus atributos valores de tipo String, sin embargo para aquellos atributos que precisan valores de otros tipos, sigue siendo necesario el uso de JavaScript.

En este ejemplo vamos cómo establecer una conexión entre componentes del primer tipo. En este caso estamos haciendo que el texto que escribamos en el interior de un campo de texto se muestre automáticamente como contenido de otros componentes, un <p>y un <button>. Además tendremos otro campo de tipo “color”que nos permitirá elegir el color del texto del botón:

7 template.html

34

Trabajo de Fin de Grado ­ ETSIT UPM

-------------------- ¿Cómo crear mis propios Web Components? --------------------

Para este apartado, para la creación de un nuevo Web Component vamos a optar por el uso de la librería de Google llamada polymer.js. Por eso, al igual que en el apartado anterior, uno de los primeros “import” que tenemos que hacer es el de esta librería.

Como siempre, Web Components presenta la ventaja de que los componentes creados por otras personas y publicados en Internet pueden ser reutilizados por cualquier desarrollador, sin embargo, detrás de esos componentes tan sencillos de utilizar, suele haber gran cantidad de código JavaScript que alguien ha tenido que programar. A pesar de todo, esto no debería ser una desmotivación, ya que siguen habiendo muchas posibilidades de crear Web Components básicos pero muy interesantes apenas utilizando JavaScript.

En este sentido, este tutorial no tiene como prioridad aprender JavaScript muy complejo, por eso este apartado se dedica a explicar los requisitos mínimos para crear un Web Component nuevo y sencillo. Para ello vamos a utilizar la sintaxis de la versión de Polymer 0.5, ya que la nueva versión Polymer 1.0 es una versión muy reciente y la mayoría de los Web Components que aparecen en los catálogos a día de hoy utilizan Polymer 0.5.

En este ejemplo vamos a crear un Web Component nuevo llamado <my-component>, que incluirá un <template>, de forma que cada vez que que alguien utilice este nuevo componente, todo lo que va entre las etiquetas de apertura y cierre de <template>se repetirá. Para este Web Component, el <template>incluirá un trozo de texto por defecto que siempre será el mismo y por otra un elemento <content>, que es un nuevo elemento HTML y a su vez otro tipo de placeholder o marcador de posición que se puede utilizar en el <template>de un Web Component, como el que vimos en el apartado anterior. De esa manera, cuando alguien utilice el nuevo Web Component que hemos creado, todo aquello que vaya entre sus etiquetas de apertura y cierre, sea texto u otro/s componente/s, se empleará allí donde el placeholder <content> aparezca en la definición del componente.

Aquí tenemos las partes más importantes del código para mostrar todo lo explicado: 8

8 nuevo.html

35

Trabajo de Fin de Grado ­ ETSIT UPM

Y a continuación una captura de pantalla de su aspecto al abrirlo en un navegador:

------- ¿Cómo evitar conflictos de CSS a la hora de utilizar Web Components? -------

Uno de los mejores aspectos de los Web Components es que emplean una nueva funcionalidad HTML que se conoce con el nombre de Shadow DOM. Se caracteriza por crear una barrera de “sombra” invisible que envuelve cada Web Component por separado, evitando de esa forma que las reglas de CSS del interior del componente afecten al estilo de la página y viceversa. En resumen, Shadow DOM previene que se produzcan interferencias entre el estilo de la página en sí y los estilos de los diferentes Web Components que se utilizan en su interior.

Hasta ahora, uno de los mayores problemas de mezclar widgets HTML de distintas fuentes en una misma página web eran los conflictos de hojas de estilo CSS. Para evitar estos problemas, como ya hemos dicho, cada Web Component está rodeado por una barrera invisible que permite mantener tanto el aspecto de la página como el de los componentes tal y como deberían estar.

Para hacer este ejemplo vamos a crear un nuevo Web Component, igual que lo hemos hecho en el apartado anterior. Este Web Component será muy similar pero con más especificaciones en cuanto al estilo. Tanto dentro del Web Component que hemos creado como en el resto de la página aparecerá la etiqueta <strong>. Dentro del Web Component haremos ciertas especificaciones de estilo para esa etiqueta y para el estilo de la página haremos otras especificaciones distintas de la misma etiqueta. Aún así, incluso utilizando la directiva !important ambas especificaciones de estilo no interferirán:

36

Trabajo de Fin de Grado ­ ETSIT UPM

A continuación podemos ver las partes más importantes del código que implementa lo 9

explicado:

Sin embargo, tal como vimos en un apartado anterior, esta funcionalidad no está implementada en todos los navegadores, de forma que si abrimos el mismo código en Internet Explorer o Safari veremos que el estilo de la página interferirá en mayor o menor medida con el de los componentes (en este caso se aplica la regla de las mayúsculas):

9 sombra.html

37

Trabajo de Fin de Grado ­ ETSIT UPM

La manera de evitar que eso pase, sería modificando las reglas de CSS de la página de forma que se centren en una clase, “warning” por ejemplo, strong.warning..., y luego en el HTML de la página usar el correspondiente <strongclass=”warning”>. Eso ayudará a asegurarse de que dicho CSS afecta solo a las etiquetas <strong>que hay en la página y no las de los Web Components empleados. Esta solución no es la más adecuada, ya que diferentes elementos podrían intentar utilizar el mismo nombre de clase para el CSS, dando lugar nuevamente a conflictos de estilo. Sin embargo, esta es la mejor solución que puede adoptarse hasta que la nueva funcionalidad Shadow DOM sea soportada por todos los navegadores.

---------- ¿Se pueden sobrescribir las reglas CSS de los Web Component? -----------

Estamos ante la siguiente pregunta: ¿qué pasa si lo que queremos es sobreescribir el estilo del interior de un componente? Puede que haya veces que encontremos un Web Component que haga justo lo que nosotros deseábamos pero que no se integre bien en el diseño de nuestra página web debido a su estilo y por eso queramos modificarlo. En teoría, según los visto en el apartado anterior, la funcionalidad HTML Shadow DOM nos lo debería impedir. Sin embargo, esta funcionalidad más que hacer eso, trata de prevenir que se de una modificación accidental, no de impedir una modificación intencionada.

Para ello, lo único que hay que hacer es un pequeño paso extra. En una regla de CSS tal como button background: gray; se llama selector de CSS a la parte correspondiente a button. Este se encarga de indicarle al navegador aquello a lo que se quiere aplicar dicho estilo. Dado que los elementos del interior de un Web Component vienen protegidos por el Shadow DOM, para modificar la apariencia de los elementos contenidos por un Web Component, es necesario utilizar un selector de CSS de tipo ::shadow.

El selector ::shadow(muy importante el par de :), indica al navegador que dicha regla de CSS puede traspasar la barrera invisible de Shadow DOM que rodea al Web Component. Pero esta regla traspasará una única barrera, de manera que si estamos ante un Web Component que contiene en su interior otro Web Component, el estilo de este último no se verá afectado.

Para este ejemplo vamos a utilizar el <basic-carousel>ya visto en un ejemplo anterior. Como vimos, este tipo de galería permitía pasar los elementos de su interior manualmente accionando los dos botones a los lados. En este caso, lo que queremos es modificar el estilo de dichos botones que vienen en el interior del Web Component. Para ello el selector de CSS que vamos a emplear será basic-carousel::shadowbuttontal y como podemos observar en los trozos de código que vienen a continuación: 10

10 estilo.html

38

Trabajo de Fin de Grado ­ ETSIT UPM

Y este es el aspecto que adquirirá el Web Component cuyo estilo acabamos de modificar, de forma que los botones dejan de ser blancos con flecha gris y pasan a ser grises con flecha blanca tal y como se lo hemos indicado en el selector mencionado anteriormente:

-------- Cosas interesantes que se pueden hacer con componentes invisibles ---------

No todos los Web Components tienen por qué mostrar algo en la pantalla del navegador, algunos simplemente sirven para guardar o cargar información en cookies del navegador, en el dispositivo que utiliza el usuario para navegar o en una base de datos de un servidor. Este tipo de componentes nos ayuda a extender la funcionalidad que puede alcanzar una página sólo mediante lenguaje HTML.

Para este ejemplo volvemos a emplear el componente ya visto en varias ocasiones, <basic-calendar-month>. Por otra parte, el componente que realmente nos interesa en este momento es el <basic-culture-selector>, un componente capaz de cargar el idioma y

39

Trabajo de Fin de Grado ­ ETSIT UPM

otras preferencias culturales de más de 300 idiomas/lugares de una base de datos abierta. Este segundo Web Component servirá para indicar al calendario en qué idioma mostrarse ante el usuario.

En este caso, el <basic-culture-selector> se puede utilizar de dos maneras distintas, bien ocultándose, y dándole un valor predeterminado que siempre se mantendrá el mismo, en este caso inglés, bien mostrándose ante el usuario y que este pueda hacer su propia elección. Para realizar la conexión entre el calendario y el selector de idioma utilizamos la funcionalidad “auto-binding”del componente <template>, igual que lo vimos hace unos apartados. Este es el aspecto de ambas variantes:

A continuación podemos también observar el código . En este caso, ambas variantes 11

son muy parecidas pero quitando en la línea 27 el style=”display:none”o sustituyéndolo por style=”display: block”:

11 invisible.html

40

Trabajo de Fin de Grado ­ ETSIT UPM

------------ ¿Cómo utilizar los Web Components a nivel de producción? -------------

Ejemplo práctico de una página web construida con la ayuda de Web Components

Todos los ejemplos de uso de los Web Components que hemos visto hasta ahora son ejemplos aislados, que solo sirven para aprender los fundamentos de funcionamiento y uso de esta nueva tecnología HTML. Pero ¿qué pasa si lo que queremos es utilizar Web Components en un proyecto real que vayamos a desplegar en Internet? Es verdad que si copiamos en nuestro proyecto el mismo código de los apartados anteriores, este funcionará perfectamente; eso se debe solo gracias a que los Web Components empleados disponen de una demo en la web de forma que todos los ficheros necesarios para su funcionamiento ya vienen almacenados en un dominio con permiso CORS habilitado, y es por eso que podemos importarlos directamente en nuestro proyecto, listos para ser usados.

Sin embargo, a la hora de utilizar Web Components a nivel de producción, tendríamos que crear un nuevo proyecto e instalar y almacenar en el mismo proyecto todos los Web Components y las librerías que vayamos a necesitar. En este caso vamos a emplear nodejs.

Instalación de nodejs y npm en distribuciones de Linux basadas en Ubuntu

Para instalar nodejs y npm vamos a basarnos en un sistema operativo Linux basado en Ubuntu. Puede que dependiendo de la versión de Linux se requiera un proceso de instalación ligeramente diferente; este método de instalación no es el oficialmente recomendado pero es mucho más rápido.

Empezamos instalando un programa que proporciona una abstracción de los repositorios de apt que usa y permite gestionar fácilmente su distribución y las fuentes de programas de proveedores independientes. En segundo lugar accedemos a un Personal Package Archives (PPA) que nos permite instalar la versión más reciente de nodejs para Ubuntu. Por último actualizamos los repositorios, es decir actualizamos la lista de todos los paquetes, con la dirección de dónde obtenerlos para que a la hora de hacer la búsqueda y su posterior descarga, sea más rápida.

apt-get install python-software-properties apt-add-repository ppa:chris-lea/node.js apt-get update

Y a continuación instalamos nodejs y npm:

apt-get install nodejs apt-get install npm

41

Trabajo de Fin de Grado ­ ETSIT UPM

Instalación de los módulos Express y Bower

Para seguir necesitamos instalar de forma global en nuestro sistema operativo los módulos de Express y Bower:

npm install -g express-generator npm install -g bower

Creación del proyecto y la aplicación con Express

Vamos a considerar que queremos crear nuestro proyecto en un directorio llamado twc y que para las vistas de nuestra página vamos a emplear ejs. Tras crear los ficheros iniciales de nuestro proyecto, nos movemos al directorio twc e instalamos las dependencias declaradas en package.json:

express --ejs twc cd twc npm install

Por último, podemos ejecutar la aplicación mediante un comando definido en package.json y a continuación abrir el navegador en la dirección http://localhost:3000 para ver su aspecto:

npm start

Instalación estándar de un Web Component mediante Bower

A la hora de instalar un nuevo Web Component con el propósito de utilizarlo en el diseño de nuestra página web, lo más recomendable es utilizar las instrucciones que se proporcionan en el fichero ReadMe del Web Component, si las hay; de lo contrario, el procedimiento de instalación estándar suele ser el que vamos a detallar a continuación. En cualquier caso, para su instalación es necesario el uso de módulo de npm llamado Bower que ya hemos instalado previamente.

Mediante el siguiente comando estamos instalando el componente en nuestro servidor, junto con las dependencias necesarias para su funcionamiento:

bower install --save web-component-name=author/web-component-name#master

Si este es el primer Web Component que estamos añadiendo a nuestro proyecto

42

Trabajo de Fin de Grado ­ ETSIT UPM

mediante Bower, recibiremos una queja de que no hay ningún fichero manifest bower.json para guardar las dependencias. Lo solucionamos ejecutando el siguiente comando que solo será necesario ejecutar esta vez por ser el primer Web Component que añadimos:

bower init

Al ejecutarlo nos harán una serie de preguntas. Llamaremos al archivo bower.json. Ignoramos las demás preguntas pulsando “Intro”. En cuanto al tipo de módulos que expone este paquete, elegimos node y continuamos dando “Intro” al resto de preguntas igual que antes. Por último, se nos preguntará si estamos de acuerdo con el contenido del archivo bower.json a lo que volveremos a aceptar.

Uso del Web Component instalado en la página

A continuación, si queremos utilizar el Web Component que acabamos de añadir a nuestro proyecto en nuestra página web, tendremos que importarlo de manera similar a como lo hacíamos en los ejemplos de antes. No obstante, antes tenemos que resolver un problema. Al añadir el Web Component, Bower almacena los archivos en una ruta por defecto, que en nuestro caso se corresponde con ~/twc/bower_components. Sin embargo, nosotros solo podemos importar a nuestra página web ficheros almacenados en el directorio de ficheros estáticos, que por defecto es ~/twc/public, estando ahí nuestro problema. La solución a este problema es cambiar el directorio de almacenamiento de Web Components dentro del directorio de ficheros estáticos.

Para ello nos situamos en el directorio raíz de nuestro proyecto. Creamos un nuevo fichero llamado bower.bowerrc. A continuación lo abrimos con nano y escribimos el siguiente texto en su interior, guardamos y cerramos. Volvemos a instalar las dependencias de Bower para que el cambio de directorio tenga efecto y por último, borramos el directorio bower_components antiguo.

cd twc touch bower.bowerrc nano bower.bowerrc

"directory": "~/twc/public/bower_components"

(Ctrl+O > Intro > Ctrl+X)

bower install

43

Trabajo de Fin de Grado ­ ETSIT UPM

rm -r ~/twc/bower_components

Pero antes de importar el Web Component a nuestra página web, tenemos que importar

la librería de compatibilidad de Google webcomponents.js, y por eso, previo a ello tenemos que instalarla:

bower install --save webcomponentsjs

Al instalar esta librería o cualquier otra, si hay varios Web Component que la utilizan, es muy probable que aparezcan conflictos de versiones. Para solucionarlo, normalmente nos quedaremos con la versión más reciente. Además, a la base de la mayoría de Web Components está Polymer, así que con cada componente nuevo que instalemos en nuestro proyecto es probable que surja una conflicto en cuanto a la versión de Polymer a instalar. Elegir la versión más reciente está bien cuando las versiones no difieren completamente (el primer número es el mismo 0.1.2). En el caso de Polymer existe la versión 0.5 y la 1.0, que es la más reciente. Se debe evitar en la medida de lo posible mezclar en el mismo proyecto elementos que utilicen la versión 0.5 de Polymer con otros que utilicen la 1.0, ya que nos tendremos que decidir por una de ellas, y al no ser compatibles, los elementos que utilizan la otra versión no funcionarán correctamente. Si antes de elegir la opción ponemos un “!” entonces se añadirá una resolución dentro del fichero de dependencias bower.json que establecerá esa versión como versión por defecto.

44

Trabajo de Fin de Grado ­ ETSIT UPM

Ahora por fin, podemos abrir el fichero de la vista principal de nuestra página web y

empezar a modificarlo. Este se encuentra en la ruta ~/twc/views/index.ejs. Una vez abierto, lo primero que tenemos que hacer es importar la librería de compatibilidad webcomponents.js dentro del <head>de la página. A continuación debemos importar también en <head>los Web Components que vayamos a utilizar finalmente en el <body>.

<!DOCTYPE html> <html> <head> <title>TWC</title> <script src="../bower_components/webcomponentsjs/webcomponents.js"></script> <link rel="import" href="../bower_components/web-component-name/web-component-name.html"> <link rel='stylesheet' href='stylesheets/style.css'> </head> <body> <h1>Tutorial Web Components</h1> <web-component-name></web-component-name> </body> </html>

Desarrollo de la página web

Todo lo explicado con anterioridad, son los pasos seguidos a la hora de crear y preparar mi proyecto para el desarrollo de una página web empleando Web Components. Se trata de una página web que refleja tanto el uso de Web Components creados por terceros y disponibles en Internet para ser aprovechados por cualquiera, como el uso de Web Components de creación y uso propios. Estos últimos se han obtenido siguiendo las pautas para la creación de un Web Component con ayuda de Polymer tal como se describe en el siguiente punto de este trabajo. Todos estos componentes se han almacenado en ~/twc/public/elements, un nuevo directorio dentro del directorio de ficheros estáticos para poder importarse posteriormente en las distintas vistas de la página web, pero separados de los Web Components de terceros para encontrarlos más fácilmente.

El objetivo de los Web Components creados para este proyecto consiste bien en ocultar la complejidad o gran extensión del código que da “cuerpo y vida” al mismo Web Component, bien para sustituir los elementos comunes a varias vistas por un código mucho más simple y compacto. Con estos componentes propios, se ha conseguido por una parte aligerar el código de las vistas y hacerlo más comprensible y por otra evitar repetir el mismo código extenso dentro de varias vistas.

45

Trabajo de Fin de Grado ­ ETSIT UPM

El objetivo de esta página web no es conseguir realizar tareas muy avanzadas ni tampoco emplear funciones de JavaScript muy complejas. Se trata de una página web de una complejidad media pero que a la vez ilustre de forma bastante completa de cómo utilizar Web Components creados por terceros o cómo crear unos propios, bien empezando de cero, bien empleando para ello otros Web Components ya existentes.

La página consiste en un buscador de series y películas que proporciona datos relevantes sobre estas y que para ello se basa en información proveniente de dos API gratuitas de Internet, una para series (http://www.tvmaze.com/api) y otra para películas (http://www.omdbapi.com/). Estas APIs tienen diferentes endpoints para la petición de distinta información y devuelven como resultado un JSON que contiene los datos. El controller de la aplicación recoge el JSON correspondiente en cada caso y lo pasa como parámetro a las diferentes vistas de la página web para que se pueda hacer uso de la información contenida en su interior (texto, enlaces a imágenes, arrays de datos, etc...).

El diseño que se ha adoptado para la estructura de esta página depende en gran parte de la forma de funcionar y la estructuración de la información ofrecida por las APIs en sus distintos endpoints, pero también se persigue mostrar el uso un mayor número de Web Components diferentes. La página consta de un total de 4 vistas: la página de inicio, que es donde se introducen los parámetros de búsqueda bien para series, bien para películas; una página listado/detalle de los resultados coincidentes con la búsqueda para las series; una página de listado de los resultados coincidentes con la búsqueda para las películas y por último una página de detalles de una película concreta que se elija entre las que aparecían en el listado resultante de la búsqueda.

En el repositorio de GitHub del proyecto expuesto hasta ahora se puede ver más claramente la estructura de directorios adoptada y el código de las distintos componentes y vistas (https://github.com/dori5/tfg­web­comps). El proyecto también se encuentra desplegado en Heroku para poder comprobar el aspecto de la página y las distintas funcionalidades y Web Components integrados en esta (https://tfgwebcomps.herokuapp.com/).

------------ ¿Como crear Web Components y compartirlos en Internet? -------------

En un apartado anterior hemos visto un ejemplo muy simple de cómo crear un nuevo Web Component y utilizarlo localmente y lo hemos hecho así, porque como ya se ha dicho, con este tutorial no se trata de aprender JavaScript complejo. Sin embargo, dado que este documento también está dirigido a los desarrolladores web, sería conveniente exponer los principios básicos de creación de un Web Component a nivel de producción y de compartición del mismo en la Web.

Para la creación de un nuevo Web Component vamos a considerar el mismo proyecto que hemos creado en el apartado anterior. Los Web Components nuevos se pueden crear de manera “tradicional”, es decir, dando todos los pasos para su creación y puesta en marcha, pero lo más cómodo es hacer uso de la librería de Google llamada Polymer, ya que ofrece

46

Trabajo de Fin de Grado ­ ETSIT UPM

numerosas funcionalidades que convierten esta tarea en una más fácil y nos ahorran tiempo y esfuerzo. Para su uso, en primer lugar, nos tenemos que situar en el directorio raíz del proyecto e instalar Polymer:

cd twc bower install --save Polymer/polymer#0.5 bower update

Hecho esto, ya tenemos todo listo para empezar a crear nuevos Web Components con ayuda del Custom Element <polymer-element>. Para empezar, lo primero que tenemos que hacer es cargar el Polymer core mediante un HTML Import y a continuación declarar el nuevo elemento, tal como vemos el siguiente esquema:

<link rel=“import” href=“../bower_components/polymer/polymer.html”> <polymer-element name=“mi-elemento” attributes=“atr1 atr2 ...” [noscript]> <template> <span>Esquema de un <b>mi-elemento</b>. Este es el Shadow DOM.</span> </template> <script> Polymer( atr1: “ … ”, atr2: “ … ”, fun1: function() … , created: function() … , ready: function() … , … ); </script> </polymer-element>

Como ya hemos mencionado en repetidas ocasiones, el namedel elemento tiene que contener un guión con el fin de que el navegador reconozca que se trata de un Web Component. Si al final de la etiqueta de <polymer-element>añadimos noscript, es que dicho elemento no necesitará el script que viene a continuación y se registrará de manera automática. Si de lo contrario, utilizamos script, en su interior vamos a llamar al constructor Polymer(...). Este constructor es un envoltorio para el registro del elemento pero también proporciona facilidades como la conexión de datos o mapeo de eventos. Además, acepta como argumento un objeto que define el prototipo del nuevo elemento y que si no se especifica, por defecto se considera que es HTMLElement. En el interior de este constructor es donde se definen tanto los atributos del elemento como sus métodos, bien se trate de métodos de ciclo de vida o de otro tipo.

Si decidimos hacer una composición, es decir, emplear en la declaración de nuestro componente otro, lo haríamos tal como vimos en el apartado anterior, primero instalándolo con

47

Trabajo de Fin de Grado ­ ETSIT UPM

ayuda de Bower, luego importándolo en la cabecera del documento y por fin utilizándolo dentro de <template>.

Una vez creado el nuevo componente, para utilizarlo en nuestra página tenemos que empezar por importar webcomponents.js y nuestro componente en la cabecera y a continuación utilizarlo en el cuerpo del documento:

<head> <script src=“../bower_components/webcomponentsjs/webcomponents.js”> </script> <link rel=“import” href=“../elements/my-element.html”> </head> <body> … <mi-elemento> … </mi-elemento> … </body>

Antes vimos cómo establecer conexiones entre los datos dentro de un componente de tipo noscript con la ayuda de un <template>de tipo “auto-binding”. En este caso vamos a ver como realizar dicho conexionado pero empleando JavaScript. El conexionado es una forma muy rápida de propagar cambios en el elemento y reducir la cantidad de código a escribir, y para su uso se emplea la sintaxis nombrePlaceholder. Este conexionado se puede hacer entre elementos del marcado y los atributos del mismo. A continuación vemos un ejemplo:

<link rel=“import” href=“../bower_components/polymer/polymer.html”> <polymer-element name=“mi-elemento” attributes=“posesor color”> <template> <p>Este es el elemento de <b style=“color: color”>posesor</b>.</p> <input id=“nombre” value=“posesor”> </template> <script> Polymer( color: “red”, posesor: “Miguel” ); </script> </polymer-element>

Como podemos observar, estamos escribiendo el nombre del posesor en el color que tiene por valor dicho atributo. Además, el nombre por defecto es “Miguel”, pero si escribimos otro nombre dentro del campo, el valor del posesor también cambiará. Además, al ser color y posesor atributos, el valor de estos se puede dar directamente al emplear el elemento:

<mi-elemento color=“blue” posesor=“Daniel”></mi-elemento>

Por último, otra cosa importante de mencionar es que el Shadow DOM del interior de <template>posee un árbol completamente aislado del de la página, de manera que los ID de

48

Trabajo de Fin de Grado ­ ETSIT UPM

su interior no interfieren con los de la página. Por tanto, cada elemento Polymer genera un mapa de IDs para referenciar a los nodos de <template>, y este mapa se puede referenciar desde dentro del script empleando $ con el fin de seleccionar el nodo deseado.

Aquí podemos decir que tenemos las pautas más importantes a la hora de crear un Web Component a nivel de producción, aunque el potencial de Polymer es uno mucho mayor. Sin embargo, para aquellos desarrolladores interesados en profundizar su conocimiento en este tema se recomienda consultar la documentación de API Developer Guide de la página oficial de Polymer.

Por otra parte, podríamos estar interesados en compartir los Custom Elements creados por nosotros en Internet y de esa forma contribuir a enriquecer el mundo de los Web Components. Como ya hemos visto, para la creación de un Custom Element de uso propio lo único que nos hace falta es un fichero .html con el CSS directamente incluido. Para uso del elemento por terceros, es muy conveniente separar código html y CSS en dos ficheros distintos e introducirlos en un repositorio de GitHub con el nombre del elemento junto con otra serie de ficheros adicionales necesarios para la publicación y registro del elemento en Internet.

La mayoría de los catálogos de Web Components añaden a su lista los distintos elementos publicados en Internet haciendo un escaneo de GitHub en búsqueda de los Web Components que aparecen listados en los directorios de los paquetes Bower y npm. Además para la descripción e información sobre el componente se utiliza información obtenida de la meta­data del repositorio que hemos publicado en Github. El primer paso consiste en crear en el repositorio del elemento un fichero bower.json o package.json y que entre los demás datos de su contenido se mencione como palabra clave “web-components”. El paso siguiente sería registrar dicho componente con Bower o npm, respectivamente, cuyas páginas oficiales proporcionan información detallada sobre dicho proceso.

“name”: “my-component”, “version”: “0.0.1”, “licence”: “MIT”, “main”: “my-component.html” “dependencies”: “polymer”: “Polymer/polymer#master” , “keywords”: [ “web-components” ], “ignore”: [ “**/.*” ]

Siempre resulta conveniente crear una imagen de vista previa del componente para

facilitar a los usuarios de Internet la comprensión de su funcionamiento. Para ello deberíamos añadir al repositorio un fichero preview.png que los catálogos mostrarán en la descripción del componente. Sin embargo, la mejor manera de comprender su funcionamiento es ilustrándolo con una demo interactiva. Para ello es necesario añadir las líneas @elementy @demoen un comentario al principio del fichero .html principal del componente y por supuesto, tener en el repositorio un fichero index.html que haga uso de manera ilustrativa del componente. Igual que antes, esta demo también aparecerá mostrada en la descripción del componente.

49

Trabajo de Fin de Grado ­ ETSIT UPM

<!-- Mi elemento @element my-element @demo https://example.github.io/my-element/index.html --> <polymer-element name=“my-element”> … </polymer-element>

Algo evidente, es que dicha demo necesita haber sido previamente desplegada por el

autor del elemento en una página web o dominio propio. Una opción gratuita para llevarlo a cabo es la creación de una página web de GitHub Pages, que en su página oficial proporciona información detallada sobre las condiciones de uso y funcionamiento.

Si se desea contribuir al mundo de los Web Components es muy recomendable, además de poner en práctica los consejos anteriores, leer la Gold Standard checklist, que explica cuáles son las pautas a seguir para conseguir unos Web Components tan fiables y flexibles como los elementos HTML estándar. Basic Web Components es un proyecto open source que tiene como objetivo crear una librería de Web Components que implementen todos los patrones de interfaz de usuario que podemos encontrar en la web o en las aplicaciones móviles. Es por eso que puede ser una opción interesante para empezar a desarrollar Web Components y compartirlos, y además cuenta con una lista de componentes deseados y una serie de principios para Web Components de propósito general.

Desventajas de los Web Components Aunque los Web Components son claramente una tecnología que llama mucho la

atención y que merece ser experimentada, esto no significa que sea todo ventajas. La principal razón por la cual los Web Components no se utilizan todavía a gran escala es la carencia que tienen en cuanto al soporte para los diferentes navegadores. Aunque se comporten muy bien en Chrome 36, el soporte ofrecido para Firefox, Safari o IE es uno parcial, de manera que para aquellos desarrolladores que quieran utilizar Web Components fuera de Chrome, los polyfills resultarán imprescindibles.

En este sentido, aunque no se le da la importancia suficiente, la complejidad de implementación de un polyfill puede variar ampliamente dependiendo de la tecnología a la que está destinado. Aquellos polyfills que deben añadir comportamiento completamente rompedor y cambios en la sintaxis CSS son los más complicados de escribir. En el caso de los Web Components, la creación de los polyfills se vuelve un verdadero reto, debido a la gran dificultad que presenta, hasta el punto de resultar inviable para su uso en la producción.

Sin embargo, el equipo de Google ha puesto mucho empeño y esfuerzo en la creación de los polyfills de Polymer y gracias a su extraordinario trabajo ha surgido platform.js. Podríamos pensar que dado que Google ha realizado ya todo el trabajo difícil, a nosotros solo nos queda disfrutar de las ventajas que ello ofrece, sin embargo, la complejidad viene con una serie de efectos adversos. En primer lugar, los polyfills de Polymer no soportan toda la

50

Trabajo de Fin de Grado ­ ETSIT UPM

funcionalidad que los Web Components ofrecen, y en especial Shadow DOM, ya que habría consistido en escribir de cero CSS en JavaScript, cosa que es inviable. En segundo lugar, está el problema de tamaño de los polyfills. Si hay desarrolladores que consideran el tamaño de jQuery como excesivo, los polyfills de Polymer llegan a más del doble. En tercer lugar, aparece el problema del tiempo que le lleva al navegador parsear e interpretar todo el código JavaScript, dando lugar a un problema de rendimiento. En este sentido, una gran cantidad de HTML Imports empleados genera una gran cantidad de peticiones HTTP, que en navegadores que no soportan nativamente los HTML Imports, se encolan dando lugar a un funcionamiento muy lento de la página web. Para mejorar este aspecto, existe la herramienta Vulcanize de la que hemos hablado con anterioridad pero que todavía se encuentra en sus inicios.

En resumen, los Web Components y Polymer son unas tecnologías muy interesantes que podrían llevar a un cambio fundamental de la manera en la que se desarrollan las aplicaciones web hoy en día, pero debido a la gran brecha entre Chrome y los demás navegadores en cuanto a su rendimiento, resultará complicado para la mayoría de los desarrolladores utilizar los Web Components hasta que no se hayan implementado y funcionen en igualdad de condiciones en todos los navegadores.

Herramientas y librerías NodeJS

Es la tecnología que se ha utilizado para la creación de la página web expuesta en un apartado anterior, y que se apoya en el motor de Javascript V8 para hacer posible la ejecución de programas hechos en Javascript en un ámbito independiente del navegador. La mayor ventaja que presenta NodeJS es la de no provocar bloqueos. Es decir, si durante la ejecución de un programa hay partes que necesitan un cierto tiempo para generar la respuesta, NodeJS no detiene la ejecución del programa esperando que esa parte acabe, sino que continúa procesando las siguientes instrucciones. Cuando el proceso anterior termina, vuelve a la ejecución de aquellas instrucciones que necesitaban hacer uso de los resultados generados por dicho proceso. Por todo ello su funcionamiento es mucho muy ágil.

Express

Express es sin duda el framework más conocido de NodeJS, es una extensión de connect y está inspirado en sinatra. Sin duda el éxito de express radica en lo sencillo que es usarlo, y es por eso el que elegimos utilizar para crear la aplicación web mencionada con anterioridad.

Bower

Se trata de un gestor de paquetes, que se dedica a encontrar e instalar los paquetes necesarios para el proyecto de una aplicacion web. Bower hace un seguimiento de estos

51

Trabajo de Fin de Grado ­ ETSIT UPM

paquetes con la ayuda de un fichero de manifiesto, bower.json. Este se ha empleado para la importar e instalar las librerías necesarias para el uso y creación de Web Components (webcomponents.js y polymer.js), y por otra parte para importar e instalar los Custom Elements deseado provenientes de terceros.

Heroku

Heroku es una Plataforma como Servicio (PaaS) en la nube, que soporta diferentes lenguajes de programación. Fue una de las primeras plataformas en la nube, que empezó en 2007 soportando solo el lenguaje de programación Ruby, pero desde entonces ha ido añadiendo soporte para Java, NodeJS, Scala, Clojure, Python, PHP y Perl. Su sistema operativo se basa en Debian o, últimamente, en Debian basado en Ubuntu. Ha sido la elección hecha para desplegar nuestra página web, dado que ofrece soporte para NodeJS y oferta un tipo de cuenta gratuito para experimentar en un entorno limitado pero que para lo que necesitamos es más que suficiente.

Polymer Element Collections (Polymer 0.5)

Es el catálogo de Custom Elements creado por Polymer para su versión 0.5. Consta de dos tipos de Custom Elements: los Core Elements, que son un conjunto de elementos de utilidad visual y no visual y los Paper Elements, que son un conjunto de alto contenido visual e interactivo que implementan diseño material para la web.

Polymer Catalog (Polymer 1.0)

Es el catálogo de Custom Elements creado por Polymer para su versión 1.0. Consta de varios tipos de Custom Elements: Iron Elements (Core Elements), Paper Elements (Material Design Elements), Google Web Components (Components for Google’s APIs and Services), Gold Elements (Ecommerce Elements), Neon Elements (Animation and Special Effects), Platinum Elements (Offline, push and more) y Molecules (Wrappers for 3rd party libraries). Es importante mencionar que estos elementos tienen principios de funcionamiento distintos a los explicados a lo largo de este documento, documento que se ha centrado en el uso de la versión 0.5 de Polymer.

CustomElements.io y Component Kitcken Catalog

Se trata de dos galerías de Custom Elements que escanean los repositorios públicos de GitHub en búsqueda de aquellos elementos que se han registrado en Internet con npm o Bower. La mayoría de los componentes que aparecen en su lista tienen a base de su creación a Polymer, tanto en su versión 0.5 con en la 1.0 y pero también aparecen otros elementos que no usan Polymer. A diferencia de los catálogos anteriores donde los elementos son creados por profesionales, los elementos listados aquí son elementos que cualquiera puede desarrollar y compartir en Internet, tal y como se ha contado en el apartado anterior de este documento.

52

Trabajo de Fin de Grado ­ ETSIT UPM

En la misma página de Polymer podemos encontrar una amplia variedad de documentación y tutoriales con ejemplos que nos ayuden a convertirnos en unos expertos en el desarrollo web con Web Components. Otro sitio que nos ofrece mucha documentación, recursos y videos explicativos de esta tecnología HTML es la página de WebComponents.org.

Conclusión Llegados a este punto, podemos decir que se han conseguido cumplir todos los

objetivos que se habían fijado al principio de este documento, y en concreto, se ha conseguido en primer lugar situar al lector en el contexto del mundo del desarrollo web y exponer los problemas a los que se enfrenta en la actualidad, para describir a continuación las características y las partes que componen Web Components, la nueva tecnología HTML capaz de solucionar muchos de dichos problemas. Lo siguiente ha sido explicar los principios básicos del funcionamiento de esta tecnología, acompañado de ejemplos prácticos, tanto a nivel introductorio como a nivel de desarrollo. También se han listado las principales herramientas y librerías utilizadas, y a continuación se ha expuesto una serie de desventajas con las que cuenta esta tecnología y que son los principales motivos por los cuales todavía no se está utilizando de manera más extendida. Y este es el punto final en el que se reflexiona sobre todo el trabajo de este documento y sobre el futuro de Web Components.

Como ya sabemos a estas alturas, la tecnología HTML conocida con el nombre de Web Components persigue ofrecer a los desarrolladores una mejora del proceso de desarrollo de aplicaciones web. Para ello hemos visto que se centra en erradicar en la medida de lo posible dos de los problemas más importantes en el desarrollo de aplicaciones web a día de hoy. Haciendo uso de sus cuatro especificaciones consigue por una parte reducir significativamente la cantidad de código redundante que se da a causa de que al desarrollar páginas web se acaban empleando muchos componentes con estructura semántica similar (basándose en mayor medida en los HTML Templates y los Custom Elements). Por otra parte, muchas veces se emplean componentes provenientes de terceros; estos, en repetidas ocasiones, además de resultar difíciles de importar y poner en funcionamiento hacen uso de su propio CSS y sus propios IDs, clases y atributos, que pueden llegar a coincidir con los de la página o de otros componentes dando lugar a un caos, problema que también consigue solucionar (basándose en mayor medida en los HTML Imports y el Shadow DOM).

Un aspecto a remarcar es que en el 90% de los casos, los artículos que tratan el tema de los Web Components solo exponen las numerosas ventajas que conlleva su utilización y apenas mencionan las desventajas. Sin embargo, tal como hemos visto en un punto anterior, hay también quienes se paran a pensar en las carencias de esta nueva tecnología HTML, que por mucho que intenta evitar y corregir el problema de que mucha gente se tenga que poner de acuerdo para la introducción de nuevas tecnologías HTML, al fin y al cabo consiste en una serie de estándares muy recientes que inevitablemente llevará a que tenga que pasar un tiempo para madurar y asentarse. Un ejemplo de ello es el que ya hemos visto, y en concreto,

53

Trabajo de Fin de Grado ­ ETSIT UPM

los Web Components no cobrarán toda la importancia que se merecen hasta que no se puedan utilizar de manera simple y óptima en absolutamente todos los navegadores.

Tenemos que reconocer que los Web Components son una tecnología HTML extraordinaria que introduce conceptos muy rompedores y especialmente útiles a la hora de ahorrar trabajo y esfuerzo en el desarrollo de aplicaciones web. Tal como hemos dicho, si se consigue encontrar la solución para su funcionamiento óptimo en todos los navegadores, podría convertirse en el estándar que revolucione completamente el mundo HTML. Sin embargo, como toda tecnología, a lo largo de su proceso de maduración tendrá que competir con otras tecnologías similares para finalmente acabar triunfando o extinguiéndose.

En este caso, el principal rival de Web Components y en concreto de Polymer, será su pariente AngularJS, ya que ambos son creación de Google. Tal como sabemos, Polymer se apoya en los Web Components, que hacen del código de las aplicaciones web uno mucho más claro y con capacidad de reciclado, facilitando notablemente el proceso de desarrollo, pero que cuenta con la carencia de ser soportados solo por navegadores modernos. Por otra parte, AngularJS trata de conseguir una funcionalidad similar pero más simple basándose en las Angular Directives. A continuación podemos ver una tabla comparativa de ambos:

A pesar de haber como siempre partidarios de ambos lados, muchos piensan que el mundo de la producción de aplicaciones web se decantará por el uso de AngularJS debido a su compatibilidad con los navegadores antiguos.

No obstante, esto no causa una desmotivación en el equipo de Polymer, sino que le hace consciente de sus carencias y aspectos a mejorar, y le incita a trabajar más aún duro con el fin sacar los Web Components hacia delante. Un ejemplo de ello es el reciente lanzamiento de la versión de Polymer 1.0, versión en la que se ha reescrito de manera casi integral la librería con respecto a la versión 0.5, todo ello con el fin de centrarse en mejorar el rendimiento en los diferentes navegadores, manteniendo a la vez todas las ventajas que se les había prometido a los desarrolladores.

En resumen, Web Components, como toda nueva tecnología, tiene sus ventajas e inconvenientes, gente que la apoya y gente que no. Desde luego, esta tecnología se encuentra dando sus primeros pasos en el mundo del desarrollo web y le queda todavía un largo camino por recorrer. Nadie puede pronunciarse actualmente sobre si perdurará y hará frente a sus

54

Trabajo de Fin de Grado ­ ETSIT UPM

posibles competidores o acabará entrando en desuso hasta extinguirse. Independientemente de lo que le reserva el futuro, Web Components sin duda ha jugado un papel importante en la evolución del desarrollo de aplicaciones web.

Bibliografía HTML5Rocks: Custom Elements ­ defining new elements in HTML

HTML5Rocks: HTML's New Template Tag ­ standardizing client­side templating

HTML5Rocks: HTML Imports ­ #include for the web

HTML5Rocks: Shadow DOM 101

HTML5Rocks: Shadow DOM 201 ­ CSS and Styling

HTML5Rocks: Shadow DOM 301 ­ Advanced Concepts and DOM APIs

An Introduction to Web Components and Polymer: Tutorial

Polymer: Polymer in 10 minutes ­ Creating elements

Polymer: Using Elements ­ Element guides

Component Kitchen: Tutorial ­ Supercharge your HTML powers with Web Components

Component Kitchen: Developers

The problem with using HTML Imports for Dependency Management

Why Web Components aren't ready for production... Yet

Polymer or AngularJS ­ what to use?

WebComponents.org: a place to discuss and evolve web component best­practices

Heroku Official Web Page

NodeJS Official Web Page

Programmable Web: the world's largest API repository

55