/[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.6 - (hide annotations) (download)
Sun Dec 23 15:47:09 2007 UTC (18 years, 4 months ago) by wakaba
Branch: MAIN
Changes since 1.5: +12 -6 lines
++ whatpm/Whatpm/CSS/ChangeLog	23 Dec 2007 15:47:04 -0000
2007-12-24  Wakaba  <wakaba@suika.fam.cx>

	* Parser.pm: Support for |@namespace| rule.

	* SelectorsSerializer.pm: Support for |lookup_namespace_prefix|
	parameter is added.

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

admin@suikawiki.org
ViewVC Help
Powered by ViewVC 1.1.24