Cory Brown

@uniqname

Native Web Components

NOW!!!

Questions?

HTML Imports

Shadow DOM

HTML Templates

Custom Elements

HTML Imports

Shadow DOM

HTML Templates

Custom Elements

Polyfill All The Things!

HTML Imports 37K/8K gmin

Shadow DOM 160K/20K gmin

HTML Templates FREE .99

Custom Elements 33K/8K gmin

webcomponents.js 258K/37K gmin

webcomponents-lite.js 78K/16K gmin

Polyfill All The Things!

OMG
IKR
Totes cray!

Roll that beautiful web components footage!!!

Let's talk about all the good things and the bad things that may be...

(...about web components)

HTML Imports

  • Include HTML in HTML (it's like HTML inception)
  • Package a component as a single consumable.
  • Handles dependency resolution
  • Handles cyclical dependencies.

 

  • Pairs well with HTTP/2
  • Less efficient over HTTP/1.1 without something like vulcanize

HTML Imports

Imports received the most controversy when in December 2014 Mozilla declared their intention NOT to implement HTML imports -- at least until ES6 modules have received significant  implementations

HTML Imports

Mozilla will not ship an implementation of HTML Imports. We expect that once JavaScript modules — a feature derived from JavaScript libraries written by the developer community — is shipped, the way we look at this problem will have changed...

HTML Imports

...We have also learned from Gaia and others, that lack of HTML Imports is not a problem as the functionality can easily be provided for with a polyfill if desired.

HTML Imports

To date, no browser implementations of ES6 modules exist

HTML Imports

<link rel="stylesheet" href="styles.css" />
<div class="class">
    Any valid HTML can go in an HTML Import file.
</div>
<script src="some-file.js"></script>

<link rel="import" href="/path/to/my/web-component.html" />

use it

create it

HTML Imports

HTML Imports

But will it blend?

HTML Imports

  • Replace the <link ="import" /> with a <script>
  • Create a template property on the component prototype
  • Assign said template property the value of a js generated template element who's contents is the template contents from the import

 

HTML Imports

HTML Imports

So we can get by without imports for now.

Shadow DOM

  • Encapsulate structural implementations of UI (HTML)
  • Encapsulate component styles (prevent "leakage")
  • Prevent the external environment from accidentally accessing the internal one.
  • Provides a means of composition via a node distribution model

Shadow DOM

Many have seen ShadowDOM as a means of explaining aspects of how the web -- specifically HTML -- works.


<select>

<audio>/<video>

<details>

This is the summaryI'm a detail

Shadow DOM

Web Components were a Google effort and little negotiation was made with other browsers before shipping.

- Mozilla

Shadow DOM

Shadow DOM

Reconciliation was made, and in July all parties agreed on a path forward* which involves breaking ShadowDOM up into two versions.

Chrome has already issued an intent to ship for ShadowDOM v1

*Controversy mostly centered around the so called "light DOM" projection model. Resolution was to implement "slotting"

Shadow DOM

let shadowHost = document.querySelector('#needsShadow'),
    shadowChild = document.createElement('p');

shadowHost.createShadowRoot();
shadowHost.shadowRoot.append(shadowChild);

Shadow DOM

Shadow DOM

But will it blend?

Shadow DOM

just replace all references to `this.shadowRoot` with `this`.

Shadow DOM

HTML Templates

  • Content is effectively inert until activated
  • Content does not render in the page
  • Content is not considered part of the document
  • Content produces no side effects (scripts don't run, images don't load, audio doesn't play)
  • Template content is "activated" by deep cloning its `content` property -- a read-only documentFragment containing the parsed DOM of the template's contents.

HTML Templates

  • Does not have a concept of data binding.
  • Is not dynamic
  • It's just DOM

HTML Templates

HTML Templates are supported by every major evergreen browser.

It's ridiculously easy to polyfill*

*OK, it's more like a patch as the contents won't be inert, but it's better than writing code around it and we're coding for the future right? RIGHT?

HTML Templates

<template>

    <p>Any <strong>HTML</strong>.</p>

    <p>Seriously, <em>any</em> <abbr>HTML<abbr></p>

</template>

build it

HTML Templates

var el = document.querySelector(div),

    fragment = document.importNode(
        document.querySelector('template').content,
        true
    );

el.appendChild(fragment);

use it

HTML Templates

HTML Templates

But will it blend?

HTML Templates

  • create a `not-a-template` element
  • define a `content` property on it with a getter
  • return a DOM fragment of the `not-a-template`s innerHTML

HTML Templates

Custom Elements

Define Custom Semantic Elements as Components

React to lifecycle events

  • createdCallback
  • attachedCallback
  • detachedCallback
  • attributeChangedCallback

All other standard events are available to you.

Receive config through attributes (events?)

Expose information via custom events.

 

Custom Elements

This is where the real power is.

Lifecycle callbacks are RAD!*

*All though technically you don't even need this. Mutation Observers can be made to accomplish the same thing. In fact, this is how Custom Elements is polyfilled.

Custom Elements

const awesomePrototype = Object.create(HTMLElement, {

    // assign methods and properties
});

awesomePrototype.createdCallback = function () { ... };

awesomePrototype.attachedCallback = function () { ... };

awesomePrototype.detachedCallback = function () { ... };

awesomePrototype.attributeChangedCallback = function (attrName, prevVal, currVal) { ... };

document.registerElement('awe-some', {
    prototype: awesomePrototype
});

built it.

Custom Elements

<awe-some rad="UtahJS">
    <p>Composed DOM</p>
    <p>AKA Light DOM</p>
</awesmome>

use it.

Custom Elements

const awesomePrototype = Object.create(HTMLElement, {

    rad: {
    
        get() {
            return this.getAttribute('rad');
        },
        set(val) {
            return this.setAttribute('rad', val);
        }

    }
});

document.registerElement('awe-some', {
    prototype: awesomePrototype
});

pro tip: bind attributes to properies with getters/setters.

Custom Elements

`But I still need ${lame_framework_feature} to do any real work.`

Well, you've got options...

  • Realize you're wrong.
  • Polymer
  • X-Tag
  • Bosonic
  • Winston Churchill

Winston Churchill

A library for authoring web components

(shameless self promotion)

Features

  • Highly Extensible 
  • Composability is first class
  • Event centric
  • Dead simple API (only 3 methods)
  • Use native web components methods when ever possible
  • Favors adherence to native web platform paradigms (very little "tribal knowledge" to learn.)
  • Highly efficient data binding within templates.

Winston Churchill

Looking for contributors. PRs and Issues are appreciated.

Thank You

(loud applause!)

Native Web Components NOW!!!

By Cory Brown

Native Web Components NOW!!!

  • 1,634