Accessing the composed DOM for a polymer element

I'm trying to access the browser-rendered DOM for a polymer element, without caring in the slightest which bits from from the "light" or "shadow" DOM as described in http://www.polymer-project.org/platform/shadow-dom.html, but I cannot find any API documentation on access functions that would let me do this.

I can see the .shadowRoots list that is on polymer elements, and I can see the regular .children property, but neither of these is particularly useful to get the content that is actually being shown on the page.

What is the correct way to get the DOM fragment that is currently visible in the browser? (or if someone knows where this is documented on the polymer site, I'd love to know that too. Google couldn't find it for me)

Upvotes: 1

Views: 350

Answers (2)

Sachin Hosmani
Sachin Hosmani

Reputation: 1742

Here is something I wrote for the same purpose:

  function getComposedDOMChildren (root) {
    if (root.shadowRoot) {
      root = root.shadowRoot;
    }
    var children = [];
    for (var i = 0; i < root.children.length; i++) {
      if (root.children[i].tagName === 'CONTENT') {
        children.push.apply(children, root.children[i].getDistributedNodes());
      } else if (root.children[i].tagName === 'SHADOW') {
        var shadowRoot = root;
        while (!shadowRoot.host) {
          shadowRoot = shadowRoot.parentNode;
        }
        children.push.apply(children, getComposedDOMChildren(shadowRoot.olderShadowRoot));
      } else {
        children.push(root.children[i]);
      }
    }
    return children;
  }

It returns an array with the children of the root as per the composed DOM. It works by going into the shadow root and replacing all <content> elements with what is actually rendered in them and recursing with the earlier shadow root when <shadow> elements are found.

Of course, to get the entire DOM tree, one has to iterate through the returned array and invoke getComposedDOMChildren on each element.

Something like:

function traverse (root) {
  var children = getComposedDOMChildren(root);
  for (var i = 0; i < children.length; i++) {
    traverse(children[i]);
  }
}

Please correct me if this isn't right.

Upvotes: 1

Scott Miles
Scott Miles

Reputation: 11027

The general idea is to only consider your virtual DOM (and even better, only consider local DOM [divide and conquer ftw]).

Therefore, today, there is no (easy) way to examine the composed DOM.

There will be such a way eventually for certain specialized uses, but I encourage you to try to adopt a mental model that allows you to avoid asking this question.

Upvotes: 1

Related Questions