| Index: sky/specs/style2.md
|
| diff --git a/sky/specs/style2.md b/sky/specs/style2.md
|
| deleted file mode 100644
|
| index 1a2cec2db3cc3ec47154a3bf68878f8212a58156..0000000000000000000000000000000000000000
|
| --- a/sky/specs/style2.md
|
| +++ /dev/null
|
| @@ -1,348 +0,0 @@
|
| -Sky Style Language
|
| -==================
|
| -
|
| -This is a trimmed down version of the API in (style.md)[style.md]
|
| -that is intended to be a stepping stone to the long-term world where
|
| -there are no hard-coded properties in the engine.
|
| -
|
| -The Sky style API looks like the following:
|
| -
|
| -```dart
|
| -
|
| - // all properties can be set as strings:
|
| - element.style['color'] = 'blue';
|
| -
|
| - // some properties have dedicated APIs
|
| - // color
|
| - element.style.color.red += 1; // 0..255
|
| - element.style.color.blue += 10; // 0..255
|
| - element.style.color.green = 255; // 0..255
|
| - element.style.color.alpha = 128; // 0..255
|
| - // transform
|
| - element.style.transform..reset()
|
| - ..translate(100, 100)
|
| - ..rotate(PI/8)
|
| - ..translate(-100, -100);
|
| - element.style.transform.translate(10, 0);
|
| - // height, width
|
| - element.style.height.auto = true;
|
| - if (element.style.height.auto)
|
| - element.style.height.pixels = 10;
|
| - element.style.height.pixels += 1;
|
| - element.style.height.em = 1;
|
| -
|
| - // each property with a dedicated API defines a shorthand setter
|
| - // style.transform takes a matrix:
|
| - element.style.transform = new Matrix(1.0, 0.0, 0.0, 1.0, 0.0, 0.0);
|
| - // style.color takes a 32bit int:
|
| - element.style.color = 0xFF009900;
|
| - // style.height and style.width takes pixels or the constant 'auto':
|
| - element.style.height = auto;
|
| - element.style.width = 100;
|
| - // all properties with a dedicated API can also be set to null, inherit, or initial:
|
| - element.style.transform = null; // unset the property
|
| - element.style.color = initial; // set it to its initial value
|
| - element.style.color = inherit; // make it get its parent's value
|
| -
|
| - // you can create a blank StyleDeclaration object:
|
| - var style = new StyleDeclaration();
|
| - // you can replace an element's StyleDeclaration object wholesale:
|
| - element.style = style;
|
| - // you can clone a StyleDeclaration object:
|
| - var style2 = new StyleDeclaration.clone(style);
|
| -```
|
| -
|
| -The dart:sky library contains the following to define this API:
|
| -
|
| -```dart
|
| -import 'dart:mirrors';
|
| -import 'dart:math';
|
| -
|
| -typedef void StringSetter(Symbol propertySymbol, StyleDeclaration declaration, String value);
|
| -typedef String StringGetter(Symbol propertySymbol, StyleDeclaration declaration);
|
| -typedef Property ObjectConstructor(Symbol propertySymbol, StyleDeclaration declaration);
|
| -
|
| -class PropertyTable {
|
| - const PropertyTable({this.symbol, this.inherited, this.stringGetter, this.stringSetter, this.objectConstructor});
|
| - final Symbol symbol;
|
| - final bool inherited;
|
| - final StringSetter stringSetter;
|
| - final StringGetter stringGetter;
|
| - final ObjectConstructor objectConstructor;
|
| -}
|
| -
|
| -Map<Symbol, PropertyTable> _registeredProperties = new Map<Symbol, PropertyTable>();
|
| -void registerProperty(PropertyTable data) {
|
| - assert(data.symbol is Symbol);
|
| - assert(data.inherited is bool);
|
| - assert(data.stringSetter is StringSetter);
|
| - assert(data.stringGetter is StringGetter);
|
| - assert(data.objectConstructor == null || data.objectConstructor is ObjectConstructor);
|
| - assert(!_registeredProperties.containsKey(data.symbol));
|
| - _registeredProperties[data.symbol] = data;
|
| -}
|
| -
|
| -@proxy
|
| -class StyleDeclaration {
|
| - StyleDeclaration() { this._init(); }
|
| - StyleDeclaration.clone(StyleDeclaration template) { this.init(template); }
|
| - external void _init([StyleDeclaration template]); // O(1)
|
| - // This class has C++-backed internal state representing the
|
| - // properties known to the system. It's assumed that Property
|
| - // subclasses are also C++-backed and can directly manipulate this
|
| - // internal state.
|
| - // If the argument 'template' is provided, then this should be a clone
|
| - // of the styles of the template StyleDeclaration
|
| -
|
| - operator [](String propertyName) {
|
| - var propertySymbol = new Symbol(propertyName);
|
| - if (_registeredProperties.containsKey(propertySymbol))
|
| - return _registeredProperties[propertySymbol].stringGetter(propertySymbol, this);
|
| - throw new ArgumentError(propertyName);
|
| - }
|
| -
|
| - operator []=(String propertyName, String newValue) {
|
| - var propertySymbol = new Symbol(propertyName);
|
| - if (_registeredProperties.containsKey(propertySymbol))
|
| - return _registeredProperties[propertySymbol].stringSetter(propertySymbol, this, newValue);
|
| - throw new ArgumentError(propertyName);
|
| - }
|
| -
|
| - // some properties expose dedicated APIs so you don't have to use string manipulation
|
| - MapOfWeakReferences<Symbol, Property> _properties = new MapOfWeakReferences<Symbol, Property>();
|
| - noSuchMethod(Invocation invocation) {
|
| - Symbol propertySymbol;
|
| - if (invocation.isSetter) {
|
| - // when it's a setter, the name will be "foo=" rather than "foo"
|
| - String propertyName = MirrorSystem.getName(invocation.memberName);
|
| - assert(propertyName[propertyName.length-1] == '=');
|
| - propertySymbol = new Symbol(propertyName.substring(0, propertyName.length-1));
|
| - } else {
|
| - propertySymbol = invocation.memberName;
|
| - }
|
| - Property property;
|
| - if (!_properties.containsKey(propertySymbol)) {
|
| - if (_registeredProperties.containsKey(propertySymbol)) {
|
| - var constructor = _registeredProperties[propertySymbol].objectConstructor;
|
| - if (constructor == null)
|
| - return super.noSuchMethod(invocation);
|
| - property = constructor(propertySymbol, this);
|
| - } else {
|
| - return super.noSuchMethod(invocation);
|
| - }
|
| - } else {
|
| - property = _properties[propertySymbol];
|
| - }
|
| - if (invocation.isMethod) {
|
| - if (property is Function)
|
| - return Function.apply(property as Function, invocation.positionalArguments, invocation.namedArguments);
|
| - return super.noSuchMethod(invocation);
|
| - }
|
| - if (invocation.isSetter)
|
| - return Function.apply(property.setter, invocation.positionalArguments, invocation.namedArguments);
|
| - return property;
|
| - }
|
| -}
|
| -
|
| -const initial = const Object();
|
| -const inherit = const Object();
|
| -
|
| -abstract class Property {
|
| - Property(this.propertySymbol, this.declaration);
|
| - final StyleDeclaration declaration;
|
| - final Symbol propertySymbol;
|
| -
|
| - bool get inherited => _registeredProperties[propertySymbol].inherited;
|
| -
|
| - bool get initial => _isInitial();
|
| - void set initial (value) {
|
| - if (value == true)
|
| - return _setInitial();
|
| - throw new ArgumentError(value);
|
| - }
|
| -
|
| - bool get inherit => _isInherit();
|
| - void set inherit (value) {
|
| - if (value == true)
|
| - return _setInherit();
|
| - throw new ArgumentError(value);
|
| - }
|
| -
|
| - void setter(dynamic newValue) {
|
| - switch (newValue) {
|
| - case initial:
|
| - _setInitial();
|
| - case inherit:
|
| - _setInherit();
|
| - case null:
|
| - _unset();
|
| - default:
|
| - throw new ArgumentError(value);
|
| - }
|
| - }
|
| -
|
| - external bool _isInitial();
|
| - external void _setInitial();
|
| - external bool _isInherit();
|
| - external void _setInherit();
|
| - external void _unset();
|
| -}
|
| -```
|
| -
|
| -Sky defines the following properties, currently as part of the core,
|
| -but eventually this will be moved to the framework:
|
| -
|
| -```dart
|
| -class LengthProperty extends Property {
|
| - LengthProperty(Symbol propertySymbol, StyleDeclaration declaration) : super(propertySymbol, declaration);
|
| -
|
| - double get pixels => _getPixels();
|
| - void set pixels (value) => _setPixels(value);
|
| -
|
| - double get inches => _getPixels() / 96.0;
|
| - void set inches (value) => _setPixels(value * 96.0);
|
| -
|
| - double get em => _getEm();
|
| - void set em (value) => _setEm(value);
|
| -
|
| - void setter(dynamic value) {
|
| - if (value is num)
|
| - return _setPixels(value.toDouble());
|
| - return super.setter(value);
|
| - }
|
| -
|
| - external double _getPixels();
|
| - // throws StateError if the value isn't in pixels
|
| - external void _setPixels(double value);
|
| -
|
| - external double _getEm();
|
| - // throws StateError if the value isn't in pixels
|
| - external void _setEm(double value);
|
| -}
|
| -
|
| -const auto = const Object();
|
| -
|
| -class AutoLengthProperty extends LengthProperty {
|
| - AutoLengthProperty(Symbol propertySymbol, StyleDeclaration declaration) : super(propertySymbol, declaration);
|
| -
|
| - bool get auto => _isAuto();
|
| - void set auto (value) {
|
| - if (value == true)
|
| - _setAuto();
|
| - throw new ArgumentError(value);
|
| - }
|
| -
|
| - void setter(dynamic value) {
|
| - if (value == auto)
|
| - return _setAuto();
|
| - return super.setter(value);
|
| - }
|
| -
|
| - external bool _isAuto();
|
| - external void _setAuto();
|
| -}
|
| -
|
| -class ColorProperty extends Property {
|
| - ColorProperty(Symbol propertySymbol, StyleDeclaration declaration) : super(propertySymbol, declaration);
|
| -
|
| - int get alpha => _getRGBA() & 0xFF000000 >> 24;
|
| - void set alpha (int value) => _setRGBA(_getRGBA() & 0x00FFFFFF + value << 24);
|
| - int get red => _getRGBA() & 0x00FF0000 >> 16;
|
| - void set red (int value) => _setRGBA(_getRGBA() & 0xFF00FFFF + value << 16);
|
| - int get green => _getRGBA() & 0x0000FF00 >> 8;
|
| - void set green (int value) => _setRGBA(_getRGBA() & 0xFFFF00FF + value << 8);
|
| - int get blue => _getRGBA() & 0x000000FF >> 0;
|
| - void set blue (int value) => _setRGBA(_getRGBA() & 0xFFFFFF00 + value << 0);
|
| -
|
| - int get rgba => _getRGBA();
|
| - void set rgba (int value) => _setRGBA(value);
|
| -
|
| - void setter(dynamic value) {
|
| - if (value is int)
|
| - return _setRGBA(value);
|
| - return super.setter(value);
|
| - }
|
| -
|
| - external int _getRGBA();
|
| - // throws StateError if the value isn't a color
|
| - external void _setRGBA(int value);
|
| -}
|
| -
|
| -class Matrix {
|
| - const Matrix(this.a, this.b, this.c, this.d, this.e, this.f);
|
| -
|
| - // +- -+
|
| - // | a c e |
|
| - // | b d f |
|
| - // | 0 0 1 |
|
| - // +- -+
|
| -
|
| - final double a;
|
| - final double b;
|
| - final double c;
|
| - final double d;
|
| - final double e;
|
| - final double f;
|
| -}
|
| -
|
| -class TransformProperty extends Property {
|
| - TransformProperty(Symbol propertySymbol, StyleDeclaration declaration) : super(propertySymbol, declaration);
|
| -
|
| - void reset() => setTransform(1.0, 0.0, 0.0, 1.0, 0.0, 0.0);
|
| -
|
| - void translate(double dx, double dy) => transform(1.0, 0.0, 0.0, 1.0, dx, dy);
|
| - void scale(double dw, double dh) => transform(dw, 0.0, 0.0, dh, 0.0, 0.0);
|
| - void rotate(double theta) => transform(cos(theta), -sin(theta), sin(theta), cos(theta), 0.0, 0.0);
|
| -
|
| - // there's no "transform" getter since it would always return a new Matrix
|
| - // such that foo.transform == foo.transform would never be true
|
| - // and foo.transform = bar; bar == foo.transform would also never be true
|
| - // which is bad API
|
| -
|
| - external Matrix getTransform();
|
| - // throws StateError if the value isn't a matrix
|
| - // returns a new matrix each time
|
| - external void setTransform(a, b, c, d, e, f);
|
| - external void transform(a, b, c, d, e, f);
|
| - // throws StateError if the value isn't a matrix
|
| -}
|
| -
|
| -external void autoLengthPropertyStringSetter(Symbol propertySymbol, StyleDeclaration declaration, String value);
|
| -external String autoLengthPropertyStringGetter(Symbol propertySymbol, StyleDeclaration declaration);
|
| -external void colorPropertyStringSetter(Symbol propertySymbol, StyleDeclaration declaration, String value);
|
| -external String colorPropertyStringGetter(Symbol propertySymbol, StyleDeclaration declaration);
|
| -external void transformPropertyStringSetter(Symbol propertySymbol, StyleDeclaration declaration, String value);
|
| -external String transformPropertyStringGetter(Symbol propertySymbol, StyleDeclaration declaration);
|
| -
|
| -void _init() {
|
| - registerProperty(new PropertyTable(
|
| - symbol: #height,
|
| - inherited: false,
|
| - stringSetter: autoLengthPropertyStringSetter,
|
| - stringGetter: autoLengthPropertyStringGetter,
|
| - objectConstructor: (Symbol propertySymbol, StyleDeclaration declaration) =>
|
| - new AutoLengthProperty(propertySymbol, declaration)));
|
| - registerProperty(new PropertyTable(
|
| - symbol: #width,
|
| - inherited: false,
|
| - stringSetter: autoLengthPropertyStringSetter,
|
| - stringGetter: autoLengthPropertyStringGetter,
|
| - objectConstructor: (Symbol propertySymbol, StyleDeclaration declaration) =>
|
| - new AutoLengthProperty(propertySymbol, declaration)));
|
| - registerProperty(new PropertyTable(
|
| - symbol: #color,
|
| - inherited: false,
|
| - stringSetter: colorPropertyStringSetter,
|
| - stringGetter: colorPropertyStringGetter,
|
| - objectConstructor: (Symbol propertySymbol, StyleDeclaration declaration) =>
|
| - new ColorProperty(propertySymbol, declaration)));
|
| - registerProperty(new PropertyTable(
|
| - symbol: #transform,
|
| - inherited: false,
|
| - stringSetter: transformPropertyStringSetter,
|
| - stringGetter: transformPropertyStringGetter,
|
| - objectConstructor: (Symbol propertySymbol, StyleDeclaration declaration) =>
|
| - new TransformProperty(propertySymbol, declaration)));
|
| -}
|
| -```
|
| -
|
|
|