Parent Directory
|
Revision Log
++ manakai/lib/Message/DOM/ChangeLog 2 Feb 2008 13:57:59 -0000 2008-02-02 Wakaba <wakaba@suika.fam.cx> * CSSStyleDeclaration.pm ($serialize_value): New (was part of Whatpm::CSS::Parser as $default_serializer). Use it instead of old 'serialize' parameter of CSS property definition.
| 1 | wakaba | 1.1 | package Message::DOM::CSSStyleDeclaration; |
| 2 | use strict; | ||
| 3 | wakaba | 1.15 | our $VERSION=do{my @r=(q$Revision: 1.14 $=~/\d+/g);sprintf "%d."."%02d" x $#r,@r}; |
| 4 | wakaba | 1.11 | push our @ISA, 'Message::IF::CSSStyleDeclaration', |
| 5 | 'Message::IF::CSS2Properties'; | ||
| 6 | wakaba | 1.1 | |
| 7 | wakaba | 1.15 | my $serialize_value = sub ($$$) { |
| 8 | my ($self, $prop_name, $value) = @_; | ||
| 9 | if ($value->[0] eq 'NUMBER' or $value->[0] eq 'WEIGHT') { | ||
| 10 | ## TODO: What we currently do for 'font-weight' is different from | ||
| 11 | ## any browser for lighter/bolder cases. We need to fix this, but | ||
| 12 | ## how? | ||
| 13 | return $value->[1]; ## TODO: big or small number cases? | ||
| 14 | } elsif ($value->[0] eq 'DIMENSION') { | ||
| 15 | return $value->[1] . $value->[2]; ## NOTE: This is what browsers do. | ||
| 16 | } elsif ($value->[0] eq 'PERCENTAGE') { | ||
| 17 | return $value->[1] . '%'; | ||
| 18 | } elsif ($value->[0] eq 'KEYWORD') { | ||
| 19 | return $value->[1]; | ||
| 20 | } elsif ($value->[0] eq 'URI') { | ||
| 21 | ## NOTE: This is what browsers do. | ||
| 22 | return 'url('.$value->[1].')'; | ||
| 23 | } elsif ($value->[0] eq 'RGBA') { | ||
| 24 | if ($value->[4] == 1) { | ||
| 25 | return 'rgb('.$value->[1].', '.$value->[2].', '.$value->[3].')'; | ||
| 26 | } elsif ($value->[4] == 0) { | ||
| 27 | ## TODO: check what browsers do... | ||
| 28 | return 'transparent'; | ||
| 29 | } else { | ||
| 30 | return 'rgba('.$value->[1].', '.$value->[2].', '.$value->[3].', ' | ||
| 31 | .$value->[4].')'; | ||
| 32 | } | ||
| 33 | } elsif ($value->[0] eq 'INHERIT') { | ||
| 34 | return 'inherit'; | ||
| 35 | } elsif ($value->[0] eq 'DECORATION') { | ||
| 36 | my @v = (); | ||
| 37 | push @v, 'underline' if $value->[1]; | ||
| 38 | push @v, 'overline' if $value->[2]; | ||
| 39 | push @v, 'line-through' if $value->[3]; | ||
| 40 | push @v, 'blink' if $value->[4]; | ||
| 41 | return 'none' unless @v; | ||
| 42 | return join ' ', @v; | ||
| 43 | } elsif ($value->[0] eq 'QUOTES') { | ||
| 44 | return join ' ', map {'"'.$_.'"'} map {$_->[0], $_->[1]} @{$value->[1]}; | ||
| 45 | ## NOTE: The result string might not be a <'quotes'> if it contains | ||
| 46 | ## e.g. '"'. In addition, it might not be a <'quotes'> if | ||
| 47 | ## @{$value->[1]} is empty (which is unlikely as long as the implementation | ||
| 48 | ## is not broken). | ||
| 49 | } elsif ($value->[0] eq 'CONTENT') { | ||
| 50 | return join ' ', map { | ||
| 51 | $_->[0] eq 'KEYWORD' ? $_->[1] : | ||
| 52 | $_->[0] eq 'STRING' ? '"' . $_->[1] . '"' : | ||
| 53 | $_->[0] eq 'URI' ? 'url(' . $_->[1] . ')' : | ||
| 54 | $_->[0] eq 'ATTR' ? 'attr(' . $_->[2] . ')' : ## TODO: prefix | ||
| 55 | $_->[0] eq 'COUNTER' ? 'counter(' . $_->[1] . ', ' . $_->[3] . ')' : | ||
| 56 | $_->[0] eq 'COUNTERS' ? 'counters(' . $_->[1] . ', "' . $_->[2] . '", ' . $_->[3] . ')' : | ||
| 57 | '' | ||
| 58 | } @{$value}[1..$#$value]; | ||
| 59 | } elsif ($value->[0] eq 'RECT') { | ||
| 60 | ## NOTE: Four components are DIMENSIONs. | ||
| 61 | return 'rect(' . $value->[1]->[1].$value->[1]->[2] . ', ' | ||
| 62 | . $value->[2]->[1].$value->[2]->[2] . ', ' | ||
| 63 | . $value->[3]->[1].$value->[3]->[2] . ', ' | ||
| 64 | . $value->[4]->[1].$value->[4]->[2] . ')'; | ||
| 65 | } elsif ($value->[0] eq 'SETCOUNTER' or $value->[0] eq 'ADDCOUNTER') { | ||
| 66 | return join ' ', map {$_->[0], $_->[1]} @$value[1..$#$value]; | ||
| 67 | } elsif ($value->[0] eq 'FONT') { | ||
| 68 | return join ', ', map { | ||
| 69 | if ($_->[0] eq 'STRING') { | ||
| 70 | '"'.$_->[1].'"'; ## NOTE: This is what Firefox does. | ||
| 71 | } elsif ($_->[0] eq 'KEYWORD') { | ||
| 72 | $_->[1]; ## NOTE: This is what Firefox does. | ||
| 73 | } else { | ||
| 74 | ## NOTE: This should be an error. | ||
| 75 | '""'; | ||
| 76 | } | ||
| 77 | } @$value[1..$#$value]; | ||
| 78 | } elsif ($value->[0] eq 'CURSOR') { | ||
| 79 | return join ', ', map { | ||
| 80 | if ($_->[0] eq 'URI') { | ||
| 81 | 'url('.$_->[1].')'; ## NOTE: This is what Firefox does. | ||
| 82 | } elsif ($_->[0] eq 'KEYWORD') { | ||
| 83 | $_->[1]; | ||
| 84 | } else { | ||
| 85 | ## NOTE: This should be an error. | ||
| 86 | '""'; | ||
| 87 | } | ||
| 88 | } @$value[1..$#$value]; | ||
| 89 | } else { | ||
| 90 | return ''; | ||
| 91 | } | ||
| 92 | }; # $serialize_value | ||
| 93 | |||
| 94 | wakaba | 1.1 | sub ____new ($) { |
| 95 | return bless \{}, $_[0]; | ||
| 96 | } # ____new | ||
| 97 | |||
| 98 | wakaba | 1.3 | sub AUTOLOAD { |
| 99 | my $method_name = our $AUTOLOAD; | ||
| 100 | $method_name =~ s/.*:://; | ||
| 101 | return if $method_name eq 'DESTROY'; | ||
| 102 | |||
| 103 | require Whatpm::CSS::Parser; | ||
| 104 | my $prop_def = $Whatpm::CSS::Parser::Attr->{$method_name}; | ||
| 105 | |||
| 106 | if ($prop_def) { | ||
| 107 | no strict 'refs'; | ||
| 108 | wakaba | 1.15 | if (defined $prop_def->{key}) { |
| 109 | wakaba | 1.13 | *{ $method_name } = sub { |
| 110 | ## TODO: setter | ||
| 111 | |||
| 112 | my $self = $_[0]; | ||
| 113 | my $value = $$self->{$prop_def->{key}}; | ||
| 114 | if ($value) { | ||
| 115 | wakaba |