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

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

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

revision 1.196 by wakaba, Sat Oct 4 12:20:35 2008 UTC revision 1.197 by wakaba, Sat Oct 4 14:31:27 2008 UTC
# Line 4956  sub _construct_tree ($) { Line 4956  sub _construct_tree ($) {
4956    
4957    undef $self->{form_element};    undef $self->{form_element};
4958    undef $self->{head_element};    undef $self->{head_element};
4959      undef $self->{head_element_inserted};
4960    $self->{open_elements} = [];    $self->{open_elements} = [];
4961    undef $self->{inner_html_node};    undef $self->{inner_html_node};
4962    
# Line 5622  sub _tree_construction_main ($) { Line 5623  sub _tree_construction_main ($) {
5623    
5624    ## NOTE: $open_tables->[-1]->[0] is the "current table" element node.    ## NOTE: $open_tables->[-1]->[0] is the "current table" element node.
5625    ## NOTE: $open_tables->[-1]->[1] is the "tainted" flag.    ## NOTE: $open_tables->[-1]->[1] is the "tainted" flag.
5626      ## NOTE: $open_tables->[-1]->[2] is set false when non-Text node inserted.
5627    my $open_tables = [[$self->{open_elements}->[0]->[0]]];    my $open_tables = [[$self->{open_elements}->[0]->[0]]];
5628    
5629    my $formatting_end_tag = sub {    my $formatting_end_tag = sub {
# Line 5895  sub _tree_construction_main ($) { Line 5897  sub _tree_construction_main ($) {
5897      }      }
5898    }; # $insert_to_foster    }; # $insert_to_foster
5899    
5900      ## NOTE: When a character is inserted, if the last node that was
5901      ## inserted by the parser is a Text node and the character has to be
5902      ## inserted after that node, then the character is appended to the
5903      ## Text node.  However, if any other node is inserted by the parser,
5904      ## then a new Text node is created and the character is appended as
5905      ## that Text node.  If I'm not wrong, there are only two cases where
5906      ## this occurs.  One is the case where an element node is inserted
5907      ## to the |head| element.  This is covered by using the
5908      ## |$self->{head_element_inserted}| flag.  Another is the case where
5909      ## an element or comment is inserted into the |table| subtree while
5910      ## foster parenting happens.  This is covered by using the [2] flag
5911      ## of the |$open_tables| structure.  All other cases are handled
5912      ## simply by calling |manakai_append_text| method.
5913    
5914    B: while (1) {    B: while (1) {
5915      if ($token->{type} == DOCTYPE_TOKEN) {      if ($token->{type} == DOCTYPE_TOKEN) {
5916                
# Line 5942  sub _tree_construction_main ($) { Line 5958  sub _tree_construction_main ($) {
5958        } else {        } else {
5959                    
5960          $self->{open_elements}->[-1]->[0]->append_child ($comment);          $self->{open_elements}->[-1]->[0]->append_child ($comment);
5961            $open_tables->[-1]->[2] = 0 if @$open_tables; # ~node inserted
5962        }        }
5963        $token = $self->_get_next_token;        $token = $self->_get_next_token;
5964        next B;        next B;
# Line 6111  sub _tree_construction_main ($) { Line 6128  sub _tree_construction_main ($) {
6128        if ($token->{type} == CHARACTER_TOKEN) {        if ($token->{type} == CHARACTER_TOKEN) {
6129          if ($token->{data} =~ s/^([\x09\x0A\x0C\x20]+)//) {          if ($token->{data} =~ s/^([\x09\x0A\x0C\x20]+)//) {
6130            unless ($self->{insertion_mode} == BEFORE_HEAD_IM) {            unless ($self->{insertion_mode} == BEFORE_HEAD_IM) {
6131                            if ($self->{head_element_inserted}) {
6132              $self->{open_elements}->[-1]->[0]->manakai_append_text ($1);                
6133              #                $self->{open_elements}->[-1]->[0]->append_child
6134                    ($self->{document}->create_text_node ($1));
6135                  delete $self->{head_element_inserted};
6136                  ## NOTE: |</head> <link> |
6137                  #
6138                } else {
6139                  
6140                  $self->{open_elements}->[-1]->[0]->manakai_append_text ($1);
6141                  ## NOTE: |</head> &#x20;|
6142                  #
6143                }
6144            } else {            } else {
6145                            
6146              ## Ignore the token.              ## Ignore the token.
# Line 6257  sub _tree_construction_main ($) { Line 6284  sub _tree_construction_main ($) {
6284                        
6285          }          }
6286    
6287              if ($token->{tag_name} eq 'base') {          if ($token->{tag_name} eq 'base') {
6288                if ($self->{insertion_mode} == IN_HEAD_NOSCRIPT_IM) {            if ($self->{insertion_mode} == IN_HEAD_NOSCRIPT_IM) {
6289                                
6290                  ## As if </noscript>              ## As if </noscript>
6291                  pop @{$self->{open_elements}};              pop @{$self->{open_elements}};
6292                  $self->{parse_error}->(level => $self->{level}->{must}, type => 'in noscript', text => 'base',              $self->{parse_error}->(level => $self->{level}->{must}, type => 'in noscript', text => 'base',
6293                                  token => $token);                              token => $token);
6294                            
6295                  $self->{insertion_mode} = IN_HEAD_IM;              $self->{insertion_mode} = IN_HEAD_IM;
6296                  ## Reprocess in the "in head" insertion mode...              ## Reprocess in the "in head" insertion mode...
6297                } else {            } else {
6298                                
6299                }            }
6300    
6301                ## NOTE: There is a "as if in head" code clone.            ## NOTE: There is a "as if in head" code clone.
6302                if ($self->{insertion_mode} == AFTER_HEAD_IM) {            if ($self->{insertion_mode} == AFTER_HEAD_IM) {
6303                                
6304                  $self->{parse_error}->(level => $self->{level}->{must}, type => 'after head',              $self->{parse_error}->(level => $self->{level}->{must}, type => 'after head',
6305                                  text => $token->{tag_name}, token => $token);                              text => $token->{tag_name}, token => $token);
6306                  push @{$self->{open_elements}},              push @{$self->{open_elements}},
6307                      [$self->{head_element}, $el_category->{head}];                  [$self->{head_element}, $el_category->{head}];
6308                } else {              $self->{head_element_inserted} = 1;
6309                              } else {
6310                }              
6311                            }
6312              
6313      {      {
6314        my $el;        my $el;
6315                
# Line 6306  sub _tree_construction_main ($) { Line 6334  sub _tree_construction_main ($) {
6334        push @{$self->{open_elements}}, [$el, $el_category->{$token->{tag_name}} || 0];        push @{$self->{open_elements}}, [$el, $el_category->{$token->{tag_name}} || 0];
6335      }      }
6336        
6337                pop @{$self->{open_elements}};            pop @{$self->{open_elements}};
6338                pop @{$self->{open_elements}} # <head>            pop @{$self->{open_elements}} # <head>
6339                    if $self->{insertion_mode} == AFTER_HEAD_IM;                if $self->{insertion_mode} == AFTER_HEAD_IM;
6340                            
6341                $token = $self->_get_next_token;            $token = $self->_get_next_token;
6342                next B;            next B;
6343          } elsif ($token->{tag_name} eq 'link') {          } elsif ($token->{tag_name} eq 'link') {
6344            ## NOTE: There is a "as if in head" code clone.            ## NOTE: There is a "as if in head" code clone.
6345            if ($self->{insertion_mode} == AFTER_HEAD_IM) {            if ($self->{insertion_mode} == AFTER_HEAD_IM) {
# Line 6320  sub _tree_construction_main ($) { Line 6348  sub _tree_construction_main ($) {
6348                              text => $token->{tag_name}, token => $token);                              text => $token->{tag_name}, token => $token);
6349              push @{$self->{open_elements}},              push @{$self->{open_elements}},
6350                  [$self->{head_element}, $el_category->{head}];                  [$self->{head_element}, $el_category->{head}];
6351                $self->{head_element_inserted} = 1;
6352            } else {            } else {
6353                            
6354            }            }
# Line 6400  sub _tree_construction_main ($) { Line 6429  sub _tree_construction_main ($) {
6429                            
6430              #              #
6431            }            }
6432              } elsif ($token->{tag_name} eq 'meta') {          } elsif ($token->{tag_name} eq 'meta') {
6433                ## NOTE: There is a "as if in head" code clone.            ## NOTE: There is a "as if in head" code clone.
6434                if ($self->{insertion_mode} == AFTER_HEAD_IM) {            if ($self->{insertion_mode} == AFTER_HEAD_IM) {
6435                                
6436                  $self->{parse_error}->(level => $self->{level}->{must}, type => 'after head',              $self->{parse_error}->(level => $self->{level}->{must}, type => 'after head',
6437                                  text => $token->{tag_name}, token => $token);                              text => $token->{tag_name}, token => $token);
6438                  push @{$self->{open_elements}},              push @{$self->{open_elements}},
6439                      [$self->{head_element}, $el_category->{head}];                  [$self->{head_element}, $el_category->{head}];
6440                } else {              $self->{head_element_inserted} = 1;
6441                              } else {
6442                }              
6443                            }
6444              
6445      {      {
6446        my $el;        my $el;
6447                
# Line 6436  sub _tree_construction_main ($) { Line 6466  sub _tree_construction_main ($) {
6466        push @{$self->{open_elements}}, [$el, $el_category->{$token->{tag_name}} || 0];        push @{$self->{open_elements}}, [$el, $el_category->{$token->{tag_name}} || 0];
6467      }      }
6468        
6469                my $meta_el = pop @{$self->{open_elements}};            my $meta_el = pop @{$self->{open_elements}};
6470    
6471                unless ($self->{confident}) {                unless ($self->{confident}) {
6472                  if ($token->{attributes}->{charset}) {                  if ($token->{attributes}->{charset}) {
# Line 6494  sub _tree_construction_main ($) { Line 6524  sub _tree_construction_main ($) {
6524                delete $self->{self_closing};                delete $self->{self_closing};
6525                $token = $self->_get_next_token;                $token = $self->_get_next_token;
6526                next B;                next B;
6527              } elsif ($token->{tag_name} eq 'title') {          } elsif ($token->{tag_name} eq 'title') {
6528                if ($self->{insertion_mode} == IN_HEAD_NOSCRIPT_IM) {            if ($self->{insertion_mode} == IN_HEAD_NOSCRIPT_IM) {
6529                                
6530                  ## As if </noscript>              ## As if </noscript>
6531                  pop @{$self->{open_elements}};              pop @{$self->{open_elements}};
6532                  $self->{parse_error}->(level => $self->{level}->{must}, type => 'in noscript', text => 'title',              $self->{parse_error}->(level => $self->{level}->{must}, type => 'in noscript', text => 'title',
6533                                  token => $token);                              token => $token);
6534                            
6535                  $self->{insertion_mode} = IN_HEAD_IM;              $self->{insertion_mode} = IN_HEAD_IM;
6536                  ## Reprocess in the "in head" insertion mode...              ## Reprocess in the "in head" insertion mode...
6537                } elsif ($self->{insertion_mode} == AFTER_HEAD_IM) {            } elsif ($self->{insertion_mode} == AFTER_HEAD_IM) {
6538                                
6539                  $self->{parse_error}->(level => $self->{level}->{must}, type => 'after head',              $self->{parse_error}->(level => $self->{level}->{must}, type => 'after head',
6540                                  text => $token->{tag_name}, token => $token);                              text => $token->{tag_name}, token => $token);
6541                  push @{$self->{open_elements}},              push @{$self->{open_elements}},
6542                      [$self->{head_element}, $el_category->{head}];                  [$self->{head_element}, $el_category->{head}];
6543                } else {              $self->{head_element_inserted} = 1;
6544                              } else {
6545                }              
6546              }
6547    
6548                ## NOTE: There is a "as if in head" code clone.            ## NOTE: There is a "as if in head" code clone.
6549                my $parent = defined $self->{head_element} ? $self->{head_element}            $parse_rcdata->(RCDATA_CONTENT_MODEL);
6550                    : $self->{open_elements}->[-1]->[0];            pop @{$self->{open_elements}} # <head>
6551                $parse_rcdata->(RCDATA_CONTENT_MODEL);                if $self->{insertion_mode} == AFTER_HEAD_IM;
6552                pop @{$self->{open_elements}} # <head>            next B;
6553                    if $self->{insertion_mode} == AFTER_HEAD_IM;          } elsif ($token->{tag_name} eq 'style' or
6554                next B;                   $token->{tag_name} eq 'noframes') {
6555              } elsif ($token->{tag_name} eq 'style' or            ## NOTE: Or (scripting is enabled and tag_name eq 'noscript' and
6556                       $token->{tag_name} eq 'noframes') {            ## insertion mode IN_HEAD_IM)
6557                ## NOTE: Or (scripting is enabled and tag_name eq 'noscript' and            ## NOTE: There is a "as if in head" code clone.
6558                ## insertion mode IN_HEAD_IM)            if ($self->{insertion_mode} == AFTER_HEAD_IM) {
6559                ## NOTE: There is a "as if in head" code clone.              
6560                if ($self->{insertion_mode} == AFTER_HEAD_IM) {              $self->{parse_error}->(level => $self->{level}->{must}, type => 'after head',
6561                                                text => $token->{tag_name}, token => $token);
6562                  $self->{parse_error}->(level => $self->{level}->{must}, type => 'after head',              push @{$self->{open_elements}},
6563                                  text => $token->{tag_name}, token => $token);                  [$self->{head_element}, $el_category->{head}];
6564                  push @{$self->{open_elements}},              $self->{head_element_inserted} = 1;
6565                      [$self->{head_element}, $el_category->{head}];            } else {
6566                } else {              
6567                              }
6568                }            $parse_rcdata->(CDATA_CONTENT_MODEL);
6569                $parse_rcdata->(CDATA_CONTENT_MODEL);            pop @{$self->{open_elements}} # <head>
6570                pop @{$self->{open_elements}} # <head>                if $self->{insertion_mode} == AFTER_HEAD_IM;
6571                    if $self->{insertion_mode} == AFTER_HEAD_IM;            next B;
               next B;  
6572              } elsif ($token->{tag_name} eq 'noscript') {              } elsif ($token->{tag_name} eq 'noscript') {
6573                if ($self->{insertion_mode} == IN_HEAD_IM) {                if ($self->{insertion_mode} == IN_HEAD_IM) {
6574                                    
# Line 6584  sub _tree_construction_main ($) { Line 6614  sub _tree_construction_main ($) {
6614                                    
6615                  #                  #
6616                }                }
6617              } elsif ($token->{tag_name} eq 'script') {          } elsif ($token->{tag_name} eq 'script') {
6618                if ($self->{insertion_mode} == IN_HEAD_NOSCRIPT_IM) {            if ($self->{insertion_mode} == IN_HEAD_NOSCRIPT_IM) {
6619                                
6620                  ## As if </noscript>              ## As if </noscript>
6621                  pop @{$self->{open_elements}};              pop @{$self->{open_elements}};
6622                  $self->{parse_error}->(level => $self->{level}->{must}, type => 'in noscript', text => 'script',              $self->{parse_error}->(level => $self->{level}->{must}, type => 'in noscript', text => 'script',
6623                                  token => $token);                              token => $token);
6624                            
6625                  $self->{insertion_mode} = IN_HEAD_IM;              $self->{insertion_mode} = IN_HEAD_IM;
6626                  ## Reprocess in the "in head" insertion mode...              ## Reprocess in the "in head" insertion mode...
6627                } elsif ($self->{insertion_mode} == AFTER_HEAD_IM) {            } elsif ($self->{insertion_mode} == AFTER_HEAD_IM) {
6628                                
6629                  $self->{parse_error}->(level => $self->{level}->{must}, type => 'after head',              $self->{parse_error}->(level => $self->{level}->{must}, type => 'after head',
6630                                  text => $token->{tag_name}, token => $token);                              text => $token->{tag_name}, token => $token);
6631                  push @{$self->{open_elements}},              push @{$self->{open_elements}},
6632                      [$self->{head_element}, $el_category->{head}];                  [$self->{head_element}, $el_category->{head}];
6633                } else {              $self->{head_element_inserted} = 1;
6634                              } else {
6635                }              
6636              }
6637    
6638                ## NOTE: There is a "as if in head" code clone.            ## NOTE: There is a "as if in head" code clone.
6639                $script_start_tag->();            $script_start_tag->();
6640                pop @{$self->{open_elements}} # <head>            pop @{$self->{open_elements}} # <head>
6641                    if $self->{insertion_mode} == AFTER_HEAD_IM;                if $self->{insertion_mode} == AFTER_HEAD_IM;
6642                next B;            next B;
6643              } elsif ($token->{tag_name} eq 'body' or          } elsif ($token->{tag_name} eq 'body' or
6644                       $token->{tag_name} eq 'frameset') {                   $token->{tag_name} eq 'frameset') {
6645                if ($self->{insertion_mode} == IN_HEAD_NOSCRIPT_IM) {                if ($self->{insertion_mode} == IN_HEAD_NOSCRIPT_IM) {
6646                                    
6647                  ## As if </noscript>                  ## As if </noscript>
# Line 7403  sub _tree_construction_main ($) { Line 7434  sub _tree_construction_main ($) {
7434    
7435          $self->{parse_error}->(level => $self->{level}->{must}, type => 'in table:#text', token => $token);          $self->{parse_error}->(level => $self->{level}->{must}, type => 'in table:#text', token => $token);
7436    
7437              ## As if in body, but insert into foster parent element          ## NOTE: As if in body, but insert into the foster parent element.
7438              ## ISSUE: Spec says that "whenever a node would be inserted          $reconstruct_active_formatting_elements->($insert_to_foster);
7439              ## into the current node" while characters might not be              
7440              ## result in a new Text node.          if ($self->{open_elements}->[-1]->[1] & TABLE_ROWS_EL) {
7441              $reconstruct_active_formatting_elements->($insert_to_foster);            # MUST
7442                          my $foster_parent_element;
7443              if ($self->{open_elements}->[-1]->[1] & TABLE_ROWS_EL) {            my $next_sibling;
7444                # MUST            my $prev_sibling;
7445                my $foster_parent_element;            OE: for (reverse 0..$#{$self->{open_elements}}) {
7446                my $next_sibling;              if ($self->{open_elements}->[$_]->[1] & TABLE_EL) {
7447                my $prev_sibling;                my $parent = $self->{open_elements}->[$_]->[0]->parent_node;
7448                OE: for (reverse 0..$#{$self->{open_elements}}) {                if (defined $parent and $parent->node_type == 1) {
7449                  if ($self->{open_elements}->[$_]->[1] & TABLE_EL) {                  $foster_parent_element = $parent;
                   my $parent = $self->{open_elements}->[$_]->[0]->parent_node;  
                   if (defined $parent and $parent->node_type == 1) {  
                       
                     $foster_parent_element = $parent;  
                     $next_sibling = $self->{open_elements}->[$_]->[0];  
                     $prev_sibling = $next_sibling->previous_sibling;  
                   } else {  
                       
                     $foster_parent_element = $self->{open_elements}->[$_ - 1]->[0];  
                     $prev_sibling = $foster_parent_element->last_child;  
                   }  
                   last OE;  
                 }  
               } # OE  
               $foster_parent_element = $self->{open_elements}->[0]->[0] and  
               $prev_sibling = $foster_parent_element->last_child  
                 unless defined $foster_parent_element;  
               if (defined $prev_sibling and  
                   $prev_sibling->node_type == 3) {  
7450                                    
7451                  $prev_sibling->manakai_append_text ($token->{data});                  $next_sibling = $self->{open_elements}->[$_]->[0];
7452                    $prev_sibling = $next_sibling->previous_sibling;
7453                    #
7454                } else {                } else {
7455                                    
7456                  $foster_parent_element->insert_before                  $foster_parent_element = $self->{open_elements}->[$_ - 1]->[0];
7457                    ($self->{document}->create_text_node ($token->{data}),                  $prev_sibling = $foster_parent_element->last_child;
7458                     $next_sibling);                  #
7459                }                }
7460                  last OE;
7461                }
7462              } # OE
7463              $foster_parent_element = $self->{open_elements}->[0]->[0] and
7464              $prev_sibling = $foster_parent_element->last_child
7465                  unless defined $foster_parent_element;
7466              undef $prev_sibling unless $open_tables->[-1]->[2]; # ~node inserted
7467              if (defined $prev_sibling and
7468                  $prev_sibling->node_type == 3) {
7469                
7470                $prev_sibling->manakai_append_text ($token->{data});
7471              } else {
7472                
7473                $foster_parent_element->insert_before
7474                    ($self->{document}->create_text_node ($token->{data}),
7475                     $next_sibling);
7476              }
7477            $open_tables->[-1]->[1] = 1; # tainted            $open_tables->[-1]->[1] = 1; # tainted
7478              $open_tables->[-1]->[2] = 1; # ~node inserted
7479          } else {          } else {
7480              ## NOTE: Fragment case or in a foster parent'ed element
7481              ## (e.g. |<table><span>a|).  In fragment case, whether the
7482              ## character is appended to existing node or a new node is
7483              ## created is irrelevant, since the foster parent'ed nodes
7484              ## are discarded and fragment parsing does not invoke any
7485              ## script.
7486                        
7487            $self->{open_elements}->[-1]->[0]->manakai_append_text ($token->{data});            $self->{open_elements}->[-1]->[0]->manakai_append_text
7488                  ($token->{data});
7489          }          }
7490                            
7491          $token = $self->_get_next_token;          $token = $self->_get_next_token;
# Line 7498  sub _tree_construction_main ($) { Line 7537  sub _tree_construction_main ($) {
7537                pop @{$self->{open_elements}};                pop @{$self->{open_elements}};
7538              }              }
7539                                    
7540                  $self->{insertion_mode} = IN_ROW_IM;              $self->{insertion_mode} = IN_ROW_IM;
7541                  if ($token->{tag_name} eq 'tr') {              if ($token->{tag_name} eq 'tr') {
7542                                    
7543                                    
7544      {      {
7545        my $el;        my $el;
7546                
# Line 7526  sub _tree_construction_main ($) { Line 7565  sub _tree_construction_main ($) {
7565        push @{$self->{open_elements}}, [$el, $el_category->{$token->{tag_name}} || 0];        push @{$self->{open_elements}}, [$el, $el_category->{$token->{tag_name}} || 0];
7566      }      }
7567        
7568                                    $open_tables->[-1]->[2] = 0 if @$open_tables; # ~node inserted
7569                    $token = $self->_get_next_token;                
7570                    next B;                $token = $self->_get_next_token;
7571                  } else {                next B;
7572                                  } else {
7573                                    
7574                  
7575      {      {
7576        my $el;        my $el;
7577                
# Line 7547  sub _tree_construction_main ($) { Line 7587  sub _tree_construction_main ($) {
7587        push @{$self->{open_elements}}, [$el, $el_category->{'tr'} || 0];        push @{$self->{open_elements}}, [$el, $el_category->{'tr'} || 0];
7588      }      }
7589        
7590                    ## reprocess in the "in row" insertion mode                ## reprocess in the "in row" insertion mode
7591                  }              }
7592                } else {            } else {
7593                                
7594                }            }
7595    
7596                ## Clear back to table row context                ## Clear back to table row context
7597                while (not ($self->{open_elements}->[-1]->[1]                while (not ($self->{open_elements}->[-1]->[1]
# Line 7560  sub _tree_construction_main ($) { Line 7600  sub _tree_construction_main ($) {
7600                  pop @{$self->{open_elements}};                  pop @{$self->{open_elements}};
7601                }                }
7602                                
7603                            
7604      {      {
7605        my $el;        my $el;
7606                
# Line 7585  sub _tree_construction_main ($) { Line 7625  sub _tree_construction_main ($) {
7625        push @{$self->{open_elements}}, [$el, $el_category->{$token->{tag_name}} || 0];        push @{$self->{open_elements}}, [$el, $el_category->{$token->{tag_name}} || 0];
7626      }      }
7627        
7628                $self->{insertion_mode} = IN_CELL_IM;            $open_tables->[-1]->[2] = 0 if @$open_tables; # ~node inserted
7629              $self->{insertion_mode} = IN_CELL_IM;
7630    
7631                push @$active_formatting_elements, ['#marker', ''];            push @$active_formatting_elements, ['#marker', ''];
7632                                
7633              
7634              $token = $self->_get_next_token;
7635              next B;
7636            } elsif ({
7637                      caption => 1, col => 1, colgroup => 1,
7638                      tbody => 1, tfoot => 1, thead => 1,
7639                      tr => 1, # $self->{insertion_mode} == IN_ROW_IM
7640                     }->{$token->{tag_name}}) {
7641              if ($self->{insertion_mode} == IN_ROW_IM) {
7642                ## As if </tr>
7643                ## have an element in table scope
7644                my $i;
7645                INSCOPE: for (reverse 0..$#{$self->{open_elements}}) {
7646                  my $node = $self->{open_elements}->[$_];
7647                  if ($node->[1] & TABLE_ROW_EL) {
7648                    
7649                    $i = $_;
7650                    last INSCOPE;
7651                  } elsif ($node->[1] & TABLE_SCOPING_EL) {
7652                    
7653                    last INSCOPE;
7654                  }
7655                } # INSCOPE
7656                unless (defined $i) {
7657                  
7658                  ## TODO: This type is wrong.
7659                  $self->{parse_error}->(level => $self->{level}->{must}, type => 'unmacthed end tag',
7660                                  text => $token->{tag_name}, token => $token);
7661                  ## Ignore the token
7662                                
7663                $token = $self->_get_next_token;                $token = $self->_get_next_token;
7664                next B;                next B;
7665              } elsif ({              }
                       caption => 1, col => 1, colgroup => 1,  
                       tbody => 1, tfoot => 1, thead => 1,  
                       tr => 1, # $self->{insertion_mode} == IN_ROW_IM  
                      }->{$token->{tag_name}}) {  
               if ($self->{insertion_mode} == IN_ROW_IM) {  
                 ## As if </tr>  
                 ## have an element in table scope  
                 my $i;  
                 INSCOPE: for (reverse 0..$#{$self->{open_elements}}) {  
                   my $node = $self->{open_elements}->[$_];  
                   if ($node->[1] & TABLE_ROW_EL) {  
                       
                     $i = $_;  
                     last INSCOPE;  
                   } elsif ($node->[1] & TABLE_SCOPING_EL) {  
                       
                     last INSCOPE;  
                   }  
                 } # INSCOPE  
                 unless (defined $i) {  
                     
 ## TODO: This type is wrong.  
                   $self->{parse_error}->(level => $self->{level}->{must}, type => 'unmacthed end tag',  
                                   text => $token->{tag_name}, token => $token);  
                   ## Ignore the token  
                     
                   $token = $self->_get_next_token;  
                   next B;  
                 }  
7666                                    
7667                  ## Clear back to table row context                  ## Clear back to table row context
7668                  while (not ($self->{open_elements}->[-1]->[1]                  while (not ($self->{open_elements}->[-1]->[1]
# Line 7691  sub _tree_construction_main ($) { Line 7732  sub _tree_construction_main ($) {
7732                                    
7733                }                }
7734    
7735                if ($token->{tag_name} eq 'col') {            if ($token->{tag_name} eq 'col') {
7736                  ## Clear back to table context              ## Clear back to table context
7737                  while (not ($self->{open_elements}->[-1]->[1]              while (not ($self->{open_elements}->[-1]->[1]
7738                                  & TABLE_SCOPING_EL)) {                              & TABLE_SCOPING_EL)) {
7739                                    
7740                    ## ISSUE: Can this state be reached?                ## ISSUE: Can this state be reached?
7741                    pop @{$self->{open_elements}};                pop @{$self->{open_elements}};
7742                  }              }
7743                                
7744                                
7745      {      {
7746        my $el;        my $el;
7747                
# Line 7716  sub _tree_construction_main ($) { Line 7757  sub _tree_construction_main ($) {
7757        push @{$self->{open_elements}}, [$el, $el_category->{'colgroup'} || 0];        push @{$self->{open_elements}}, [$el, $el_category->{'colgroup'} || 0];
7758      }      }
7759        
7760                  $self->{insertion_mode} = IN_COLUMN_GROUP_IM;              $self->{insertion_mode} = IN_COLUMN_GROUP_IM;
7761                  ## reprocess              ## reprocess
7762                                $open_tables->[-1]->[2] = 0 if @$open_tables; # ~node inserted
7763                  next B;              
7764                } elsif ({              next B;
7765                          caption => 1,            } elsif ({
7766                          colgroup => 1,                      caption => 1,
7767                          tbody => 1, tfoot => 1, thead => 1,                      colgroup => 1,
7768                         }->{$token->{tag_name}}) {                      tbody => 1, tfoot => 1, thead => 1,
7769                  ## Clear back to table context                     }->{$token->{tag_name}}) {
7770                ## Clear back to table context
7771                  while (not ($self->{open_elements}->[-1]->[1]                  while (not ($self->{open_elements}->[-1]->[1]
7772                                  & TABLE_SCOPING_EL)) {                                  & TABLE_SCOPING_EL)) {
7773                                        
# Line 7733  sub _tree_construction_main ($) { Line 7775  sub _tree_construction_main ($) {
7775                    pop @{$self->{open_elements}};                    pop @{$self->{open_elements}};
7776                  }                  }
7777                                    
7778                  push @$active_formatting_elements, ['#marker', '']              push @$active_formatting_elements, ['#marker', '']
7779                      if $token->{tag_name} eq 'caption';                  if $token->{tag_name} eq 'caption';
                   
7780                                    
7781                
7782      {      {
7783        my $el;        my $el;
7784                
# Line 7761  sub _tree_construction_main ($) { Line 7803  sub _tree_construction_main ($) {
7803        push @{$self->{open_elements}}, [$el, $el_category->{$token->{tag_name}} || 0];        push @{$self->{open_elements}}, [$el, $el_category->{$token->{tag_name}} || 0];
7804      }      }
7805        
7806                  $self->{insertion_mode} = {              $open_tables->[-1]->[2] = 0 if @$open_tables; # ~node inserted
7807                                             caption => IN_CAPTION_IM,              $self->{insertion_mode} = {
7808                                             colgroup => IN_COLUMN_GROUP_IM,                                         caption => IN_CAPTION_IM,
7809                                             tbody => IN_TABLE_BODY_IM,                                         colgroup => IN_COLUMN_GROUP_IM,
7810                                             tfoot => IN_TABLE_BODY_IM,                                         tbody => IN_TABLE_BODY_IM,
7811                                             thead => IN_TABLE_BODY_IM,                                         tfoot => IN_TABLE_BODY_IM,
7812                                            }->{$token->{tag_name}};                                         thead => IN_TABLE_BODY_IM,
7813                  $token = $self->_get_next_token;                                        }->{$token->{tag_name}};
7814                                $token = $self->_get_next_token;
7815                  next B;              
7816                } else {              next B;
7817                  die "$0: in table: <>: $token->{tag_name}";            } else {
7818                }              die "$0: in table: <>: $token->{tag_name}";
7819              }
7820              } elsif ($token->{tag_name} eq 'table') {              } elsif ($token->{tag_name} eq 'table') {
7821                $self->{parse_error}->(level => $self->{level}->{must}, type => 'not closed',                $self->{parse_error}->(level => $self->{level}->{must}, type => 'not closed',
7822                                text => $self->{open_elements}->[-1]->[0]                                text => $self->{open_elements}->[-1]->[0]
# Line 7836  sub _tree_construction_main ($) { Line 7879  sub _tree_construction_main ($) {
7879                            
7880              ## NOTE: This is a "as if in head" code clone.              ## NOTE: This is a "as if in head" code clone.
7881              $parse_rcdata->(CDATA_CONTENT_MODEL);              $parse_rcdata->(CDATA_CONTENT_MODEL);
7882                $open_tables->[-1]->[2] = 0 if @$open_tables; # ~node inserted
7883              next B;              next B;
7884            } else {            } else {
7885                            
# Line 7846  sub _tree_construction_main ($) { Line 7890  sub _tree_construction_main ($) {
7890                            
7891              ## NOTE: This is a "as if in head" code clone.              ## NOTE: This is a "as if in head" code clone.
7892              $script_start_tag->();              $script_start_tag->();
7893                $open_tables->[-1]->[2] = 0 if @$open_tables; # ~node inserted
7894              next B;              next B;
7895            } else {            } else {
7896                            
# Line 7885  sub _tree_construction_main ($) { Line 7930  sub _tree_construction_main ($) {
7930        push @{$self->{open_elements}}, [$el, $el_category->{$token->{tag_name}} || 0];        push @{$self->{open_elements}}, [$el, $el_category->{$token->{tag_name}} || 0];
7931      }      }
7932        
7933                    $open_tables->[-1]->[2] = 0 if @$open_tables; # ~node inserted
7934    
7935                  ## TODO: form element pointer                  ## TODO: form element pointer
7936    
# Line 10706  sub set_inner_html ($$$$;$) { Line 10752  sub set_inner_html ($$$$;$) {
10752      push @{$p->{open_elements}}, [$root, $el_category->{html}];      push @{$p->{open_elements}}, [$root, $el_category->{html}];
10753    
10754      undef $p->{head_element};      undef $p->{head_element};
10755        undef $p->{head_element_inserted};
10756    
10757      ## Step 6 # MUST      ## Step 6 # MUST
10758      $p->_reset_insertion_mode;      $p->_reset_insertion_mode;

Legend:
Removed from v.1.196  
changed lines
  Added in v.1.197

[email protected]
ViewVC Help
Powered by ViewVC 1.1.24