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

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

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

revision 1.6 by wakaba, Sun May 13 09:52:08 2007 UTC revision 1.7 by wakaba, Sun May 13 10:17:35 2007 UTC
# Line 39  my $Element = {}; Line 39  my $Element = {};
39    
40  my $HTML_NS = q<http://www.w3.org/1999/xhtml>;  my $HTML_NS = q<http://www.w3.org/1999/xhtml>;
41    
42  my $HTMLMetadataElements = [  my $HTMLMetadataElements = {
43    [$HTML_NS, 'link'],    $HTML_NS => {
44    [$HTML_NS, 'meta'],      qw/link 1 meta 1 style 1 script 1 event-source 1 command 1 base 1 title 1/,
45    [$HTML_NS, 'style'],    },
46    [$HTML_NS, 'script'],  };
   [$HTML_NS, 'event-source'],  
   [$HTML_NS, 'command'],  
   [$HTML_NS, 'base'],  
   [$HTML_NS, 'title'],  
 ];  
47    
48  my $HTMLSectioningElements = {  my $HTMLSectioningElements = {
49    $HTML_NS => {qw/body 1 section 1 nav 1 article 1 blockquote 1 aside 1/},    $HTML_NS => {qw/body 1 section 1 nav 1 article 1 blockquote 1 aside 1/},
50  };  };
51    
52  my $HTMLBlockLevelElements = [  my $HTMLBlockLevelElements = {
53    [$HTML_NS, 'section'],    $HTML_NS => {
54    [$HTML_NS, 'nav'],      qw/
55    [$HTML_NS, 'article'],        section 1 nav 1 article 1 blockquote 1 aside 1
56    [$HTML_NS, 'blockquote'],        h1 1 h2 1 h3 1 h4 1 h5 1 h6 1 header 1 footer 1
57    [$HTML_NS, 'aside'],        address 1 p 1 hr 1 dialog 1 pre 1 ol 1 ul 1 dl 1
58    [$HTML_NS, 'h1'],        ins 1 del 1 figure 1 map 1 table 1 script 1 noscript 1
59    [$HTML_NS, 'h2'],        event-source 1 details 1 datagrid 1 menu 1 div 1 font 1
60    [$HTML_NS, 'h3'],      /,
61    [$HTML_NS, 'h4'],    },
62    [$HTML_NS, 'h5'],  };
63    [$HTML_NS, 'h6'],  
64    [$HTML_NS, 'header'],  my $HTMLStrictlyInlineLevelElements = {
65    [$HTML_NS, 'footer'],    $HTML_NS => {
66    [$HTML_NS, 'address'],      qw/
67    [$HTML_NS, 'p'],        br 1 a 1 q 1 cite 1 em 1 strong 1 small 1 m 1 dfn 1 abbr 1
68    [$HTML_NS, 'hr'],        time 1 meter 1 progress 1 code 1 var 1 samp 1 kbd 1
69    [$HTML_NS, 'dialog'],        sub 1 sup 1 span 1 i 1 b 1 bdo 1 ins 1 del 1 img 1
70    [$HTML_NS, 'pre'],        iframe 1 embed 1 object 1 video 1 audio 1 canvas 1 area 1
71    [$HTML_NS, 'ol'],        script 1 noscript 1 event-source 1 command 1 font 1
72    [$HTML_NS, 'ul'],      /,
73    [$HTML_NS, 'dl'],    },
74    [$HTML_NS, 'ins'],  };
75    [$HTML_NS, 'del'],  
76    [$HTML_NS, 'figure'],  my $HTMLStructuredInlineLevelElements = {
77    [$HTML_NS, 'map'],    $HTML_NS => {qw/blockquote 1 pre 1 ol 1 ul 1 dl 1 table 1 menu 1/},
78    [$HTML_NS, 'table'],  };
   [$HTML_NS, 'script'],  
   [$HTML_NS, 'noscript'],  
   [$HTML_NS, 'event-source'],  
   [$HTML_NS, 'details'],  
   [$HTML_NS, 'datagrid'],  
   [$HTML_NS, 'menu'],  
   [$HTML_NS, 'div'],  
   [$HTML_NS, 'font'],  
 ];  
   
 my $HTMLStrictlyInlineLevelElements = [  
   [$HTML_NS, 'br'],  
   [$HTML_NS, 'a'],  
   [$HTML_NS, 'q'],  
   [$HTML_NS, 'cite'],  
   [$HTML_NS, 'em'],  
   [$HTML_NS, 'strong'],  
   [$HTML_NS, 'small'],  
   [$HTML_NS, 'm'],  
   [$HTML_NS, 'dfn'],  
   [$HTML_NS, 'abbr'],  
   [$HTML_NS, 'time'],  
   [$HTML_NS, 'meter'],  
   [$HTML_NS, 'progress'],  
   [$HTML_NS, 'code'],  
   [$HTML_NS, 'var'],  
   [$HTML_NS, 'samp'],  
   [$HTML_NS, 'kbd'],  
   [$HTML_NS, 'sub'],  
   [$HTML_NS, 'sup'],  
   [$HTML_NS, 'span'],  
   [$HTML_NS, 'i'],  
   [$HTML_NS, 'b'],  
   [$HTML_NS, 'bdo'],  
   [$HTML_NS, 'ins'],  
   [$HTML_NS, 'del'],  
   [$HTML_NS, 'img'],  
   [$HTML_NS, 'iframe'],  
   [$HTML_NS, 'embed'],  
   [$HTML_NS, 'object'],  
   [$HTML_NS, 'video'],  
   [$HTML_NS, 'audio'],  
   [$HTML_NS, 'canvas'],  
   [$HTML_NS, 'area'],  
   [$HTML_NS, 'script'],  
   [$HTML_NS, 'noscript'],  
   [$HTML_NS, 'event-source'],  
   [$HTML_NS, 'command'],  
   [$HTML_NS, 'font'],  
 ];  
   
 my $HTMLStructuredInlineLevelElements = [  
   [$HTML_NS, 'blockquote'],  
   [$HTML_NS, 'pre'],  
   [$HTML_NS, 'ol'],  
   [$HTML_NS, 'ul'],  
   [$HTML_NS, 'dl'],  
   [$HTML_NS, 'table'],  
   [$HTML_NS, 'menu'],  
 ];  
79    
80  my $HTMLInteractiveElements = {  my $HTMLInteractiveElements = {
81    $HTML_NS => {a => 1, details => 1, datagrid => 1},    $HTML_NS => {a => 1, details => 1, datagrid => 1},
# Line 148  my $HTMLInteractiveElements = { Line 83  my $HTMLInteractiveElements = {
83  ## NOTE: |html:a| and |html:datagrid| are not allowed as a descendant  ## NOTE: |html:a| and |html:datagrid| are not allowed as a descendant
84  ## of interactive elements  ## of interactive elements
85    
86  my $HTMLTransparentElements = [  my $HTMLTransparentElements = {
87    [$HTML_NS, 'ins'],    $HTML_NS => {qw/ins 1 font 1 noscript 1/},
88    [$HTML_NS, 'font'],    ## NOTE: |html:noscript| is transparent if scripting is disabled.
89    [$HTML_NS, 'noscript'], ## NOTE: If scripting is disabled.  };
90  ];  
91    #my $HTMLSemiTransparentElements = {
92  #my $HTMLSemiTransparentElements = [  #  $HTML_NS => {qw/video 1 audio 1/},
93  #  [$HTML_NS, 'video'],  #};
94  #  [$HTML_NS, 'audio'],  
95  #];  my $HTMLEmbededElements = {
96      $HTML_NS => {qw/img 1 iframe 1 embed 1 object 1 video 1 audio 1 canvas 1/},
97  my $HTMLEmbededElements = [  };
   [$HTML_NS, 'img'],  
   [$HTML_NS, 'iframe'],  
   [$HTML_NS, 'embed'],  
   [$HTML_NS, 'object'],  
   [$HTML_NS, 'video'],  
   [$HTML_NS, 'audio'],  
   [$HTML_NS, 'canvas'],  
 ];  
98    
99  ## Empty  ## Empty
100  my $HTMLEmptyChecker = sub {  my $HTMLEmptyChecker = sub {
# Line 244  my $HTMLStylableBlockChecker = sub { Line 171  my $HTMLStylableBlockChecker = sub {
171        my $not_allowed = $self->{minuses}->{$node_ns}->{$node_ln};        my $not_allowed = $self->{minuses}->{$node_ns}->{$node_ln};
172        if ($node->manakai_element_type_match ($HTML_NS, 'style')) {        if ($node->manakai_element_type_match ($HTML_NS, 'style')) {
173          $not_allowed = 1 if $has_non_style;          $not_allowed = 1 if $has_non_style;
174          } elsif ($HTMLBlockLevelElements->{$node_ns}->{$node_ln}) {
175            $has_non_style = 1;
176        } else {        } else {
177          $has_non_style = 1;          $has_non_style = 1;
178          CHK: {          $not_allowed = 1;
           for (@{$HTMLBlockLevelElements}) {  
             if ($node->manakai_element_type_match ($_->[0], $_->[1])) {  
               last CHK;  
             }  
           }  
           $not_allowed = 1;  
         } # CHK  
179        }        }
180        $self->{onerror}->(node => $node, type => 'element not allowed')        $self->{onerror}->(node => $node, type => 'element not allowed')
181          if $not_allowed;          if $not_allowed;
# Line 288  my $HTMLBlockChecker = sub { Line 210  my $HTMLBlockChecker = sub {
210        $node_ns = '' unless defined $node_ns;        $node_ns = '' unless defined $node_ns;
211        my $node_ln = $node->manakai_local_name;        my $node_ln = $node->manakai_local_name;
212        my $not_allowed = $self->{minuses}->{$node_ns}->{$node_ln};        my $not_allowed = $self->{minuses}->{$node_ns}->{$node_ln};
213        CHK: {        $not_allowed = 1
214          for (@{$HTMLBlockLevelElements}) {          unless $HTMLBlockLevelElements->{$node_ns}->{$node_ln};
           if ($node->manakai_element_type_match ($_->[0], $_->[1])) {  
             last CHK;  
           }  
         }  
         $not_allowed = 1;  
       } # CHK  
215        $self->{onerror}->(node => $node, type => 'element not allowed')        $self->{onerror}->(node => $node, type => 'element not allowed')
216          if $not_allowed;          if $not_allowed;
217        my ($sib, $ch) = $self->_check_get_children ($node);        my ($sib, $ch) = $self->_check_get_children ($node);
# Line 329  my $HTMLInlineChecker = sub { Line 245  my $HTMLInlineChecker = sub {
245        $node_ns = '' unless defined $node_ns;        $node_ns = '' unless defined $node_ns;
246        my $node_ln = $node->manakai_local_name;        my $node_ln = $node->manakai_local_name;
247        my $not_allowed = $self->{minuses}->{$node_ns}->{$node_ln};        my $not_allowed = $self->{minuses}->{$node_ns}->{$node_ln};
248        CHK: {        $not_allowed = 1
249          for (@{$HTMLStrictlyInlineLevelElements},          unless $HTMLStrictlyInlineLevelElements->{$node_ns}->{$node_ln} or
250               @{$HTMLStructuredInlineLevelElements}) {            $HTMLStructuredInlineLevelElements->{$node_ns}->{$node_ln};
           if ($node->manakai_element_type_match ($_->[0], $_->[1])) {  
             last CHK;  
           }  
         }  
         $not_allowed = 1;  
       } # CHK  
251        $self->{onerror}->(node => $node, type => 'element not allowed')        $self->{onerror}->(node => $node, type => 'element not allowed')
252          if $not_allowed;          if $not_allowed;
253        my ($sib, $ch) = $self->_check_get_children ($node);        my ($sib, $ch) = $self->_check_get_children ($node);
# Line 374  my $HTMLStrictlyInlineChecker = sub { Line 284  my $HTMLStrictlyInlineChecker = sub {
284        $node_ns = '' unless defined $node_ns;        $node_ns = '' unless defined $node_ns;
285        my $node_ln = $node->manakai_local_name;        my $node_ln = $node->manakai_local_name;
286        my $not_allowed = $self->{minuses}->{$node_ns}->{$node_ln};        my $not_allowed = $self->{minuses}->{$node_ns}->{$node_ln};
287        CHK: {        $not_allowed = 1
288          for (@{$HTMLStrictlyInlineLevelElements}) {          unless $HTMLStrictlyInlineLevelElements->{$node_ns}->{$node_ln};
           if ($node->manakai_element_type_match ($_->[0], $_->[1])) {  
             last CHK;  
           }  
         }  
         $not_allowed = 1;  
       } # CHK  
289        $self->{onerror}->(node => $node, type => 'element not allowed')        $self->{onerror}->(node => $node, type => 'element not allowed')
290          if $not_allowed;          if $not_allowed;
291        my ($sib, $ch) = $self->_check_get_children ($node);        my ($sib, $ch) = $self->_check_get_children ($node);
# Line 419  my $HTMLInlineOrStrictlyInlineChecker = Line 323  my $HTMLInlineOrStrictlyInlineChecker =
323        $node_ns = '' unless defined $node_ns;        $node_ns = '' unless defined $node_ns;
324        my $node_ln = $node->manakai_local_name;        my $node_ln = $node->manakai_local_name;
325        my $not_allowed = $self->{minuses}->{$node_ns}->{$node_ln};        my $not_allowed = $self->{minuses}->{$node_ns}->{$node_ln};
326        CHK: {        if ($todo->{strictly_inline}) {
327          for (@{$HTMLStrictlyInlineLevelElements},          $not_allowed = 1
328               $todo->{strictly_inline} ? () : @{$HTMLStructuredInlineLevelElements}) {            unless $HTMLStrictlyInlineLevelElements->{$node_ns}->{$node_ln};
329            if ($node->manakai_element_type_match ($_->[0], $_->[1])) {        } else {
330              last CHK;          $not_allowed = 1
331            }            unless $HTMLStrictlyInlineLevelElements->{$node_ns}->{$node_ln} or
332          }              $HTMLStructuredInlineLevelElements->{$node_ns}->{$node_ln};
333          $not_allowed = 1;        }
       } # CHK  
334        $self->{onerror}->(node => $node, type => 'element not allowed')        $self->{onerror}->(node => $node, type => 'element not allowed')
335          if $not_allowed;          if $not_allowed;
336        my ($sib, $ch) = $self->_check_get_children ($node);        my ($sib, $ch) = $self->_check_get_children ($node);
# Line 468  my $HTMLBlockOrInlineChecker = sub { Line 371  my $HTMLBlockOrInlineChecker = sub {
371        my $node_ln = $node->manakai_local_name;        my $node_ln = $node->manakai_local_name;
372        my $not_allowed = $self->{minuses}->{$node_ns}->{$node_ln};        my $not_allowed = $self->{minuses}->{$node_ns}->{$node_ln};
373        if ($content eq 'block') {        if ($content eq 'block') {
374          CHK: {          $not_allowed = 1
375            for (@{$HTMLBlockLevelElements}) {            unless $HTMLBlockLevelElements->{$node_ns}->{$node_ln};
             if ($node->manakai_element_type_match ($_->[0], $_->[1])) {  
               last CHK;  
             }  
           }  
           $not_allowed = 1;  
         } # CHK  
376        } elsif ($content eq 'inline') {        } elsif ($content eq 'inline') {
377          CHK: {          $not_allowed = 1
378            for (@{$HTMLStrictlyInlineLevelElements},            unless $HTMLStrictlyInlineLevelElements->{$node_ns}->{$node_ln} or
379                 @{$HTMLStructuredInlineLevelElements}) {              $HTMLStructuredInlineLevelElements->{$node_ns}->{$node_ln};
             if ($node->manakai_element_type_match ($_->[0], $_->[1])) {  
               last CHK;  
             }  
           }  
           $not_allowed = 1;  
         } # CHK  
380        } else {        } else {
381          my $is_block;          my $is_block = $HTMLBlockLevelElements->{$node_ns}->{$node_ln};
382          my $is_inline;          my $is_inline
383          for (@{$HTMLBlockLevelElements}) {            = $HTMLStrictlyInlineLevelElements->{$node_ns}->{$node_ln} ||
384            if ($node->manakai_element_type_match ($_->[0], $_->[1])) {              $HTMLStructuredInlineLevelElements->{$node_ns}->{$node_ln};
             $is_block = 1;  
             last;  
           }  
         }  
           
         for (@{$HTMLStrictlyInlineLevelElements},  
              @{$HTMLStructuredInlineLevelElements}) {  
           if ($node->manakai_element_type_match ($_->[0], $_->[1])) {  
             $is_inline = 1;  
             last;  
           }  
         }  
385                    
386          push @block_not_inline, $node          push @block_not_inline, $node
387            if $is_block and not $is_inline and not $not_allowed;            if $is_block and not $is_inline and not $not_allowed;
# Line 569  my $GetHTMLZeroOrMoreThenBlockOrInlineCh Line 448  my $GetHTMLZeroOrMoreThenBlockOrInlineCh
448            $not_allowed = 1 if $has_non_style;            $not_allowed = 1 if $has_non_style;
449          } elsif ($content eq 'block') {          } elsif ($content eq 'block') {
450            $has_non_style = 1;            $has_non_style = 1;
451            CHK: {            $not_allowed = 1
452              for (@{$HTMLBlockLevelElements}) {              unless $HTMLBlockLevelElements->{$node_ns}->{$node_ln};
               if ($node->manakai_element_type_match ($_->[0], $_->[1])) {  
                 last CHK;  
               }  
             }  
             $not_allowed = 1;  
           } # CHK  
453          } elsif ($content eq 'inline') {          } elsif ($content eq 'inline') {
454            $has_non_style = 1;            $has_non_style = 1;
455            CHK: {            $not_allowed = 1
456              for (@{$HTMLStrictlyInlineLevelElements},              unless $HTMLStrictlyInlineLevelElements->{$node_ns}->{$node_ln} or
457                   @{$HTMLStructuredInlineLevelElements}) {                $HTMLStructuredInlineLevelElements->{$node_ns}->{$node_ln};
               if ($node->manakai_element_type_match ($_->[0], $_->[1])) {  
                 last CHK;  
               }  
             }  
             $not_allowed = 1;  
           } # CHK  
458          } else {          } else {
459            $has_non_style = 1;            $has_non_style = 1;
460            my $is_block;            my $is_block = $HTMLBlockLevelElements->{$node_ns}->{$node_ln};
461            my $is_inline;            my $is_inline
462            for (@{$HTMLBlockLevelElements}) {              = $HTMLStrictlyInlineLevelElements->{$node_ns}->{$node_ln} ||
463              if ($node->manakai_element_type_match ($_->[0], $_->[1])) {                $HTMLStructuredInlineLevelElements->{$node_ns}->{$node_ln};
               $is_block = 1;  
               last;  
             }  
           }  
             
           for (@{$HTMLStrictlyInlineLevelElements},  
                @{$HTMLStructuredInlineLevelElements}) {  
             if ($node->manakai_element_type_match ($_->[0], $_->[1])) {  
               $is_inline = 1;  
               last;  
             }  
           }  
464                            
465            push @block_not_inline, $node            push @block_not_inline, $node
466              if $is_block and not $is_inline and not $not_allowed;              if $is_block and not $is_inline and not $not_allowed;
# Line 758  $Element->{$HTML_NS}->{head} = { Line 613  $Element->{$HTML_NS}->{head} = {
613            } else {            } else {
614              $not_allowed = 1;              $not_allowed = 1;
615            }            }
616          } else {          } elsif ($HTMLMetadataElements->{$node_ns}->{$node_ln}) {
617            $phase = 'after base';            $phase = 'after base';
618            CHK: {          } else {
619              for (@{$HTMLMetadataElements}) {            $not_allowed = 1;
               if ($node->manakai_element_type_match ($_->[0], $_->[1])) {  
                 last CHK;  
               }  
             }  
             $not_allowed = 1;  
           } # CHK  
620          }          }
621          $self->{onerror}->(node => $node, type => 'element not allowed')          $self->{onerror}->(node => $node, type => 'element not allowed')
622            if $not_allowed;            if $not_allowed;
# Line 890  $Element->{$HTML_NS}->{footer} = { Line 739  $Element->{$HTML_NS}->{footer} = {
739            $not_allowed = 1;            $not_allowed = 1;
740          }          }
741          if ($content eq 'block') {          if ($content eq 'block') {
742            CHK: {            $not_allowed = 1
743              for (@{$HTMLBlockLevelElements}) {              unless $HTMLBlockLevelElements->{$node_ns}->{$node_ln};
               if ($node->manakai_element_type_match ($_->[0], $_->[1])) {  
                 last CHK;  
               }  
             }  
             $not_allowed = 1;  
           } # CHK  
744          } elsif ($content eq 'inline') {          } elsif ($content eq 'inline') {
745            CHK: {            $not_allowed = 1
746              for (@{$HTMLStrictlyInlineLevelElements},              unless $HTMLStrictlyInlineLevelElements->{$node_ns}->{$node_ln} or
747                   @{$HTMLStructuredInlineLevelElements}) {                $HTMLStructuredInlineLevelElements->{$node_ns}->{$node_ln};
               if ($node->manakai_element_type_match ($_->[0], $_->[1])) {  
                 last CHK;  
               }  
             }  
             $not_allowed = 1;  
           } # CHK  
748          } else {          } else {
749            my $is_block;            my $is_block = $HTMLBlockLevelElements->{$node_ns}->{$node_ln};
750            my $is_inline;            my $is_inline
751            for (@{$HTMLBlockLevelElements}) {              = $HTMLStrictlyInlineLevelElements->{$node_ns}->{$node_ln} ||
752              if ($node->manakai_element_type_match ($_->[0], $_->[1])) {                $HTMLStructuredInlineLevelElements->{$node_ns}->{$node_ln};
               $is_block = 1;  
               last;  
             }  
           }  
             
           for (@{$HTMLStrictlyInlineLevelElements},  
                @{$HTMLStructuredInlineLevelElements}) {  
             if ($node->manakai_element_type_match ($_->[0], $_->[1])) {  
               $is_inline = 1;  
               last;  
             }  
           }  
753                        
754            push @block_not_inline, $node            push @block_not_inline, $node
755              if $is_block and not $is_inline and not $not_allowed;              if $is_block and not $is_inline and not $not_allowed;
# Line 1668  $Element->{$HTML_NS}->{menu} = { Line 1493  $Element->{$HTML_NS}->{menu} = {
1493              $content = 'li';              $content = 'li';
1494            }            }
1495          } else {          } else {
1496            CHK: {            if ($HTMLStrictlyInlineLevelElements->{$node_ns}->{$node_ln} or
1497              for (@{$HTMLStrictlyInlineLevelElements},                $HTMLStructuredInlineLevelElements->{$node_ns}->{$node_ln}) {
1498                   @{$HTMLStructuredInlineLevelElements}) {              $content = 'inline';
1499                if ($node->manakai_element_type_match ($_->[0], $_->[1])) {            } else {
                 $content = 'inline';  
                 last CHK;  
               }  
             }  
1500              $not_allowed = 1;              $not_allowed = 1;
1501            } # CHK            }
1502          }          }
1503          $self->{onerror}->(node => $node, type => 'element not allowed')          $self->{onerror}->(node => $node, type => 'element not allowed')
1504            if $not_allowed;            if $not_allowed;
# Line 1807  sub _check_get_children ($$) { Line 1628  sub _check_get_children ($$) {
1628          push @$sib, $end;          push @$sib, $end;
1629        }        }
1630      }      }
1631      for (@{$HTMLTransparentElements}) {      if ($HTMLTransparentElements->{$node_ns}->{$node_ln}) {
1632        if ($node->manakai_element_type_match ($_->[0], $_->[1])) {        unshift @$sib, @{$node->child_nodes};
1633          unshift @$sib, @{$node->child_nodes};        last TP;
         last TP;  
       }  
1634      }      }
1635      if ($node->manakai_element_type_match ($HTML_NS, 'video') or      if ($node->manakai_element_type_match ($HTML_NS, 'video') or
1636          $node->manakai_element_type_match ($HTML_NS, 'audio')) {          $node->manakai_element_type_match ($HTML_NS, 'audio')) {

Legend:
Removed from v.1.6  
changed lines
  Added in v.1.7

admin@suikawiki.org
ViewVC Help
Powered by ViewVC 1.1.24