/[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.5 - (hide annotations) (download)
Sun Oct 28 06:35:15 2007 UTC (18 years, 6 months ago) by wakaba
Branch: MAIN
Changes since 1.4: +8 -16 lines
++ whatpm/Whatpm/CSS/ChangeLog	28 Oct 2007 06:34:48 -0000
2007-10-28  Wakaba  <wakaba@suika.fam.cx>

	* SelectorsSerializer.pm (serialize_test): Namespace prefix
	IS namespace URI for sorting stability (attribute and :not()
	selectors).

	* selectors-object.en.html: Namespace URI cannot be empty.

1 wakaba 1.1 package Whatpm::CSS::SelectorsSerializer;
2     use strict;
3 wakaba 1.5 our $VERSION=do{my @r=(q$Revision: 1.4 $=~/\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.5 sub serialize_test ($$) {
8     my (undef, $selectors) = @_;
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     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 wakaba 1.5 $v .= $ident->($ss->[NAMESPACE_SELECTOR]->[1]) . '|';
48 wakaba 1.1 } else {
49     $v .= '|';
50     }
51    
52     if (defined $ss->[LOCAL_NAME_SELECTOR]->[1]) {
53     $v .= $ident->($ss->[LOCAL_NAME_SELECTOR]->[1]);
54     } else {
55     $v .= '*';
56     }
57    
58     $v .= join '', sort {$a cmp $b} map {
59     '[' .
60     (defined $_->[1] ?
61 wakaba 1.5 $_->[1] eq '' ? '' : $ident->($_->[1]) : '*') .
62 wakaba 1.1 '|' .
63     $ident->($_->[2]) .
64     ($_->[3] != EXISTS_MATCH ?
65     {EQUALS_MATCH, '=',
66     INCLUDES_MATCH, '~=',
67     DASH_MATCH, '|=',
68     PREFIX_MATCH, '^=',
69     SUFFIX_MATCH, '$=',
70     SUBSTRING_MATCH, '*='}->{$_->[3]} .
71     $str->($_->[4])
72     : '') .
73     ']';
74     } @{$ss->[ATTRIBUTE_SELECTOR] || []};
75    
76     $v .= join '', sort {$a cmp $b} map {
77     '.' . $ident->($_->[1]);
78     } @{$ss->[CLASS_SELECTOR] || []};
79    
80     $v .= join '', sort {$a cmp $b} map {
81     '#' . $ident->($_->[1]);
82     } @{$ss->[ID_SELECTOR] || []};
83    
84     $v .= join '', sort {$a cmp $b} map {
85     my $v = $_;
86     if ($v->[1] eq 'lang') {
87     ':lang(' . $ident->($v->[2]) . ')';
88     } elsif ($v->[1] eq 'not') {
89     my $v = Whatpm::CSS::SelectorsSerializer->serialize_test
90 wakaba 1.5 ([[DESCENDANT_COMBINATOR, [@{$v}[2..$#{$v}]]]]);
91 wakaba 1.1 $v =~ s/^ \*\|\*(?!$)/ /;
92     ":not(\n " . $v . " )";
93     } elsif ({'nth-child' => 1,
94     'nth-last-child' => 1,
95     'nth-of-type' => 1,
96     'nth-last-of-type' => 1}->{$v->[1]}) {
97     ':' . $ident->($v->[1]) . '(' .
98     ($v->[2] . 'n' . ($v->[3] < 0 ? $v->[3] : '+' . $v->[3])) . ')';
99 wakaba 1.2 } elsif ($v->[1] eq '-manakai-contains') {
100     ':-manakai-contains(' . $str->($v->[2]) . ')';
101 wakaba 1.1 } else {
102     ':' . $ident->($v->[1]);
103     }
104     } @{$ss->[PSEUDO_CLASS_SELECTOR] || []};
105    
106     $v .= join '', sort {$a cmp $b} map {
107     '::' . $ident->($_->[1]);
108     } @{$ss->[PSEUDO_ELEMENT_SELECTOR] || []};
109    
110     $v . "\n";
111     } else {
112     " " . {
113     DESCENDANT_COMBINATOR, ' ',
114     CHILD_COMBINATOR, '>',
115     ADJACENT_SIBLING_COMBINATOR, '+',
116     GENERAL_SIBLING_COMBINATOR, '~',
117     }->{$_} . " ";
118     }
119     } @$_;
120     } @$selectors;
121    
122 wakaba 1.5 return $r;
123 wakaba 1.1 } # serialize_test
124    
125 wakaba 1.3 =head1 LICENSE
126    
127     Copyright 2007 Wakaba <w@suika.fam.cx>
128    
129     This library is free software; you can redistribute it
130     and/or modify it under the same terms as Perl itself.
131    
132     =cut
133    
134 wakaba 1.1 1;
135 wakaba 1.5 # $Date: 2007/10/23 11:32:57 $

admin@suikawiki.org
ViewVC Help
Powered by ViewVC 1.1.24