/[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.31 by wakaba, Mon Jun 25 00:14:39 2007 UTC revision 1.32 by wakaba, Mon Jun 25 12:39:11 2007 UTC
# Line 957  my $HTMLAttrChecker = { Line 957  my $HTMLAttrChecker = {
957    },    },
958    dir => $GetHTMLEnumeratedAttrChecker->({ltr => 1, rtl => 1}),    dir => $GetHTMLEnumeratedAttrChecker->({ltr => 1, rtl => 1}),
959    class => $HTMLUnorderedSetOfSpaceSeparatedTokensAttrChecker,    class => $HTMLUnorderedSetOfSpaceSeparatedTokensAttrChecker,
960      contextmenu => sub {
961        my ($self, $attr) = @_;
962        my $value = $attr->value;
963        push @{$self->{contextmenu}}, [$value => $attr];
964        ## ISSUE: "The value must be the ID of a menu element in the DOM."
965        ## What is "in the DOM"?  A menu Element node that is not part
966        ## of the Document tree is in the DOM?  A menu Element node that
967        ## belong to another Document tree is in the DOM?
968      },
969    irrelevant => $GetHTMLBooleanAttrChecker->('irrelevant'),    irrelevant => $GetHTMLBooleanAttrChecker->('irrelevant'),
970    tabindex => $HTMLIntegerAttrChecker,    tabindex => $HTMLIntegerAttrChecker,
971  };  };
# Line 988  my $GetHTMLAttrsChecker = sub { Line 997  my $GetHTMLAttrsChecker = sub {
997        $checker ||= $AttrChecker->{$attr_ns}->{$attr_ln}        $checker ||= $AttrChecker->{$attr_ns}->{$attr_ln}
998          || $AttrChecker->{$attr_ns}->{''};          || $AttrChecker->{$attr_ns}->{''};
999        if ($checker) {        if ($checker) {
1000          $checker->($self, $attr);          $checker->($self, $attr, $todo);
1001        } else {        } else {
1002          $self->{onerror}->(node => $attr, type => 'attribute not supported');          $self->{onerror}->(node => $attr, type => 'attribute not supported');
1003          ## ISSUE: No comformance createria for unknown attributes in the spec          ## ISSUE: No comformance createria for unknown attributes in the spec
# Line 1774  $Element->{$HTML_NS}->{a} = { Line 1783  $Element->{$HTML_NS}->{a} = {
1783      my ($self, $todo) = @_;      my ($self, $todo) = @_;
1784    
1785      my $end = $self->_add_minuses ($HTMLInteractiveElements);      my $end = $self->_add_minuses ($HTMLInteractiveElements);
1786      my ($sib, $ch)      my ($new_todos, $ch)
1787        = $HTMLSignificantInlineOrStrictlyInlineChecker->($self, $todo);        = $HTMLSignificantInlineOrStrictlyInlineChecker->($self, $todo);
1788      push @$sib, $end;      push @$new_todos, $end;
1789      return ($sib, $ch);  
1790        $_->{flag}->{has_a} = 1 for @$new_todos;
1791    
1792        return ($new_todos, $ch);
1793    },    },
1794  };  };
1795    
# Line 2004  $Element->{$HTML_NS}->{img} = { Line 2016  $Element->{$HTML_NS}->{img} = {
2016        alt => sub { }, ## NOTE: No syntactical requirement        alt => sub { }, ## NOTE: No syntactical requirement
2017        src => $HTMLURIAttrChecker,        src => $HTMLURIAttrChecker,
2018        usemap => $HTMLUsemapAttrChecker,        usemap => $HTMLUsemapAttrChecker,
2019        ismap => $GetHTMLBooleanAttrChecker->('ismap'), ## TODO: MUST ancestor <a>        ismap => sub {
2020            my ($self, $attr, $parent_todo) = @_;
2021            if (not $todo->{flag}->{has_a}) {
2022              $self->{onerror}->(node => $attr, type => 'attribute not allowed');
2023            }
2024            $GetHTMLBooleanAttrChecker->('ismap')->($self, $attr, $parent_todo);
2025          },
2026        ## TODO: height        ## TODO: height
2027        ## TODO: width        ## TODO: width
2028      })->($self, $todo);      })->($self, $todo);
# Line 2680  $Element->{$HTML_NS}->{datagrid} = { Line 2698  $Element->{$HTML_NS}->{datagrid} = {
2698    }),    }),
2699    checker => sub {    checker => sub {
2700      my ($self, $todo) = @_;      my ($self, $todo) = @_;
2701        my $el = $todo->{node};
2702        my $new_todos = [];
2703        my @nodes = (@{$el->child_nodes});
2704    
2705      my $end = $self->_add_minuses ({$HTML_NS => {a => 1, datagrid => 1}});      my $end = $self->_add_minuses ({$HTML_NS => {a => 1, datagrid => 1}});
2706      my ($sib, $ch) = $HTMLBlockChecker->($self, $todo);      
2707      ## TODO: (Block-table)+ | table | select | datalist      ## Block-table Block* | table | select | datalist | Empty
2708      push @$sib, $end;      my $mode = 'any';
2709      return ($sib, $ch);      while (@nodes) {
2710          my $node = shift @nodes;
2711          $self->_remove_minuses ($node) and next if ref $node eq 'HASH';
2712          
2713          my $nt = $node->node_type;
2714          if ($nt == 1) {
2715            my $node_ns = $node->namespace_uri;
2716            $node_ns = '' unless defined $node_ns;
2717            my $node_ln = $node->manakai_local_name;
2718            my $not_allowed = $self->{minuses}->{$node_ns}->{$node_ln};
2719            if ($mode eq 'block') {
2720              $not_allowed = 1
2721                  unless $HTMLBlockLevelElements->{$node_ns}->{$node_ln};
2722            } elsif ($mode eq 'any') {
2723              if ($node_ns eq $HTML_NS and
2724                  {table => 1, select => 1, datalist => 1}->{$node_ln}) {
2725                $mode = 'none';
2726              } elsif ($HTMLBlockLevelElements->{$node_ns}->{$node_ln}) {
2727                $mode = 'block';
2728              } else {
2729                $not_allowed = 1;
2730              }
2731            } else {
2732              $not_allowed = 1;
2733            }
2734            $self->{onerror}->(node => $node, type => 'element not allowed')
2735                if $not_allowed;
2736            my ($sib, $ch) = $self->_check_get_children ($node, $todo);
2737            unshift @nodes, @$sib;
2738            push @$new_todos, @$ch;
2739          } elsif ($nt == 3 or $nt == 4) {
2740            if ($node->data =~ /[^\x09-\x0D\x20]/) {
2741              $self->{onerror}->(node => $node, type => 'character not allowed');
2742            }
2743          } elsif ($nt == 5) {
2744            unshift @nodes, @{$node->child_nodes};
2745          }
2746        }
2747    
2748        push @$new_todos, $end;
2749        return ($new_todos);
2750    },    },
2751  };  };
2752    
2753  $Element->{$HTML_NS}->{command} = {  $Element->{$HTML_NS}->{command} = {
2754    attrs_checker => $GetHTMLAttrsChecker->({}), ## TODO    attrs_checker => $GetHTMLAttrsChecker->({
2755        checked => $GetHTMLBooleanAttrChecker->('checked'),
2756        default => $GetHTMLBooleanAttrChecker->('default'),
2757        disabled => $GetHTMLBooleanAttrChecker->('disabled'),
2758        hidden => $GetHTMLBooleanAttrChecker->('hidden'),
2759        icon => $HTMLURIAttrChecker,
2760        label => sub { }, ## NOTE: No conformance creteria
2761        radiogroup => sub { }, ## NOTE: No conformance creteria
2762        ## NOTE: |title| has special semantics, but no syntactical difference
2763        type => sub {
2764          my ($self, $attr) = @_;
2765          my $value = $attr->value;
2766          unless ({command => 1, checkbox => 1, radio => 1}->{$value}) {
2767            $self->{onerror}->(node => $attr, type => 'attribute value not allowed');
2768          }
2769        },
2770      }),
2771    checker => $HTMLEmptyChecker,    checker => $HTMLEmptyChecker,
2772  };  };
2773    
2774  $Element->{$HTML_NS}->{menu} = {  $Element->{$HTML_NS}->{menu} = {
2775    attrs_checker => $GetHTMLAttrsChecker->({}), ## TODO    attrs_checker => $GetHTMLAttrsChecker->({
2776        autosubmit => $GetHTMLBooleanAttrChecker->('autosubmit'),
2777        id => sub {
2778          ## NOTE: same as global |id=""|, with |$self->{menu}| registeration
2779          my ($self, $attr) = @_;
2780          my $value = $attr->value;
2781          if (length $value > 0) {
2782            if ($self->{id}->{$value}) {
2783              $self->{onerror}->(node => $attr, type => 'duplicate ID');
2784            } else {
2785              $self->{id}->{$value} = 1;
2786            }
2787          } else {
2788            ## NOTE: MUST contain at least one character
2789            $self->{onerror}->(node => $attr, type => 'attribute value is empty');
2790          }
2791          if ($value =~ /[\x09-\x0D\x20]/) {
2792            $self->{onerror}->(node => $attr, type => 'space in ID');
2793          }
2794          $self->{menu}->{$value} ||= $attr;
2795          ## ISSUE: <menu id=""><p contextmenu=""> match?
2796        },
2797        label => sub { }, ## NOTE: No conformance creteria
2798        type => $GetHTMLEnumeratedAttrChecker->({context => 1, toolbar => 1}),
2799      }),
2800    checker => sub {    checker => sub {
2801      my ($self, $todo) = @_;      my ($self, $todo) = @_;
2802      my $el = $todo->{node};      my $el = $todo->{node};
# Line 2827  sub check_element ($$$) { Line 2928  sub check_element ($$$) {
2928    $self->{id} = {};    $self->{id} = {};
2929    $self->{term} = {};    $self->{term} = {};
2930    $self->{usemap} = [];    $self->{usemap} = [];
2931      $self->{contextmenu} = [];
2932    $self->{map} = {};    $self->{map} = {};
2933      $self->{menu} = {};
2934    $self->{has_link_type} = {};    $self->{has_link_type} = {};
2935    
2936    my @todo = ({type => 'element', node => $el});    my @todo = ({type => 'element', node => $el});
# Line 2878  sub check_element ($$$) { Line 2981  sub check_element ($$$) {
2981      }      }
2982    }    }
2983    
2984      for (@{$self->{contextmenu}}) {
2985        unless ($self->{menu}->{$_->[0]}) {
2986          $self->{onerror}->(node => $_->[1], type => 'no referenced menu');
2987        }
2988      }
2989    
2990    delete $self->{minuses};    delete $self->{minuses};
2991    delete $self->{onerror};    delete $self->{onerror};
2992    delete $self->{id};    delete $self->{id};

Legend:
Removed from v.1.31  
changed lines
  Added in v.1.32

admin@suikawiki.org
ViewVC Help
Powered by ViewVC 1.1.24