diff --git a/specs/README.md b/specs/README.md
index 2501e6a4ebb48494f7636bb76edc29e1e522e214..95bd287f2fbc040fc136a3b91cba68f0cf3ad46f 100644
--- a/specs/README.md
+++ b/specs/README.md
@@ -1,37 +1,2 @@
-The Sky Environment
-===================
-
-The main files loaded by the Sky environment are Sky files, though
-they can refer to binary resources like images and fonts.
-
-Sky files
----------
-
-Conventional MIME type: ``text/sky``, though this type is neither
-necessary nor sufficient to indicate that a file is a Sky file; only
-the signature matters for type dispatch of Sky files.
-
-Conventional extension: ``.sky``
-
-Signatures:
-
-For application files, one of the following:
-* ``23 21 6d 6f 6a 6f 20 6d 6f 6a 6f 3a 73 6b 79 0a`` ("``#!mojo mojo:sky\n``")
-* ``23 21 6d 6f 6a 6f 20 6d 6f 6a 6f 3a 73 6b 79 0d`` ("``#!mojo mojo:sky\r``")
-* ``23 21 6d 6f 6a 6f 20 6d 6f 6a 6f 3a 73 6b 79 20`` ("``#!mojo mojo:sky ``")
-
-For module files, one of the following:
-* ``53 4b 59 20 4d 4f 44 55 4c 45 0a`` ("``SKY MODULE\n``")
-* ``53 4b 59 20 4d 4f 44 55 4c 45 0d`` ("``SKY MODULE\r``")
-* ``53 4b 59 20 4d 4f 44 55 4c 45 20`` ("``SKY MODULE ``")
-
-
-Notes
------
-
-```
-magical imports:
- the mojo fabric API dart:mojo
- the mojom for the shell, proxying through C++ so that the shell pipe isn't exposed dart:mojo-shell
- the Sky API dart:sky
-```
+This file contains documentation for what we hope Sky to support in due course.
+It's mostly proposals. It's not intended to be comprehensive.
diff --git a/specs/animation.md b/specs/animation.md
deleted file mode 100644
index 06f72e6f802cfc952665d3da41c5309c5200e979..0000000000000000000000000000000000000000
--- a/specs/animation.md
+++ /dev/null
@@ -1,58 +0,0 @@
-Animation API
-=============
-
-```dart
-typedef void TimerCallback();
-
-external void _addTask({ TimerCallback callback, Duration budget, int bits, int priority, Queue queue });
-// see (runloop.md)[runloop.md] for the semantics of tasks and queues
-// _addTask() does the zone magic on callback
-
-external final Queue get _idleQueue;
-external final Queue get _paintQueue;
-external final Queue get _nextPaintQueue;
-
-class AnimationTimer extends Timer {
- factory whenIdle(TimerCallback callback, { Duration budget: 1.0 }) {
- if (budget.inMilliseconds > 1.0)
- budget = new Duration(milliseconds: 1.0);
- _addTask(callback: callback, budget: budget, bits: IdleTask, priority: IdlePriority, queue: _idleQueue);
- }
-
- factory beforePaint(TimerCallback callback, { int priority: 0 }) {
- _addTask(callback: callback, budget: new Duration(milliseconds: 1.0), bits: PaintTask, priority: priority, queue: _paintQueue);
- }
-
- factory nextFrame(TimerCallback callback, { int priority: 0 }) {
- _addTask(callback: callback, budget: new Duration(milliseconds: 1.0), bits: PaintTask, priority: priority, queue: _nextPaintQueue);
- }
-}
-```
-
-
-Easing Functions
-----------------
-
-```dart
-// part of the framework, not dart:sky
-
-typedef void AnimationCallback();
-
-abstract class EasingFunction {
- EasingFunction({double duration: 0.0, AnimationCallback completionCallback: null });
- double getFactor(Float time);
- // calls completionCallback if time >= duration
- // then returns a number ostensibly in the range 0.0 to 1.0
- // (but it could in practice go outside this range, e.g. for
- // animation styles that overreach then come back)
-}
-```
-
-If you want to have two animations simultaneously, e.g. two
-transforms, then you can add to the RenderNode's overrideStyles a
-StyleValue that combines other StyleValues, e.g. a
-"TransformStyleValueCombinerStyleValue", and then add to it the
-regular animated StyleValues, e.g. multiple
-"AnimatedTransformStyleValue" objects. A framework API could make
-setting all that up easy, given the right underlying StyleValue
-classes.
diff --git a/specs/builtins.md b/specs/builtins.md
deleted file mode 100644
index 90ac3dbc3f5a8e23e200ea7dccf30395693e4227..0000000000000000000000000000000000000000
--- a/specs/builtins.md
+++ /dev/null
@@ -1,112 +0,0 @@
-Built-In Elements
-=================
-
-```dart
-SKY MODULE
-
-
-```
diff --git a/specs/conventions.md b/specs/conventions.md
deleted file mode 100644
index 25c24e277d997e9064506c24d83d18f33770c7d5..0000000000000000000000000000000000000000
--- a/specs/conventions.md
+++ /dev/null
@@ -1,6 +0,0 @@
-Best Practices and Conventions for Sky Frameworks
-=================================================
-
-* elements should not expose convenience property accessors that just
- reflect content attributes.
-
diff --git a/specs/elements.md b/specs/elements.md
deleted file mode 100644
index 99bd845dd8b36fe75ca0a6b8d0a877feb1344e16..0000000000000000000000000000000000000000
--- a/specs/elements.md
+++ /dev/null
@@ -1,288 +0,0 @@
-Sky DOM APIs
-============
-
-```dart
-// ELEMENT TREE API
-
-abstract class Node extends EventTarget {
- @override
- external List getEventDispatchChain(); // O(N) in number of ancestors across shadow trees
- // implements EventTarget.getEventDispatchChain()
- // returns the event dispatch chain (including handling shadow trees)
-
- external Root get owner; // O(1)
-
- external ParentNode get parentNode; // O(1)
- Element get parentElement {
- if (parentNode is Element)
- return parentNode as Element;
- return null;
- }
-
- external Node get previousSibling; // O(1)
- Element get previousElementSibling {
- var result = previousSibling;
- while (result != null && result is! Element)
- result = result.previousSibling;
- return result as Element;
- }
-
- external Node get nextSibling; // O(1)
- Element get nextElementSibling {
- var result = nextSibling;
- while (result != null && result is! Element)
- result = result.nextSibling;
- return result as Element;
- }
-
- // TODO(ianh): rename insertBefore() and insertAfter() since the Web
- // has an insertBefore() that means something else. What's a good
- // name, though?
-
- external void _insertBefore(Node node); // O(N) in number of descendants
- // node must be Text or Element, parentNode must be non-null
- void insertBefore(List nodes) {
- List.forEach((node) {
- if (node is String)
- node = new Text(node);
- _insertBefore(node);
- });
- }
-
- external void _insertAfter(Node node); // O(N) in number of arguments plus all their descendants
- // node must be Text or Element, parentNode must be non-null
- void insertAfter(List nodes) {
- var lastNode = this;
- List.forEach((node) {
- if (node is String)
- node = new Text(node);
- lastNode._insertAfter(node);
- lastNode = node;
- });
- }
-
- void replaceWith(List nodes) {
- if (nextSibling != null) {
- var anchor = nextSibling;
- remove(); // parentNode can't be null here, so this won't throw
- anchor.insertBefore(nodes);
- } else {
- var anchor = parentNode;
- remove(); // throws if parentNode is null
- anchor.append(nodes);
- }
- }
-
- external void remove(); // O(N) in number of descendants
- // parentNode must be non-null
-
- // called when parentNode changes
- // this is why insertBefore(), append(), et al, are O(N) -- the whole affected subtree is walked
- // mutating the element tree from within this is strongly discouraged, since it will result in the
- // callbacks being invoked while the element tree is in a different state than implied by the callbacks
- external void parentChangedCallback(ParentNode oldParent, ParentNode newParent); // O(N) in descendants
- // default implementation calls attached/detached
- void attachedCallback() { }
- void detachedCallback() { }
-
- external List getDestinationInsertionPoints(); // O(N) in number of insertion points the node is in
- // returns the elements to which this element was distributed
-
- external Node cloneNode({bool deep: false}); // O(1) if deep=false, O(N) in the number of descendants if deep=true
-
- external ElementStyleDeclarationList get style; // O(1)
- // for nodes that aren't in the ApplicationRoot's composed tree,
- // returns null (so in particular orphaned subtrees and nodes in
- // module Roots don't have one, nor do shadow tree Roots)
- // also always returns null for ContentElement elements
- // -- should be (lazily) updated when the node's parent chain
- // changes (same time as, e.g., the id hashtable is marked
- // dirty)
-
- external RenderNode get renderNode; // O(1)
- // this will be null until the first time it is rendered
- // it becomes null again when it is taken out of the rendering (see style.md)
-
- Type getLayoutManager() => null; // O(1)
-
- void resetLayoutManager() { // O(1)
- if (renderNode != null) {
- renderNode._layoutManager = null;
- renderNode._needsManager = true;
- }
- }
-}
-
-abstract class ParentNode extends Node {
- external Node get firstChild; // O(1)
- Element get firstElementChild {
- var result = firstChild;
- while (result != null && result is! Element)
- result = result.nextSibling;
- return result as Element;
- }
-
- external Node get lastChild; // O(1)
- Element get lastElementChild {
- var result = lastChild;
- while (result != null && result is! Element)
- result = result.previousSibling;
- return result as Element;
- }
-
- // Returns a new List every time.
- external List getChildren(); // O(N) in number of child nodes
- List getChildElements() {
- // that the following works without a cast is absurd
- return getChildren().where((node) => node is Element).toList();
- }
-
- external void _appendChild(Node node); // O(N) in number of descendants
- // node must be Text or Element
- void appendChild(node) {
- if (node is String)
- node = new Text(node);
- _appendChild(node);
- }
- void append(List nodes) {
- nodes.forEach(appendChild);
- }
-
- external void _prependChild(Node node); // O(N) in number of descendants
- // node must be Text or Element
- void prependChild(node) {
- if (node is String)
- node = new Text(node);
- _prependChild(node);
- }
- void prepend(List nodes) {
- // note: not implemented in terms of _prependChild()
- if (firstChild != null)
- firstChild.insertBefore(nodes);
- else
- append(nodes);
- }
-
- external void removeChildren(); // O(N) in number of descendants
- void setChild(node) {
- removeChildren();
- appendChild(node);
- }
- void setChildren(List nodes) {
- removeChildren();
- append(nodes);
- }
-}
-
-class Attr {
- const Attr (this.name, [this.value = '']); // O(1)
- final String name; // O(1)
- final String value; // O(1)
-}
-
-// @hasShadow annotation for registering elements
-class _HasShadow {
- const _HasShadow();
-}
-const hasShadow = const _HasShadow();
-
-abstract class Element extends ParentNode {
- Element({Map attributes: null,
- List children: null,
- Module hostModule: null}) { // O(M+N), M = number of attributes, N = number of children nodes plus all their descendants
- var shadowClass = reflectClass(hasShadow.runtimeType);
- var shadowAnnotations = reflect(this).type.metadata.where((mirror) => mirror.type == shadowClass);
- if (shadowAnnotations.length > 2)
- throw new StateError('@hasShadow specified multiple times on ' + currentMirrorSystem().getName(reflectClass(this.runtimeType).simpleName));
- bool needsShadow = shadowAnnotations.length == 1;
- if (children != null)
- children = children.map((node) => node is String ? new Text(node) : node).toList();
- this._initElement(attributes, children, hostModule, needsShadow);
- }
- external void _initElement(Map attributes, List children, Module hostModule, bool needsShadow);
- // initialises the internal attributes table, which is a ordered list
- // appends the given children nodes
- // children must be Text or Element
- // if needsShadow is true, creates a shadow tree
-
- external bool hasAttribute(String name); // O(N) in number of attributes
- external String getAttribute(String name); // O(N) in number of attributes
- external void setAttribute(String name, [String value = '']); // O(N) in number of attributes
- external void removeAttribute(String name); // O(N) in number of attributes
- // calling setAttribute() with a null value removes the attribute
- // (calling it without a value sets it to the empty string)
-
- // Returns a new Array and new Attr instances every time.
- external List getAttributes(); // O(N) in number of attributes
-
- external Root get shadowRoot; // O(1)
- // returns the shadow root
-
- void endTagParsedCallback() { }
- void attributeChangedCallback(String name, String oldValue, String newValue) { }
- // name will never be null when this is called by sky
-
- // TODO(ianh): does a node ever need to know when it's been redistributed?
-
- @override
- Type getLayoutManager() { // O(1)
- if (renderNode)
- return renderNode.getProperty(phDisplay);
- return super.getLayoutManager();
- }
-}
-
-class Text extends Node {
- external Text([String value = '']); // O(1)
-
- external String get value; // O(1)
- external void set (String value); // O(1)
-
- void valueChangedCallback(String oldValue, String newValue) { }
-
- @override
- Type getLayoutManager() => TextLayoutManager; // O(1)
-}
-
-class Fragment extends ParentNode {
- Fragment({List children}); // O(N) in number of arguments plus all their descendants
- // children must be String, Text, or Element
-}
-
-class Root extends ParentNode {
- Root({List children: null, this.host}) { // O(N) in number of children nodes plus all their descendants
- if (children != null)
- children = children.map((node) => node is String ? new Text(node) : node).toList();
- this._initRoot(children);
- }
- external void _initRoot(List children);
- // appends the given children nodes
- // children must be Text or Element
-
- final Element host;
-
- external Element findId(String id); // O(1)
- // throws if id is null
-}
-
-class ApplicationRoot extends Root {
- ApplicationRoot ({List children}) : super(children: children); // O(N) in number of children nodes arguments plus all their descendants
-
- @override
- Type getLayoutManager() => rootLayoutManager; // O(1)
-}
-
-Type rootLayoutManager = BlockLayoutManager; // O(1)
-
-class SelectorQuery {
- external SelectorQuery(String selector); // O(F()) where F() is the complexity of the selector
-
- external bool matches(Element element); // O(F())
- external Element find(Node root); // O(N*F())+O(M) where N is the number of descendants and M the average depth of the tree
- external List findAll(Node root); // O(N*F())+O(N*M) where N is the number of descendants and M the average depth of the tree
- // find() and findAll() throw if the root is not one of the following:
- // - Element
- // - Fragment
- // - Root
-}
-```
diff --git a/specs/frameworks.md b/specs/frameworks.md
deleted file mode 100644
index f7d91a517f6f7347e3687548a8bd79b832b43853..0000000000000000000000000000000000000000
--- a/specs/frameworks.md
+++ /dev/null
@@ -1,31 +0,0 @@
-Frameworks
-----------
-
-Sky is intended to support multiple frameworks. Here is one way you
-could register a custom element using Dart annotations:
-
-```dart
-// @tagname annotation for registering elements
-// only useful when placed on classes that inherit from Element
-class tagname extends AutomaticMetadata {
- const tagname(this.name);
- final String name;
- void init(DeclarationMirror target, Module module, ScriptElement script) {
- assert(target is ClassMirror);
- if (!(target as ClassMirror).isSubclassOf(reflectClass(Element)))
- throw new UnsupportedError('@tagname can only be used on descendants of Element');
- module.registerElement(name, (target as ClassMirror).reflectedType);
- }
-}
-```
-
-A framework that used the above code could use the following code to
-get the tag name of an element:
-
-```dart
-String getTagName(Element element) { // O(N) in number of annotations on the class
- // throws a StateError if the class doesn't have an @tagname annotation
- var tagnameClass = reflectClass(tagname);
- return (reflectClass(element.runtimeType).metadata.singleWhere((mirror) => mirror.type == tagnameClass).reflectee as tagname).name;
-}
-```
diff --git a/specs/markup.md b/specs/markup.md
deleted file mode 100644
index b35f937c6fbb36ced1b4ebc4483fcaf592c984eb..0000000000000000000000000000000000000000
--- a/specs/markup.md
+++ /dev/null
@@ -1,222 +0,0 @@
-Sky Markup: Syntax
-==================
-
-A Sky file must consist of the following components:
-
- 1. If the file is intended to be a top-level Sky application, the
- string "``#!mojo mojo:sky``" followed by a U+0020, U+000A or
- U+000D character.
-
- If the file is intended to be a module, then the string "SKY", a
- U+0020 (space) character, the string "MODULE", and a U+0020,
- U+000A or U+000D character.
-
- These signatures make it more difficult to e.g. embed some Sky
- markup into a PNG and then cause someone to import that image as a
- module.
-
- 2. Zero or more of the following, in any order:
- - comments
- - text
- - escapes
- - elements
-
-Sky files must be encoded using UTF-8.
-
-A file that doesn't begin with the "``#!mojo mojo:sky``" signature
-isn't a Sky application file. For example:
-
- #!mojo https://example.com/runtimes/sky.asmjs
- Hello World
-
-...is not a Sky file, even if ``https://example.com/runtimes/sky.asmjs``
-is an implementation of the Sky runtime: it's just a file intended
-specifically for that runtime.
-
-The ``mojo:sky`` URL represents the generic Sky runtime provided by
-your Mojo runtime vendor.
-
-
-Comments
---------
-
-Comments start with the sequence "````", where the start and end hyphens don't overlap.
-In between these characters, any sequence of characters is allowed
-except "``-->``", which terminates the comment. Comments cannot,
-therefore, be nested.
-
-
-Text
-----
-
-Any sequence of Unicode characters other than ``<``, ``&``, and
-U+0000.
-
-
-Escapes
--------
-
-There are three kinds of escapes:
-
-### Hex
-
-They begin with the sequence ```` or ````, followed by a
-sequence of hex characters (lowercase or uppercase), followed by a
-semicolon. The number 0 is not allowed.
-
-### Decimal
-
-They begin with the sequence ```` or ````, followed by a
-sequence of decimal characters, followed by a semicolon. The number 0
-is not allowed.
-
-### Named
-
-They begin with the sequence ``&``, followed by any characters,
-followed by a semicolon.
-
-The following names work:
-
-| Name | Character | Unicode |
-| ---- | --------- | ------- |
-| `lt` | `<` | U+003C LESS-THAN SIGN character |
-| `gt` | `>` | U+003E GREATER-THAN SIGN character |
-| `amp` | `&` | U+0026 AMPERSAND character |
-| `apos` | `'` | U+0027 APOSTROPHE character |
-| `quot` | `"` | U+0022 QUOTATION MARK character |
-
-
-Elements
---------
-
-An element consists of the following:
-
-1. ``<``
-2. Tag name: A sequence of characters other than ``/``, ``>``,
- U+0020, U+000A, U+000D (whitespace).
-3. Zero or more of the following:
- 1. One or more U+0020, U+000A, U+000D (whitespace).
- 2. Attribute name: A sequence of characters other than ``/``,
- ``=``, ``>``, U+0020, U+000A, U+000D (whitespace).
- 3. Optionally:
- 1. Zero or more U+0020, U+000A, U+000D (whitespace) characters.
- 2. ``=``
- 3. Zero or more U+0020, U+000A, U+000D (whitespace) characters.
- 4. Attribute value: Either:
- - ``'`` followed by attribute text other than ``'``
- followed by a terminating ``'``.
- - ``"`` followed by attribute text other than ``'``
- followed by a terminating ``"``.
- - attribute text other than ``/``, ``>``,
- U+0020, U+000A, U+000D (whitespace).
- "Attribute text" is escapes or any unicode characters other
- than U+0000.
-4. Either:
- - For a void element:
- 1. ``/``, indicating an empty element.
- 2. ``>``
- - For a non-void element:
- 2. ``>``
- 3. The element's contents:
- - If the element's tag name is ``script``, then any sequence of
- characters other than U+0000, but there must not be the
- substring ````
-
-
-Sky Markup: Elements
-====================
-
-The Sky language consists of very few elements, since it is expected
-that everything of note would be provided by frameworks.
-
-The following elements are implicitly registered by default, even if
-you haven't imported anything. You can get to their constructors if
-you import dart:sky (basically, dart:sky is always imported by defaul;
-it's the runtime library). None of these elements have shadow trees.
-
-````
- - Downloads and imports foo.sky in the background.
-
-````
- - Downloads and imports foo.sky in the background, using "foo" as its
- local name (see ````': Create an end tag token, and
- let its tag name be the string '``style``'. Switch to the
- **before attribute name** state without consuming the character.
-
-* Anything else: Emit '````': Emit character tokens for '``<>``'. Consume the current
- character. Switch to the **data** state.
-
-* '``0``'..'``9``', '``a``'..'``z``', '``A``'..'``Z``',
- '``-``', '``_``', '``.``': Create a start tag token, let its
- tag name be the current character, consume the current character and
- switch to the **tag name** state.
-
-* Anything else: Emit the character token for '``<``'. Switch to the
- **data** state without consuming the current character.
-
-
-#### **Close tag** state ####
-
-If the current character is...
-
-* '``>``': Emit an automatic end tag token. Switch to the **data**
- state.
-
-* '``0``'..'``9``', '``a``'..'``z``', '``A``'..'``Z``',
- '``-``', '``_``', '``.``': Create an end tag token, let its
- tag name be the current character, consume the current character and
- switch to the **tag name** state.
-
-* Anything else: Emit the character tokens for '````'. Switch to
- the **data** state without consuming the current character.
-
-
-#### **Tag name** state ####
-
-If the current character is...
-
-* U+0020, U+000A: Consume the current character. Switch to the
- **before attribute name** state.
-
-* '``/``': Consume the current character. Switch to the **void tag**
- state.
-
-* '``>``': Consume the current character. Switch to the **after
- tag** state.
-
-* Anything else: Append the current character to the tag name, and
- consume the current character. Stay in this state.
-
-
-#### **Void tag** state ####
-
-If the current character is...
-
-* '``>``': Consume the current character. Switch to the **after void
- tag** state.
-
-* Anything else: Switch to the **before attribute name** state without
- consuming the current character.
-
-
-#### **Before attribute name** state ####
-
-If the current character is...
-
-* U+0020, U+000A: Consume the current character. Stay in this state.
-
-* '``/``': Consume the current character. Switch to the **void tag**
- state.
-
-* '``>``': Consume the current character. Switch to the **after
- tag** state.
-
-* Anything else: Create a new attribute in the tag token, and set its
- name to the current character and its value to the empty string.
- Consume the current character. Switch to the **attribute name**
- state.
-
-
-#### **Attribute name** state ####
-
-If the current character is...
-
-* U+0020, U+000A: Consume the current character. Switch to the **after
- attribute name** state.
-
-* '``/``': Consume the current character. Switch to the **void tag**
- state.
-
-* '``=``': Consume the current character. Switch to the **before
- attribute value** state.
-
-* '``>``': Consume the current character. Switch to the **after
- tag** state.
-
-* Anything else: Append the current character to the most recently
- added attribute's name, and consume the current character. Stay in
- this state.
-
-
-#### **After attribute name** state ####
-
-If the current character is...
-
-* U+0020, U+000A: Consume the current character. Stay in this state.
-
-* '``/``': Consume the current character. Switch to the **void tag**
- state.
-
-* '``=``': Consume the current character. Switch to the **before
- attribute value** state.
-
-* '``>``': Consume the current character. Switch to the **after
- tag** state.
-
-* Anything else: Create a new attribute in the tag token, and set its
- name to the current character and its value to the empty string.
- Consume the current character. Switch to the **attribute name**
- state.
-
-
-#### **Before attribute value** state ####
-
-If the current character is...
-
-* U+0020, U+000A: Consume the current character. Stay in this state.
-
-* '``>``': Consume the current character. Switch to the **after
- tag** state.
-
-* '``'``': Consume the current character. Switch to the
- **single-quoted attribute value** state.
-
-* '``"``': Consume the current character. Switch to the
- **double-quoted attribute value** state.
-
-* Anything else: Switch to the **unquoted attribute value** state
- without consuming the current character.
-
-
-#### **Single-quoted attribute value** state ####
-
-If the current character is...
-
-* '``'``': Consume the current character. Switch to the
- **before attribute name** state.
-
-* '``&``': Consume the character and switch to the **character
- reference** state, with the _return state_ set to the
- **single-quoted attribute value** state and the _emitting operation_
- being to append the given character to the value of the most
- recently added attribute.
-
-* Anything else: Append the current character to the value of the most
- recently added attribute. Consume the current character. Stay in
- this state.
-
-
-#### **Double-quoted attribute value** state ####
-
-If the current character is...
-
-* '``"``': Consume the current character. Switch to the
- **before attribute name** state.
-
-* '``&``': Consume the character and switch to the **character
- reference** state, with the _return state_ set to the
- **double-quoted attribute value** state and the _emitting operation_
- being to append the given character to the value of the most
- recently added attribute.
-
-* Anything else: Append the current character to the value of the most
- recently added attribute. Consume the current character. Stay in
- this state.
-
-
-#### **Unquoted attribute value** state ####
-
-If the current character is...
-
-* U+0020, U+000A: Consume the current character. Switch to the
- **before attribute name** state.
-
-* '``>``': Consume the current character. Switch to the **after tag**
- state.
-
-* '``&``': Consume the character and switch to the **character
- reference** state, with the _return state_ set to the **unquoted
- attribute value** state, and the _emitting operation_ being to
- append the given character to the value of the most recently added
- attribute.
-
-* Anything else: Append the current character to the value of the most
- recently added attribute. Consume the current character. Stay in
- this state.
-
-
-#### **After tag** state ####
-
-Emit the tag token.
-
-If the tag token was a start tag token and the tag name was
-'``script``', then switch to the **script raw data** state.
-
-If the tag token was a start tag token and the tag name was
-'``style``', then switch to the **style raw data** state.
-
-Otherwise, switch to the **data** state.
-
-
-#### **After void tag** state ####
-
-Emit the tag token.
-
-If the tag token is a start tag token, emit an end tag token with the
-same tag name.
-
-Switch to the **data** state.
-
-
-#### **Comment start 1** state ####
-
-If the current character is...
-
-* '``-``': Consume the character and switch to the **comment start
- 2** state.
-
-* Anything else: Emit character tokens for '````': Consume the character and switch to the **data** state.
-
-* '``-``': Consume the character, but stay in this state.
-
-* Anything else: Consume the character, and switch to the **comment**
- state.
-
-
-#### **Character reference** state ####
-
-Let _raw value_ be the string '``&``'.
-
-Append the current character to _raw value_.
-
-If the current character is...
-
-* '``#``': Consume the character, and switch to the **numeric
- character reference** state.
-
-* '``0``'..'``9``', '``a``'..'``f``', '``A``'..'``F``': switch to the
- **named character reference** state without consuming the current
- character.
-
-* Anything else: Run the _emitting operation_ for all but the last
- character in _raw value_, and switch to the _return state_ without
- consuming the current character.
-
-
-#### **Numeric character reference** state ####
-
-Append the current character to _raw value_.
-
-If the current character is...
-
-* '``x``', '``X``': Consume the character and switch to the **before
- hexadecimal numeric character reference** state.
-
-* '``0``'..'``9``': Let _value_ be the numeric value of the
- current character interpreted as a decimal digit, consume the
- character, and switch to the **decimal numeric character reference**
- state.
-
-* Anything else: Run the _emitting operation_ for all but the last
- character in _raw value_, and switch to the _return state_ without
- consuming the current character.
-
-
-#### **Before hexadecimal numeric character reference** state ####
-
-Append the current character to _raw value_.
-
-If the current character is...
-
-* '``0``'..'``9``', '``a``'..'``f``', '``A``'..'``F``':
- Let _value_ be the numeric value of the current character
- interpreted as a hexadecimal digit, consume the character, and
- switch to the **hexadecimal numeric character reference** state.
-
-* Anything else: Run the _emitting operation_ for all but the last
- character in _raw value_, and switch to the _return state_ without
- consuming the current character.
-
-
-#### **Hexadecimal numeric character reference** state ####
-
-Append the current character to _raw value_.
-
-If the current character is...
-
-* '``0``'..'``9``', '``a``'..'``f``', '``A``'..'``F``':
- Let _value_ be sixteen times _value_ plus the numeric value of the
- current character interpreted as a hexadecimal digit.
-
-* '``;``': Consume the character. If _value_ is between 0x0001 and
- 0x10FFFF inclusive, but is not between 0xD800 and 0xDFFF inclusive,
- run the _emitting operation_ with a unicode character having the
- scalar value _value_; otherwise, run the _emitting operation_ with
- the character U+FFFD. Then, in either case, switch to the _return
- state_.
-
-* Anything else: Run the _emitting operation_ for all but the last
- character in _raw value_, and switch to the _return state_ without
- consuming the current character.
-
-
-#### **Decimal numeric character reference** state ####
-
-Append the current character to _raw value_.
-
-If the current character is...
-
-* '``0``'..'``9``': Let _value_ be ten times _value_ plus the
- numeric value of the current character interpreted as a decimal
- digit.
-
-* '``;``': Consume the character. If _value_ is between 0x0001 and
- 0x10FFFF inclusive, but is not between 0xD800 and 0xDFFF inclusive,
- run the _emitting operation_ with a unicode character having the
- scalar value _value_; otherwise, run the _emitting operation_ with
- the character U+FFFD. Then, in either case, switch to the _return
- state_.
-
-* Anything else: Run the _emitting operation_ for all but the last
- character in _raw value_, and switch to the _return state_ without
- consuming the current character.
-
-
-#### **Named character reference** state ####
-
-Append the current character to _raw value_.
-
-If the current character is...
-
-* '``;``': Consume the character.
- If the _raw value_ is...
-
- - '``&``: Emit Run the _emitting operation_ for the character
- '``&``'.
-
- - '``'``: Emit Run the _emitting operation_ for the character
- '``'``'.
-
- - '``>``: Emit Run the _emitting operation_ for the character
- '``>``'.
-
- - '``<``: Emit Run the _emitting operation_ for the character
- '``<``'.
-
- - '``"``: Emit Run the _emitting operation_ for the character
- '``"``'.
-
- Then, switch to the _return state_.
-
-* '``0``'..'``9``', '``a``'..'``z``', '``A``'..'``Z``': Consume the
- character and stay in this state.
-
-* Anything else: Run the _emitting operation_ for all but the last
- character in _raw value_, and switch to the _return state_ without
- consuming the current character.
-
-
-Token cleanup stage
--------------------
-
-Replace each sequence of character tokens with a single string token
-whose value is the concatenation of all the characters in the
-character tokens.
-
-For each start tag token, remove all but the first name/value pair for
-each name (i.e. remove duplicate attributes, keeping only the first
-one).
-
-TODO(ianh): maybe sort the attributes?
-
-For each end tag token, remove the attributes entirely.
-
-If the token is a start tag token, notify the JavaScript token stream
-callback of the token.
-
-Then, pass the tokens to the tree construction stage.
-
-
-Tree construction stage
------------------------
-
-To construct a node tree from a _sequence of tokens_ and an element
-tree rooted at a `Root` node _root_ (this is implemented in JS):
-
-1. Initialize the _stack of open nodes_ to be _root_.
-2. Initialize _imported modules_ to an empty list.
-3. Consider each token _token_ in the _sequence of tokens_ in turn, as
- follows. If a token is to be skipped, then jump straight to the
- next token, without doing any more work with the skipped token.
- - If _token_ is a string token,
- 1. If the value of the token contains only U+0020 and U+000A
- characters, and there is no ``t`` element on the _stack of
- open nodes_, then skip the token.
- 2. Create a text node _node_ whose character data is the value of
- the token.
- 3. Append _node_ to the top node in the _stack of open nodes_.
- - If _token_ is a start tag token,
- 1. If the tag name isn't a registered tag name, then yield until
- _imported modules_ contains no entries with unresolved
- promises.
- 2. If the tag name is not registered, then let the ErrorElement
- constructor from dart:sky be the element constructor.
- Otherwise, let the element constructor be the registered
- element's constructor for that tag name in this module.
- 3. Create an element _node_ with the attributes given by the
- token by calling the constructor.
- 4. If _node_ is not an Element object, then let the constructor
- be the ErrorElement constructor and return to the previous
- step.
- 5. Append _node_ to the top node in the _stack of open nodes_.
- 6. Push _node_ onto the top of the _stack of open nodes_.
- 7. If _node_ is a ``template`` element, then:
- 1. Let _fragment_ be the ``Fragment`` object that the
- ``template`` element uses as its template contents
- container.
- 2. Push _fragment_ onto the top of the _stack of open nodes_.
- If _node_ is an ``import`` element, then:
- 1. Let ``url`` be the value of _node_'s ``src`` attribute.
- 2. Call ``parsing context``'s ``importModule()`` method,
- passing it ``url``.
- 3. Add the returned promise to _imported modules_; if _node_
- has an ``as`` attribute, associate the entry with that
- name.
- - If _token_ is an end tag token:
- 1. If the tag name is registered, let _tag name_ be that tag
- name. Otherwise, let _tag name_ be "error".
- 2. Let _node_ be the topmost node in the _stack of open nodes_
- whose tag name is _tag name_, if any. If there isn't one, skip
- this token.
- 3. If there's a ``template`` element in the _stack of open
- nodes_ above _node_, then skip this token.
- 4. Pop nodes from the _stack of open nodes_ until _node_ has been
- popped.
- 5. If _node_'s tag name is ``script``, then yield until _imported
- modules_ contains no entries with unresolved promises, then
- execute the script given by the element's contents, using the
- associated names as appropriate.
- - If _token_ is an automatic end tag token:
- 1. Pop the top node from the _stack of open nodes_, unless it is
- the _root_ node.
-4. Yield until _imported modules_ has no promises.
-5. Fire a ``load`` event at the _parsing context_ object.
diff --git a/specs/runloop.md b/specs/runloop.md
deleted file mode 100644
index b080090af1b1d6b4e2fe487d21d4fd569b36bbe2..0000000000000000000000000000000000000000
--- a/specs/runloop.md
+++ /dev/null
@@ -1,144 +0,0 @@
-Sky's Run Loop
-==============
-
-Sky has three task queues, named idle, frame, and nextFrame.
-
-When a task is run, it has a time budget, and if the time budget is
-exceeded, then a catchable DeadlineExceededException exception is
-fired.
-
-```dart
-class DeadlineExceededException implements Exception { }
-```
-
-There is a method you can use that guards your code against these
-exceptions:
-
-```dart
-typedef void Callback();
-external guardAgainstDeadlineExceptions(Callback callback);
-// runs callback.
-// if the time budget for the _task_ expires while the callback is
-// running, the callback isn't interrupted, but the method will throw
-// an exception once the callback returns.
-```
-
-When Sky is to *process a task queue until a particular time*, with a
-queue *relevant task queue*, bits *filter bits*, a time
-*particular time*, and an *idle rule* which is either "sleep" or
-"abort", it must run the following steps:
-
-1. Let *remaining time* be the time until the given *particular time*.
-2. If *remaining time* is less than or equal to zero, exit this
- algorithm.
-3. Let *task list* be the list of tasks in the *relevant task queue*
- that have bits that, when 'and'ed with *filter bits*, are equal to
- *filter bits*, whose required budget is less than or equal to
- *remaining time*; and whose due time, if any, has been reached.
-4. If *task list* is empty, then if *idle rule* is "sleep" then return
- to step 1, otherwise, exit this algorithm.
-5. Sort *task list* by the priority of each task, highest first.
-6. Remove the top task from *task list* from the *relevant task
- queue*, and let that be *selected task*.
-7. Run *selected task*, with a budget of *remaining time* or 1ms,
- whichever is shorter.
-8. Return to step 1.
-
-When Sky is to *drain a task queue for a specified time*, with a queue
-*relevant task queue*, bits *filter bits*, and a duration *budget*, it
-must run the following steps:
-
-2. Let *task list* be the list of tasks in the *relevant task queue*
- that have bits that, when 'or'ed with *filter bits*, are non-zero;
- and whose required budget is less than or equal to *budget*.
-4. If *task list* is empty, then exit.
-5. Sort *task list* by the priority of each task, highest first.
-6. Remove the top task from *task list* from the *relevant task
- queue*, and let that be *selected task*.
-7. Run *selected task*, with a budget of *budget*.
-8. Decrease *budget* with the amount of time that *selected task* took
- to run.
-9. If *selected task* threw an uncaught DeadlineExceededException
- exception, then cancel all the tasks in *relevant task queue*.
- Otherwise, return to step 2.
-
-Sky's run loop consists of running the following, at 120Hz (each loop
-takes 8.333ms):
-
-1. *Drain* the *frame task queue*, with bits
- `application.frameTaskBits`, for 1ms.
-
-2. Create a task that does the following, then run it with a budget of
- 1ms:
-
- 1. Update the render tree, including calling childAdded(),
- childRemoved(), and getLayoutManager() as needed, catching any
- exceptions other than DeadlineExceededException exceptions.
-
- If an exception is thrown by this, then the RenderNode tree will
- continue to not quite match the element tree, which is fine.
-
-3. If there are no tasks on the *idle task queue* with bits
- `LayoutKind`, create a task that tells the root node to layout if
- it has needsLayout or descendantNeedsLayout, mark that with
- priority 0 and bits `LayoutKind`, and add it to the *idle task
- queue*.
-
-4. *Process* the *idle task queue*, with bits `LayoutKind`, with a
- target time of t-1ms, where t is the time at which we have to send
- the frame to the GPU, and with an *idle rule* of "abort".
-
-5. Create a task that does the following, then run it with a budget of
- 1ms:
-
- 1. If there are no RenderNodes that need paint, abort.
-
- 2. Call the `paint()` callback of the RenderNode that was least
- recently marked as needing paint, catching any exceptions other
- than DeadlineExceededException exceptions.
-
- 3. Jump to step 1.
-
- If an exception is thrown by this, then some RenderNode objects
- will be out-of-date during the paint.
-
-6. Send frame to GPU.
-
-7. Replace the frame queue with the nextFrame queue, and let the
- nextFrame queue be an empty queue.
-
-8. *Process* the *idle task queue*, with bits
- `application.idleTaskBits`, with a target time of t, where t is the
- time at which we have to start the next frame's layout and paint
- computations, and with an *idle rule* of "sleep".
-
-TODO(ianh): Update the timings above to have some relationship to
-reality.
-
-TODO(ianh): Define an API so that the application can adjust the
-budgets.
-
-Task kinds and priorities
--------------------------
-
-Tasks scheduled by futures get the priority and task kind bits from
-the task they are scheduled from.
-
-```dart
-int IdlePriority = 0; // tasks that can be delayed arbitrarily
-int FutureLayoutPriority = 1000; // async-layout tasks
-int AnimationPriority = 3000; // animation-related tasks
-int InputPriority = 4000; // input events
-int ScrollPriority = 5000; // framework-fired events for scrolling
-
-// possible idle queue task bits
-int IdleKind = 0x01; // tasks that should run during the idle loop
-int LayoutKind = 0x02; // tasks that should run during layout
-int TouchSafeKind = 0x04; // tasks that should keep running while there is a pointer down
-int idleTaskBits = IdleKind; // tasks must have all these bits to run during idle loop
-int layoutTaskBits = LayoutKind; // tasks must have all these bits to run during layout
-
-// possible frame queue task bits
-// (there are none at this time)
-int frameTaskBits = 0x00; // tasks must have all these bits to run during the frame loop
-```
diff --git a/specs/script.md b/specs/script.md
deleted file mode 100644
index 4004283159ed787187667169ebb5eb24d20e19f2..0000000000000000000000000000000000000000
--- a/specs/script.md
+++ /dev/null
@@ -1,101 +0,0 @@
-Sky Script Language
-===================
-
-The Sky script language is Dart.
-
-The way that Sky integrates the module system with its script language
-is described in [modules.md](modules.md).
-
-All the APIs defined in this documentation, unless explicitly called
-out as being in a framework, are in the `dart:sky` built-in module.
-
-When a method in `dart:sky` defined as ``external`` receives an
-argument, it must type-check it, and, if the argument's value is the
-wrong type, then it must throw an ArgumentError as follows:
-
- throw new ArgumentError(value, name: name);
-
-...where "name" is the name of the argument. Type checking here
-includes rejecting nulls unless otherwise indicated or unless null is
-argument's default value.
-
-The following definitions are exposed in ``dart:sky``:
-
-```dart
-import 'dart:mirrors';
-
-abstract class AutomaticMetadata {
- const AutomaticMetadata();
- void init(DeclarationMirror target, Module module, ScriptElement script);
-
- static void runLibrary(LibraryMirror library, Module module, ScriptElement script) {
- library.declarations.values.toList() /* ..sort((DeclarationMirror a, DeclarationMirror b) {
- bool aHasLocation;
- try {
- aHasLocation = a.location != null;
- } catch(e) {
- aHasLocation = false;
- }
- bool bHasLocation;
- try {
- bHasLocation = b.location != null;
- } catch(e) {
- bHasLocation = false;
- }
- if (!aHasLocation)
- return bHasLocation ? 1 : 0;
- if (!bHasLocation)
- return -1;
- if (a.location.sourceUri != b.location.sourceUri)
- return a.location.sourceUri.toString().compareTo(b.location.sourceUri.toString());
- if (a.location.line != b.location.line)
- return a.location.line - b.location.line;
- return a.location.column - b.location.column;
- }) */
- ..forEach((DeclarationMirror d) {
- d.metadata.forEach((InstanceMirror i) {
- if (i.reflectee is AutomaticMetadata)
- i.reflectee.run(d, module, script);
- });
- });
- }
-}
-
-class AutomaticFunction extends AutomaticMetadata {
- const AutomaticFunction();
- void init(DeclarationMirror target, Module module, ScriptElement script) {
- assert(target is MethodMirror);
- MethodMirror f = target as MethodMirror;
- assert(!f.isAbstract);
- assert(f.isRegularMethod);
- assert(f.isTopLevel);
- assert(f.isStatic);
- assert(f.parameters.length == 1);
- assert(f.parameters[0].type == ScriptElement);
- assert(f.returnType == currentMirrorSystem().voidType);
- (f.owner as LibraryMirror).invoke(f.simpleName, [script]);
- }
-}
-const autorun = const AutomaticFunction();
-```
-
-Extensions
-----------
-
-The following as-yet unimplemented features of the Dart language are
-assumed to exist:
-
-* It is assumed that a subclass can define a constructor by reference
- to a superclass' constructor, wherein the subclass' constructor has
- the same arguments as the superclass' constructor and does nothing
- but invoke that superclass' constructor with the same arguments. The
- syntax for defining this is, within the class body for a class
- called ClassName:
-
-```dart
- ClassName = SuperclassName;
- ClassName.namedConstructor = SuperclassName.otherNamedConstructor;
-```
-
-* The reflection APIs (`dart:mirrors`) are assumed to reflect a
- library's declarations in source order.
diff --git a/specs/style.md b/specs/style.md
deleted file mode 100644
index 2f878bb844f066a5487097de760d50d9e605c8bd..0000000000000000000000000000000000000000
--- a/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 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 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