| Index: sky/specs/dom.md | 
| diff --git a/sky/specs/dom.md b/sky/specs/dom.md | 
| index d1801ab0e2ab2690d0f531afb76beefe61a7d84d..34a5a159dc350e0270a97363a6ea963b3c86d22f 100644 | 
| --- a/sky/specs/dom.md | 
| +++ b/sky/specs/dom.md | 
| @@ -2,27 +2,21 @@ Sky DOM APIs | 
| ============ | 
|  | 
| ```dart | 
| -abstract class ChildNode { } | 
| +// ELEMENT TREE API | 
|  | 
| -abstract class Node extends EventTarget { | 
| -  external TreeScope get ownerScope; // O(1) // never null | 
| +abstract class ChildNode { | 
| +  @nonnull external TreeScope get ownerScope; // O(1) | 
|  | 
| external ParentNode get parentNode; // O(1) | 
| external Element get parentElement; // O(1) // if parentNode isn't an element, returns null | 
| external ChildNode get previousSibling; // O(1) | 
| external ChildNode get nextSibling; // O(1) | 
|  | 
| -  @override | 
| -  external List</*@nonnull*/ EventTarget> getEventDispatchChain(); // O(N) in number of ancestors across shadow trees | 
| -  // implements EventTarget.getEventDispatchChain() | 
| -  // returns the event dispatch chain (including handling shadow trees) | 
| - | 
| // the following all throw if parentNode is null | 
| -  external void insertBefore(List</*@nonnull*/ ChildNode> nodes); // O(N) in number of arguments plus all their descendants | 
| -  external void insertAfter(List</*@nonnull*/ ChildNode> nodes); // O(N) in number of arguments plus all their descendants | 
| -  external void replaceWith(List</*@nonnull*/ ChildNode> nodes); // O(N) in number of descendants plus arguments plus all their descendants | 
| +  external void insertBefore(@nonnull List</*@nonnull*/ ChildNode> nodes); // O(N) in number of arguments plus all their descendants | 
| +  external void insertAfter(@nonnull List</*@nonnull*/ ChildNode> nodes); // O(N) in number of arguments plus all their descendants | 
| +  external void replaceWith(@nonnull List</*@nonnull*/ ChildNode> nodes); // O(N) in number of descendants plus arguments plus all their descendants | 
| external void remove(); // O(N) in number of descendants | 
| -  external Node cloneNode({bool deep: false}); // O(1) if deep=false, O(N) in the number of descendants if deep=true | 
|  | 
| // called when parentNode changes | 
| external void parentChangeCallback(ParentNode oldParent, ParentNode newParent, ChildNode previousSibling, ChildNode nextSibling); // O(N) in descendants | 
| @@ -32,6 +26,15 @@ abstract class Node extends EventTarget { | 
|  | 
| external List<ContentElement> getDestinationInsertionPoints(); // O(N) in number of insertion points the node is in | 
| // returns the <content> elements to which this element was distributed | 
| +} | 
| + | 
| +abstract class Node extends EventTarget { | 
| +  @override | 
| +  external List</*@nonnull*/ EventTarget> getEventDispatchChain(); // O(N) in number of ancestors across shadow trees | 
| +  // implements EventTarget.getEventDispatchChain() | 
| +  // returns the event dispatch chain (including handling shadow trees) | 
| + | 
| +  external Node cloneNode({bool deep: false}); // O(1) if deep=false, O(N) in the number of descendants if deep=true | 
|  | 
| external ElementStyleDeclarationList get style; // O(1) | 
| // for nodes that aren't reachable from the Application Document, returns null | 
| @@ -44,7 +47,7 @@ abstract class Node extends EventTarget { | 
| // this will be null until the first time it is rendered | 
| // it becomes null again when it is taken out of the rendering (see style.md) | 
|  | 
| -  LayoutManagerConstructor getLayoutManager(); // O(1) | 
| +  Type getLayoutManager() => null; // O(1) | 
|  | 
| void resetLayoutManager() { // O(1) | 
| if (renderNode != null) { | 
| @@ -59,13 +62,13 @@ abstract class ParentNode extends Node { | 
| external ChildNode get lastChild; // O(1) | 
|  | 
| // Returns a new List every time. | 
| -  external List<ChildNode> getChildNodes(); // O(N) in number of child nodes | 
| +  external List</*nonnull*/ ChildNode> getChildNodes(); // O(N) in number of child nodes | 
| external List<Element> getChildElements(); // O(N) in number of child nodes | 
| // TODO(ianh): might not be necessary if we have the parser drop unnecessary whitespace text nodes | 
|  | 
| -  external void append(List<ChildNode> nodes); // O(N) in number of arguments plus all their descendants | 
| -  external void prepend(List<ChildNode> nodes); // O(N) in number of arguments plus all their descendants | 
| -  external void replaceChildrenWith(List<ChildNode> nodes); // O(N) in number of descendants plus arguments plus all their descendants | 
| +  external void append(@nonnull List</*nonnull*/ ChildNode> nodes); // O(N) in number of arguments plus all their descendants | 
| +  external void prepend(@nonnull List</*nonnull*/ ChildNode> nodes); // O(N) in number of arguments plus all their descendants | 
| +  external void replaceChildrenWith(@nonnull List</*nonnull*/ ChildNode> nodes); // O(N) in number of descendants plus arguments plus all their descendants | 
| } | 
|  | 
| class Attr { | 
| @@ -74,16 +77,32 @@ class Attr { | 
| final String value; // O(1) | 
| } | 
|  | 
| -abstract class Element extends ParentNode { | 
| -  final String tagName; // O(1) | 
| +// @tagname annotation for registering elements | 
| +// only useful when placed on classes that inherit from Element | 
| +class tagname { | 
| +  const tagname(this.value); | 
| +  @nonnull final String value; | 
| +} | 
| + | 
| +abstract class FindRoot { } | 
| + | 
| +abstract class Element extends ParentNode with ChildNode implements FindRoot { | 
| +  Element({Map</*@nonnull*/ String, /*@nonnull*/ String> attributes: null, | 
| +           List</*nonnull*/ ChildNode> nodes: null}); // O(M+N), M = number of attributes, N = number of nodes plus all their descendants | 
|  | 
| -  external bool hasAttribute(@nonnull String name); // O(N) in number of attributes | 
| -  external String getAttribute(@nonnull String name); // O(N) in number of attributes | 
| +  @nonnull String get tagName { // O(N) in number of annotations on the class | 
| +    // throws a StateError if the class doesn't have an @tagname annotation | 
| +    var tagnameClass = reflectClass(tagname); | 
| +    return (reflectClass(this.runtimeType).metadata.singleWhere((mirror) => mirror.type == tagnameClass).reflectee as tagname).value; | 
| +  } | 
| + | 
| +  @nonnull external bool hasAttribute(@nonnull String name); // O(N) in number of attributes | 
| +  @nonnull external String getAttribute(@nonnull String name); // O(N) in number of attributes | 
| external void setAttribute(@nonnull String name, [@nonnull String value = '']); // O(N) in number of attributes | 
| external void removeAttribute(@nonnull String name); // O(N) in number of attributes | 
|  | 
| // Returns a new Array and new Attr instances every time. | 
| -  List<Attr> getAttributes(); // O(N) in number of attributes | 
| +  @nonnull external List<Attr> getAttributes(); // O(N) in number of attributes | 
|  | 
| external ShadowRoot get shadowRoot; // O(1) | 
| // returns the shadow root | 
| @@ -96,29 +115,27 @@ abstract class Element extends ParentNode { | 
| // TODO(ianh): does a node ever need to know when it's been redistributed? | 
|  | 
| @override | 
| -  LayoutManagerConstructor getLayoutManager() { // O(1) | 
| +  Type getLayoutManager() { // O(1) | 
| if (renderNode) | 
| return renderNode.getProperty(phDisplay); | 
| return super.getLayoutManager(); | 
| } | 
| } | 
|  | 
| -class Text extends Node { | 
| -  external Text([String value = '']); // O(1) | 
| -  // throws if value is null | 
| +class Text extends Node with ChildNode { | 
| +  external Text([@nonnull String value = '']); // O(1) | 
|  | 
| -  external String get value; // O(1) | 
| +  @nonnull external String get value; // O(1) | 
| +  external void set (@nonnull String value); // O(1) | 
|  | 
| -  void valueChangeCallback(String oldValue, String newValue) { } | 
| +  void valueChangeCallback(@nonnull String oldValue, @nonnull String newValue) { } | 
|  | 
| @override | 
| -  LayoutManagerConstructor getLayoutManager() { // O(1) | 
| -    return TextLayoutManager; | 
| -  } | 
| +  Type getLayoutManager() => TextLayoutManager; // O(1) | 
| } | 
|  | 
| -class DocumentFragment extends ParentNode { | 
| -  DocumentFragment([List<ChildNode> nodes = null]); // O(N) in number of arguments plus all their descendants | 
| +class DocumentFragment extends ParentNode implements FindRoot { | 
| +  DocumentFragment([List</*nonnull*/ ChildNode> nodes = null]); // O(N) in number of arguments plus all their descendants | 
| } | 
|  | 
| abstract class TreeScope extends ParentNode { | 
| @@ -129,7 +146,7 @@ abstract class TreeScope extends ParentNode { | 
| // throws if id is null | 
| } | 
|  | 
| -class ShadowRoot extends TreeScope { | 
| +class ShadowRoot extends TreeScope implements FindRoot { | 
| ShadowRoot([this._host]); // O(1) | 
| // note that there is no way in the API to use a newly created ShadowRoot currently | 
|  | 
| @@ -137,180 +154,126 @@ class ShadowRoot extends TreeScope { | 
| Element get host => _host; // O(1) | 
| } | 
|  | 
| -// DARTIFICATION INCOMPLETE PAST THIS POINT | 
| - | 
| -class Document extends TreeScope { | 
| -  constructor (ChildArguments... nodes); // O(N) in number of arguments plus all their descendants | 
| +class Document extends TreeScope implements FindRoot { | 
| +  external Document ([List</*@nonnull*/ ChildNode> nodes = null]); // O(N) in number of arguments plus all their descendants | 
| } | 
|  | 
| class ApplicationDocument extends Document { | 
| -  constructor (ChildArguments... nodes); // O(N) in number of /nodes/ arguments plus all their descendants | 
| +  external ApplicationDocument ([List</*@nonnull*/ ChildNode> nodes = null]); // O(N) in number of /nodes/ arguments plus all their descendants | 
|  | 
| -  virtual LayoutManagerConstructor getLayoutManager(); // O(1) | 
| -    // returns sky.rootLayoutManager; | 
| +  @override | 
| +  Type getLayoutManager() => rootLayoutManager; // O(1) | 
| } | 
|  | 
| -attribute LayoutManagerConstructor rootLayoutManager; // O(1) | 
| -  // initially configured to return BlockLayoutManager | 
| +Type rootLayoutManager = BlockLayoutManager; // O(1) | 
|  | 
|  | 
| // BUILT-IN ELEMENTS | 
|  | 
| +@tagname('import') | 
| class ImportElement extends Element { | 
| -  constructor (Dictionary<String> attributes, ChildArguments... nodes); // O(M+N), M = number of attributes, N = number of nodes plus all their descendants | 
| -  constructor (ChildArguments... nodes); // shorthand | 
| -  constructor (Dictionary<String> attributes); // shorthand | 
| -  constructor (); // shorthand | 
| -  constructor attribute String tagName; // O(1) // "import" | 
| -  constructor attribute Boolean shadow; // O(1) // false | 
| - | 
| -  virtual LayoutManagerConstructor getLayoutManager(); // O(1) | 
| -    // returns null | 
| +  //XXX ImportElement = Element; | 
| + | 
| +  @override | 
| +  Type getLayoutManager() => null; // O(1) | 
| } | 
| + | 
| +@tagname('template') | 
| class TemplateElement extends Element { | 
| -  constructor (Dictionary<String> attributes, ChildArguments... nodes); // O(M+N), M = number of attributes, N = number of nodes plus all their descendants | 
| -  constructor (ChildArguments... nodes); // shorthand | 
| -  constructor (Dictionary<String> attributes); // shorthand | 
| -  constructor (); // shorthand | 
| -  constructor attribute String tagName; // O(1) // "template" | 
| -  constructor attribute Boolean shadow; // O(1) // false | 
| - | 
| -  readonly attribute DocumentFragment content; // O(1) | 
| -  virtual LayoutManagerConstructor getLayoutManager(); // O(1) | 
| -    // returns null | 
| +  //XXX TemplateElement = Element; | 
| + | 
| +  // TODO(ianh): convert <template> to using a token stream instead of a DocumentFragment | 
| + | 
| +  @nonnull external DocumentFragment get content; // O(1) | 
| + | 
| +  @override | 
| +  Type getLayoutManager() => null; // O(1) | 
| } | 
| + | 
| +@tagname('script') | 
| class ScriptElement extends Element { | 
| -  constructor (Dictionary<String> attributes, ChildArguments... nodes); // O(M+N), M = number of attributes, N = number of nodes plus all their descendants | 
| -  constructor (ChildArguments... nodes); // shorthand | 
| -  constructor (Dictionary<String> attributes); // shorthand | 
| -  constructor (); // shorthand | 
| -  constructor attribute String tagName; // O(1) // "script" | 
| -  constructor attribute Boolean shadow; // O(1) // false | 
| - | 
| -  virtual LayoutManagerConstructor getLayoutManager(); // O(1) | 
| -    // returns null | 
| +  //XXX ScriptElement = Element; | 
| + | 
| +  @override | 
| +  Type getLayoutManager() => null; // O(1) | 
| } | 
| + | 
| +@tagname('style') | 
| class StyleElement extends Element { | 
| -  constructor (Dictionary<String> attributes, ChildArguments... nodes); // O(M+N), M = number of attributes, N = number of nodes plus all their descendants | 
| -  constructor (ChildArguments... nodes); // shorthand | 
| -  constructor (Dictionary<String> attributes); // shorthand | 
| -  constructor (); // shorthand | 
| -  constructor attribute String tagName; // O(1) // "style" | 
| -  constructor attribute Boolean shadow; // O(1) // false | 
| - | 
| -  Array<Rule> getRules(); // O(N) in rules | 
| -  virtual LayoutManagerConstructor getLayoutManager(); // O(1) | 
| -    // returns null | 
| +  //XXX StyleElement = Element; | 
| + | 
| +  @nonnull external List</*@nonnull*/ Rule> getRules(); // O(N) in rules | 
| + | 
| +  @override | 
| +  Type getLayoutManager() => null; // O(1) | 
| } | 
| + | 
| +@tagname('content') | 
| class ContentElement extends Element { | 
| -  constructor (Dictionary<String> attributes, ChildArguments... nodes); // O(M+N), M = number of attributes, N = number of nodes plus all their descendants | 
| -  constructor (ChildArguments... nodes); // shorthand | 
| -  constructor (Dictionary<String> attributes); // shorthand | 
| -  constructor (); // shorthand | 
| -  constructor attribute String tagName; // O(1) // "content" | 
| -  constructor attribute Boolean shadow; // O(1) // false | 
| - | 
| -  Array<Node> getDistributedNodes(); // O(N) in distributed nodes | 
| -  virtual LayoutManagerConstructor getLayoutManager(); // O(1) | 
| -    // returns null | 
| +  //XXX ContentElement = Element; | 
| + | 
| +  @nonnull external List</*@nonnull*/ Node> getDistributedNodes(); // O(N) in distributed nodes | 
| + | 
| +  @override | 
| +  Type getLayoutManager() => null; // O(1) | 
| } | 
| + | 
| +@tagname('img') | 
| class ImgElement extends Element { | 
| -  constructor (Dictionary<String> attributes, ChildArguments... nodes); // O(M+N), M = number of attributes, N = number of nodes plus all their descendants | 
| -  constructor (ChildArguments... nodes); // shorthand | 
| -  constructor (Dictionary<String> attributes); // shorthand | 
| -  constructor (); // shorthand | 
| -  constructor attribute String tagName; // O(1) // "img" | 
| -  constructor attribute Boolean shadow; // O(1) // false | 
| - | 
| -  virtual LayoutManagerConstructor getLayoutManager(); // O(1) | 
| -    // returns ImgElementLayoutManager | 
| +  //XXX ImgElement = Element; | 
| + | 
| +  @override | 
| +  Type getLayoutManager() => ImgElementLayoutManager; // O(1) | 
| } | 
| + | 
| +@tagname('div') | 
| class DivElement extends Element { | 
| -  constructor (Dictionary<String> attributes, ChildArguments... nodes); // O(M+N), M = number of attributes, N = number of nodes plus all their descendants | 
| -  constructor (ChildArguments... nodes); // shorthand | 
| -  constructor (Dictionary<String> attributes); // shorthand | 
| -  constructor (); // shorthand | 
| -  constructor attribute String tagName; // O(1) // "div" | 
| -  constructor attribute Boolean shadow; // O(1) // false | 
| +  //XXX DivElement = Element; | 
| } | 
| + | 
| +@tagname('span') | 
| class SpanElement extends Element { | 
| -  constructor (Dictionary<String> attributes, ChildArguments... nodes); // O(M+N), M = number of attributes, N = number of nodes plus all their descendants | 
| -  constructor (ChildArguments... nodes); // shorthand | 
| -  constructor (Dictionary<String> attributes); // shorthand | 
| -  constructor (); // shorthand | 
| -  constructor attribute String tagName; // O(1) // "span" | 
| -  constructor attribute Boolean shadow; // O(1) // false | 
| +  //XXX SpanElement = Element; | 
| } | 
| + | 
| +@tagname('iframe') | 
| class IframeElement extends Element { | 
| -  constructor (Dictionary<String> attributes, ChildArguments... nodes); // O(M+N), M = number of attributes, N = number of nodes plus all their descendants | 
| -  constructor (ChildArguments... nodes); // shorthand | 
| -  constructor (Dictionary<String> attributes); // shorthand | 
| -  constructor (); // shorthand | 
| -  constructor attribute String tagName; // O(1) // "iframe" | 
| -  constructor attribute Boolean shadow; // O(1) // false | 
| - | 
| -  virtual LayoutManagerConstructor getLayoutManager(); // O(1) | 
| -    // returns IframeElementLayoutManager | 
| +  //XXX IframeElement = Element; | 
| + | 
| +  @override | 
| +  Type getLayoutManager() => IframeElementLayoutManager; // O(1) | 
| } | 
| + | 
| +@tagname('t') | 
| class TElement extends Element { | 
| -  constructor (Dictionary<String> attributes, ChildArguments... nodes); // O(M+N), M = number of attributes, N = number of nodes plus all their descendants | 
| -  constructor (ChildArguments... nodes); // shorthand | 
| -  constructor (Dictionary<String> attributes); // shorthand | 
| -  constructor (); // shorthand | 
| -  constructor attribute String tagName; // O(1) // "t" | 
| -  constructor attribute Boolean shadow; // O(1) // false | 
| +  //XXX TElement = Element; | 
| } | 
| + | 
| +@tagname('a') | 
| class AElement extends Element { | 
| -  constructor (Dictionary<String> attributes, ChildArguments... nodes); // O(M+N), M = number of attributes, N = number of nodes plus all their descendants | 
| -  constructor (ChildArguments... nodes); // shorthand | 
| -  constructor (Dictionary<String> attributes); // shorthand | 
| -  constructor (); // shorthand | 
| -  constructor attribute String tagName; // O(1) // "a" | 
| -  constructor attribute Boolean shadow; // O(1) // false | 
| +  //XXX AElement = Element; | 
| } | 
| + | 
| +@tagname('title') | 
| class TitleElement extends Element { | 
| -  constructor (Dictionary<String> attributes, ChildArguments... nodes); // O(M+N), M = number of attributes, N = number of nodes plus all their descendants | 
| -  constructor (ChildArguments... nodes); // shorthand | 
| -  constructor (Dictionary<String> attributes); // shorthand | 
| -  constructor (); // shorthand | 
| -  constructor attribute String tagName; // O(1) // "title" | 
| -  constructor attribute Boolean shadow; // O(1) // false | 
| - | 
| -  virtual LayoutManagerConstructor getLayoutManager(); // O(1) | 
| -    // returns null | 
| -} | 
| -class ErrorElement extends Element { | 
| -  constructor (Dictionary<String> attributes, ChildArguments... nodes); // O(M+N), M = number of attributes, N = number of nodes plus all their descendants | 
| -  constructor (ChildArguments... nodes); // shorthand | 
| -  constructor (Dictionary<String> attributes); // shorthand | 
| -  constructor (); // shorthand | 
| -  constructor attribute String tagName; // O(1) // "error" | 
| -  constructor attribute Boolean shadow; // O(1) // false | 
| - | 
| -  virtual LayoutManagerConstructor getLayoutManager(); // O(1) | 
| -    // returns ErrorElementLayoutManager | 
| +  //XXX TitleElement = Element; | 
| + | 
| +  @override | 
| +  Type getLayoutManager() => null; // O(1) | 
| } | 
|  | 
| -interface ElementConstructor { | 
| -  constructor (Dictionary<String> attributes, ChildArguments... nodes); // O(M+N), M = number of attributes, N = number of nodes plus all their descendants | 
| -  constructor (ChildArguments... nodes); // shorthand | 
| -  constructor (Dictionary<String> attributes); // shorthand | 
| -  constructor (); // shorthand | 
| +class ErrorElement extends Element { | 
| +  ErrorElement._create(); | 
|  | 
| -  constructor attribute String tagName; | 
| -  constructor attribute Boolean shadow; | 
| +  @override | 
| +  Type getLayoutManager() => ErrorElementLayoutManager; // O(1) | 
| } | 
|  | 
| class SelectorQuery { | 
| -  constructor (String selector); // O(F()) where F() is the complexity of the selector | 
| - | 
| -  Boolean matches(Element element); // O(F()) | 
| -  Element? find(Element root); // O(N*F())+O(M) where N is the number of descendants and M the average depth of the tree | 
| -  Element? find(DocumentFragment root); // O(N*F())+O(M) where N is the number of descendants and M the average depth of the tree | 
| -  Element? find(TreeScope root); // O(N*F()) where N is the number of descendants | 
| -  Array<Element> findAll(Element root); // O(N*F())+O(N*M) where N is the number of descendants and M the average depth of the tree | 
| -  Array<Element> findAll(DocumentFragment root); // O(N*F())+O(N*M) where N is the number of descendants and M the average depth of the tree | 
| -  Array<Element> findAll(TreeScope root); // O(N*F()) where N is the number of descendants | 
| +  external SelectorQuery(@nonnull String selector); // O(F()) where F() is the complexity of the selector | 
|  | 
| +  @nonnull external bool matches(@nonnull Element element); // O(F()) | 
| +  external Element find(@nonnull FindRoot root); // O(N*F())+O(M) where N is the number of descendants and M the average depth of the tree | 
| +  @nonnull external List</*@nonnull*/ Element> findAll(FindRoot root); // O(N*F())+O(N*M) where N is the number of descendants and M the average depth of the tree | 
| } | 
| ``` | 
|  |