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

Contents of /markup/html/whatpm/Whatpm/CSS/SelectorsSerializer.pm

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.3 - (hide annotations) (download)
Wed Oct 17 10:46:26 2007 UTC (18 years, 9 months ago) by wakaba
Branch: MAIN
Changes since 1.2: +13 -0 lines
++ whatpm/Whatpm/ChangeLog	17 Oct 2007 10:45:53 -0000
	* Makefile (clean): New rule.

	* NanoDOM.pm (public_id, system_id): New attributes.

2007-10-17  Wakaba  <wakaba@suika.fam.cx>

1 wakaba 1.1 package Whatpm::CSS::SelectorsSerializer;
2     use strict;
3 wakaba 1.3 our $VERSION=do{my @r=(q$Revision: 1.5 $=~/\d+/g);sprintf "%d."."%02d" x $#r,@r};
4 wakaba 1.1
5     use Whatpm::CSS::SelectorsParser qw(:selector :combinator :match);
6    
7     sub serialize_test ($$$) {
8     my (undef, $selectors, $ns) = @_;
9     $ns ||= {};
10     my $i = 0;
11     my $ident = sub {
12     my $s = shift;
13     $s =~ s{([^A-Za-z_0-9\x80-\x{D7FF}\x{E000}-\x{10FFFF}-])}{
14     my $v = ord $1;
15     sprintf '\\%06X',$v > 0x10FFFF ? 0xFFFFFF : $v;
16     }ge;
17     $s =~ s/^([0-9])/\\00003$1/g;
18     $s =~ s/^-([^A-Za-z_])/\\00002D$1/g;
19     return $s;
20     }; # $str
21     my $str = sub {
22     my $s = shift;
23     $s =~ s{([^\x20\x21\x23-\x5B\x5D-\x{D7FF}\x{E000}-\x{10FFFF}])}{
24     my $v = ord $1;
25     sprintf '\\%06X',$v > 0x10FFFF ? 0xFFFFFF : $v;
26     }ge;
27     return '"'.$s.'"';
28     }; # $str
29     my $r = join ",\n", map {
30     join "", map {
31     if (ref $_) {
32     my $ss = [];
33     $ss->[LOCAL_NAME_SELECTOR] = [LOCAL_NAME_SELECTOR, undef];
34     for my $s (@$_) {
35     if ($s->[0] == NAMESPACE_SELECTOR or
36     $s->[0] == LOCAL_NAME_SELECTOR) {
37     $ss->[$s->[0]] = $s;
38     } else {
39     push @{$ss->[$s->[0]] ||= []}, $s;
40     }
41     }
42    
43     my $v = '';
44     if (not defined $ss->[NAMESPACE_SELECTOR]) {
45     $v .= '*|';
46     } elsif (defined $ss->[NAMESPACE_SELECTOR]->[1]) {
47     unless (defined $ns->{$ss->[NAMESPACE_SELECTOR]->[1]}) {
48     $ns->{$ss->[NAMESPACE_SELECTOR]->[1]} = 'n' . ++$i;
49     }
50     $v .= $ns->{$ss->[NAMESPACE_SELECTOR]->[1]} . '|';
51     } else {
52     $v .= '|';
53     }
54    
55     if (defined $ss->[LOCAL_NAME_SELECTOR]->[1]) {
56     $v .= $ident->($ss->[LOCAL_NAME_SELECTOR]->[1]);
57     } else {
58     $v .= '*';
59     }
60    
61 wakaba 1.3 ## BUG: sorting order is wrong (see editor's comment in the spec)
62 wakaba 1.1 $v .= join '', sort {$a cmp $b} map {
63     '[' .
64     (defined $_->[1] ?
65     $_->[1] eq '' ? '' : ($ns->{$_->[1]} ||= 'n'.++$i) : '*') .
66     '|' .
67     $ident->($_->[2]) .
68     ($_->[3] != EXISTS_MATCH ?
69     {EQUALS_MATCH, '=',
70     INCLUDES_MATCH, '~=',
71     DASH_MATCH, '|=',
72     PREFIX_MATCH, '^=',
73     SUFFIX_MATCH, '$=',
74     SUBSTRING_MATCH, '*='}->{$_->[3]} .
75     $str->($_->[4])
76     : '') .
77     ']';
78     } @{$ss->[ATTRIBUTE_SELECTOR] || []};
79    
80     $v .= join '', sort {$a cmp $b} map {
81     '.' . $ident->($_->[1]);
82     } @{$ss->[CLASS_SELECTOR] || []};
83    
84     $v .= join '', sort {$a cmp $b} map {
85     '#' . $ident->($_->[1]);
86     } @{$ss->[ID_SELECTOR] || []};
87    
88     $v .= join '', sort {$a cmp $b} map {
89     my $v = $_;
90     if ($v->[1] eq 'lang') {
91     ':lang(' . $ident->($v->[2]) . ')';
92     } elsif ($v->[1] eq 'not') {
93     my $v = Whatpm::CSS::SelectorsSerializer->serialize_test
94     ([[DESCENDANT_COMBINATOR, [@{$v}[2..$#{$v}]]]], $ns);
95     $v =~ s/^ \*\|\*(?!$)/ /;
96     ":not(\n " . $v . " )";
97     } elsif ({'nth-child' => 1,
98     'nth-last-child' => 1,
99     'nth-of-type' => 1,
100     'nth-last-of-type' => 1}->{$v->[1]}) {
101     ':' . $ident->($v->[1]) . '(' .
102     ($v->[2] . 'n' . ($v->[3] < 0 ? $v->[3] : '+' . $v->[3])) . ')';
103 wakaba 1.2 } elsif ($v->[1] eq '-manakai-contains') {
104     ':-manakai-contains(' . $str->($v->[2]) . ')';
105 wakaba 1.1 } else {
106     ':' . $ident->($v->[1]);
107     }
108     } @{$ss->[PSEUDO_CLASS_SELECTOR] || []};
109    
110     $v .= join '', sort {$a cmp $b} map {
111     '::' . $ident->($_->[1]);
112     } @{$ss->[PSEUDO_ELEMENT_SELECTOR] || []};
113    
114     $v . "\n";
115     } else {
116     " " . {
117     DESCENDANT_COMBINATOR, ' ',
118     CHILD_COMBINATOR, '>',
119     ADJACENT_SIBLING_COMBINATOR, '+',
120     GENERAL_SIBLING_COMBINATOR, '~',
121     }->{$_} . " ";
122     }
123     } @$_;
124     } @$selectors;
125    
126     return wantarray ? ($r, join '', map {
127     '@namespace ' . $ns->{$_} . ' ' . $str->($_) . ";\n";
128     } sort {$a cmp $b} keys %$ns) : $r;
129     } # serialize_test
130    
131 wakaba 1.3
132     =head1 LICENSE
133    
134     Copyright 2007 Wakaba <[email protected]>
135    
136     This library is free software; you can redistribute it
137     and/or modify it under the same terms as Perl itself.
138    
139     =cut
140    
141 wakaba 1.1 1;
142 wakaba 1.3 # $Date:$

[email protected]
ViewVC Help
Powered by ViewVC 1.1.24