Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
weixin_43355755
engine
提交
1bdbdebf
E
engine
项目概览
weixin_43355755
/
engine
与 Fork 源项目一致
从无法访问的项目Fork
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
E
engine
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
1bdbdebf
编写于
2月 24, 2015
作者:
H
Hixie
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Specs: part 1 of the new approach to style
Review URL:
https://codereview.chromium.org/959473002
上级
3ed20172
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
351 addition
and
0 deletion
+351
-0
specs/style2.md
specs/style2.md
+351
-0
未找到文件。
specs/style2.md
0 → 100644
浏览文件 @
1bdbdebf
Sky Style Language
==================
Note: This is a work in progress that will eventually replace
(style.md)[style.md].
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'
;
class
WeakMap
<
Key
,
Value
>
{
Expando
<
Value
>
_map
=
new
Expando
<
Value
>();
operator
[](
Key
key
)
=>
_map
[
key
];
operator
[]=(
Key
key
,
Value
value
)
=>
_map
[
key
]
=
value
;
bool
containsKey
(
Key
key
)
=>
_map
[
key
]
!=
null
;
}
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
WeakMap
<
Symbol
,
Property
>
_properties
=
new
WeakMap
<
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
value
)
{
if
(
value
==
initial
)
return
_setInitial
();
if
(
value
==
inherit
)
return
_setInitial
();
if
(
value
==
null
)
return
_unset
();
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
)));
}
```
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录