Sky DOM APIs
============

```javascript

// DOM

typedef ChildNode (Element or Text);
typedef ChildArgument (Element or Text or String);

abstract class Node : EventTarget { // implemented in C++
  readonly attribute TreeScope? ownerScope; // O(1)

  readonly attribute ParentNode? parentNode; // O(1)
  readonly attribute Element? parentElement; // O(1) // if parentNode isn't an element, returns null
  readonly attribute ChildNode? previousSibling; // O(1)
  readonly attribute ChildNode? nextSibling; // O(1)

  virtual Array<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
  void insertBefore(ChildArgument... nodes); // O(N) in number of arguments plus all their descendants
  void insertAfter(ChildArgument... nodes); // O(N) in number of arguments plus all their descendants
  void replaceWith(ChildArgument... nodes); // O(N) in number of descendants plus arguments plus all their descendants
  void remove(); // O(N) in number of descendants
  Node cloneNode(Boolean deep = false); // O(1) if deep=false, O(N) in the number of descendants if deep=true

  // called when parentNode changes
  virtual void parentChangeCallback(ParentNode? oldParent, ParentNode? newParent, ChildNode? previousSibling, ChildNode? nextSibling); // O(N) in descendants (calls attached/detached)
  virtual void attachedCallback(); // noop
  virtual void detachedCallback(); // noop

  Array<ContentElement> getDestinationInsertionPoints(); // O(N) in number of insertion points the node is in
    // returns the <content> elements to which this element was distributed

  readonly attribute ElementStyleDeclarationList? style; // O(1)
    // for nodes that aren't reachable from the Application Document, returns null
    // (so in particular orphaned subtrees and nodes in module documents don't have one)
    //  -- should be updated when the node's parent chain changes (same time as, e.g.,
    //     the id hashtable is updated)
    // also always returns null for ContentElement elements and ShadowRoot nodes
  readonly attribute RenderNode? renderNode; // O(1)
    // 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)
  abstract virtual LayoutManagerConstructor getLayoutManager(); // O(1)
  void resetLayoutManager(); // O(1)
    // if renderNode is non-null:
    //   sets renderNode.layoutManager to null
    //   sets renderNode.needsManager to true
}

abstract class ParentNode : Node {
  readonly attribute ChildNode? firstChild; // O(1)
  readonly attribute ChildNode? lastChild; // O(1)

  // Returns a new Array every time.
  Array<ChildNode> getChildNodes(); // O(N) in number of child nodes
  Array<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

  void append(ChildArgument... nodes); // O(N) in number of arguments plus all their descendants
  void prepend(ChildArgument... nodes); // O(N) in number of arguments plus all their descendants
  void replaceChildrenWith(ChildArgument... nodes); // O(N) in number of descendants plus arguments plus all their descendants
}

class Attr {
  constructor (String name, String value = ''); // O(1)
  readonly attribute String name; // O(1)
  readonly attribute String value; // O(1)
}

abstract class Element : ParentNode {
  readonly attribute String tagName; // O(1)

  Boolean hasAttribute(String name); // O(N) in number of attributes
  String getAttribute(String name); // O(N) in number of attributes
  void setAttribute(String name, String value = ''); // O(N) in number of attributes
  void removeAttribute(String name); // O(N) in number of attributes

  // Returns a new Array and new Attr instances every time.
  Array<Attr> getAttributes(); // O(N) in number of attributes

  readonly attribute ShadowRoot? shadowRoot; // O(1) // returns the shadow root // TODO(ianh): Should this be mutable? It would help explain how it gets set...

  virtual void endTagParsedCallback(); // noop
  virtual void attributeChangeCallback(String name, String? oldValue, String? newValue); // noop
  // TODO(ianh): does a node ever need to know when it's been redistributed?

  virtual LayoutManagerConstructor getLayoutManager(); // O(1)
    // default implementation looks up the 'display' property and returns the value:
    //   if (renderNode)
    //     return renderNode.getProperty(phDisplay);
    //   return null;
}

class Text : Node {
  constructor (String value = ''); // O(1)
  attribute String value; // O(1)

  void replaceWith(String node); // O(1) // special case override of Node.replaceWith()

  virtual void valueChangeCallback(String? oldValue, String? newValue); // noop

  virtual LayoutManagerConstructor getLayoutManager(); // O(1)
    // default implementation returns TextLayoutManager's constructor
}

class DocumentFragment : ParentNode {
  constructor (ChildArguments... nodes); // O(N) in number of arguments plus all their descendants
}

abstract class TreeScope : ParentNode {
  readonly attribute Document? ownerDocument; // O(1)
  readonly attribute TreeScope? parentScope; // O(1)

  Element? findId(String id); // O(1)
}

class ShadowRoot : TreeScope {
  constructor (Element host); // O(1) // note that there is no way in the API to use a newly created ShadowRoot
  readonly attribute Element host; // O(1)
}

class Document : TreeScope {
  constructor (ChildArguments... nodes); // O(N) in number of arguments plus all their descendants

  virtual LayoutManagerConstructor getLayoutManager(); // O(1)
    // returns sky.rootLayoutManager;
}

attribute LayoutManagerConstructor rootLayoutManager; // O(1)
  // initially configured to return BlockLayoutManager


// BUILT-IN ELEMENTS

class ImportElement : 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
}
class TemplateElement : 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
}
class ScriptElement : 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
}
class StyleElement : 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
}
class ContentElement : 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
}
class ImgElement : 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
}
class DivElement : 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
}
class SpanElement : 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
}
class IframeElement : 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
}
class TElement : 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
}
class AElement : 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
}
class TitleElement : 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 : 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
}

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;
}

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
}
```
