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 "@document",
optionally followed by a pseudo-element, as in:

```css
@document::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 sky:core,
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

// sky:core 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, sky:core 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.


Cascade
-------

Simultaneously walk the tree rooted at the application Document,
taking into account shadow trees and child distribution, and the tree
rooted at the document'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
------

sky:core 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);
```

sky:core 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.)
