/[suikacvs]/markup/html/whatpm/What/NanoDOM.pm
Suika

Contents of /markup/html/whatpm/What/NanoDOM.pm

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.1 - (hide annotations) (download)
Mon Apr 30 14:12:02 2007 UTC (17 years, 7 months ago) by wakaba
Branch: MAIN
++ whatpm/What/ChangeLog	30 Apr 2007 14:11:13 -0000
	* HTML.pm.src: Some typos are fixed.

2007-04-30  Wakaba  <wakaba@suika.fam.cx>

++ whatpm/t/ChangeLog	30 Apr 2007 14:11:55 -0000
	* .cvsignore: |tree-consturction| is added.

	* HTML-tree.t: New test.

	* Makefile: Rules for tree constructor tests are added.

2007-04-30  Wakaba  <wakaba@suika.fam.cx>

1 wakaba 1.1 package What::NanoDOM;
2     use strict;
3    
4     package What::NanoDOM::Node;
5    
6     sub new ($) {
7     my $class = shift;
8     my $self = bless {}, $class;
9     return $self;
10     } # new
11    
12     sub is_equal_node ($$) {
13     return shift eq shift;
14     } # is_equal_node
15    
16     sub parent_node ($) {
17     return shift->{parent_node};
18     } # parent_node
19    
20     ## NOTE: Only applied to Elements and Documents
21     sub child_nodes ($) {
22     return shift->{child_nodes};
23     } # child_nodes
24    
25     ## NOTE: Only applied to Elements and Documents
26     sub append_child ($$) {
27     my ($self, $new_child) = @_;
28     if (defined $new_child->{parent_node}) {
29     my $parent_list = $new_child->{parent_node}->{child_nodes};
30     for (0..$#$parent_list) {
31     if ($parent_list->[$_] eq $new_child) {
32     splice @$parent_list, $_, 1;
33     }
34     }
35     }
36     push @{$self->{child_nodes}}, $new_child;
37     $new_child->{parent_node} = $self; ## TODO: weaken this ref
38     return $new_child;
39     } # append_child
40    
41     ## NOTE: Only applied to Elements and Documents
42     sub insert_before ($$;$) {
43     my ($self, $new_child, $ref_child) = @_;
44     if (defined $new_child->{parent_node}) {
45     my $parent_list = $new_child->{parent_node}->{child_nodes};
46     for (0..$#$parent_list) {
47     if ($parent_list->[$_] eq $new_child) {
48     splice @$parent_list, $_, 1;
49     }
50     }
51     }
52     my $i = @{$self->{child_nodes}};
53     if (defined $ref_child) {
54     for (0..$#{$self->{child_nodes}}) {
55     if ($self->{child_nodes}->[$_] eq $ref_child) {
56     $i = $_;
57     last;
58     }
59     }
60     }
61     splice @{$self->{child_nodes}}, $i, 0, $new_child;
62     $new_child->{parent_node} = $self; ## TODO: weaken this ref
63     return $new_child;
64     } # insert_before
65    
66     sub remove_child ($$) {
67     my ($self, $old_child) = @_;
68     my $parent_list = $self->{child_nodes};
69     for (0..$#$parent_list) {
70     if ($parent_list->[$_] eq $old_child) {
71     splice @$parent_list, $_, 1;
72     }
73     }
74     delete $old_child->{parent_node};
75     return $old_child;
76     } # remove_child
77    
78     ## NOTE: Only applied to Elements and Documents
79     sub has_child_nodes ($) {
80     return @{shift->{child_nodes}} > 0;
81     } # has_child_nodes
82    
83     sub ELEMENT_NODE () { 1 }
84     sub ATTRIBUTE_NODE () { 2 }
85     sub TEXT_NODE () { 3 }
86     sub CDATA_SECTION_NODE () { 4 }
87     sub ENTITY_REFERENCE_NODE () { 5 }
88     sub ENTITY_NODE () { 6 }
89     sub PROCESSING_INSTRUCTION_NODE () { 7 }
90     sub COMMENT_NODE () { 8 }
91     sub DOCUMENT_NODE () { 9 }
92     sub DOCUMENT_TYPE_NODE () { 10 }
93     sub DOCUMENT_FRAGMENT_NODE () { 11 }
94     sub NOTATION_NODE () { 12 }
95    
96     package What::NanoDOM::Document;
97     push our @ISA, 'What::NanoDOM::Node';
98    
99     sub new ($) {
100     my $self = shift->SUPER::new;
101     $self->{child_nodes} = [];
102     return $self;
103     } # new
104    
105     ## A manakai extension
106     sub manakai_append_text ($$) {
107     my $self = shift;
108     if (@{$self->{child_nodes}} and
109     $self->{child_nodes}->[-1]->node_type == 3) {
110     $self->{child_nodes}->[-1]->manakai_append_text (shift);
111     } else {
112     my $text = $self->create_text_node (shift);
113     $self->append_child ($text);
114     }
115     } # manakai_append_text
116    
117     sub node_type () { 9 }
118    
119     sub strict_error_checking {
120     return 0;
121     } # strict_error_checking
122    
123     sub create_text_node ($$) {
124     shift;
125     return What::NanoDOM::Text->new (shift);
126     } # create_text_node
127    
128     sub create_comment ($$) {
129     shift;
130     return What::NanoDOM::Comment->new (shift);
131     } # create_comment
132    
133     ## The second parameter only supports manakai extended way
134     ## to specify qualified name - "[$prefix, $local_name]"
135     sub create_element_ns ($$$) {
136     my ($self, $nsuri, $qn) = @_;
137     return What::NanoDOM::Element->new ($nsuri, $qn->[0], $qn->[1]);
138     } # create_element_ns
139    
140     ## A manakai extension
141     sub create_document_type_definition ($$) {
142     shift;
143     return What::NanoDOM::DocumentType->new (shift);
144     } # create_document_type_definition
145    
146     package What::NanoDOM::Element;
147     push our @ISA, 'What::NanoDOM::Node';
148    
149     sub new ($$$$) {
150     my $self = shift->SUPER::new;
151     $self->{namespace_uri} = shift;
152     $self->{prefix} = shift;
153     $self->{local_name} = shift;
154     $self->{attributes} = {};
155     $self->{child_nodes} = [];
156     return $self;
157     } # new
158    
159     sub clone_node ($$) {
160     my ($self, $deep) = @_; ## NOTE: Deep cloning is not supported
161     my $clone = bless {
162     namespace_uri => $self->{namespace_uri},
163     prefix => $self->{prefix},
164     local_name => $self->{local_name},
165     child_nodes => [],
166     }, ref $self;
167     for my $ns (keys %{$self->{attributes}}) {
168     for my $ln (keys %{$self->{attributes}->{$ns}}) {
169     $clone->{attributes}->{$ns}->{$ln} = bless {
170     prefix => $self->{attributes}->{$ns}->{$ln}->{prefix},
171     value => $self->{attributes}->{$ns}->{$ln}->{value},
172     }, ref $self->{attributes}->{$ns}->{$ln};
173     }
174     }
175     return $clone;
176     } # clone
177    
178     ## A manakai extension
179     sub manakai_append_text ($$) {
180     my $self = shift;
181     if (@{$self->{child_nodes}} and
182     $self->{child_nodes}->[-1]->node_type == 3) {
183     $self->{child_nodes}->[-1]->manakai_append_text (shift);
184     } else {
185     my $text = What::NanoDOM::Text->new (shift);
186     $self->append_child ($text);
187     }
188     } # manakai_append_text
189    
190     sub attributes ($) {
191     my $self = shift;
192     my $r = [];
193     ## Order MUST be stable
194     for my $ns (sort {$a cmp $b} keys %{$self->{attributes}}) {
195     for my $ln (sort {$a cmp $b} keys %{$self->{attributes}->{$ns}}) {
196     push @$r, $self->{attributes}->{$ns}->{$ln}
197     if defined $self->{attributes}->{$ns}->{$ln};
198     }
199     }
200     return $r;
201     } # attributes
202    
203     sub node_type { 1 }
204    
205     ## TODO: HTML5 capitalization
206     sub tag_name ($) {
207     my $self = shift;
208     if (defined $self->{prefix}) {
209     return $self->{prefix} . ':' . $self->{local_name};
210     } else {
211     return $self->{local_name};
212     }
213     } # tag_name
214    
215     sub has_attribute_ns ($$$) {
216     my ($self, $nsuri, $ln) = @_;
217     return defined $self->{attributes}->{$nsuri}->{$ln};
218     } # has_attribute_ns
219    
220     ## The second parameter only supports manakai extended way
221     ## to specify qualified name - "[$prefix, $local_name]"
222     sub set_attribute_ns ($$$$) {
223     my ($self, $nsuri, $qn, $value) = @_;
224     $self->{attributes}->{$nsuri}->{$qn->[1]}
225     = What::NanoDOM::Attr->new ($nsuri, $qn->[0], $qn->[1], $value);
226     } # set_attribute_ns
227    
228     package What::NanoDOM::Attr;
229     push our @ISA, 'What::NanoDOM::Node';
230    
231     sub new ($$$$$) {
232     my $self = shift->SUPER::new;
233     $self->{namespace_uri} = shift;
234     $self->{prefix} = shift;
235     $self->{local_name} = shift;
236     $self->{value} = shift;
237     return $self;
238     } # new
239    
240     sub node_type { 2 }
241    
242     ## TODO: HTML5 case stuff?
243     sub name ($) {
244     my $self = shift;
245     if (defined $self->{prefix}) {
246     return $self->{prefix} . ':' . $self->{local_name};
247     } else {
248     return $self->{local_name};
249     }
250     } # name
251    
252     sub value ($) {
253     return shift->{value};
254     } # value
255    
256     package What::NanoDOM::CharacterData;
257     push our @ISA, 'What::NanoDOM::Node';
258    
259     sub new ($$) {
260     my $self = shift->SUPER::new;
261     $self->{data} = shift;
262     return $self;
263     } # new
264    
265     ## A manakai extension
266     sub manakai_append_text ($$) {
267     my ($self, $s) = @_;
268     $self->{data} .= $s;
269     } # manakai_append_text
270    
271     sub data ($) {
272     return shift->{data};
273     } # data
274    
275     package What::NanoDOM::Text;
276     push our @ISA, 'What::NanoDOM::CharacterData';
277    
278     sub node_type () { 3 }
279    
280     package What::NanoDOM::Comment;
281     push our @ISA, 'What::NanoDOM::CharacterData';
282    
283     sub node_type () { 8 }
284    
285     package What::NanoDOM::DocumentType;
286     push our @ISA, 'What::NanoDOM::Node';
287    
288     sub new ($$) {
289     my $self = shift->SUPER::new;
290     $self->{name} = shift;
291     return $self;
292     } # new
293    
294     sub node_type () { 10 }
295    
296     sub name ($) {
297     return shift->{name};
298     } # name
299    
300     1;
301     # $Date:$

admin@suikawiki.org
ViewVC Help
Powered by ViewVC 1.1.24