APIs
====

The Sky core API
----------------

```javascript
module 'sky:core' {

  // EVENTS

  class Event {
    constructor (String type, Boolean bubbles = true, any data = null); // O(1)
    readonly attribute String type; // O(1)
    readonly attribute Boolean bubbles; // O(1)
    attribute any data; // O(1)

    readonly attribute EventTarget target; // O(1)
    attribute Boolean handled; // O(1)
    attribute any result; // O(1)

    // TODO(ianh): do events get blocked at scope boundaries, e.g. focus events when both sides are in the scope?
    // TODO(ianh): do events get retargetted, e.g. focus when leaving a custom element?
  }

  callback EventListener any (Event event);
    // if the return value is not undefined:
    //   assign it to event.result
    //   set event.handled to true

  abstract class EventTarget {
    any dispatchEvent(Event event); // O(N) in total number of listeners for this type in the chain
      // sets event.handled to false and event.result to undefined
      // makes a record of the event target chain by calling getEventDispatchChain()
      // invokes all the handlers on the chain in turn
      // returns event.result
    virtual Array<EventTarget> getEventDispatchChain(); // O(1) // returns []
    void addEventListener(String type, EventListener listener); // O(1)
    void removeEventListener(String type, EventListener listener); // O(N) in event listeners with that type
    private Array<String> getRegisteredEventListenerTypes(); // O(N)
    private Array<EventListener> getRegisteredEventListenersForType(String type); // O(N)
  }

  class CustomEventTarget : EventTarget { // implemented in JS
    constructor (); // O(1)
    attribute EventTarget parentNode; // getter O(1), setter O(N) in height of tree, throws if this would make a loop

    virtual Array<EventTarget> getEventDispatchChain(); // O(N) in height of tree // implements EventTarget.getEventDispatchChain()
      // let result = [];
      // let node = this;
      // while (node) {
      //   result.push(node);
      //   node = node.parentNode;
      // }
      // return result;

    // you can inherit from this to make your object into an event target
    // or you can inherit from EventTarget and implement your own getEventDispatchChain()
  }



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

  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
    Array<ContentElement> getDestinationInsertionPoints(); // O(N) in number of insertion points the node is in

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

  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
  }

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


  // 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
  }
  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)
  }
  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
  }
  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
  }
  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
  }
  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
  }
  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
  }
  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
  }
  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
  }



  // MODULES

  callback InternalElementConstructor void (Module module);
  dictionary ElementRegistration {
    String tagName;
    Boolean shadow = false;
    InternalElementConstructor? constructor = null;
  }

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

  abstract class AbstractModule : EventTarget {
    readonly attribute Document document; // O(1) // the Documentof the module or application
    Promise<any> import(String url); // O(Yikes) // returns the module's exports
    private Array<Module> getImports(); O(N) // returns the Module objects of all the imported modules

    readonly attribute String url;

    ElementConstructor registerElement(ElementRegistration options); // O(1)
    // if you call registerElement() with an object that was created by
    // registerElement(), it just returns the object after registering it,
    // rather than creating a new constructor
    // otherwise, it proceeds as follows:
    //  1. let constructor be the constructor passed in, if any
    //  2. let prototype be the constructor's prototype; if there is no
    //     constructor, let prototype be Element
    //  3. create a new Function that:
    //      1. throws if not called as a constructor
    //      2. creates an actual Element object
    //      3. initialises the shadow tree if shadow on the options is true
    //      4. calls constructor, if it's not null, with the module as the argument
    //  4. let that new Function's prototype be the aforementioned prototype
    //  5. let that new Function have tagName and shadow properties set to
    //     the values passed in on options
    //  6. register the new element

    readonly attribute ScriptElement? currentScript; // O(1) // returns the <script> element currently being executed if any, and if it's in this module; else null
  }

  class Module : AbstractModule {
    constructor (Application application, Document document, String url); // O(1)
    readonly attribute Application application; // O(1)

    attribute any exports; // O(1) // defaults to {}
  }

  class Application : AbstractModule {
    constructor (Document document, String url); // O(1)
    attribute String title; // O(1)
  }

  // see script.md for a description of the global object, though note that
  // the sky core module doesn't use it or affect it in any way.

}
```

TODO(ianh): event loop

TODO(ianh): define the DOM APIs listed above, including firing the
change callbacks

TODO(ianh): schedule microtask, schedule task, requestAnimationFrame,
custom element callbacks...



Appendices
==========

Sky IDL
-------

The Sky IDL language is used to describe JS APIs found in Sky, in
particular, the JS APIs exposed by the four magical imports defined in
this document.

Sky IDL definitions are typically compiled to C++ that exposes the C++
implementations of the APIs to JavaScript.

Sky IDL works more or less the same as Web IDL but the syntax is a bit
different.

```javascript
module 'sky:modulename' {

  // this is a comment

  typedef NewType OldType; // useful when OldType is a commonly-used union

  callback CallbackName ReturnType (ArgumentType argumentName);

  class ClassName {
    // a class corresponds to a JavaScript prototype
    // corresponds to a WebIDL 'interface'
  }

  abstract class Superclass {
    // an abstract class can't have a constructor
    // in every other respect it is the same as a regular class
  }

  class Subclass : Superclass {
    // properties
    readonly attribute ReturnType attributeName; // getter
    attribute ReturnType attributeName; // getter and setter

    // methods and constructors
    constructor ();
    ReturnType method();
      // When the platform calls this method, it always invokes the "real" method, even if it's been
      // deleted from the prototypes (as if it took a reference to the method at startup, and stored
      // state using Symbols)
      // Calling a method with fewer arguments than defined will throw.
      // Calling a method with more arguments ignores the extra arguments.
    virtual ReturnType methodCallback();
      // when the platform calls this, it actually calls it the way JS would, so author overrides do
      // affect what gets called. Make sure if you override it that you call the superclass implementation!
      // The default implementations of 'virtual' methods all end by calling the identically named method
      // on the superclass, if there is such a method.

    // properties on the constructor
    constructor readonly attribute ReturnType staticName;

    // private APIs - see below
    private void method();

    // arguments and overloading are done as follows
    // note that the argument names are only for documentation purposes
    ReturnType method(ArgumentType argumentName1, ArgumentType argumentName2);
    // the last argument's type can have "..." appended to it to indicate a varargs-like situation
    ReturnType method(ArgumentType argumentName1, ArgumentType... allSubsequentArguments);
    // trailing arguments can have a default value, which must be a literal of the given type
    ReturnType method(ArgumentType argumentName1, ArgumentType argumentName2 = defaultValue);
  }

  dictionary Options {
    String foo; // if there's no default, the property must be specified or it's a TypeError
    Integer bar = 4; // properties can have default values
  }

  // the module can have properties and methods also
  attribute String Foo;
  void method();

  interface InterfaceName {
    // describes a template of a prototype, in the same syntax as a class
    // not actually exposed in the runtime
  }

}
```

### Private APIs ###

Private APIs are only accessible via Symbol objects, which are then
exposed on the sky:debug module's exports object as the name of the
member given in the IDL.

For example, consider:

```javascript
class Foo {
  private void Bar();
}
```

In a script with a ``foo`` object of type ``Foo``, ``foo.Bar`` is
undefined. However, it can be obtained as follows:

```html
<import src="sky:debug" as="debug"/>
<!-- ... import whatever defines 'foo' ... -->
<script>
  foo[debug.Bar]
</script>
```

### Types ###

The following types are available:

* ``Integer`` - WebIDL ``long long``
* ``Float`` - WebIDL ``double``
* ``Infinity`` - singleton type with value ``Infinity``
* ``String`` - WebIDL ``USVString``
* ``Boolean`` - WebIDL ``boolean``
# ``Object`` - WebIDL ``object`` (``ClassName`` can be used as a literal for this type)
* ``ClassName`` - an instance of the class ClassName
* ``DictionaryName`` - an instance of the dictionary DictionaryName
* ``Promise<Type>`` - WebIDL ``Promise<T>``
* ``Generator<Type>`` - An ECMAScript generator function that returns data of the given type
* ``Array<Type>`` - WebIDL ``sequence<T>``
* ``Dictionary<Type>`` - unordered set of name-value String-Type pairs with no duplicate names
* ``Type?`` - union of Type and the singleton type with value ``null`` (WebIDL nullable)
* ``(Type1 or Type2)`` - union of Type1 and Type2 (WebIDL union)
* ``any`` - union of all types (WebIDL ``any``)

Methods that return nothing (undefined, in JS) use the keyword "void"
instead of a type.


TODO(ianh): Define in detail how this actually works


Mojom IDL
---------

The Mojom IDL language is used to describe the APIs exposed over Mojo
pipes.

Mojom IDL definitions are typically compiled to wrappers in each
language, which are then used as imports.

TODO(ianh): Define in detail how this actually works


Notes
-----
```javascript
global object = {} // with Math, RegExp, etc

magical imports:
  the core mojo fabric JS API   sky:mojo:fabric:core
  the asyncWait/cancelWait mojo fabric JS API (interface to IPC thread)  sky:mojo:fabric:ipc
  the mojom for the shell, proxying through C++ so that the shell pipe isn't exposed  sky:mojo:shell
  the sky API  sky:core
  the sky debug symbols for private APIs  sky:debug
```

TODO(ianh): determine if we want to separate the "this" from the
Document, especially for Modules, so that exposing a module's element
doesn't expose the module's exports attribute.
