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

The Giving Tree

The Giving Tree

DOM Talk given at EmpireJS 2015

Mark Wunsch

April 27, 2015
Tweet

More Decks by Mark Wunsch

Other Decks in Programming

Transcript

  1. 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.
  2. 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).”
  3. $

  4. 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).
  5. var walker = document.createTreeWalker( document.body, NodeFilter.SHOW_ELEMENT, function (n) { return

    NodeFilter.FILTER_ACCEPT; }); do { doSomething(walker.currentNode); } while (walker.nextNode());
  6. 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
  7. 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
  8. 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/
  9. 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/
  10. <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
  11. 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]); } }
  12. 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
  13. 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
  14. 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 }
  15. $

  16. 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
  17. ^D