Scalable Vector Ember 
Death to HTML. Long live the DOM.
@mixonic 
httP://madhatted.com 
matt.beale@madhatted.com
201 Created 
We build õ-age apps with Ember.js. We take 
teams from £ to • in no time flat.
1 <svg> 
2 {{#each d in paths}} 
3 <path {{bind-attr d=d}} /> 
4 {{/each}} 
5 </svg>
http://emberjs.jsbin.com/woxes/10/edit 
1.7: http://emberjs.jsbin.com/woxes/9 
! 
1.8: http://emberjs.jsbin.com/woxes/10
Preamble 
Vector Graphics
Raster Graphic (PNG) 
w3.org
Benefits of Raster Graphics 
• Small file-size (photos) 
• Computationally simple to 
render
Vector Graphic (SVG) 
1 <?xml version="1.0" standalone="no"?> 
2 <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" 
3 "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> 
4 <svg width="12cm" height="4cm" viewBox="0 0 1200 400" 
5 xmlns="http://www.w3.org/2000/svg" version="1.1"> 
6 <desc>Example rect01 - rectangle with sharp corners</desc> 
7 
8 <rect x="400" y="100" width="400" height="200" 
9 fill="yellow" stroke="navy" stroke-width="10" /> 
10 </svg> 
w3.org
Benefits of Vector Graphics 
• Small file-size (graphics) 
• Arbitrary resolution
Part I 
Scalable Vector Graphics
Why are we talking about this in 2014?
1998 Vector Markup Language proposed 
by Macromedia, Microsoft. PGML 
proposed by Adobe, Sun. W3C kick off 
SVG. 
2001 SVG 1.0 
2003 SVG 1.1
Benefits of SVG Standard 
• Easy-to-parse metadata 
• Links 
• Animation
1998 Vector Markup Language proposed 
by Macromedia, Microsoft. PGML 
proposed by Adobe, Sun. W3C kick off 
SVG. 
2001 SVG 1.0 
2003 SVG 1.1 
2004 Konqueror 3.2 support 
2005 Gecko (Firefox) support 
2006 WebKit (Chrome, Safari) support
5upmushroom.tumblr.com
1998 Vector Markup Language proposed 
by Macromedia, Microsoft. PGML 
proposed by Adobe, Sun. W3C kick off 
SVG. 
2001 SVG 1.0 
2003 SVG 1.1 
2004 Konqueror 3.2 support 
2005 Gecko (Firefox) support 
2006 WebKit (Chrome, Safari) support 
2011 IE9 is the last platform to support SVG
0.5% Woo! 
(almost) 
w3techs.com
( ๑‾̀◡‾́)σ» 
(´⊙ω⊙`) 
w3techs.com
3 ways to use SVG 
logo.svg 
<svg> 
document.createElementNS
3 ways to use SVG 
logo.svg 
<svg> 
document.createElementNS
Creating elements with a namespace 
1 var svg = document.createElementNS("http://www.w3.org/2000/svg", "svg"); 
2 svg.setAttribute("viewBox", "0 0 1200 400"); 
3 svg.setAttribute("width", "12cm"); 
4 svg.setAttribute("height", "4cm"); 
5 var path = document.createElementNS("http://www.w3.org/2000/svg", "path"); 
6 path.setAttribute("x", "400"); 
7 path.setAttribute("y", "100"); 
8 path.setAttribute("width", "400"); 
9 path.setAttribute("height", "200"); 
10 path.setAttribute("fill", "yellow"); 
11 path.setAttribute("stroke", "navy"); 
12 path.setAttribute("stroke-width", "10"); 
13 svg.appendChild(path); 
14 document.body.appendChild(svg);
Setting SVG attributes 
• Attributes are case sensitive 
1 var div = document.createElement("div"); 
2 div.setAttribute("someWacky", "foo"); 
3 div.getAttribute("someWacky"); // => "foo" 
4 div.getAttribute("somewacky"); // => "foo" 
5 
6 var svg = document.createElementNS(svgNS, "svg"); 
7 svg.setAttribute("someWow", "boo") 
8 svg.getAttribute("someWow"); // => "boo" 
9 svg.getAttribute("somewow"); // => null 
• Property values are not primitives 
1 svg.viewBox; // => SVGAnimatedRect {animVal: SVGRect, baseVal: SVGRect} 
2 var viewBox = new SVGAnimatedRect(); // => TypeError: Illegal constructor 
3 svg.viewBox = "0 0 100 100"; 
4 svg.getAttribute("viewBox"); // => null
Changing namespaces 
1 <div> 
2 <span></span> 
3 <svg> 
4 <path></path> 
5 <foreignObject> 
6 <div></div> 
7 </foreignObject> 
8 </svg> 
9 </div> 
Entrance to namespace dictated by next element 
Exit from namespace dictated by previous element
Part II 
Old Man Ember, Young Man Ember
Handlebars 
HTMLBars
THERE CAN ONLY BE ONE
THERE CAN ONLY BE DECK
A template 
1 <section> 
2 {{if isShowing}} 
3 <span>Howdy!</span> 
4 {{/if}} 
5 </section>
Ember.js pre-1.8 
1 var buffer = "<section>n"; 
2 buffer += "<script metamorph-0-start></script>"; 
3 if (isShowing) { 
4 buffer += " <span>Howdy!</span>n"; 
5 } 
6 buffer += "<script metamorph-0-end></script>"; 
7 buffer += "</section>"; 
8 
9 rootElement.innerHTML = buffer;
Ember.js pre-1.8 
1 var 
2 buffer 
3 if (isShowing) { 
4 buffer 
5 } 
6 buffer 
7 buffer 
8 
9 rootElement.innerHTML 
STRINGS, INNERHTML
Ember.js 1.10 
1 var outerChilden = [document.createElement('section')]; 
2 
3 var innerChildren; 
4 if (isShowing) { 
5 innerChildren = [document.createElement('span');] 
6 innerChildren[0].appendChild(document.createTextNode('Howdy!')); 
7 while (innerChildren[0]) { 
8 outerChilden[0].appendChild(innerChildren[0]); 
9 } 
10 } 
11 
12 while (outerChilden[0]) { 
13 rootElement.appendChild(outerChilden[0]); 
14 }
Ember.js 1.10 
1 var 
2 
3 var 
4 if (isShowing) { 
5 innerChildren 
6 innerChildren[ 
7 while (innerChildren[ 
8 outerChilden[ 
9 } 
10 } 
11 
12 while (outerChilden[ 
13 rootElement.appendChild(outerChilden[ 
14 } 
DOM! HTMLBARS! WOOOMG!
Ember.js 1.8-1.9 
1 var buffer, parsingNode; 
2 
3 buffer = "<section>n</section>"; 
4 parsingNode = document.createElement('div'); 
5 parsingNode.innerHTML = buffer; 
6 var outerChilden = parsingNode.childNodes; 
7 
8 if (isShowing) { 
9 buffer = " <span>Howdy!</span>n"; 
10 parsingNode.innerHTML = buffer; 
11 var innerChildren = parsingNode.childNodes; 
12 while (innerChildren[0]) { 
13 outerChilden[0].appendChild(innerChildren[0]); 
14 } 
15 } 
16 
17 while (outerChilden[0]) { 
18 rootElement.appendChild(outerChilden[0]); 
19 }
Ember.js 1.8-1.9 
1 var 
2 
3 buffer 
4 parsingNode 
5 parsingNode.innerHTML 
6 var 
7 
8 if (isShowing) { 
9 buffer 
10 parsingNode.innerHTML 
11 
12 while (innerChildren[ 
13 outerChilden[ 
14 } 
15 } 
16 
17 while (outerChilden[ 
18 rootElement.appendChild(outerChilden[ 
19 } 
STRING TEMPLATES, DOM for stitching
Tricky stuff in 1.8+ 
• managing a context 
• detecting a namespace 
!
Tricky stuff in 1.8+ 
1 var string = handlebarsTemplate(context, options); 
2 var nodes = domHelper.parseHTML(string, morph.contextualElement); 
3 
4 var node; 
5 while (node = nodes[0]) { 
6 rootElement.appendChild(node); 
7 }
HTMLBARS, Tricky stuff in 1.8+ 
1.10 
1 var nodes = htmlbarsTemplate(context, env, morph.contextualElement); 
2 
3 var node; 
4 while (node = nodes[0]) { 
5 rootElement.appendChild(node); 
6 }
Tricky stuff in 1.8+ 
• managing a context 
• detecting a namespace 
!
Tricky stuff in 1.8+ 
1 var root = document.createElement('div'); 
2 
3 root.innerHTML = "<svg><foreignObject><div></div></foreignObject></svg>"; 
4 
5 var svg = div.firstChild; 
6 var foreignObject = svg.firstChild; 
7 var div = foreignObject.firstChild; 
8 
9 svg.namespaceURI; // http://www.w3.org/2000/svg 
10 foreignObject.namespaceURI; // http://www.w3.org/2000/svg 
11 div.namespaceURI; // undefined
Tricky stuff in 1.8+ 
1 var root = document.createElementNS(svgNs, 'svg');! 
2 ! 
3 root.innerHTML = "<foreignObject><div></div></foreignObject>";! 
4 ! 
5 var foreignObject = root.firstChild;! 
6 var div = foreignObject.firstChild;! 
7 ! 
8 svg.namespaceURI; // http://www.w3.org/2000/svg! 
9 foreignObject.namespaceURI; // http://www.w3.org/2000/svg! 
10 div.namespaceURI; // undefined!
Tricky stuff in 1.8+ HTMLBARS, 1.10 
1 var template = htmlbarsCompile( 
2 "<foreignObject><div></div></foreignObject>" 
3 ); 
4 // so long as contextualElement is an SVG tag... 
5 var nodes = template(context, env, morph.contextualElement); 
6 
7 var foreignObject = nodes[0]; 
8 var div = foreignObject.firstChild; 
9 
10 foreignObject.namespaceURI; // http://www.w3.org/2000/svg 
11 div.namespaceURI; // undefined
Part III 
Death to HTML. Long live the DOM.
HTML is transmitted as a string.
• JS String (.jst, Ember <1.10) 
• HTML (Angular, Polymer) 
• JavaScript (React, Ember > 1.9, 
Mithril)
But that doesn’t mean we should process it as a string.
• innerHTML (.jst, Ember <1.10) 
• DOM (Angular, React, Ember > 1.9, 
Polymer, Mithril)
ACTIONS UP 
! 
BINDINGS DOWN
transmit strings 
! 
process DOM
CONTROLLERS LEFT 
! 
YEHUDA’S RIGHT
Thank you

Scalable vector ember

  • 1.
    Scalable Vector Ember Death to HTML. Long live the DOM.
  • 2.
  • 3.
    201 Created Webuild õ-age apps with Ember.js. We take teams from £ to • in no time flat.
  • 4.
    1 <svg> 2{{#each d in paths}} 3 <path {{bind-attr d=d}} /> 4 {{/each}} 5 </svg>
  • 5.
  • 7.
  • 9.
  • 10.
    Benefits of RasterGraphics • Small file-size (photos) • Computationally simple to render
  • 11.
    Vector Graphic (SVG) 1 <?xml version="1.0" standalone="no"?> 2 <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" 3 "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> 4 <svg width="12cm" height="4cm" viewBox="0 0 1200 400" 5 xmlns="http://www.w3.org/2000/svg" version="1.1"> 6 <desc>Example rect01 - rectangle with sharp corners</desc> 7 8 <rect x="400" y="100" width="400" height="200" 9 fill="yellow" stroke="navy" stroke-width="10" /> 10 </svg> w3.org
  • 12.
    Benefits of VectorGraphics • Small file-size (graphics) • Arbitrary resolution
  • 13.
    Part I ScalableVector Graphics
  • 14.
    Why are wetalking about this in 2014?
  • 15.
    1998 Vector MarkupLanguage proposed by Macromedia, Microsoft. PGML proposed by Adobe, Sun. W3C kick off SVG. 2001 SVG 1.0 2003 SVG 1.1
  • 16.
    Benefits of SVGStandard • Easy-to-parse metadata • Links • Animation
  • 17.
    1998 Vector MarkupLanguage proposed by Macromedia, Microsoft. PGML proposed by Adobe, Sun. W3C kick off SVG. 2001 SVG 1.0 2003 SVG 1.1 2004 Konqueror 3.2 support 2005 Gecko (Firefox) support 2006 WebKit (Chrome, Safari) support
  • 18.
  • 19.
    1998 Vector MarkupLanguage proposed by Macromedia, Microsoft. PGML proposed by Adobe, Sun. W3C kick off SVG. 2001 SVG 1.0 2003 SVG 1.1 2004 Konqueror 3.2 support 2005 Gecko (Firefox) support 2006 WebKit (Chrome, Safari) support 2011 IE9 is the last platform to support SVG
  • 20.
    0.5% Woo! (almost) w3techs.com
  • 21.
  • 22.
    3 ways touse SVG logo.svg <svg> document.createElementNS
  • 23.
    3 ways touse SVG logo.svg <svg> document.createElementNS
  • 24.
    Creating elements witha namespace 1 var svg = document.createElementNS("http://www.w3.org/2000/svg", "svg"); 2 svg.setAttribute("viewBox", "0 0 1200 400"); 3 svg.setAttribute("width", "12cm"); 4 svg.setAttribute("height", "4cm"); 5 var path = document.createElementNS("http://www.w3.org/2000/svg", "path"); 6 path.setAttribute("x", "400"); 7 path.setAttribute("y", "100"); 8 path.setAttribute("width", "400"); 9 path.setAttribute("height", "200"); 10 path.setAttribute("fill", "yellow"); 11 path.setAttribute("stroke", "navy"); 12 path.setAttribute("stroke-width", "10"); 13 svg.appendChild(path); 14 document.body.appendChild(svg);
  • 25.
    Setting SVG attributes • Attributes are case sensitive 1 var div = document.createElement("div"); 2 div.setAttribute("someWacky", "foo"); 3 div.getAttribute("someWacky"); // => "foo" 4 div.getAttribute("somewacky"); // => "foo" 5 6 var svg = document.createElementNS(svgNS, "svg"); 7 svg.setAttribute("someWow", "boo") 8 svg.getAttribute("someWow"); // => "boo" 9 svg.getAttribute("somewow"); // => null • Property values are not primitives 1 svg.viewBox; // => SVGAnimatedRect {animVal: SVGRect, baseVal: SVGRect} 2 var viewBox = new SVGAnimatedRect(); // => TypeError: Illegal constructor 3 svg.viewBox = "0 0 100 100"; 4 svg.getAttribute("viewBox"); // => null
  • 26.
    Changing namespaces 1<div> 2 <span></span> 3 <svg> 4 <path></path> 5 <foreignObject> 6 <div></div> 7 </foreignObject> 8 </svg> 9 </div> Entrance to namespace dictated by next element Exit from namespace dictated by previous element
  • 27.
    Part II OldMan Ember, Young Man Ember
  • 28.
  • 29.
  • 31.
  • 33.
    A template 1<section> 2 {{if isShowing}} 3 <span>Howdy!</span> 4 {{/if}} 5 </section>
  • 34.
    Ember.js pre-1.8 1var buffer = "<section>n"; 2 buffer += "<script metamorph-0-start></script>"; 3 if (isShowing) { 4 buffer += " <span>Howdy!</span>n"; 5 } 6 buffer += "<script metamorph-0-end></script>"; 7 buffer += "</section>"; 8 9 rootElement.innerHTML = buffer;
  • 35.
    Ember.js pre-1.8 1var 2 buffer 3 if (isShowing) { 4 buffer 5 } 6 buffer 7 buffer 8 9 rootElement.innerHTML STRINGS, INNERHTML
  • 36.
    Ember.js 1.10 1var outerChilden = [document.createElement('section')]; 2 3 var innerChildren; 4 if (isShowing) { 5 innerChildren = [document.createElement('span');] 6 innerChildren[0].appendChild(document.createTextNode('Howdy!')); 7 while (innerChildren[0]) { 8 outerChilden[0].appendChild(innerChildren[0]); 9 } 10 } 11 12 while (outerChilden[0]) { 13 rootElement.appendChild(outerChilden[0]); 14 }
  • 37.
    Ember.js 1.10 1var 2 3 var 4 if (isShowing) { 5 innerChildren 6 innerChildren[ 7 while (innerChildren[ 8 outerChilden[ 9 } 10 } 11 12 while (outerChilden[ 13 rootElement.appendChild(outerChilden[ 14 } DOM! HTMLBARS! WOOOMG!
  • 38.
    Ember.js 1.8-1.9 1var buffer, parsingNode; 2 3 buffer = "<section>n</section>"; 4 parsingNode = document.createElement('div'); 5 parsingNode.innerHTML = buffer; 6 var outerChilden = parsingNode.childNodes; 7 8 if (isShowing) { 9 buffer = " <span>Howdy!</span>n"; 10 parsingNode.innerHTML = buffer; 11 var innerChildren = parsingNode.childNodes; 12 while (innerChildren[0]) { 13 outerChilden[0].appendChild(innerChildren[0]); 14 } 15 } 16 17 while (outerChilden[0]) { 18 rootElement.appendChild(outerChilden[0]); 19 }
  • 39.
    Ember.js 1.8-1.9 1var 2 3 buffer 4 parsingNode 5 parsingNode.innerHTML 6 var 7 8 if (isShowing) { 9 buffer 10 parsingNode.innerHTML 11 12 while (innerChildren[ 13 outerChilden[ 14 } 15 } 16 17 while (outerChilden[ 18 rootElement.appendChild(outerChilden[ 19 } STRING TEMPLATES, DOM for stitching
  • 40.
    Tricky stuff in1.8+ • managing a context • detecting a namespace !
  • 41.
    Tricky stuff in1.8+ 1 var string = handlebarsTemplate(context, options); 2 var nodes = domHelper.parseHTML(string, morph.contextualElement); 3 4 var node; 5 while (node = nodes[0]) { 6 rootElement.appendChild(node); 7 }
  • 42.
    HTMLBARS, Tricky stuffin 1.8+ 1.10 1 var nodes = htmlbarsTemplate(context, env, morph.contextualElement); 2 3 var node; 4 while (node = nodes[0]) { 5 rootElement.appendChild(node); 6 }
  • 43.
    Tricky stuff in1.8+ • managing a context • detecting a namespace !
  • 44.
    Tricky stuff in1.8+ 1 var root = document.createElement('div'); 2 3 root.innerHTML = "<svg><foreignObject><div></div></foreignObject></svg>"; 4 5 var svg = div.firstChild; 6 var foreignObject = svg.firstChild; 7 var div = foreignObject.firstChild; 8 9 svg.namespaceURI; // http://www.w3.org/2000/svg 10 foreignObject.namespaceURI; // http://www.w3.org/2000/svg 11 div.namespaceURI; // undefined
  • 45.
    Tricky stuff in1.8+ 1 var root = document.createElementNS(svgNs, 'svg');! 2 ! 3 root.innerHTML = "<foreignObject><div></div></foreignObject>";! 4 ! 5 var foreignObject = root.firstChild;! 6 var div = foreignObject.firstChild;! 7 ! 8 svg.namespaceURI; // http://www.w3.org/2000/svg! 9 foreignObject.namespaceURI; // http://www.w3.org/2000/svg! 10 div.namespaceURI; // undefined!
  • 46.
    Tricky stuff in1.8+ HTMLBARS, 1.10 1 var template = htmlbarsCompile( 2 "<foreignObject><div></div></foreignObject>" 3 ); 4 // so long as contextualElement is an SVG tag... 5 var nodes = template(context, env, morph.contextualElement); 6 7 var foreignObject = nodes[0]; 8 var div = foreignObject.firstChild; 9 10 foreignObject.namespaceURI; // http://www.w3.org/2000/svg 11 div.namespaceURI; // undefined
  • 47.
    Part III Deathto HTML. Long live the DOM.
  • 48.
    HTML is transmittedas a string.
  • 49.
    • JS String(.jst, Ember <1.10) • HTML (Angular, Polymer) • JavaScript (React, Ember > 1.9, Mithril)
  • 51.
    But that doesn’tmean we should process it as a string.
  • 52.
    • innerHTML (.jst,Ember <1.10) • DOM (Angular, React, Ember > 1.9, Polymer, Mithril)
  • 53.
    ACTIONS UP ! BINDINGS DOWN
  • 54.
    transmit strings ! process DOM
  • 55.
    CONTROLLERS LEFT ! YEHUDA’S RIGHT
  • 56.