1CSS::DOM::PropertyParseUrs(e3r)Contributed Perl DocumentCaStSi:o:nDOM::PropertyParser(3)
2
3
4
6 CSS::DOM::PropertyParser - Parser for CSS property values
7
9 Version 0.17
10
12 use CSS::DOM::PropertyParser;
13
14 $spec = new CSS::DOM::PropertyParser; # empty
15 # OR
16 $spec = $CSS::DOM::PropertyParser::Default->clone;
17
18 $spec->add_property(
19 overflow => {
20 format => 'visible|hidden|scroll|auto',
21 default => 'visible',
22 inherit => 0,
23 }
24 );
25
26 $hashref = $spec->get_property('overflow');
27
28 $hashref = $spec->delete_property('overflow');
29
30 @names = $spec->property_names;
31
33 Objects of this class provide lists of supported properties for
34 CSS::DOM style sheets. They also describe the syntax and parsing of
35 those properties' values.
36
37 Some CSS properties simply have their own values (e.g., overflow); some
38 are abbreviated forms of several other properties (e.g., font). These
39 are referred to in this documentation as 'simple' and 'shorthand'
40 properties.
41
43 "$spec = new CSS::DOM::PropertyParser" returns an object that does not
44 recognise any properties, to which you can add your own properties.
45
46 There are two parser objects that come with this module. These are
47 $CSS::DOM::PropertyParser::CSS21, which contains all of CSS 2.1, and
48 $CSS::DOM::PropertyParser::Default, which is currently identical to the
49 former, but to which parts of CSS 3 which eventually be added.
50
51 If one of the default specs will do, you don't need a constructor.
52 Simply pass it to the CSS::DOM constructor. If you want to modify it,
53 clone it first, using the "clone" method (as shown in the "SYNOPSIS").
54 It is often convenient to clone the $Default spec and delete those
55 properties that are not supported.
56
58 clone
59 Returns a deep clone of the object. (It's deep so that you can
60 modify the hashes/arrays inside it without modifying the original.)
61
62 add_property ( $name, \%spec )
63 Adds the specification for the named property. See "HOW INDIVIDUAL
64 PROPERTIES ARE SPECIFIED", below.
65
66 get_property ( $name )
67 Returns the hashref passed to the previous method.
68
69 delete_property ( $name )
70 Deletes the property and returns the hash ref.
71
72 property_names
73 Returns a list of the names of supported properties.
74
75 subproperty_names ( $name )
76 Returns a list of the names of $name's sub-properties if it is a
77 shorthand property.
78
79 match
80 Currently for internal use only. See the source code for
81 documentation. Use at your own risk.
82
84 Before you read this the first time, look at the "Example" below, and
85 then come back and use this for reference.
86
87 The specification for an individual property is a hash ref. There are
88 several keys that each hash ref can have:
89
90 format
91 This is set to a string that describes the format of the property.
92 The syntax used is based on the CSS 2.1 spec, but is not exactly
93 the same. Unlike regular expressions, these formats are applied to
94 properties on a token-by-token basis, not one character at a time.
95 (This means that "100|200" cannot be written as "[1|2]00", as that
96 would mean "1 00 | 2 00".)
97
98 Whitespace is ignored in the format and in the CSS property except
99 as a token separator.
100
101 There are several metachars (in order of precedence):
102
103 [...] grouping (like (?:...) )
104 (...) capturing group (just like a regexp)
105 ? optional
106 * zero or more
107 + one or more
108 || alternates that can come in any order and are optional,
109 but at least one must be specified (the order will be
110 retained if possible)
111 | alternates, exactly one of which is required
112
113 In addition, the following datatypes can be specified in angle
114 brackets:
115
116 <angle> A number with a 'deg', 'rad' or 'grad' suffix
117 <attr> attr(...)
118 <colour> (You can omit the 'u' if you want to.) One of CSS's
119 predefined colour or system colour names, or a #
120 followed by 3 or 6 hex digits, or the 'rgb(...)'
121 format (rgba is supported, too)
122 <counter> counter(...)
123 <frequency> A unit of Hz or kHz
124 <identifier> An identifier token
125 <integer> An integer (really?!)
126 <length> Number followed by a length unit (em, ex, px, in, cm,
127 mm, pt, pc)
128 <number> A number token
129 <percentage> Number followed by %
130 <shape> rect(...)
131 <string> A string token
132 <str/words> A sequence of identifiers or a single string (e.g., a
133 font name)
134 <time> A unit of seconds or milliseconds
135 <url> A URL token
136
137 The format for a shorthand property can contain the name of a sub-
138 property in single ASCII quotes.
139
140 All other characters are understood verbatim.
141
142 It is not necessary to include the word 'inherit' in the format,
143 since every property supports that.
144
145 "<counter>" makes use of the specification for the list-style-type
146 property. So if you modify the latter, it will affect "<counter>"
147 as well.
148
149 default
150 The default value. This only applies to simple properties.
151
152 inherit
153 Whether the property is inherited.
154
155 special_values
156 A hash ref of values that are replaced with other values (e.g.,
157 "caption => '13px sans-serif'".) The keys are lowercase identifier
158 names.
159
160 This feature only applies to single identifiers. In fact, it exists
161 solely for the font property's use.
162
163 list
164 Set to true if the property is a list of values. The capturing
165 parentheses in the format determine the individual values of the
166 list.
167
168 This applies to simple properties only.
169
170 properties
171 For a shorthand property, list the sub-properties here. The keys
172 are the property names. The values are array refs. The elements
173 within the arrays are numbers indicating which captures in the
174 format are to be used for the sub-property's value. They are tried
175 one after the other. Whichever is the first that matches (null
176 matches not counting) is used.
177
178 Sub-properties that are referenced in the "format" need not be
179 listed here.
180
181 serialise
182 For shorthand properties only. Set this to a subroutine that
183 serialises the property. It is called with a hashref of sub-
184 properties as its sole argument. The values of the hash are blank
185 for properties that are set to their initial values. This sub is
186 only called when all sub-properties are set.
187
188 Example
189 our $CSS21 = new CSS::DOM::PropertyParser;
190 my %properties = (
191 azimuth => {
192 format => '<angle> |
193 [ left-side | far-left | left | center-left |
194 center | center-right | right | far-right |
195 right-inside ] || behind
196 | leftwards | rightwards',
197 default => '0',
198 inherit => 1,
199 },
200
201 'background-attachment' => {
202 format => 'scroll | fixed',
203 default => 'scroll',
204 inherit => 0,
205 },
206
207 'background-color' => {
208 format => '<colour>',
209 default => 'transparent',
210 inherit => 0,
211 },
212
213 'background-image' => {
214 format => '<url> | none',
215 default => 'none',
216 inherit => 0,
217 },
218
219 'background-position' => {
220 format => '[<percentage>|<length>|left|right]
221 [<percentage>|<length>|top|center|bottom]? |
222 [top|bottom] [left|center|right]? |
223 center [<percentage>|<length>|left|right|top|bottom|
224 center]?',
225 default => '0% 0%',
226 inherit => 0,
227 },
228
229 'background-repeat' => {
230 format => 'repeat | repeat-x | repeat-y | no-repeat',
231 default => 'repeat',
232 inherit => 0,
233 },
234
235 background => {
236 format => "'background-color' || 'background-image' ||
237 'background-repeat' || 'background-attachment' ||
238 'background-position'",
239 serialise => sub {
240 my $p = shift;
241 my $ret = '';
242 for(qw/ background-color background-image background-repeat
243 background-attachment background-position /) {
244 length $p->{$_} and $ret .= "$p->{$_} ";
245 }
246 chop $ret;
247 length $ret ? $ret : 'none'
248 },
249 },
250
251 'border-collapse' => {
252 format => 'collapse | separate',
253 inherit => 1,
254 default => 'separate',
255 },
256
257 'border-color' => {
258 format => '(<colour>)[(<colour>)[(<colour>)(<colour>)?]?]?',
259 properties => {
260 'border-top-color' => [1],
261 'border-right-color' => [2,1],
262 'border-bottom-color' => [3,1],
263 'border-left-color' => [4,2,1],
264 },
265 serialise => sub {
266 my $p = shift;
267 my @vals = map $p->{"border-$_-color"},
268 qw/top right bottom left/;
269 $vals[3] eq $vals[1] and pop @vals,
270 $vals[2] eq $vals[0] and pop @vals,
271 $vals[1] eq $vals[0] and pop @vals;
272 return join " ", @vals;
273 },
274 },
275
276 'border-spacing' => {
277 format => '<length> <length>?',
278 default => '0',
279 inherit => 1,
280 },
281
282 'border-style' => {
283 format => "(none|hidden|dotted|dashed|solid|double|groove|ridge|
284 inset|outset)
285 [ (none|hidden|dotted|dashed|solid|double|groove|
286 ridge|inset|outset)
287 [ (none|hidden|dotted|dashed|solid|double|groove|
288 ridge|inset|outset)
289 (none|hidden|dotted|dashed|solid|double|groove|
290 ridge|inset|outset)?
291 ]?
292 ]?",
293 properties => {
294 'border-top-style' => [1],
295 'border-right-style' => [2,1],
296 'border-bottom-style' => [3,1],
297 'border-left-style' => [4,2,1],
298 },
299 serialise => sub {
300 my $p = shift;
301 my @vals = map $p->{"border-$_-style"},
302 qw/top right bottom left/;
303 $vals[3] eq $vals[1] and pop @vals,
304 $vals[2] eq $vals[0] and pop @vals,
305 $vals[1] eq $vals[0] and pop @vals;
306 return join " ", map $_||'none', @vals;
307 },
308 },
309
310 'border-top' => {
311 format => "'border-top-width' || 'border-top-style' ||
312 'border-top-color'",
313 serialise => sub {
314 my $p = shift;
315 my $ret = '';
316 for(qw/ width style color /) {
317 length $p->{"border-top-$_"}
318 and $ret .= $p->{"border-top-$_"}." ";
319 }
320 chop $ret;
321 $ret
322 },
323 },
324 'border-right' => {
325 format => "'border-right-width' || 'border-right-style' ||
326 'border-right-color'",
327 serialise => sub {
328 my $p = shift;
329 my $ret = '';
330 for(qw/ width style color /) {
331 length $p->{"border-right-$_"}
332 and $ret .= $p->{"border-right-$_"}." ";
333 }
334 chop $ret;
335 $ret
336 },
337 },
338 'border-bottom' => {
339 format => "'border-bottom-width' || 'border-bottom-style' ||
340 'border-bottom-color'",
341 serialise => sub {
342 my $p = shift;
343 my $ret = '';
344 for(qw/ width style color /) {
345 length $p->{"border-bottom-$_"}
346 and $ret .= $p->{"border-bottom-$_"}." ";
347 }
348 chop $ret;
349 $ret
350 },
351 },
352 'border-left' => {
353 format => "'border-left-width' || 'border-left-style' ||
354 'border-left-color'",
355 serialise => sub {
356 my $p = shift;
357 my $ret = '';
358 for(qw/ width style color /) {
359 length $p->{"border-left-$_"}
360 and $ret .= $p->{"border-left-$_"}." ";
361 }
362 chop $ret;
363 $ret
364 },
365 },
366
367 'border-top-color' => {
368 format => '<colour>',
369 default => "",
370 inherit => 0,
371 },
372 'border-right-color' => {
373 format => '<colour>',
374 default => "",
375 inherit => 0,
376 },
377 'border-bottom-color' => {
378 format => '<colour>',
379 default => "",
380 inherit => 0,
381 },
382 'border-left-color' => {
383 format => '<colour>',
384 default => "",
385 inherit => 0,
386 },
387
388 'border-top-style' => {
389 format => 'none|hidden|dotted|dashed|solid|double|groove|ridge|
390 inset|outset',
391 default => 'none',
392 inherit => 0,
393 },
394 'border-right-style' => {
395 format => 'none|hidden|dotted|dashed|solid|double|groove|ridge|
396 inset|outset',
397 default => 'none',
398 inherit => 0,
399 },
400 'border-bottom-style' => {
401 format => 'none|hidden|dotted|dashed|solid|double|groove|ridge|
402 inset|outset',
403 default => 'none',
404 inherit => 0,
405 },
406 'border-left-style' => {
407 format => 'none|hidden|dotted|dashed|solid|double|groove|ridge|
408 inset|outset',
409 default => 'none',
410 inherit => 0,
411 },
412
413 'border-top-width' => {
414 format => '<length>|thin|thick|medium',
415 default => 'medium',
416 inherit => 0,
417 },
418 'border-right-width' => {
419 format => '<length>|thin|thick|medium',
420 default => 'medium',
421 inherit => 0,
422 },
423 'border-bottom-width' => {
424 format => '<length>|thin|thick|medium',
425 default => 'medium',
426 inherit => 0,
427 },
428 'border-left-width' => {
429 format => '<length>|thin|thick|medium',
430 default => 'medium',
431 inherit => 0,
432 },
433
434 'border-width' => {
435 format => "(<length>|thin|thick|medium)
436 [ (<length>|thin|thick|medium)
437 [ (<length>|thin|thick|medium)
438 (<length>|thin|thick|medium)?
439 ]?
440 ]?",
441 properties => {
442 'border-top-width' => [1],
443 'border-right-width' => [2,1],
444 'border-bottom-width' => [3,1],
445 'border-left-width' => [4,2,1],
446 },
447 serialise => sub {
448 my $p = shift;
449 my @vals = map $p->{"border-$_-width"},
450 qw/top right bottom left/;
451 $vals[3] eq $vals[1] and pop @vals,
452 $vals[2] eq $vals[0] and pop @vals,
453 $vals[1] eq $vals[0] and pop @vals;
454 return join " ", map length $_ ? $_ : 'medium', @vals;
455 },
456 },
457
458 border => {
459 format => "(<length>|thin|thick|medium) ||
460 (none|hidden|dotted|dashed|solid|double|groove|ridge|
461 inset|outset) || (<colour>)",
462 properties => {
463 'border-top-width' => [1],
464 'border-right-width' => [1],
465 'border-bottom-width' => [1],
466 'border-left-width' => [1],
467 'border-top-style' => [2],
468 'border-right-style' => [2],
469 'border-bottom-style' => [2],
470 'border-left-style' => [2],
471 'border-top-color' => [3],
472 'border-right-color' => [3],
473 'border-bottom-color' => [3],
474 'border-left-color' => [3],
475 },
476 serialise => sub {
477 my $p = shift;
478 my $ret = '';
479 for(qw/ width style color /) {
480 my $temp = $p->{"border-top-$_"};
481 for my $side(qw/ right bottom left /) {
482 $temp eq $p->{"border-$side-$_"} or return "";
483 }
484 length $temp and $ret .= "$temp ";
485 }
486 chop $ret;
487 $ret
488 },
489 },
490
491 bottom => {
492 format => '<length>|<percentage>|auto',
493 default => 'auto',
494 inherit => 0,
495 },
496
497 'caption-side' => {
498 format => 'top|bottom',
499 default => 'top',
500 inherit => 1,
501 },
502
503 clear => {
504 format => 'none|left|right|both',
505 default => 'none',
506 inherit => 0,
507 },
508
509 clip => {
510 format => '<shape>|auto',
511 default => 'auto',
512 inherit => 0,
513 },
514
515 color => {
516 format => '<colour>',
517 default => 'rgba(0,0,0,1)',
518 inherit => 1,
519 },
520
521 content => {
522 format => '( normal|none|open-quote|close-quote|no-open-quote|
523 no-close-quote|<string>|<url>|<counter>|<attr> )+',
524 default => 'normal',
525 inherit => 0,
526 list => 1,
527 },
528
529 'counter-increment' => {
530 format => '[(<identifier>) (<integer>)? ]+ | none',
531 default => 'none',
532 inherit => 0,
533 list => 1,
534 },
535 'counter-reset' => {
536 format => '[(<identifier>) (<integer>)? ]+ | none',
537 default => 'none',
538 inherit => 0,
539 list => 1,
540 },
541
542 'cue-after' => {
543 format => '<url>|none',
544 default => 'none',
545 inherit => 0,
546 },
547 'cue-before' => {
548 format => '<url>|none',
549 default => 'none',
550 inherit => 0,
551 },
552
553 cue =>{
554 format => '(<url>|none) (<url>|none)?',
555 properties => {
556 'cue-before' => [1],
557 'cue-after' => [2,1],
558 },
559 serialise => sub {
560 my $p = shift;
561 my @vals = @$p{"cue-before", "cue-after"};
562 $vals[1] eq $vals[0] and pop @vals;
563 return join " ", map length $_ ? $_ : 'none', @vals;
564 },
565 },
566
567 cursor => {
568 format => '[(<url>) ,]*
569 (auto|crosshair|default|pointer|move|e-resize|
570 ne-resize|nw-resize|n-resize|se-resize|sw-resize|
571 s-resize|w-resize|text|wait|help|progress)',
572 default => 'auto',
573 inherit => 1,
574 list => 1,
575 },
576
577 direction => {
578 format => 'ltr|rtl',
579 default => 'ltr',
580 inherit => 1,
581 },
582
583 display => {
584 format => 'inline|block|list-item|run-in|inline-block|table|
585 inline-table|table-row-group|table-header-group|
586 table-footer-group|table-row|table-column-group|
587 table-column|table-cell|table-caption|none',
588 default => 'inline',
589 inherit => 0,
590 },
591
592 elevation => {
593 format => '<angle>|below|level|above|higher|lower',
594 default => '0',
595 inherit => 1,
596 },
597
598 'empty-cells' => {
599 format => 'show|hide',
600 default => 'show',
601 inherit => 1,
602 },
603
604 float => {
605 format => 'left|right|none',
606 default => 'none',
607 inherit => 0,
608 },
609
610 'font-family' => { # aka typeface
611 format => '(serif|sans-serif|cursive|fantasy|monospace|
612 <str/words>)
613 [,(serif|sans-serif|cursive|fantasy|monospace|
614 <str/words>)]*',
615 default => 'Times, serif',
616 inherit => 1,
617 list => 1,
618 },
619
620 'font-size' => {
621 format => 'xx-small|x-small|small|medium|large|x-large|xx-large|
622 larger|smaller|<length>|<percentage>',
623 default => 'medium',
624 inherit => 1,
625 },
626
627 'font-style' => {
628 format => 'normal|italic|oblique',
629 default => 'normal',
630 inherit => 1,
631 },
632
633 'font-variant' => {
634 format => 'normal | small-caps',
635 default => 'normal',
636 inherit => 1,
637 },
638
639 'font-weight' => {
640 format => 'normal|bold|bolder|lighter|
641 100|200|300|400|500|600|700|800|900',
642 default => 'normal',
643 inherit => 1,
644 },
645
646 font => {
647 format => "[ 'font-style' || 'font-variant' || 'font-weight' ]?
648 'font-size' [ / 'line-height' ]? 'font-family'",
649 special_values => {
650 caption => '13px Lucida Grande, sans-serif',
651 icon => '13px Lucida Grande, sans-serif',
652 menu => '13px Lucida Grande, sans-serif',
653 'message-box' => '13px Lucida Grande, sans-serif',
654 'small-caption' => '11px Lucida Grande, sans-serif',
655 'status-bar' => '10px Lucida Grande, sans-serif',
656 },
657 serialise => sub {
658 my $p = shift;
659 my $ret = '';
660 for(qw/ style variant weight /) {
661 length $p->{"font-$_"}
662 and $ret .= $p->{"font-$_"}." ";
663 }
664 $ret .= length $p->{'font-size'}
665 ? $p->{'font-size'}
666 : 'medium';
667 $ret .= "/$p->{'line-height'}" if length $p->{'line-height'};
668 $ret .= " " . ($p->{'font-family'} || "Times, serif");
669 $ret
670 },
671 },
672
673 height => {
674 format => '<length>|<percentage>|auto',
675 default => 'auto',
676 inherit => 0,
677 },
678
679 left => {
680 format => '<length>|<percentage>|auto',
681 default => 'auto',
682 inherit => 0,
683 },
684
685 'letter-spacing' => { # aka tracking
686 format => 'normal|<length>',
687 default => 'normal',
688 inherit => 1,
689 },
690
691 'line-height' => { # aka leading
692 format => 'normal|<number>|<length>|<percentage>',
693 default => "normal",
694 inherit => 1,
695 },
696
697 'list-style-image' => {
698 format => '<url>|none',
699 default => 'none',
700 inherit => 1,
701 },
702
703 'list-style-position' => {
704 format => 'inside|outside',
705 default => 'outside',
706 inherit => 1,
707 },
708
709 'list-style-type' => {
710 format => 'disc|circle|square|decimal|decimal-leading-zero|
711 lower-roman|upper-roman|lower-greek|lower-latin|
712 upper-latin|armenian|georgian|lower-alpha|
713 upper-alpha',
714 default => 'disc',
715 inherit => 1,
716 },
717
718 'list-style' => {
719 format => "'list-style-type'||'list-style-position'||
720 'list-style-image'",
721 serialise => sub {
722 my $p = shift;
723 my $ret = '';
724 for(qw/ type position image /) {
725 $p->{"list-style-$_"}
726 and $ret .= $p->{"list-style-$_"}." ";
727 }
728 chop $ret;
729 $ret || 'disc'
730 },
731 },
732
733 'margin-right' => {
734 format => '<length>|<percentage>|auto',
735 default => '0',
736 inherit => 0,
737 },
738 'margin-left' => {
739 format => '<length>|<percentage>|auto',
740 default => '0',
741 inherit => 0,
742 },
743 'margin-top' => {
744 format => '<length>|<percentage>|auto',
745 default => '0',
746 inherit => 0,
747 },
748 'margin-bottom' => {
749 format => '<length>|<percentage>|auto',
750 default => '0',
751 inherit => 0,
752 },
753
754 margin => {
755 format => "(<length>|<percentage>|auto)
756 [ (<length>|<percentage>|auto)
757 [ (<length>|<percentage>|auto)
758 (<length>|<percentage>|auto)?
759 ]?
760 ]?",
761 properties => {
762 'margin-top' => [1],
763 'margin-right' => [2,1],
764 'margin-bottom' => [3,1],
765 'margin-left' => [4,2,1],
766 },
767 serialise => sub {
768 my $p = shift;
769 my @vals = map $p->{"margin-$_"},
770 qw/top right bottom left/;
771 $vals[3] eq $vals[1] and pop @vals,
772 $vals[2] eq $vals[0] and pop @vals,
773 $vals[1] eq $vals[0] and pop @vals;
774 return join " ", map $_ || 0, @vals;
775 },
776 },
777
778 'max-height' => {
779 format => '<length>|<percentage>|none',
780 default => 'none',
781 inherit => 0,
782 },
783 'max-width' => {
784 format => '<length>|<percentage>|none',
785 default => 'none',
786 inherit => 0,
787 },
788 'min-height' => {
789 format => '<length>|<percentage>|none',
790 default => 'none',
791 inherit => 0,
792 },
793 'min-width' => {
794 format => '<length>|<percentage>|none',
795 default => 'none',
796 inherit => 0,
797 },
798
799 orphans => {
800 format => '<integer>',
801 default => 2,
802 inherit => 1,
803 },
804
805 'outline-color' => {
806 format => '<colour>|invert',
807 default => 'invert',
808 inherit => 0,
809 },
810
811 'outline-style' => {
812 format => 'none|hidden|dotted|dashed|solid|double|groove|ridge|
813 inset|outset',
814 default => 'none',
815 inherit => 0,
816 },
817
818 'outline-width' => {
819 format => '<length>|thin|thick|medium',
820 default => 'medium',
821 inherit => 0,
822 },
823
824 outline => {
825 format => "'outline-color'||'outline-style'||'outline-width'",
826 serialise => sub {
827 my $p = shift;
828 my $ret = '';
829 for(qw/ color style width /) {
830 length $p->{"outline-$_"}
831 and $ret .= $p->{"outline-$_"}." ";
832 }
833 chop $ret;
834 length $ret ? $ret : 'invert';
835 },
836 },
837
838 overflow => {
839 format => 'visible|hidden|scroll|auto',
840 default => 'visible',
841 inherit => 0,
842 },
843
844 'padding-top' => {
845 format => '<length>|<percentage>',
846 default => 0,
847 inherit => 0,
848 },
849 'padding-right' => {
850 format => '<length>|<percentage>',
851 default => 0,
852 inherit => 0,
853 },
854 'padding-bottom' => {
855 format => '<length>|<percentage>',
856 default => 0,
857 inherit => 0,
858 },
859 'padding-left' => {
860 format => '<length>|<percentage>',
861 default => 0,
862 inherit => 0,
863 },
864
865 padding => {
866 format => "(<length>|<percentage>)
867 [ (<length>|<percentage>)
868 [ (<length>|<percentage>)
869 (<length>|<percentage>)?
870 ]?
871 ]?",
872 properties => {
873 'padding-top' => [1],
874 'padding-right' => [2,1],
875 'padding-bottom' => [3,1],
876 'padding-left' => [4,2,1],
877 },
878 serialise => sub {
879 my $p = shift;
880 my @vals = map $p->{"padding-$_"},
881 qw/top right bottom left/;
882 $vals[3] eq $vals[1] and pop @vals,
883 $vals[2] eq $vals[0] and pop @vals,
884 $vals[1] eq $vals[0] and pop @vals;
885 return join " ", map $_ || 0, @vals;
886 },
887 },
888
889 'page-break-after' => {
890 format => 'auto|always|avoid|left|right',
891 default => 'auto',
892 inherit => 0,
893 },
894 'page-break-before' => {
895 format => 'auto|always|avoid|left|right',
896 default => 'auto',
897 inherit => 0,
898 },
899
900 'page-break-inside' => {
901 format => 'avoid|auto',
902 default => 'auto',
903 inherit => 1,
904 },
905
906 'pause-after' => {
907 format => '<time>|<percentage>',
908 default => 0,
909 inherit => 0,
910 },
911 'pause-before' => {
912 format => '<time>|<percentage>',
913 default => 0,
914 inherit => 0,
915 },
916
917 pause => {
918 format => '(<time>|<percentage>)(<time>|<percentage>)?',
919 properties => {
920 'pause-before' => [1],
921 'pause-after' => [2,1],
922 }
923 },
924
925 'pitch-range' => {
926 format => '<number>',
927 default => 50,
928 inherit => 1,
929 },
930
931 pitch => {
932 format => '<frequency>|x-low|low|medium|high|x-high',
933 default => 'medium',
934 inherit => 1,
935 },
936
937 'play-during' => {
938 format => '<url> [ mix || repeat ]? | auto | none',
939 default => 'auto',
940 inherit => 0,
941 },
942
943 position => {
944 format => 'static|relative|absolute|fixed',
945 default => 'relative',
946 inherit => 0,
947 },
948
949 quotes => {
950 format => '[(<string>)(<string>)]+|none',
951 default => 'none',
952 inherit => 1,
953 list => 1,
954 },
955
956 richness => {
957 format => '<number>',
958 default => 50,
959 inherit => 1,
960 },
961
962 right => {
963 format => '<length>|<percentage>|auto',
964 default => 'auto',
965 inherit => 0,
966 },
967
968 'speak-header' => {
969 format => 'once|always',
970 default => 'once',
971 inherit => 1,
972 },
973
974 'speak-numeral' => {
975 format => 'digits|continuous',
976 default => 'continuous',
977 inherit => 1,
978 },
979
980 'speak-punctuation' => {
981 format => 'code|none',
982 default => 'none',
983 inherit => 1,
984 },
985
986 speak => {
987 format => 'normal|none|spell-out',
988 default => 'normal',
989 inherit => 1,
990 },
991
992 'speech-rate' => {
993 format => '<number>|x-slow|slow|medium|fast|x-fast|faster|slower',
994 default => 'medium',
995 inherit => 1,
996 },
997
998 stress => {
999 format => '<number>',
1000 default => 50,
1001 inherit => 1,
1002 },
1003
1004 'table-layout' => {
1005 format => 'auto|fixed',
1006 default => 'auto',
1007 inherit => 0,
1008 },
1009
1010 'text-align' => {
1011 format => 'left|right|center|justify|auto',
1012 default => 'auto',
1013 inherit => 1,
1014 },
1015
1016 'text-decoration' => {
1017 format => 'none | underline||overline||line-through||blink ',
1018 default => 'none',
1019 inherit => 0,
1020 },
1021
1022 'text-indent' => {
1023 format => '<length>|<percentage>',
1024 default => 0,
1025 inherit => 1,
1026 },
1027
1028 'text-transform' => {
1029 format => 'capitalize|uppercase|lowercase|none',
1030 default => 'none',
1031 inherit => 1,
1032 },
1033
1034 top => {
1035 format => '<length>|<percentage>|auto',
1036 default => 'auto',
1037 inherit => 0,
1038 },
1039
1040 'unicode-bidi' => {
1041 format => 'normal|embed|bidi-override',
1042 default => 'normal',
1043 inherit => 0,
1044 },
1045
1046 'vertical-align' => {
1047 format => 'baseline|sub|super|top|text-top|middle|bottom|
1048 text-bottom|<percentage>|<length>',
1049 default => 'baseline',
1050 inherit => 0,
1051 },
1052
1053 visibility => {
1054 format => 'visible|hidden|collapse',
1055 default => 'visible',
1056 inherit => 1,
1057 },
1058
1059 'voice-family' => {
1060 format => '(male|female|child|<str/words>)
1061 [, (male|female|child|<str/words>) ]*',
1062 default => '',
1063 inherit => 1,
1064 list => 1,
1065 },
1066
1067 volume => {
1068 format => '<number>|<percentage>|silent|x-soft|soft|medium|loud|
1069 x-loud',
1070 default => 'medium',
1071 inherit => 1,
1072 },
1073
1074 'white-space' => {
1075 format => 'normal|pre|nowrap|pre-wrap|pre-line',
1076 default => 'normal',
1077 inherit => 1,
1078 },
1079
1080 widows => {
1081 format => '<integer>',
1082 default => 2,
1083 inherit => 1,
1084 },
1085
1086 width => {
1087 format => '<length>|<percentage>|auto',
1088 default => 'auto',
1089 inherit => 0,
1090 },
1091
1092 'word-spacing' => {
1093 format => 'normal|<length>',
1094 default => 'normal',
1095 inherit => 1,
1096 },
1097
1098 'z-index' => {
1099 format => 'auto|<integer>',
1100 default => 'auto',
1101 inherit => 0,
1102 },
1103 );
1104 $CSS21->add_property( $_ => $properties{$_} ) for keys %properties;
1105
1107 CSS::DOM
1108
1109
1110
1111perl v5.30.0 2019-07-26 CSS::DOM::PropertyParser(3)