Done Right?

Distributed Extensibility on the Web

Robin Berjon / berjon.com / @robinberjon

Extensibility?

X

Of What?

Syntax

Vocabulary

Validity

Meaning

Behaviour

Distributed?

XML

  • Syntax: no
  • Vocabulary: yes
  • Validity: yes (externally)
  • Meaning: presumably
  • Behaviour: undefined

HTML (old school)

  • Syntax: no, but…
  • Vocabulary: no
  • Validity: no
  • Meaning: who knows?
  • Behaviour: sorta (painfully)

HTML (Web Components)

  • Syntax: no, but…
  • Vocabulary: yes
  • Validity: no (but yes)
  • Meaning: semantics, semantics, semantics
  • Behaviour: yes

A Boring Old Page


<!DOCTYPE html>
<title>My Rockin' Page</title>
<h1>My Rockin' Page</h1>
<p>Hi Prague!</p>
          

Old School Components


<!DOCTYPE html>
<title>My Rockin' Page</title>
<link rel='stylesheet' href='demo/old-school/big-red-button.css'>
<h1>My Rockin' Page</h1>
<p>Hi Prague!</p>
<!-- or is this in <head>? -->
<script src='demo/old-school/big-red-button.js'></script>
          

Big Red Button


<title>My Rockin' Page</title>
<link rel='stylesheet' href='demo/old-school/big-red-button.css'>
<h1>My Rockin' Page</h1>
<p>I am so hot I spontaneously unbreak symmetry.</p>
<div id="red-button" data-big-red-button="200">Push Me!</div>
<script src='demo/old-school/big-red-button.js'></script>
          

But… it's dead


// make it smaller
$("#red-button").attr("data-big-red-button", "100");
          

Or...


// add a new button!!!!!
$("<div data-big-red-button=50>Boom?</div>")
      .appendTo(document.body);
          

How do we fix this?

HTMLElement!

Natural Markup


<big-red-button size="100" id='brb'>
  Hit Me!
</big-red-button>
          

Natural Scripting


var brb = document.getElementById("brb");
brb.onclick = function () {
    brb.setAttribute("size", brb.size === 200 ? "500" : "200");
};
          

Templating


<template>
  <style>
    .brb {
        background: #f00;
        font-family:  Impact;
        color:  #fff;
        text-align: center;
    }
  </style>
  <div class='brb'><content></content></div>
</template>
          

Element Prototype (1/3)


var bigRedProto = Object.create(HTMLElement.prototype, {
    createdCallback:    {
        value:  function () {
            var tmpl = document.importNode(
                          doc.querySelector("template").content,
                          true);
            this._div = tmpl.querySelector("div.brb");
            this.createShadowRoot().appendChild(tmpl);
            this.size = this.getAttribute("size") || 100;
        }
    }
          

Element Prototype (2/3)


,   size:   {
        enumerable:     true
    ,   get:    function () { return this._size; }
    ,   set:    function (val) {
            var s = this._size = parseInt(val || "100", 10)
            ,   st = this._div.style;
            st.width = s + "px";
            st.height = s + "px";
            // more rendering changes
        }
    }
          

Element Prototype (3/3)


,   attributeChangedCallback:   {
        value:  function (name, oldVal, newVal) {
            if (name === "size") this.size = newVal;
        }
    }
});
          

Register It


  document.registerElement("big-red-button",
                           { prototype: bigRedProto });
          

Import The Component


<!DOCTYPE html>
<title>My Rockin' Page</title>
<link rel='import' href='brb-component.html'>
<h1>My Rockin' Page</h1>
<p>Whoa, such component!</p>
<big-red-button size="100" id='attr'>Attr</big-red-button>
<big-red-button size="200" id='brb'>Push Me!</big-red-button>
<script>
  // manipulate it directly...
</script>
          

Warning Traveller!

  • Moving target
  • Browser flags
  • Flimsy polyfills
  • Lots more to know

Extensible Web Manifesto

extensiblewebmanifesto.org

But... HEY!

Isn't this supposed to be an XML conference?

Okay!

XML Components?

<xml-import …>

registerElementNS()

In the meantime…

You can XSLT this

s/xforms:/xforms-/

Downsides

  • Ugly
  • Ad Hoc
  • May get complicated for some vocabularies

Upside

It works a lot better than any other option you have to make XML languages work in the browser today.

Thank
You!

Robin Berjon / berjon.com / @robinberjon