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

The Giving Tree

The Giving Tree

DOM Talk given at EmpireJS 2015

63e2f6b0de6ae817af2e185b82aa05c2?s=128

Mark Wunsch

April 27, 2015
Tweet

Transcript

  1. The Giving Tree @markwunsch

  2. None
  3. The Ash Yggdrasil Friedrich Wilhelm Heine, 1886

  4. Document Object Model

  5. Document Object Model (DOM) Level 1 Specification http://www.w3.org/TR/REC-DOM-Level-1/ In the

    DOM, documents have a logical structure which is very much like a tree; to be more precise, it is like a “forest” or “grove”, which can contain more than one tree. However, the DOM does not specify that documents must be implemented as a tree or a grove, nor does it specify how the relationships among objects be implemented.
  6. What the Document Object Model is not • “…it does

    not implement all of ‘Dynamic HTML’.” • “The Document Object Model is not a binary specification.” • “The Document Object Model is not a way of persisting objects to XML or HTML.” • “The Document Object Model is not a set of data structures, it is an object model that specifies interfaces.” • “The Document Object Model does not define ‘the true inner semantics’ of XML or HTML.” • “The Document Object Model…is not a competitor to the Component Object Model (COM).”
  7. $

  8. Closer to the METAL

  9. window.document

  10. TreeWalker

  11. document.createTreeWalker()

  12. createTreeWalker(root, whatToShow, filter) root, whatToShow, filter

  13. Document Object Model (DOM) Level 2 Traversal and Range Specification

    http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ TreeWalker objects are used to navigate a document tree or subtree using the view of the document defined by their whatToShow flags and filter (if any).
  14. depth first pre-order

  15. HEADER HGROUP H2 H1 SECTION FOOTER DIV BODY 1 2

    3 4 5 6 7 8
  16. var walker = document.createTreeWalker( document.body, NodeFilter.SHOW_ELEMENT, function (n) { return

    NodeFilter.FILTER_ACCEPT; }); do { doSomething(walker.currentNode); } while (walker.nextNode());
  17. function getLegitTextNodes(el, f) { var blacklist = [‘SCRIPT’,‘OPTION’,‘TEXTAREA’], filter =

    function (node) { var parentName = node.parentElement.nodeName.toUpperCase(); if (blacklist.indexOf(parentName) >= 0) { return NodeFilter.FILTER_REJECT; } if (!node.NodeValue.trim().length) { return NodeFilter.FILTER_SKIP; } return NodeFilter.FILTER_ACCEPT; }, walker = document.createTreeWalker( el, NodeFilter.SHOW_TEXT, filter); while(walker.nextNode()) f(walker.currentNode); } https://gist.github.com/mwunsch/4710561
  18. console.log("digraph El {"); do { var parentEl = walker.currentNode.parentElement; if

    (parentEl) { console.log(“\t\""+ vizLabel(parentEl)+”\"->\""+ vizLabel(walker.currentNode)+ "\";"); } else { console.log(“\t\""+ vizLabel(walker.currentNode)+ "\";"); } } while (walker.nextNode()); console.log("}"); https://gist.github.com/mwunsch/6b538a0352cae834457a
  19. $ phantomjs viz.js http://2015.empirejs.org/ | dot -Tpng empire.png https://gist.github.com/mwunsch/6b538a0352cae834457a

  20. https://gist.github.com/mwunsch/6b538a0352cae834457a

  21. DocumentFragment

  22. document.createDocumentFragment()

  23. DocumentFragment is a “lightweight” or “minimal” Document object. It is

    very common to want to be able to extract a portion of a document’s tree or to create a new fragment of a document. Document Object Model (DOM) Level 1 Specification http://www.w3.org/TR/REC-DOM-Level-1/
  24. When a DocumentFragment is inserted into a Document…the children of

    the DocumentFragment and not the DocumentFragment itself are inserted into the Node. Document Object Model (DOM) Level 1 Specification http://www.w3.org/TR/REC-DOM-Level-1/
  25. <div class="grid-thumb" id="grid-thumb-viv9"> <a class="item-link" href="…"> <div class="grid-thumb-images"> <img class="current"

    alt="…" width="270" height="405" src="…"> </div> <div class="grid-thumb-info"> <div class="thumb-designer upper">Vivienne…</div> <div class="thumb-name subtitle">Julia Dress</div> <div class="thumb-price thumb-price-default subtitle-strong"> $275 rental </div> <div class="thumb-retail subtitle"> $1739 retail </div> </div> </a> <div class="favorite-wrapper heart-wrapper"> <div class="thumb-heart" title="Add to Favorites"></div> </div> </div> https://gist.github.com/mwunsch/29bca83eaf7649873900
  26. var el = document.getElementById("grid-thumb-viv9"), frag = document.createDocumentFragment(), walker = walkerFactory(document.body),

    fragWalker = walkerFactory(frag), diffs = [], diff; https://gist.github.com/mwunsch/29bca83eaf7649873900 frag.appendChild(el.cloneNode(true)); frag.querySelector(".thumb-price").textContent = "$285 rental"; while (walker.nextNode() && fragWalker.nextNode()) { if (!walker.currentNode.isEqualNode(fragWalker.currentNode)) { diffs.push([walker.currentNode, fragWalker.currentNode]); } }
  27. do { diff = diffs.pop(); if (diff[0].isEqualNode(diff[1])) break; if (diff[0].parentNode)

    { diff[0].parentNode.replaceChild( diff[1].cloneNode(true), diff[0]); } } while (diffs.length) https://gist.github.com/mwunsch/29bca83eaf7649873900
  28. do { diff = diffs.pop() if (diff[0].isEqualNode(diff[1])) break if (diff[0].parentNode)

    { diff[0].parentNode.replaceChild( diff[1].cloneNode(true) diff[0]) } } while (diffs.length) https://gist.github.com/mwunsch/29bca83eaf7649873900 CO NSIDERED HARM FUL
  29. FUNCTIONAL PEARL GÉRARD HUET INRIA Rocquencourt, France The Zipper

  30. HEADER HGROUP H2 H1 SECTION FOOTER DIV BODY

  31. HEADER HGROUP H1 SECTION FOOTER DIV BODY H2

  32. HEADER HGROUP H1 SECTION FOOTER DIV BODY H2

  33. var el = document.getElementById("grid-thumb-viv9"), loc = new Zipper(el); var designer

    = location .goDown() .goDown() .goRight() .goDown(); https://gist.github.com/mwunsch/d46a4ebde8567e2e5102 >> Zipper { tree: div.thumb-designer, crumb: Breadcrumb }
  34. $

  35. Further Reading • DOM Living Standard: https://dom.spec.whatwg.org/ • Range: https://developer.mozilla.org/en-US/docs/Web/API/Range

    • HTMLBars: https://github.com/tildeio/htmlbars • [WIP] Implement Glimmer Engine: https://github.com/emberjs/ ember.js/pull/10501 • React Reconciliation: https://facebook.github.io/react/docs/ reconciliation.html • Lee Byron, Immutable Data and React: https://youtu.be/I7IdS-PbEgI
  36. Dante and Virgil Penetrating the Forest William Blake, 1824–27

  37. ^D