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

THIS IS NOT UP TO DATE

DO NOT IMPLEMENT THIS YET

It has not been Dartified.

It has not been converted to have a sane element.style API.

It has not been converted to have layout be interruptible using Futures.


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.)
