/[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.4 - (hide annotations) (download)
Tue Oct 23 11:32:57 2007 UTC (18 years, 9 months ago) by wakaba
Branch: MAIN
Changes since 1.3: +5 -4 lines
++ whatpm/t/ChangeLog	23 Oct 2007 11:31:04 -0000
2007-10-23  Wakaba  <wakaba@suika.fam.cx>

	* content-model-2.dat: <script async defer> is now conforming (HTML5
	revision 1085).

++ whatpm/Whatpm/ContentChecker/ChangeLog	23 Oct 2007 11:25:14 -0000
2007-10-23  Wakaba  <wakaba@suika.fam.cx>

	* HTML.pm: Make <script async defer> conforming (HTML5
	revision 1085).

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

[email protected]
ViewVC Help
Powered by ViewVC 1.1.24