/[suikacvs]/messaging/manakai/lib/Message/DOM/Attr.pm
Suika

Contents of /messaging/manakai/lib/Message/DOM/Attr.pm

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.7 - (show annotations) (download)
Sat Jul 7 09:11:05 2007 UTC (17 years, 4 months ago) by wakaba
Branch: MAIN
Changes since 1.6: +141 -4 lines
++ manakai/t/ChangeLog	7 Jul 2007 09:10:55 -0000
	* DOM-Document.t: New test for ARRAY qualified name
	is added.  Set |strict_error_checking| to false
	for a test not to be raised by |create_attribute_ns|.

2007-07-07  Wakaba  <wakaba@suika.fam.cx>

++ manakai/lib/Message/DOM/ChangeLog	7 Jul 2007 09:09:46 -0000
	* Attr.pm (create_attribute, create_attribute_ns): Implemented.

	* DOMDocument.pm: Load character classes from |Char::Class::XML|.
	(compat_mode): Check |defined| not to be warned as "uninitialized"
	when |{manakai_compat_mode}| is |undef|.

	* DOMException.pm (INVALID_CHARACTER_ERR, NAMESPACE_ERR): Added.

	* DOMImplementationRegistry.pm, DOMImplementationSource.pm:
	Statements to set |$Error::Depth| are removed since they
	are result in "uninitialized" warnings unless
	the |Message::DOM::DOMException| module is loaded earlier.
	Usually methods invoked in these methods does not
	raise any exception so that it makes no difference.

2007-07-07  Wakaba  <wakaba@suika.fam.cx>

1 package Message::DOM::Attr;
2 use strict;
3 our $VERSION=do{my @r=(q$Revision: 1.6 $=~/\d+/g);sprintf "%d."."%02d" x $#r,@r};
4 push our @ISA, 'Message::DOM::Node', 'Message::IF::Attr';
5 require Message::DOM::Node;
6
7 sub ____new ($$$$$$) {
8 my $self = shift->SUPER::____new (shift);
9 ($$self->{owner_element},
10 $$self->{namespace_uri},
11 $$self->{prefix},
12 $$self->{local_name}) = @_;
13 Scalar::Util::weaken ($$self->{owner_element});
14 $$self->{child_nodes} = [];
15 $$self->{specified} = 1;
16 return $self;
17 } # ____new
18
19 sub AUTOLOAD {
20 my $method_name = our $AUTOLOAD;
21 $method_name =~ s/.*:://;
22 return if $method_name eq 'DESTROY';
23
24 if ({
25 ## Read-only attributes (trivial accessors)
26 namespace_uri => 1,
27 owner_element => 1,
28 }->{$method_name}) {
29 no strict 'refs';
30 eval qq{
31 sub $method_name (\$) {
32 return \${\$_[0]}->{$method_name};
33 }
34 };
35 goto &{ $AUTOLOAD };
36 } else {
37 require Carp;
38 Carp::croak (qq<Can't locate method "$AUTOLOAD">);
39 }
40 } # AUTOLOAD
41 sub owner_element ($);
42
43 ## |Node| attributes
44
45 sub base_uri ($) {
46 my $self = $_[0];
47 local $Error::Depth = $Error::Depth + 1;
48 my $oe = $self->owner_element;
49 if ($oe) {
50 my $ln = $self->local_name;
51 my $nsuri = $self->namespace_uri;
52 if (($ln eq 'base' and
53 defined $nsuri and $nsuri eq 'http://www.w3.org/XML/1998/namespace') or
54 ($ln eq 'xml:base' and not defined $nsuri)) {
55 my $oep = $oe->parent_node;
56 if ($oep) {
57 return $oep->base_uri;
58 } else {
59 return $self->owner_document->base_uri;
60 }
61 } else {
62 return $oe->base_uri;
63 }
64 } else {
65 return $self->owner_document->base_uri;
66 }
67 } # base_uri
68
69 sub local_name ($) {
70 ## TODO: HTML5
71 return ${+shift}->{local_name};
72 } # local_name
73
74 sub manakai_local_name ($) {
75 return ${$_[0]}->{local_name};
76 } # manakai_local_name
77
78 sub namespace_uri ($);
79
80 ## The name of the attribute [DOM1, DOM2].
81 ## Same as |Attr.name| [DOM3].
82
83 *node_name = \&name;
84
85 sub node_type () { 2 } # ATTRIBUTE_NODE
86
87 ## The value of the attribute [DOM1, DOM2].
88 ## Same as |Attr.value| [DOM3].
89
90 *node_value = \&value;
91
92 sub prefix ($;$) {
93 ## NOTE: No check for new value as Firefox doesn't do.
94 ## See <http://suika.fam.cx/gate/2005/sw/prefix>.
95
96 ## NOTE: Same as trivial setter except "" -> undef
97
98 ## NOTE: Same as |Element|'s |prefix|.
99
100 if (@_ > 1) {
101 if (${${$_[0]}->{owner_document}}->{strict_error_checking} and
102 ${$_[0]}->{manakai_read_only}) {
103 report Message::DOM::DOMException
104 -object => $_[0],
105 -type => 'NO_MODIFICATION_ALLOWED_ERR',
106 -subtype => 'READ_ONLY_NODE_ERR';
107 }
108 if (defined $_[1] and $_[1] ne '') {
109 ${$_[0]}->{prefix} = ''.$_[1];
110 } else {
111 delete ${$_[0]}->{prefix};
112 }
113 }
114 return ${$_[0]}->{prefix};
115 } # prefix
116
117 ## |Attr| attributes
118
119 sub manakai_attribute_type ($;$) {
120 my $self = $_[0];
121 if (@_ > 1) {
122 if (${$$self->{owner_document}}->{strict_error_checking}) {
123 if ($$self->{manakai_read_only}) {
124 report Message::DOM::DOMException
125 -object => $self,
126 -type => 'NO_MODIFICATION_ALLOWED_ERR',
127 -subtype => 'READ_ONLY_NODE_ERR';
128 }
129 }
130 if ($_[1]) {
131 $$self->{manakai_attribute_type} = 0+$_[1];
132 } else {
133 delete $$self->{manakai_attribute_type};
134 }
135 }
136
137 return $$self->{manakai_attribute_type} || 0;
138 } # manakai_attribute_type
139
140 ## TODO: HTML5 case stuff?
141 sub name ($) {
142 my $self = shift;
143 if (defined $$self->{prefix}) {
144 return $$self->{prefix} . ':' . $$self->{local_name};
145 } else {
146 return $$self->{local_name};
147 }
148 } # name
149
150 sub specified ($;$) {
151 if (@_ > 1) {
152 ## NOTE: A manakai extension.
153 if (${${$_[0]}->{owner_document}}->{strict_error_checking} and
154 ${$_[0]}->{manakai_read_only}) {
155 report Message::DOM::DOMException
156 -object => $_[0],
157 -type => 'NO_MODIFICATION_ALLOWED_ERR',
158 -subtype => 'READ_ONLY_NODE_ERR';
159 }
160 if ($_[1] or not defined ${$_[0]}->{owner_element}) {
161 ${$_[0]}->{specified} = 1;
162 } else {
163 delete ${$_[0]}->{specified};
164 }
165 }
166 return ${$_[0]}->{specified};
167 } # specified
168
169 sub value ($;$) {
170 ## TODO:
171 shift->text_content (@_);
172 } # value
173
174 package Message::IF::Attr;
175
176 package Message::DOM::Document;
177
178 sub create_attribute ($$) {
179 if (${$_[0]}->{strict_error_checking}) {
180 my $xv = $_[0]->xml_version;
181 ## TODO: HTML Document ??
182 if (defined $xv) {
183 if ($xv eq '1.0' and
184 $_[1] =~ /\A\p{InXML_NameStartChar10}\p{InXMLNameChar10}*\z/) {
185 #
186 } elsif ($xv eq '1.1' and
187 $_[1] =~ /\A\p{InXMLNameStartChar11}\p{InXMLNameChar11}*\z/) {
188 #
189 } else {
190 report Message::DOM::DOMException
191 -object => $_[0],
192 -type => 'INVALID_CHARACTER_ERR',
193 -subtype => 'MALFORMED_NAME_ERR';
194 }
195 }
196 }
197 ## TODO: HTML5
198 return Message::DOM::Attr->____new ($_[0], undef, undef, undef, $_[1]);
199 } # create_attribute
200
201 sub create_attribute_ns ($$$) {
202 my ($prefix, $lname);
203 if (ref $_[2] eq 'ARRAY') {
204 ($prefix, $lname) = @{$_[2]};
205 } else {
206 ($prefix, $lname) = split /:/, $_[2], 2;
207 ($prefix, $lname) = (undef, $prefix) unless defined $lname;
208 }
209
210 if (${$_[0]}->{strict_error_checking}) {
211 my $xv = $_[0]->xml_version;
212 ## TODO: HTML Document ?? (NOT_SUPPORTED_ERR is different from what Web browsers do)
213 if (defined $xv) {
214 if ($xv eq '1.0') {
215 if (ref $_[2] eq 'ARRAY' or
216 $_[2] =~ /\A\p{InXML_NameStartChar10}\p{InXMLNameChar10}*\z/) {
217 if (defined $prefix) {
218 if ($prefix =~ /\A\p{InXML_NCNameStartChar10}\p{InXMLNCNameChar10}*\z/) {
219 #
220 } else {
221 report Message::DOM::DOMException
222 -object => $_[0],
223 -type => 'NAMESPACE_ERR',
224 -subtype => 'MALFORMED_QNAME_ERR';
225 }
226 }
227 if ($lname =~ /\A\p{InXML_NCNameStartChar10}\p{InXMLNCNameChar10}*\z/) {
228 #
229 } else {
230 report Message::DOM::DOMException
231 -object => $_[0],
232 -type => 'NAMESPACE_ERR',
233 -subtype => 'MALFORMED_QNAME_ERR';
234 }
235 } else {
236 report Message::DOM::DOMException
237 -object => $_[0],
238 -type => 'INVALID_CHARACTER_ERR',
239 -subtype => 'MALFORMED_NAME_ERR';
240 }
241 } elsif ($xv eq '1.1') {
242 if (ref $_[2] eq 'ARRAY' or
243 $_[2] =~ /\A\p{InXML_NameStartChar10}\p{InXMLNameChar10}*\z/) {
244 if (defined $prefix) {
245 if ($prefix =~ /\A\p{InXMLNCNameStartChar11}\p{InXMLNCNameChar11}*\z/) {
246 #
247 } else {
248 report Message::DOM::DOMException
249 -object => $_[0],
250 -type => 'NAMESPACE_ERR',
251 -subtype => 'MALFORMED_QNAME_ERR';
252 }
253 }
254 if ($lname =~ /\A\p{InXMLNCNameStartChar11}\p{InXMLNCNameChar11}*\z/) {
255 #
256 } else {
257 report Message::DOM::DOMException
258 -object => $_[0],
259 -type => 'NAMESPACE_ERR',
260 -subtype => 'MALFORMED_QNAME_ERR';
261 }
262 } else {
263 report Message::DOM::DOMException
264 -object => $_[0],
265 -type => 'INVALID_CHARACTER_ERR',
266 -subtype => 'MALFORMED_NAME_ERR';
267 }
268 } else {
269 die "create_attribute_ns: XML version |$xv| is not supported";
270 }
271 }
272
273 if (defined $prefix) {
274 if (not defined $_[1]) {
275 report Message::DOM::DOMException
276 -object => $_[0],
277 -type => 'NAMESPACE_ERR',
278 -subtype => 'PREFIXED_NULLNS_ERR';
279 } elsif ($prefix eq 'xml' and
280 $_[1] ne q<http://www.w3.org/XML/1998/namespace>) {
281 report Message::DOM::DOMException
282 -object => $_[0],
283 -type => 'NAMESPACE_ERR',
284 -subtype => 'XMLPREFIX_NONXMLNS_ERR';
285 } elsif ($prefix eq 'xmlns' and
286 $_[1] ne q<http://www.w3.org/2000/xmlns/>) {
287 report Message::DOM::DOMException
288 -object => $_[0],
289 -type => 'NAMESPACE_ERR',
290 -subtype => 'XMLNSPREFIX_NONXMLNSNS_ERR';
291 } elsif ($_[1] eq q<http://www.w3.org/2000/xmlns/> and
292 $prefix ne 'xmlns') {
293 report Message::DOM::DOMException
294 -object => $_[0],
295 -type => 'NAMESPACE_ERR',
296 -subtype => 'NONXMLNSPREFIX_XMLNSNS_ERR';
297 }
298 } else { # no prefix
299 if ($lname eq 'xmlns' and
300 (not defined $_[1] or $_[1] ne q<http://www.w3.org/2000/xmlns/>)) {
301 report Message::DOM::DOMException
302 -object => $_[0],
303 -type => 'NAMESPACE_ERR',
304 -subtype => 'XMLNS_NONXMLNSNS_ERR';
305 } elsif (not defined $_[1]) {
306 #
307 } elsif ($_[1] eq q<http://www.w3.org/2000/xmlns/> and
308 $lname ne 'xmlns') {
309 report Message::DOM::DOMException
310 -object => $_[0],
311 -type => 'NAMESPACE_ERR',
312 -subtype => 'NONXMLNSPREFIX_XMLNSNS_ERR';
313 }
314 }
315 }
316
317 ## TODO: Older version of manakai set |attribute_type|
318 ## attribute for |xml:id| attribute. Should we support this?
319
320 return Message::DOM::Attr->____new ($_[0], undef, $_[1], $prefix, $lname);
321 } # create_attribute_ns
322
323 =head1 LICENSE
324
325 Copyright 2007 Wakaba <w@suika.fam.cx>
326
327 This program is free software; you can redistribute it and/or
328 modify it under the same terms as Perl itself.
329
330 =cut
331
332 1;
333 ## $Date: 2007/06/17 13:37:40 $

admin@suikawiki.org
ViewVC Help
Powered by ViewVC 1.1.24