5. THE BROWSER AS AN
APPLICATION PLATFORM
• Powerful new language standards (TC39)
• Uniting around web standards (W3C)
• Use tomorrow’s technology today (Babel,
Web Frameworks)
6. HOW COMPONENTS HELP
• Encapsulation
• Maintainability
• Testability
• Scalability
• Extensibility
11. HTMLTEMPLATES
<template id="something">
<!-- Some style -->
<style type="text/css">
.title {
font-size: 24px;
}
</style>
<!-- Some behavior -->
<script type="text/javascript">
</script>
<!-- Some structure and content -->
<div class="frame">
<h3 class="title">I am a title</h3>
<p class="body">I am the body</p>
</div>
</template>
12. HTMLTEMPLATES
Add to the DOM
Example: http://codepen.io/TrueNorth/pen/xbyVgL?editors=101
// Grab the template
var tmpl = document.querySelector('#something');
// Add the cloned document fragment to the DOM
document.body.appendChild(
// Clone the template's document fragment
document.importNode(tmpl.content, true)
);
13. SHADOW DOM
What’s the point?
• CSS rules bleeding into UI components is
annoying
• DOM encapsulation is poor, unless you iframe
• Shadow DOM is a subtree within the parent page
14. SHADOW DOM
• Shadow Root - root
element of DOM subtree
• Shadow Host - parent of a
shadow root
Application DOM
Component
Shadow DOM
15. SHADOW DOM
Creating a Shadow Root
// Grab an element
var elem = document.querySelector("#good-host");
// Create the shadow root
var root = elem.createShadowRoot();
// Create a new element
var h1 = document.createElement("h1");
h1.innerHTML = "Hello World";
// Append to the shadow root
root.appendChild(h1);
16. SHADOW DOM
Add a template to the mix
Example: http://codepen.io/TrueNorth/pen/OPBNmq?editors=101
<template id="something">
<h1>Hello, world!</h1>
<p>This is part of my component</p>
</template>
<div id="good-host"></div>
// Grab an element
var elem = document.querySelector("#good-host");
// Create the shadow root
var root = elem.createShadowRoot();
// Grab the template
var tmpl = document.querySelector('#something');
// Add the cloned document fragment to the DOM
root.appendChild(
// Clone the template's document fragment
document.importNode(tmpl.content, true)
);
17. SHADOW DOM
Styling
• Style defined/loaded within
the shadow DOM only
applies to shadow DOM
• :host pseudo-selector -
for outer element
:host {
border: 1px solid red;
}
:host(.hover) {
border: 1px solid blue;
}
18. SHADOW DOM
Styling
• The ::shadow pseudo-selector
penetrates a shadow root
• the /deep/ pseudo-selector penetrates all
shadow roots
19. SHADOW DOM
Styling
.example-host {
border: 1px solid purple;
padding: 10px;
margin: 10px;
}
#good-host p {
color: blue;
}
#better-host::shadow p {
color: red;
}
#better-host/deep/ h1 {
color: cyan;
}
<template id="something">
<h1>Hello, world!</h1>
<p>This is part of my component</p>
<content></content>
</template>
<div id="good-host" class="example-host"></div>
<div id="better-host" class="example-host">
<div id="best-host" class="example-host"></div>
</div>
Example: http://codepen.io/TrueNorth/pen/MYPyOe
20. SHADOW DOM
Content Projection
• <content> tag to project all content
• <content select=“”> to project selected
content
<template id="something">
<h1><content select=".h1"></content></h1>
<p>This is part of my component</p>
<content></content>
</template>
Examples: http://codepen.io/TrueNorth/pen/emPZMv
21. CUSTOM ELEMENTS
What’s the point?
• Compose larger parts of an app declaratively
• Provide a standard and consistent life-cycle
• Extensibility
22. CUSTOM ELEMENTS
Registering
// Extend a DOM element prototype
var MegaButtonProto = Object.create(HTMLButtonElement.prototype);
// Register your new element type
var MegaButton = document.registerElement("mega-button", {
prototype: MegaButtonProto,
extends: "button"
});
23. CUSTOM ELEMENTS
Adding templates
// Template
var infoBoxTemplate = document.querySelector('#info-pane-template');
// Register the custom element
var InfoBox = document.registerElement("info-pane", {
prototype: Object.create(HTMLElement.prototype, {
createdCallback: {
value: function () {
// Create the shadow root
this.createShadowRoot()
// Add the template to the shadow root
.appendChild(
document.importNode(
infoBoxTemplate.content, true)
);
}
}
})
});
Examples: http://codepen.io/TrueNorth/pen/gbBmMR
24. HTML IMPORTS
• #include for the web
• onload, onerror hooks
• Can include CSS, JS and HTML
• Content can be accessed from the
outside
• HTML Imported JS can reference
either the main DOM or imported
document fragment
<link rel="import"
href="myfile.html" />
// Get document fragment of an import
var content = document
.querySelector('link[rel="import"]')
.import;
// From a <script> included,
// with the import access,
// imported DOM
document
.currentScript
.ownerDocument
.querySelector('.abc');
25. A REAL USE CASE
• Declarative Syntax
• Responds to click
<hamburger-menu title="My Menu">
<hb-menu-item href="#abc"
caption="Better get on these soon">
Serious Bugs
</hb-menu-item>
<hb-menu-item href="#def"
caption="Oh %#@$!">
Really Serious Bugs
</hb-menu-item>
</hamburger-menu>
Starting Point: http://codepen.io/TrueNorth/pen/PwdLrj
Componentized: http://codepen.io/TrueNorth/pen/xbyqME
HTML Importified: http://codepen.io/TrueNorth/pen/ogawLm
• Content projection
• Style on shadow root