Skip to content

Shadow DOM Design Constraints In Examples

Dimitri Glazkov edited this page Apr 20, 2015 · 40 revisions

See Design Refresher for discussion on objectives.

Simple Component

Calendar

basic-calendar

In HTML:

<basic-calendar-month></basic-calendar-month>

In JS:

var calendar = document.createElement("basic-calendar-month");

place.appendChild(calendar);

console.log(calendar.firstChild); // null

// suppose that #monthTable is an element inside of calendar
console.log(document.querySelector('#monthTable')); // null

document.body.addEventListener('click', function(evt) {
  console.log(evt.target.id); // should never return monthTable
});

document.body.addEventListener('mouseenter', function(evt) {
  console.log(evt.relatedTarget.id); // should never return monthTable
});

Constraints:

  • Implementation details are not accessible using standard DOM traversal/query APIs: Node, ParentNode, Element, etc.)
  • When traversing implementation details, you can't easily walk out.
  • Event target values do not leak implementation details.
  • Active element values do not leak implementation details.
  • You can style implementation details with scoped <style> element (Early tabs control example that illustrates the need for style scoping )
  • Style selectors in the document do not match inside of the implementation details
  • Style selectors in the implementation details do not match in the document.

Component With One Insertion Point

Basic Carousel

basic-carousel

In HTML:

<basic-carousel>
 <img id="image1" src="../basic-sequence/images/image1.jpg">
 <img src="../basic-sequence/images/image2.jpg">
 <img src="../basic-sequence/images/image3.jpg">
 <img src="../basic-sequence/images/image4.jpg">
 <img src="../basic-sequence/images/image5.jpg">
</basic-carousel>

In JS:

var carousel = document.querySelector('basic-carousel');

console.log(carousel.firstChild.id == 'image1'); // returns true

console.log(carousel.childElementCount);; // returns 5

carousel.appendChild(anotherImage); // does not break carousel

carousel.removeChild(anotherImage); // does not break carousel

console.log(document.activeElement); // never returns the elements, representing the next/previous buttons in the carousel.

Constraints:

  • Enable rendering the children of an element at an arbitrary place in the DOM sub-tree that represents the internal implementation details.
  • Element's children are are always its direct children according to standard DOM traversal/query APIs: Node, ParentNode, Element, etc.)
  • Similarly, no additional children from implementation details are detectable by these DOM APIs.
  • Mutating the list of children does not require any knowledge of the implementation details.

Component With Several Insertion Points

Polymer core-drawer-panel

Video Tutorial

Constraints:

  • Need a way to select which children go into which insertion point.
  • Let internal implementation details style children, distributed into the insertion point.
  • Let internal implementation known which child is distributed into which insertion point.
  • Distribution needs to happen before child style is computed

Nested Components

Example: my-editing-bar + my-zebra

Constraints:

  • The outside of implementation details is not always main document. Sometimes it's the implementation details of another component.
  • Another component's insertion point may end up being a child of the component.

Inherited Components

Basic Sequence

basic-sequence

A base class for slideshows, image carousels, and other cases where a sequence of items are shown. Could be used directly, but is primarily designed as an abstract component. For example, basic-sequence could be a base class of [basic-carousel](https://github.com/w3c/webcomponents/wiki/Shadow-DOM-Design-Constraints-In-Examples#basic-carousel).

Constraints:

  • implementation details of the base class are hidden from the super class.
  • super class should have a choice to compose the rendering of the base class in one of its insertion points.

Component Use In Real World

Accessibility Checker

Accessibility Developer Tools is a tool that allows developers to include Accessibility Audits into their developer workflow. The tool traverses the DOM tree of an app (using PhantomJS) and provides a report. To make analysis of the document complete, it actually needs to traverse the composed tree.

Constraints:

  • A way to occasionally cross style-scoping boundaries
  • A way to introspect shadow trees