Specs: finishing initial dartification of dom.md

Review URL: https://codereview.chromium.org/909613002
diff --git a/sky/specs/dom.md b/sky/specs/dom.md
index d1801ab..34a5a15 100644
--- a/sky/specs/dom.md
+++ b/sky/specs/dom.md
@@ -2,27 +2,21 @@
 ============
 
 ```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 @@
 
   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 @@
   // 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 @@
   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 @@
   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;
+}
 
-  external bool hasAttribute(@nonnull String name); // O(N) in number of attributes
-  external String getAttribute(@nonnull String name); // O(N) in number of attributes
+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
+
+  @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 @@
   // 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 @@
   // 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 @@
   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
+  //XXX ImportElement = Element;
 
-  virtual LayoutManagerConstructor getLayoutManager(); // O(1)
-    // returns null
+  @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
+  //XXX TemplateElement = Element;
 
-  readonly attribute DocumentFragment content; // O(1)
-  virtual LayoutManagerConstructor getLayoutManager(); // O(1)
-    // returns null
+  // 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
+  //XXX ScriptElement = Element;
 
-  virtual LayoutManagerConstructor getLayoutManager(); // O(1)
-    // returns null
+  @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
+  //XXX StyleElement = Element;
 
-  Array<Rule> getRules(); // O(N) in rules
-  virtual LayoutManagerConstructor getLayoutManager(); // O(1)
-    // returns null
+  @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
+  //XXX ContentElement = Element;
 
-  Array<Node> getDistributedNodes(); // O(N) in distributed nodes
-  virtual LayoutManagerConstructor getLayoutManager(); // O(1)
-    // returns null
+  @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
+  //XXX ImgElement = Element;
 
-  virtual LayoutManagerConstructor getLayoutManager(); // O(1)
-    // returns ImgElementLayoutManager
+  @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
+  //XXX IframeElement = Element;
 
-  virtual LayoutManagerConstructor getLayoutManager(); // O(1)
-    // returns IframeElementLayoutManager
+  @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
+  //XXX TitleElement = Element;
 
-  virtual LayoutManagerConstructor getLayoutManager(); // O(1)
-    // returns null
+  @override
+  Type getLayoutManager() => null; // O(1)
 }
+
 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
+  ErrorElement._create();
 
-  virtual LayoutManagerConstructor getLayoutManager(); // O(1)
-    // returns ErrorElementLayoutManager
-}
-
-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
-
-  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
+  external SelectorQuery(@nonnull 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
-
+  @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
 }
 ```