/[suikacvs]/markup/html/whatpm/Whatpm/ContentChecker/Atom.pm
Suika

Diff of /markup/html/whatpm/Whatpm/ContentChecker/Atom.pm

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.17 by wakaba, Thu Mar 20 10:58:17 2008 UTC revision 1.22 by wakaba, Sat Sep 20 06:10:18 2008 UTC
# Line 23  sub FEATURE_RFC4685 () { Line 23  sub FEATURE_RFC4685 () {
23    
24  ## NOTE: Commants and PIs are not explicitly allowed.  ## NOTE: Commants and PIs are not explicitly allowed.
25    
26    our $IsInHTMLInteractiveContent; # See Whatpm::ContentChecker.
27    
28  our $AttrChecker;  our $AttrChecker;
29    
30  ## Any element MAY have xml:base, xml:lang  ## Any element MAY have xml:base, xml:lang
# Line 47  my $GetAtomAttrsChecker = sub { Line 49  my $GetAtomAttrsChecker = sub {
49        } elsif ($attr_ln eq '') {        } elsif ($attr_ln eq '') {
50          #          #
51        } else {        } else {
52          $self->{onerror}->(node => $attr, level => 'unsupported',          $self->{onerror}->(node => $attr,
53                             type => 'attribute');                             type => 'unknown attribute',
54                               level => $self->{level}->{uncertain});
55          ## ISSUE: No comformance createria for unknown attributes in the spec          ## ISSUE: No comformance createria for unknown attributes in the spec
56        }        }
57    
# Line 67  my $AtomLanguageTagAttrChecker = sub { Line 70  my $AtomLanguageTagAttrChecker = sub {
70    my $value = $attr->value;    my $value = $attr->value;
71    require Whatpm::LangTag;    require Whatpm::LangTag;
72    Whatpm::LangTag->check_rfc3066_language_tag ($value, sub {    Whatpm::LangTag->check_rfc3066_language_tag ($value, sub {
73      my %opt = @_;      $self->{onerror}->(@_, node => $attr);
74      my $type = 'LangTag:'.$opt{type};    }, $self->{level});
     $type .= ':' . $opt{subtag} if defined $opt{subtag};  
     $self->{onerror}->(node => $attr, type => $type, value => $opt{value},  
                        level => $opt{level});  
   });  
75    ## ISSUE: RFC 4646 (3066bis)?    ## ISSUE: RFC 4646 (3066bis)?
76  }; # $AtomLanguageTagAttrChecker  }; # $AtomLanguageTagAttrChecker
77    
# Line 97  my %AtomTextConstruct = ( Line 96  my %AtomTextConstruct = (
96          $element_state->{type} = $value;          $element_state->{type} = $value;
97        } else {        } else {
98          ## NOTE: IMT MUST NOT be used here.          ## NOTE: IMT MUST NOT be used here.
99          $self->{onerror}->(node => $attr, type => 'keyword:invalid');          $self->{onerror}->(node => $attr,
100                               type => 'invalid attribute value',
101                               level => $self->{level}->{must});
102        }        }
103      }, # checked in |checker|      }, # checked in |checker|
104    }, {    }, {
# Line 106  my %AtomTextConstruct = ( Line 107  my %AtomTextConstruct = (
107    check_child_element => sub {    check_child_element => sub {
108      my ($self, $item, $child_el, $child_nsuri, $child_ln,      my ($self, $item, $child_el, $child_nsuri, $child_ln,
109          $child_is_transparent, $element_state) = @_;          $child_is_transparent, $element_state) = @_;
110      if ($self->{minus_elements}->{$child_nsuri}->{$child_ln}) {      if ($self->{minus_elements}->{$child_nsuri}->{$child_ln} and
111            $IsInHTMLInteractiveContent->($child_el, $child_nsuri, $child_ln)) {
112        $self->{onerror}->(node => $child_el,        $self->{onerror}->(node => $child_el,
113                           type => 'element not allowed:minus',                           type => 'element not allowed:minus',
114                           level => $self->{must_level});                           level => $self->{level}->{must});
115      } elsif ($self->{plus_elements}->{$child_nsuri}->{$child_ln}) {      } elsif ($self->{plus_elements}->{$child_nsuri}->{$child_ln}) {
116        #        #
117      } else {      } else {
# Line 117  my %AtomTextConstruct = ( Line 119  my %AtomTextConstruct = (
119            $element_state->{type} eq 'html') { # MUST NOT            $element_state->{type} eq 'html') { # MUST NOT
120          $self->{onerror}->(node => $child_el,          $self->{onerror}->(node => $child_el,
121                             type => 'element not allowed:atom|TextConstruct',                             type => 'element not allowed:atom|TextConstruct',
122                             level => $self->{must_level});                             level => $self->{level}->{must});
123        } elsif ($element_state->{type} eq 'xhtml') {        } elsif ($element_state->{type} eq 'xhtml') {
124          if ($child_nsuri eq q<http://www.w3.org/1999/xhtml> and          if ($child_nsuri eq q<http://www.w3.org/1999/xhtml> and
125              $child_ln eq 'div') { # MUST              $child_ln eq 'div') { # MUST
# Line 125  my %AtomTextConstruct = ( Line 127  my %AtomTextConstruct = (
127              $self->{onerror}              $self->{onerror}
128                  ->(node => $child_el,                  ->(node => $child_el,
129                     type => 'element not allowed:atom|TextConstruct',                     type => 'element not allowed:atom|TextConstruct',
130                     level => $self->{must_level});                     level => $self->{level}->{must});
131            } else {            } else {
132              $element_state->{has_div} = 1;              $element_state->{has_div} = 1;
133              ## TODO: SHOULD be suitable for handling as HTML [XHTML10]              ## TODO: SHOULD be suitable for handling as HTML [XHTML10]
# Line 133  my %AtomTextConstruct = ( Line 135  my %AtomTextConstruct = (
135          } else {          } else {
136            $self->{onerror}->(node => $child_el,            $self->{onerror}->(node => $child_el,
137                               type => 'element not allowed:atom|TextConstruct',                               type => 'element not allowed:atom|TextConstruct',
138                               level => $self->{must_level});                               level => $self->{level}->{must});
139          }          }
140        } else {        } else {
141          die "atom:TextConstruct type error: $element_state->{type}";          die "atom:TextConstruct type error: $element_state->{type}";
# Line 151  my %AtomTextConstruct = ( Line 153  my %AtomTextConstruct = (
153        if ($has_significant) {        if ($has_significant) {
154          $self->{onerror}->(node => $child_node,          $self->{onerror}->(node => $child_node,
155                             type => 'character not allowed:atom|TextConstruct',                             type => 'character not allowed:atom|TextConstruct',
156                             level => $self->{must_level});                             level => $self->{level}->{must});
157        }        }
158      } else {      } else {
159        die "atom:TextConstruct type error: $element_state->{type}";        die "atom:TextConstruct type error: $element_state->{type}";
# Line 162  my %AtomTextConstruct = ( Line 164  my %AtomTextConstruct = (
164      if ($element_state->{type} eq 'xhtml') {      if ($element_state->{type} eq 'xhtml') {
165        unless ($element_state->{has_div}) {        unless ($element_state->{has_div}) {
166          $self->{onerror}->(node => $item->{node},          $self->{onerror}->(node => $item->{node},
167                             type => 'element missing:div',                             type => 'child element missing',
168                             level => $self->{must_level});                             text => 'div',
169                               level => $self->{level}->{must});
170        }        }
171      } elsif ($element_state->{type} eq 'html') {      } elsif ($element_state->{type} eq 'html') {
172        ## TODO: SHOULD be suitable for handling as HTML [HTML4]        ## TODO: SHOULD be suitable for handling as HTML [HTML4]
# Line 184  my %AtomPersonConstruct = ( Line 187  my %AtomPersonConstruct = (
187    check_child_element => sub {    check_child_element => sub {
188      my ($self, $item, $child_el, $child_nsuri, $child_ln,      my ($self, $item, $child_el, $child_nsuri, $child_ln,
189          $child_is_transparent, $element_state) = @_;          $child_is_transparent, $element_state) = @_;
190      if ($self->{minus_elements}->{$child_nsuri}->{$child_ln}) {      if ($self->{minus_elements}->{$child_nsuri}->{$child_ln} and
191            $IsInHTMLInteractiveContent->($child_el, $child_nsuri, $child_ln)) {
192        $self->{onerror}->(node => $child_el,        $self->{onerror}->(node => $child_el,
193                           type => 'element not allowed:minus',                           type => 'element not allowed:minus',
194                           level => $self->{must_level});                           level => $self->{level}->{must});
195      } elsif ($self->{plus_elements}->{$child_nsuri}->{$child_ln}) {      } elsif ($self->{plus_elements}->{$child_nsuri}->{$child_ln}) {
196        #        #
197      } elsif ($child_nsuri eq $ATOM_NS) {      } elsif ($child_nsuri eq $ATOM_NS) {
# Line 196  my %AtomPersonConstruct = ( Line 200  my %AtomPersonConstruct = (
200            $self->{onerror}            $self->{onerror}
201                ->(node => $child_el,                ->(node => $child_el,
202                   type => 'element not allowed:atom|PersonConstruct',                   type => 'element not allowed:atom|PersonConstruct',
203                   level => $self->{must_level});                   level => $self->{level}->{must});
204          } else {          } else {
205            $element_state->{has_name} = 1;            $element_state->{has_name} = 1;
206          }          }
# Line 205  my %AtomPersonConstruct = ( Line 209  my %AtomPersonConstruct = (
209            $self->{onerror}            $self->{onerror}
210                ->(node => $child_el,                ->(node => $child_el,
211                   type => 'element not allowed:atom|PersonConstruct',                   type => 'element not allowed:atom|PersonConstruct',
212                   level => $self->{must_level});                   level => $self->{level}->{must});
213          } else {          } else {
214            $element_state->{has_uri} = 1;            $element_state->{has_uri} = 1;
215          }          }
# Line 214  my %AtomPersonConstruct = ( Line 218  my %AtomPersonConstruct = (
218            $self->{onerror}            $self->{onerror}
219                ->(node => $child_el,                ->(node => $child_el,
220                   type => 'element not allowed:atom|PersonConstruct',                   type => 'element not allowed:atom|PersonConstruct',
221                   level => $self->{must_level});                   level => $self->{level}->{must});
222          } else {          } else {
223            $element_state->{has_email} = 1;            $element_state->{has_email} = 1;
224          }          }
# Line 222  my %AtomPersonConstruct = ( Line 226  my %AtomPersonConstruct = (
226          $self->{onerror}          $self->{onerror}
227              ->(node => $child_el,              ->(node => $child_el,
228                 type => 'element not allowed:atom|PersonConstruct',                 type => 'element not allowed:atom|PersonConstruct',
229                 level => $self->{must_level});                 level => $self->{level}->{must});
230        }        }
231      } else {      } else {
232        $self->{onerror}        $self->{onerror}
233            ->(node => $child_el,            ->(node => $child_el,
234               type => 'element not allowed:atom|PersonConstruct',               type => 'element not allowed:atom|PersonConstruct',
235               level => $self->{must_level});               level => $self->{level}->{must});
236      }      }
237      ## TODO: extension element      ## TODO: extension element
238    },    },
# Line 237  my %AtomPersonConstruct = ( Line 241  my %AtomPersonConstruct = (
241      if ($has_significant) {      if ($has_significant) {
242        $self->{onerror}->(node => $child_node,        $self->{onerror}->(node => $child_node,
243                           type => 'character not allowed:atom|PersonConstruct',                           type => 'character not allowed:atom|PersonConstruct',
244                           level => $self->{must_level});                           level => $self->{level}->{must});
245      }      }
246    },    },
247    check_end => sub {    check_end => sub {
# Line 245  my %AtomPersonConstruct = ( Line 249  my %AtomPersonConstruct = (
249    
250      unless ($element_state->{has_name}) {      unless ($element_state->{has_name}) {
251        $self->{onerror}->(node => $item->{node},        $self->{onerror}->(node => $item->{node},
252                           type => 'element missing:atom|name',                           type => 'child element missing:atom',
253                           level => $self->{must_level});                           text => 'name',
254                             level => $self->{level}->{must});
255      }      }
256    
257      $AtomChecker{check_end}->(@_);      $AtomChecker{check_end}->(@_);
# Line 290  $Element->{$ATOM_NS}->{uri} = { Line 295  $Element->{$ATOM_NS}->{uri} = {
295    
296      ## NOTE: There MUST NOT be any white space.      ## NOTE: There MUST NOT be any white space.
297      Whatpm::URIChecker->check_iri_reference ($element_state->{value}, sub {      Whatpm::URIChecker->check_iri_reference ($element_state->{value}, sub {
298        my %opt = @_;        $self->{onerror}->(@_, node => $item->{node});
299        $self->{onerror}->(node => $item->{node}, level => $opt{level},      }, $self->{level});
                          type => 'URI::'.$opt{type}.  
                          (defined $opt{position} ? ':'.$opt{position} : ''));  
     });  
300    
301      $AtomChecker{check_end}->(@_);      $AtomChecker{check_end}->(@_);
302    },    },
# Line 314  $Element->{$ATOM_NS}->{email} = { Line 316  $Element->{$ATOM_NS}->{email} = {
316      ## TODO: addr-spec      ## TODO: addr-spec
317      $self->{onerror}->(node => $item->{node},      $self->{onerror}->(node => $item->{node},
318                         type => 'addr-spec not supported',                         type => 'addr-spec not supported',
319                         level => $self->{unsupported_level});                         level => $self->{level}->{uncertain});
320    
321      $AtomChecker{check_end}->(@_);      $AtomChecker{check_end}->(@_);
322    },    },
# Line 345  my %AtomDateConstruct = ( Line 347  my %AtomDateConstruct = (
347    
348        ## Check additional constraints described or referenced in        ## Check additional constraints described or referenced in
349        ## comments of ABNF rules for |date-time|.        ## comments of ABNF rules for |date-time|.
       my $level = $self->{must_level};  
350        if (0 < $M and $M < 13) {              if (0 < $M and $M < 13) {      
351          $self->{onerror}->(node => $node, type => 'datetime:bad day',          $self->{onerror}->(node => $node, type => 'datetime:bad day',
352                             level => $level)                             level => $self->{level}->{must})
353              if $d < 1 or              if $d < 1 or
354                  $d > [0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]->[$M];                  $d > [0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]->[$M];
355          $self->{onerror}->(node => $node, type => 'datetime:bad day',          $self->{onerror}->(node => $node, type => 'datetime:bad day',
356                             level => $level)                             level => $self->{level}->{must})
357              if $M == 2 and $d == 29 and              if $M == 2 and $d == 29 and
358                  not ($y % 400 == 0 or ($y % 4 == 0 and $y % 100 != 0));                  not ($y % 400 == 0 or ($y % 4 == 0 and $y % 100 != 0));
359        } else {        } else {
360          $self->{onerror}->(node => $node, type => 'datetime:bad month',          $self->{onerror}->(node => $node, type => 'datetime:bad month',
361                             level => $level);                             level => $self->{level}->{must});
362        }        }
363        $self->{onerror}->(node => $node, type => 'datetime:bad hour',        $self->{onerror}->(node => $node, type => 'datetime:bad hour',
364                           level => $level) if $h > 23;                           level => $self->{level}->{must}) if $h > 23;
365        $self->{onerror}->(node => $node, type => 'datetime:bad minute',        $self->{onerror}->(node => $node, type => 'datetime:bad minute',
366                           level => $level) if $m > 59;                           level => $self->{level}->{must}) if $m > 59;
367        $self->{onerror}->(node => $node, type => 'datetime:bad second',        $self->{onerror}->(node => $node, type => 'datetime:bad second',
368                           level => $level)                           level => $self->{level}->{must})
369            if $s > 60; ## NOTE: Validness of leap seconds are not checked.            if $s > 60; ## NOTE: Validness of leap seconds are not checked.
370        $self->{onerror}->(node => $node, type => 'datetime:bad timezone hour',        $self->{onerror}->(node => $node, type => 'datetime:bad timezone hour',
371                           level => $level) if $zh > 23;                           level => $self->{level}->{must}) if $zh > 23;
372        $self->{onerror}->(node => $node, type => 'datetime:bad timezone minute',        $self->{onerror}->(node => $node, type => 'datetime:bad timezone minute',
373                           level => $level) if $zm > 59;                           level => $self->{level}->{must}) if $zm > 59;
374      } else {      } else {
375        $self->{onerror}->(node => $item->{node},        $self->{onerror}->(node => $item->{node},
376                           type => 'datetime:syntax error',                           type => 'datetime:syntax error',
377                           level => $self->{must_level});                           level => $self->{level}->{must});
378      }      }
379      ## NOTE: SHOULD be accurate as possible (cannot be checked)      ## NOTE: SHOULD be accurate as possible (cannot be checked)
380    
# Line 390  $Element->{$ATOM_NS}->{entry} = { Line 391  $Element->{$ATOM_NS}->{entry} = {
391    
392      ## NOTE: metadata elements, followed by atom:entry* (no explicit MAY)      ## NOTE: metadata elements, followed by atom:entry* (no explicit MAY)
393    
394      if ($self->{minus_elements}->{$child_nsuri}->{$child_ln}) {      if ($self->{minus_elements}->{$child_nsuri}->{$child_ln} and
395            $IsInHTMLInteractiveContent->($child_el, $child_nsuri, $child_ln)) {
396        $self->{onerror}->(node => $child_el,        $self->{onerror}->(node => $child_el,
397                           type => 'element not allowed:minus',                           type => 'element not allowed:minus',
398                           level => $self->{must_level});                           level => $self->{level}->{must});
399      } elsif ($self->{plus_elements}->{$child_nsuri}->{$child_ln}) {      } elsif ($self->{plus_elements}->{$child_nsuri}->{$child_ln}) {
400        #        #
401      } elsif ($child_nsuri eq $ATOM_NS) {      } elsif ($child_nsuri eq $ATOM_NS) {
# Line 445  $Element->{$ATOM_NS}->{entry} = { Line 447  $Element->{$ATOM_NS}->{entry} = {
447          $not_allowed = 1;          $not_allowed = 1;
448        }        }
449        if ($not_allowed) {        if ($not_allowed) {
450          $self->{onerror}->(node => $child_el, type => 'element not allowed');          $self->{onerror}->(node => $child_el, type => 'element not allowed',
451                               level => $self->{level}->{must});
452        }        }
453      } elsif ($child_nsuri eq $THR_NS and $child_ln eq 'in-reply-to') {      } elsif ($child_nsuri eq $THR_NS and $child_ln eq 'in-reply-to') {
454        ## ISSUE: Where |thr:in-reply-to| is allowed is not explicit;y        ## ISSUE: Where |thr:in-reply-to| is allowed is not explicit;y
# Line 455  $Element->{$ATOM_NS}->{entry} = { Line 458  $Element->{$ATOM_NS}->{entry} = {
458        #        #
459      } else {      } else {
460        ## TODO: extension element        ## TODO: extension element
461        $self->{onerror}->(node => $child_el, type => 'element not allowed');        $self->{onerror}->(node => $child_el, type => 'element not allowed',
462                             level => $self->{level}->{must});
463      }      }
464    },    },
465    check_child_text => sub {    check_child_text => sub {
466      my ($self, $item, $child_node, $has_significant, $element_state) = @_;      my ($self, $item, $child_node, $has_significant, $element_state) = @_;
467      if ($has_significant) {      if ($has_significant) {
468        $self->{onerror}->(node => $child_node, type => 'character not allowed',        $self->{onerror}->(node => $child_node, type => 'character not allowed',
469                           level => $self->{must_level});                           level => $self->{level}->{must});
470      }      }
471    },    },
472    check_end => sub {    check_end => sub {
# Line 493  $Element->{$ATOM_NS}->{entry} = { Line 497  $Element->{$ATOM_NS}->{entry} = {
497          }          }
498                    
499          $self->{onerror}->(node => $item->{node},          $self->{onerror}->(node => $item->{node},
500                             type => 'element missing:atom|author',                             type => 'child element missing:atom',
501                             level => $self->{must_level});                             text => 'author',
502                               level => $self->{level}->{must});
503        } # A        } # A
504      }      }
505    
# Line 506  $Element->{$ATOM_NS}->{entry} = { Line 511  $Element->{$ATOM_NS}->{entry} = {
511    
512      unless ($element_state->{has_element}->{id}) { # MUST      unless ($element_state->{has_element}->{id}) { # MUST
513        $self->{onerror}->(node => $item->{node},        $self->{onerror}->(node => $item->{node},
514                           type => 'element missing:atom|id');                           type => 'child element missing:atom',
515                             text => 'id',
516                             level => $self->{level}->{must});
517      }      }
518      unless ($element_state->{has_element}->{title}) { # MUST      unless ($element_state->{has_element}->{title}) { # MUST
519        $self->{onerror}->(node => $item->{node},        $self->{onerror}->(node => $item->{node},
520                           type => 'element missing:atom|title');                           type => 'child element missing:atom',
521                             text => 'title',
522                             level => $self->{level}->{must});
523      }      }
524      unless ($element_state->{has_element}->{updated}) { # MUST      unless ($element_state->{has_element}->{updated}) { # MUST
525        $self->{onerror}->(node => $item->{node},        $self->{onerror}->(node => $item->{node},
526                           type => 'element missing:atom|updated');                           type => 'child element missing:atom',
527                             text => 'updated',
528                             level => $self->{level}->{must});
529      }      }
530      if (not $element_state->{has_element}->{content} and      if (not $element_state->{has_element}->{content} and
531          not $element_state->{has_element}->{'link.alternate'}) {          not $element_state->{has_element}->{'link.alternate'}) {
532        $self->{onerror}->(node => $item->{node},        $self->{onerror}->(node => $item->{node},
533                           type => 'element missing:atom|link|alternate');                           type => 'child element missing:atom:link:alternate',
534                             level => $self->{level}->{must});
535      }      }
536    
537      if ($element_state->{require_summary} and      if ($element_state->{require_summary} and
538          not $element_state->{has_element}->{summary}) {          not $element_state->{has_element}->{summary}) {
539        $self->{onerror}->(node => $item->{node},        $self->{onerror}->(node => $item->{node},
540                           type => 'element missing:atom|summary',                           type => 'child element missing:atom',
541                           level => $self->{must_level});                           text => 'summary',
542                             level => $self->{level}->{must});
543      }      }
544    },    },
545  };  };
# Line 540  $Element->{$ATOM_NS}->{feed} = { Line 553  $Element->{$ATOM_NS}->{feed} = {
553    
554      ## NOTE: metadata elements, followed by atom:entry* (no explicit MAY)      ## NOTE: metadata elements, followed by atom:entry* (no explicit MAY)
555    
556      if ($self->{minus_elements}->{$child_nsuri}->{$child_ln}) {      if ($self->{minus_elements}->{$child_nsuri}->{$child_ln} and
557            $IsInHTMLInteractiveContent->($child_el, $child_nsuri, $child_ln)) {
558        $self->{onerror}->(node => $child_el,        $self->{onerror}->(node => $child_el,
559                           type => 'element not allowed:minus',                           type => 'element not allowed:minus',
560                           level => $self->{must_level});                           level => $self->{level}->{must});
561      } elsif ($self->{plus_elements}->{$child_nsuri}->{$child_ln}) {      } elsif ($self->{plus_elements}->{$child_nsuri}->{$child_ln}) {
562        #        #
563      } elsif ($child_nsuri eq $ATOM_NS) {      } elsif ($child_nsuri eq $ATOM_NS) {
# Line 597  $Element->{$ATOM_NS}->{feed} = { Line 611  $Element->{$ATOM_NS}->{feed} = {
611        } else {        } else {
612          $not_allowed = 1;          $not_allowed = 1;
613        }        }
614        $self->{onerror}->(node => $child_el, type => 'element not allowed')        $self->{onerror}->(node => $child_el, type => 'element not allowed',
615                             level => $self->{level}->{must})
616            if $not_allowed;            if $not_allowed;
617      } else {      } else {
618        ## TODO: extension element        ## TODO: extension element
619        $self->{onerror}->(node => $child_el, type => 'element not allowed');        $self->{onerror}->(node => $child_el, type => 'element not allowed',
620                             level => $self->{level}->{must});
621      }      }
622    },    },
623    check_child_text => sub {    check_child_text => sub {
624      my ($self, $item, $child_node, $has_significant, $element_state) = @_;      my ($self, $item, $child_node, $has_significant, $element_state) = @_;
625      if ($has_significant) {      if ($has_significant) {
626        $self->{onerror}->(node => $child_node, type => 'character not allowed',        $self->{onerror}->(node => $child_node, type => 'character not allowed',
627                           level => $self->{must_level});                           level => $self->{level}->{must});
628      }      }
629    },    },
630    check_end => sub {    check_end => sub {
# Line 617  $Element->{$ATOM_NS}->{feed} = { Line 633  $Element->{$ATOM_NS}->{feed} = {
633      if ($element_state->{has_no_author_entry} and      if ($element_state->{has_no_author_entry} and
634          not $element_state->{has_element}->{author}) {          not $element_state->{has_element}->{author}) {
635        $self->{onerror}->(node => $item->{node},        $self->{onerror}->(node => $item->{node},
636                           type => 'element missing:atom|author',                           type => 'child element missing:atom',
637                           level => $self->{must_level});                           text => 'author',
638                             level => $self->{level}->{must});
639        ## ISSUE: If there is no |atom:entry| element,        ## ISSUE: If there is no |atom:entry| element,
640        ## there should be an |atom:author| element?        ## there should be an |atom:author| element?
641      }      }
# Line 627  $Element->{$ATOM_NS}->{feed} = { Line 644  $Element->{$ATOM_NS}->{feed} = {
644    
645      unless ($element_state->{has_element}->{id}) { # MUST      unless ($element_state->{has_element}->{id}) { # MUST
646        $self->{onerror}->(node => $item->{node},        $self->{onerror}->(node => $item->{node},
647                           type => 'element missing:atom|id');                           type => 'child element missing:atom',
648                             text => 'id',
649                             level => $self->{level}->{must});
650      }      }
651      unless ($element_state->{has_element}->{title}) { # MUST      unless ($element_state->{has_element}->{title}) { # MUST
652        $self->{onerror}->(node => $item->{node},        $self->{onerror}->(node => $item->{node},
653                           type => 'element missing:atom|title');                           type => 'child element missing:atom',
654                             text => 'title',
655                             level => $self->{level}->{must});
656      }      }
657      unless ($element_state->{has_element}->{updated}) { # MUST      unless ($element_state->{has_element}->{updated}) { # MUST
658        $self->{onerror}->(node => $item->{node},        $self->{onerror}->(node => $item->{node},
659                           type => 'element missing:atom|updated');                           type => 'element missing:atom',
660                             text => 'updated',
661                             level => $self->{level}->{must});
662      }      }
663      unless ($element_state->{has_element}->{'link.self'}) {      unless ($element_state->{has_element}->{'link.self'}) {
664        $self->{onerror}->(node => $item->{node}, level => 's',        $self->{onerror}->(node => $item->{node},
665                           type => 'element missing:atom|link|self');                           type => 'element missing:atom:link:self',
666                             level => $self->{level}->{should});
667      }      }
668    
669      $AtomChecker{check_end}->(@_);      $AtomChecker{check_end}->(@_);
# Line 662  $Element->{$ATOM_NS}->{content} = { Line 686  $Element->{$ATOM_NS}->{content} = {
686    
687        ## NOTE: There MUST NOT be any white space.        ## NOTE: There MUST NOT be any white space.
688        Whatpm::URIChecker->check_iri_reference ($attr->value, sub {        Whatpm::URIChecker->check_iri_reference ($attr->value, sub {
689          my %opt = @_;          $self->{onerror}->(@_, node => $item->{node});
690          $self->{onerror}->(node => $item->{node}, level => $opt{level},        }, $self->{level});
                            type => 'URI::'.$opt{type}.  
                            (defined $opt{position} ? ':'.$opt{position} : ''));  
       });  
691      },      },
692      type => sub {      type => sub {
693        my ($self, $attr, $item, $element_state) = @_;        my ($self, $attr, $item, $element_state) = @_;
# Line 695  $Element->{$ATOM_NS}->{content} = { Line 716  $Element->{$ATOM_NS}->{content} = {
716              }              }
717            }            }
718            require Whatpm::IMTChecker;            require Whatpm::IMTChecker;
719            Whatpm::IMTChecker->check_imt (sub {            my $ic = Whatpm::IMTChecker->new;
720              my %opt = @_;            $ic->{level} = $self->{level};
721              $self->{onerror}->(node => $attr, level => $opt{level},            $ic->check_imt (sub {
722                                 type => 'IMT:'.$opt{type});              $self->{onerror}->(@_, node => $attr);
723            }, @type);            }, @type);
724          } else {          } else {
725            $self->{onerror}->(node => $attr, type => 'IMT:syntax error',            $self->{onerror}->(node => $attr, type => 'IMT:syntax error',
726                               level => $self->{must_level});                               level => $self->{level}->{must});
727          }          }
728        }        }
729    
# Line 716  $Element->{$ATOM_NS}->{content} = { Line 737  $Element->{$ATOM_NS}->{content} = {
737          $value = 'mime_text';          $value = 'mime_text';
738        } elsif ($value =~ m!^(?>message|multipart)/!i) {        } elsif ($value =~ m!^(?>message|multipart)/!i) {
739          $self->{onerror}->(node => $attr, type => 'IMT:composite',          $self->{onerror}->(node => $attr, type => 'IMT:composite',
740                             level => $self->{must_level});                             level => $self->{level}->{must});
741          $item->{parent_state}->{require_summary} = 1;          $item->{parent_state}->{require_summary} = 1;
742        } else {        } else {
743          $item->{parent_state}->{require_summary} = 1;          $item->{parent_state}->{require_summary} = 1;
# Line 732  $Element->{$ATOM_NS}->{content} = { Line 753  $Element->{$ATOM_NS}->{content} = {
753      my ($self, $item, $child_el, $child_nsuri, $child_ln,      my ($self, $item, $child_el, $child_nsuri, $child_ln,
754          $child_is_transparent, $element_state) = @_;          $child_is_transparent, $element_state) = @_;
755    
756      if ($self->{minus_elements}->{$child_nsuri}->{$child_ln}) {      if ($self->{minus_elements}->{$child_nsuri}->{$child_ln} and
757            $IsInHTMLInteractiveContent->($child_el, $child_nsuri, $child_ln)) {
758        $self->{onerror}->(node => $child_el,        $self->{onerror}->(node => $child_el,
759                           type => 'element not allowed:minus',                           type => 'element not allowed:minus',
760                           level => $self->{must_level});                           level => $self->{level}->{must});
761      } elsif ($self->{plus_elements}->{$child_nsuri}->{$child_ln}) {      } elsif ($self->{plus_elements}->{$child_nsuri}->{$child_ln}) {
762        #        #
763      } else {      } else {
# Line 745  $Element->{$ATOM_NS}->{content} = { Line 767  $Element->{$ATOM_NS}->{content} = {
767          # MUST NOT          # MUST NOT
768          $self->{onerror}->(node => $child_el,          $self->{onerror}->(node => $child_el,
769                             type => 'element not allowed:atom|content',                             type => 'element not allowed:atom|content',
770                             level => $self->{must_level});                             level => $self->{level}->{must});
771        } elsif ($element_state->{type} eq 'xhtml') {        } elsif ($element_state->{type} eq 'xhtml') {
772          if ($element_state->{has_div}) {          if ($element_state->{has_div}) {
773            $self->{onerror}->(node => $child_el,            $self->{onerror}->(node => $child_el,
774                               type => 'element not allowed:atom|content',                               type => 'element not allowed:atom|content',
775                               level => $self->{must_level});                               level => $self->{level}->{must});
776          } else {          } else {
777            ## TODO: SHOULD be suitable for handling as HTML [XHTML10]            ## TODO: SHOULD be suitable for handling as HTML [XHTML10]
778            $element_state->{has_div} = 1;            $element_state->{has_div} = 1;
# Line 760  $Element->{$ATOM_NS}->{content} = { Line 782  $Element->{$ATOM_NS}->{content} = {
782          if ($element_state->{has_src}) {          if ($element_state->{has_src}) {
783            $self->{onerror}->(node => $child_el,            $self->{onerror}->(node => $child_el,
784                               type => 'element not allowed:atom|content',                               type => 'element not allowed:atom|content',
785                               level => $self->{must_level});                               level => $self->{level}->{must});
786          }          }
787        } else {        } else {
788          ## NOTE: Elements are not explicitly disallowed.          ## NOTE: Elements are not explicitly disallowed.
# Line 777  $Element->{$ATOM_NS}->{content} = { Line 799  $Element->{$ATOM_NS}->{content} = {
799      if ($has_significant) {      if ($has_significant) {
800        if ($element_state->{has_src}) {        if ($element_state->{has_src}) {
801          $self->{onerror}->(node => $child_node,          $self->{onerror}->(node => $child_node,
802                             type => 'character not allowed',                             type => 'character not allowed:empty',
803                             level => $self->{must_level});                             level => $self->{level}->{must});
804        } elsif ($element_state->{type} eq 'xhtml' or        } elsif ($element_state->{type} eq 'xhtml' or
805                 $element_state->{type} eq 'xml') {                 $element_state->{type} eq 'xml') {
806          $self->{onerror}->(node => $child_node,          $self->{onerror}->(node => $child_node,
807                             type => 'character not allowed:atom|content',                             type => 'character not allowed:atom|content',
808                             level => $self->{must_level});                             level => $self->{level}->{must});
809        }        }
810      }      }
811    
# Line 798  $Element->{$ATOM_NS}->{content} = { Line 820  $Element->{$ATOM_NS}->{content} = {
820      if ($element_state->{has_src}) {      if ($element_state->{has_src}) {
821        if (not $element_state->{has_type}) {        if (not $element_state->{has_type}) {
822          $self->{onerror}->(node => $item->{node},          $self->{onerror}->(node => $item->{node},
823                             type => 'attribute missing:type',                             type => 'attribute missing',
824                             level => $self->{should_level});                             text => 'type',
825                               level => $self->{level}->{should});
826        } elsif ($element_state->{type} eq 'text' or        } elsif ($element_state->{type} eq 'text' or
827                 $element_state->{type} eq 'html' or                 $element_state->{type} eq 'html' or
828                 $element_state->{type} eq 'xhtml') {                 $element_state->{type} eq 'xhtml') {
829          $self->{onerror}          $self->{onerror}
830              ->(node => $item->{node}->get_attribute_node_ns (undef, 'type'),              ->(node => $item->{node}->get_attribute_node_ns (undef, 'type'),
831                 type => 'not IMT', level => $self->{must_level});                 type => 'not IMT', level => $self->{level}->{must});
832        }        }
833      }      }
834    
835      if ($element_state->{type} eq 'xhtml') {      if ($element_state->{type} eq 'xhtml') {
836        unless ($element_state->{has_div}) {        unless ($element_state->{has_div}) {
837          $self->{onerror}->(node => $item->{node},          $self->{onerror}->(node => $item->{node},
838                             type => 'element missing:div',                             type => 'child element missing',
839                             level => $self->{must_level});                             text => 'div',
840                               level => $self->{level}->{must});
841        }        }
842      } elsif ($element_state->{type} eq 'html') {      } elsif ($element_state->{type} eq 'html') {
843        ## TODO: SHOULD be suitable for handling as HTML [HTML4]        ## TODO: SHOULD be suitable for handling as HTML [HTML4]
# Line 828  $Element->{$ATOM_NS}->{content} = { Line 852  $Element->{$ATOM_NS}->{content} = {
852        ## If no @src, this would normally mean it contains a        ## If no @src, this would normally mean it contains a
853        ## single child element that would serve as the root element.        ## single child element that would serve as the root element.
854        $self->{onerror}->(node => $item->{node},        $self->{onerror}->(node => $item->{node},
                          level => $self->{unsupported_level},  
855                           type => 'atom|content not supported',                           type => 'atom|content not supported',
856                           value => $item->{node}->get_attribute_ns                           text => $item->{node}->get_attribute_ns
857                               (undef, 'type'));                               (undef, 'type'),
858                             level => $self->{level}->{uncertain});
859      } elsif ($element_state->{type} eq 'text' or      } elsif ($element_state->{type} eq 'text' or
860               $element_state->{type} eq 'mime-text') {               $element_state->{type} eq 'mime-text') {
861        #        #
# Line 842  $Element->{$ATOM_NS}->{content} = { Line 866  $Element->{$ATOM_NS}->{content} = {
866    
867        ## NOTE: SHOULD be suitable for the indicated media type.        ## NOTE: SHOULD be suitable for the indicated media type.
868        $self->{onerror}->(node => $item->{node},        $self->{onerror}->(node => $item->{node},
                          level => $self->{unsupported_level},  
869                           type => 'atom|content not supported',                           type => 'atom|content not supported',
870                           value => $item->{node}->get_attribute_ns                           text => $item->{node}->get_attribute_ns
871                               (undef, 'type'));                               (undef, 'type'),
872                             level => $self->{level}->{uncertain});
873      }      }
874    
875      $AtomChecker{check_end}->(@_);      $AtomChecker{check_end}->(@_);
# Line 863  $Element->{$ATOM_NS}->{category} = { Line 887  $Element->{$ATOM_NS}->{category} = {
887        my ($self, $attr) = @_;        my ($self, $attr) = @_;
888        ## NOTE: There MUST NOT be any white space.        ## NOTE: There MUST NOT be any white space.
889        Whatpm::URIChecker->check_iri ($attr->value, sub {        Whatpm::URIChecker->check_iri ($attr->value, sub {
890          my %opt = @_;          $self->{onerror}->(@_, node => $attr);
891          $self->{onerror}->(node => $attr, level => $opt{level},        }, $self->{level});
                            type => 'URI::'.$opt{type}.  
                            (defined $opt{position} ? ':'.$opt{position} : ''));  
       });  
892      },      },
893      term => sub {      term => sub {
894        my ($self, $attr, $item, $element_state) = @_;        my ($self, $attr, $item, $element_state) = @_;
# Line 885  $Element->{$ATOM_NS}->{category} = { Line 906  $Element->{$ATOM_NS}->{category} = {
906      my ($self, $item, $element_state) = @_;      my ($self, $item, $element_state) = @_;
907      unless ($element_state->{has_term}) {      unless ($element_state->{has_term}) {
908        $self->{onerror}->(node => $item->{node},        $self->{onerror}->(node => $item->{node},
909                           type => 'attribute missing:term');                           type => 'attribute missing',
910                             text => 'term',
911                             level => $self->{level}->{must});
912      }      }
913    
914      $AtomChecker{check_end}->(@_);      $AtomChecker{check_end}->(@_);
# Line 904  $Element->{$ATOM_NS}->{generator} = { Line 927  $Element->{$ATOM_NS}->{generator} = {
927        my ($self, $attr) = @_;        my ($self, $attr) = @_;
928        ## NOTE: There MUST NOT be any white space.        ## NOTE: There MUST NOT be any white space.
929        Whatpm::URIChecker->check_iri_reference ($attr->value, sub {        Whatpm::URIChecker->check_iri_reference ($attr->value, sub {
930          my %opt = @_;          $self->{onerror}->(@_, node => $attr);
931          $self->{onerror}->(node => $attr, level => $opt{level},        }, $self->{level});
                            type => 'URI::'.$opt{type}.  
                            (defined $opt{position} ? ':'.$opt{position} : ''));  
       });  
932        ## NOTE: Dereferencing SHOULD produce a representation        ## NOTE: Dereferencing SHOULD produce a representation
933        ## that is relevant to the agent.        ## that is relevant to the agent.
934      },      },
# Line 941  $Element->{$ATOM_NS}->{icon} = { Line 961  $Element->{$ATOM_NS}->{icon} = {
961      ## NOTE: No MUST.      ## NOTE: No MUST.
962      ## NOTE: There MUST NOT be any white space.      ## NOTE: There MUST NOT be any white space.
963      Whatpm::URIChecker->check_iri_reference ($element_state->{value}, sub {      Whatpm::URIChecker->check_iri_reference ($element_state->{value}, sub {
964        my %opt = @_;        $self->{onerror}->(@_, node => $item->{node});
965        $self->{onerror}->(node => $item->{node}, level => $opt{level},      }, $self->{level});
                          type => 'URI::'.$opt{type}.  
                          (defined $opt{position} ? ':'.$opt{position} : ''));  
     });  
966    
967      ## NOTE: Image SHOULD be 1:1 and SHOULD be small      ## NOTE: Image SHOULD be 1:1 and SHOULD be small
968    
# Line 969  $Element->{$ATOM_NS}->{id} = { Line 986  $Element->{$ATOM_NS}->{id} = {
986    
987      ## NOTE: There MUST NOT be any white space.      ## NOTE: There MUST NOT be any white space.
988      Whatpm::URIChecker->check_iri ($element_state->{value}, sub {      Whatpm::URIChecker->check_iri ($element_state->{value}, sub {
989        my %opt = @_;        $self->{onerror}->(@_, node => $item->{node});
990        $self->{onerror}->(node => $item->{node}, level => $opt{level},      }, $self->{level});
                          type => 'URI::'.$opt{type}.  
                          (defined $opt{position} ? ':'.$opt{position} : ''));  
     });  
991      ## TODO: SHOULD be normalized      ## TODO: SHOULD be normalized
992    
993      $AtomChecker{check_end}->(@_);      $AtomChecker{check_end}->(@_);
# Line 1000  my $AtomIMTAttrChecker = sub { Line 1014  my $AtomIMTAttrChecker = sub {
1014            }            }
1015          }          }
1016          require Whatpm::IMTChecker;          require Whatpm::IMTChecker;
1017          Whatpm::IMTChecker->check_imt (sub {          my $ic = Whatpm::IMTChecker->new;
1018            my %opt = @_;          $ic->{level} = $self->{level};
1019            $self->{onerror}->(node => $attr, level => $opt{level},          $ic->check_imt (sub {
1020                               type => 'IMT:'.$opt{type});            $self->{onerror}->(@_, node => $attr);
1021          }, @type);          }, @type);
1022        } else {        } else {
1023          $self->{onerror}->(node => $attr, type => 'IMT:syntax error');          $self->{onerror}->(node => $attr, type => 'IMT:syntax error',
1024                               level => $self->{level}->{must});
1025        }        }
1026  }; # $AtomIMTAttrChecker  }; # $AtomIMTAttrChecker
1027    
# Line 1014  my $AtomIRIReferenceAttrChecker = sub { Line 1029  my $AtomIRIReferenceAttrChecker = sub {
1029    my ($self, $attr) = @_;    my ($self, $attr) = @_;
1030    ## NOTE: There MUST NOT be any white space.    ## NOTE: There MUST NOT be any white space.
1031    Whatpm::URIChecker->check_iri_reference ($attr->value, sub {    Whatpm::URIChecker->check_iri_reference ($attr->value, sub {
1032      my %opt = @_;      $self->{onerror}->(@_, node => $attr);
1033      $self->{onerror}->(node => $attr, level => $opt{level},    }, $self->{level});
                        type => 'URI::'.$opt{type}.  
                        (defined $opt{position} ? ':'.$opt{position} : ''));  
   });  
1034  }; # $AtomIRIReferenceAttrChecker  }; # $AtomIRIReferenceAttrChecker
1035    
1036  $Element->{$ATOM_NS}->{link} = {  $Element->{$ATOM_NS}->{link} = {
# Line 1036  $Element->{$ATOM_NS}->{link} = { Line 1048  $Element->{$ATOM_NS}->{link} = {
1048    
1049        ## NOTE: There MUST NOT be any white space.        ## NOTE: There MUST NOT be any white space.
1050        Whatpm::URIChecker->check_iri ($value, sub {        Whatpm::URIChecker->check_iri ($value, sub {
1051          my %opt = @_;          $self->{onerror}->(@_, node => $attr);
1052          $self->{onerror}->(node => $attr, level => $opt{level},        }, $self->{level});
                            type => 'URI::'.$opt{type}.  
                            (defined $opt{position} ? ':'.$opt{position} : ''));  
       });  
1053    
1054        ## TODO: Warn if unregistered        ## TODO: Warn if unregistered
1055    
# Line 1069  $Element->{$ATOM_NS}->{link} = { Line 1078  $Element->{$ATOM_NS}->{link} = {
1078    
1079      unless ($item->{node}->has_attribute_ns (undef, 'href')) { # MUST      unless ($item->{node}->has_attribute_ns (undef, 'href')) { # MUST
1080        $self->{onerror}->(node => $item->{node},        $self->{onerror}->(node => $item->{node},
1081                           type => 'attribute missing:href');                           type => 'attribute missing',
1082                             text => 'href',
1083                             level => $self->{level}->{must});
1084      }      }
1085    
1086      if ($item->{node}->rel eq $LINK_REL . 'enclosure' and      if ($item->{node}->rel eq $LINK_REL . 'enclosure' and
1087          not $item->{node}->has_attribute_ns (undef, 'length')) {          not $item->{node}->has_attribute_ns (undef, 'length')) {
1088        $self->{onerror}->(node => $item->{node}, level => 's',        $self->{onerror}->(node => $item->{node},
1089                           type => 'attribute missing:length');                           type => 'attribute missing',
1090                             text => 'length',
1091                             level => $self->{level}->{should});
1092      }      }
1093    },    },
1094  };  };
# Line 1097  $Element->{$ATOM_NS}->{logo} = { Line 1110  $Element->{$ATOM_NS}->{logo} = {
1110    
1111      ## NOTE: There MUST NOT be any white space.      ## NOTE: There MUST NOT be any white space.
1112      Whatpm::URIChecker->check_iri_reference ($element_state->{value}, sub {      Whatpm::URIChecker->check_iri_reference ($element_state->{value}, sub {
1113        my %opt = @_;        $self->{onerror}->(@_, node => $item->{node});
1114        $self->{onerror}->(node => $item->{node}, level => $opt{level},      }, $self->{level});
                          type => 'URI::'.$opt{type}.  
                          (defined $opt{position} ? ':'.$opt{position} : ''));  
     });  
1115            
1116      ## NOTE: Image SHOULD be 2:1      ## NOTE: Image SHOULD be 2:1
1117    
# Line 1120  $Element->{$ATOM_NS}->{source} = { Line 1130  $Element->{$ATOM_NS}->{source} = {
1130      my ($self, $item, $child_el, $child_nsuri, $child_ln,      my ($self, $item, $child_el, $child_nsuri, $child_ln,
1131          $child_is_transparent, $element_state) = @_;          $child_is_transparent, $element_state) = @_;
1132    
1133      if ($self->{minus_elements}->{$child_nsuri}->{$child_ln}) {      if ($self->{minus_elements}->{$child_nsuri}->{$child_ln} and
1134            $IsInHTMLInteractiveContent->($child_el, $child_nsuri, $child_ln)) {
1135        $self->{onerror}->(node => $child_el,        $self->{onerror}->(node => $child_el,
1136                           type => 'element not allowed:minus',                           type => 'element not allowed:minus',
1137                           level => $self->{must_level});                           level => $self->{level}->{must});
1138      } elsif ($self->{plus_elements}->{$child_nsuri}->{$child_ln}) {      } elsif ($self->{plus_elements}->{$child_nsuri}->{$child_ln}) {
1139        #        #
1140      } elsif ($child_nsuri eq $ATOM_NS) {      } elsif ($child_nsuri eq $ATOM_NS) {
# Line 1173  $Element->{$ATOM_NS}->{source} = { Line 1184  $Element->{$ATOM_NS}->{source} = {
1184          $not_allowed = 1;          $not_allowed = 1;
1185        }        }
1186        if ($not_allowed) {        if ($not_allowed) {
1187          $self->{onerror}->(node => $child_el, type => 'element not allowed');          $self->{onerror}->(node => $child_el, type => 'element not allowed',
1188                               level => $self->{level}->{must});
1189        }        }
1190      } else {      } else {
1191        ## TODO: extension element        ## TODO: extension element
1192        $self->{onerror}->(node => $child_el, type => 'element not allowed');        $self->{onerror}->(node => $child_el, type => 'element not allowed',
1193                             level => $self->{level}->{must});
1194      }      }
1195    },    },
1196    check_child_text => sub {    check_child_text => sub {
1197      my ($self, $item, $child_node, $has_significant, $element_state) = @_;      my ($self, $item, $child_node, $has_significant, $element_state) = @_;
1198      if ($has_significant) {      if ($has_significant) {
1199        $self->{onerror}->(node => $child_node, type => 'character not allowed',        $self->{onerror}->(node => $child_node, type => 'character not allowed',
1200                           level => $self->{must_level});                           level => $self->{level}->{must});
1201      }      }
1202    },    },
1203  };  };
# Line 1225  $Element->{$THR_NS}->{'in-reply-to'} = { Line 1238  $Element->{$THR_NS}->{'in-reply-to'} = {
1238        ## NOTE: Same as |atom:id|.        ## NOTE: Same as |atom:id|.
1239        ## NOTE: There MUST NOT be any white space.        ## NOTE: There MUST NOT be any white space.
1240        Whatpm::URIChecker->check_iri ($attr->value, sub {        Whatpm::URIChecker->check_iri ($attr->value, sub {
1241          my %opt = @_;          $self->{onerror}->(@_, node => $attr);
1242          $self->{onerror}->(node => $attr, level => $opt{level},        }, $self->{level});
                            type => 'URI::'.$opt{type}.  
                            (defined $opt{position} ? ':'.$opt{position} : ''));  
       });  
1243    
1244        ## TODO: Check against ID guideline...        ## TODO: Check against ID guideline...
1245      },      },
# Line 1249  $Element->{$THR_NS}->{'in-reply-to'} = { Line 1259  $Element->{$THR_NS}->{'in-reply-to'} = {
1259        
1260      unless ($element_state->{has_ref}) {      unless ($element_state->{has_ref}) {
1261        $self->{onerror}->(node => $item->{node},        $self->{onerror}->(node => $item->{node},
1262                           type => 'attribute missing:ref',                           type => 'attribute missing',
1263                           level => $self->{must_level});                           text => 'ref',
1264                             level => $self->{level}->{must});
1265      }      }
1266    
1267      $AtomChecker{check_end}->(@_);      $AtomChecker{check_end}->(@_);
# Line 1268  $Element->{$THR_NS}->{total} = { Line 1279  $Element->{$THR_NS}->{total} = {
1279      my ($self, $item, $child_el, $child_nsuri, $child_ln,      my ($self, $item, $child_el, $child_nsuri, $child_ln,
1280          $child_is_transparent, $element_state) = @_;          $child_is_transparent, $element_state) = @_;
1281    
1282      if ($self->{minus_elements}->{$child_nsuri}->{$child_ln}) {      if ($self->{minus_elements}->{$child_nsuri}->{$child_ln} and
1283            $IsInHTMLInteractiveContent->($child_el, $child_nsuri, $child_ln)) {
1284        $self->{onerror}->(node => $child_el,        $self->{onerror}->(node => $child_el,
1285                           type => 'element not allowed:minus',                           type => 'element not allowed:minus',
1286                           level => $self->{must_level});                           level => $self->{level}->{must});
1287      } elsif ($self->{plus_elements}->{$child_nsuri}->{$child_ln}) {      } elsif ($self->{plus_elements}->{$child_nsuri}->{$child_ln}) {
1288        #        #
1289      } else {      } else {
1290        $self->{onerror}->(node => $child_el,        $self->{onerror}->(node => $child_el,
1291                           type => 'element not allowed',                           type => 'element not allowed',
1292                           level => $self->{must_level});                           level => $self->{level}->{must});
1293      }      }
1294    },    },
1295    check_child_text => sub {    check_child_text => sub {
# Line 1290  $Element->{$THR_NS}->{total} = { Line 1302  $Element->{$THR_NS}->{total} = {
1302      ## NOTE: xsd:nonNegativeInteger      ## NOTE: xsd:nonNegativeInteger
1303      unless ($element_state->{value} =~ /\A(?>[0-9]+|-0+)\z/) {      unless ($element_state->{value} =~ /\A(?>[0-9]+|-0+)\z/) {
1304        $self->{onerror}->(node => $item->{node},        $self->{onerror}->(node => $item->{node},
1305                           type => 'syntax error', ## TODO:                           type => 'invalid attribute value',
1306                           level => $self->{must_level});                           level => $self->{level}->{must});
1307      }      }
1308    
1309      $AtomChecker{check_end}->(@_);      $AtomChecker{check_end}->(@_);

Legend:
Removed from v.1.17  
changed lines
  Added in v.1.22

admin@suikawiki.org
ViewVC Help
Powered by ViewVC 1.1.24