/[suikacvs]/messaging/manakai/lib/Message/DOM/CSSStyleDeclaration.pm
Suika

Contents of /messaging/manakai/lib/Message/DOM/CSSStyleDeclaration.pm

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.11 - (hide annotations) (download)
Mon Jan 14 11:18:49 2008 UTC (16 years, 10 months ago) by wakaba
Branch: MAIN
Changes since 1.10: +83 -4 lines
++ manakai/lib/Message/DOM/ChangeLog	14 Jan 2008 11:18:35 -0000
	* CSSStyleDeclaration.pm: The classes now explicitly implement
	the |CSS2Properties| interface.
	(@{}, TIEARRAY, FETCH, FETCHSIZE, EXISTS, item, length): Implemented.

2008-01-14  Wakaba  <wakaba@suika.fam.cx>

1 wakaba 1.1 package Message::DOM::CSSStyleDeclaration;
2     use strict;
3 wakaba 1.11 our $VERSION=do{my @r=(q$Revision: 1.10 $=~/\d+/g);sprintf "%d."."%02d" x $#r,@r};
4     push our @ISA, 'Message::IF::CSSStyleDeclaration',
5     'Message::IF::CSS2Properties';
6 wakaba 1.1
7     sub ____new ($) {
8     return bless \{}, $_[0];
9     } # ____new
10    
11 wakaba 1.3 sub AUTOLOAD {
12     my $method_name = our $AUTOLOAD;
13     $method_name =~ s/.*:://;
14     return if $method_name eq 'DESTROY';
15    
16     require Whatpm::CSS::Parser;
17     my $prop_def = $Whatpm::CSS::Parser::Attr->{$method_name};
18    
19     if ($prop_def) {
20     no strict 'refs';
21     *{ $method_name } = sub {
22     ## TODO: setter
23    
24     my $self = $_[0];
25     my $value = $$self->{$prop_def->{key}};
26     if ($value) {
27     return $prop_def->{serialize}->($self, $prop_def->{css}, $value->[0]);
28     } else {
29 wakaba 1.10 return "";
30 wakaba 1.3 }
31 wakaba 1.8 ## ISSUE: If one of shorthand component properties is !important?
32 wakaba 1.3 };
33     goto &{ $AUTOLOAD };
34     } else {
35     require Carp;
36     Carp::croak (qq<Can't locate method "$AUTOLOAD">);
37     }
38     } # AUTOLOAD
39    
40 wakaba 1.11 use overload
41     '@{}' => sub {
42     tie my @list, ref $_[0], $_[0];
43     return \@list;
44     },
45     fallback => 1;
46    
47     sub TIEARRAY ($$) { $_[1] }
48    
49 wakaba 1.1 ## |CSSStyleDeclaration| attributes
50    
51 wakaba 1.2 sub css_text ($;$) {
52 wakaba 1.3 ## TODO: setter
53    
54 wakaba 1.9 ## NOTE: Where and how white space characters are inserted are
55     ## intentionally changed from those in browsers so that properties are
56     ## more prettily printed.
57     ## See <http://suika.fam.cx/gate/2005/sw/cssText> for what browsers do.
58     ## TODO: Ordering issue.
59 wakaba 1.3 require Whatpm::CSS::Parser;
60     my $self = $_[0];
61     my $r = '';
62 wakaba 1.7 my %serialized;
63 wakaba 1.3 for (grep {$$self->{$_}} keys %$$self) {
64     my $prop_def = $Whatpm::CSS::Parser::Key->{$_};
65     next unless $prop_def;
66 wakaba 1.7
67     if ($prop_def->{serialize_multiple}) {
68     unless ($serialized{$prop_def->{serialize_multiple}}) {
69     $serialized{$prop_def->{serialize_multiple}} = 1;
70     my $v = $prop_def->{serialize_multiple}->($self);
71     for my $prop_name (sort {$a cmp $b} keys %$v) {
72     $r .= ' ' . $prop_name . ': ' . $v->{$prop_name} . ";\n"
73     }
74     }
75     } else {
76     my $value = $$self->{$_};
77     my $s = $prop_def->{serialize}->($self, $prop_def->{css}, $value->[0]);
78 wakaba 1.10 if (length $s) {
79 wakaba 1.7 $r .= ' ' . $prop_def->{css} . ': ' . $s;
80 wakaba 1.10 $r .= ' ! ' . $value->[1] if length $value->[1];
81 wakaba 1.7 $r .= ";\n";
82     }
83 wakaba 1.3 }
84     }
85     return $r;
86 wakaba 1.2 } # css_text
87    
88 wakaba 1.11 sub length ($) {
89     require Whatpm::CSS::Parser;
90     return scalar @{[grep {$_}
91     map { $Whatpm::CSS::Parser::Key->{$_} }
92     keys %${$_[0]}]->[$_[1]]};
93     } # length
94     *FETCHSIZE = \&length;
95    
96     ## TODO: STORESIZE
97    
98 wakaba 1.1 sub parent_rule ($) {
99     return ${$_[0]}->{parent_rule};
100     } # parent_rule
101    
102 wakaba 1.7 ## |CSSStyleDeclaration| methods
103    
104     sub get_property_priority ($$) {
105     my $prop_name = ''.$_[1];
106    
107     require Whatpm::CSS::Parser;
108     my $prop_def = $Whatpm::CSS::Parser::Prop->{$prop_name};
109     return '' unless defined $prop_def;
110    
111     my $v = ${$_[0]}->{$prop_def->{key}};
112 wakaba 1.10 return $v ? $v->[1] : '';
113 wakaba 1.7 } # get_property_priority
114    
115 wakaba 1.11 sub item ($$) {
116     require Whatpm::CSS::Parser;
117     return '' if $_[1] < 0;
118     ## TODO: ordering (should be same as that in |css_text|.
119     my $v = [map {$_->{key}}
120     grep {$_}
121     map { $Whatpm::CSS::Parser::Key->{$_} }
122     keys %${$_[0]}]->[$_[1]];
123     return defined $v ? $v : '';
124     } # item
125     *FETCH = \&item;
126    
127     ## TODO: STORE, DELETE
128    
129     sub EXISTS ($$) {
130     return length $_[0]->item;
131     } # EXISTS
132    
133 wakaba 1.1 ## TODO: Implement other methods and attributes
134    
135 wakaba 1.4 package Message::DOM::CSSComputedStyleDeclaration;
136 wakaba 1.11 push our @ISA, 'Message::IF::CSSStyleDeclaration',
137     'Message::IF::CSS2Properties';
138 wakaba 1.4
139     sub ____new ($$$) {
140     my $self = bless \{}, shift;
141     $$self->{cascade} = shift; # Whatpm::CSS::Cascade object.
142     $$self->{element} = shift; ## TODO: This link should be weaken?
143     return $self;
144     } # ____new
145    
146 wakaba 1.7 sub AUTOLOAD {
147     my $method_name = our $AUTOLOAD;
148     $method_name =~ s/.*:://;
149     return if $method_name eq 'DESTROY';
150    
151     require Whatpm::CSS::Parser;
152     my $prop_def = $Whatpm::CSS::Parser::Attr->{$method_name};
153    
154     if ($prop_def) {
155     no strict 'refs';
156     *{ $method_name } = sub {
157     ## TODO: setter
158    
159     my $self = $_[0];
160     my $value = $$self->{cascade}->get_computed_value
161     ($$self->{element}, $prop_def->{css});
162     if ($value) {
163     return $prop_def->{serialize}->($self, $prop_def->{css}, $value);
164     } else {
165 wakaba 1.10 return "";
166 wakaba 1.7 }
167     };
168     goto &{ $AUTOLOAD };
169     } else {
170     require Carp;
171     Carp::croak (qq<Can't locate method "$AUTOLOAD">);
172     }
173     } # AUTOLOAD
174    
175 wakaba 1.11 use overload
176     '@{}' => sub {
177     tie my @list, ref $_[0], $_[0];
178     return \@list;
179     },
180     fallback => 1;
181    
182     sub TIEARRAY ($$) { $_[1] }
183    
184     ## |CSSStyleDeclaration| attributes
185    
186 wakaba 1.4 sub css_text ($;$) {
187     ## TODO: error if modified
188    
189     my $self = shift;
190     require Whatpm::CSS::Parser;
191    
192 wakaba 1.9 ## NOTE: Where and how white space characters are inserted are
193     ## intentionally changed from those in browsers so that properties are
194     ## more prettily printed.
195     ## See <http://suika.fam.cx/gate/2005/sw/cssText> for what browsers do.
196 wakaba 1.4 ## TODO: ordering
197     ## TODO: any spec?
198     my $r = '';
199 wakaba 1.7 my %serialized;
200 wakaba 1.6 for my $prop_def (sort {$a->{css} cmp $b->{css}}
201 wakaba 1.7 grep {$_->{compute} or
202     $_->{compute_multiple} or
203     $_->{serialize_multiple}}
204 wakaba 1.6 values %$Whatpm::CSS::Parser::Prop) {
205 wakaba 1.7 if ($prop_def->{serialize_multiple}) {
206     unless ($serialized{$prop_def->{serialize_multiple}}) {
207     $serialized{$prop_def->{serialize_multiple}} = 1;
208     my $v = $prop_def->{serialize_multiple}->($self);
209     for my $prop_name (sort {$a cmp $b} keys %$v) {
210     $r .= ' ' . $prop_name . ': ' . $v->{$prop_name} . ";\n"
211     }
212     }
213 wakaba 1.5 } else {
214 wakaba 1.7 my $prop_value = $$self->{cascade}->get_computed_value
215     ($$self->{element}, $prop_def->{css});
216     my $s = $prop_def->{serialize}->($self, $prop_def->{css}, $prop_value);
217 wakaba 1.10 if (length $s) {
218 wakaba 1.7 $r .= ' ' . $prop_def->{css} . ': ' . $s;
219     $r .= ";\n";
220     } else {
221     ## NOTE: This should be an error of the implementation.
222     $r .= " /* $prop_def->{css}: ???; */\n";
223     }
224 wakaba 1.4 }
225     }
226 wakaba 1.6
227     ## ISSUE: Should we include CSS properties that are not supported?
228    
229 wakaba 1.4 return $r;
230     } # css_text
231    
232 wakaba 1.11 ## TODO: What should we enumerate is unclear.
233     sub length ($) {
234     require Whatpm::CSS::Parser;
235     return scalar @{[grep {$_}
236     values %$Whatpm::CSS::Parser::Key]};
237     } # length
238     *FETCHSIZE = \&length;
239    
240     ## TODO: STORESIZE
241    
242 wakaba 1.7 ## |CSSStyleDeclaration| methods
243    
244 wakaba 1.10 sub get_property_priority ($$) { '' }
245 wakaba 1.7
246 wakaba 1.11 sub item ($$) {
247     require Whatpm::CSS::Parser;
248     return '' if $_[1] < 0;
249     ## TODO: ordering (should be same as that in |css_text|.
250     my $v = [sort {$a cmp $b}
251     map {$_->{css}}
252     grep {$_}
253     values %$Whatpm::CSS::Parser::Key]->[$_[1]];
254     return defined $v ? $v : '';
255     } # item
256     *FETCH = \&item;
257    
258     ## TODO: STORE, DELETE
259    
260     sub EXISTS ($$) {
261     return length $_[0]->item;
262     } # EXISTS
263    
264 wakaba 1.4 ## TODO: members
265    
266 wakaba 1.1 package Message::IF::CSSStyleDeclaration;
267 wakaba 1.11 package Message::IF::CSS2Properties;
268 wakaba 1.1
269     1;
270 wakaba 1.11 ## $Date: 2008/01/14 10:04:40 $

admin@suikawiki.org
ViewVC Help
Powered by ViewVC 1.1.24