KEMBAR78
Introduction to web components | PDF
WEBCOMPONENTS
@marcbaechinger
‚web development is overly complex…‘
unknown, but desperate software engineer
lack of encapsulation and abstraction
TODAYS STANDARDS BODY
STANDARDS BODY
W3C webcomponents
STANDARDS BODY
W3C webcomponents
heavily in flux
STANDARDS BODY
W3C webcomponents
webcomponents polyfill
heavily in flux
STANDARDS BODY
W3C webcomponents
webcomponents polyfill
heavily in flux
2013: same for x-tags and polymer
STANDARDS BODY
W3C webcomponents
webcomponents polyfill
x-tags polymer
brick polymer elements
heavily in flux
2013: same for x-tags and polymer
STANDARDS BODY
W3C webcomponents
webcomponents polyfill
x-tags polymer
brick polymer elements
heavily in flux
2013: same for x-tags and polymer
wrapper API (JS/HTML)
STANDARDS BODY
W3C webcomponents
webcomponents polyfill
x-tags polymer
brick polymer elements
heavily in flux
2013: same for x-tags and polymer
wrapper API (JS/HTML)
element sets (accordion, …)
http://www.w3.org/TR/components-intro/
Templates
Custom elements
Shadow DOM
Imports
June 2013
BROWSER SUPPORT
polymer
BROWSER SUPPORT
x-tags
polymer
HTML IMPORTS
imports.html
<link href="../styles/import.css" rel="stylesheet"/> 

<section id="root">

<h1>Caption of import</h1>

<p>imported text<p>

</section>

<script>

(function (global) {

global.markup = {

hi: function () {

console.log("hi from a fun declared in an import");

}

};

}(this));

</script>
HTML IMPORTS
<link id="markup" rel="import" href="imports.html">
import html fragment
var link = __.e("#markup");

var markup = link.import;

var fragment = markup.querySelector("#root");
access import
HTML IMPORTS
<link id="markup" rel="import" href="imports.html">
import html fragment
var link = __.e("#markup");

var markup = link.import;

var fragment = markup.querySelector("#root");
access import
HTML IMPORTS
<link id="markup" rel="import" href="imports.html">
import html fragment
usually cloned before use
HTML IMPORTS
HTML IMPORTS
check for import property to feature test
SCRIPTS IN IMPORTS
// in the import fragment

<script>

(function (global) {

global.markup = {

hi: function () {}

};

}(window));

</script>
// in the parent document

window.markup.hi();

SCRIPTS IN IMPORTS
// in the import fragment

<script>

(function (global) {

global.markup = {

hi: function () {}

};

}(window));

</script>
// in the parent document

window.markup.hi();

executed once when imported
SCRIPTS IN IMPORTS
// in the import fragment

<script>

(function (global) {

global.markup = {

hi: function () {}

};

}(window));

</script>
// in the parent document

window.markup.hi();

parent global context
executed once when imported
NO PARENT DOCUMENT!
<script>

var importDoc = 

document.currentScript.ownerDocument;



var parentDocument = document;

</script>

part of the imports.html
NO PARENT DOCUMENT!
<script>

var importDoc = 

document.currentScript.ownerDocument;



var parentDocument = document;

</script>

part of the imports.html
so scripts behave the same as in parent doc
TEMPLATES
TEMPLATE - LAZY MARKUP
<template id="template">

<h1>Diego Maradona</h1>

<img src="maradona.jpg"/>

<script>

console.log("exec template script");

</script>

</template>
TEMPLATE - LAZY MARKUP
<template id="template">

<h1>Diego Maradona</h1>

<img src="maradona.jpg"/>

<script>

console.log("exec template script");

</script>

</template>
lazy loaded
TEMPLATE - LAZY MARKUP
<template id="template">

<h1>Diego Maradona</h1>

<img src="maradona.jpg"/>

<script>

console.log("exec template script");

</script>

</template>
executed each time when applied
lazy loaded
FEATURETEST
function supportsTemplate() {

var el = document.createElement('template');

return !!('content' in el);

}
read-only DocumentFragment
INSERTING ATEMPLATE
var tmpl = __.e("#template"),

target = __.e("#target");



target.appendChild(

document.importNode(tmpl.content, true)

);
IMPORTEDTEMPLATES
// select the import root from the ‚link‘ elem

var importLink = __.e("#import-1").import;

// select the template within the import

var tmpl = __.e("template", importLink);
__.e("#target").appendChild(

document.importNode(tmpl.content, true)

);
SHADOW DOM
!
Denn die einen sind im Dunkeln

Und die andern sind im Licht

Und man siehet die im Lichte

Die im Dunkeln sieht man nicht 	

!
aus Mackie Messer von Berthold Brecht
RENDERTREE
t e
RENDERTREE
t e
shadow = target.createShadowRoot()
RENDERTREE
t e
shadow = target.createShadowRoot()
RENDERTREE
t e
shadow = target.createShadowRoot()
s
shadow root
RENDERTREE
t e
shadow = target.createShadowRoot() shadow.appendChild(element)
s
shadow root
RENDERTREE
t e
shadow = target.createShadowRoot()
<content/>
shadow.appendChild(element)
s
shadow root
HTML IMPORTS
HTML IMPORTS
initial child node
HTML IMPORTS
initial child node
shadow DOM from template
HTML IMPORTS
initial child node
shadow DOM from template
insertion point of initial content
SHADOW DOMTEMPLATES
function renderShadow(tmplId, targetSelector) {

var tmpl = __.e("#" + tmplId),

target = __.e(targetSelector),

shadow = target.createShadowRoot();



target.style.display = "block";

shadow.appendChild(

tmpl.content.cloneNode(true)

);

}
SHADOW DOMTEMPLATES
function renderShadow(tmplId, targetSelector) {

var tmpl = __.e("#" + tmplId),

target = __.e(targetSelector),

shadow = target.createShadowRoot();



target.style.display = "block";

shadow.appendChild(

tmpl.content.cloneNode(true)

);

}
visually removes all previous children
SHADOW DOMTEMPLATES
<div id="name-shadow-hook" class="hook">

<span class="email">marc.baechinger@gmail.com</span>

<span class="address">Webergasse 23, 8408 Winterthur</span>

<span class="name">Hans Meier</span>

<img src="../images/alaska.jpg" width="480"/>

</div>
<template id="person-template">

<section>

<h3><content select=".name"/></h3>

<p><b>Address</b> <content select=".address"/></p>

<p><b>E-Mail</b> <content select=".email"/></p>

<div><content select=„img"/></div>

</section>

</template>
SHADOW DOMTEMPLATES
<div id="name-shadow-hook" class="hook">

<span class="email">marc.baechinger@gmail.com</span>

<span class="address">Webergasse 23, 8408 Winterthur</span>

<span class="name">Hans Meier</span>

<img src="../images/alaska.jpg" width="480"/>

</div>
<template id="person-template">

<section>

<h3><content select=".name"/></h3>

<p><b>Address</b> <content select=".address"/></p>

<p><b>E-Mail</b> <content select=".email"/></p>

<div><content select=„img"/></div>

</section>

</template>
change initial DOM to change shadow dom
SHADOW DOMTEMPLATES
<template id=„person-template">

<article id="master">

<header><content select=".header"/></header>

<div><content select=".content"/></div>

<footer><content select=".footer"/></footer>

</article>

</template>
template demo
pic: www.lolpig.com
CUSTOM ELEMENTS
<woot/>
CUSTOM ELEMENTS
<polymer-ui-accordion selected="1" id="accordion">

<polymer-ui-collapsible id="abstraction">

<div class="polymer-ui-collapsible-
header">Abstraction and encapsulation</div>

<div>…</div>

</polymer-ui-collapsible>

<polymer-ui-collapsible id="abstraction">

<div class="polymer-ui-collapsible-
header">Abstraction and encapsulation</div>

<div>…</div>

</polymer-ui-collapsible>

</polymer-ui-accordion>
CUSTOM ELEMENTS
CUSTOM ELEMENTS
invisible to querySelector and CSS rules
CUSTOM ELEMENTS
invisible to querySelector and CSS rules
use elements and attributes of DOM as 	

API to interact with the 	

shadow DOM component:

!
acc.setAttribute("selected", 1);
CUSTOM ELEMENTS
function (name, spec, callbacks) {

var proto =

Object.create(HTMLDivElement.prototype);



// […] check for callbacks



return document.registerElement(name, {

prototype: Object.create(proto, spec || {})

});

}
CUSTOM ELEMENTS
function (name, spec, callbacks) {

var proto =

Object.create(HTMLDivElement.prototype);



// […] check for callbacks



return document.registerElement(name, {

prototype: Object.create(proto, spec || {})

});

}
returns a constructor
CUSTOM ELEMENTS
function (name, spec, callbacks) {

var proto =

Object.create(HTMLDivElement.prototype);



// […] check for callbacks



return document.registerElement(name, {

prototype: Object.create(proto, spec || {})

});

}
returns a constructor
the prototype of the constructor
CALLBACKS
proto.createdCallback = function () {}



proto.attachedCallback = function () {}



proto.detachedCallback = function () {}
proto.attributeChangedCallback = f(name,oldV,newV) {}
CALLBACKS
proto.createdCallback = function () {}



proto.attachedCallback = function () {}



proto.detachedCallback = function () {}
proto.attributeChangedCallback = f(name,oldV,newV) {}
this is the DOM element
CUSTOM ELEMENTS
register(

'x-label', 

{},

{

createdCallback: function() {},

attachedCallback: function() {}

}

);
x-label demo
pic: www.lolpig.com
WEBCOMPONENTS	

RECAP
polyfills to use it today
infrastructure for abstraction and
encapsulation
infrastructure to build frameworks 	

on top of it
heavily pushed by Google
future in the dust
RECAP
BRICK AND POLYMER
POLYMER
POLYMER
polyfill
POLYMER
polyfill
polymer framework (eg. databinding)
POLYMER
polyfill
polymer framework (eg. databinding)
polymer elements
POLYMER
polyfill
polymer framework (eg. databinding)
polymer elementspolymer elements
X-TAGS
X-TAGS API (IMPERATIVE)
MOZILLA.GITHUB.IO/BRICK/
MOZILLA.GITHUB.IO/BRICK/
available elements
MOZILLA.GITHUB.IO/BRICK/
available elements
styles and scripts of Brick
THX, GUYS!
RESOURCES
GENERAL
https://html5-demos.appspot.com/static/webcomponents/index.html	

!
www.html5rocks.com/en/tutorials/webcomponents/customelements/	

!
!
https://developer.mozilla.org/en-US/Apps/Tools_and_frameworks/x-tags
HTML IMPORTS
http://w3c.github.io/webcomponents/spec/imports/

http://www.w3.org/TR/2013/WD-html-imports-20130514/

http://www.w3.org/TR/2014/WD-html-imports-20140311/
http://www.html5rocks.com/en/tutorials/webcomponents/
imports/

http://www.polymer-project.org/platform/html-imports.html
https://bugzilla.mozilla.org/show_bug.cgi?id=877072

http://www.x-tags.org/blog
TEMPLATES
http://www.w3.org/TR/components-intro/#template-
section
https://dvcs.w3.org/hg/webcomponents/raw-file/tip/
spec/templates/index.html
http://www.html5rocks.com/en/tutorials/webcomponents/
template/

Introduction to web components