Slide 1

Slide 1 text

Godfrey Chan @chancancode Yehuda Katz @wycats

Slide 2

Slide 2 text

No content

Slide 3

Slide 3 text

No content

Slide 4

Slide 4 text

HTMLBars, how do I even? Freedom Freedom ! !

Slide 5

Slide 5 text

Three Handlebars templates walk into one of the newly-opened HTMLBars on the block. After having a few drinks, they each put down a $100 bill.

Slide 6

Slide 6 text

The renderer said to them, “sorry, no change” and left the DOM untouched.

Slide 7

Slide 7 text

HTML

Slide 8

Slide 8 text

No content

Slide 9

Slide 9 text

DHTML

Slide 10

Slide 10 text

Dynamic HTML

Slide 11

Slide 11 text

DOM APIs

Slide 12

Slide 12 text

var list = document.getElementById("todos"); for (var i = 0; i < todoItems.length; i++) { var item = todoItems[i]; var row = document.createElement("li"); var content = document.createTextNode(item.title); if (item.completed) { var del = document.createElement("del"); del.appendChild(content); row.appendChild(del); } else { row.appendChild(content); } list.appendChild(row); }

Slide 13

Slide 13 text

What happened to the HTML in the DHTML?

Slide 14

Slide 14 text

var list = document.getElementById("todos"); var html = ""; for (var i = 0; i < todoItems.length; i++) { var item = todoItems[i]; html += "
  • "; if (item.completed) { html += "" + item.title + ""; } else { html += item.title; } html += "
  • "; } list.innerHTML = html;

    Slide 15

    Slide 15 text

    var completedItem = "
  • {{title}}
  • "; var incompleteItem = "
  • {{title}}
  • "; var list = document.getElementById("todos"); var html = ""; for (var i = 0; i < todoItems.length; i++) { var item = todoItems[i]; var template = item.completed ? completedItem : incompleteItem; html += template.replace("{{title}}", item.title); } list.innerHTML = html;

    Slide 16

    Slide 16 text

    Data + HTML

    Slide 17

    Slide 17 text

    Data + HTML

    Slide 18

    Slide 18 text

    Templates

    Slide 19

    Slide 19 text

    No content

    Slide 20

    Slide 20 text

    } mustasche

    Slide 21

    Slide 21 text

    Logicless Templates

    Slide 22

    Slide 22 text

      {{#items}} {{#completed}}
    • {{name}}
    • {{/completed}} {{^completed}}
    • {{name}}
    • {{/completed}} {{/items}}

    Slide 23

    Slide 23 text

    No content

    Slide 24

    Slide 24 text

    Logicless Templates Semantic

    Slide 25

    Slide 25 text

      {{#each items as |item|}} {{#if item.completed}}
    • {{item.title}}
    • {{else}}
    • {{item.title}}
    • {{/if}} {{/each}}

    Slide 26

    Slide 26 text

    Extensibility

    Slide 27

    Slide 27 text

    Pre-compilation

    Slide 28

    Slide 28 text

    function(todoItems) { var html = ""; html += "
      "; for (var i = 0; i < todoItems.length; i++) { var item = todoItems[i]; html += "
    • "; if (item.completed) { html += "" + item.title + ""; } else { html += item.title; } html += "
    • "; } html += "
    "; return html; }
      {{#each items as |item|}} {{#if item.completed}}
    • {{item.title}}
    • {{else}}
    • {{item.title}}
    • {{/if}} {{/each}}
    Compiler todos.hbs todos.js

    Slide 29

    Slide 29 text

    No content

    Slide 30

    Slide 30 text

    No content

    Slide 31

    Slide 31 text

    Ember ❤ HTML+CSS

    Slide 32

    Slide 32 text

    Problem

    Slide 33

    Slide 33 text

    {{#if item.completed}}
  • {{item.title}}
  • {{else}}
  • {{item.title}}
  • {{/if}} { "completed": false, "title": "Finish HTMLBars Talk " } +
  • Finish HTMLBars Talk
  • Slide 34

    Slide 34 text

    {{#if item.completed}}
  • {{item.title}}
  • {{else}}
  • {{item.title}}
  • {{/if}} { "completed": true, "title": "Finish HTMLBars Talk " } +
  • Finish HTMLBars Talk
  • Slide 35

    Slide 35 text

    {{#if item.completed}}
  • {{item.title}}
  • {{else}}
  • {{item.title}}
  • {{/if}} { "completed": true, "title": "Finish HTMLBars Talk " } +
  • Finish HTMLBars Talk
  • Slide 36

    Slide 36 text

    How?

    Slide 37

    Slide 37 text

  • Finish HTMLBars Talk
  • {{#if item.completed}}
  • {{item.title}}
  • {{else}}
  • {{item.title}}
  • {{/if}}

    Slide 38

    Slide 38 text

    No content

    Slide 39

    Slide 39 text

    Slide 40

    Slide 40 text

    No content

    Slide 41

    Slide 41 text

    No content

    Slide 42

    Slide 42 text

    HTMLBars

    Slide 43

    Slide 43 text

    function(todoItems) { var list = document.createElement("ul"); for (var i = 0; i < todoItems.length; i++) { var item = todoItems[i]; var row = document.createElement("li"); var content = document.createTextNode(item.title); if (item.completed) { var del = document.createElement("del"); del.appendChild(content); row.appendChild(del); } else { row.appendChild(content); } list.appendChild(row); } return list; }
      {{#each items as |item|}} {{#if item.completed}}
    • {{item.title}}
    • {{else}}
    • {{item.title}}
    • {{/if}} {{/each}}
    Compiler todos.hbs todos.js

    Slide 44

    Slide 44 text

    AST Template Opcodes JavaScript Program HTML Tokens

    Slide 45

    Slide 45 text

    Metamorph Tags

    Slide 46

    Slide 46 text

    {{bind-attr}}

    Slide 47

    Slide 47 text

    XSS Protection

    Slide 48

    Slide 48 text

    AST Transformations

    Slide 49

    Slide 49 text

    Real HTML Parser

    Slide 50

    Slide 50 text

    SVG!

    Slide 51

    Slide 51 text

    Demo

    Slide 52

    Slide 52 text

    {{#each points as |point|}} {{/each}}

    Slide 53

    Slide 53 text

    Better Foundation

    Slide 54

    Slide 54 text

    No content

    Slide 55

    Slide 55 text

    No content

    Slide 56

    Slide 56 text

    Programming Model

    Slide 57

    Slide 57 text

    var TodoList = React.createClass({ render() { var items = []; this.props.todoItems.forEach(function (item) { if (item.completed) { items.push(
  • { item.title }
  • ); } else { items.push(
  • { item.title }
  • ); } }); return
      { items }
    ; } });

    Slide 58

    Slide 58 text

    Always Be Re-rendering™

    Slide 59

    Slide 59 text

    Diffing

    Slide 60

    Slide 60 text

    Virtual DOM

    Slide 61

    Slide 61 text

    O(n3) ?!

    Slide 62

    Slide 62 text

    Heuristics

    Slide 63

    Slide 63 text

    O(n)

    Slide 64

    Slide 64 text

    Incremental DOM

    Slide 65

    Slide 65 text

    function render(data) { elementOpen('ul'); todoItems.forEach(function (item) { elementOpen('li'); if (item.completed) { elementOpen('del'); } text(item.title); if (item.completed) { elementClose('del'); } elementClose('li'); }); elementClose('ul'); }

    Slide 66

    Slide 66 text

    Compilation Target

    Slide 67

    Slide 67 text

    “ASM.dom”

    Slide 68

    Slide 68 text

    Incremental Diffing

    Slide 69

    Slide 69 text

    No content

    Slide 70

    Slide 70 text

    Programming Model

    Slide 71

    Slide 71 text

    Write-only Algorithm

    Slide 72

    Slide 72 text

    {{post.title}}


    {{post.body}}

    Slide 73

    Slide 73 text

    {{post.title}}

    Slide 74

    Slide 74 text

    Oh hai!

    Slide 75

    Slide 75 text

    Virtual DOOM?

    Slide 76

    Slide 76 text

    Semantic Templates

    Slide 77

    Slide 77 text

    Compiler

    Slide 78

    Slide 78 text

    Render Nodes

    Slide 79

    Slide 79 text

    {{post.title}}


    {{post.body}}
    [ { node: [TextNode], statement: "{{post.title}}", lastValue: "Rails is omakase" }, { node: [TextNode], statement: "{{relative-time post.published_at}}", lastValue: "3 days ago" }, { node: [TextNode], statement: "{{post.body}}", lastValue: "There are lots of à la carte software..." } ]

    Slide 80

    Slide 80 text

    [ { node: [TextNode], statement: "{{post.title}}", lastValue: "Rails is omakase" } ]
    {{post.title}}

    Slide 81

    Slide 81 text

    [ // Nothing to diff! ]
    Oh hai!

    Slide 82

    Slide 82 text

    O(n*)

    Slide 83

    Slide 83 text

    O(n*) * n = Number of {{curlies}}, not DOM nodes

    Slide 84

    Slide 84 text

    No content

    Slide 85

    Slide 85 text

    No content

    Slide 86

    Slide 86 text

    Glimmer 2

    Slide 87

    Slide 87 text

    Runtime Optimizations

    Slide 88

    Slide 88 text

    Better Integration with Ember

    Slide 89

    Slide 89 text

    References

    Slide 90

    Slide 90 text

    {{post.title}}


    {{post.body}}
    [ { node: [TextNode], statement: "{{post.title}}", lastValue: "Rails is omakase" }, { node: [TextNode], statement: "{{relative-time post.published_at}}", lastValue: "3 days ago" }, { node: [TextNode], statement: "{{post.body}}", lastValue: "There are lots of à la carte software..." } ]

    Slide 91

    Slide 91 text

    {{post.title}}


    {{post.body}}
    [ { node: [TextNode], reference: { value(): …, isDirty(): … }, lastValue: "Rails is omakase" }, { node: [TextNode], reference: { value(): …, isDirty(): … }, lastValue: "3 days ago" }, { node: [TextNode], reference: { value(): …, isDirty(): … }, lastValue: "There are lots of à la carte software..." } ]

    Slide 92

    Slide 92 text

    Components

    Slide 93

    Slide 93 text

    No content

    Slide 94

    Slide 94 text

    One More Thing™

    Slide 95

    Slide 95 text

    TypeScript

    Slide 96

    Slide 96 text

    Godfrey Chan @chancancode Yehuda Katz @wycats