line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package CSS::DOM::PropertyParser; |
2
|
|
|
|
|
|
|
|
3
|
|
|
|
|
|
|
$VERSION = '0.17'; |
4
|
|
|
|
|
|
|
|
5
|
4
|
|
|
4
|
|
3580
|
use warnings; no warnings qw 'utf8 parenthesis'; |
|
4
|
|
|
4
|
|
7
|
|
|
4
|
|
|
|
|
147
|
|
|
4
|
|
|
|
|
17
|
|
|
4
|
|
|
|
|
11
|
|
|
4
|
|
|
|
|
139
|
|
6
|
4
|
|
|
4
|
|
18
|
use strict; |
|
4
|
|
|
|
|
7
|
|
|
4
|
|
|
|
|
92
|
|
7
|
|
|
|
|
|
|
|
8
|
4
|
|
|
4
|
|
17
|
use constant 1.03 (); # multiple |
|
4
|
|
|
|
|
64
|
|
|
4
|
|
|
|
|
102
|
|
9
|
4
|
|
|
4
|
|
19
|
use CSS::DOM'Constants ':primitive', ':value'; |
|
4
|
|
|
|
|
5
|
|
|
4
|
|
|
|
|
814
|
|
10
|
4
|
|
|
4
|
|
715
|
use CSS'DOM'Util; |
|
4
|
|
|
|
|
7
|
|
|
4
|
|
|
|
|
394
|
|
11
|
|
|
|
|
|
|
|
12
|
4
|
|
|
4
|
|
23
|
use constant old_perl => $] < 5.01; |
|
4
|
|
|
|
|
7
|
|
|
4
|
|
|
|
|
228
|
|
13
|
4
|
|
|
4
|
|
17
|
{ no strict 'refs'; delete ${__PACKAGE__.'::'}{old_perl} } |
|
4
|
|
|
|
|
16
|
|
|
4
|
|
|
|
|
214
|
|
14
|
|
|
|
|
|
|
|
15
|
|
|
|
|
|
|
# perl 5.10.0 has a bug affecting $^N (perl bug #56194; not the initial |
16
|
|
|
|
|
|
|
# report, but regressions in 5.10; read the whole ticket for details). We |
17
|
|
|
|
|
|
|
# have a workaround, but it requires more CPU, so we only enable it for |
18
|
|
|
|
|
|
|
# this perl version. |
19
|
4
|
|
|
4
|
|
20
|
use constant naughty_perl => 0+$] eq 5.01; |
|
4
|
|
|
|
|
6
|
|
|
4
|
|
|
|
|
189
|
|
20
|
4
|
|
|
4
|
|
17
|
{ no strict 'refs'; delete ${__PACKAGE__.'::'}{naughty_perl} } |
|
4
|
|
|
|
|
18
|
|
|
4
|
|
|
|
|
3118
|
|
21
|
|
|
|
|
|
|
|
22
|
|
|
|
|
|
|
*s2c = *CSS'DOM'Constants'SuffixToConst; |
23
|
|
|
|
|
|
|
our %s2c; |
24
|
|
|
|
|
|
|
|
25
|
|
|
|
|
|
|
our %compiled; # compiled formats |
26
|
|
|
|
|
|
|
our %subcompiled; # compiled sub-formats |
27
|
|
|
|
|
|
|
# We use ‘our’ instead of ‘my’, because re-evals that are compiled at run |
28
|
|
|
|
|
|
|
# time can be a bit buggy when they refer to ‘my’ variables. |
29
|
|
|
|
|
|
|
|
30
|
|
|
|
|
|
|
sub new { |
31
|
8
|
|
|
8
|
0
|
1376
|
bless{}, shift |
32
|
|
|
|
|
|
|
} |
33
|
|
|
|
|
|
|
|
34
|
|
|
|
|
|
|
sub add_property { |
35
|
474
|
|
|
474
|
1
|
715
|
$_[0]{$_[1]}=$_[2] |
36
|
|
|
|
|
|
|
} |
37
|
|
|
|
|
|
|
|
38
|
|
|
|
|
|
|
sub get_property { |
39
|
2332
|
100
|
|
2332
|
1
|
6827
|
exists $_[0]{$_[1]} ? $_[0]{$_[1]} : () |
40
|
|
|
|
|
|
|
} |
41
|
|
|
|
|
|
|
|
42
|
|
|
|
|
|
|
sub delete_property { |
43
|
1
|
50
|
|
1
|
1
|
4
|
delete $_[0]{$_[1]} or () |
44
|
|
|
|
|
|
|
} |
45
|
|
|
|
|
|
|
|
46
|
|
|
|
|
|
|
sub property_names { |
47
|
1
|
|
|
1
|
1
|
4
|
sort keys %{$_[0]}; |
|
1
|
|
|
|
|
9
|
|
48
|
|
|
|
|
|
|
} |
49
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
sub subproperty_names { |
51
|
1414
|
50
|
|
1414
|
1
|
2902
|
exists $_[0]{$_[1]} or return; |
52
|
1414
|
|
|
|
|
2064
|
my $p = $_[0]{$_[1]}; |
53
|
1414
|
|
|
|
|
3289
|
my @p = $p->{format} =~ /'([^']+)'/g; |
54
|
|
|
|
|
|
|
exists $p->{properties} && $p->{properties} and |
55
|
1414
|
50
|
66
|
|
|
2710
|
push @p, keys %{$p->{properties}}; |
|
135
|
|
|
|
|
389
|
|
56
|
1414
|
|
|
|
|
2259
|
@p; |
57
|
|
|
|
|
|
|
} |
58
|
|
|
|
|
|
|
|
59
|
|
|
|
|
|
|
sub clone { |
60
|
|
|
|
|
|
|
# exists &dclone or require Storable, "Storable"->import('dclone'); |
61
|
|
|
|
|
|
|
# return dclone($_[0]); |
62
|
1
|
|
|
1
|
1
|
379
|
require Clone; |
63
|
1
|
|
|
|
|
2506
|
return Clone'clone($_[0]); |
64
|
|
|
|
|
|
|
} |
65
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
|
# Declare the variables that the re-evals use. Some nasty hacker went and |
67
|
|
|
|
|
|
|
# ‘fixed’ run-time re-evals to propagate hints, so now we have to do this |
68
|
|
|
|
|
|
|
# as of perl 5.13.8. |
69
|
|
|
|
|
|
|
our( |
70
|
|
|
|
|
|
|
@match,@list,@valtypes,$prepped,$alt_types,@List,%Match,%match,@Match, |
71
|
|
|
|
|
|
|
$tokens,$Self,$Fail |
72
|
|
|
|
|
|
|
); |
73
|
|
|
|
|
|
|
|
74
|
|
|
|
|
|
|
# The interface for match is documented in a POD comment further down |
75
|
|
|
|
|
|
|
# (search for the second occurrence of ‘=item match’). |
76
|
|
|
|
|
|
|
sub match { SUB: { |
77
|
1197
|
|
|
1197
|
1
|
1624
|
my ($self,$property) = (shift,shift); |
|
1203
|
|
|
|
|
1972
|
|
78
|
1203
|
50
|
|
|
|
2302
|
return unless exists $self->{$property}; |
79
|
|
|
|
|
|
|
|
80
|
|
|
|
|
|
|
# Prepare the value |
81
|
1203
|
|
|
|
|
2059
|
(my $types, local our ($tokens,$prepped,$alt_types)) = _prep_val(@_); |
82
|
|
|
|
|
|
|
# tokens is the actual tokens; $prepped is the tokens unescaped and lc'd |
83
|
|
|
|
|
|
|
# if they are ids; $alt_types contains single-char strings indicating pos- |
84
|
|
|
|
|
|
|
# sible datum types. |
85
|
|
|
|
|
|
|
#use DDS; Dump $types if $property =~ /clip/; |
86
|
|
|
|
|
|
|
|
87
|
|
|
|
|
|
|
|
88
|
1203
|
|
|
|
|
2630
|
my @subproperties = $self->subproperty_names($property); |
89
|
1203
|
|
|
|
|
1371
|
my $shorthand = @subproperties; |
90
|
1203
|
|
|
|
|
1596
|
my $spec = $self->{$property}; |
91
|
|
|
|
|
|
|
|
92
|
|
|
|
|
|
|
# Check for special values |
93
|
1203
|
100
|
100
|
|
|
2267
|
if(exists $spec->{special_values} |
|
|
|
66
|
|
|
|
|
94
|
|
|
|
|
|
|
&& $types eq 'i' |
95
|
|
|
|
|
|
|
&& exists $spec->{special_values}{$prepped->[0]}) { |
96
|
6
|
|
|
|
|
19
|
@_ = ($self,$property,$spec->{special_values}{$prepped->[0]}); |
97
|
6
|
|
|
|
|
20
|
redo SUB; |
98
|
|
|
|
|
|
|
} |
99
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
# Check for inherit |
101
|
1197
|
100
|
100
|
|
|
3200
|
if($types eq 'i' and $prepped->[0] eq 'inherit') { |
102
|
6
|
|
|
|
|
16
|
my @arg_array = ( |
103
|
|
|
|
|
|
|
$$tokens[0],'CSS::DOM::Value', type => CSS_INHERIT, css => $$tokens[0] |
104
|
|
|
|
|
|
|
); |
105
|
6
|
50
|
|
|
|
13
|
if($shorthand) { |
106
|
0
|
|
|
|
|
0
|
return { map +($_ => \@arg_array), @subproperties }; |
107
|
|
|
|
|
|
|
} |
108
|
6
|
|
|
|
|
28
|
else { return @arg_array } |
109
|
|
|
|
|
|
|
} |
110
|
|
|
|
|
|
|
|
111
|
|
|
|
|
|
|
# Localise other vars used by the hairy regexps |
112
|
1191
|
|
|
|
|
2148
|
local our (@Match,%Match,@valtypes,@List); |
113
|
1191
|
|
|
|
|
1434
|
local our $Self = $self; |
114
|
|
|
|
|
|
|
|
115
|
|
|
|
|
|
|
# Compile the formats of the sub-properties, something we can’t do |
116
|
|
|
|
|
|
|
# during the pattern match, as compilation requires regular expressions |
117
|
|
|
|
|
|
|
# and perl’s re engine is not reëntrant. This has to come before the for- |
118
|
|
|
|
|
|
|
# mat for this property, in case it relies on list-style-type. We use |
119
|
|
|
|
|
|
|
# (??{...}) to pick it up, but that is too buggy in perl 5.8.x, so, for |
120
|
|
|
|
|
|
|
# old perls, we compile it straight in. Consequently we also have to |
121
|
|
|
|
|
|
|
# ‘un-cache’ any compiled format containing , in case it is |
122
|
|
|
|
|
|
|
# shared with another parser object with another definition for |
123
|
|
|
|
|
|
|
# list-style-type. |
124
|
1191
|
|
|
|
|
1434
|
my $format = $$spec{format}; |
125
|
1191
|
100
|
|
|
|
2584
|
for( |
126
|
|
|
|
|
|
|
@subproperties, |
127
|
|
|
|
|
|
|
$format =~ '' |
128
|
|
|
|
|
|
|
? scalar(old_perl && delete $compiled{$format}, 'list-style-type') |
129
|
|
|
|
|
|
|
: () |
130
|
|
|
|
|
|
|
) { |
131
|
670
|
100
|
|
|
|
1035
|
next unless exists $self->{$_}; |
132
|
669
|
|
|
|
|
844
|
my $format = $self->{$_}{format}; |
133
|
669
|
|
|
|
|
619
|
old_perl and $compiled{$format} and delete $compiled{$format}; |
134
|
669
|
|
66
|
|
|
1221
|
$compiled{$format} ||= _compile_format($format) |
135
|
|
|
|
|
|
|
} |
136
|
|
|
|
|
|
|
|
137
|
|
|
|
|
|
|
# Prepare this property’s format pattern |
138
|
1191
|
|
66
|
|
|
2634
|
my $pattern = $compiled{$format} ||= _compile_format($format); |
139
|
|
|
|
|
|
|
|
140
|
|
|
|
|
|
|
# Do the actual pattern matching |
141
|
1191
|
100
|
|
|
|
90476
|
$types =~ /^$pattern\z/ or return; |
142
|
|
|
|
|
|
|
|
143
|
|
|
|
|
|
|
#use DDS; Dump $types,$tokens,\@valtypes; |
144
|
|
|
|
|
|
|
#use DDS; Dump \%Match if $property =~ /clip/; |
145
|
|
|
|
|
|
|
# Get the values, convert them into CSSValue arg lists and return them |
146
|
1113
|
100
|
|
|
|
2716
|
if($shorthand) { |
147
|
118
|
|
|
|
|
300
|
my $retval = {%Match}; |
148
|
118
|
100
|
|
|
|
269
|
my $subprops = exists $spec->{properties} ? $spec->{properties} : undef; |
149
|
|
|
|
|
|
|
|
150
|
|
|
|
|
|
|
# We record which captures have been turned into arg lists already, |
151
|
|
|
|
|
|
|
# since these are sometimes shared between properties. |
152
|
118
|
|
|
|
|
133
|
my @arglistified; |
153
|
|
|
|
|
|
|
|
154
|
118
|
|
|
|
|
224
|
for(@subproperties) { |
155
|
621
|
100
|
|
|
|
963
|
if(exists $retval->{$_}) { |
156
|
106
|
|
|
|
|
120
|
@{ $retval->{$_} } = _make_arg_list( @{ $retval->{$_} } ); |
|
106
|
|
|
|
|
328
|
|
|
106
|
|
|
|
|
198
|
|
157
|
|
|
|
|
|
|
} |
158
|
|
|
|
|
|
|
else { |
159
|
515
|
|
|
|
|
516
|
my $set; |
160
|
515
|
50
|
66
|
|
|
1192
|
if($subprops and exists $subprops->{$_}) { |
161
|
393
|
|
|
|
|
429
|
for my $c( @{ $subprops->{$_} } ) { # capture nums |
|
393
|
|
|
|
|
573
|
|
162
|
|
|
|
|
|
|
# find the first one that matched something |
163
|
446
|
100
|
66
|
|
|
987
|
if( $Match[$c] and length $Match[$c][0] ) { |
164
|
273
|
100
|
|
|
|
457
|
@{ $Match[$c] } = _make_arg_list( @{ $Match[$c] } ) |
|
157
|
|
|
|
|
391
|
|
|
157
|
|
|
|
|
268
|
|
165
|
|
|
|
|
|
|
unless $arglistified[$c]++; |
166
|
273
|
|
|
|
|
326
|
++$set; |
167
|
273
|
|
|
|
|
439
|
$retval->{$_} = $Match[$c]; |
168
|
273
|
|
|
|
|
306
|
last; |
169
|
|
|
|
|
|
|
} |
170
|
|
|
|
|
|
|
} |
171
|
|
|
|
|
|
|
} |
172
|
515
|
100
|
|
|
|
865
|
if(!$set) { |
173
|
|
|
|
|
|
|
# use default value |
174
|
|
|
|
|
|
|
# ~~~ Should we cache this? (If we do, we need to distinguish between |
175
|
|
|
|
|
|
|
# ‘content: Times New Roman’ and ‘font-family: Times New Roman’.) |
176
|
242
|
|
|
|
|
362
|
my $default = $self->{$_}{default}; |
177
|
4
|
|
|
4
|
|
26
|
no warnings 'uninitialized'; |
|
4
|
|
|
|
|
54
|
|
|
4
|
|
|
|
|
1530
|
|
178
|
242
|
100
|
|
|
|
566
|
$retval->{$_} = length $default |
179
|
|
|
|
|
|
|
? [ |
180
|
|
|
|
|
|
|
$self->match($_, $default) |
181
|
|
|
|
|
|
|
] |
182
|
|
|
|
|
|
|
: "" |
183
|
|
|
|
|
|
|
} |
184
|
|
|
|
|
|
|
} |
185
|
|
|
|
|
|
|
} |
186
|
118
|
|
|
|
|
957
|
$retval; |
187
|
|
|
|
|
|
|
} |
188
|
|
|
|
|
|
|
else { # simple |
189
|
995
|
|
|
|
|
1208
|
my $css = join "", @{ (_space_out($types,$tokens))[1] }; |
|
995
|
|
|
|
|
1724
|
|
190
|
|
|
|
|
|
|
#use DDS; Dump \@List if exists $$spec{list} && $$spec{list}; |
191
|
|
|
|
|
|
|
return _make_arg_list( |
192
|
|
|
|
|
|
|
$types, $tokens, |
193
|
|
|
|
|
|
|
exists $$spec{list} && $$spec{list} |
194
|
|
|
|
|
|
|
? \@List |
195
|
995
|
100
|
66
|
|
|
3440
|
: (\@valtypes, $prepped) |
196
|
|
|
|
|
|
|
); |
197
|
|
|
|
|
|
|
} |
198
|
|
|
|
|
|
|
}} |
199
|
|
|
|
|
|
|
|
200
|
|
|
|
|
|
|
sub _make_arg_list { |
201
|
1424
|
|
|
1424
|
|
2296
|
my($types, $tokens) = (shift,shift); |
202
|
1424
|
|
|
|
|
1947
|
my($stypes,$stokens) = _space_out($types, $tokens); |
203
|
1424
|
|
|
|
|
2519
|
my $css = join "", @$stokens; |
204
|
1424
|
100
|
|
|
|
2249
|
if(@_ == 1) { # list property |
205
|
90
|
|
|
|
|
110
|
my $list = shift @'_; |
206
|
90
|
100
|
|
|
|
183
|
my $sep = @$list <= 1 ? '' : do { |
207
|
46
|
|
|
|
|
73
|
my $range_start = $$list[0][4]; |
208
|
46
|
|
|
|
|
98
|
my $range_end = $$list[1][4] - length($$list[1][4]) - 1; |
209
|
46
|
|
|
|
|
163
|
my(undef,$stokens) = _space_out( |
210
|
|
|
|
|
|
|
substr($types, $range_start-1, $range_end-$range_start+3), |
211
|
|
|
|
|
|
|
[@$tokens[$range_start-1...$range_end+1]] |
212
|
|
|
|
|
|
|
); |
213
|
46
|
|
|
|
|
168
|
join "", @$stokens[1...$#$stokens-1]; |
214
|
|
|
|
|
|
|
}; |
215
|
|
|
|
|
|
|
return $css, "CSS::DOM::Value::List", |
216
|
|
|
|
|
|
|
separator => $sep, css => $css, |
217
|
|
|
|
|
|
|
values => [ map { |
218
|
90
|
|
|
|
|
188
|
my @args = _make_arg_list( |
|
166
|
|
|
|
|
306
|
|
219
|
|
|
|
|
|
|
@$_[0...3] |
220
|
|
|
|
|
|
|
); |
221
|
166
|
|
|
|
|
224
|
shift @args, shift @args; |
222
|
|
|
|
|
|
|
\@args |
223
|
166
|
|
|
|
|
1168
|
} @$list ]; |
224
|
|
|
|
|
|
|
} |
225
|
|
|
|
|
|
|
else{ |
226
|
1334
|
|
|
|
|
1796
|
my($valtypes, $prepped) = @_; |
227
|
1334
|
|
|
|
|
2881
|
my @valtypes = grep defined, @$valtypes; |
228
|
1334
|
100
|
66
|
|
|
2360
|
if(@valtypes != 1 and |
|
|
|
66
|
|
|
|
|
229
|
|
|
|
|
|
|
$valtypes[0] != CSS_COUNTER || do { # The code in this block is to |
230
|
4
|
|
|
4
|
|
29
|
no warnings 'uninitialized'; # distinguish between counter(id, |
|
4
|
|
|
|
|
36
|
|
|
4
|
|
|
|
|
4896
|
|
231
|
|
|
|
|
|
|
my $found; # id) (which is a CSS_COUNTER) and |
232
|
|
|
|
|
|
|
for(@valtypes[1...$#valtypes-1]) { # counter(id) id (CSS_CUSTOM). |
233
|
|
|
|
|
|
|
$_ == -1 and ++$found, last; # -1 is a special marker for the end of |
234
|
|
|
|
|
|
|
} # a counter |
235
|
|
|
|
|
|
|
$found |
236
|
|
|
|
|
|
|
}) { |
237
|
64
|
|
|
|
|
469
|
return $css => "CSS::DOM::Value", type => CSS_CUSTOM, value => $css; |
238
|
|
|
|
|
|
|
} |
239
|
1270
|
|
|
|
|
1554
|
my $type = shift @valtypes; |
240
|
|
|
|
|
|
|
return $css, "CSS::DOM::Value::Primitive", |
241
|
|
|
|
|
|
|
type => $type, css => $css, |
242
|
|
|
|
|
|
|
value => |
243
|
|
|
|
|
|
|
$type == CSS_NUMBER || $type == CSS_PERCENTAGE || $type == CSS_EMS || |
244
|
|
|
|
|
|
|
$type == CSS_EXS || $type == CSS_PX || $type == CSS_CM || |
245
|
|
|
|
|
|
|
$type == CSS_MM || $type == CSS_IN || $type == CSS_PT || |
246
|
|
|
|
|
|
|
$type == CSS_PC || $type == CSS_DEG || $type == CSS_RAD || |
247
|
|
|
|
|
|
|
$type == CSS_GRAD || $type == CSS_MS || $type == CSS_S || |
248
|
|
|
|
|
|
|
$type == CSS_HZ || $type == CSS_KHZ |
249
|
|
|
|
|
|
|
? $css |
250
|
|
|
|
|
|
|
: $type == CSS_STRING |
251
|
|
|
|
|
|
|
? unescape_str $css |
252
|
|
|
|
|
|
|
: $type == CSS_IDENT |
253
|
|
|
|
|
|
|
? unescape $css |
254
|
|
|
|
|
|
|
: $type == CSS_URI |
255
|
|
|
|
|
|
|
? unescape_url $css |
256
|
|
|
|
|
|
|
: $type == CSS_COUNTER |
257
|
|
|
|
|
|
|
? [ |
258
|
|
|
|
|
|
|
$$prepped[$types =~ /i/, $-[0]], |
259
|
|
|
|
|
|
|
$types =~ /'/ ? $$prepped[$-[0]] : undef, |
260
|
|
|
|
|
|
|
$types =~ /i.*?i/ ? $$prepped[$+[0]-1] : undef, |
261
|
|
|
|
|
|
|
] |
262
|
|
|
|
|
|
|
: $type == CSS_RGBCOLOR |
263
|
|
|
|
|
|
|
? substr $types, 0, 1, eq '#' |
264
|
|
|
|
|
|
|
? $$prepped[0] |
265
|
|
|
|
|
|
|
: do{ |
266
|
222
|
|
|
|
|
272
|
my @vals; |
267
|
222
|
|
|
|
|
548
|
while($types =~ /([%D1])/g) { |
268
|
|
|
|
|
|
|
push @vals, [ |
269
|
|
|
|
|
|
|
type => |
270
|
|
|
|
|
|
|
$1 eq '%' ? CSS_PERCENTAGE |
271
|
64
|
50
|
|
|
|
281
|
: $1 eq 'D' ? $s2c{unescape do{ |
|
|
100
|
|
|
|
|
|
272
|
0
|
|
|
|
|
0
|
($$tokens[$-[1]] =~ '(\D+)')[0] |
273
|
|
|
|
|
|
|
}} |
274
|
|
|
|
|
|
|
: CSS_NUMBER, |
275
|
|
|
|
|
|
|
value => $1, |
276
|
|
|
|
|
|
|
css => $1, |
277
|
|
|
|
|
|
|
] |
278
|
|
|
|
|
|
|
} |
279
|
|
|
|
|
|
|
\@vals |
280
|
222
|
|
|
|
|
1670
|
} |
281
|
|
|
|
|
|
|
: $type == CSS_ATTR |
282
|
|
|
|
|
|
|
? $$prepped[$types =~ /i/, $-[0]] |
283
|
|
|
|
|
|
|
: $type == CSS_RECT |
284
|
|
|
|
|
|
|
? [ |
285
|
|
|
|
|
|
|
map scalar( |
286
|
|
|
|
|
|
|
$types =~ /\G.*?(d?([D1])|i)/g, |
287
|
|
|
|
|
|
|
$1 eq 'i' |
288
|
|
|
|
|
|
|
? [type => CSS_IDENT, value => 'auto'] #$$prepped[$-[1]]] |
289
|
|
|
|
|
|
|
: [ |
290
|
|
|
|
|
|
|
type => |
291
|
|
|
|
|
|
|
$2 eq 'D' |
292
|
1270
|
100
|
100
|
|
|
19263
|
? $s2c{unescape do{($$tokens[$-[2]] =~ '(\D+)')[0]}} |
|
7
|
100
|
|
|
|
33
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
293
|
|
|
|
|
|
|
: CSS_NUMBER, |
294
|
|
|
|
|
|
|
value => join "", @$tokens[$-[1]...$+[1]-1] |
295
|
|
|
|
|
|
|
] |
296
|
|
|
|
|
|
|
), 1...4 |
297
|
|
|
|
|
|
|
] |
298
|
|
|
|
|
|
|
: die __PACKAGE__ . " internal error: unknown type: $type" |
299
|
|
|
|
|
|
|
} |
300
|
|
|
|
|
|
|
} |
301
|
|
|
|
|
|
|
|
302
|
|
|
|
|
|
|
sub _space_out { |
303
|
2465
|
|
|
2465
|
|
3439
|
my($types,$tokens) = @_; |
304
|
2465
|
50
|
|
|
|
4284
|
Carp'cluck() if ref $tokens ne 'ARRAY'; |
305
|
2465
|
|
|
|
|
3740
|
$tokens = [@$tokens]; |
306
|
2465
|
|
|
|
|
2779
|
my @posses; |
307
|
2465
|
|
|
|
|
5137
|
$types =~ s/(?<=[^(f])(?![),]|\z)/ |
308
|
577
|
100
|
|
|
|
1177
|
if($tokens->[-1+pos $types] =~ m=^[+-]\z=) { |
309
|
86
|
|
|
|
|
206
|
'' |
310
|
|
|
|
|
|
|
} |
311
|
|
|
|
|
|
|
else { |
312
|
491
|
|
|
|
|
583
|
push @posses, pos $types; 's' |
|
491
|
|
|
|
|
1217
|
|
313
|
|
|
|
|
|
|
} |
314
|
|
|
|
|
|
|
/ge; |
315
|
2465
|
|
|
|
|
4076
|
splice @$tokens, $_, 0, ' ' for reverse @posses; |
316
|
2465
|
|
|
|
|
5669
|
return $types, $tokens; |
317
|
|
|
|
|
|
|
} |
318
|
|
|
|
|
|
|
|
319
|
|
|
|
|
|
|
# Defined further down, to keep the hairiness out of the way. |
320
|
|
|
|
|
|
|
my($colour_names_re, $system_colour_names_re); |
321
|
|
|
|
|
|
|
|
322
|
|
|
|
|
|
|
sub _prep_val { |
323
|
1203
|
50
|
|
1203
|
|
2296
|
defined &unescape or |
324
|
|
|
|
|
|
|
require CSS::DOM::Util, 'CSS::DOM::Util'->import('unescape'); |
325
|
1203
|
|
|
|
|
1438
|
my($types,$tokens); |
326
|
1203
|
100
|
|
|
|
2031
|
if(@_ > 1) { |
327
|
915
|
|
|
|
|
1517
|
($types,$tokens)= @_; |
328
|
|
|
|
|
|
|
} |
329
|
|
|
|
|
|
|
else { |
330
|
288
|
|
|
|
|
1229
|
require CSS::DOM::Parser; |
331
|
288
|
|
|
|
|
695
|
($types, $tokens) = CSS::DOM::Parser'tokenise($_[0]); |
332
|
|
|
|
|
|
|
} |
333
|
|
|
|
|
|
|
|
334
|
|
|
|
|
|
|
# strip out all whitespace tokens |
335
|
|
|
|
|
|
|
{ |
336
|
1203
|
|
|
|
|
1337
|
my @posses; |
|
1203
|
|
|
|
|
1658
|
|
337
|
1203
|
|
|
|
|
2217
|
$tokens = [@$tokens]; # We have to copy it as it may be referenced |
338
|
1203
|
|
|
|
|
2125
|
$types =~ s/s/push @posses,pos$types;''/gem; # elsewhere. |
|
343
|
|
|
|
|
494
|
|
|
343
|
|
|
|
|
613
|
|
339
|
1203
|
|
|
|
|
2407
|
splice@$tokens,$_,1 for reverse @posses; |
340
|
|
|
|
|
|
|
} |
341
|
|
|
|
|
|
|
|
342
|
1203
|
|
|
|
|
1515
|
my @prepped; |
343
|
|
|
|
|
|
|
my @alt_type; |
344
|
1203
|
|
|
|
|
2401
|
for(0..$#$tokens) { |
345
|
1843
|
|
|
|
|
2850
|
my $type = substr $types, $_, 1; |
346
|
1843
|
|
|
|
|
1816
|
my $thing; |
347
|
1843
|
100
|
|
|
|
4922
|
if($type =~ /[if#]/) { |
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
348
|
1119
|
|
|
|
|
2599
|
$thing = lc unescape($$tokens[$_]); |
349
|
1119
|
100
|
|
|
|
2064
|
if($type eq 'i') { |
|
|
100
|
|
|
|
|
|
350
|
1061
|
100
|
|
|
|
6555
|
if($thing =~ /^$colour_names_re\z/o) { $alt_type[$_] = 'c' } |
|
216
|
100
|
|
|
|
372
|
|
351
|
31
|
|
|
|
|
59
|
elsif($thing =~ /^$system_colour_names_re\z/o) { $alt_type[$_] = 's' } |
352
|
|
|
|
|
|
|
} |
353
|
|
|
|
|
|
|
elsif($type eq '#') { |
354
|
13
|
100
|
|
|
|
56
|
$thing =~ /^#(?:[0-9a-f]{3}){1,2}\z/ and $alt_type[$_] = 'c';#olour |
355
|
|
|
|
|
|
|
# ~~~ What about escapes? |
356
|
|
|
|
|
|
|
} |
357
|
|
|
|
|
|
|
} |
358
|
|
|
|
|
|
|
elsif($type eq 'D') { # dimension |
359
|
200
|
|
|
|
|
696
|
($thing = $$tokens[$_]) =~ s/^[.0-9]+//; |
360
|
200
|
|
|
|
|
465
|
$thing = lc unescape($thing); |
361
|
200
|
100
|
|
|
|
699
|
if($thing =~ /^(?:deg|g?rad)\z/) { $alt_type[$_] = 'a'}#ngle |
|
24
|
100
|
|
|
|
50
|
|
362
|
|
|
|
|
|
|
elsif($thing =~ /^(?:e[mx]|p[xtc]|in|[cm]m)\z/) { |
363
|
147
|
|
|
|
|
271
|
$alt_type[$_] = 'l'#ength |
364
|
|
|
|
|
|
|
} |
365
|
|
|
|
|
|
|
} |
366
|
|
|
|
|
|
|
elsif($type eq '1') { # number |
367
|
141
|
|
|
|
|
228
|
$thing = 0+$$tokens[$_]; # change 0.000 to 0, etc. |
368
|
|
|
|
|
|
|
} |
369
|
|
|
|
|
|
|
elsif($type eq 'd') { # delimiter |
370
|
45
|
100
|
|
|
|
112
|
$alt_type[$_] = '+' if $$tokens[$_] =~ /^[+-]\z/; |
371
|
|
|
|
|
|
|
} |
372
|
1843
|
100
|
|
|
|
3643
|
defined $alt_type[$_] or $alt_type[$_] = ''; |
373
|
1843
|
|
|
|
|
3298
|
push @prepped, $thing; |
374
|
|
|
|
|
|
|
} |
375
|
|
|
|
|
|
|
|
376
|
1203
|
|
|
|
|
3555
|
return ($types,$tokens,\@prepped,\@alt_type); |
377
|
|
|
|
|
|
|
} |
378
|
|
|
|
|
|
|
|
379
|
|
|
|
|
|
|
|
380
|
|
|
|
|
|
|
# Various bits and pieces for _compile_format’s use |
381
|
|
|
|
|
|
|
|
382
|
|
|
|
|
|
|
$Fail = qr/(?!)/; # avoid recompiling the same sub-regexp doz- |
383
|
|
|
|
|
|
|
# ens of times |
384
|
|
|
|
|
|
|
|
385
|
|
|
|
|
|
|
# This optionally matches a sign |
386
|
|
|
|
|
|
|
my $sign = '(?:d(?(?{$$alt_types[pos()-1]eq"+"})|(?!)))?'; |
387
|
|
|
|
|
|
|
|
388
|
|
|
|
|
|
|
# These $type_ expressions save the current value type in @valtypes. |
389
|
|
|
|
|
|
|
my $type_is_ # generic one to stick inside (?{...}) |
390
|
|
|
|
|
|
|
= '$valtypes[$#valtypes=' |
391
|
|
|
|
|
|
|
. (naughty_perl ? '$pos[-1]' : 'pos()-length$^N') |
392
|
|
|
|
|
|
|
. ']='; |
393
|
|
|
|
|
|
|
my $type_is_dim_or_number |
394
|
|
|
|
|
|
|
= '(?{ |
395
|
|
|
|
|
|
|
$valtypes[ |
396
|
|
|
|
|
|
|
$#valtypes=' . (naughty_perl ? '$pos[-1]' : 'pos()-length$^N') . ' |
397
|
|
|
|
|
|
|
] |
398
|
|
|
|
|
|
|
= $$prepped[pos()-1] ? $s2c{ $$prepped[pos()-1] } : CSS_NUMBER |
399
|
|
|
|
|
|
|
})'; |
400
|
|
|
|
|
|
|
|
401
|
|
|
|
|
|
|
# Constants defined in _compile_format and only used there get deleted at |
402
|
|
|
|
|
|
|
# run time. |
403
|
4
|
|
|
4
|
|
26
|
{ no strict 'refs'; delete @{__PACKAGE__.'::'}{cap_start=>cap_end=>} } |
|
4
|
|
|
|
|
12
|
|
|
4
|
|
|
|
|
630
|
|
404
|
|
|
|
|
|
|
|
405
|
|
|
|
|
|
|
sub _compile_format { |
406
|
116
|
|
|
116
|
|
162
|
my $format = shift; |
407
|
116
|
|
|
|
|
133
|
my $no_match_stuff = shift; # Leave out the @%match localisation stuff |
408
|
|
|
|
|
|
|
|
409
|
|
|
|
|
|
|
# The types of transmogrifications we need to make: |
410
|
|
|
|
|
|
|
|
411
|
|
|
|
|
|
|
# Whitespace is ignored. |
412
|
|
|
|
|
|
|
# |
413
|
|
|
|
|
|
|
# [] is simply (?:). |
414
|
|
|
|
|
|
|
# |
415
|
|
|
|
|
|
|
# () is itself, except we record the captures manually with (?{}). |
416
|
|
|
|
|
|
|
# |
417
|
|
|
|
|
|
|
# The chars ? * + | are left as is (except when | is doubled). |
418
|
|
|
|
|
|
|
# |
419
|
|
|
|
|
|
|
# <...> thingies are replaced with simple regexps that match the type |
420
|
|
|
|
|
|
|
# and then check with a re-eval to see whether the token matches. Then we |
421
|
|
|
|
|
|
|
# have another re-eval that records the type of match in @valtypes, so we |
422
|
|
|
|
|
|
|
# can distinguish between ‘red’ matched by (counter-reset: red), |
423
|
|
|
|
|
|
|
# ‘red’ matched by (color: red) and ‘red’ matched by |
424
|
|
|
|
|
|
|
# (font-family: red). |
425
|
|
|
|
|
|
|
# |
426
|
|
|
|
|
|
|
# Identifiers are treated similarly. |
427
|
|
|
|
|
|
|
# |
428
|
|
|
|
|
|
|
# '...' references are turned into complicated re-evals that look up the |
429
|
|
|
|
|
|
|
# format for the other property and add it to the %match hash if |
430
|
|
|
|
|
|
|
# it matches. |
431
|
|
|
|
|
|
|
# |
432
|
|
|
|
|
|
|
# || causes the innermost enclosing group to be transformed into a per- |
433
|
|
|
|
|
|
|
# mutation-matching pattern. Since at least one is required, we |
434
|
|
|
|
|
|
|
# put question marks after all sub-patterns except the first in |
435
|
|
|
|
|
|
|
# each alternate. For example, a||b||c (where the letters rep- |
436
|
|
|
|
|
|
|
# resent sub-patterns, not actual chars in the format) |
437
|
|
|
|
|
|
|
# becomes a(?:bc?|cb?)?|b(?:ac?|ca?)?|c(?:ab?|ba?)?. |
438
|
|
|
|
|
|
|
|
439
|
|
|
|
|
|
|
# Concerning the [@%][Mm]atch variables: |
440
|
|
|
|
|
|
|
# |
441
|
|
|
|
|
|
|
# All captures are saved separately in an array during matching. To |
442
|
|
|
|
|
|
|
# account for backtracking, we have to localise every assignment. Since |
443
|
|
|
|
|
|
|
# the localisations will be undone when the re exits, we have to save them |
444
|
|
|
|
|
|
|
# in separate variables. The lc vars are used during matching; the capita- |
445
|
|
|
|
|
|
|
# lised variables afterwards. Since we may be parsing sub-properties |
446
|
|
|
|
|
|
|
# (with their own sets of captures), we need a second localisation mechan- |
447
|
|
|
|
|
|
|
# ism that restores the previous set of captured values when a sub-proper- |
448
|
|
|
|
|
|
|
# ty’s re exits. (We can’t use Perl’s, because the rest of the outer pat- |
449
|
|
|
|
|
|
|
# tern is called recursively from within the inner pattern.) So: |
450
|
|
|
|
|
|
|
# |
451
|
|
|
|
|
|
|
# @match holds arrays of captures, $match[-1] being the current array. |
452
|
|
|
|
|
|
|
# When the re exits, @{ $match[-1] } is copied into @Match. Subpatterns |
453
|
|
|
|
|
|
|
# push onto @match upon entry and pop it on exit. |
454
|
|
|
|
|
|
|
# ~~~ Actually, it seems we don’t currently pop it, but all tests pass. Why |
455
|
|
|
|
|
|
|
# is this? |
456
|
|
|
|
|
|
|
# |
457
|
|
|
|
|
|
|
# @list is similar to @match, but it holds all captured matches in the |
458
|
|
|
|
|
|
|
# order they matched, skipping those that did not match. It includes mul- |
459
|
|
|
|
|
|
|
# tiple elements for quantified captures (that is, if they matched multi- |
460
|
|
|
|
|
|
|
# ple times). @match, on the other hand, is indexed by capture number, |
461
|
|
|
|
|
|
|
# like @-, et al. In other words, if we match ‘'rhext' 'scled'’ against |
462
|
|
|
|
|
|
|
# ‘()? ()+’, we have: |
463
|
|
|
|
|
|
|
# @match: undef (elem 0 is always undef), undef, 'scled' |
464
|
|
|
|
|
|
|
# @list: 'rhext', 'scled' |
465
|
|
|
|
|
|
|
# |
466
|
|
|
|
|
|
|
# %match holds named captures (sub-properties) directly (no extra locali- |
467
|
|
|
|
|
|
|
# sation necessary), which are then copied to %Match afterwards. |
468
|
|
|
|
|
|
|
# |
469
|
|
|
|
|
|
|
# In perl 5.10.0 (see the definition of naughty_perl, above). We work |
470
|
|
|
|
|
|
|
# around the unreliability of $^N by pushing the current pos onto @pos |
471
|
|
|
|
|
|
|
# before a sub-pattern or capture, and popping it afterwards. We use |
472
|
|
|
|
|
|
|
# $pos[-1] instead of pos()-length$^N (for the beginning of the capture). |
473
|
|
|
|
|
|
|
|
474
|
116
|
50
|
|
|
|
227
|
my $pattern = $no_match_stuff |
475
|
|
|
|
|
|
|
? '' : '(?{local @match=(@match,[]); local @list=(@list,[])})(?:'; |
476
|
|
|
|
|
|
|
# We add (?: to account for top-level alternations. |
477
|
|
|
|
|
|
|
|
478
|
116
|
|
|
|
|
217
|
my @group_start = length $pattern; # holds the position within $pattern of |
479
|
|
|
|
|
|
|
# the last group start |
480
|
116
|
|
|
|
|
160
|
my @permut_marker = []; # where a || occurs (array of arrays; each group |
481
|
|
|
|
|
|
|
# has its own array on this stack) |
482
|
116
|
|
|
|
|
126
|
my @capture_nums; |
483
|
116
|
|
|
|
|
155
|
my $last_capture = 0; |
484
|
|
|
|
|
|
|
|
485
|
|
|
|
|
|
|
# For each piece of the format, add to the pattern. |
486
|
116
|
|
|
|
|
506
|
while( |
487
|
|
|
|
|
|
|
$format =~ /(\s+)|(\|\|)|<([^>]+)>|([a-z-]+)|([0-9]+)|'([^']+)'|(.)/g |
488
|
|
|
|
|
|
|
) { |
489
|
1687
|
100
|
|
|
|
3049
|
next if $1; # ignore whitespace |
490
|
|
|
|
|
|
|
|
491
|
|
|
|
|
|
|
# cygwin hack: |
492
|
|
|
|
|
|
|
use constant { # re-evals for before and after captures |
493
|
4
|
|
|
|
|
3753
|
cap_start => naughty_perl ? '(?{local @pos=(@pos,pos)})' : '', |
494
|
|
|
|
|
|
|
cap_end => naughty_perl ? '(?{local @pos=@pos; --$#pos})' : '', |
495
|
4
|
|
|
4
|
|
24
|
}; |
|
4
|
|
|
|
|
5
|
|
496
|
|
|
|
|
|
|
|
497
|
1413
|
100
|
|
|
|
3341
|
if($2) { # || |
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
498
|
32
|
|
|
|
|
36
|
push @{ $permut_marker[-1] }, length $pattern; |
|
32
|
|
|
|
|
93
|
|
499
|
|
|
|
|
|
|
} |
500
|
|
|
|
|
|
|
elsif($3) { # <...> |
501
|
|
|
|
|
|
|
# We have to wrap most of these in (?:...) in case they get quantified. |
502
|
|
|
|
|
|
|
# (‘ab’ has to become ‘(?:ab)’ so that ‘ab?’ becomes ‘(?:ab)?’.) |
503
|
|
|
|
|
|
|
$pattern .= |
504
|
|
|
|
|
|
|
$3 eq 'angle' ? |
505
|
|
|
|
|
|
|
"(?:($sign\[D1])" . cap_start . '(?(?{ |
506
|
|
|
|
|
|
|
$$alt_types[pos()-1]eq"a"||$$prepped[pos()-1]eq 0 |
507
|
|
|
|
|
|
|
})|(?!))' . $type_is_dim_or_number . cap_end .")" |
508
|
|
|
|
|
|
|
: $3 eq 'attr' ? |
509
|
|
|
|
|
|
|
'(?x:' . cap_start . '( |
510
|
|
|
|
|
|
|
f(?(?{$$prepped[pos()-1]eq"attr("})|(?!))i\) |
511
|
|
|
|
|
|
|
)' . "(?{ $type_is_ CSS_ATTR })" . cap_end . ")" |
512
|
|
|
|
|
|
|
: $3 =~ /^colou?r\z/ ? |
513
|
|
|
|
|
|
|
"(?x:" . cap_start . "(?: |
514
|
|
|
|
|
|
|
([i#](?(?{ |
515
|
|
|
|
|
|
|
\$\$alt_types[pos()-1]eq 'c'||\$\$alt_types[pos()-1]eq 's' |
516
|
|
|
|
|
|
|
})|(?!))) (?{ $type_is_ ( |
517
|
|
|
|
|
|
|
\$\$alt_types[pos()-1]eq 'c' ? CSS_RGBCOLOR : CSS_IDENT |
518
|
|
|
|
|
|
|
) }) |
519
|
|
|
|
|
|
|
| |
520
|
|
|
|
|
|
|
(f |
521
|
|
|
|
|
|
|
(?: |
522
|
|
|
|
|
|
|
(?(?{\$\$prepped[pos()-1]eq 'rgb('})|(?!)) |
523
|
|
|
|
|
|
|
(?: $sign 1(?:,$sign 1){2} | $sign%(?:,$sign%){2} ) |
524
|
|
|
|
|
|
|
| |
525
|
|
|
|
|
|
|
(?(?{\$\$prepped[pos()-1]eq 'rgba('})|(?!)) |
526
|
|
|
|
|
|
|
(?: $sign 1(?:,$sign 1){2} | $sign%(?:,$sign%){2} ),$sign 1 |
527
|
|
|
|
|
|
|
) |
528
|
|
|
|
|
|
|
\\)) (?{ $type_is_ CSS_RGBCOLOR }) |
529
|
|
|
|
|
|
|
)" . cap_end . ")" |
530
|
|
|
|
|
|
|
|
531
|
|
|
|
|
|
|
# represents the following four: |
532
|
|
|
|
|
|
|
# counter() |
533
|
|
|
|
|
|
|
# counter(,'list-style-type') |
534
|
|
|
|
|
|
|
# counters(,) |
535
|
|
|
|
|
|
|
# counters(,,'list-style-type') |
536
|
138
|
50
|
|
|
|
1380
|
: $3 eq 'counter' ? do { |
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
537
|
4
|
|
|
|
|
7
|
our $Self; |
538
|
|
|
|
|
|
|
my $list_style_type = old_perl |
539
|
|
|
|
|
|
|
? exists $$Self{"list-style-type"} |
540
|
|
|
|
|
|
|
? $compiled{$$Self{"list-style-type"}{format}} |
541
|
|
|
|
|
|
|
||= _compile_format($$Self{"list-style-type"}{format}) |
542
|
4
|
|
|
|
|
9
|
: '(?!)' |
543
|
|
|
|
|
|
|
: '(??{ |
544
|
|
|
|
|
|
|
exists $$Self{"list-style-type"} |
545
|
|
|
|
|
|
|
? $compiled{$$Self{"list-style-type"}{format}} |
546
|
|
|
|
|
|
|
: $Fail |
547
|
|
|
|
|
|
|
})' |
548
|
|
|
|
|
|
|
; |
549
|
4
|
|
|
|
|
27
|
q*(?x:* . cap_start . q*(f(?{$$prepped[pos()-1]}) |
550
|
|
|
|
|
|
|
(?(?{$^R eq "counter("}) |
551
|
|
|
|
|
|
|
i(?:,* . $list_style_type . q*)? |
552
|
|
|
|
|
|
|
| |
553
|
|
|
|
|
|
|
(?(?{$^R eq "counters("}) |
554
|
|
|
|
|
|
|
i,'(?:,* . $list_style_type . q*)? |
555
|
|
|
|
|
|
|
| |
556
|
|
|
|
|
|
|
(?!) |
557
|
|
|
|
|
|
|
) |
558
|
|
|
|
|
|
|
) |
559
|
|
|
|
|
|
|
\))* |
560
|
|
|
|
|
|
|
. "(?{ $type_is_ CSS_COUNTER;" |
561
|
|
|
|
|
|
|
. ' $valtypes[$#valtypes=pos()-1] = -1})' # -1 is a special |
562
|
|
|
|
|
|
|
. cap_end . ')' # marker for the end |
563
|
|
|
|
|
|
|
} # of a counter |
564
|
|
|
|
|
|
|
: $3 eq 'frequency' ? |
565
|
|
|
|
|
|
|
'(?:' . cap_start . '((?:d(?(?{ |
566
|
|
|
|
|
|
|
$$tokens[pos()-1]eq"+"||$$tokens[-1+pos]eq"-"&&$$tokens[pos]eq 0 |
567
|
|
|
|
|
|
|
})|(?!)))?[D1](?(?{ |
568
|
|
|
|
|
|
|
my$p=$$prepped[pos()-1];$p eq"hz"||$p eq"khz"||$p eq 0 |
569
|
|
|
|
|
|
|
})|(?!)))' . $type_is_dim_or_number . cap_end . ")" |
570
|
|
|
|
|
|
|
: $3 eq 'identifier' ? |
571
|
|
|
|
|
|
|
"(?:" . cap_start . "(i)(?{ $type_is_ CSS_IDENT })" . cap_end . ")" |
572
|
|
|
|
|
|
|
: $3 eq 'integer' ? |
573
|
|
|
|
|
|
|
'(?:' . cap_start . '(1(?(?{index$$tokens[pos()-1],".",==-1})|(?!)))' |
574
|
|
|
|
|
|
|
. "(?{ $type_is_ CSS_NUMBER })" . cap_end . ")" |
575
|
|
|
|
|
|
|
: $3 eq 'length' ? |
576
|
|
|
|
|
|
|
"(?:" . cap_start . "($sign\[D1])" . '(?(?{ |
577
|
|
|
|
|
|
|
$$alt_types[pos()-1]eq"l"||$$prepped[pos()-1]eq 0 |
578
|
|
|
|
|
|
|
})|(?!))' . $type_is_dim_or_number . cap_end . ")" |
579
|
|
|
|
|
|
|
: $3 eq 'number' ? |
580
|
|
|
|
|
|
|
"(?:" . cap_start . "(1)(?{ $type_is_ CSS_NUMBER })" . cap_end . ")" |
581
|
|
|
|
|
|
|
: $3 eq 'percentage' ? |
582
|
|
|
|
|
|
|
"(?:" . cap_start |
583
|
|
|
|
|
|
|
. "($sign%)(?{ $type_is_ CSS_PERCENTAGE })" |
584
|
|
|
|
|
|
|
. cap_end . ")" |
585
|
|
|
|
|
|
|
: $3 eq 'shape' ? |
586
|
|
|
|
|
|
|
q*(?x:* . cap_start . q*(f |
587
|
|
|
|
|
|
|
(?(?{$$prepped[pos()-1] eq "rect("}) |
588
|
|
|
|
|
|
|
(?: |
589
|
|
|
|
|
|
|
(?: |
590
|
|
|
|
|
|
|
(?:d(?(?{$$alt_types[pos()-1]eq"+"})|(?!)))?[D1](?(?{ |
591
|
|
|
|
|
|
|
$$alt_types[pos()-1]eq"l"||$$prepped[pos()-1] eq 0 |
592
|
|
|
|
|
|
|
})|(?!)) |
593
|
|
|
|
|
|
|
| |
594
|
|
|
|
|
|
|
i(?(?{$$prepped[pos()-1]eq"auto"})|(?!)) |
595
|
|
|
|
|
|
|
),? |
596
|
|
|
|
|
|
|
){4} |
597
|
|
|
|
|
|
|
| |
598
|
|
|
|
|
|
|
(?!) |
599
|
|
|
|
|
|
|
) |
600
|
|
|
|
|
|
|
\))* . "(?{ $type_is_ CSS_RECT })" . cap_end . ")" |
601
|
|
|
|
|
|
|
: $3 eq 'string' ? |
602
|
|
|
|
|
|
|
"(?:" . cap_start . "(')(?{ $type_is_ CSS_STRING })" . cap_end . ")" |
603
|
|
|
|
|
|
|
: $3 eq 'str/words' ? |
604
|
|
|
|
|
|
|
"(?:" . cap_start |
605
|
|
|
|
|
|
|
. "('|i+)(?{ $type_is_ CSS_STRING })" |
606
|
|
|
|
|
|
|
. cap_end . ")" |
607
|
|
|
|
|
|
|
: $3 eq 'time' ? |
608
|
|
|
|
|
|
|
"(?:" . cap_start . "($sign\[D1])" . '(?(?{ |
609
|
|
|
|
|
|
|
my$p=$$prepped[pos()-1];$p eq"ms"||$p eq"s"||$p eq 0 |
610
|
|
|
|
|
|
|
})|(?!))' . $type_is_dim_or_number . cap_end . ")" |
611
|
|
|
|
|
|
|
: $3 eq 'url' ? |
612
|
|
|
|
|
|
|
"(?:" . cap_start . "(u)(?{ $type_is_ CSS_URI })" . cap_end . ")" |
613
|
|
|
|
|
|
|
: die "Unrecognised data type in property format: <$3>"; |
614
|
|
|
|
|
|
|
} |
615
|
|
|
|
|
|
|
elsif($4) { # identifier |
616
|
477
|
|
|
|
|
1622
|
$pattern .= |
617
|
|
|
|
|
|
|
'(?:' . cap_start |
618
|
|
|
|
|
|
|
. '(i)(?(?{$$prepped[-1+pos]eq"' . $4 . '"})|(?!))' |
619
|
|
|
|
|
|
|
. "(?{ $type_is_ CSS_IDENT })" |
620
|
|
|
|
|
|
|
. cap_end . ")"; |
621
|
|
|
|
|
|
|
} |
622
|
|
|
|
|
|
|
elsif($5) { # number |
623
|
18
|
|
|
|
|
55
|
$pattern .= |
624
|
|
|
|
|
|
|
'(?:' . cap_start |
625
|
|
|
|
|
|
|
. '(1)(?(?{$$tokens[-1+pos]eq"' . $5 . '"})|(?!))' |
626
|
|
|
|
|
|
|
. "(?{ $type_is_ CSS_NUMBER })" |
627
|
|
|
|
|
|
|
. cap_end . ")"; |
628
|
|
|
|
|
|
|
} |
629
|
|
|
|
|
|
|
elsif($6) { # '...' reference |
630
|
35
|
|
|
|
|
151
|
$pattern .= |
631
|
|
|
|
|
|
|
'(?:' # again, we use (?: ... ) in case a question mark is added |
632
|
|
|
|
|
|
|
. cap_start |
633
|
|
|
|
|
|
|
. '((??{ |
634
|
|
|
|
|
|
|
exists $$Self{"' . $6 . '"} |
635
|
|
|
|
|
|
|
? $compiled{$$Self{"' . $6 . '"}{format}} |
636
|
|
|
|
|
|
|
: $Fail; |
637
|
|
|
|
|
|
|
}))' |
638
|
|
|
|
|
|
|
. '(?{ |
639
|
|
|
|
|
|
|
# We have a do-block here because a re-eval’s lexical pad is very |
640
|
|
|
|
|
|
|
# buggy and must not be used. (See perl bug #65150.) |
641
|
|
|
|
|
|
|
local$match{"'.$6.'"}=do{ |
642
|
|
|
|
|
|
|
my @range |
643
|
|
|
|
|
|
|
= ' . (naughty_perl ? '$pos[-1]' : 'pos()-length$^N') . ' |
644
|
|
|
|
|
|
|
...-1+pos; |
645
|
|
|
|
|
|
|
[ |
646
|
|
|
|
|
|
|
'.( |
647
|
|
|
|
|
|
|
naughty_perl ? 'substr($_,$pos[-1],pos()-$pos[-1])' : '$^N' |
648
|
|
|
|
|
|
|
).', |
649
|
|
|
|
|
|
|
[@$tokens[@range]],[@valtypes[@range]],[@$prepped[@range]] |
650
|
|
|
|
|
|
|
]; |
651
|
|
|
|
|
|
|
} |
652
|
|
|
|
|
|
|
})' |
653
|
|
|
|
|
|
|
. cap_end |
654
|
|
|
|
|
|
|
.')' |
655
|
|
|
|
|
|
|
|
656
|
|
|
|
|
|
|
} |
657
|
713
|
|
|
|
|
1533
|
elsif(do{$7 =~ /^[]|[()]\z/}) { # group or alternation |
658
|
|
|
|
|
|
|
# For non-capturing groups, we use (?: ... ). |
659
|
|
|
|
|
|
|
# For capturing groups, since they may be quantified, and since we have |
660
|
|
|
|
|
|
|
# to put a re-eval after them to capture the value, we use an extra non- |
661
|
|
|
|
|
|
|
# capturing group: (?:( ... )(?{...})) |
662
|
|
|
|
|
|
|
# Since || is stronger than |, we have to treat | a bit like ][ |
663
|
|
|
|
|
|
|
|
664
|
659
|
100
|
|
|
|
722
|
if(do{$7 =~ /^[])|]\z/}) { # end of a group |
|
659
|
|
|
|
|
1354
|
|
665
|
569
|
|
|
|
|
676
|
my $markers = pop @permut_marker; |
666
|
569
|
100
|
|
|
|
822
|
if(@$markers) { # Oh no! |
667
|
6
|
|
|
|
|
14
|
unshift @$markers, $group_start[-1]; |
668
|
6
|
|
|
|
|
14
|
_make_permutations($pattern, $markers); |
669
|
|
|
|
|
|
|
} |
670
|
569
|
|
|
|
|
582
|
pop @group_start; |
671
|
569
|
100
|
|
|
|
1209
|
$pattern .= |
|
|
100
|
|
|
|
|
|
672
|
|
|
|
|
|
|
$7 eq '|' ? '|' |
673
|
|
|
|
|
|
|
: $7 eq ']' ? ')' |
674
|
|
|
|
|
|
|
: ')(?{ |
675
|
|
|
|
|
|
|
( |
676
|
|
|
|
|
|
|
local $match[-1][' . pop(@capture_nums) . '], |
677
|
|
|
|
|
|
|
local $list[-1] |
678
|
|
|
|
|
|
|
) = do { |
679
|
|
|
|
|
|
|
my @range |
680
|
|
|
|
|
|
|
= '.(naughty_perl ? '$pos[-1]' : 'pos()-length$^N').'...-1+pos; |
681
|
|
|
|
|
|
|
my @a = ( |
682
|
|
|
|
|
|
|
'.( |
683
|
|
|
|
|
|
|
naughty_perl |
684
|
|
|
|
|
|
|
? 'substr($_,$pos[-1],pos()-$pos[-1])' |
685
|
|
|
|
|
|
|
: '$^N' |
686
|
|
|
|
|
|
|
).', |
687
|
|
|
|
|
|
|
[@$tokens[@range]],[@valtypes[@range]],[@$prepped[@range]], |
688
|
|
|
|
|
|
|
pos |
689
|
|
|
|
|
|
|
); |
690
|
|
|
|
|
|
|
\@a, [@{$list[-1]}, \@a] |
691
|
|
|
|
|
|
|
} |
692
|
|
|
|
|
|
|
})' . cap_end . ')'; |
693
|
|
|
|
|
|
|
# We have to intertwine these assignments in this convoluted way |
694
|
|
|
|
|
|
|
# because of the lexical-in-re-eval bug [perl #65150]. |
695
|
|
|
|
|
|
|
} |
696
|
659
|
100
|
|
|
|
743
|
if(do{$7 =~ /^[[(|]\z/}) { # start of a group |
|
659
|
|
|
|
|
1507
|
|
697
|
569
|
100
|
|
|
|
1028
|
$pattern |
698
|
|
|
|
|
|
|
.= '(?:' |
699
|
|
|
|
|
|
|
. (cap_start.'(') |
700
|
|
|
|
|
|
|
x ($7 eq '(') |
701
|
|
|
|
|
|
|
unless $7 eq '|'; |
702
|
569
|
|
|
|
|
648
|
push @group_start, length $pattern; |
703
|
569
|
|
|
|
|
646
|
push @permut_marker, []; |
704
|
569
|
100
|
|
|
|
1854
|
$7 eq '(' and push @capture_nums, ++$last_capture; |
705
|
|
|
|
|
|
|
} |
706
|
|
|
|
|
|
|
} |
707
|
|
|
|
|
|
|
else { |
708
|
54
|
|
|
|
|
220
|
$pattern .= do{$7 =~ /^[?*+]\z/} ? $7 |
709
|
54
|
100
|
|
|
|
60
|
: do{$7 =~ /^[;{},:]\z/} ? quotemeta $7 |
|
9
|
100
|
|
|
|
47
|
|
710
|
|
|
|
|
|
|
: '(?:d(?(?{$$tokens[-1+pos]eq"' .quotemeta($7) .'"})|(?!)))' |
711
|
|
|
|
|
|
|
; |
712
|
|
|
|
|
|
|
} |
713
|
|
|
|
|
|
|
} |
714
|
|
|
|
|
|
|
|
715
|
|
|
|
|
|
|
# There may be top-level ‘||’ things, so we check for those. |
716
|
116
|
100
|
|
|
|
155
|
if(@{$permut_marker[0]}) { |
|
116
|
|
|
|
|
241
|
|
717
|
10
|
|
|
|
|
18
|
unshift @{ $permut_marker[0] }, $group_start[0]; |
|
10
|
|
|
|
|
24
|
|
718
|
10
|
|
|
|
|
27
|
_make_permutations($pattern, $permut_marker[0]); |
719
|
|
|
|
|
|
|
} |
720
|
|
|
|
|
|
|
|
721
|
|
|
|
|
|
|
# Deal with the match vars |
722
|
116
|
50
|
|
|
|
251
|
$pattern .= ')(?{@Match=@{$match[-1]};@List=@{$list[-1]};%Match=%match})' |
723
|
|
|
|
|
|
|
unless $no_match_stuff; |
724
|
|
|
|
|
|
|
|
725
|
4
|
|
|
4
|
|
27
|
use re 'eval'; |
|
4
|
|
|
|
|
7
|
|
|
4
|
|
|
|
|
8956
|
|
726
|
116
|
|
|
|
|
133697
|
return qr/$pattern/; |
727
|
|
|
|
|
|
|
} |
728
|
|
|
|
|
|
|
|
729
|
|
|
|
|
|
|
sub _make_permutations { # args: pattern, \@markers |
730
|
|
|
|
|
|
|
# pattern is modified in-place |
731
|
16
|
|
|
16
|
|
26
|
my $markers = pop; |
732
|
16
|
|
|
|
|
36
|
for my $pattern($_[0]) { |
733
|
|
|
|
|
|
|
# Split up the end of the pattern back to the beginning of the inner- |
734
|
|
|
|
|
|
|
# most enclosing group, as specified by the markers. Put the separate |
735
|
|
|
|
|
|
|
# pieces into @alts. |
736
|
16
|
|
|
|
|
24
|
my @alts; |
737
|
16
|
|
|
|
|
32
|
for(reverse @$markers) { |
738
|
48
|
|
|
|
|
126
|
unshift @alts, substr $pattern, $_, length $pattern, ''; |
739
|
|
|
|
|
|
|
} |
740
|
|
|
|
|
|
|
|
741
|
|
|
|
|
|
|
# Do the permutations |
742
|
16
|
|
|
|
|
57
|
$pattern .= _permute(@alts); |
743
|
|
|
|
|
|
|
} |
744
|
|
|
|
|
|
|
} |
745
|
|
|
|
|
|
|
|
746
|
|
|
|
|
|
|
sub _permute { |
747
|
160
|
100
|
|
160
|
|
248
|
if(@_ == 2) { return "(?:$_[0]$_[1]?|$_[1]$_[0]?)" } |
|
115
|
|
|
|
|
1984
|
|
748
|
|
|
|
|
|
|
else { |
749
|
|
|
|
|
|
|
return |
750
|
45
|
|
|
|
|
128
|
"(?:" |
751
|
|
|
|
|
|
|
. join("|", map $_[$_] . _permute(@_[0..$_-1,$_+1...$#_]) . '?', 0..$#_) |
752
|
|
|
|
|
|
|
. ")" |
753
|
|
|
|
|
|
|
} |
754
|
|
|
|
|
|
|
} |
755
|
|
|
|
|
|
|
|
756
|
|
|
|
|
|
|
|
757
|
|
|
|
|
|
|
=begin comment |
758
|
|
|
|
|
|
|
|
759
|
|
|
|
|
|
|
Colour names: |
760
|
|
|
|
|
|
|
|
761
|
|
|
|
|
|
|
perl -MRegexp::Assemble -le 'my $ra = new Regexp::Assemble; $ra->add($_) for qw " transparent aliceblue antiquewhite aqua aquamarine azure beige bisque black blanchedalmond blue blueviolet brown burlywood cadetblue chartreuse chocolate coral cornflowerblue cornsilk crimson cyan darkblue darkcyan darkgoldenrod darkgray darkgreen darkgrey darkkhaki darkmagenta darkolivegreen darkorange darkorchid darkred darksalmon darkseagreen darkslateblue darkslategray darkslategrey darkturquoise darkviolet deeppink deepskyblue dimgray dimgrey dodgerblue firebrick floralwhite forestgreen fuchsia gainsboro ghostwhite gold goldenrod gray green greenyellow grey honeydew hotpink indianred indigo ivory khaki lavender lavenderblush lawngreen lemonchiffon lightblue lightcoral lightcyan lightgoldenrodyellow lightgray lightgreen lightgrey lightpink lightsalmon lightseagreen lightskyblue lightslategray lightslategrey lightsteelblue lightyellow lime limegreen linen magenta maroon mediumaquamarine mediumblue mediumorchid mediumpurple mediumseagreen mediumslateblue mediumspringgreen mediumturquoise mediumvioletred midnightblue mintcream mistyrose moccasin navajowhite navy oldlace olive olivedrab orange orangered orchid palegoldenrod palegreen paleturquoise palevioletred papayawhip peachpuff peru pink plum powderblue purple red rosybrown royalblue saddlebrown salmon sandybrown seagreen seashell sienna silver skyblue slateblue slategray slategrey snow springgreen steelblue tan teal thistle tomato turquoise violet wheat white whitesmoke yellow yellowgreen"; print $ra->re ' |
762
|
|
|
|
|
|
|
|
763
|
|
|
|
|
|
|
perl -MRegexp::Assemble -le 'my $ra = new Regexp::Assemble; $ra->add($_) for qw " activeborder activecaption appworkspace background buttonface buttonhighlight buttonshadow buttontext captiontext graytext highlight highlighttext inactiveborder inactivecaption incativecaptiontext infobackground infotext menu menutext scrollbar threeddarkshadow threedface threedhighlight threedlightshadow threedshadow window windowframe windowtext "; print $ra->re ' |
764
|
|
|
|
|
|
|
|
765
|
|
|
|
|
|
|
=end comment |
766
|
|
|
|
|
|
|
|
767
|
|
|
|
|
|
|
=cut |
768
|
|
|
|
|
|
|
|
769
|
|
|
|
|
|
|
$colour_names_re = '(?:d(?:ark(?:s(?:late(?:gr[ae]y|blue)|(?:eagree|almo)n)|g(?:r(?:e(?:en|y)|ay)|oldenrod)|o(?:r(?:ange|chid)|livegreen)|(?:turquois|blu)e|magenta|violet|khaki|cyan|red)|eep(?:skyblue|pink)|imgr[ae]y|odgerblue)|l(?:i(?:ght(?:s(?:(?:eagree|almo)n|(?:teel|ky)blue|lategr[ae]y)|g(?:r(?:e(?:en|y)|ay)|oldenrodyellow)|c(?:oral|yan)|yellow|blue|pink)|me(?:green)?|nen)|a(?:vender(?:blush)?|wngreen)|emonchiffon)|m(?:edium(?:(?:aquamarin|turquois|purpl|blu)e|s(?:(?:pring|ea)green|lateblue)|(?:violetre|orchi)d)|i(?:(?:dnightblu|styros)e|ntcream)|a(?:genta|roon)|occasin)|s(?:(?:a(?:(?:ddle|ndy)brow|lmo)|pringgree)n|late(?:gr[ae]y|blue)|ea(?:green|shell)|(?:teel|ky)blue|i(?:enna|lver)|now)|p(?:a(?:le(?:g(?:oldenrod|reen)|turquoise|violetred)|payawhip)|(?:owderblu|urpl)e|e(?:achpuff|ru)|ink|lum)|c(?:(?:h(?:artreus|ocolat)|adetblu)e|or(?:n(?:flowerblue|silk)|al)|(?:rimso|ya)n)|b(?:l(?:a(?:nchedalmond|ck)|ue(?:violet)?)|(?:isqu|eig)e|urlywood|rown)|g(?:r(?:e(?:en(?:yellow)?|y)|ay)|ol(?:denro)?d|hostwhite|ainsboro)|o(?:l(?:ive(?:drab)?|dlace)|r(?:ange(?:red)?|chid))|a(?:(?:ntiquewhit|liceblu|zur)e|qua(?:marine)?)|t(?:(?:urquois|histl)e|ransparent|omato|eal|an)|f(?:loralwhite|orestgreen|irebrick|uchsia)|r(?:o(?:sybrown|yalblue)|ed)|i(?:ndi(?:anred|go)|vory)|wh(?:it(?:esmok)?e|eat)|ho(?:neydew|tpink)|nav(?:ajowhite|y)|yellow(?:green)?|violet|khaki)'; |
770
|
|
|
|
|
|
|
|
771
|
|
|
|
|
|
|
$system_colour_names_re = '(?:in(?:active(?:caption|border)|fo(?:background|text)|cativecaptiontext)|b(?:utton(?:(?:highligh|tex)t|shadow|face)|ackground)|threed(?:(?:light|dark)?shadow|highlight|face)|(?:(?:caption|gray)tex|highligh(?:ttex)?)t|a(?:ctive(?:caption|border)|ppworkspace)|window(?:frame|text)?|menu(?:text)?|scrollbar)'; |
772
|
|
|
|
|
|
|
|
773
|
|
|
|
|
|
|
=encoding utf8 |
774
|
|
|
|
|
|
|
|
775
|
|
|
|
|
|
|
=head1 NAME |
776
|
|
|
|
|
|
|
|
777
|
|
|
|
|
|
|
CSS::DOM::PropertyParser - Parser for CSS property values |
778
|
|
|
|
|
|
|
|
779
|
|
|
|
|
|
|
=head1 VERSION |
780
|
|
|
|
|
|
|
|
781
|
|
|
|
|
|
|
Version 0.17 |
782
|
|
|
|
|
|
|
|
783
|
|
|
|
|
|
|
=head1 SYNOPSIS |
784
|
|
|
|
|
|
|
|
785
|
|
|
|
|
|
|
use CSS::DOM::PropertyParser; |
786
|
|
|
|
|
|
|
|
787
|
|
|
|
|
|
|
$spec = new CSS::DOM::PropertyParser; # empty |
788
|
|
|
|
|
|
|
# OR |
789
|
|
|
|
|
|
|
$spec = $CSS::DOM::PropertyParser::Default->clone; |
790
|
|
|
|
|
|
|
|
791
|
|
|
|
|
|
|
$spec->add_property( |
792
|
|
|
|
|
|
|
overflow => { |
793
|
|
|
|
|
|
|
format => 'visible|hidden|scroll|auto', |
794
|
|
|
|
|
|
|
default => 'visible', |
795
|
|
|
|
|
|
|
inherit => 0, |
796
|
|
|
|
|
|
|
} |
797
|
|
|
|
|
|
|
); |
798
|
|
|
|
|
|
|
|
799
|
|
|
|
|
|
|
$hashref = $spec->get_property('overflow'); |
800
|
|
|
|
|
|
|
|
801
|
|
|
|
|
|
|
$hashref = $spec->delete_property('overflow'); |
802
|
|
|
|
|
|
|
|
803
|
|
|
|
|
|
|
@names = $spec->property_names; |
804
|
|
|
|
|
|
|
|
805
|
|
|
|
|
|
|
=head1 DESCRIPTION |
806
|
|
|
|
|
|
|
|
807
|
|
|
|
|
|
|
Objects of this class provide lists of supported properties for L |
808
|
|
|
|
|
|
|
style sheets. They also describe the syntax and parsing of those |
809
|
|
|
|
|
|
|
properties' values. |
810
|
|
|
|
|
|
|
|
811
|
|
|
|
|
|
|
Some CSS properties simply have their own values (e.g., overflow); some |
812
|
|
|
|
|
|
|
are abbreviated forms of several other properties (e.g., font). These are |
813
|
|
|
|
|
|
|
referred to in this documentation as 'simple' and 'shorthand' properties. |
814
|
|
|
|
|
|
|
|
815
|
|
|
|
|
|
|
=head1 CONSTRUCTOR |
816
|
|
|
|
|
|
|
|
817
|
|
|
|
|
|
|
C<$spec = new CSS::DOM::PropertyParser> returns an object that does not |
818
|
|
|
|
|
|
|
recognise any properties, to which you |
819
|
|
|
|
|
|
|
can add your own properties. |
820
|
|
|
|
|
|
|
|
821
|
|
|
|
|
|
|
There are two parser objects that come with this module. These are |
822
|
|
|
|
|
|
|
C<$CSS::DOM::PropertyParser::CSS21>, which contains all of CSS 2.1, and |
823
|
|
|
|
|
|
|
C<$CSS::DOM::PropertyParser::Default>, which is currently identical to the |
824
|
|
|
|
|
|
|
former, but to which parts of CSS 3 which eventually be added. |
825
|
|
|
|
|
|
|
|
826
|
|
|
|
|
|
|
If one of the default specs will do, you don't need a constructor. Simply |
827
|
|
|
|
|
|
|
pass it to the L constructor. If you want to modify it, clone it |
828
|
|
|
|
|
|
|
first, using the C method (as shown in the L). It is |
829
|
|
|
|
|
|
|
often convenient to clone the C<$Default> spec and delete those properties |
830
|
|
|
|
|
|
|
that are not supported. |
831
|
|
|
|
|
|
|
|
832
|
|
|
|
|
|
|
=head1 METHODS |
833
|
|
|
|
|
|
|
|
834
|
|
|
|
|
|
|
=for comment |
835
|
|
|
|
|
|
|
=head2 Methods for Controlling Property Specifications |
836
|
|
|
|
|
|
|
|
837
|
|
|
|
|
|
|
=over 4 |
838
|
|
|
|
|
|
|
|
839
|
|
|
|
|
|
|
=item clone |
840
|
|
|
|
|
|
|
|
841
|
|
|
|
|
|
|
Returns a deep clone of the object. (It's deep so that you can modify the |
842
|
|
|
|
|
|
|
hashes/arrays inside it without modifying the original.) |
843
|
|
|
|
|
|
|
|
844
|
|
|
|
|
|
|
=item add_property ( $name, \%spec ) |
845
|
|
|
|
|
|
|
|
846
|
|
|
|
|
|
|
Adds the specification for the named property. See |
847
|
|
|
|
|
|
|
L, below. |
848
|
|
|
|
|
|
|
|
849
|
|
|
|
|
|
|
=item get_property ( $name ) |
850
|
|
|
|
|
|
|
|
851
|
|
|
|
|
|
|
Returns the hashref passed to the previous method. |
852
|
|
|
|
|
|
|
|
853
|
|
|
|
|
|
|
=item delete_property ( $name ) |
854
|
|
|
|
|
|
|
|
855
|
|
|
|
|
|
|
Deletes the property and returns the hash ref. |
856
|
|
|
|
|
|
|
|
857
|
|
|
|
|
|
|
=item property_names |
858
|
|
|
|
|
|
|
|
859
|
|
|
|
|
|
|
Returns a list of the names of supported properties. |
860
|
|
|
|
|
|
|
|
861
|
|
|
|
|
|
|
=item subproperty_names ( $name ) |
862
|
|
|
|
|
|
|
|
863
|
|
|
|
|
|
|
Returns a list of the names of C<$name>'s sub-properties if it is a |
864
|
|
|
|
|
|
|
shorthand property. |
865
|
|
|
|
|
|
|
|
866
|
|
|
|
|
|
|
=item match |
867
|
|
|
|
|
|
|
|
868
|
|
|
|
|
|
|
Currently for internal use only. See the source code for documentation. |
869
|
|
|
|
|
|
|
Use at your own risk. |
870
|
|
|
|
|
|
|
|
871
|
|
|
|
|
|
|
=back |
872
|
|
|
|
|
|
|
|
873
|
|
|
|
|
|
|
=begin comment |
874
|
|
|
|
|
|
|
|
875
|
|
|
|
|
|
|
Once I’ve made CSS::DOM::Parser’s tokenise routine public (after a bit of |
876
|
|
|
|
|
|
|
polishing) (or broken it out into a separate module, CSS::Tokeniser), I’ll |
877
|
|
|
|
|
|
|
add this to the docs. I also actually have to modify ‘match’ to use this |
878
|
|
|
|
|
|
|
interface, of course. |
879
|
|
|
|
|
|
|
|
880
|
|
|
|
|
|
|
=head2 Methods Used by L |
881
|
|
|
|
|
|
|
|
882
|
|
|
|
|
|
|
If you are thinking of writing a subclass of PropertyParser, you need to be |
883
|
|
|
|
|
|
|
aware of these methods. |
884
|
|
|
|
|
|
|
|
885
|
|
|
|
|
|
|
Instead of writing a subclass, you can create your |
886
|
|
|
|
|
|
|
own class that does not inherit from PropertyParser use that. It will need |
887
|
|
|
|
|
|
|
to |
888
|
|
|
|
|
|
|
implement these methods here. The methods listed above can be omitted. |
889
|
|
|
|
|
|
|
|
890
|
|
|
|
|
|
|
=over |
891
|
|
|
|
|
|
|
|
892
|
|
|
|
|
|
|
=item match ( $property, $value ) |
893
|
|
|
|
|
|
|
|
894
|
|
|
|
|
|
|
=item match ( $property, $token_types, \@tokens ) |
895
|
|
|
|
|
|
|
|
896
|
|
|
|
|
|
|
This checks to see whether C<$value> is a valid value for the C<$property>, |
897
|
|
|
|
|
|
|
parsing it if it is. C<$token_types> and C<@tokens> are the values returned |
898
|
|
|
|
|
|
|
by C. |
899
|
|
|
|
|
|
|
|
900
|
|
|
|
|
|
|
Return values are as follows: |
901
|
|
|
|
|
|
|
|
902
|
|
|
|
|
|
|
If the value doesn't match: empty list. |
903
|
|
|
|
|
|
|
|
904
|
|
|
|
|
|
|
If the property is a simple one: (0) the CSS |
905
|
|
|
|
|
|
|
code for the value (possibly normalised), (1) the class to which a value |
906
|
|
|
|
|
|
|
object belongs, (2..) arguments to be passed to the constructor. |
907
|
|
|
|
|
|
|
|
908
|
|
|
|
|
|
|
For a shorthand property, the return value is a single hash ref, the keys |
909
|
|
|
|
|
|
|
being sub-property names and the values array refs containing what would be |
910
|
|
|
|
|
|
|
returned for a simple property. |
911
|
|
|
|
|
|
|
|
912
|
|
|
|
|
|
|
A custom class or subclass can return a L instead of the |
913
|
|
|
|
|
|
|
class and constructor args, in which case the first return value can |
914
|
|
|
|
|
|
|
simply be C (it should return C<(undef, $object)>). |
915
|
|
|
|
|
|
|
|
916
|
|
|
|
|
|
|
Examples (return value starts on the line following each method call): |
917
|
|
|
|
|
|
|
|
918
|
|
|
|
|
|
|
# $prim stands for "CSS::DOM::Value::Primitive" |
919
|
|
|
|
|
|
|
# $list stands for "CSS::DOM::Value::List" |
920
|
|
|
|
|
|
|
|
921
|
|
|
|
|
|
|
$prop_parser->match('background-position','top left'); |
922
|
|
|
|
|
|
|
'top left', 'CSS::DOM::Value', CSS_CUSTOM, 'top left' |
923
|
|
|
|
|
|
|
|
924
|
|
|
|
|
|
|
$prop_parser->match('background-position','inherit'); |
925
|
|
|
|
|
|
|
'inherit', 'CSS::DOM::Value', CSS_INHERIT |
926
|
|
|
|
|
|
|
|
927
|
|
|
|
|
|
|
$prop_parser->match('top','1em'); |
928
|
|
|
|
|
|
|
'1em', $prim, type => CSS_EMS, value => 1 |
929
|
|
|
|
|
|
|
|
930
|
|
|
|
|
|
|
$prop_parser->match('content','"\66oo"'); |
931
|
|
|
|
|
|
|
'"\66oo"', $prim, type => CSS_STRING, value => foo |
932
|
|
|
|
|
|
|
|
933
|
|
|
|
|
|
|
$prop_parser->match('clip','rect( 5px, 6px, 7px, 8px )'); |
934
|
|
|
|
|
|
|
'rect(5px, 6px, 7px, 8px)', $prim, |
935
|
|
|
|
|
|
|
type => CSS_RECT, |
936
|
|
|
|
|
|
|
value => [ [ type => CSS_PX, value => 5 ], |
937
|
|
|
|
|
|
|
[ type => CSS_PX, value => 6 ], |
938
|
|
|
|
|
|
|
[ type => CSS_PX, value => 7 ], |
939
|
|
|
|
|
|
|
[ type => CSS_PX, value => 8 ] ] |
940
|
|
|
|
|
|
|
|
941
|
|
|
|
|
|
|
$prop_parser->match('color','#fff'); |
942
|
|
|
|
|
|
|
'#fff', $prim, type => CSS_RGBCOLOR, value => '#fff' |
943
|
|
|
|
|
|
|
|
944
|
|
|
|
|
|
|
$prop_parser->match('color','rgba(255,0,0,.5)'); |
945
|
|
|
|
|
|
|
'rgba(255, 0, 0, .5)', $prim, type => CSS_RGBCOLOR, |
946
|
|
|
|
|
|
|
value => [ [ type => CSS_NUMBER, value => 255 ], |
947
|
|
|
|
|
|
|
[ type => CSS_NUMBER, value => 0 ], |
948
|
|
|
|
|
|
|
[ type => CSS_NUMBER, value => 0 ], |
949
|
|
|
|
|
|
|
[ type => CSS_NUMBER, value => .5 ] ] |
950
|
|
|
|
|
|
|
|
951
|
|
|
|
|
|
|
$prop_parser->match('content','counter(foo,disc)'); |
952
|
|
|
|
|
|
|
'counter(foo, disc)', $list, |
953
|
|
|
|
|
|
|
separator => ' ', |
954
|
|
|
|
|
|
|
values => [ |
955
|
|
|
|
|
|
|
[ |
956
|
|
|
|
|
|
|
type => CSS_COUNTER, |
957
|
|
|
|
|
|
|
value => [ |
958
|
|
|
|
|
|
|
[ type => CSS_IDENT, value => 'foo' ], |
959
|
|
|
|
|
|
|
undef, |
960
|
|
|
|
|
|
|
[ type => CSS_IDENT, value => 'disc' ], |
961
|
|
|
|
|
|
|
] |
962
|
|
|
|
|
|
|
], |
963
|
|
|
|
|
|
|
] |
964
|
|
|
|
|
|
|
|
965
|
|
|
|
|
|
|
$prop_parser->match('font-family','Lucida Grande'); |
966
|
|
|
|
|
|
|
'Lucida Grande', $list, |
967
|
|
|
|
|
|
|
separator => ', ', |
968
|
|
|
|
|
|
|
values => [ |
969
|
|
|
|
|
|
|
[ type => CSS_STRING, value => 'Lucida Grande' ], |
970
|
|
|
|
|
|
|
] |
971
|
|
|
|
|
|
|
|
972
|
|
|
|
|
|
|
$prop_parser->match('counter-reset','Lucida Grande'); |
973
|
|
|
|
|
|
|
'Lucida Grande', $list, |
974
|
|
|
|
|
|
|
separator => ' ', |
975
|
|
|
|
|
|
|
values => [ |
976
|
|
|
|
|
|
|
[ type => CSS_IDENT, value => 'Lucida' ], |
977
|
|
|
|
|
|
|
[ type => CSS_IDENT, value => 'Grande' ], |
978
|
|
|
|
|
|
|
] |
979
|
|
|
|
|
|
|
|
980
|
|
|
|
|
|
|
$prop_parser->match('font','bold 13px Lucida Grande'); |
981
|
|
|
|
|
|
|
{ |
982
|
|
|
|
|
|
|
'font-style' => [ |
983
|
|
|
|
|
|
|
'normal', $prim, type => CSS_IDENT, value => 'normal' |
984
|
|
|
|
|
|
|
], |
985
|
|
|
|
|
|
|
'font-variant' => [ |
986
|
|
|
|
|
|
|
'normal', $prim, type => CSS_IDENT, value => 'normal' |
987
|
|
|
|
|
|
|
], |
988
|
|
|
|
|
|
|
'font-weight' => [ |
989
|
|
|
|
|
|
|
'bold', $prim, type => CSS_IDENT, value => 'bold' |
990
|
|
|
|
|
|
|
], |
991
|
|
|
|
|
|
|
'font-size' => [ '13px', $prim, type => CSS_PX, value => 13 ], |
992
|
|
|
|
|
|
|
'line-height' => [ |
993
|
|
|
|
|
|
|
'normal', $prim, type => CSS_IDENT, value => 'normal' |
994
|
|
|
|
|
|
|
], |
995
|
|
|
|
|
|
|
'font-family' => [ 'Lucida Grande', $list, |
996
|
|
|
|
|
|
|
separator => ', ', |
997
|
|
|
|
|
|
|
values => [ |
998
|
|
|
|
|
|
|
[ type => CSS_STRING, value => 'Lucida Grande' ], |
999
|
|
|
|
|
|
|
] |
1000
|
|
|
|
|
|
|
] |
1001
|
|
|
|
|
|
|
} |
1002
|
|
|
|
|
|
|
|
1003
|
|
|
|
|
|
|
=item whatever |
1004
|
|
|
|
|
|
|
|
1005
|
|
|
|
|
|
|
~~~ |
1006
|
|
|
|
|
|
|
CSS::DOM::Style currently relies on the internal formatting of the hash |
1007
|
|
|
|
|
|
|
refs. I want to allow custom property parser classes to do away with hash |
1008
|
|
|
|
|
|
|
refs |
1009
|
|
|
|
|
|
|
altogether, so I will need extra methods here that Style will use instead. |
1010
|
|
|
|
|
|
|
|
1011
|
|
|
|
|
|
|
=back |
1012
|
|
|
|
|
|
|
|
1013
|
|
|
|
|
|
|
=end comment |
1014
|
|
|
|
|
|
|
|
1015
|
|
|
|
|
|
|
=head1 HOW INDIVIDUAL PROPERTIES ARE SPECIFIED |
1016
|
|
|
|
|
|
|
|
1017
|
|
|
|
|
|
|
Before you read this the first time, look at the L below, and |
1018
|
|
|
|
|
|
|
then come back and use this for reference. |
1019
|
|
|
|
|
|
|
|
1020
|
|
|
|
|
|
|
The specification for an individual property is a hash ref. There are |
1021
|
|
|
|
|
|
|
several keys that each hash ref can have: |
1022
|
|
|
|
|
|
|
|
1023
|
|
|
|
|
|
|
=over |
1024
|
|
|
|
|
|
|
|
1025
|
|
|
|
|
|
|
=item format |
1026
|
|
|
|
|
|
|
|
1027
|
|
|
|
|
|
|
This is set to a string that describes the format of the property. The |
1028
|
|
|
|
|
|
|
syntax used is based on the CSS 2.1 spec, but is not exactly the same. |
1029
|
|
|
|
|
|
|
Unlike regular expressions, these formats are applied to properties on a |
1030
|
|
|
|
|
|
|
token-by-token basis, not one character at a time. (This means that |
1031
|
|
|
|
|
|
|
C<100|200> cannot be written as C<[1|2]00>, as that would mean |
1032
|
|
|
|
|
|
|
S>.) |
1033
|
|
|
|
|
|
|
|
1034
|
|
|
|
|
|
|
Whitespace is ignored in the format and in the CSS property except as a |
1035
|
|
|
|
|
|
|
token separator. |
1036
|
|
|
|
|
|
|
|
1037
|
|
|
|
|
|
|
There are several metachars (in order of precedence): |
1038
|
|
|
|
|
|
|
|
1039
|
|
|
|
|
|
|
[...] grouping (like (?:...) ) |
1040
|
|
|
|
|
|
|
(...) capturing group (just like a regexp) |
1041
|
|
|
|
|
|
|
? optional |
1042
|
|
|
|
|
|
|
* zero or more |
1043
|
|
|
|
|
|
|
+ one or more |
1044
|
|
|
|
|
|
|
|| alternates that can come in any order and are optional, |
1045
|
|
|
|
|
|
|
but at least one must be specified (the order will be |
1046
|
|
|
|
|
|
|
retained if possible) |
1047
|
|
|
|
|
|
|
| alternates, exactly one of which is required |
1048
|
|
|
|
|
|
|
|
1049
|
|
|
|
|
|
|
In addition, the following datatypes can be specified in angle brackets: |
1050
|
|
|
|
|
|
|
|
1051
|
|
|
|
|
|
|
A number with a 'deg', 'rad' or 'grad' suffix |
1052
|
|
|
|
|
|
|
attr(...) |
1053
|
|
|
|
|
|
|
(You can omit the 'u' if you want to.) One of CSS's |
1054
|
|
|
|
|
|
|
predefined colour or system colour names, or a # |
1055
|
|
|
|
|
|
|
followed by 3 or 6 hex digits, or the 'rgb(...)' |
1056
|
|
|
|
|
|
|
format (rgba is supported, too) |
1057
|
|
|
|
|
|
|
counter(...) |
1058
|
|
|
|
|
|
|
A unit of Hz or kHz |
1059
|
|
|
|
|
|
|
An identifier token |
1060
|
|
|
|
|
|
|
An integer (really?!) |
1061
|
|
|
|
|
|
|
Number followed by a length unit (em, ex, px, in, cm, |
1062
|
|
|
|
|
|
|
mm, pt, pc) |
1063
|
|
|
|
|
|
|
A number token |
1064
|
|
|
|
|
|
|
Number followed by % |
1065
|
|
|
|
|
|
|
rect(...) |
1066
|
|
|
|
|
|
|
A string token |
1067
|
|
|
|
|
|
|
A sequence of identifiers or a single string (e.g., a |
1068
|
|
|
|
|
|
|
font name) |
1069
|
|
|
|
|
|
|
|
1070
|
|
|
|
|
|
|
A URL token |
1071
|
|
|
|
|
|
|
|
1072
|
|
|
|
|
|
|
The format for a shorthand property can contain the name of a sub-property |
1073
|
|
|
|
|
|
|
in single ASCII quotes. |
1074
|
|
|
|
|
|
|
|
1075
|
|
|
|
|
|
|
All other characters are understood verbatim. |
1076
|
|
|
|
|
|
|
|
1077
|
|
|
|
|
|
|
It is not necessary to include the word 'inherit' in the format, since |
1078
|
|
|
|
|
|
|
every property supports that. |
1079
|
|
|
|
|
|
|
|
1080
|
|
|
|
|
|
|
C<< >> makes use of the specification for the list-style-type |
1081
|
|
|
|
|
|
|
property. So if you modify the latter, it will affect C<< >> as |
1082
|
|
|
|
|
|
|
well. |
1083
|
|
|
|
|
|
|
|
1084
|
|
|
|
|
|
|
=item default |
1085
|
|
|
|
|
|
|
|
1086
|
|
|
|
|
|
|
The default value. This only applies to simple properties. |
1087
|
|
|
|
|
|
|
|
1088
|
|
|
|
|
|
|
=item inherit |
1089
|
|
|
|
|
|
|
|
1090
|
|
|
|
|
|
|
Whether the property is inherited. |
1091
|
|
|
|
|
|
|
|
1092
|
|
|
|
|
|
|
=item special_values |
1093
|
|
|
|
|
|
|
|
1094
|
|
|
|
|
|
|
A hash ref of values that are replaced with other values (e.g., |
1095
|
|
|
|
|
|
|
S '13px sans-serif' >>>.) The keys |
1096
|
|
|
|
|
|
|
are lowercase identifier names. |
1097
|
|
|
|
|
|
|
|
1098
|
|
|
|
|
|
|
This feature only applies to single identifiers. In fact, it exists solely |
1099
|
|
|
|
|
|
|
for the font property's use. |
1100
|
|
|
|
|
|
|
|
1101
|
|
|
|
|
|
|
=item list |
1102
|
|
|
|
|
|
|
|
1103
|
|
|
|
|
|
|
Set to true if the property is a list of values. The capturing parentheses |
1104
|
|
|
|
|
|
|
in the format determine the individual values of the list. |
1105
|
|
|
|
|
|
|
|
1106
|
|
|
|
|
|
|
This applies to simple properties only. |
1107
|
|
|
|
|
|
|
|
1108
|
|
|
|
|
|
|
=item properties |
1109
|
|
|
|
|
|
|
|
1110
|
|
|
|
|
|
|
For a shorthand property, list the sub-properties here. The keys are the |
1111
|
|
|
|
|
|
|
property names. The values are array refs. The elements within the arrays |
1112
|
|
|
|
|
|
|
are numbers indicating which captures in the format are to be used for the |
1113
|
|
|
|
|
|
|
sub-property's value. They are tried one after the other. Whichever is the |
1114
|
|
|
|
|
|
|
first that matches (null matches not counting) is used. |
1115
|
|
|
|
|
|
|
|
1116
|
|
|
|
|
|
|
Sub-properties that are referenced in the C need not be listed |
1117
|
|
|
|
|
|
|
here. |
1118
|
|
|
|
|
|
|
|
1119
|
|
|
|
|
|
|
=item serialise |
1120
|
|
|
|
|
|
|
|
1121
|
|
|
|
|
|
|
For shorthand properties only. Set this to a subroutine that serialises the |
1122
|
|
|
|
|
|
|
property. It is called with a hashref of sub-properties as its sole |
1123
|
|
|
|
|
|
|
argument. The values of the hash are blank for properties that are set to |
1124
|
|
|
|
|
|
|
their initial values. This sub is only called when all sub-properties are |
1125
|
|
|
|
|
|
|
set. |
1126
|
|
|
|
|
|
|
|
1127
|
|
|
|
|
|
|
=back |
1128
|
|
|
|
|
|
|
|
1129
|
|
|
|
|
|
|
=head2 Example |
1130
|
|
|
|
|
|
|
|
1131
|
|
|
|
|
|
|
=cut |
1132
|
|
|
|
|
|
|
|
1133
|
|
|
|
|
|
|
0&&q r |
1134
|
|
|
|
|
|
|
|
1135
|
|
|
|
|
|
|
=for ; |
1136
|
|
|
|
|
|
|
|
1137
|
|
|
|
|
|
|
our $CSS21 = new CSS::DOM::PropertyParser; |
1138
|
|
|
|
|
|
|
my %properties = ( |
1139
|
|
|
|
|
|
|
azimuth => { |
1140
|
|
|
|
|
|
|
format => ' | |
1141
|
|
|
|
|
|
|
[ left-side | far-left | left | center-left | |
1142
|
|
|
|
|
|
|
center | center-right | right | far-right | |
1143
|
|
|
|
|
|
|
right-inside ] || behind |
1144
|
|
|
|
|
|
|
| leftwards | rightwards', |
1145
|
|
|
|
|
|
|
default => '0', |
1146
|
|
|
|
|
|
|
inherit => 1, |
1147
|
|
|
|
|
|
|
}, |
1148
|
|
|
|
|
|
|
|
1149
|
|
|
|
|
|
|
'background-attachment' => { |
1150
|
|
|
|
|
|
|
format => 'scroll | fixed', |
1151
|
|
|
|
|
|
|
default => 'scroll', |
1152
|
|
|
|
|
|
|
inherit => 0, |
1153
|
|
|
|
|
|
|
}, |
1154
|
|
|
|
|
|
|
|
1155
|
|
|
|
|
|
|
'background-color' => { |
1156
|
|
|
|
|
|
|
format => '', |
1157
|
|
|
|
|
|
|
default => 'transparent', |
1158
|
|
|
|
|
|
|
inherit => 0, |
1159
|
|
|
|
|
|
|
}, |
1160
|
|
|
|
|
|
|
|
1161
|
|
|
|
|
|
|
'background-image' => { |
1162
|
|
|
|
|
|
|
format => ' | none', |
1163
|
|
|
|
|
|
|
default => 'none', |
1164
|
|
|
|
|
|
|
inherit => 0, |
1165
|
|
|
|
|
|
|
}, |
1166
|
|
|
|
|
|
|
|
1167
|
|
|
|
|
|
|
'background-position' => { |
1168
|
|
|
|
|
|
|
format => '[||left|right] |
1169
|
|
|
|
|
|
|
[||top|center|bottom]? | |
1170
|
|
|
|
|
|
|
[top|bottom] [left|center|right]? | |
1171
|
|
|
|
|
|
|
center [||left|right|top|bottom| |
1172
|
|
|
|
|
|
|
center]?', |
1173
|
|
|
|
|
|
|
default => '0% 0%', |
1174
|
|
|
|
|
|
|
inherit => 0, |
1175
|
|
|
|
|
|
|
}, |
1176
|
|
|
|
|
|
|
|
1177
|
|
|
|
|
|
|
'background-repeat' => { |
1178
|
|
|
|
|
|
|
format => 'repeat | repeat-x | repeat-y | no-repeat', |
1179
|
|
|
|
|
|
|
default => 'repeat', |
1180
|
|
|
|
|
|
|
inherit => 0, |
1181
|
|
|
|
|
|
|
}, |
1182
|
|
|
|
|
|
|
|
1183
|
|
|
|
|
|
|
background => { |
1184
|
|
|
|
|
|
|
format => "'background-color' || 'background-image' || |
1185
|
|
|
|
|
|
|
'background-repeat' || 'background-attachment' || |
1186
|
|
|
|
|
|
|
'background-position'", |
1187
|
|
|
|
|
|
|
serialise => sub { |
1188
|
|
|
|
|
|
|
my $p = shift; |
1189
|
|
|
|
|
|
|
my $ret = ''; |
1190
|
|
|
|
|
|
|
for(qw/ background-color background-image background-repeat |
1191
|
|
|
|
|
|
|
background-attachment background-position /) { |
1192
|
|
|
|
|
|
|
length $p->{$_} and $ret .= "$p->{$_} "; |
1193
|
|
|
|
|
|
|
} |
1194
|
|
|
|
|
|
|
chop $ret; |
1195
|
|
|
|
|
|
|
length $ret ? $ret : 'none' |
1196
|
|
|
|
|
|
|
}, |
1197
|
|
|
|
|
|
|
}, |
1198
|
|
|
|
|
|
|
|
1199
|
|
|
|
|
|
|
'border-collapse' => { |
1200
|
|
|
|
|
|
|
format => 'collapse | separate', |
1201
|
|
|
|
|
|
|
inherit => 1, |
1202
|
|
|
|
|
|
|
default => 'separate', |
1203
|
|
|
|
|
|
|
}, |
1204
|
|
|
|
|
|
|
|
1205
|
|
|
|
|
|
|
'border-color' => { |
1206
|
|
|
|
|
|
|
format => '()[()[()()?]?]?', |
1207
|
|
|
|
|
|
|
properties => { |
1208
|
|
|
|
|
|
|
'border-top-color' => [1], |
1209
|
|
|
|
|
|
|
'border-right-color' => [2,1], |
1210
|
|
|
|
|
|
|
'border-bottom-color' => [3,1], |
1211
|
|
|
|
|
|
|
'border-left-color' => [4,2,1], |
1212
|
|
|
|
|
|
|
}, |
1213
|
|
|
|
|
|
|
serialise => sub { |
1214
|
|
|
|
|
|
|
my $p = shift; |
1215
|
|
|
|
|
|
|
my @vals = map $p->{"border-$_-color"}, |
1216
|
|
|
|
|
|
|
qw/top right bottom left/; |
1217
|
|
|
|
|
|
|
$vals[3] eq $vals[1] and pop @vals, |
1218
|
|
|
|
|
|
|
$vals[2] eq $vals[0] and pop @vals, |
1219
|
|
|
|
|
|
|
$vals[1] eq $vals[0] and pop @vals; |
1220
|
|
|
|
|
|
|
return join " ", @vals; |
1221
|
|
|
|
|
|
|
}, |
1222
|
|
|
|
|
|
|
}, |
1223
|
|
|
|
|
|
|
|
1224
|
|
|
|
|
|
|
'border-spacing' => { |
1225
|
|
|
|
|
|
|
format => ' ?', |
1226
|
|
|
|
|
|
|
default => '0', |
1227
|
|
|
|
|
|
|
inherit => 1, |
1228
|
|
|
|
|
|
|
}, |
1229
|
|
|
|
|
|
|
|
1230
|
|
|
|
|
|
|
'border-style' => { |
1231
|
|
|
|
|
|
|
format => "(none|hidden|dotted|dashed|solid|double|groove|ridge| |
1232
|
|
|
|
|
|
|
inset|outset) |
1233
|
|
|
|
|
|
|
[ (none|hidden|dotted|dashed|solid|double|groove| |
1234
|
|
|
|
|
|
|
ridge|inset|outset) |
1235
|
|
|
|
|
|
|
[ (none|hidden|dotted|dashed|solid|double|groove| |
1236
|
|
|
|
|
|
|
ridge|inset|outset) |
1237
|
|
|
|
|
|
|
(none|hidden|dotted|dashed|solid|double|groove| |
1238
|
|
|
|
|
|
|
ridge|inset|outset)? |
1239
|
|
|
|
|
|
|
]? |
1240
|
|
|
|
|
|
|
]?", |
1241
|
|
|
|
|
|
|
properties => { |
1242
|
|
|
|
|
|
|
'border-top-style' => [1], |
1243
|
|
|
|
|
|
|
'border-right-style' => [2,1], |
1244
|
|
|
|
|
|
|
'border-bottom-style' => [3,1], |
1245
|
|
|
|
|
|
|
'border-left-style' => [4,2,1], |
1246
|
|
|
|
|
|
|
}, |
1247
|
|
|
|
|
|
|
serialise => sub { |
1248
|
|
|
|
|
|
|
my $p = shift; |
1249
|
|
|
|
|
|
|
my @vals = map $p->{"border-$_-style"}, |
1250
|
|
|
|
|
|
|
qw/top right bottom left/; |
1251
|
|
|
|
|
|
|
$vals[3] eq $vals[1] and pop @vals, |
1252
|
|
|
|
|
|
|
$vals[2] eq $vals[0] and pop @vals, |
1253
|
|
|
|
|
|
|
$vals[1] eq $vals[0] and pop @vals; |
1254
|
|
|
|
|
|
|
return join " ", map $_||'none', @vals; |
1255
|
|
|
|
|
|
|
}, |
1256
|
|
|
|
|
|
|
}, |
1257
|
|
|
|
|
|
|
|
1258
|
|
|
|
|
|
|
'border-top' => { |
1259
|
|
|
|
|
|
|
format => "'border-top-width' || 'border-top-style' || |
1260
|
|
|
|
|
|
|
'border-top-color'", |
1261
|
|
|
|
|
|
|
serialise => sub { |
1262
|
|
|
|
|
|
|
my $p = shift; |
1263
|
|
|
|
|
|
|
my $ret = ''; |
1264
|
|
|
|
|
|
|
for(qw/ width style color /) { |
1265
|
|
|
|
|
|
|
length $p->{"border-top-$_"} |
1266
|
|
|
|
|
|
|
and $ret .= $p->{"border-top-$_"}." "; |
1267
|
|
|
|
|
|
|
} |
1268
|
|
|
|
|
|
|
chop $ret; |
1269
|
|
|
|
|
|
|
$ret |
1270
|
|
|
|
|
|
|
}, |
1271
|
|
|
|
|
|
|
}, |
1272
|
|
|
|
|
|
|
'border-right' => { |
1273
|
|
|
|
|
|
|
format => "'border-right-width' || 'border-right-style' || |
1274
|
|
|
|
|
|
|
'border-right-color'", |
1275
|
|
|
|
|
|
|
serialise => sub { |
1276
|
|
|
|
|
|
|
my $p = shift; |
1277
|
|
|
|
|
|
|
my $ret = ''; |
1278
|
|
|
|
|
|
|
for(qw/ width style color /) { |
1279
|
|
|
|
|
|
|
length $p->{"border-right-$_"} |
1280
|
|
|
|
|
|
|
and $ret .= $p->{"border-right-$_"}." "; |
1281
|
|
|
|
|
|
|
} |
1282
|
|
|
|
|
|
|
chop $ret; |
1283
|
|
|
|
|
|
|
$ret |
1284
|
|
|
|
|
|
|
}, |
1285
|
|
|
|
|
|
|
}, |
1286
|
|
|
|
|
|
|
'border-bottom' => { |
1287
|
|
|
|
|
|
|
format => "'border-bottom-width' || 'border-bottom-style' || |
1288
|
|
|
|
|
|
|
'border-bottom-color'", |
1289
|
|
|
|
|
|
|
serialise => sub { |
1290
|
|
|
|
|
|
|
my $p = shift; |
1291
|
|
|
|
|
|
|
my $ret = ''; |
1292
|
|
|
|
|
|
|
for(qw/ width style color /) { |
1293
|
|
|
|
|
|
|
length $p->{"border-bottom-$_"} |
1294
|
|
|
|
|
|
|
and $ret .= $p->{"border-bottom-$_"}." "; |
1295
|
|
|
|
|
|
|
} |
1296
|
|
|
|
|
|
|
chop $ret; |
1297
|
|
|
|
|
|
|
$ret |
1298
|
|
|
|
|
|
|
}, |
1299
|
|
|
|
|
|
|
}, |
1300
|
|
|
|
|
|
|
'border-left' => { |
1301
|
|
|
|
|
|
|
format => "'border-left-width' || 'border-left-style' || |
1302
|
|
|
|
|
|
|
'border-left-color'", |
1303
|
|
|
|
|
|
|
serialise => sub { |
1304
|
|
|
|
|
|
|
my $p = shift; |
1305
|
|
|
|
|
|
|
my $ret = ''; |
1306
|
|
|
|
|
|
|
for(qw/ width style color /) { |
1307
|
|
|
|
|
|
|
length $p->{"border-left-$_"} |
1308
|
|
|
|
|
|
|
and $ret .= $p->{"border-left-$_"}." "; |
1309
|
|
|
|
|
|
|
} |
1310
|
|
|
|
|
|
|
chop $ret; |
1311
|
|
|
|
|
|
|
$ret |
1312
|
|
|
|
|
|
|
}, |
1313
|
|
|
|
|
|
|
}, |
1314
|
|
|
|
|
|
|
|
1315
|
|
|
|
|
|
|
'border-top-color' => { |
1316
|
|
|
|
|
|
|
format => '', |
1317
|
|
|
|
|
|
|
default => "", |
1318
|
|
|
|
|
|
|
inherit => 0, |
1319
|
|
|
|
|
|
|
}, |
1320
|
|
|
|
|
|
|
'border-right-color' => { |
1321
|
|
|
|
|
|
|
format => '', |
1322
|
|
|
|
|
|
|
default => "", |
1323
|
|
|
|
|
|
|
inherit => 0, |
1324
|
|
|
|
|
|
|
}, |
1325
|
|
|
|
|
|
|
'border-bottom-color' => { |
1326
|
|
|
|
|
|
|
format => '', |
1327
|
|
|
|
|
|
|
default => "", |
1328
|
|
|
|
|
|
|
inherit => 0, |
1329
|
|
|
|
|
|
|
}, |
1330
|
|
|
|
|
|
|
'border-left-color' => { |
1331
|
|
|
|
|
|
|
format => '', |
1332
|
|
|
|
|
|
|
default => "", |
1333
|
|
|
|
|
|
|
inherit => 0, |
1334
|
|
|
|
|
|
|
}, |
1335
|
|
|
|
|
|
|
|
1336
|
|
|
|
|
|
|
'border-top-style' => { |
1337
|
|
|
|
|
|
|
format => 'none|hidden|dotted|dashed|solid|double|groove|ridge| |
1338
|
|
|
|
|
|
|
inset|outset', |
1339
|
|
|
|
|
|
|
default => 'none', |
1340
|
|
|
|
|
|
|
inherit => 0, |
1341
|
|
|
|
|
|
|
}, |
1342
|
|
|
|
|
|
|
'border-right-style' => { |
1343
|
|
|
|
|
|
|
format => 'none|hidden|dotted|dashed|solid|double|groove|ridge| |
1344
|
|
|
|
|
|
|
inset|outset', |
1345
|
|
|
|
|
|
|
default => 'none', |
1346
|
|
|
|
|
|
|
inherit => 0, |
1347
|
|
|
|
|
|
|
}, |
1348
|
|
|
|
|
|
|
'border-bottom-style' => { |
1349
|
|
|
|
|
|
|
format => 'none|hidden|dotted|dashed|solid|double|groove|ridge| |
1350
|
|
|
|
|
|
|
inset|outset', |
1351
|
|
|
|
|
|
|
default => 'none', |
1352
|
|
|
|
|
|
|
inherit => 0, |
1353
|
|
|
|
|
|
|
}, |
1354
|
|
|
|
|
|
|
'border-left-style' => { |
1355
|
|
|
|
|
|
|
format => 'none|hidden|dotted|dashed|solid|double|groove|ridge| |
1356
|
|
|
|
|
|
|
inset|outset', |
1357
|
|
|
|
|
|
|
default => 'none', |
1358
|
|
|
|
|
|
|
inherit => 0, |
1359
|
|
|
|
|
|
|
}, |
1360
|
|
|
|
|
|
|
|
1361
|
|
|
|
|
|
|
'border-top-width' => { |
1362
|
|
|
|
|
|
|
format => '|thin|thick|medium', |
1363
|
|
|
|
|
|
|
default => 'medium', |
1364
|
|
|
|
|
|
|
inherit => 0, |
1365
|
|
|
|
|
|
|
}, |
1366
|
|
|
|
|
|
|
'border-right-width' => { |
1367
|
|
|
|
|
|
|
format => '|thin|thick|medium', |
1368
|
|
|
|
|
|
|
default => 'medium', |
1369
|
|
|
|
|
|
|
inherit => 0, |
1370
|
|
|
|
|
|
|
}, |
1371
|
|
|
|
|
|
|
'border-bottom-width' => { |
1372
|
|
|
|
|
|
|
format => '|thin|thick|medium', |
1373
|
|
|
|
|
|
|
default => 'medium', |
1374
|
|
|
|
|
|
|
inherit => 0, |
1375
|
|
|
|
|
|
|
}, |
1376
|
|
|
|
|
|
|
'border-left-width' => { |
1377
|
|
|
|
|
|
|
format => '|thin|thick|medium', |
1378
|
|
|
|
|
|
|
default => 'medium', |
1379
|
|
|
|
|
|
|
inherit => 0, |
1380
|
|
|
|
|
|
|
}, |
1381
|
|
|
|
|
|
|
|
1382
|
|
|
|
|
|
|
'border-width' => { |
1383
|
|
|
|
|
|
|
format => "(|thin|thick|medium) |
1384
|
|
|
|
|
|
|
[ (|thin|thick|medium) |
1385
|
|
|
|
|
|
|
[ (|thin|thick|medium) |
1386
|
|
|
|
|
|
|
(|thin|thick|medium)? |
1387
|
|
|
|
|
|
|
]? |
1388
|
|
|
|
|
|
|
]?", |
1389
|
|
|
|
|
|
|
properties => { |
1390
|
|
|
|
|
|
|
'border-top-width' => [1], |
1391
|
|
|
|
|
|
|
'border-right-width' => [2,1], |
1392
|
|
|
|
|
|
|
'border-bottom-width' => [3,1], |
1393
|
|
|
|
|
|
|
'border-left-width' => [4,2,1], |
1394
|
|
|
|
|
|
|
}, |
1395
|
|
|
|
|
|
|
serialise => sub { |
1396
|
|
|
|
|
|
|
my $p = shift; |
1397
|
|
|
|
|
|
|
my @vals = map $p->{"border-$_-width"}, |
1398
|
|
|
|
|
|
|
qw/top right bottom left/; |
1399
|
|
|
|
|
|
|
$vals[3] eq $vals[1] and pop @vals, |
1400
|
|
|
|
|
|
|
$vals[2] eq $vals[0] and pop @vals, |
1401
|
|
|
|
|
|
|
$vals[1] eq $vals[0] and pop @vals; |
1402
|
|
|
|
|
|
|
return join " ", map length $_ ? $_ : 'medium', @vals; |
1403
|
|
|
|
|
|
|
}, |
1404
|
|
|
|
|
|
|
}, |
1405
|
|
|
|
|
|
|
|
1406
|
|
|
|
|
|
|
border => { |
1407
|
|
|
|
|
|
|
format => "(|thin|thick|medium) || |
1408
|
|
|
|
|
|
|
(none|hidden|dotted|dashed|solid|double|groove|ridge| |
1409
|
|
|
|
|
|
|
inset|outset) || ()", |
1410
|
|
|
|
|
|
|
properties => { |
1411
|
|
|
|
|
|
|
'border-top-width' => [1], |
1412
|
|
|
|
|
|
|
'border-right-width' => [1], |
1413
|
|
|
|
|
|
|
'border-bottom-width' => [1], |
1414
|
|
|
|
|
|
|
'border-left-width' => [1], |
1415
|
|
|
|
|
|
|
'border-top-style' => [2], |
1416
|
|
|
|
|
|
|
'border-right-style' => [2], |
1417
|
|
|
|
|
|
|
'border-bottom-style' => [2], |
1418
|
|
|
|
|
|
|
'border-left-style' => [2], |
1419
|
|
|
|
|
|
|
'border-top-color' => [3], |
1420
|
|
|
|
|
|
|
'border-right-color' => [3], |
1421
|
|
|
|
|
|
|
'border-bottom-color' => [3], |
1422
|
|
|
|
|
|
|
'border-left-color' => [3], |
1423
|
|
|
|
|
|
|
}, |
1424
|
|
|
|
|
|
|
serialise => sub { |
1425
|
|
|
|
|
|
|
my $p = shift; |
1426
|
|
|
|
|
|
|
my $ret = ''; |
1427
|
|
|
|
|
|
|
for(qw/ width style color /) { |
1428
|
|
|
|
|
|
|
my $temp = $p->{"border-top-$_"}; |
1429
|
|
|
|
|
|
|
for my $side(qw/ right bottom left /) { |
1430
|
|
|
|
|
|
|
$temp eq $p->{"border-$side-$_"} or return ""; |
1431
|
|
|
|
|
|
|
} |
1432
|
|
|
|
|
|
|
length $temp and $ret .= "$temp "; |
1433
|
|
|
|
|
|
|
} |
1434
|
|
|
|
|
|
|
chop $ret; |
1435
|
|
|
|
|
|
|
$ret |
1436
|
|
|
|
|
|
|
}, |
1437
|
|
|
|
|
|
|
}, |
1438
|
|
|
|
|
|
|
|
1439
|
|
|
|
|
|
|
bottom => { |
1440
|
|
|
|
|
|
|
format => '||auto', |
1441
|
|
|
|
|
|
|
default => 'auto', |
1442
|
|
|
|
|
|
|
inherit => 0, |
1443
|
|
|
|
|
|
|
}, |
1444
|
|
|
|
|
|
|
|
1445
|
|
|
|
|
|
|
'caption-side' => { |
1446
|
|
|
|
|
|
|
format => 'top|bottom', |
1447
|
|
|
|
|
|
|
default => 'top', |
1448
|
|
|
|
|
|
|
inherit => 1, |
1449
|
|
|
|
|
|
|
}, |
1450
|
|
|
|
|
|
|
|
1451
|
|
|
|
|
|
|
clear => { |
1452
|
|
|
|
|
|
|
format => 'none|left|right|both', |
1453
|
|
|
|
|
|
|
default => 'none', |
1454
|
|
|
|
|
|
|
inherit => 0, |
1455
|
|
|
|
|
|
|
}, |
1456
|
|
|
|
|
|
|
|
1457
|
|
|
|
|
|
|
clip => { |
1458
|
|
|
|
|
|
|
format => '|auto', |
1459
|
|
|
|
|
|
|
default => 'auto', |
1460
|
|
|
|
|
|
|
inherit => 0, |
1461
|
|
|
|
|
|
|
}, |
1462
|
|
|
|
|
|
|
|
1463
|
|
|
|
|
|
|
color => { |
1464
|
|
|
|
|
|
|
format => '', |
1465
|
|
|
|
|
|
|
default => 'rgba(0,0,0,1)', |
1466
|
|
|
|
|
|
|
inherit => 1, |
1467
|
|
|
|
|
|
|
}, |
1468
|
|
|
|
|
|
|
|
1469
|
|
|
|
|
|
|
content => { |
1470
|
|
|
|
|
|
|
format => '( normal|none|open-quote|close-quote|no-open-quote| |
1471
|
|
|
|
|
|
|
no-close-quote|||| )+', |
1472
|
|
|
|
|
|
|
default => 'normal', |
1473
|
|
|
|
|
|
|
inherit => 0, |
1474
|
|
|
|
|
|
|
list => 1, |
1475
|
|
|
|
|
|
|
}, |
1476
|
|
|
|
|
|
|
|
1477
|
|
|
|
|
|
|
'counter-increment' => { |
1478
|
|
|
|
|
|
|
format => '[() ()? ]+ | none', |
1479
|
|
|
|
|
|
|
default => 'none', |
1480
|
|
|
|
|
|
|
inherit => 0, |
1481
|
|
|
|
|
|
|
list => 1, |
1482
|
|
|
|
|
|
|
}, |
1483
|
|
|
|
|
|
|
'counter-reset' => { |
1484
|
|
|
|
|
|
|
format => '[() ()? ]+ | none', |
1485
|
|
|
|
|
|
|
default => 'none', |
1486
|
|
|
|
|
|
|
inherit => 0, |
1487
|
|
|
|
|
|
|
list => 1, |
1488
|
|
|
|
|
|
|
}, |
1489
|
|
|
|
|
|
|
|
1490
|
|
|
|
|
|
|
'cue-after' => { |
1491
|
|
|
|
|
|
|
format => '|none', |
1492
|
|
|
|
|
|
|
default => 'none', |
1493
|
|
|
|
|
|
|
inherit => 0, |
1494
|
|
|
|
|
|
|
}, |
1495
|
|
|
|
|
|
|
'cue-before' => { |
1496
|
|
|
|
|
|
|
format => '|none', |
1497
|
|
|
|
|
|
|
default => 'none', |
1498
|
|
|
|
|
|
|
inherit => 0, |
1499
|
|
|
|
|
|
|
}, |
1500
|
|
|
|
|
|
|
|
1501
|
|
|
|
|
|
|
cue =>{ |
1502
|
|
|
|
|
|
|
format => '(|none) (|none)?', |
1503
|
|
|
|
|
|
|
properties => { |
1504
|
|
|
|
|
|
|
'cue-before' => [1], |
1505
|
|
|
|
|
|
|
'cue-after' => [2,1], |
1506
|
|
|
|
|
|
|
}, |
1507
|
|
|
|
|
|
|
serialise => sub { |
1508
|
|
|
|
|
|
|
my $p = shift; |
1509
|
|
|
|
|
|
|
my @vals = @$p{"cue-before", "cue-after"}; |
1510
|
|
|
|
|
|
|
$vals[1] eq $vals[0] and pop @vals; |
1511
|
|
|
|
|
|
|
return join " ", map length $_ ? $_ : 'none', @vals; |
1512
|
|
|
|
|
|
|
}, |
1513
|
|
|
|
|
|
|
}, |
1514
|
|
|
|
|
|
|
|
1515
|
|
|
|
|
|
|
cursor => { |
1516
|
|
|
|
|
|
|
format => '[() ,]* |
1517
|
|
|
|
|
|
|
(auto|crosshair|default|pointer|move|e-resize| |
1518
|
|
|
|
|
|
|
ne-resize|nw-resize|n-resize|se-resize|sw-resize| |
1519
|
|
|
|
|
|
|
s-resize|w-resize|text|wait|help|progress)', |
1520
|
|
|
|
|
|
|
default => 'auto', |
1521
|
|
|
|
|
|
|
inherit => 1, |
1522
|
|
|
|
|
|
|
list => 1, |
1523
|
|
|
|
|
|
|
}, |
1524
|
|
|
|
|
|
|
|
1525
|
|
|
|
|
|
|
direction => { |
1526
|
|
|
|
|
|
|
format => 'ltr|rtl', |
1527
|
|
|
|
|
|
|
default => 'ltr', |
1528
|
|
|
|
|
|
|
inherit => 1, |
1529
|
|
|
|
|
|
|
}, |
1530
|
|
|
|
|
|
|
|
1531
|
|
|
|
|
|
|
display => { |
1532
|
|
|
|
|
|
|
format => 'inline|block|list-item|run-in|inline-block|table| |
1533
|
|
|
|
|
|
|
inline-table|table-row-group|table-header-group| |
1534
|
|
|
|
|
|
|
table-footer-group|table-row|table-column-group| |
1535
|
|
|
|
|
|
|
table-column|table-cell|table-caption|none', |
1536
|
|
|
|
|
|
|
default => 'inline', |
1537
|
|
|
|
|
|
|
inherit => 0, |
1538
|
|
|
|
|
|
|
}, |
1539
|
|
|
|
|
|
|
|
1540
|
|
|
|
|
|
|
elevation => { |
1541
|
|
|
|
|
|
|
format => '|below|level|above|higher|lower', |
1542
|
|
|
|
|
|
|
default => '0', |
1543
|
|
|
|
|
|
|
inherit => 1, |
1544
|
|
|
|
|
|
|
}, |
1545
|
|
|
|
|
|
|
|
1546
|
|
|
|
|
|
|
'empty-cells' => { |
1547
|
|
|
|
|
|
|
format => 'show|hide', |
1548
|
|
|
|
|
|
|
default => 'show', |
1549
|
|
|
|
|
|
|
inherit => 1, |
1550
|
|
|
|
|
|
|
}, |
1551
|
|
|
|
|
|
|
|
1552
|
|
|
|
|
|
|
float => { |
1553
|
|
|
|
|
|
|
format => 'left|right|none', |
1554
|
|
|
|
|
|
|
default => 'none', |
1555
|
|
|
|
|
|
|
inherit => 0, |
1556
|
|
|
|
|
|
|
}, |
1557
|
|
|
|
|
|
|
|
1558
|
|
|
|
|
|
|
'font-family' => { # aka typeface |
1559
|
|
|
|
|
|
|
format => '(serif|sans-serif|cursive|fantasy|monospace| |
1560
|
|
|
|
|
|
|
) |
1561
|
|
|
|
|
|
|
[,(serif|sans-serif|cursive|fantasy|monospace| |
1562
|
|
|
|
|
|
|
)]*', |
1563
|
|
|
|
|
|
|
default => 'Times, serif', |
1564
|
|
|
|
|
|
|
inherit => 1, |
1565
|
|
|
|
|
|
|
list => 1, |
1566
|
|
|
|
|
|
|
}, |
1567
|
|
|
|
|
|
|
|
1568
|
|
|
|
|
|
|
'font-size' => { |
1569
|
|
|
|
|
|
|
format => 'xx-small|x-small|small|medium|large|x-large|xx-large| |
1570
|
|
|
|
|
|
|
larger|smaller||', |
1571
|
|
|
|
|
|
|
default => 'medium', |
1572
|
|
|
|
|
|
|
inherit => 1, |
1573
|
|
|
|
|
|
|
}, |
1574
|
|
|
|
|
|
|
|
1575
|
|
|
|
|
|
|
'font-style' => { |
1576
|
|
|
|
|
|
|
format => 'normal|italic|oblique', |
1577
|
|
|
|
|
|
|
default => 'normal', |
1578
|
|
|
|
|
|
|
inherit => 1, |
1579
|
|
|
|
|
|
|
}, |
1580
|
|
|
|
|
|
|
|
1581
|
|
|
|
|
|
|
'font-variant' => { |
1582
|
|
|
|
|
|
|
format => 'normal | small-caps', |
1583
|
|
|
|
|
|
|
default => 'normal', |
1584
|
|
|
|
|
|
|
inherit => 1, |
1585
|
|
|
|
|
|
|
}, |
1586
|
|
|
|
|
|
|
|
1587
|
|
|
|
|
|
|
'font-weight' => { |
1588
|
|
|
|
|
|
|
format => 'normal|bold|bolder|lighter| |
1589
|
|
|
|
|
|
|
100|200|300|400|500|600|700|800|900', |
1590
|
|
|
|
|
|
|
default => 'normal', |
1591
|
|
|
|
|
|
|
inherit => 1, |
1592
|
|
|
|
|
|
|
}, |
1593
|
|
|
|
|
|
|
|
1594
|
|
|
|
|
|
|
font => { |
1595
|
|
|
|
|
|
|
format => "[ 'font-style' || 'font-variant' || 'font-weight' ]? |
1596
|
|
|
|
|
|
|
'font-size' [ / 'line-height' ]? 'font-family'", |
1597
|
|
|
|
|
|
|
special_values => { |
1598
|
|
|
|
|
|
|
caption => '13px Lucida Grande, sans-serif', |
1599
|
|
|
|
|
|
|
icon => '13px Lucida Grande, sans-serif', |
1600
|
|
|
|
|
|
|
menu => '13px Lucida Grande, sans-serif', |
1601
|
|
|
|
|
|
|
'message-box' => '13px Lucida Grande, sans-serif', |
1602
|
|
|
|
|
|
|
'small-caption' => '11px Lucida Grande, sans-serif', |
1603
|
|
|
|
|
|
|
'status-bar' => '10px Lucida Grande, sans-serif', |
1604
|
|
|
|
|
|
|
}, |
1605
|
|
|
|
|
|
|
serialise => sub { |
1606
|
|
|
|
|
|
|
my $p = shift; |
1607
|
|
|
|
|
|
|
my $ret = ''; |
1608
|
|
|
|
|
|
|
for(qw/ style variant weight /) { |
1609
|
|
|
|
|
|
|
length $p->{"font-$_"} |
1610
|
|
|
|
|
|
|
and $ret .= $p->{"font-$_"}." "; |
1611
|
|
|
|
|
|
|
} |
1612
|
|
|
|
|
|
|
$ret .= length $p->{'font-size'} |
1613
|
|
|
|
|
|
|
? $p->{'font-size'} |
1614
|
|
|
|
|
|
|
: 'medium'; |
1615
|
|
|
|
|
|
|
$ret .= "/$p->{'line-height'}" if length $p->{'line-height'}; |
1616
|
|
|
|
|
|
|
$ret .= " " . ($p->{'font-family'} || "Times, serif"); |
1617
|
|
|
|
|
|
|
$ret |
1618
|
|
|
|
|
|
|
}, |
1619
|
|
|
|
|
|
|
}, |
1620
|
|
|
|
|
|
|
|
1621
|
|
|
|
|
|
|
height => { |
1622
|
|
|
|
|
|
|
format => '||auto', |
1623
|
|
|
|
|
|
|
default => 'auto', |
1624
|
|
|
|
|
|
|
inherit => 0, |
1625
|
|
|
|
|
|
|
}, |
1626
|
|
|
|
|
|
|
|
1627
|
|
|
|
|
|
|
left => { |
1628
|
|
|
|
|
|
|
format => '||auto', |
1629
|
|
|
|
|
|
|
default => 'auto', |
1630
|
|
|
|
|
|
|
inherit => 0, |
1631
|
|
|
|
|
|
|
}, |
1632
|
|
|
|
|
|
|
|
1633
|
|
|
|
|
|
|
'letter-spacing' => { # aka tracking |
1634
|
|
|
|
|
|
|
format => 'normal|', |
1635
|
|
|
|
|
|
|
default => 'normal', |
1636
|
|
|
|
|
|
|
inherit => 1, |
1637
|
|
|
|
|
|
|
}, |
1638
|
|
|
|
|
|
|
|
1639
|
|
|
|
|
|
|
'line-height' => { # aka leading |
1640
|
|
|
|
|
|
|
format => 'normal|||', |
1641
|
|
|
|
|
|
|
default => "normal", |
1642
|
|
|
|
|
|
|
inherit => 1, |
1643
|
|
|
|
|
|
|
}, |
1644
|
|
|
|
|
|
|
|
1645
|
|
|
|
|
|
|
'list-style-image' => { |
1646
|
|
|
|
|
|
|
format => '|none', |
1647
|
|
|
|
|
|
|
default => 'none', |
1648
|
|
|
|
|
|
|
inherit => 1, |
1649
|
|
|
|
|
|
|
}, |
1650
|
|
|
|
|
|
|
|
1651
|
|
|
|
|
|
|
'list-style-position' => { |
1652
|
|
|
|
|
|
|
format => 'inside|outside', |
1653
|
|
|
|
|
|
|
default => 'outside', |
1654
|
|
|
|
|
|
|
inherit => 1, |
1655
|
|
|
|
|
|
|
}, |
1656
|
|
|
|
|
|
|
|
1657
|
|
|
|
|
|
|
'list-style-type' => { |
1658
|
|
|
|
|
|
|
format => 'disc|circle|square|decimal|decimal-leading-zero| |
1659
|
|
|
|
|
|
|
lower-roman|upper-roman|lower-greek|lower-latin| |
1660
|
|
|
|
|
|
|
upper-latin|armenian|georgian|lower-alpha| |
1661
|
|
|
|
|
|
|
upper-alpha', |
1662
|
|
|
|
|
|
|
default => 'disc', |
1663
|
|
|
|
|
|
|
inherit => 1, |
1664
|
|
|
|
|
|
|
}, |
1665
|
|
|
|
|
|
|
|
1666
|
|
|
|
|
|
|
'list-style' => { |
1667
|
|
|
|
|
|
|
format => "'list-style-type'||'list-style-position'|| |
1668
|
|
|
|
|
|
|
'list-style-image'", |
1669
|
|
|
|
|
|
|
serialise => sub { |
1670
|
|
|
|
|
|
|
my $p = shift; |
1671
|
|
|
|
|
|
|
my $ret = ''; |
1672
|
|
|
|
|
|
|
for(qw/ type position image /) { |
1673
|
|
|
|
|
|
|
$p->{"list-style-$_"} |
1674
|
|
|
|
|
|
|
and $ret .= $p->{"list-style-$_"}." "; |
1675
|
|
|
|
|
|
|
} |
1676
|
|
|
|
|
|
|
chop $ret; |
1677
|
|
|
|
|
|
|
$ret || 'disc' |
1678
|
|
|
|
|
|
|
}, |
1679
|
|
|
|
|
|
|
}, |
1680
|
|
|
|
|
|
|
|
1681
|
|
|
|
|
|
|
'margin-right' => { |
1682
|
|
|
|
|
|
|
format => '||auto', |
1683
|
|
|
|
|
|
|
default => '0', |
1684
|
|
|
|
|
|
|
inherit => 0, |
1685
|
|
|
|
|
|
|
}, |
1686
|
|
|
|
|
|
|
'margin-left' => { |
1687
|
|
|
|
|
|
|
format => '||auto', |
1688
|
|
|
|
|
|
|
default => '0', |
1689
|
|
|
|
|
|
|
inherit => 0, |
1690
|
|
|
|
|
|
|
}, |
1691
|
|
|
|
|
|
|
'margin-top' => { |
1692
|
|
|
|
|
|
|
format => '||auto', |
1693
|
|
|
|
|
|
|
default => '0', |
1694
|
|
|
|
|
|
|
inherit => 0, |
1695
|
|
|
|
|
|
|
}, |
1696
|
|
|
|
|
|
|
'margin-bottom' => { |
1697
|
|
|
|
|
|
|
format => '||auto', |
1698
|
|
|
|
|
|
|
default => '0', |
1699
|
|
|
|
|
|
|
inherit => 0, |
1700
|
|
|
|
|
|
|
}, |
1701
|
|
|
|
|
|
|
|
1702
|
|
|
|
|
|
|
margin => { |
1703
|
|
|
|
|
|
|
format => "(||auto) |
1704
|
|
|
|
|
|
|
[ (||auto) |
1705
|
|
|
|
|
|
|
[ (||auto) |
1706
|
|
|
|
|
|
|
(||auto)? |
1707
|
|
|
|
|
|
|
]? |
1708
|
|
|
|
|
|
|
]?", |
1709
|
|
|
|
|
|
|
properties => { |
1710
|
|
|
|
|
|
|
'margin-top' => [1], |
1711
|
|
|
|
|
|
|
'margin-right' => [2,1], |
1712
|
|
|
|
|
|
|
'margin-bottom' => [3,1], |
1713
|
|
|
|
|
|
|
'margin-left' => [4,2,1], |
1714
|
|
|
|
|
|
|
}, |
1715
|
|
|
|
|
|
|
serialise => sub { |
1716
|
|
|
|
|
|
|
my $p = shift; |
1717
|
|
|
|
|
|
|
my @vals = map $p->{"margin-$_"}, |
1718
|
|
|
|
|
|
|
qw/top right bottom left/; |
1719
|
|
|
|
|
|
|
$vals[3] eq $vals[1] and pop @vals, |
1720
|
|
|
|
|
|
|
$vals[2] eq $vals[0] and pop @vals, |
1721
|
|
|
|
|
|
|
$vals[1] eq $vals[0] and pop @vals; |
1722
|
|
|
|
|
|
|
return join " ", map $_ || 0, @vals; |
1723
|
|
|
|
|
|
|
}, |
1724
|
|
|
|
|
|
|
}, |
1725
|
|
|
|
|
|
|
|
1726
|
|
|
|
|
|
|
'max-height' => { |
1727
|
|
|
|
|
|
|
format => '||none', |
1728
|
|
|
|
|
|
|
default => 'none', |
1729
|
|
|
|
|
|
|
inherit => 0, |
1730
|
|
|
|
|
|
|
}, |
1731
|
|
|
|
|
|
|
'max-width' => { |
1732
|
|
|
|
|
|
|
format => '||none', |
1733
|
|
|
|
|
|
|
default => 'none', |
1734
|
|
|
|
|
|
|
inherit => 0, |
1735
|
|
|
|
|
|
|
}, |
1736
|
|
|
|
|
|
|
'min-height' => { |
1737
|
|
|
|
|
|
|
format => '||none', |
1738
|
|
|
|
|
|
|
default => 'none', |
1739
|
|
|
|
|
|
|
inherit => 0, |
1740
|
|
|
|
|
|
|
}, |
1741
|
|
|
|
|
|
|
'min-width' => { |
1742
|
|
|
|
|
|
|
format => '||none', |
1743
|
|
|
|
|
|
|
default => 'none', |
1744
|
|
|
|
|
|
|
inherit => 0, |
1745
|
|
|
|
|
|
|
}, |
1746
|
|
|
|
|
|
|
|
1747
|
|
|
|
|
|
|
orphans => { |
1748
|
|
|
|
|
|
|
format => '', |
1749
|
|
|
|
|
|
|
default => 2, |
1750
|
|
|
|
|
|
|
inherit => 1, |
1751
|
|
|
|
|
|
|
}, |
1752
|
|
|
|
|
|
|
|
1753
|
|
|
|
|
|
|
'outline-color' => { |
1754
|
|
|
|
|
|
|
format => '|invert', |
1755
|
|
|
|
|
|
|
default => 'invert', |
1756
|
|
|
|
|
|
|
inherit => 0, |
1757
|
|
|
|
|
|
|
}, |
1758
|
|
|
|
|
|
|
|
1759
|
|
|
|
|
|
|
'outline-style' => { |
1760
|
|
|
|
|
|
|
format => 'none|hidden|dotted|dashed|solid|double|groove|ridge| |
1761
|
|
|
|
|
|
|
inset|outset', |
1762
|
|
|
|
|
|
|
default => 'none', |
1763
|
|
|
|
|
|
|
inherit => 0, |
1764
|
|
|
|
|
|
|
}, |
1765
|
|
|
|
|
|
|
|
1766
|
|
|
|
|
|
|
'outline-width' => { |
1767
|
|
|
|
|
|
|
format => '|thin|thick|medium', |
1768
|
|
|
|
|
|
|
default => 'medium', |
1769
|
|
|
|
|
|
|
inherit => 0, |
1770
|
|
|
|
|
|
|
}, |
1771
|
|
|
|
|
|
|
|
1772
|
|
|
|
|
|
|
outline => { |
1773
|
|
|
|
|
|
|
format => "'outline-color'||'outline-style'||'outline-width'", |
1774
|
|
|
|
|
|
|
serialise => sub { |
1775
|
|
|
|
|
|
|
my $p = shift; |
1776
|
|
|
|
|
|
|
my $ret = ''; |
1777
|
|
|
|
|
|
|
for(qw/ color style width /) { |
1778
|
|
|
|
|
|
|
length $p->{"outline-$_"} |
1779
|
|
|
|
|
|
|
and $ret .= $p->{"outline-$_"}." "; |
1780
|
|
|
|
|
|
|
} |
1781
|
|
|
|
|
|
|
chop $ret; |
1782
|
|
|
|
|
|
|
length $ret ? $ret : 'invert'; |
1783
|
|
|
|
|
|
|
}, |
1784
|
|
|
|
|
|
|
}, |
1785
|
|
|
|
|
|
|
|
1786
|
|
|
|
|
|
|
overflow => { |
1787
|
|
|
|
|
|
|
format => 'visible|hidden|scroll|auto', |
1788
|
|
|
|
|
|
|
default => 'visible', |
1789
|
|
|
|
|
|
|
inherit => 0, |
1790
|
|
|
|
|
|
|
}, |
1791
|
|
|
|
|
|
|
|
1792
|
|
|
|
|
|
|
'padding-top' => { |
1793
|
|
|
|
|
|
|
format => '|', |
1794
|
|
|
|
|
|
|
default => 0, |
1795
|
|
|
|
|
|
|
inherit => 0, |
1796
|
|
|
|
|
|
|
}, |
1797
|
|
|
|
|
|
|
'padding-right' => { |
1798
|
|
|
|
|
|
|
format => '|', |
1799
|
|
|
|
|
|
|
default => 0, |
1800
|
|
|
|
|
|
|
inherit => 0, |
1801
|
|
|
|
|
|
|
}, |
1802
|
|
|
|
|
|
|
'padding-bottom' => { |
1803
|
|
|
|
|
|
|
format => '|', |
1804
|
|
|
|
|
|
|
default => 0, |
1805
|
|
|
|
|
|
|
inherit => 0, |
1806
|
|
|
|
|
|
|
}, |
1807
|
|
|
|
|
|
|
'padding-left' => { |
1808
|
|
|
|
|
|
|
format => '|', |
1809
|
|
|
|
|
|
|
default => 0, |
1810
|
|
|
|
|
|
|
inherit => 0, |
1811
|
|
|
|
|
|
|
}, |
1812
|
|
|
|
|
|
|
|
1813
|
|
|
|
|
|
|
padding => { |
1814
|
|
|
|
|
|
|
format => "(|) |
1815
|
|
|
|
|
|
|
[ (|) |
1816
|
|
|
|
|
|
|
[ (|) |
1817
|
|
|
|
|
|
|
(|)? |
1818
|
|
|
|
|
|
|
]? |
1819
|
|
|
|
|
|
|
]?", |
1820
|
|
|
|
|
|
|
properties => { |
1821
|
|
|
|
|
|
|
'padding-top' => [1], |
1822
|
|
|
|
|
|
|
'padding-right' => [2,1], |
1823
|
|
|
|
|
|
|
'padding-bottom' => [3,1], |
1824
|
|
|
|
|
|
|
'padding-left' => [4,2,1], |
1825
|
|
|
|
|
|
|
}, |
1826
|
|
|
|
|
|
|
serialise => sub { |
1827
|
|
|
|
|
|
|
my $p = shift; |
1828
|
|
|
|
|
|
|
my @vals = map $p->{"padding-$_"}, |
1829
|
|
|
|
|
|
|
qw/top right bottom left/; |
1830
|
|
|
|
|
|
|
$vals[3] eq $vals[1] and pop @vals, |
1831
|
|
|
|
|
|
|
$vals[2] eq $vals[0] and pop @vals, |
1832
|
|
|
|
|
|
|
$vals[1] eq $vals[0] and pop @vals; |
1833
|
|
|
|
|
|
|
return join " ", map $_ || 0, @vals; |
1834
|
|
|
|
|
|
|
}, |
1835
|
|
|
|
|
|
|
}, |
1836
|
|
|
|
|
|
|
|
1837
|
|
|
|
|
|
|
'page-break-after' => { |
1838
|
|
|
|
|
|
|
format => 'auto|always|avoid|left|right', |
1839
|
|
|
|
|
|
|
default => 'auto', |
1840
|
|
|
|
|
|
|
inherit => 0, |
1841
|
|
|
|
|
|
|
}, |
1842
|
|
|
|
|
|
|
'page-break-before' => { |
1843
|
|
|
|
|
|
|
format => 'auto|always|avoid|left|right', |
1844
|
|
|
|
|
|
|
default => 'auto', |
1845
|
|
|
|
|
|
|
inherit => 0, |
1846
|
|
|
|
|
|
|
}, |
1847
|
|
|
|
|
|
|
|
1848
|
|
|
|
|
|
|
'page-break-inside' => { |
1849
|
|
|
|
|
|
|
format => 'avoid|auto', |
1850
|
|
|
|
|
|
|
default => 'auto', |
1851
|
|
|
|
|
|
|
inherit => 1, |
1852
|
|
|
|
|
|
|
}, |
1853
|
|
|
|
|
|
|
|
1854
|
|
|
|
|
|
|
'pause-after' => { |
1855
|
|
|
|
|
|
|
format => ' |
1856
|
|
|
|
|
|
|
default => 0, |
1857
|
|
|
|
|
|
|
inherit => 0, |
1858
|
|
|
|
|
|
|
}, |
1859
|
|
|
|
|
|
|
'pause-before' => { |
1860
|
|
|
|
|
|
|
format => ' |
1861
|
|
|
|
|
|
|
default => 0, |
1862
|
|
|
|
|
|
|
inherit => 0, |
1863
|
|
|
|
|
|
|
}, |
1864
|
|
|
|
|
|
|
|
1865
|
|
|
|
|
|
|
pause => { |
1866
|
|
|
|
|
|
|
format => '( |
1867
|
|
|
|
|
|
|
properties => { |
1868
|
|
|
|
|
|
|
'pause-before' => [1], |
1869
|
|
|
|
|
|
|
'pause-after' => [2,1], |
1870
|
|
|
|
|
|
|
} |
1871
|
|
|
|
|
|
|
}, |
1872
|
|
|
|
|
|
|
|
1873
|
|
|
|
|
|
|
'pitch-range' => { |
1874
|
|
|
|
|
|
|
format => '', |
1875
|
|
|
|
|
|
|
default => 50, |
1876
|
|
|
|
|
|
|
inherit => 1, |
1877
|
|
|
|
|
|
|
}, |
1878
|
|
|
|
|
|
|
|
1879
|
|
|
|
|
|
|
pitch => { |
1880
|
|
|
|
|
|
|
format => '|x-low|low|medium|high|x-high', |
1881
|
|
|
|
|
|
|
default => 'medium', |
1882
|
|
|
|
|
|
|
inherit => 1, |
1883
|
|
|
|
|
|
|
}, |
1884
|
|
|
|
|
|
|
|
1885
|
|
|
|
|
|
|
'play-during' => { |
1886
|
|
|
|
|
|
|
format => ' [ mix || repeat ]? | auto | none', |
1887
|
|
|
|
|
|
|
default => 'auto', |
1888
|
|
|
|
|
|
|
inherit => 0, |
1889
|
|
|
|
|
|
|
}, |
1890
|
|
|
|
|
|
|
|
1891
|
|
|
|
|
|
|
position => { |
1892
|
|
|
|
|
|
|
format => 'static|relative|absolute|fixed', |
1893
|
|
|
|
|
|
|
default => 'relative', |
1894
|
|
|
|
|
|
|
inherit => 0, |
1895
|
|
|
|
|
|
|
}, |
1896
|
|
|
|
|
|
|
|
1897
|
|
|
|
|
|
|
quotes => { |
1898
|
|
|
|
|
|
|
format => '[()()]+|none', |
1899
|
|
|
|
|
|
|
default => 'none', |
1900
|
|
|
|
|
|
|
inherit => 1, |
1901
|
|
|
|
|
|
|
list => 1, |
1902
|
|
|
|
|
|
|
}, |
1903
|
|
|
|
|
|
|
|
1904
|
|
|
|
|
|
|
richness => { |
1905
|
|
|
|
|
|
|
format => '', |
1906
|
|
|
|
|
|
|
default => 50, |
1907
|
|
|
|
|
|
|
inherit => 1, |
1908
|
|
|
|
|
|
|
}, |
1909
|
|
|
|
|
|
|
|
1910
|
|
|
|
|
|
|
right => { |
1911
|
|
|
|
|
|
|
format => '||auto', |
1912
|
|
|
|
|
|
|
default => 'auto', |
1913
|
|
|
|
|
|
|
inherit => 0, |
1914
|
|
|
|
|
|
|
}, |
1915
|
|
|
|
|
|
|
|
1916
|
|
|
|
|
|
|
'speak-header' => { |
1917
|
|
|
|
|
|
|
format => 'once|always', |
1918
|
|
|
|
|
|
|
default => 'once', |
1919
|
|
|
|
|
|
|
inherit => 1, |
1920
|
|
|
|
|
|
|
}, |
1921
|
|
|
|
|
|
|
|
1922
|
|
|
|
|
|
|
'speak-numeral' => { |
1923
|
|
|
|
|
|
|
format => 'digits|continuous', |
1924
|
|
|
|
|
|
|
default => 'continuous', |
1925
|
|
|
|
|
|
|
inherit => 1, |
1926
|
|
|
|
|
|
|
}, |
1927
|
|
|
|
|
|
|
|
1928
|
|
|
|
|
|
|
'speak-punctuation' => { |
1929
|
|
|
|
|
|
|
format => 'code|none', |
1930
|
|
|
|
|
|
|
default => 'none', |
1931
|
|
|
|
|
|
|
inherit => 1, |
1932
|
|
|
|
|
|
|
}, |
1933
|
|
|
|
|
|
|
|
1934
|
|
|
|
|
|
|
speak => { |
1935
|
|
|
|
|
|
|
format => 'normal|none|spell-out', |
1936
|
|
|
|
|
|
|
default => 'normal', |
1937
|
|
|
|
|
|
|
inherit => 1, |
1938
|
|
|
|
|
|
|
}, |
1939
|
|
|
|
|
|
|
|
1940
|
|
|
|
|
|
|
'speech-rate' => { |
1941
|
|
|
|
|
|
|
format => '|x-slow|slow|medium|fast|x-fast|faster|slower', |
1942
|
|
|
|
|
|
|
default => 'medium', |
1943
|
|
|
|
|
|
|
inherit => 1, |
1944
|
|
|
|
|
|
|
}, |
1945
|
|
|
|
|
|
|
|
1946
|
|
|
|
|
|
|
stress => { |
1947
|
|
|
|
|
|
|
format => '', |
1948
|
|
|
|
|
|
|
default => 50, |
1949
|
|
|
|
|
|
|
inherit => 1, |
1950
|
|
|
|
|
|
|
}, |
1951
|
|
|
|
|
|
|
|
1952
|
|
|
|
|
|
|
'table-layout' => { |
1953
|
|
|
|
|
|
|
format => 'auto|fixed', |
1954
|
|
|
|
|
|
|
default => 'auto', |
1955
|
|
|
|
|
|
|
inherit => 0, |
1956
|
|
|
|
|
|
|
}, |
1957
|
|
|
|
|
|
|
|
1958
|
|
|
|
|
|
|
'text-align' => { |
1959
|
|
|
|
|
|
|
format => 'left|right|center|justify|auto', |
1960
|
|
|
|
|
|
|
default => 'auto', |
1961
|
|
|
|
|
|
|
inherit => 1, |
1962
|
|
|
|
|
|
|
}, |
1963
|
|
|
|
|
|
|
|
1964
|
|
|
|
|
|
|
'text-decoration' => { |
1965
|
|
|
|
|
|
|
format => 'none | underline||overline||line-through||blink ', |
1966
|
|
|
|
|
|
|
default => 'none', |
1967
|
|
|
|
|
|
|
inherit => 0, |
1968
|
|
|
|
|
|
|
}, |
1969
|
|
|
|
|
|
|
|
1970
|
|
|
|
|
|
|
'text-indent' => { |
1971
|
|
|
|
|
|
|
format => '|', |
1972
|
|
|
|
|
|
|
default => 0, |
1973
|
|
|
|
|
|
|
inherit => 1, |
1974
|
|
|
|
|
|
|
}, |
1975
|
|
|
|
|
|
|
|
1976
|
|
|
|
|
|
|
'text-transform' => { |
1977
|
|
|
|
|
|
|
format => 'capitalize|uppercase|lowercase|none', |
1978
|
|
|
|
|
|
|
default => 'none', |
1979
|
|
|
|
|
|
|
inherit => 1, |
1980
|
|
|
|
|
|
|
}, |
1981
|
|
|
|
|
|
|
|
1982
|
|
|
|
|
|
|
top => { |
1983
|
|
|
|
|
|
|
format => '||auto', |
1984
|
|
|
|
|
|
|
default => 'auto', |
1985
|
|
|
|
|
|
|
inherit => 0, |
1986
|
|
|
|
|
|
|
}, |
1987
|
|
|
|
|
|
|
|
1988
|
|
|
|
|
|
|
'unicode-bidi' => { |
1989
|
|
|
|
|
|
|
format => 'normal|embed|bidi-override', |
1990
|
|
|
|
|
|
|
default => 'normal', |
1991
|
|
|
|
|
|
|
inherit => 0, |
1992
|
|
|
|
|
|
|
}, |
1993
|
|
|
|
|
|
|
|
1994
|
|
|
|
|
|
|
'vertical-align' => { |
1995
|
|
|
|
|
|
|
format => 'baseline|sub|super|top|text-top|middle|bottom| |
1996
|
|
|
|
|
|
|
text-bottom||', |
1997
|
|
|
|
|
|
|
default => 'baseline', |
1998
|
|
|
|
|
|
|
inherit => 0, |
1999
|
|
|
|
|
|
|
}, |
2000
|
|
|
|
|
|
|
|
2001
|
|
|
|
|
|
|
visibility => { |
2002
|
|
|
|
|
|
|
format => 'visible|hidden|collapse', |
2003
|
|
|
|
|
|
|
default => 'visible', |
2004
|
|
|
|
|
|
|
inherit => 1, |
2005
|
|
|
|
|
|
|
}, |
2006
|
|
|
|
|
|
|
|
2007
|
|
|
|
|
|
|
'voice-family' => { |
2008
|
|
|
|
|
|
|
format => '(male|female|child|) |
2009
|
|
|
|
|
|
|
[, (male|female|child|) ]*', |
2010
|
|
|
|
|
|
|
default => '', |
2011
|
|
|
|
|
|
|
inherit => 1, |
2012
|
|
|
|
|
|
|
list => 1, |
2013
|
|
|
|
|
|
|
}, |
2014
|
|
|
|
|
|
|
|
2015
|
|
|
|
|
|
|
volume => { |
2016
|
|
|
|
|
|
|
format => '||silent|x-soft|soft|medium|loud| |
2017
|
|
|
|
|
|
|
x-loud', |
2018
|
|
|
|
|
|
|
default => 'medium', |
2019
|
|
|
|
|
|
|
inherit => 1, |
2020
|
|
|
|
|
|
|
}, |
2021
|
|
|
|
|
|
|
|
2022
|
|
|
|
|
|
|
'white-space' => { |
2023
|
|
|
|
|
|
|
format => 'normal|pre|nowrap|pre-wrap|pre-line', |
2024
|
|
|
|
|
|
|
default => 'normal', |
2025
|
|
|
|
|
|
|
inherit => 1, |
2026
|
|
|
|
|
|
|
}, |
2027
|
|
|
|
|
|
|
|
2028
|
|
|
|
|
|
|
widows => { |
2029
|
|
|
|
|
|
|
format => '', |
2030
|
|
|
|
|
|
|
default => 2, |
2031
|
|
|
|
|
|
|
inherit => 1, |
2032
|
|
|
|
|
|
|
}, |
2033
|
|
|
|
|
|
|
|
2034
|
|
|
|
|
|
|
width => { |
2035
|
|
|
|
|
|
|
format => '||auto', |
2036
|
|
|
|
|
|
|
default => 'auto', |
2037
|
|
|
|
|
|
|
inherit => 0, |
2038
|
|
|
|
|
|
|
}, |
2039
|
|
|
|
|
|
|
|
2040
|
|
|
|
|
|
|
'word-spacing' => { |
2041
|
|
|
|
|
|
|
format => 'normal|', |
2042
|
|
|
|
|
|
|
default => 'normal', |
2043
|
|
|
|
|
|
|
inherit => 1, |
2044
|
|
|
|
|
|
|
}, |
2045
|
|
|
|
|
|
|
|
2046
|
|
|
|
|
|
|
'z-index' => { |
2047
|
|
|
|
|
|
|
format => 'auto|', |
2048
|
|
|
|
|
|
|
default => 'auto', |
2049
|
|
|
|
|
|
|
inherit => 0, |
2050
|
|
|
|
|
|
|
}, |
2051
|
|
|
|
|
|
|
); |
2052
|
|
|
|
|
|
|
$CSS21->add_property( $_ => $properties{$_} ) for keys %properties; |
2053
|
|
|
|
|
|
|
|
2054
|
|
|
|
|
|
|
=pod |
2055
|
|
|
|
|
|
|
|
2056
|
|
|
|
|
|
|
=cut |
2057
|
|
|
|
|
|
|
|
2058
|
|
|
|
|
|
|
our $Default = $CSS21; |
2059
|
|
|
|
|
|
|
|
2060
|
|
|
|
|
|
|
=head1 SEE ALSO |
2061
|
|
|
|
|
|
|
|
2062
|
|
|
|
|
|
|
L |