Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1058)

Unified Diff: sky/specs/style.md

Issue 1142853006: [Specs] Remove all the obsolete specs. (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « sky/specs/script.md ('k') | sky/specs/style2.md » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: sky/specs/style.md
diff --git a/sky/specs/style.md b/sky/specs/style.md
deleted file mode 100644
index 2f878bb844f066a5487097de760d50d9e605c8bd..0000000000000000000000000000000000000000
--- a/sky/specs/style.md
+++ /dev/null
@@ -1,1082 +0,0 @@
-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.)
« no previous file with comments | « sky/specs/script.md ('k') | sky/specs/style2.md » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698