/[suikacvs]/markup/html/whatpm/Whatpm/CSS/Parser.pm
Suika

Diff of /markup/html/whatpm/Whatpm/CSS/Parser.pm

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.4 by wakaba, Sun Dec 23 15:47:09 2007 UTC revision 1.5 by wakaba, Mon Dec 31 03:00:42 2007 UTC
# Line 5  require Whatpm::CSS::SelectorsParser; Line 5  require Whatpm::CSS::SelectorsParser;
5    
6  sub new ($) {  sub new ($) {
7    my $self = bless {onerror => sub { }, must_level => 'm',    my $self = bless {onerror => sub { }, must_level => 'm',
8                        message_level => 'w',
9                      unsupported_level => 'unsupported'}, shift;                      unsupported_level => 'unsupported'}, shift;
10    
11    return $self;    return $self;
# Line 15  sub BEFORE_DECLARATION_STATE () { 1 } Line 16  sub BEFORE_DECLARATION_STATE () { 1 }
16  sub IGNORED_STATEMENT_STATE () { 2 }  sub IGNORED_STATEMENT_STATE () { 2 }
17  sub IGNORED_DECLARATION_STATE () { 3 }  sub IGNORED_DECLARATION_STATE () { 3 }
18    
19    our $Prop; ## By CSS property name
20    our $Attr; ## By CSSOM attribute name
21    our $Key; ## By internal key
22    
23  sub parse_char_string ($$) {  sub parse_char_string ($$) {
24    my $self = $_[0];    my $self = $_[0];
25    
# Line 88  sub parse_char_string ($$) { Line 93  sub parse_char_string ($$) {
93                $t->{type} == CDC_TOKEN;                $t->{type} == CDC_TOKEN;
94    
95        if ($t->{type} == ATKEYWORD_TOKEN) {        if ($t->{type} == ATKEYWORD_TOKEN) {
96          if ($t->{value} eq 'namespace') {          if (lc $t->{value} eq 'namespace') { ## TODO: case folding
97            $t = $tt->get_next_token;            $t = $tt->get_next_token;
98            $t = $tt->get_next_token while $t->{type} == S_TOKEN;            $t = $tt->get_next_token while $t->{type} == S_TOKEN;
99    
# Line 138  sub parse_char_string ($$) { Line 143  sub parse_char_string ($$) {
143                       level => $self->{must_level},                       level => $self->{must_level},
144                       token => $t);                       token => $t);
145            #            #
146          } elsif ($t->{value} eq 'charset') {          } elsif (lc $t->{value} eq 'charset') { ## TODO: case folding
147            $t = $tt->get_next_token;            $t = $tt->get_next_token;
148            $t = $tt->get_next_token while $t->{type} == S_TOKEN;            $t = $tt->get_next_token while $t->{type} == S_TOKEN;
149    
# Line 233  sub parse_char_string ($$) { Line 238  sub parse_char_string ($$) {
238        ## NOTE: DELIM? in declaration will be removed:        ## NOTE: DELIM? in declaration will be removed:
239        ## <http://csswg.inkedblade.net/spec/css2.1?s=declaration%20delim#issue-2>.        ## <http://csswg.inkedblade.net/spec/css2.1?s=declaration%20delim#issue-2>.
240    
241          my $prop_def;
242          my $prop_value;
243          my $prop_flag;
244        $t = $tt->get_next_token while $t->{type} == S_TOKEN;        $t = $tt->get_next_token while $t->{type} == S_TOKEN;
245        if ($t->{type} == IDENT_TOKEN) { # property        if ($t->{type} == IDENT_TOKEN) { # property
246          ## TODO: If supported, ...          my $prop_name = lc $t->{value}; ## TODO: case folding
   
247          $t = $tt->get_next_token;          $t = $tt->get_next_token;
248          #          if ($t->{type} == COLON_TOKEN) {
249        } elsif ($t->{type} == RBRACE_TOKEN) {            $t = $tt->get_next_token;
250              $t = $tt->get_next_token while $t->{type} == S_TOKEN;
251    
252              $prop_def = $Prop->{$prop_name};
253              if ($prop_def) {
254                ($t, $prop_value)
255                    = $prop_def->{parse}->($self, $prop_name, $tt, $t, $onerror);
256                if ($prop_value) {
257                  ## NOTE: {parse} don't have to consume trailing spaces.
258                  $t = $tt->get_next_token while $t->{type} == S_TOKEN;
259    
260                  if ($t->{type} == EXCLAMATION_TOKEN) {
261                    $t = $tt->get_next_token;
262                    $t = $tt->get_next_token while $t->{type} == S_TOKEN;
263                    if ($t->{type} == IDENT_TOKEN and
264                        lc $t->{value} eq 'important') { ## TODO: case folding
265                      $prop_flag = 'important';
266                      
267                      $t = $tt->get_next_token;
268                      $t = $tt->get_next_token while $t->{type} == S_TOKEN;
269    
270                      #
271                    } else {
272                      $onerror->(type => 'syntax error:important',
273                                 level => $self->{must_level},
274                                 token => $t);
275                      
276                      ## Reprocess.
277                      $state = IGNORED_DECLARATION_STATE;
278                      redo S;
279                    }
280                  }
281    
282                  #
283                } else {
284                  ## Syntax error.
285            
286                  ## Reprocess.
287                  $state = IGNORED_DECLARATION_STATE;
288                  redo S;
289                }
290              } else {
291                $onerror->(type => 'not supported:property',
292                           level => $self->{unsupported_level},
293                           token => $t, value => $prop_name);
294    
295                #
296                $state = IGNORED_DECLARATION_STATE;
297                redo S;
298              }
299            } else {
300              $onerror->(type => 'syntax error:property colon',
301                         level => $self->{must_level},
302                         token => $t);
303    
304              #
305              $state = IGNORED_DECLARATION_STATE;
306              redo S;
307            }
308          }
309    
310          if ($t->{type} == RBRACE_TOKEN) {
311          $t = $tt->get_next_token;          $t = $tt->get_next_token;
312          $state = BEFORE_STATEMENT_STATE;          $state = BEFORE_STATEMENT_STATE;
313          redo S;          #redo S;
314          } elsif ($t->{type} == SEMICOLON_TOKEN) {
315            $t = $tt->get_next_token;
316            ## Stay in the state.
317            #redo S;
318        } elsif ($t->{type} == EOF_TOKEN) {        } elsif ($t->{type} == EOF_TOKEN) {
319          $onerror->(type => 'syntax error:ruleset not closed',          $onerror->(type => 'syntax error:ruleset not closed',
320                     level => $self->{must_level},                     level => $self->{must_level},
321                     token => $t);                     token => $t);
322          ## Reprocess.          ## Reprocess.
323          $state = BEFORE_STATEMENT_STATE;          $state = BEFORE_STATEMENT_STATE;
324            #redo S;
325          } else {
326            if ($prop_value) {
327              $onerror->(type => 'syntax error:property semicolon',
328                         level => $self->{must_level},
329                         token => $t);
330            } else {
331              $onerror->(type => 'syntax error:property name',
332                         level => $self->{must_level},
333                         token => $t);
334            }
335    
336            #
337            $state = IGNORED_DECLARATION_STATE;
338          redo S;          redo S;
339        }        }
340    
341        #        if ($prop_value) {
342        $state = IGNORED_DECLARATION_STATE;          $$current_decls->{$prop_def->{key}} = [$prop_value, $prop_flag];
343          }
344        redo S;        redo S;
345      } elsif ($state == IGNORED_STATEMENT_STATE or      } elsif ($state == IGNORED_STATEMENT_STATE or
346               $state == IGNORED_DECLARATION_STATE) {               $state == IGNORED_DECLARATION_STATE) {
# Line 337  sub parse_char_string ($$) { Line 424  sub parse_char_string ($$) {
424    return $ss;    return $ss;
425  } # parse_char_string  } # parse_char_string
426    
427    $Prop->{color} = {
428      css => 'color',
429      dom => 'color',
430      key => 'color',
431      parse => sub {
432        my ($self, $prop_name, $tt, $t, $onerror) = @_;
433    
434        if ($t->{type} == IDENT_TOKEN) {
435          if (lc $t->{value} eq 'blue') { ## TODO: case folding
436            $t = $tt->get_next_token;
437            return ($t, ["RGBA", 0, 0, 255, 0]);
438          } else {
439            #
440          }
441        } else {
442          #
443        }
444    
445        $onerror->(type => 'syntax error:color',
446                   level => $self->{must_level},
447                   token => $t);
448        
449        return ($t, undef);
450      },
451      serialize => sub {
452        my ($self, $prop_name, $value) = @_;
453        if ($value->[0] eq 'RGBA') { ## TODO: %d? %f?
454          return sprintf 'rgba(%d, %d, %d, %f)', @$value[1, 2, 3, 4];
455        } else {
456          return undef;
457        }
458      },
459    };
460    $Attr->{color} = $Prop->{color};
461    $Key->{color} = $Prop->{color};
462    
463  1;  1;
464  ## $Date$  ## $Date$

Legend:
Removed from v.1.4  
changed lines
  Added in v.1.5

admin@suikawiki.org
ViewVC Help
Powered by ViewVC 1.1.24