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

Side by Side Diff: sky/specs/style2.md

Issue 959473002: Specs: part 1 of the new approach to style (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Created 5 years, 10 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 unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 Sky Style Language
2 ==================
3
4 Note: This is a work in progress that will eventually replace
5 (style.md)[style.md].
6
7 The Sky style API looks like the following:
8
9 ```dart
10
11 // all properties can be set as strings:
12 element.style['color'] = 'blue';
13
14 // some properties have dedicated APIs
15 // color
16 element.style.color.red += 1; // 0..255
17 element.style.color.blue += 10; // 0..255
18 element.style.color.green = 255; // 0..255
19 element.style.color.alpha = 128; // 0..255
20 // transform
21 element.style.transform..reset()
22 ..translate(100, 100)
23 ..rotate(PI/8)
24 ..translate(-100, -100);
25 element.style.transform.translate(10, 0);
26 // height, width
27 element.style.height.auto = true;
28 if (element.style.height.auto)
29 element.style.height.pixels = 10;
30 element.style.height.pixels += 1;
31 element.style.height.em = 1;
32
33 // each property with a dedicated API defines a shorthand setter
34 // style.transform takes a matrix:
35 element.style.transform = new Matrix(1.0, 0.0, 0.0, 1.0, 0.0, 0.0);
36 // style.color takes a 32bit int:
37 element.style.color = 0xFF009900;
38 // style.height and style.width takes pixels or the constant 'auto':
39 element.style.height = auto;
40 element.style.width = 100;
41 // all properties with a dedicated API can also be set to null, inherit, or in itial:
42 element.style.transform = null; // unset the property
43 element.style.color = initial; // set it to its initial value
44 element.style.color = inherit; // make it get its parent's value
45
46 // you can create a blank StyleDeclaration object:
47 var style = new StyleDeclaration();
48 // you can replace an element's StyleDeclaration object wholesale:
49 element.style = style;
50 // you can clone a StyleDeclaration object:
51 var style2 = new StyleDeclaration.clone(style);
52 ```
53
54 The dart:sky library contains the following to define this API:
55
56 ```dart
57 import 'dart:mirrors';
58 import 'dart:math';
59
60 class WeakMap<Key, Value> {
61 Expando<Value> _map = new Expando<Value>();
62 operator[](Key key) => _map[key];
63 operator[]=(Key key, Value value) => _map[key] = value;
64 bool containsKey(Key key) => _map[key] != null;
65 }
66
67 typedef void StringSetter(Symbol propertySymbol, StyleDeclaration declaration, S tring value);
68 typedef String StringGetter(Symbol propertySymbol, StyleDeclaration declaration) ;
69 typedef Property ObjectConstructor(Symbol propertySymbol, StyleDeclaration decla ration);
70
71 class PropertyTable {
72 const PropertyTable({this.symbol, this.inherited, this.stringGetter, this.stri ngSetter, this.objectConstructor});
73 final Symbol symbol;
74 final bool inherited;
75 final StringSetter stringSetter;
76 final StringGetter stringGetter;
77 final ObjectConstructor objectConstructor;
78 }
79
80 Map<Symbol, PropertyTable> _registeredProperties = new Map<Symbol, PropertyTable >();
81 void registerProperty(PropertyTable data) {
82 assert(data.symbol is Symbol);
83 assert(data.inherited is bool);
84 assert(data.stringSetter is StringSetter);
85 assert(data.stringGetter is StringGetter);
86 assert(data.objectConstructor == null || data.objectConstructor is ObjectConst ructor);
87 assert(!_registeredProperties.containsKey(data.symbol));
88 _registeredProperties[data.symbol] = data;
89 }
90
91 @proxy
92 class StyleDeclaration {
93 StyleDeclaration() { this._init(); }
94 StyleDeclaration.clone(StyleDeclaration template) { this.init(template); }
95 external void _init([StyleDeclaration template]); // O(1)
96 // This class has C++-backed internal state representing the
97 // properties known to the system. It's assumed that Property
98 // subclasses are also C++-backed and can directly manipulate this
99 // internal state.
100 // If the argument 'template' is provided, then this should be a clone
101 // of the styles of the template StyleDeclaration
102
103 operator [](String propertyName) {
104 var propertySymbol = new Symbol(propertyName);
105 if (_registeredProperties.containsKey(propertySymbol))
106 return _registeredProperties[propertySymbol].stringGetter(propertySymbol, this);
107 throw new ArgumentError(propertyName);
108 }
109
110 operator []=(String propertyName, String newValue) {
111 var propertySymbol = new Symbol(propertyName);
112 if (_registeredProperties.containsKey(propertySymbol))
113 return _registeredProperties[propertySymbol].stringSetter(propertySymbol, this, newValue);
114 throw new ArgumentError(propertyName);
115 }
116
117 // some properties expose dedicated APIs so you don't have to use string manip ulation
118 WeakMap<Symbol, Property> _properties = new WeakMap<Symbol, Property>();
119 noSuchMethod(Invocation invocation) {
120 Symbol propertySymbol;
121 if (invocation.isSetter) {
122 // when it's a setter, the name will be "foo=" rather than "foo"
123 String propertyName = MirrorSystem.getName(invocation.memberName);
124 assert(propertyName[propertyName.length-1] == '=');
125 propertySymbol = new Symbol(propertyName.substring(0, propertyName.length- 1));
126 } else {
127 propertySymbol = invocation.memberName;
128 }
129 Property property;
130 if (!_properties.containsKey(propertySymbol)) {
131 if (_registeredProperties.containsKey(propertySymbol)) {
132 var constructor = _registeredProperties[propertySymbol].objectConstructo r;
133 if (constructor == null)
134 return super.noSuchMethod(invocation);
135 property = constructor(propertySymbol, this);
136 } else {
137 return super.noSuchMethod(invocation);
138 }
139 } else {
140 property = _properties[propertySymbol];
141 }
142 if (invocation.isMethod) {
143 if (property is Function)
144 return Function.apply(property as Function, invocation.positionalArgumen ts, invocation.namedArguments);
145 return super.noSuchMethod(invocation);
146 }
147 if (invocation.isSetter)
148 return Function.apply(property.setter, invocation.positionalArguments, inv ocation.namedArguments);
149 return property;
150 }
151 }
152
153 const initial = const Object();
154 const inherit = const Object();
155
156 abstract class Property {
157 Property(this.propertySymbol, this.declaration);
158 final StyleDeclaration declaration;
159 final Symbol propertySymbol;
160
161 bool get inherited => _registeredProperties[propertySymbol].inherited;
162
163 bool get initial => _isInitial();
164 void set initial (value) {
165 if (value == true)
166 return _setInitial();
167 throw new ArgumentError(value);
168 }
169
170 bool get inherit => _isInherit();
171 void set inherit (value) {
172 if (value == true)
173 return _setInherit();
174 throw new ArgumentError(value);
175 }
176
177 void setter(dynamic value) {
178 if (value == initial)
179 return _setInitial();
180 if (value == inherit)
181 return _setInitial();
182 if (value == null)
183 return _unset();
184 throw new ArgumentError(value);
185 }
186
187 external bool _isInitial();
188 external void _setInitial();
189 external bool _isInherit();
190 external void _setInherit();
191 external void _unset();
192 }
193 ```
194
195 Sky defines the following properties, currently as part of the core,
196 but eventually this will be moved to the framework:
197
198 ```dart
199 class LengthProperty extends Property {
200 LengthProperty(Symbol propertySymbol, StyleDeclaration declaration) : super(pr opertySymbol, declaration);
201
202 double get pixels => _getPixels();
203 void set pixels (value) => _setPixels(value);
204
205 double get inches => _getPixels() / 96.0;
206 void set inches (value) => _setPixels(value * 96.0);
207
208 double get em => _getEm();
209 void set em (value) => _setEm(value);
210
211 void setter(dynamic value) {
212 if (value is num)
213 return _setPixels(value.toDouble());
214 return super.setter(value);
215 }
216
217 external double _getPixels();
218 // throws StateError if the value isn't in pixels
219 external void _setPixels(double value);
220
221 external double _getEm();
222 // throws StateError if the value isn't in pixels
223 external void _setEm(double value);
224 }
225
226 const auto = const Object();
227
228 class AutoLengthProperty extends LengthProperty {
229 AutoLengthProperty(Symbol propertySymbol, StyleDeclaration declaration) : supe r(propertySymbol, declaration);
230
231 bool get auto => _isAuto();
232 void set auto (value) {
233 if (value == true)
234 _setAuto();
235 throw new ArgumentError(value);
236 }
237
238 void setter(dynamic value) {
239 if (value == auto)
240 return _setAuto();
241 return super.setter(value);
242 }
243
244 external bool _isAuto();
245 external void _setAuto();
246 }
247
248 class ColorProperty extends Property {
249 ColorProperty(Symbol propertySymbol, StyleDeclaration declaration) : super(pro pertySymbol, declaration);
250
251 int get alpha => _getRGBA() & 0xFF000000 >> 24;
252 void set alpha (int value) => _setRGBA(_getRGBA() & 0x00FFFFFF + value << 24);
253 int get red => _getRGBA() & 0x00FF0000 >> 16;
254 void set red (int value) => _setRGBA(_getRGBA() & 0xFF00FFFF + value << 16);
255 int get green => _getRGBA() & 0x0000FF00 >> 8;
256 void set green (int value) => _setRGBA(_getRGBA() & 0xFFFF00FF + value << 8);
257 int get blue => _getRGBA() & 0x000000FF >> 0;
258 void set blue (int value) => _setRGBA(_getRGBA() & 0xFFFFFF00 + value << 0);
259
260 int get rgba => _getRGBA();
261 void set rgba (int value) => _setRGBA(value);
262
263 void setter(dynamic value) {
264 if (value is int)
265 return _setRGBA(value);
266 return super.setter(value);
267 }
268
269 external int _getRGBA();
270 // throws StateError if the value isn't a color
271 external void _setRGBA(int value);
272 }
273
274 class Matrix {
275 const Matrix(this.a, this.b, this.c, this.d, this.e, this.f);
276
277 // +- -+
278 // | a c e |
279 // | b d f |
280 // | 0 0 1 |
281 // +- -+
282
283 final double a;
284 final double b;
285 final double c;
286 final double d;
287 final double e;
288 final double f;
289 }
290
291 class TransformProperty extends Property {
292 TransformProperty(Symbol propertySymbol, StyleDeclaration declaration) : super (propertySymbol, declaration);
293
294 void reset() => setTransform(1.0, 0.0, 0.0, 1.0, 0.0, 0.0);
295
296 void translate(double dx, double dy) => transform(1.0, 0.0, 0.0, 1.0, dx, dy);
297 void scale(double dw, double dh) => transform(dw, 0.0, 0.0, dh, 0.0, 0.0);
298 void rotate(double theta) => transform(cos(theta), -sin(theta), sin(theta), co s(theta), 0.0, 0.0);
299
300 // there's no "transform" getter since it would always return a new Matrix
301 // such that foo.transform == foo.transform would never be true
302 // and foo.transform = bar; bar == foo.transform would also never be true
303 // which is bad API
304
305 external Matrix getTransform();
306 // throws StateError if the value isn't a matrix
307 // returns a new matrix each time
308 external void setTransform(a, b, c, d, e, f);
309 external void transform(a, b, c, d, e, f);
310 // throws StateError if the value isn't a matrix
311 }
312
313 external void autoLengthPropertyStringSetter(Symbol propertySymbol, StyleDeclara tion declaration, String value);
314 external String autoLengthPropertyStringGetter(Symbol propertySymbol, StyleDecla ration declaration);
315 external void colorPropertyStringSetter(Symbol propertySymbol, StyleDeclaration declaration, String value);
316 external String colorPropertyStringGetter(Symbol propertySymbol, StyleDeclaratio n declaration);
317 external void transformPropertyStringSetter(Symbol propertySymbol, StyleDeclarat ion declaration, String value);
318 external String transformPropertyStringGetter(Symbol propertySymbol, StyleDeclar ation declaration);
319
320 void _init() {
321 registerProperty(new PropertyTable(
322 symbol: #height,
323 inherited: false,
324 stringSetter: autoLengthPropertyStringSetter,
325 stringGetter: autoLengthPropertyStringGetter,
326 objectConstructor: (Symbol propertySymbol, StyleDeclaration declaration) =>
327 new AutoLengthProperty(propertySymbol, declaration)));
328 registerProperty(new PropertyTable(
329 symbol: #width,
330 inherited: false,
331 stringSetter: autoLengthPropertyStringSetter,
332 stringGetter: autoLengthPropertyStringGetter,
333 objectConstructor: (Symbol propertySymbol, StyleDeclaration declaration) =>
334 new AutoLengthProperty(propertySymbol, declaration)));
335 registerProperty(new PropertyTable(
336 symbol: #color,
337 inherited: false,
338 stringSetter: colorPropertyStringSetter,
339 stringGetter: colorPropertyStringGetter,
340 objectConstructor: (Symbol propertySymbol, StyleDeclaration declaration) =>
341 new ColorProperty(propertySymbol, declaration)));
342 registerProperty(new PropertyTable(
343 symbol: #transform,
344 inherited: false,
345 stringSetter: transformPropertyStringSetter,
346 stringGetter: transformPropertyStringGetter,
347 objectConstructor: (Symbol propertySymbol, StyleDeclaration declaration) =>
348 new TransformProperty(propertySymbol, declaration)));
349 }
350 ```
351
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698