Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Componentize all the things!

4cf764dcd5d1efc1de7051603bdf8215?s=47 JSIST
September 28, 2014

Componentize all the things!

JSIST 2014
By : Pascal Precht
http://jsist.org

4cf764dcd5d1efc1de7051603bdf8215?s=128

JSIST

September 28, 2014
Tweet

Transcript

  1. #jsist2014 @Web_Components @PascalPrecht COMPONENTIZE ALL THE THINGS! Pascal Precht @PascalPrecht

  2. Pascal Precht

  3. None
  4. None
  5. None
  6. None
  7. Oh my gosh this talk on Web Components by @PascalPrecht

    blows my mind! #jsist2014
  8. Web Components

  9. None
  10. Web Components are a collection of standards that change the

    way we build web applications.
  11. Four technologies HTML Templates - Inert chunks of clonable DOM

    Shadow DOM - Style & DOM encapsulation Custom Elements - Define and use new DOM elements HTML Imports - Include/Reuse other HTML documents
  12. Four technologies HTML Templates - Inert chunks of clonable DOM

    Shadow DOM - Style & DOM encapsulation Custom Elements - Define and use new DOM elements HTML Imports - Include/Reuse other HTML documents
  13. HTML Templates

  14. Inert chunks of clonable DOM that can be activated for

    later use.
  15. What we did before...

  16. Offscreen DOM < d i v i d = "

    m y t e m p l a t e " h i d d e n > < i m g s r c = " l o g o . p n g " > < d i v c l a s s = " c o m m e n t " > < / d i v > < / d i v > We can clone the DOM Nothing is rendered Not inert, network request is made for the image Styling is painful, all styles must be prefixed with # m y t e m p l a t e
  17. Overloading script < s c r i p t i

    d = " m y t e m p l a t e " t y p e = " t e x t / x - h a n d l e b a r s - t e m p l a t e " > < / s c r i p t > < i m g s r c = " l o g o . p n g " > < d i v c l a s s = " c o m m e n t " > < / d i v > Nothing rendered, < s c r i p t > is d i s p l a y : n o n e ; by default It's inert (yay!), JS isn't parsed because of its type Security issues, run-time string of user-supplied data can easily lead to XSS vulnerabilities
  18. HTML Templates to the rescue! < t e m p

    l a t e i d = " m y t e m p l a t e " > < i m g s r c = " p a t h / t o / s o u r c e . p n g " a l t = " g r e a t i m a g e " > < d i v c l a s s = " c o m m e n t " > < / d i v > < / t e m p l a t e > Clonable DOM Parsed, not rendered Stylesheets/Images aren't loaded, media isn't played, scripts don't run
  19. Activating a template You can activate templates by cloning their

    c o n t e n t document fragment. v a r t = d o c u m e n t . q u e r y S e l e c t o r ( ' # m y t e m p l a t e ' ) ; t . c o n t e n t . q u e r y S e l e c t o r ( ' i m g ' ) . s r c = ' l o g o . p n g ' ; d o c u m e n t . b o d y . a p p e n d C h i l d ( t . c o n t e n t . c l o n e N o d e ( t r u e ) ) ; Demo
  20. A few gotchas to know about...

  21. No prerendering Templates can't be "precompiled" like you can with

    libs like handlebars Assets, images, JS processing can't be preloaded
  22. Nested templates behaviour Activating outer template will not activate inner

    templates. < t e m p l a t e > < u l > < t e m p l a t e > < l i > S t u f f < / l i > < / t e m p l a t e > < / u l > < / t e m p l a t e >
  23. None
  24. None
  25. Reads HTML5Rocks.com - HTML's New Template Tag WhatWG HTML Templates

    specification
  26. Four technologies HTML Templates - Inert chunks of clonable DOM

    Shadow DOM - Style & DOM encapsulation Custom Elements - Define and use new DOM elements HTML Imports - Include/Reuse other HTML documents
  27. Four technologies Shadow DOM - Style & DOM encapsulation HTML

    Templates - Inert chunks of clonable DOM Custom Elements - Define and use new DOM elements HTML Imports - Include/Reuse other HTML documents
  28. Shadow DOM

  29. Shadow DO is a beast!

  30. Shadow DOM gives us DOM tree encapsulation and style boundaries.

  31. The web platform offered only one built-in mechanism to isolate

    one chunk of code to another - < i f r a m e >
  32. each of my custom but a separate iframe? Wh of

    insane are you
  33. < i n p u t t y p e

    = " t i m e " > - - : - -
  34. < d e t a i l s > C

    o n t e n t g o e s h e r e < / d e t a i l s > Details
  35. Shadow Trees shadow host shadow root child child child child

    Document Tree ... ... ... shadow boundary ... ...
  36. Shadow Tree shadow host shadow root child shadow root child

    Tree as Rendered ...
  37. Creating Shadow DOM . c r e a t e

    S h a d o w R o o t ( ) creates a shadow root on a host element. < b u t t o n > H e l l o W o r l d ! < / b u t t o n > v a r h o s t = d o c u m e n t . q u e r y S e l e c t o r ( ' b u t t o n ' ) ; v a r s h a d o w R o o t = h o s t . c r e a t e S h a d o w R o o t ( ) ; s h a d o w R o o t . t e x t C o n t e n t = ' H e l l o J s i s t ! ' ; Demo
  38. It's just HTML Use typical JS APIs to put nodes

    into your Shadow DOM (. i n n e r H T M L , . a p p e n d C h i l d ( ) ...). v a r h o s t = d o c u m e n t . q u e r y S e l e c t o r ( ' # h o s t ' ) ; v a r s h a d o w R o o t = h o s t . c r e a t e S h a d o w R o o t ( ) ; v a r p = d o c u m e n t . c r e a t e E l e m e n t ( ' p ' ) ; p . i n n e r H T M L = ' T h i s i s H T M L c o d e ' ; / * * * B o t h w o r k * / s h a d o w R o o t . i n n e r H T M L = ' < p > T h i s i s H T M L c o d e < / p > ' ; s h a d o w R o o t . a p p e n d C h i l d ( p ) ;
  39. So that means we can use HTML Templates together with

    Shadow DOM? YES!
  40. Shadow DOM <3 Templates Simply combine the things we just

    learned. < t e m p l a t e i d = " c u s t o m - t e m p l a t e " > < p > T h i s i s H T M L C o d e < / p > < / t e m p l a t e > v a r h o s t = d o c u m e n t . q u e r y S e l e c t o r ( ' # h o s t ' ) ; v a r s h a d o w R o o t = h o s t . c r e a t e S h a d o w R o o t ( ) ; v a r t = d o c u m e n t . q u e r y S e l e c t o r ( ' # c u s t o m - t e m p l a t e ' ) ; s h a d o w R o o t . a p p e n d C h i l d ( t . c o n t e n t . c l o n e N o d e ( t r u e ) ) ;
  41. Great! But is there also a way to separate the

    content from presentation? YES!
  42. Insertion Points < c o n t e n t

    > < / c o n t e n t > lets you create insertion points that cherry-pick content from the shadow host.
  43. Let's create a special button < t e m p

    l a t e i d = " s p e c i a l - b u t t o n - t e m p l a t e " > < s t y l e > < / s t y l e > < b u t t o n c l a s s = " s p e c i a l - b u t t o n " > S p e c i a l B u t t o n ! < / b u t t o n > < / t e m p l a t e > . s p e c i a l - b u t t o n { b a c k g r o u n d : # b a d a 5 5 ; c o l o r : r e d ; p a d d i n g : 1 e m ; b o r d e r - r a d i u s : 0 . 3 e m ; f o n t - s i z e : 1 e m ; }
  44. < s p a n i d = " s

    p e c i a l - b u t t o n " > < / s p a n > Special Button!
  45. < s p a n i d = " s

    p e c i a l - b u t t o n " > S p e c i a l B u t t o n ! < / s p a n > Special Button!
  46. < s p a n i d = " s

    p e c i a l - b u t t o n " > M e r h a b a ! < / s p a n > Merhaba!
  47. < t e m p l a t e i

    d = " s p e c i a l - b u t t o n - t e m p l a t e " > < s t y l e > < / s t y l e > < b u t t o n c l a s s = " s p e c i a l - b u t t o n " > S p e c i a l B u t t o n ! < / b u t t o n > < / t e m p l a t e > . s p e c i a l - b u t t o n { b a c k g r o u n d : # b a d a 5 5 ; c o l o r : r e d ; p a d d i n g : 1 e m ; b o r d e r - r a d i u s : 0 . 3 e m ; f o n t - s i z e : 1 e m ; }
  48. < t e m p l a t e i

    d = " s p e c i a l - b u t t o n - t e m p l a t e " > < s t y l e > < / s t y l e > < b u t t o n c l a s s = " s p e c i a l - b u t t o n " > < c o n t e n t > < / c o n t e n t > < / b u t t o n > < / t e m p l a t e > . s p e c i a l - b u t t o n { b a c k g r o u n d : # b a d a 5 5 ; c o l o r : r e d ; p a d d i n g : 1 e m ; b o r d e r - r a d i u s : 0 . 3 e m ; f o n t - s i z e : 1 e m ; } Demo
  49. Insertions Points are to Web Components, what transclusion is to

    AngularJS (sort of).
  50. Can we decide what content is projected and which not?

    YES!
  51. Cherry-picking content projection s e l e c t attribute

    uses CSS selectors to specify where children are projected. < d i v i d = " h o s t " > < h 1 > M y T i t l e < / h 1 > < h 2 > M y S u b t i t l e < / h 2 > < d i v > . . . o t h e r c o n t e n t . . . < / d i v > < / d i v > < h g r o u p > < c o n t e n t s e l e c t = " h 2 " > < / c o n t e n t > < c o n t e n t s e l e c t = " h 1 : f i r s t - c h i l d " > < / c o n t e n t > < / h g r o u p >
  52. Wow! Can we even select descendents for projection like s

    e l e c t = " t a b l e t r " ? NO!
  53. Style Encapsulation Shadow DOM comes with a shadow boundary that

    enables style encapsulation for free. Styles are scoped to shadow root < d i v > < h 3 > L i g h t D O M < / h 3 > < / d i v > < s c r i p t > v a r h o s t = d o c u m e n t . q u e r y S e l e c t o r ( ' d i v ' ) . c r e a t e S h a d o w R o o t ( ) ; h o s t . i n n e r H T M L = ' < s t y l e > h 3 { c o l o r : r e d ; } < / s t y l e > ' + ' < h 3 > S h a d o w D O M < / h 3 > ' ; < / s c r i p t > Shadow DOM
  54. Styling the host element : h o s t allows

    us to style the element hosting a shadow tree. < b u t t o n > M y b u t t o n < / b u t t o n > < s c r i p t > v a r b u t t o n = d o c u m e n t . q u e r y S e l e c t o r ( ' b u t t o n ' ) ; v a r h o s t = b u t t o n . c r e a t e S h a d o w R o o t ( ) ; h o s t . i n n e r H T M L = ' < s t y l e > ' + ' : h o s t { t e x t - t r a n s f o r m : u p p e r c a s e ; } ' + ' < / s t y l e > ' + ' < c o n t e n t > < / c o n t e n t > ' ; < / s c r i p t > MY BUTTON
  55. Moar host selectors : h o s t ( s

    e l e c t o r ) - Matches if host itself s e l e c t o r : h o s t ( : h o v e r / : a c t i v e ) - Know pseudo selectors
  56. Context selectors : h o s t - c o

    n t e x t ( s e l e c t o r ) - Matches if host element or any of its ancestors match s e l e c t o r < d i v c l a s s = " t h e m e - n a m e " > < x - f o o > < / x - f o o > < / d i v > : h o s t - c o n t e x t ( . t h e m e - n a m e ) { / * s t y l e s * / }
  57. Styling Shadow DOM from outside We have two new selectors

    to cross the shadow boundaries and style Shadow DOM from the outside world. : : s h a d o w - matches the shadow root itself / d e e p / - Crosses into any number of shadow trees
  58. The : : s h a d o w pseudo-element

    < s t y l e > < / s t y l e > < d i v i d = " h o s t " > < s p a n > L i g h t D O M < / s p a n > < / d i v > # h o s t : : s h a d o w s p a n { c o l o r : r e d ; } v a r h o s t = d o c u m e n t . q u e r y S e l e c t o r ( ' d i v ' ) ; v a r r o o t = h o s t . c r e a t e S h a d o w R o o t ( ) ; r o o t . i n n e r H T M L = ' < s p a n > S h a d o w D O M < / s p a n > ' + ' < c o n t e n t > < / c o n t e n t > ' ; Shadow DOMLight DOM
  59. The / d e e p / combinator Useful when

    having multiple levels of Shadow DOM (very common when working with Custom Elements. x - t a b s / d e e p / x - p a n e l { / * s t y l e s * / } ^ Select all x - p a n e l elements that are descendents of x - t a b anywhere in the tree.
  60. None
  61. None
  62. Reads HTML5Rocks.com - Shadow DOM 101 HTML5Rocks.com - Shadow DOM

    201 HTML5Rocks.com - Shadow DOM 301
  63. Four technologies Shadow DOM - Style & DOM encapsulation HTML

    Templates - Inert chunks of clonable DOM Custom Elements - Define and use new DOM elements HTML Imports - Include/Reuse other HTML documents
  64. Four technologies Custom Elements - Define and use new DOM

    elements HTML Templates - Inert chunks of clonable DOM Shadow DOM - Style & DOM encapsulation HTML Imports - Include/Reuse other HTML documents
  65. Custom Elements

  66. Custom Elements allow web developers to define new types of

    HTML elements.
  67. Custom Elements Features Define new HTML/DOM Elements Extend existing elements

    Bundle together custom functionality into a single tag
  68. Registering new elements d o c u m e n

    t . r e g i s t e r E l e m e n t ( ) let's you create custom elements. v a r M y E l e m e n t = d o c u m e n t . r e g i s t e r E l e m e n t ( ' m y - e l e m e n t ' ) ; d o c u m e n t . b o d y . a p p e n d C h i l d ( n e w M y E l e m e n t ( ) ) ; Or with an optional prototype v a r M y E l e m e n t = d o c u m e n t . r e g i s t e r E l e m e n t ( ' m y - e l e m e n t ' , { p r o t o t y p e : O b j e c t . c r e a t e ( H T M L E l e m e n t . p r o t o t y p e ) } ) ;
  69. Extend native/custom elements Simply inherit prototype from H T M

    L [ t y p e ] E l e m e n t and add e x t e n d s property accordingly. v a r M e g a B u t t o n = d o c u m e n t . r e g i s t e r E l e m e n t ( ' m e g a - b u t t o n ' , { p r o t o t y p e : O b j e c t . c r e a t e ( H T M L B u t t o n E l e m e n t . p r o t o t y p e , { / * n e w A P I s * / } ) , e x t e n d s : ' b u t t o n ' } ) ; < b u t t o n i s = " m e g a - b u t t o n " > < / b u t t o n > Custom elements that inherit from native elements are called type extension custom elements.
  70. Instantiate Custom Elements Declarative: < m y - e l

    e m e n t > < / m y - e l e m e n t > Via DOM APIs: v a r m y E l e m e n t = d o c u m e n t . c r e a t e E l e m e n t ( ' m y - e l e m e n t ' ) ; Using n e w : v a r m y E l e m e n t = n e w M y E l e m e n t ( ) ; d o c u m e n t . b o d y . a p p e n d C h i l d ( m y E l e m e n t ) ;
  71. Lifecycle callback methods c r e a t e d

    C a l l b a c k - instance of the element is created a t t a c h e d C a l l b a c k - instance was inserted into the document d e t a c h e d C a l l b a c k - instance was removed into the document a t t r i b u t e C h a n g e d C a l l b a c k - attribute was added, removed or updated
  72. v a r p r o t o = O

    b j e c t . c r e a t e ( H T M L E l e m e n t . p r o t o t y p e ) ; p r o t o . c r e a t e d C a l l b a c k = f u n c t i o n ( ) { . . . } ; p r o t o . a t t a c h e d C a l l b a c k = f u n c t i o n ( ) { . . . } ; v a r X F o o = d o c u m e n t . r e g i s t e r E l e m e n t ( ' x - f o o ' , { p r o t o t y p e : p r o t o } ) ;
  73. Alright, so can we add markup to our custom element?

    SURE!
  74. v a r p r o t o = O

    b j e c t . c r e a t e ( H T M L E l e m e n t . p r o t o t y p e ) ; p r o t o . c r e a t e d C a l l b a c k = f u n c t i o n ( ) { t h i s . i n n e r H T M L = ' < p > H T M L g o e s h e r e < / p > ' ; } ; v a r X F o o = d o c u m e n t . r e g i s t e r E l e m e n t ( ' x - f o o ' , { p r o t o t y p e : p r o t o } ) ;
  75. o works h mplates Shadow M? SURE!

  76. v a r p r o t o = O

    b j e c t . c r e a t e ( H T M L E l e m e n t . p r o t o t y p e ) ; p r o t o . c r e a t e d C a l l b a c k = f u n c t i o n ( ) { v a r t = d o c u m e n t . q u e r y S e l e c t o r ( ' # s d t e m p l a t e ' ) ; v a r c l o n e = t . c o n t e n t . c l o n e N o d e ( t r u e ) ; t h i s . c r e a t e S h a d o w R o o t ( ) . a p p e n d C h i l d ( c l o n e ) ; } ; v a r X F o o = d o c u m e n t . r e g i s t e r E l e m e n t ( ' x - f o o ' , { p r o t o t y p e : p r o t o } ) ;
  77. None
  78. Reads customelements.io HTML5Rocks.com - Custom Elements

  79. Four technologies Custom Elements - Define and use new DOM

    elements HTML Templates - Inert chunks of clonable DOM Shadow DOM - Style & DOM encapsulation HTML Imports - Include/Reuse other HTML documents
  80. Four technologies HTML Imports - Include/Reuse other HTML documents HTML

    Templates - Inert chunks of clonable DOM Shadow DOM - Style & DOM encapsulation Custom Elements - Define and use new DOM elements
  81. HTML Imports

  82. #include for the web

  83. Why Imports? Different types of the web that can be

    loaded: < s c r i p t s r c > - For JavaScript < l i n k r e l = " s t y l e s h e e t " > - For Stylesheets < i m g > , < v i d e o > , < a u d i o > ...
  84. So what about HTML itself?

  85. Here are our options < i f r a m

    e > - super heavy, super restrictive, frustrating to script in/out A J A X - x h r . r e s p o n s e T y p e = " d o c u m e n t " , wtf? We need JS to load HTML? Hacks - embedded in strings, hidden as comments
  86. None
  87. HTML Imports to the rescue! Use < l i n

    k r e l = " i m p o r t " > to import external HTML documents. < l i n k r e l = " i m p o r t " h r e f = " p a t h / t o / i m p o r t . h t m l " >
  88. Turns this... < l i n k r e l

    = " s t y l e s h e e t " h r e f = " b o o t s t r a p . c s s " > < l i n k r e l = " s t y l e s h e e t " h r e f = " f o n t s . c s s " > < s c r i p t s r c = " j q u e r y . j s " > < / s c r i p t > < s c r i p t s r c = " b o o t s t r a p . j s " > < / s c r i p t > < s c r i p t s r c = " b o o t s t r a p - t o o l t i p . j s " > < / s c r i p t > < s c r i p t s r c = " b o o t s t r a p - d r o p d o w n . j s " > < / s c r i p t >
  89. ...into this. < l i n k r e l

    = " i m p o r t " h r e f = " b o o t s t r a p . h t m l " >
  90. Getting the content v a r c o n t

    e n t = d o c u m e n t . q u e r y S e l e c t o r ( ' l i n k [ r e l = " i m p o r t " ] ' ) . i m p o r t
  91. Cloning contents into main document v a r l i

    n k = d o c u m e n t . q u e r y S e l e c t o r ( ' l i n k [ r e l = " i m p o r t " ] ' ) ; v a r c o n t e n t = l i n k . i m p o r t ; v a r e l = c o n t e n t . q u e r y S e l e c t o r ( ' . w i d g e t ' ) ; d o c u m e n t . b o d y . a p p e n d C h i l d ( e l ) ; Content is inert until cloned into the DOM!
  92. None
  93. Reads Steve Souders - Scope, Security and Suggestions HTML5Rocks.com -

    #includes for the web
  94. Putting it all together... Demo

  95. None
  96. So what about Polymer and X-Tag?

  97. Both make the development of web components easier and better!

    FACT!
  98. None
  99. None
  100. Declaring elements with Polymer < p o l y m

    e r - e l e m e n t n a m e = " f o o - e l e m e n t " c o n s t r u c t o r = " F o o E l e m e n t " > < t e m p l a t e > < ! - - s h a d o w D O M h e r e - - > < p > T h i s i s a f o o - e l e m e n t . < / p > < / t e m p l a t e > < s c r i p t > < / s c r i p t > < / p o l y m e r - e l e m e n t > P o l y m e r ( { / / p r o p e r t i e s a n d m e t h o d s h e r e } ) ;
  101. Declaring elements with X-Tag v a r f r a

    g = x t a g . c r e a t e F r a g m e n t ( ' < p > T h i s i s a f o o - e l e m e n t . < / p > ' ) ; x t a g . r e g i s t e r ( ' f o o - e l e m e n t ' , { l i f e c y c l e : { c r e a t e d : f u n c t i o n ( ) { t h i s . a p p e n d C h i l d ( f r a g . c l o n e N o d e ( t r u e ) ) ; } } } ) ;
  102. X-Tag doesn't use Shadow DOM by default.

  103. Shadow DOM is optional in X-Tag x t a g

    . r e g i s t e r ( ' m y - e l e m e n t ' , { l i f e c y c l e : { c r e a t e d : f u n c t i o n ( ) { v a r t p l = d o c u m e n t . q u e r y S e l e c t o r ( ' # m y - t e m p l a t e ' ) ; v a r s h a d o w = t h i s . c r e a t e S h a d o w R o o t ( ) s h a d o w . a p p e n d C h i l d ( t p l . c o n t e n t . c l o n e N o d e ( t r u e ) ) ; } } } ) ;
  104. Reads Polymer vs. X-Tag - Here's the difference Inheritance and

    Composition in Polymer Sharing styles across Web Components with Polymer and core-style
  105. None
  106. THANK YOU. Pascal Precht @PascalPrecht