Sky Style Language
==================

Planed changes
--------------

Add //-to-end-of-line comments to be consistent with the script
language.


Style Parser
------------

(this section is incomplete)

### Tokenisation


#### Value parser


##### **Value** state

If the current character is...

* '``;``': Consume the character and exit the value parser
  successfully.

* '``@``': Consume the character and switch to the **at**
  state.

* '``#``': Consume the character and switch to the **hash**
  state.

* '``$``': Consume the character and switch to the **dollar**
  state.

* '``%``': Consume the character and switch to the **percent**
  state.

* '``&``': Consume the character and switch to the **ampersand**
  state.

* '``'``': Set _value_ to the empty string, consume the character, and
  switch to the **single-quoted string** state.

* '``"``': Set _value_ to the empty string, consume the character, and
  switch to the **double-quoted string** state.

* '``-``': Consume the character, and switch to the **negative
  integer** state.

* '``0``'-'``9``': Set _value_ to the decimal value of the current
  character, consume the character, and switch to the **integer**
  state.

* '``a``'-'``z``', '``A``'-'``Z``': Set _value_ to the current
  character, consume the character, and switch to the **identifier**
  state.

* '``*``', '``^``', '``!``', '``?``', '``,``', '``/``', '``<``',
  '``[``', '``)``', '``>``', '``]``', '``+``': Emit a symbol token
  with the current character as the symbol, consume the character, and
  stay in this state.

* Anything else: Consume the character and switch to the **error**
  state.


##### **At** state

* '``0``'-'``9``', '``a``'-'``z``', '``A``'-'``Z``': Set _value_ to
  the current character, create a literal token with the unit set to
  ``@``, consume the character, and switch to the **literal** state.

* Anything else: Emit a symbol token with ``@`` as the symbol, and
  switch to the **value** state without consuming the character.


##### **Hash** state

* '``0``'-'``9``', '``a``'-'``z``', '``A``'-'``Z``': Set _value_ to
  the current character, create a literal token with the unit set to
  ``@``, consume the character, and switch to the **literal** state.

* Anything else: Emit a symbol token with ``#`` as the symbol, and
  switch to the **value** state without consuming the character.


##### **Dollar** state

* '``0``'-'``9``', '``a``'-'``z``', '``A``'-'``Z``': Set _value_ to
  the current character, create a literal token with the unit set to
  ``@``, consume the character, and switch to the **literal** state.

* Anything else: Emit a symbol token with ``$`` as the symbol, and
  switch to the **value** state without consuming the character.


##### **Percent** state

* '``0``'-'``9``', '``a``'-'``z``', '``A``'-'``Z``': Set _value_ to
  the current character, create a literal token with the unit set to
  ``@``, consume the character, and switch to the **literal** state.

* Anything else: Emit a symbol token with ``%`` as the symbol, and
  switch to the **value** state without consuming the character.


##### **Ampersand** state

* '``0``'-'``9``', '``a``'-'``z``', '``A``'-'``Z``': Set _value_ to
  the current character, create a literal token with the unit set to
  ``@``, consume the character, and switch to the **literal** state.

* Anything else: Emit a symbol token with ``&`` as the symbol, and
  switch to the **value** state without consuming the character.


##### TODO(ianh): more states...


##### **Error** state

If the current character is...

* '``;``': Consume the character and exit the value parser in failure.

* Anything else: Consume the character and stay in this state.



Selectors
---------

Sky Style uses whatever SelectorQuery. Maybe one day we'll make
SelectorQuery support being extended to support arbitrary selectors,
but for now, it supports:

```css
tagname
#id
.class
[attrname]
[attrname=value]
:host                  ("host" string is fixed)
::pseudo-element
```

These can be combined (without whitespace), with at most one tagname
(must be first) and at most one pseudo-element (must be last) as in:

```css
tagname[attrname]#id:host.class.class[attrname=value]::foo
```

In debug mode, giving two IDs, or the same selector twice (e.g. the
same classname), or specifying other redundant or conflicting
selectors (e.g. [foo][foo=bar], or [foo=bar][foo=baz]) will be
flagged.

Alternatively, a selector can be the special value "@root",
optionally followed by a pseudo-element, as in:

```css
@root::bar
```


Value Parser
------------

```javascript
class StyleToken {
  constructor (String king, String value);
  readonly attribute String kind;
     // string
     // identifier
     // function (identifier + '(')
     // number
     // symbol (one of @#$%& if not immediately following numeric or preceding alphanumeric, or one of *^!?,/<[)>]+ or, if not followed by a digit, -)
     // dimension (number + identifier or number + one of @#$%&)
     // literal (one of @#$%& + alphanumeric)
  readonly attribute String value;
  readonly attribute String unit; // for 'dimension' type, this is the punctuation or identifier that follows the number, for 'literal' type, this is the punctuation that precedes it
}

class TokenSource {
  constructor (Array<StyleToken> tokens);
  IteratorResult next();
  TokenSourceBookmark getBookmark();
  void rewind(TokenSourceBookmark bookmark);
}

class TokenSourceBookmark {
  constructor ();
  // TokenSource stores unforgeable state on this object using symbols or a weakmap or some such
}

callback ParserCallback = AbstractStyleValue (TokenSource tokens); // return if successful, throw if not

class StyleGrammar {
  constructor ();
  void addParser(ParserCallback parser);
  AbstractStyleValue parse(TokenSource tokens, Boolean root = false);
   // for each parser callback that was registered, in reverse
   // order (most recently registered first), run these steps:
   //   let bookmark = tokens.getBookmark();
   //   try { 
   //     let result = parser(tokens);
   //     if (root) {
   //       if (!tokens.next().done)
   //         throw new Error();
   //     }
   //   } except {
   //     tokens.rewind(bookmark);
   //   }
   // (root is set when you need to parse the entire token stream to be valid)
}

/*
StyleNode
 |
 +-- Property
 |
 +-- AbstractStyleValue
     |   
     +-- NumericStyleValue
     |    |
     |    +-- AnimatableNumericStyleValue*
     |   
     +-- LengthStyleValue
     |    |
     |    +-- AnimatableLengthStyleValue*
     |    |
     |    +-- TransitionLengthStyleValue*
     |    |
     |    +-- PixelLengthStyleValue
     |    |
     |    +-- EmLengthStyleValue*
     |    |
     |    +-- VHLengthStyleValue*
     |    |
     |    +-- CalcLengthStyleValue*
     |    
     +-- ColorStyleValue
     |    |
     |    +-- RGBColorStyleValue
     |    |
     |    +-- AnimatableColorStyleValue*
     |    
     +-- AbstractOpaqueStyleValue
     |    |
     |    +-- IdentifierStyleValue
     |    |    |
     |    |    +-- AnimatableIdentifierStyleValue*
     |    |    
     |    +-- URLStyleValue*
     |    |    |
     |    |    +-- AnimatableURLStyleValue*
     |    |    
     |    +-- StringStyleValue*
     |    |    |
     |    |    +-- AnimatableStringStyleValue*
     |    |    
     |    +-- ObjectStyleValue
     |    
     +-- PrimitiveValuesListStyleValue*
*/
```

The types marked with * in the list above are not part of dart:sky,
and are only shown here to illustrate what kinds of extensions are
possible and where they would fit.

TODO(ianh): consider removing 'StyleValue' from these class names

```javascript
abstract class StyleNode {
  abstract void markDirty();
}

dictionary StyleValueResolverSettingsSettings {
  Boolean firstTime = false;
  any state = null;
}

class StyleValueResolverSettings {
  // this is used as an "out" parameter for 'resolve()' below
  constructor(StyleValueResolverSettingsSettings initial);
  void reset(StyleValueResolverSettingsSettings initial);
    // sets firstTime and state to given values
    // sets layoutDependent to false
    // sets dependencies to empty set
    // sets lifetime to Infinity

  readonly attribute Boolean firstTime;
    // true if this is the first time this property is being resolved for this element,
    // or if the last time it was resolved, the value was a different object

  // attribute Boolean layoutDependent
  void setLayoutDependent();
    // call this if the value should be recomputed each time the ownerLayoutManager's dimensions change, rather than being cached
  Boolean getLayoutDependent();
    // returns true if setLayoutDependent has been called since the last reset()

  // attribute "BitField" dependencies; // defaults to no bits set
  void dependsOn(PropertyHandle property);
    // if the given property doesn't have a dependency bit assigned:
    //  - assign the next bit to the property
    //  - if there's no bits left, throw
    // set the bit on this StyleValueResolverSettings's dependencies bitfield
  Array<PropertyHandle> getDependencies();
    // returns an array of the PropertyHandle values for the bits that are set in dependencies

  // attribute (Float or Infinity) lifetime;
  void setLifetime(Float age);
    // if the new value is less than the current value of lifetime, update the current value
  (Float or Infinity) getLifetime();
    // return current value of lfietime

  attribute any state; // initially null, can be set to store value for this RenderNode/property pair
    // for example, TransitioningColorStyleValue would store
    //    {
    //      initial: /* color at time of transition */,
    //      target: /* color at end of transition */,
    //      start: /* time at start of transition */,
    //    }
    // ...which would enable it to update appropriately, and would also
    // let other transitions that come later know that you were half-way
    // through a transition so they can shorten their time accordingly
    //
    // best practices: if you're storing values on the state object,
    // then remove the values once they are no longer needed. For
    // example, when your transition ends, set the object to null.
    //
    // best practices: if you're a style value that contains multiple
    // style values, then before you call their resolve you should
    // replace the state with a state that is specific to them, and
    // when you get it back you should insert that value into your
    // state somehow. For example, in a resolve()r with two child
    // style values a and b:
    //    let ourState;
    //    if (settings.firstTime)
    //      ourState = { a: null, b: null };
    //    else
    //      ourState = settings.state;
    //    settings.state = ourState.a;
    //    let aResult = a.resolve(node, settings);
    //    ourState.a = settings.state;
    //    settings.state = ourState.b;
    //    let aResult = b.resolve(node, settings);
    //    ourState.b = settings.state;
    //    settings.state = ourState;
    //    return a + b; // or whatever
    //
    // best practices: if you're a style value that contains multiple
    // style values, and all those style values are storing null, then
    // store null yourself, instead of storing many nulls of your own.

  // attribute Boolean wasStateSet;
  Boolean getShouldSaveState();
    // returns true if state is not null, and either state was set
    // since the last reset, or firstTime is false.

}

class Property : StyleNode {
  constructor (AbstractStyleDeclaration parentNode, PropertyHandle property, AbstractStyleValue? initialValue = null);
  readonly attribute AbstractStyleDeclaration parentNode;
  readonly attribute PropertyHandle property;
  readonly attribute AbstractStyleValue value;

  void setValue(AbstractStyleValue? newValue);
    // updates value and calls markDirty()

  void markDirty();
    // call parentNode.markDirty(property);

  abstract any resolve(RenderNode node, StyleValueResolverSettings? settings = null);
    // if value is null, returns null
    // otherwise, returns value.resolve(property, node, settings)
}

abstract class AbstractStyleValue : StyleNode {
  abstract constructor(StyleNode? parentNode = null);
  attribute StyleNode? parentNode;

  void markDirty();
    // call this.parentNode.markDirty()

  abstract any resolve(PropertyHandle property, RenderNode node, StyleValueResolverSettings? settings = null);
}

abstract class LengthStyleValue : AbstractStyleValue {
  abstract Float resolve(PropertyHandle property, RenderNode node, StyleValueResolverSettings? settings = null);
}

class PixelLengthStyleValue : LengthStyleValue {
  constructor(Float number, StyleNode? parentNode = null);
  attribute Float value;
    // on setting, calls markDirty();
  Float resolve(PropertyHandle property, RenderNode node, StyleValueResolverSettings? settings = null);
    // return value
}

typedef RawColor Float; // TODO(ianh): figure out what Color should be
class ColorStyleValue : LengthStyleValue {
  constructor(Float red, Float green, Float blue, Float alpha, StyleNode? parentNode = null);
  // ... color API ...
  RawColor resolve(PropertyHandle property, RenderNode node, StyleValueResolverSettings? settings = null);
}

class AbstractOpaqueStyleValue : AbstractStyleValue {
  abstract constructor(any value, StyleNode? parentNode = null);
  attribute any value;
    // on setting, calls markDirty();
  any resolve(PropertyHandle property, RenderNode node, StyleValueResolverSettings? settings = null);
    // returns value
}

class IdentifierStyleValue : AbstractOpaqueStyleValue {
  constructor(String value, StyleNode? parentNode = null);
    // calls superclass constructor
}

/*
class AnimatableIdentifierStyleValue : AbstractOpaqueStyleValue {
  constructor(String value, String newValue, AnimationFunction player, StyleNode? parentNode = null);
  readonly attribute String newValue;
  readonly attribute AnimationFunction player;
  any resolve(PropertyHandle property, RenderNode node, StyleValueResolverSettings? settings = null);
}
*/

class ObjectStyleValue : AbstractOpaqueStyleValue {
  constructor(any value, StyleNode? parentNode = null);
    // calls superclass constructor
}

dictionary PropertySettings {
  String? name = null; // null if the property can't be set from a <style> block
  StyleGrammar? grammar = null; // must be non-null if name is non-null; must be null otherwise
  Boolean inherited = false;
  any initialValue = null;
  Boolean needsManager = false;
  Boolean needsLayout = false;
  Boolean needsPaint = false;
  // PropertyHandle propertyHandle; // assigned by registerProperty
  // Integer dependencyBit; // assigned by StyleValueResolverSettings.dependsOn()
}
typedef PropertyHandle Integer;
PropertyHandle registerProperty(PropertySettings propertySettings);
  // registers a property with the given settings, and returns an integer >= 0
  // that can be used to refer to this property

// dart:sky exports a bunch of style grammars so that people can extend them
attribute StyleGrammar PositiveLengthOrInfinityStyleGrammar; // resolves to LengthStyleValue
attribute StyleGrammar PositiveLengthOrAutoStyleGrammar; // resolves to LengthStyleValue or IdentifierStyleValue (with value 'auto')
attribute StyleGrammar PositiveLengthStyleGrammar; // resolves to LengthStyleValue
attribute StyleGrammar NumberGrammar; // resolves to NumericStyleValue
attribute StyleGrammar ColorGrammar; // resolves to ColorStyleValue
attribute StyleGrammar DisplayStyleGrammar; // resolves to ObjectStyleValue
```  

Inline Styles
-------------

```javascript
abstract class AbstractStyleDeclarationList {
  void addStyles(StyleDeclaration styles, String pseudoElement = ''); // O(1)
  void removeStyles(StyleDeclaration styles, String pseudoElement = ''); // O(N) in number of declarations
  Array<StyleDeclaration> getDeclarations(String pseudoElement = ''); // O(N) in number of declarations
}

class ElementStyleDeclarationList : AbstractStyleDeclarationList {
  constructor (Element? element);
  readonly attribute Element? element;

  // there are two batches of styles in an ElementStyleDeclarationList.

  // the first batch is the per-frame styles; these get (conceptually)
  // cleared each frame, after which all the matching rules in relevant
  // <style> blocks get added back in, followed by all the animation-
  // derived rules; scripts can also add styles themselves, but they are
  // dropped after the next frame
  void addFrameStyles(StyleDeclaration styles, String pseudoElement = ''); // O(1)
  void clearFrameStyles();

  // the second batch is the persistent styles, which remain until removed;
  // they are accessed via the AbstractStyleDeclarationList accessors

  // as StyleDeclarations are added and removed, the ElementStyleDeclarationList
  // calls register(element) and unregister(element) respectively on those
  // StyleDeclaration objects, where element is the element that was passed
  // to the constructor, if not null
  // then, it calls element.renderNode.cascadedValueChanged
  // for each property on the object

  // the inherited getDeclarations() method returns all the frame
  // styles followed by all the persistent styles, in insertion order
}

class RenderNodeStyleDeclarationList : AbstractStyleDeclarationList {
  constructor (RenderNode? renderNode);
  readonly attribute RenderNode? renderNode;

  // as StyleDeclarations are added and removed, the RenderNodeStyleDeclarationList
  // calls register(renderNode) and unregister(renderNode) respectively on those
  // StyleDeclaration objects, where renderNode is the RenderNode that was passed
  // to the constructor, if not null
  // then, it calls renderNode.cascadedValueChanged
  // for each property on the object
}

class StyleDeclaration {
  constructor ();

  void markDirty(PropertyHandle property);
    // this indicates that the cascaded value of the property thinks
    // it will now have a different result (as opposed to the cascaded
    // value itself having changed)
    // invoke element.renderNode.cascadedValueDirty(property, pseudoElement); for each
    // currently registered consumer element/pseudoElement pair

  void register((Element or RenderNode) consumer, String pseudoElement = ''); // O(1)
  void unregister((Element or RenderNode) consumer, String pseudoElement = ''); // O(N)
    // registers an element/pseudoElement or renderNode/pseudoElement pair with
    // this StyleDeclaration so that a property/value on the style declaration
    // is marked dirty, the relevant render node is informed and can then update
    // its property cache accordingly


  getter AbstractStyleValue? (PropertyHandle property);
    // looks up the Property object for /property/, and returns its value
    // null if property is missing

  setter void (PropertyHandle property, AbstractStyleValue value);
    // verify that value.parentNode is null
    // if there is no Property object for /property/, creates one
    // else calls its update() method to change the value
    // update value's parentNode
    // invoke consumer.renderNode.cascadedValueChanged(property); for each
    // currently registered consumer

  void remove(PropertyHandle property);
    // drops the Property object for /property/ from this StyleDeclaration object
    // invoke consumer.renderNode.cascadedValueChanged(property); for each
    // currently registered consumer
}
```

Rule Matching
-------------

```javascript
class Rule {
  constructor ();
  attribute SelectorQuery selector; // O(1)
  attribute String pseudoElement; // O(1)
  attribute StyleDeclaration styles; // O(1)
}
```

Each frame, at some defined point relative to requestAnimationFrame(),
if a Rule has started applying, or a Rule stopped applying, to an
element, dart:sky calls thatElement.style.clearFrameStyles() and then,
for each Rule that now applies, calls
thatElement.style.addFrameStyles() with the relevant StyleDeclaration
and pseudoElement from each such Rule.


Update the render tree
----------------------

Simultaneously walk the tree rooted at the application's element
tree's root node, taking into account shadow trees and child
distribution, and the tree rooted at that Root node's RenderNode.

If you come across a node that doesn't have an assigned RenderNode,
then create one, placing it in the appropriate place in the RenderTree
tree, after any nodes marked isGhost=true, with ownerLayoutManager
pointing to the parent RenderNode's layoutManager, if it has one, and,
if it has one and autoreap is false on that layout manager, mark the
new node "isNew". (This means that when a node is marked isNew, the
layout manager has already laid out at least one frame.)

For each element, if the node's needsManager is true, call
getLayoutManager() on the element, and if that's not null, and if the
returned class isn't the same class as the current layoutManager, if
any, construct the given class and assign it to the RenderNode's
layoutManager, then set all the child RenderNodes' ownerLayoutManager
to that object; if it returns null, and that node already has a
layoutManager, then set isGhost=true for that node and all its
children (without changing the layoutManager). Otherwise, if it
returned null and there's already no layoutManager, remove the node
from the tree. Then, in any case, clear the needsManager bit.

When an Element or Text node is to be removed from its parent, and it
has a renderNode, and that renderNode has an ownerLayoutManager with
autoreap=false, then before actually removing the node, the node's
renderNode should be marked isGhost=true, and all the
StyleDeclarations in the relevant ElementStyleDeclarationList should
be added to the RenderNode's overrideStyles for use later (creating a
RenderNodeStyleDeclarationList if necessary).

When an Element is to be removed from its parent, regardless of the
above, the node's renderNode attribute should be nulled out.

When a RenderNode is added with isNew=true, call its parent
RenderNode's LayoutManager's childAdded() callback. When a a
RenderNode has its isGhost property set to true, then call it's parent
RenderNode's LayoutManager's childRemoved() callback.


```javascript
dictionary PropertySettings {
  String? name = null; // null if the property can't be set from a <style> block
  StyleGrammar? grammar = null; // must be non-null if name is non-null; must be null otherwise
  Boolean inherited = false;
  any initialValue = null;
  Boolean needsManager = false;
  Boolean needsLayout = false;
  Boolean needsPaint = false;
  // PropertyHandle propertyHandle; // assigned by registerProperty
  // Integer dependencyBit; // assigned by StyleValueResolverSettings.dependsOn()
}

dictionary GetPropertySettings {
  String pseudoElement = '';
  Boolean forceCache = false;
    // if set to true, will return the cached value if any, or null otherwise
    // this is used by transitions to figure out what to transition from
}

class RenderNode { // implemented in C++ with no virtual tables
  // this is generated before layout
  readonly attribute String text;
  readonly attribute Node? parentNode;
  readonly attribute Node? firstChild;
  readonly attribute Node? nextSibling;

  // internal state:
  // - back pointer to backing Node, if we're not a ghost
  // - cache of resolved property values, mapping as follows:
  //    - pseudoElement, property => StyleValue object, resolved value, StyleValueResolverSettings, cascade dirty bit, value dirty bit
  // - property state map (initially empty), as follows:
  //    - pseudoElement, property => object

  any getProperty(PropertyHandle property, GetPropertySettings? settings = null);
     // looking at the cached data for the given pseudoElement:
     // if there's a cached value:
     //   if settings.forceCache is true, return the cached value
     //   if neither dirty bit is set, return the cached value
     //   if the cascade dirty bit is not set (value dirty is set) then
     //    - clear any pending lifetime-enforcing tasks for this
     //      property/pseudoElement pair on this render node
     //    - resolve the value using the same StyleValue object
     //       - with firstTime=false on the resolver settings
     //       - with the cached state object if any
     //       - jump to "cache" below
     // if settings.forceCache is true, return null
     // - clear any pending lifetime-enforcing tasks for this
     //   property/pseudoElement pair on this render node
     // - if there's an override declaration with the property (with
     //   the pseudo or without), then get the value object from there
     //   and jump to "resolve" below.
     // - if there's an element and it has a style declaration with
     //   the property (with the pseudo or without), then get the
     //   value object from there and jump to "resolve" below.
     // - if it's not an inherited property, or if there's no parent,
     //   then get the default value and jump to "resolve" below.
     // - call the parent render node's getProperty() with the same
     //   property but no settings, then cache that value as the value
     //   for this element with the given pseudoElement, with no
     //   StyleValue object, no resolver settings, and set the state
     //   to null.
     // resolve:
     //   - get a new resolver settings object (or reset an existing one)
     //     - if the obtained StyleValue object is different than the
     //       cached StyleValue object, or if there is no cached
     //       object, then set the resolver settings to
     //       firstTime=true, otherwise it's the same object and set
     //       firstTime=false.
     //     - set the resolver settings' state to the current state
     //       for this pseudoElement/property combination
     //   - using the obtained StyleValue object, call resolve(),
     //     passing it this node and the resolver settings object.
     //   - jump to "cache" below
     // cache:
     //   - update the cache with the obtained value and resolver
     //     settings
     //   - reset the dirty bits
     //   - if the resolver settings' getShouldSaveState() method
     //     returns false, then discard any cached state, otherwise,
     //     cache the new state
     //   - if the resolver settings' lifetime is not infinity, then
     //     queue a lifetime-enforcing task for the appropriate time
     //     in the future which calls cascadedValueDirty for this
     //     property/pseudoElement pair on this render node

  attribute RenderNodeStyleDeclarationList overrideStyles;
     // mutable; initially null
     // this is used when isGhost is true, and can also be used more generally to
     // override styles from the layout manager (e.g. to animate a new node into view)  
     // this is the only arbitrarily mutable state of a RenderNode object

  private void cascadedValueChanged(PropertyHandle property, String pseudoElement = '');
  private void cascadedValueDirty(PropertyHandle property, String pseudoElement = '');
    // - set the appropriate dirty bit on the cached data for this property/pseudoElement pair
    //    - cascade dirty for cascadedValueChanged
    //    - value dirty for cascadedValueDirty
    // - if the property is needsManager, set needsManager to true
    // - if the property is needsLayout, set needsLayout to true and walk up the
    //   tree setting descendantNeedsLayout
    // - if the property is needsPaint, add the node to the list of nodes that need painting
    // - if the property has a dependencyBit defined, then check the cache of all the
    //   properties on this RenderNode, and the cache for the property in all the child
    //   nodes and, if pseudoElement is '', the pseudoElements of this node, and,
    //   if any of them have the relevant dependency bit set, then call
    //     thatRenderNode.cascadedValueDirty(thatProperty, thatPseudoElement)
    // - if the property is inherited, then for each child node, and, if pseudoElement
    //   is '', the pseudoElements of this node, if the cached value for this property
    //   is present but has no StyleValue, call thatNode.cascadedValueChanged(property, thatPseudoElement)

  readonly attribute Boolean needsManager;
    // means that a property with needsManager:true has changed on this node

  readonly attribute Boolean needsLayout;
    // means that either needsManager is true or a property with needsLayout:true has changed on this node
    // needsLayout is set to false by the ownerLayoutManager's default layout() method

  readonly attribute Boolean descendantNeedsLayout;
    // means that some child of this node has needsLayout set to true
    // descendantNeedsLayout is set to false by the ownerLayoutManager's default layout() method

  readonly attribute LayoutManager layoutManager;
  readonly attribute LayoutManager ownerLayoutManager; // defaults to the parentNode.layoutManager
    // if you are not the ownerLayoutManager, then ignore this RenderNode in layout() and paintChildren()
    // using walkChildren() does this for you

  // only the ownerLayoutManager can change these
  readonly attribute Float x; // relative to left edge of ownerLayoutManager
  readonly attribute Float y; // relative to top edge of ownerLayoutManager
  readonly attribute Float width;
  readonly attribute Float height;
  readonly attribute Boolean isNew; // node has just been added (and maybe you want to animate it in)
  readonly attribute Boolean isGhost; // node has just been removed (and maybe you want to animate it away)
}
```

The flattened tree is represented as a hierarchy of Node objects. For
any element that only contains text node children, the "text" property
is set accordingly. For elements with mixed text node and non-text
node children, each run of text nodes is represented as a separate
Node with the "text" property set accordingly and the styles set as if
the Node inherited everything inheritable from its parent.


Layout
------

dart:sky registers 'display' as follows:

```javascript
  {
    name: 'display',
    grammar: sky.DisplayStyleGrammar,
    inherited: false,
    initialValue: sky.BlockLayoutManager,
    needsManager: true,
  }
```

The following API is then used to add new layout manager types to 'display':

```javascript
void registerLayoutManager(String displayValue, LayoutManagerConstructor? layoutManager);
```

dart:sky by default registers:

- 'block': sky.BlockLayoutManager
- 'paragraph': sky.ParagraphLayoutManager
- 'inline': sky.InlineLayoutManager
- 'none': null


Layout managers inherit from the following API:

```javascript
callback LayoutManagerConstructor LayoutManager (RenderNode node);

class LayoutManager : EventTarget {
  readonly attribute RenderNode node;
  constructor LayoutManager(RenderNode node);
    // sets needsManager to false on the node

  readonly attribute Boolean autoreap;
    // defaults to true
    // when true, children that are added don't get set to isNew=true
    // when true, children that are removed don't get set to isGhost=true, they're just removed

  virtual Array<EventTarget> getEventDispatchChain(); // O(N) in number of this.node's ancestors // implements EventTarget.getEventDispatchChain()
    // let result = [];
    // let node = this.node;
    // while (node && node.layoutManager) {
    //   result.push(node.layoutManager);
    //   node = node.parentNode;
    // }
    // return result;

  void setProperty(RenderNode node, PropertyHandle property, any value, String pseudoElement = ''); // O(1)
    // replaces the value that getProperty() would return on that node with /value/
    // this also clears the dependency bits, dirty bits, and sets the property state to null
    // this also clears any relevant lifetime-enforcing tasks

  void take(RenderNode victim); // sets victim.ownerLayoutManager = this;
    // assert: victim hasn't been take()n yet during this layout
    // assert: an ancestor of victim has node.layoutManager == this (aka, victim is a descendant of this.node)

  virtual void release(RenderNode victim);
    // called when the RenderNode was removed from the tree

  virtual void childAdded(RenderNode child);
  virtual void childRemoved(RenderNode child);
    // called when a child has its isNew or isGhost attributes set respectively

  void setChildPosition(child, x, y); // sets child.x, child.y
  void setChildX(child, y); // sets child.x
  void setChildY(child, y); // sets child.y
  void setChildSize(child, width, height); // sets child.width, child.height
  void setChildWidth(child, width); // sets child.width
  void setChildHeight(child, height); // sets child.height
    // assert: child.ownerLayoutManager == this
    // for setChildSize/Width/Height: if the new dimension is different than the last assumed dimensions, and
    // any RenderNodes with an ownerLayoutManager==this have cached values for getProperty() that are marked
    // as layout-dependent, mark them as dirty with cascadedValueDirty()

  void assumeDimensions(Float width, Float height);
    // sets the assumed dimensions for calls to getProperty() on RenderNodes that have this as an ownerLayoutManager,
    // by updating renderNode width/height;
    // if the new dimension is different than the last assumed dimensions, and any RenderNodes with an
    // ownerLayoutManager==this have cached values for getProperty() that are marked as layout-dependent, mark them
    // as dirty with cascadedValueDirty()

  virtual LayoutValueRange getIntrinsicWidth(Float? defaultWidth = null);
  /*
     function getIntrinsicWidth(defaultWidth) {
       if (defaultWidth == null) {
         defaultWidth = this.node.getProperty('width');
         if (typeof defaultWidth != 'number')
           defaultWidth = 0;
       }
       let minWidth = this.node.getProperty('min-width');
       if (typeof minWidth != 'number')
         minWidth = 0;
       let maxWidth = this.node.getProperty('max-width');
       if (typeof maxWidth != 'number')
         maxWidth = Infinity;
       if (maxWidth < minWidth)
         maxWidth = minWidth;
       if (defaultWidth > maxWidth)
         defaultWidth = maxWidth;
       if (defaultWidth < minWidth)
         defaultWidth = minWidth;
       return {
         minimum: minWidth,
         value: defaultWidth,
         maximum: maxWidth,
       };
     }
  */

  virtual LayoutValueRange getIntrinsicHeight(Float? defaultHeight = null);
  /*
     function getIntrinsicHeight(defaultHeight) {
       if (defaultHeight == null) {
         defaultHeight = this.node.getProperty('height');
         if (typeof defaultHeight != 'number')
           defaultHeight = 0;
       }
       let minHeight = this.node.getProperty('min-height');
       if (typeof minHeight != 'number')
         minHeight = 0;
       let maxHeight = this.node.getProperty('max-height');
       if (typeof maxHeight != 'number')
         maxHeight = Infinity;
       if (maxHeight < minHeight)
         maxHeight = minHeight;
       if (defaultHeight > maxHeight)
         defaultHeight = maxHeight;
       if (defaultHeight < minHeight)
         defaultHeight = minHeight;
       return {
         minimum: minHeight,
         value: defaultHeight,
         maximum: maxHeight,
       };
     }
  */

  void welcomeChild(child);
    // assert: this == child.ownerLayoutManager
    // assert: child.isNew is true
    // resets child.isNew
  void reapChild(child);
    // assert: this == child.ownerLayoutManager
    // assert: child.isGhost is true
    // removes the RenderNode from its parent if isGhost is true

  Generator<RenderNode> walkChildren();
    // returns a generator that iterates over the children, skipping any whose ownerLayoutManager is not |this|

  Generator<RenderNode> walkChildrenBackwards();
    // returns a generator that iterates over the children backwards, skipping any whose ownerLayoutManager is not |this|

  void markAsLaidOut(); // sets this.node.needsLayout and this.node.descendantNeedsLayout to false
  virtual Dimensions layout(Float? width, Float? height);
    // if width is null, set width to getIntrinsicWidth().value
    // if height is null, set height to getIntrinsicHeight().value
    // call this.assumeDimensions(width, height);
    // call this.layoutChildren(width, height);
    // call markAsLaidOut();
    // return { width: width, height: height }
    // - this should always call this.markAsLaidOut() to reset
    //   needsLayout and descendantNeedsLayout
    // - the return value should include the final value for whichever
    //   of the width and height arguments that is null
    // - subclasses that want to make 'auto' values dependent on the
    //   children should override this entirely, rather than
    //   overriding layoutChildren; but see layoutChildren()'s notes
    //   for how to do this

  virtual void layoutChildren(Float width, Float height);
    // default implementation does nothing
    // - override only this (and not layout()) if you want to lay out
    //   children but not have the children affect your dimensions
    // - always call setChildSize() and setChildPosition() after
    //   calling a child's layout() method
    // - if the child has needsLayout or if you need to have it
    //   autosize, call its ownerLayoutManager's layout() method
    // - otherwise if the child has needs descendantNeedsLayout, call
    //   layoutDescendants()

  virtual Dimensions layoutDescendants();
    // assert: node.needsLayout is false, node.descendantNeedsLayout is true
    // walk children:
    //  - if it has needsLayout, call its layout() method with its
    //    current width and height, then call setChildSize() with
    //    those same dimensions
    //  - else, if it has descendantNeedsLayout, call its
    //    layoutDescendants() method
    // call markAsLaidOut();
    // - override this if you use take() to control more children, in
    //   which case you should call their methods too
    // - this should always call this.markAsLaidOut() to reset
    //   needsLayout and descendantNeedsLayout

  virtual void paint(RenderingSurface canvas);
    // set a clip rect on the canvas for rect(0,0,this.width,this.height)
    //   (? we don't really have to do this; consider shadows...)
    // call this.paintChildren(canvas)
    // (the default implementation doesn't paint anything on top of the children)
    // unset the clip
    // - this gets called by the system if:
    //    - you are in your parent's current display list and it's in its parent's and so on up to the top, and
    //    - you haven't had paint() called since the last time you were dirtied
    // - the following things make you dirty:
    //    - dimensions of your RenderNode changed
    //    - one of your properties with needsLayout or needsPaint changed

  virtual void paintChildren(RenderingSurface canvas);
    // for each child returned by walkChildren():
    //   if child bounds intersects our bounds:
    //     call canvas.paintChild(child);
    // - you should skip children that will be clipped out of yourself because they're outside your bounds
    // - if you transform the canvas, you'll have to implement your own version of paintChildren() so
    //   that you don't skip the children that are visible in the new coordinate space but wouldn't be
    //   without the transform

  virtual RenderNode hitTest(Float x, Float y);
    // default implementation uses the node's children nodes' x, y,
    // width, and height, skipping any that have width=0 or height=0, or
    // whose ownerLayoutManager is not |this|
    // default implementation walks the tree backwards from its built-in order
    // if no child is hit, then return this.node
    // override this if you changed your children's z-order, or if you used take() to
    // hoist some descendants up to be your responsibility, or if your children aren't
    // rectangular (e.g. you lay them out in a hex grid)
    // make sure to offset the value you pass your children: child.layoutManager.hitTest(x-child.x, y-child.y)
}

dictionary LayoutValueRange {
  // negative values here should be treated as zero
  Float minimum = 0;
  Float value = 0; // ideal desired width; if it's not in the range minimum .. maximum then it overrides minimum and maximum
  (Float or Infinity) maximum = Infinity; 
}

dictionary Dimensions {
  Float width = 0;
  Float height = 0;
}
```


Paint
-----

Sky has a list of RenderNodes that need painting. When a RenderNode is
created, it's added to this list. (See also needsPaint for another
time it is added to the list.)

```javascript
callback void Painter (RenderNode node, RenderingSurface canvas);

class RenderingSurface {

  // ... (API similar to <canvas>'s 2D API)

  void paintChild(RenderNode node);
    // inserts a "paint this child" instruction in this canvas's display list.
    // the child's display list, transformed by the child's x and y coordinates, will be inserted into this
    // display list during painting.
}
```


The default framework provides global hooks for extending the painting of:

 - borders
 - backgrounds

These are called during the default framework's layout managers'
paint() functions. They are also made available so that other people
can call them from their paint() functions.



Default Styles
--------------

In the constructors for the default elements, they add to themselves
StyleDeclaration objects as follows:

* ``span``
* ``a``
  These all add to themselves the same declaration as follows:
```javascript
let d = new StyleDeclaration();
d[pDisplay] = new ObjectStyleValue(InlineLayoutManager);
this.style.addStyles(d);
```

* ``t``
  This adds to itself the declaration as follows:
```javascript
let d = new StyleDeclaration();
d[pDisplay] = new ObjectStyleValue(ParagraphLayoutManager);
this.style.addStyles(d);
```

The other elements don't have any default styles.

These declarations are all shared between all the elements (so e.g. if
you reach in and change the declaration that was added to a ``span``
element, you're going to change the styles of all the other
default-hidden elements). (In other words, in the code snippets above,
the ``d`` variable is initialised in shared code, and only the
addStyles() call is per-element.)
