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

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

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

revision 1.194 by wakaba, Sat Oct 4 05:53:45 2008 UTC revision 1.202 by wakaba, Sat Oct 4 14:31:28 2008 UTC
# Line 86  sub ALL_END_TAG_OPTIONAL_EL () { Line 86  sub ALL_END_TAG_OPTIONAL_EL () {
86    LI_EL |    LI_EL |
87    P_EL |    P_EL |
88    
89      ## ISSUE: option, optgroup, rt, rp?
90    
91    BODY_EL |    BODY_EL |
92    HTML_EL |    HTML_EL |
93    TABLE_CELL_EL |    TABLE_CELL_EL |
# Line 130  sub SPECIAL_EL () { Line 132  sub SPECIAL_EL () {
132    FORM_EL |    FORM_EL |
133    FRAMESET_EL |    FRAMESET_EL |
134    HEADING_EL |    HEADING_EL |
   OPTION_EL |  
   OPTGROUP_EL |  
135    SELECT_EL |    SELECT_EL |
136    TABLE_ROW_EL |    TABLE_ROW_EL |
137    TABLE_ROW_GROUP_EL |    TABLE_ROW_GROUP_EL |
# Line 249  my $el_category_f = { Line 249  my $el_category_f = {
249      mtext => FOREIGN_FLOW_CONTENT_EL,      mtext => FOREIGN_FLOW_CONTENT_EL,
250    },    },
251    $SVG_NS => {    $SVG_NS => {
252      foreignObject => FOREIGN_FLOW_CONTENT_EL,      foreignObject => FOREIGN_FLOW_CONTENT_EL | MISC_SCOPING_EL,
253      desc => FOREIGN_FLOW_CONTENT_EL,      desc => FOREIGN_FLOW_CONTENT_EL,
254      title => FOREIGN_FLOW_CONTENT_EL,      title => FOREIGN_FLOW_CONTENT_EL,
255    },    },
# Line 488  sub parse_byte_stream ($$$$;$$) { Line 488  sub parse_byte_stream ($$$$;$$) {
488      if (defined $charset_name) {      if (defined $charset_name) {
489        $charset = Message::Charset::Info->get_by_html_name ($charset_name);        $charset = Message::Charset::Info->get_by_html_name ($charset_name);
490    
       ## ISSUE: Unsupported encoding is not ignored according to the spec.  
491        require Whatpm::Charset::DecodeHandle;        require Whatpm::Charset::DecodeHandle;
492        $buffer = Whatpm::Charset::DecodeHandle::ByteBuffer->new        $buffer = Whatpm::Charset::DecodeHandle::ByteBuffer->new
493            ($byte_stream);            ($byte_stream);
# Line 2485  sub _get_next_token ($) { Line 2484  sub _get_next_token ($) {
2484          !!!cp (160);          !!!cp (160);
2485          $self->{ct}->{name} = chr $self->{nc};          $self->{ct}->{name} = chr $self->{nc};
2486          delete $self->{ct}->{quirks};          delete $self->{ct}->{quirks};
 ## ISSUE: "Set the token's name name to the" in the spec  
2487          $self->{state} = DOCTYPE_NAME_STATE;          $self->{state} = DOCTYPE_NAME_STATE;
2488          !!!next-input-character;          !!!next-input-character;
2489          redo A;          redo A;
# Line 3478  sub _construct_tree ($) { Line 3476  sub _construct_tree ($) {
3476    
3477    undef $self->{form_element};    undef $self->{form_element};
3478    undef $self->{head_element};    undef $self->{head_element};
3479      undef $self->{head_element_inserted};
3480    $self->{open_elements} = [];    $self->{open_elements} = [];
3481    undef $self->{inner_html_node};    undef $self->{inner_html_node};
3482    
# Line 3785  sub _tree_construction_root_element ($) Line 3784  sub _tree_construction_root_element ($)
3784      ## NOTE: Reprocess the token.      ## NOTE: Reprocess the token.
3785      !!!ack-later;      !!!ack-later;
3786      return; ## Go to the "before head" insertion mode.      return; ## Go to the "before head" insertion mode.
   
     ## ISSUE: There is an issue in the spec  
3787    } # B    } # B
3788    
3789    die "$0: _tree_construction_root_element: This should never be reached";    die "$0: _tree_construction_root_element: This should never be reached";
# Line 4087  sub _tree_construction_main ($) { Line 4084  sub _tree_construction_main ($) {
4084    
4085    ## NOTE: $open_tables->[-1]->[0] is the "current table" element node.    ## NOTE: $open_tables->[-1]->[0] is the "current table" element node.
4086    ## NOTE: $open_tables->[-1]->[1] is the "tainted" flag.    ## NOTE: $open_tables->[-1]->[1] is the "tainted" flag.
4087      ## NOTE: $open_tables->[-1]->[2] is set false when non-Text node inserted.
4088    my $open_tables = [[$self->{open_elements}->[0]->[0]]];    my $open_tables = [[$self->{open_elements}->[0]->[0]]];
4089    
4090    my $formatting_end_tag = sub {    my $formatting_end_tag = sub {
# Line 4360  sub _tree_construction_main ($) { Line 4358  sub _tree_construction_main ($) {
4358      }      }
4359    }; # $insert_to_foster    }; # $insert_to_foster
4360    
4361      ## NOTE: When a character is inserted, if the last node that was
4362      ## inserted by the parser is a Text node and the character has to be
4363      ## inserted after that node, then the character is appended to the
4364      ## Text node.  However, if any other node is inserted by the parser,
4365      ## then a new Text node is created and the character is appended as
4366      ## that Text node.  If I'm not wrong, there are only two cases where
4367      ## this occurs.  One is the case where an element node is inserted
4368      ## to the |head| element.  This is covered by using the
4369      ## |$self->{head_element_inserted}| flag.  Another is the case where
4370      ## an element or comment is inserted into the |table| subtree while
4371      ## foster parenting happens.  This is covered by using the [2] flag
4372      ## of the |$open_tables| structure.  All other cases are handled
4373      ## simply by calling |manakai_append_text| method.
4374    
4375    B: while (1) {    B: while (1) {
4376      if ($token->{type} == DOCTYPE_TOKEN) {      if ($token->{type} == DOCTYPE_TOKEN) {
4377        !!!cp ('t73');        !!!cp ('t73');
# Line 4407  sub _tree_construction_main ($) { Line 4419  sub _tree_construction_main ($) {
4419        } else {        } else {
4420          !!!cp ('t87');          !!!cp ('t87');
4421          $self->{open_elements}->[-1]->[0]->append_child ($comment);          $self->{open_elements}->[-1]->[0]->append_child ($comment);
4422            $open_tables->[-1]->[2] = 0 if @$open_tables; # ~node inserted
4423        }        }
4424        !!!next-token;        !!!next-token;
4425        next B;        next B;
# Line 4522  sub _tree_construction_main ($) { Line 4535  sub _tree_construction_main ($) {
4535          pop @{$self->{open_elements}}          pop @{$self->{open_elements}}
4536              while $self->{open_elements}->[-1]->[1] & FOREIGN_EL;              while $self->{open_elements}->[-1]->[1] & FOREIGN_EL;
4537    
4538            ## NOTE: |<span><svg>| ... two parse errors, |<svg>| ... a parse error.
4539    
4540          $self->{insertion_mode} &= ~ IN_FOREIGN_CONTENT_IM;          $self->{insertion_mode} &= ~ IN_FOREIGN_CONTENT_IM;
4541          ## Reprocess.          ## Reprocess.
4542          next B;          next B;
# Line 4534  sub _tree_construction_main ($) { Line 4549  sub _tree_construction_main ($) {
4549        if ($token->{type} == CHARACTER_TOKEN) {        if ($token->{type} == CHARACTER_TOKEN) {
4550          if ($token->{data} =~ s/^([\x09\x0A\x0C\x20]+)//) {          if ($token->{data} =~ s/^([\x09\x0A\x0C\x20]+)//) {
4551            unless ($self->{insertion_mode} == BEFORE_HEAD_IM) {            unless ($self->{insertion_mode} == BEFORE_HEAD_IM) {
4552              !!!cp ('t88.2');              if ($self->{head_element_inserted}) {
4553              $self->{open_elements}->[-1]->[0]->manakai_append_text ($1);                !!!cp ('t88.3');
4554              #                $self->{open_elements}->[-1]->[0]->append_child
4555                    ($self->{document}->create_text_node ($1));
4556                  delete $self->{head_element_inserted};
4557                  ## NOTE: |</head> <link> |
4558                  #
4559                } else {
4560                  !!!cp ('t88.2');
4561                  $self->{open_elements}->[-1]->[0]->manakai_append_text ($1);
4562                  ## NOTE: |</head> &#x20;|
4563                  #
4564                }
4565            } else {            } else {
4566              !!!cp ('t88.1');              !!!cp ('t88.1');
4567              ## Ignore the token.              ## Ignore the token.
# Line 4632  sub _tree_construction_main ($) { Line 4657  sub _tree_construction_main ($) {
4657            !!!cp ('t97');            !!!cp ('t97');
4658          }          }
4659    
4660              if ($token->{tag_name} eq 'base') {          if ($token->{tag_name} eq 'base') {
4661                if ($self->{insertion_mode} == IN_HEAD_NOSCRIPT_IM) {            if ($self->{insertion_mode} == IN_HEAD_NOSCRIPT_IM) {
4662                  !!!cp ('t98');              !!!cp ('t98');
4663                  ## As if </noscript>              ## As if </noscript>
4664                  pop @{$self->{open_elements}};              pop @{$self->{open_elements}};
4665                  !!!parse-error (type => 'in noscript', text => 'base',              !!!parse-error (type => 'in noscript', text => 'base',
4666                                  token => $token);                              token => $token);
4667                            
4668                  $self->{insertion_mode} = IN_HEAD_IM;              $self->{insertion_mode} = IN_HEAD_IM;
4669                  ## Reprocess in the "in head" insertion mode...              ## Reprocess in the "in head" insertion mode...
4670                } else {            } else {
4671                  !!!cp ('t99');              !!!cp ('t99');
4672                }            }
4673    
4674                ## NOTE: There is a "as if in head" code clone.            ## NOTE: There is a "as if in head" code clone.
4675                if ($self->{insertion_mode} == AFTER_HEAD_IM) {            if ($self->{insertion_mode} == AFTER_HEAD_IM) {
4676                  !!!cp ('t100');              !!!cp ('t100');
4677                  !!!parse-error (type => 'after head',              !!!parse-error (type => 'after head',
4678                                  text => $token->{tag_name}, token => $token);                              text => $token->{tag_name}, token => $token);
4679                  push @{$self->{open_elements}},              push @{$self->{open_elements}},
4680                      [$self->{head_element}, $el_category->{head}];                  [$self->{head_element}, $el_category->{head}];
4681                } else {              $self->{head_element_inserted} = 1;
4682                  !!!cp ('t101');            } else {
4683                }              !!!cp ('t101');
4684                !!!insert-element ($token->{tag_name}, $token->{attributes}, $token);            }
4685                pop @{$self->{open_elements}};            !!!insert-element ($token->{tag_name}, $token->{attributes}, $token);
4686                pop @{$self->{open_elements}} # <head>            pop @{$self->{open_elements}};
4687                    if $self->{insertion_mode} == AFTER_HEAD_IM;            pop @{$self->{open_elements}} # <head>
4688                !!!nack ('t101.1');                if $self->{insertion_mode} == AFTER_HEAD_IM;
4689                !!!next-token;            !!!nack ('t101.1');
4690                next B;            !!!next-token;
4691              next B;
4692          } elsif ($token->{tag_name} eq 'link') {          } elsif ($token->{tag_name} eq 'link') {
4693            ## NOTE: There is a "as if in head" code clone.            ## NOTE: There is a "as if in head" code clone.
4694            if ($self->{insertion_mode} == AFTER_HEAD_IM) {            if ($self->{insertion_mode} == AFTER_HEAD_IM) {
# Line 4671  sub _tree_construction_main ($) { Line 4697  sub _tree_construction_main ($) {
4697                              text => $token->{tag_name}, token => $token);                              text => $token->{tag_name}, token => $token);
4698              push @{$self->{open_elements}},              push @{$self->{open_elements}},
4699                  [$self->{head_element}, $el_category->{head}];                  [$self->{head_element}, $el_category->{head}];
4700                $self->{head_element_inserted} = 1;
4701            } else {            } else {
4702              !!!cp ('t103');              !!!cp ('t103');
4703            }            }
# Line 4703  sub _tree_construction_main ($) { Line 4730  sub _tree_construction_main ($) {
4730              !!!cp ('t103.3');              !!!cp ('t103.3');
4731              #              #
4732            }            }
4733              } elsif ($token->{tag_name} eq 'meta') {          } elsif ($token->{tag_name} eq 'meta') {
4734                ## NOTE: There is a "as if in head" code clone.            ## NOTE: There is a "as if in head" code clone.
4735                if ($self->{insertion_mode} == AFTER_HEAD_IM) {            if ($self->{insertion_mode} == AFTER_HEAD_IM) {
4736                  !!!cp ('t104');              !!!cp ('t104');
4737                  !!!parse-error (type => 'after head',              !!!parse-error (type => 'after head',
4738                                  text => $token->{tag_name}, token => $token);                              text => $token->{tag_name}, token => $token);
4739                  push @{$self->{open_elements}},              push @{$self->{open_elements}},
4740                      [$self->{head_element}, $el_category->{head}];                  [$self->{head_element}, $el_category->{head}];
4741                } else {              $self->{head_element_inserted} = 1;
4742                  !!!cp ('t105');            } else {
4743                }              !!!cp ('t105');
4744                !!!insert-element ($token->{tag_name}, $token->{attributes}, $token);            }
4745                my $meta_el = pop @{$self->{open_elements}}; ## ISSUE: This step is missing in the spec.            !!!insert-element ($token->{tag_name}, $token->{attributes}, $token);
4746              my $meta_el = pop @{$self->{open_elements}};
4747    
4748                unless ($self->{confident}) {                unless ($self->{confident}) {
4749                  if ($token->{attributes}->{charset}) {                  if ($token->{attributes}->{charset}) {
# Line 4773  sub _tree_construction_main ($) { Line 4801  sub _tree_construction_main ($) {
4801                !!!ack ('t110.1');                !!!ack ('t110.1');
4802                !!!next-token;                !!!next-token;
4803                next B;                next B;
4804              } elsif ($token->{tag_name} eq 'title') {          } elsif ($token->{tag_name} eq 'title') {
4805                if ($self->{insertion_mode} == IN_HEAD_NOSCRIPT_IM) {            if ($self->{insertion_mode} == IN_HEAD_NOSCRIPT_IM) {
4806                  !!!cp ('t111');              !!!cp ('t111');
4807                  ## As if </noscript>              ## As if </noscript>
4808                  pop @{$self->{open_elements}};              pop @{$self->{open_elements}};
4809                  !!!parse-error (type => 'in noscript', text => 'title',              !!!parse-error (type => 'in noscript', text => 'title',
4810                                  token => $token);                              token => $token);
4811                            
4812                  $self->{insertion_mode} = IN_HEAD_IM;              $self->{insertion_mode} = IN_HEAD_IM;
4813                  ## Reprocess in the "in head" insertion mode...              ## Reprocess in the "in head" insertion mode...
4814                } elsif ($self->{insertion_mode} == AFTER_HEAD_IM) {            } elsif ($self->{insertion_mode} == AFTER_HEAD_IM) {
4815                  !!!cp ('t112');              !!!cp ('t112');
4816                  !!!parse-error (type => 'after head',              !!!parse-error (type => 'after head',
4817                                  text => $token->{tag_name}, token => $token);                              text => $token->{tag_name}, token => $token);
4818                  push @{$self->{open_elements}},              push @{$self->{open_elements}},
4819                      [$self->{head_element}, $el_category->{head}];                  [$self->{head_element}, $el_category->{head}];
4820                } else {              $self->{head_element_inserted} = 1;
4821                  !!!cp ('t113');            } else {
4822                }              !!!cp ('t113');
4823              }
4824    
4825                ## NOTE: There is a "as if in head" code clone.            ## NOTE: There is a "as if in head" code clone.
4826                my $parent = defined $self->{head_element} ? $self->{head_element}            $parse_rcdata->(RCDATA_CONTENT_MODEL);
4827                    : $self->{open_elements}->[-1]->[0];            pop @{$self->{open_elements}} # <head>
4828                $parse_rcdata->(RCDATA_CONTENT_MODEL);                if $self->{insertion_mode} == AFTER_HEAD_IM;
4829                pop @{$self->{open_elements}} # <head>            next B;
4830                    if $self->{insertion_mode} == AFTER_HEAD_IM;          } elsif ($token->{tag_name} eq 'style' or
4831                next B;                   $token->{tag_name} eq 'noframes') {
4832              } elsif ($token->{tag_name} eq 'style' or            ## NOTE: Or (scripting is enabled and tag_name eq 'noscript' and
4833                       $token->{tag_name} eq 'noframes') {            ## insertion mode IN_HEAD_IM)
4834                ## NOTE: Or (scripting is enabled and tag_name eq 'noscript' and            ## NOTE: There is a "as if in head" code clone.
4835                ## insertion mode IN_HEAD_IM)            if ($self->{insertion_mode} == AFTER_HEAD_IM) {
4836                ## NOTE: There is a "as if in head" code clone.              !!!cp ('t114');
4837                if ($self->{insertion_mode} == AFTER_HEAD_IM) {              !!!parse-error (type => 'after head',
4838                  !!!cp ('t114');                              text => $token->{tag_name}, token => $token);
4839                  !!!parse-error (type => 'after head',              push @{$self->{open_elements}},
4840                                  text => $token->{tag_name}, token => $token);                  [$self->{head_element}, $el_category->{head}];
4841                  push @{$self->{open_elements}},              $self->{head_element_inserted} = 1;
4842                      [$self->{head_element}, $el_category->{head}];            } else {
4843                } else {              !!!cp ('t115');
4844                  !!!cp ('t115');            }
4845                }            $parse_rcdata->(CDATA_CONTENT_MODEL);
4846                $parse_rcdata->(CDATA_CONTENT_MODEL);            pop @{$self->{open_elements}} # <head>
4847                pop @{$self->{open_elements}} # <head>                if $self->{insertion_mode} == AFTER_HEAD_IM;
4848                    if $self->{insertion_mode} == AFTER_HEAD_IM;            next B;
               next B;  
4849              } elsif ($token->{tag_name} eq 'noscript') {              } elsif ($token->{tag_name} eq 'noscript') {
4850                if ($self->{insertion_mode} == IN_HEAD_IM) {                if ($self->{insertion_mode} == IN_HEAD_IM) {
4851                  !!!cp ('t116');                  !!!cp ('t116');
# Line 4839  sub _tree_construction_main ($) { Line 4867  sub _tree_construction_main ($) {
4867                  !!!cp ('t118');                  !!!cp ('t118');
4868                  #                  #
4869                }                }
4870              } elsif ($token->{tag_name} eq 'script') {          } elsif ($token->{tag_name} eq 'script') {
4871                if ($self->{insertion_mode} == IN_HEAD_NOSCRIPT_IM) {            if ($self->{insertion_mode} == IN_HEAD_NOSCRIPT_IM) {
4872                  !!!cp ('t119');              !!!cp ('t119');
4873                  ## As if </noscript>              ## As if </noscript>
4874                  pop @{$self->{open_elements}};              pop @{$self->{open_elements}};
4875                  !!!parse-error (type => 'in noscript', text => 'script',              !!!parse-error (type => 'in noscript', text => 'script',
4876                                  token => $token);                              token => $token);
4877                            
4878                  $self->{insertion_mode} = IN_HEAD_IM;              $self->{insertion_mode} = IN_HEAD_IM;
4879                  ## Reprocess in the "in head" insertion mode...              ## Reprocess in the "in head" insertion mode...
4880                } elsif ($self->{insertion_mode} == AFTER_HEAD_IM) {            } elsif ($self->{insertion_mode} == AFTER_HEAD_IM) {
4881                  !!!cp ('t120');              !!!cp ('t120');
4882                  !!!parse-error (type => 'after head',              !!!parse-error (type => 'after head',
4883                                  text => $token->{tag_name}, token => $token);                              text => $token->{tag_name}, token => $token);
4884                  push @{$self->{open_elements}},              push @{$self->{open_elements}},
4885                      [$self->{head_element}, $el_category->{head}];                  [$self->{head_element}, $el_category->{head}];
4886                } else {              $self->{head_element_inserted} = 1;
4887                  !!!cp ('t121');            } else {
4888                }              !!!cp ('t121');
4889              }
4890    
4891                ## NOTE: There is a "as if in head" code clone.            ## NOTE: There is a "as if in head" code clone.
4892                $script_start_tag->();            $script_start_tag->();
4893                pop @{$self->{open_elements}} # <head>            pop @{$self->{open_elements}} # <head>
4894                    if $self->{insertion_mode} == AFTER_HEAD_IM;                if $self->{insertion_mode} == AFTER_HEAD_IM;
4895                next B;            next B;
4896              } elsif ($token->{tag_name} eq 'body' or          } elsif ($token->{tag_name} eq 'body' or
4897                       $token->{tag_name} eq 'frameset') {                   $token->{tag_name} eq 'frameset') {
4898                if ($self->{insertion_mode} == IN_HEAD_NOSCRIPT_IM) {                if ($self->{insertion_mode} == IN_HEAD_NOSCRIPT_IM) {
4899                  !!!cp ('t122');                  !!!cp ('t122');
4900                  ## As if </noscript>                  ## As if </noscript>
# Line 5172  sub _tree_construction_main ($) { Line 5201  sub _tree_construction_main ($) {
5201        } else {        } else {
5202          die "$0: $token->{type}: Unknown token type";          die "$0: $token->{type}: Unknown token type";
5203        }        }
   
           ## ISSUE: An issue in the spec.  
5204      } elsif ($self->{insertion_mode} & BODY_IMS) {      } elsif ($self->{insertion_mode} & BODY_IMS) {
5205            if ($token->{type} == CHARACTER_TOKEN) {            if ($token->{type} == CHARACTER_TOKEN) {
5206              !!!cp ('t150');              !!!cp ('t150');
# Line 5559  sub _tree_construction_main ($) { Line 5586  sub _tree_construction_main ($) {
5586    
5587          !!!parse-error (type => 'in table:#text', token => $token);          !!!parse-error (type => 'in table:#text', token => $token);
5588    
5589              ## As if in body, but insert into foster parent element          ## NOTE: As if in body, but insert into the foster parent element.
5590              ## ISSUE: Spec says that "whenever a node would be inserted          $reconstruct_active_formatting_elements->($insert_to_foster);
             ## into the current node" while characters might not be  
             ## result in a new Text node.  
             $reconstruct_active_formatting_elements->($insert_to_foster);  
5591                            
5592              if ($self->{open_elements}->[-1]->[1] & TABLE_ROWS_EL) {          if ($self->{open_elements}->[-1]->[1] & TABLE_ROWS_EL) {
5593                # MUST            # MUST
5594                my $foster_parent_element;            my $foster_parent_element;
5595                my $next_sibling;            my $next_sibling;
5596                my $prev_sibling;            my $prev_sibling;
5597                OE: for (reverse 0..$#{$self->{open_elements}}) {            OE: for (reverse 0..$#{$self->{open_elements}}) {
5598                  if ($self->{open_elements}->[$_]->[1] & TABLE_EL) {              if ($self->{open_elements}->[$_]->[1] & TABLE_EL) {
5599                    my $parent = $self->{open_elements}->[$_]->[0]->parent_node;                my $parent = $self->{open_elements}->[$_]->[0]->parent_node;
5600                    if (defined $parent and $parent->node_type == 1) {                if (defined $parent and $parent->node_type == 1) {
5601                      !!!cp ('t196');                  $foster_parent_element = $parent;
5602                      $foster_parent_element = $parent;                  !!!cp ('t196');
5603                      $next_sibling = $self->{open_elements}->[$_]->[0];                  $next_sibling = $self->{open_elements}->[$_]->[0];
5604                      $prev_sibling = $next_sibling->previous_sibling;                  $prev_sibling = $next_sibling->previous_sibling;
5605                    } else {                  #
                     !!!cp ('t197');  
                     $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) {  
                 !!!cp ('t198');  
                 $prev_sibling->manakai_append_text ($token->{data});  
5606                } else {                } else {
5607                  !!!cp ('t199');                  !!!cp ('t197');
5608                  $foster_parent_element->insert_before                  $foster_parent_element = $self->{open_elements}->[$_ - 1]->[0];
5609                    ($self->{document}->create_text_node ($token->{data}),                  $prev_sibling = $foster_parent_element->last_child;
5610                     $next_sibling);                  #
5611                }                }
5612                  last OE;
5613                }
5614              } # OE
5615              $foster_parent_element = $self->{open_elements}->[0]->[0] and
5616              $prev_sibling = $foster_parent_element->last_child
5617                  unless defined $foster_parent_element;
5618              undef $prev_sibling unless $open_tables->[-1]->[2]; # ~node inserted
5619              if (defined $prev_sibling and
5620                  $prev_sibling->node_type == 3) {
5621                !!!cp ('t198');
5622                $prev_sibling->manakai_append_text ($token->{data});
5623              } else {
5624                !!!cp ('t199');
5625                $foster_parent_element->insert_before
5626                    ($self->{document}->create_text_node ($token->{data}),
5627                     $next_sibling);
5628              }
5629            $open_tables->[-1]->[1] = 1; # tainted            $open_tables->[-1]->[1] = 1; # tainted
5630              $open_tables->[-1]->[2] = 1; # ~node inserted
5631          } else {          } else {
5632              ## NOTE: Fragment case or in a foster parent'ed element
5633              ## (e.g. |<table><span>a|).  In fragment case, whether the
5634              ## character is appended to existing node or a new node is
5635              ## created is irrelevant, since the foster parent'ed nodes
5636              ## are discarded and fragment parsing does not invoke any
5637              ## script.
5638            !!!cp ('t200');            !!!cp ('t200');
5639            $self->{open_elements}->[-1]->[0]->manakai_append_text ($token->{data});            $self->{open_elements}->[-1]->[0]->manakai_append_text
5640                  ($token->{data});
5641          }          }
5642                            
5643          !!!next-token;          !!!next-token;
# Line 5639  sub _tree_construction_main ($) { Line 5674  sub _tree_construction_main ($) {
5674                pop @{$self->{open_elements}};                pop @{$self->{open_elements}};
5675              }              }
5676                                    
5677                  $self->{insertion_mode} = IN_ROW_IM;              $self->{insertion_mode} = IN_ROW_IM;
5678                  if ($token->{tag_name} eq 'tr') {              if ($token->{tag_name} eq 'tr') {
5679                    !!!cp ('t204');                !!!cp ('t204');
5680                    !!!insert-element ($token->{tag_name}, $token->{attributes}, $token);                !!!insert-element ($token->{tag_name}, $token->{attributes}, $token);
5681                    !!!nack ('t204');                $open_tables->[-1]->[2] = 0 if @$open_tables; # ~node inserted
5682                    !!!next-token;                !!!nack ('t204');
5683                    next B;                !!!next-token;
5684                  } else {                next B;
5685                    !!!cp ('t205');              } else {
5686                    !!!insert-element ('tr',, $token);                !!!cp ('t205');
5687                    ## reprocess in the "in row" insertion mode                !!!insert-element ('tr',, $token);
5688                  }                ## reprocess in the "in row" insertion mode
5689                } else {              }
5690                  !!!cp ('t206');            } else {
5691                }              !!!cp ('t206');
5692              }
5693    
5694                ## Clear back to table row context                ## Clear back to table row context
5695                while (not ($self->{open_elements}->[-1]->[1]                while (not ($self->{open_elements}->[-1]->[1]
# Line 5662  sub _tree_construction_main ($) { Line 5698  sub _tree_construction_main ($) {
5698                  pop @{$self->{open_elements}};                  pop @{$self->{open_elements}};
5699                }                }
5700                                
5701                !!!insert-element ($token->{tag_name}, $token->{attributes}, $token);            !!!insert-element ($token->{tag_name}, $token->{attributes}, $token);
5702                $self->{insertion_mode} = IN_CELL_IM;            $open_tables->[-1]->[2] = 0 if @$open_tables; # ~node inserted
5703              $self->{insertion_mode} = IN_CELL_IM;
5704    
5705                push @$active_formatting_elements, ['#marker', ''];            push @$active_formatting_elements, ['#marker', ''];
5706                                
5707                !!!nack ('t207.1');            !!!nack ('t207.1');
5708              !!!next-token;
5709              next B;
5710            } elsif ({
5711                      caption => 1, col => 1, colgroup => 1,
5712                      tbody => 1, tfoot => 1, thead => 1,
5713                      tr => 1, # $self->{insertion_mode} == IN_ROW_IM
5714                     }->{$token->{tag_name}}) {
5715              if ($self->{insertion_mode} == IN_ROW_IM) {
5716                ## As if </tr>
5717                ## have an element in table scope
5718                my $i;
5719                INSCOPE: for (reverse 0..$#{$self->{open_elements}}) {
5720                  my $node = $self->{open_elements}->[$_];
5721                  if ($node->[1] & TABLE_ROW_EL) {
5722                    !!!cp ('t208');
5723                    $i = $_;
5724                    last INSCOPE;
5725                  } elsif ($node->[1] & TABLE_SCOPING_EL) {
5726                    !!!cp ('t209');
5727                    last INSCOPE;
5728                  }
5729                } # INSCOPE
5730                unless (defined $i) {
5731                  !!!cp ('t210');
5732                  ## TODO: This type is wrong.
5733                  !!!parse-error (type => 'unmacthed end tag',
5734                                  text => $token->{tag_name}, token => $token);
5735                  ## Ignore the token
5736                  !!!nack ('t210.1');
5737                !!!next-token;                !!!next-token;
5738                next B;                next B;
5739              } 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) {  
                     !!!cp ('t208');  
                     $i = $_;  
                     last INSCOPE;  
                   } elsif ($node->[1] & TABLE_SCOPING_EL) {  
                     !!!cp ('t209');  
                     last INSCOPE;  
                   }  
                 } # INSCOPE  
                 unless (defined $i) {  
                   !!!cp ('t210');  
 ## TODO: This type is wrong.  
                   !!!parse-error (type => 'unmacthed end tag',  
                                   text => $token->{tag_name}, token => $token);  
                   ## Ignore the token  
                   !!!nack ('t210.1');  
                   !!!next-token;  
                   next B;  
                 }  
5740                                    
5741                  ## Clear back to table row context                  ## Clear back to table row context
5742                  while (not ($self->{open_elements}->[-1]->[1]                  while (not ($self->{open_elements}->[-1]->[1]
# Line 5769  sub _tree_construction_main ($) { Line 5806  sub _tree_construction_main ($) {
5806                  !!!cp ('t218');                  !!!cp ('t218');
5807                }                }
5808    
5809                if ($token->{tag_name} eq 'col') {            if ($token->{tag_name} eq 'col') {
5810                  ## Clear back to table context              ## Clear back to table context
5811                  while (not ($self->{open_elements}->[-1]->[1]              while (not ($self->{open_elements}->[-1]->[1]
5812                                  & TABLE_SCOPING_EL)) {                              & TABLE_SCOPING_EL)) {
5813                    !!!cp ('t219');                !!!cp ('t219');
5814                    ## ISSUE: Can this state be reached?                ## ISSUE: Can this state be reached?
5815                    pop @{$self->{open_elements}};                pop @{$self->{open_elements}};
5816                  }              }
5817                                
5818                  !!!insert-element ('colgroup',, $token);              !!!insert-element ('colgroup',, $token);
5819                  $self->{insertion_mode} = IN_COLUMN_GROUP_IM;              $self->{insertion_mode} = IN_COLUMN_GROUP_IM;
5820                  ## reprocess              ## reprocess
5821                  !!!ack-later;              $open_tables->[-1]->[2] = 0 if @$open_tables; # ~node inserted
5822                  next B;              !!!ack-later;
5823                } elsif ({              next B;
5824                          caption => 1,            } elsif ({
5825                          colgroup => 1,                      caption => 1,
5826                          tbody => 1, tfoot => 1, thead => 1,                      colgroup => 1,
5827                         }->{$token->{tag_name}}) {                      tbody => 1, tfoot => 1, thead => 1,
5828                  ## Clear back to table context                     }->{$token->{tag_name}}) {
5829                ## Clear back to table context
5830                  while (not ($self->{open_elements}->[-1]->[1]                  while (not ($self->{open_elements}->[-1]->[1]
5831                                  & TABLE_SCOPING_EL)) {                                  & TABLE_SCOPING_EL)) {
5832                    !!!cp ('t220');                    !!!cp ('t220');
# Line 5796  sub _tree_construction_main ($) { Line 5834  sub _tree_construction_main ($) {
5834                    pop @{$self->{open_elements}};                    pop @{$self->{open_elements}};
5835                  }                  }
5836                                    
5837                  push @$active_formatting_elements, ['#marker', '']              push @$active_formatting_elements, ['#marker', '']
5838                      if $token->{tag_name} eq 'caption';                  if $token->{tag_name} eq 'caption';
5839                                    
5840                  !!!insert-element ($token->{tag_name}, $token->{attributes}, $token);              !!!insert-element ($token->{tag_name}, $token->{attributes}, $token);
5841                  $self->{insertion_mode} = {              $open_tables->[-1]->[2] = 0 if @$open_tables; # ~node inserted
5842                                             caption => IN_CAPTION_IM,              $self->{insertion_mode} = {
5843                                             colgroup => IN_COLUMN_GROUP_IM,                                         caption => IN_CAPTION_IM,
5844                                             tbody => IN_TABLE_BODY_IM,                                         colgroup => IN_COLUMN_GROUP_IM,
5845                                             tfoot => IN_TABLE_BODY_IM,                                         tbody => IN_TABLE_BODY_IM,
5846                                             thead => IN_TABLE_BODY_IM,                                         tfoot => IN_TABLE_BODY_IM,
5847                                            }->{$token->{tag_name}};                                         thead => IN_TABLE_BODY_IM,
5848                  !!!next-token;                                        }->{$token->{tag_name}};
5849                  !!!nack ('t220.1');              !!!next-token;
5850                  next B;              !!!nack ('t220.1');
5851                } else {              next B;
5852                  die "$0: in table: <>: $token->{tag_name}";            } else {
5853                }              die "$0: in table: <>: $token->{tag_name}";
5854              }
5855              } elsif ($token->{tag_name} eq 'table') {              } elsif ($token->{tag_name} eq 'table') {
5856                !!!parse-error (type => 'not closed',                !!!parse-error (type => 'not closed',
5857                                text => $self->{open_elements}->[-1]->[0]                                text => $self->{open_elements}->[-1]->[0]
# Line 5875  sub _tree_construction_main ($) { Line 5914  sub _tree_construction_main ($) {
5914              !!!cp ('t227.8');              !!!cp ('t227.8');
5915              ## NOTE: This is a "as if in head" code clone.              ## NOTE: This is a "as if in head" code clone.
5916              $parse_rcdata->(CDATA_CONTENT_MODEL);              $parse_rcdata->(CDATA_CONTENT_MODEL);
5917                $open_tables->[-1]->[2] = 0 if @$open_tables; # ~node inserted
5918              next B;              next B;
5919            } else {            } else {
5920              !!!cp ('t227.7');              !!!cp ('t227.7');
# Line 5885  sub _tree_construction_main ($) { Line 5925  sub _tree_construction_main ($) {
5925              !!!cp ('t227.6');              !!!cp ('t227.6');
5926              ## NOTE: This is a "as if in head" code clone.              ## NOTE: This is a "as if in head" code clone.
5927              $script_start_tag->();              $script_start_tag->();
5928                $open_tables->[-1]->[2] = 0 if @$open_tables; # ~node inserted
5929              next B;              next B;
5930            } else {            } else {
5931              !!!cp ('t227.5');              !!!cp ('t227.5');
# Line 5900  sub _tree_construction_main ($) { Line 5941  sub _tree_construction_main ($) {
5941                                  text => $token->{tag_name}, token => $token);                                  text => $token->{tag_name}, token => $token);
5942    
5943                  !!!insert-element ($token->{tag_name}, $token->{attributes}, $token);                  !!!insert-element ($token->{tag_name}, $token->{attributes}, $token);
5944                    $open_tables->[-1]->[2] = 0 if @$open_tables; # ~node inserted
5945    
5946                  ## TODO: form element pointer                  ## TODO: form element pointer
5947    
# Line 6801  sub _tree_construction_main ($) { Line 6843  sub _tree_construction_main ($) {
6843        } else {        } else {
6844          die "$0: $token->{type}: Unknown token type";          die "$0: $token->{type}: Unknown token type";
6845        }        }
   
       ## ISSUE: An issue in spec here  
6846      } else {      } else {
6847        die "$0: $self->{insertion_mode}: Unknown insertion mode";        die "$0: $self->{insertion_mode}: Unknown insertion mode";
6848      }      }
# Line 6911  sub _tree_construction_main ($) { Line 6951  sub _tree_construction_main ($) {
6951          !!!next-token;          !!!next-token;
6952          next B;          next B;
6953        } elsif ({        } elsif ({
6954                  address => 1, blockquote => 1, center => 1, dir => 1,                  ## NOTE: Start tags for non-phrasing flow content elements
6955                  div => 1, dl => 1, fieldset => 1,  
6956                  h1 => 1, h2 => 1, h3 => 1, h4 => 1, h5 => 1, h6 => 1,                  ## NOTE: The normal one
6957                  menu => 1, ol => 1, p => 1, ul => 1,                  address => 1, article => 1, aside => 1, blockquote => 1,
6958                    center => 1, datagrid => 1, details => 1, dialog => 1,
6959                    dir => 1, div => 1, dl => 1, fieldset => 1, figure => 1,
6960                    footer => 1, h1 => 1, h2 => 1, h3 => 1, h4 => 1, h5 => 1,
6961                    h6 => 1, header => 1, menu => 1, nav => 1, ol => 1, p => 1,
6962                    section => 1, ul => 1,
6963                    ## NOTE: As normal, but drops leading newline
6964                  pre => 1, listing => 1,                  pre => 1, listing => 1,
6965                    ## NOTE: As normal, but interacts with the form element pointer
6966                  form => 1,                  form => 1,
6967                    
6968                  table => 1,                  table => 1,
6969                  hr => 1,                  hr => 1,
6970                 }->{$token->{tag_name}}) {                 }->{$token->{tag_name}}) {
# Line 6983  sub _tree_construction_main ($) { Line 7031  sub _tree_construction_main ($) {
7031            !!!next-token;            !!!next-token;
7032          }          }
7033          next B;          next B;
7034        } elsif ({li => 1, dt => 1, dd => 1}->{$token->{tag_name}}) {        } elsif ($token->{tag_name} eq 'li') {
7035          ## has a p element in scope          ## NOTE: As normal, but imply </li> when there's another <li> ...
         INSCOPE: for (reverse @{$self->{open_elements}}) {  
           if ($_->[1] & P_EL) {  
             !!!cp ('t353');  
             !!!back-token; # <x>  
             $token = {type => END_TAG_TOKEN, tag_name => 'p',  
                       line => $token->{line}, column => $token->{column}};  
             next B;  
           } elsif ($_->[1] & SCOPING_EL) {  
             !!!cp ('t354');  
             last INSCOPE;  
           }  
         } # INSCOPE  
7036    
7037          ## NOTE: Special, Scope (<li><foo><li> == <li><foo><li/></foo></li>)          ## NOTE: Special, Scope (<li><foo><li> == <li><foo><li/></foo></li>)
7038            ## Interpreted as <li><foo/></li><li/> (non-conforming)            ## Interpreted as <li><foo/></li><li/> (non-conforming)
# Line 7010  sub _tree_construction_main ($) { Line 7046  sub _tree_construction_main ($) {
7046          ## address, div, p (<li><foo><li> == <li><foo/></li><li/>)          ## address, div, p (<li><foo><li> == <li><foo/></li><li/>)
7047            ## Interpreted as <li><foo><li/></foo></li> (non-conforming)            ## Interpreted as <li><foo><li/></foo></li> (non-conforming)
7048            ## div (Fx, S)            ## div (Fx, S)
7049              
7050          ## Step 1          my $non_optional;
7051          my $i = -1;          my $i = -1;
7052          my $node = $self->{open_elements}->[$i];  
7053          my $li_or_dtdd = {li => {li => 1},          ## 1.
7054                            dt => {dt => 1, dd => 1},          for my $node (reverse @{$self->{open_elements}}) {
7055                            dd => {dt => 1, dd => 1}}->{$token->{tag_name}};            if ($node->[1] & LI_EL) {
7056          LI: {              ## 2. (a) As if </li>
7057            ## Step 2              {
7058            if ($li_or_dtdd->{$node->[0]->manakai_local_name}) {                ## If no </li> - not applied
7059              if ($i != -1) {                #
7060                !!!cp ('t355');  
7061                !!!parse-error (type => 'not closed',                ## Otherwise
7062                                text => $self->{open_elements}->[-1]->[0]  
7063                                    ->manakai_local_name,                ## 1. generate implied end tags, except for </li>
7064                                token => $token);                #
7065              } else {  
7066                !!!cp ('t356');                ## 2. If current node != "li", parse error
7067                  if ($non_optional) {
7068                    !!!parse-error (type => 'not closed',
7069                                    text => $non_optional->[0]->manakai_local_name,
7070                                    token => $token);
7071                    !!!cp ('t355');
7072                  } else {
7073                    !!!cp ('t356');
7074                  }
7075    
7076                  ## 3. Pop
7077                  splice @{$self->{open_elements}}, $i;
7078              }              }
7079              splice @{$self->{open_elements}}, $i;  
7080              last LI;              last; ## 2. (b) goto 5.
7081            } else {            } elsif (
7082                       ## NOTE: not "formatting" and not "phrasing"
7083                       ($node->[1] & SPECIAL_EL or
7084                        $node->[1] & SCOPING_EL) and
7085                       ## NOTE: "li", "dt", and "dd" are in |SPECIAL_EL|.
7086    
7087                       (not $node->[1] & ADDRESS_EL) &
7088                       (not $node->[1] & DIV_EL) &
7089                       (not $node->[1] & P_EL)) {
7090                ## 3.
7091              !!!cp ('t357');              !!!cp ('t357');
7092            }              last; ## goto 5.
7093                        } elsif ($node->[1] & END_TAG_OPTIONAL_EL) {
           ## Step 3  
           if (not ($node->[1] & FORMATTING_EL) and  
               #not $phrasing_category->{$node->[1]} and  
               ($node->[1] & SPECIAL_EL or  
                $node->[1] & SCOPING_EL) and  
               not ($node->[1] & ADDRESS_EL) and  
               not ($node->[1] & DIV_EL)) {  
7094              !!!cp ('t358');              !!!cp ('t358');
7095              last LI;              #
7096              } else {
7097                !!!cp ('t359');
7098                $non_optional ||= $node;
7099                #
7100            }            }
7101                        ## 4.
7102            !!!cp ('t359');            ## goto 2.
           ## Step 4  
7103            $i--;            $i--;
7104            $node = $self->{open_elements}->[$i];          }
7105            redo LI;  
7106          } # LI          ## 5. (a) has a |p| element in scope
7107                      INSCOPE: for (reverse @{$self->{open_elements}}) {
7108              if ($_->[1] & P_EL) {
7109                !!!cp ('t353');
7110    
7111                ## NOTE: |<p><li>|, for example.
7112    
7113                !!!back-token; # <x>
7114                $token = {type => END_TAG_TOKEN, tag_name => 'p',
7115                          line => $token->{line}, column => $token->{column}};
7116                next B;
7117              } elsif ($_->[1] & SCOPING_EL) {
7118                !!!cp ('t354');
7119                last INSCOPE;
7120              }
7121            } # INSCOPE
7122    
7123            ## 5. (b) insert
7124          !!!insert-element-t ($token->{tag_name}, $token->{attributes}, $token);          !!!insert-element-t ($token->{tag_name}, $token->{attributes}, $token);
7125          !!!nack ('t359.1');          !!!nack ('t359.1');
7126          !!!next-token;          !!!next-token;
7127          next B;          next B;
7128          } elsif ($token->{tag_name} eq 'dt' or
7129                   $token->{tag_name} eq 'dd') {
7130            ## NOTE: As normal, but imply </dt> or </dd> when ...
7131    
7132            my $non_optional;
7133            my $i = -1;
7134    
7135            ## 1.
7136            for my $node (reverse @{$self->{open_elements}}) {
7137              if ($node->[1] & DT_EL or $node->[1] & DD_EL) {
7138                ## 2. (a) As if </li>
7139                {
7140                  ## If no </li> - not applied
7141                  #
7142    
7143                  ## Otherwise
7144    
7145                  ## 1. generate implied end tags, except for </dt> or </dd>
7146                  #
7147    
7148                  ## 2. If current node != "dt"|"dd", parse error
7149                  if ($non_optional) {
7150                    !!!parse-error (type => 'not closed',
7151                                    text => $non_optional->[0]->manakai_local_name,
7152                                    token => $token);
7153                    !!!cp ('t355.1');
7154                  } else {
7155                    !!!cp ('t356.1');
7156                  }
7157    
7158                  ## 3. Pop
7159                  splice @{$self->{open_elements}}, $i;
7160                }
7161    
7162                last; ## 2. (b) goto 5.
7163              } elsif (
7164                       ## NOTE: not "formatting" and not "phrasing"
7165                       ($node->[1] & SPECIAL_EL or
7166                        $node->[1] & SCOPING_EL) and
7167                       ## NOTE: "li", "dt", and "dd" are in |SPECIAL_EL|.
7168    
7169                       (not $node->[1] & ADDRESS_EL) &
7170                       (not $node->[1] & DIV_EL) &
7171                       (not $node->[1] & P_EL)) {
7172                ## 3.
7173                !!!cp ('t357.1');
7174                last; ## goto 5.
7175              } elsif ($node->[1] & END_TAG_OPTIONAL_EL) {
7176                !!!cp ('t358.1');
7177                #
7178              } else {
7179                !!!cp ('t359.1');
7180                $non_optional ||= $node;
7181                #
7182              }
7183              ## 4.
7184              ## goto 2.
7185              $i--;
7186            }
7187    
7188            ## 5. (a) has a |p| element in scope
7189            INSCOPE: for (reverse @{$self->{open_elements}}) {
7190              if ($_->[1] & P_EL) {
7191                !!!cp ('t353.1');
7192                !!!back-token; # <x>
7193                $token = {type => END_TAG_TOKEN, tag_name => 'p',
7194                          line => $token->{line}, column => $token->{column}};
7195                next B;
7196              } elsif ($_->[1] & SCOPING_EL) {
7197                !!!cp ('t354.1');
7198                last INSCOPE;
7199              }
7200            } # INSCOPE
7201    
7202            ## 5. (b) insert
7203            !!!insert-element-t ($token->{tag_name}, $token->{attributes}, $token);
7204            !!!nack ('t359.2');
7205            !!!next-token;
7206            next B;
7207        } elsif ($token->{tag_name} eq 'plaintext') {        } elsif ($token->{tag_name} eq 'plaintext') {
7208            ## NOTE: As normal, but effectively ends parsing
7209    
7210          ## has a p element in scope          ## has a p element in scope
7211          INSCOPE: for (reverse @{$self->{open_elements}}) {          INSCOPE: for (reverse @{$self->{open_elements}}) {
7212            if ($_->[1] & P_EL) {            if ($_->[1] & P_EL) {
# Line 7295  sub _tree_construction_main ($) { Line 7444  sub _tree_construction_main ($) {
7444          }          }
7445          !!!next-token;          !!!next-token;
7446          next B;          next B;
7447          } elsif ($token->{tag_name} eq 'optgroup' or
7448                   $token->{tag_name} eq 'option') {
7449            ## has an |option| element in scope
7450            INSCOPE: for (reverse 0..$#{$self->{open_elements}}) {
7451              my $node = $self->{open_elements}->[$_];
7452              if ($node->[1] & OPTION_EL) {
7453                !!!cp ('t397.1');
7454                ## NOTE: As if </option>
7455                !!!back-token; # <option> or <optgroup>
7456                $token = {type => END_TAG_TOKEN, tag_name => 'option',
7457                          line => $token->{line}, column => $token->{column}};
7458                next B;
7459              } elsif ($node->[1] & SCOPING_EL) {
7460                !!!cp ('t397.2');
7461                last INSCOPE;
7462              }
7463            } # INSCOPE
7464    
7465            $reconstruct_active_formatting_elements->($insert_to_current);
7466    
7467            !!!insert-element-t ($token->{tag_name}, $token->{attributes}, $token);
7468    
7469            !!!nack ('t397.3');
7470            !!!next-token;
7471            redo B;
7472        } elsif ($token->{tag_name} eq 'rt' or        } elsif ($token->{tag_name} eq 'rt' or
7473                 $token->{tag_name} eq 'rp') {                 $token->{tag_name} eq 'rp') {
7474          ## has a |ruby| element in scope          ## has a |ruby| element in scope
# Line 7342  sub _tree_construction_main ($) { Line 7516  sub _tree_construction_main ($) {
7516                    
7517          if ($self->{self_closing}) {          if ($self->{self_closing}) {
7518            pop @{$self->{open_elements}};            pop @{$self->{open_elements}};
7519            !!!ack ('t398.1');            !!!ack ('t398.6');
7520          } else {          } else {
7521            !!!cp ('t398.2');            !!!cp ('t398.7');
7522            $self->{insertion_mode} |= IN_FOREIGN_CONTENT_IM;            $self->{insertion_mode} |= IN_FOREIGN_CONTENT_IM;
7523            ## NOTE: |<body><math><mi><svg>| -> "in foreign content" insertion            ## NOTE: |<body><math><mi><svg>| -> "in foreign content" insertion
7524            ## mode, "in body" (not "in foreign content") secondary insertion            ## mode, "in body" (not "in foreign content") secondary insertion
# Line 7355  sub _tree_construction_main ($) { Line 7529  sub _tree_construction_main ($) {
7529          next B;          next B;
7530        } elsif ({        } elsif ({
7531                  caption => 1, col => 1, colgroup => 1, frame => 1,                  caption => 1, col => 1, colgroup => 1, frame => 1,
7532                  frameset => 1, head => 1, option => 1, optgroup => 1,                  frameset => 1, head => 1,
7533                  tbody => 1, td => 1, tfoot => 1, th => 1,                  tbody => 1, td => 1, tfoot => 1, th => 1,
7534                  thead => 1, tr => 1,                  thead => 1, tr => 1,
7535                 }->{$token->{tag_name}}) {                 }->{$token->{tag_name}}) {
# Line 7366  sub _tree_construction_main ($) { Line 7540  sub _tree_construction_main ($) {
7540          !!!nack ('t401.1'); ## NOTE: |<col/>| or |<frame/>| here is an error.          !!!nack ('t401.1'); ## NOTE: |<col/>| or |<frame/>| here is an error.
7541          !!!next-token;          !!!next-token;
7542          next B;          next B;
7543                  } elsif ($token->{tag_name} eq 'param' or
7544          ## ISSUE: An issue on HTML5 new elements in the spec.                 $token->{tag_name} eq 'source') {
7545            !!!insert-element-t ($token->{tag_name}, $token->{attributes}, $token);
7546            pop @{$self->{open_elements}};
7547    
7548            !!!ack ('t398.5');
7549            !!!next-token;
7550            redo B;
7551        } else {        } else {
7552          if ($token->{tag_name} eq 'image') {          if ($token->{tag_name} eq 'image') {
7553            !!!cp ('t384');            !!!cp ('t384');
# Line 7403  sub _tree_construction_main ($) { Line 7583  sub _tree_construction_main ($) {
7583            !!!ack ('t388.2');            !!!ack ('t388.2');
7584          } elsif ({          } elsif ({
7585                    area => 1, basefont => 1, bgsound => 1, br => 1,                    area => 1, basefont => 1, bgsound => 1, br => 1,
7586                    embed => 1, img => 1, param => 1, spacer => 1, wbr => 1,                    embed => 1, img => 1, spacer => 1, wbr => 1,
                   #image => 1,  
7587                   }->{$token->{tag_name}}) {                   }->{$token->{tag_name}}) {
7588            !!!cp ('t388.1');            !!!cp ('t388.1');
7589            pop @{$self->{open_elements}};            pop @{$self->{open_elements}};
# Line 7445  sub _tree_construction_main ($) { Line 7624  sub _tree_construction_main ($) {
7624              }              }
7625            }            }
7626    
7627            !!!parse-error (type => 'start tag not allowed',            ## NOTE: |<marquee></body>|, |<svg><foreignobject></body>|
7628    
7629              !!!parse-error (type => 'unmatched end tag',
7630                            text => $token->{tag_name}, token => $token);                            text => $token->{tag_name}, token => $token);
7631            ## NOTE: Ignore the token.            ## NOTE: Ignore the token.
7632            !!!next-token;            !!!next-token;
# Line 7472  sub _tree_construction_main ($) { Line 7653  sub _tree_construction_main ($) {
7653          ## up-to-date, though it has same effect as speced.          ## up-to-date, though it has same effect as speced.
7654          if (@{$self->{open_elements}} > 1 and          if (@{$self->{open_elements}} > 1 and
7655              $self->{open_elements}->[1]->[1] & BODY_EL) {              $self->{open_elements}->[1]->[1] & BODY_EL) {
           ## ISSUE: There is an issue in the spec.  
7656            unless ($self->{open_elements}->[-1]->[1] & BODY_EL) {            unless ($self->{open_elements}->[-1]->[1] & BODY_EL) {
7657              !!!cp ('t406');              !!!cp ('t406');
7658              !!!parse-error (type => 'not closed',              !!!parse-error (type => 'not closed',
# Line 7494  sub _tree_construction_main ($) { Line 7674  sub _tree_construction_main ($) {
7674            next B;            next B;
7675          }          }
7676        } elsif ({        } elsif ({
7677                  address => 1, blockquote => 1, center => 1, dir => 1,                  ## NOTE: End tags for non-phrasing flow content elements
7678                  div => 1, dl => 1, fieldset => 1, listing => 1,  
7679                  menu => 1, ol => 1, pre => 1, ul => 1,                  ## NOTE: The normal ones
7680                    address => 1, article => 1, aside => 1, blockquote => 1,
7681                    center => 1, datagrid => 1, details => 1, dialog => 1,
7682                    dir => 1, div => 1, dl => 1, fieldset => 1, figure => 1,
7683                    footer => 1, header => 1, listing => 1, menu => 1, nav => 1,
7684                    ol => 1, pre => 1, section => 1, ul => 1,
7685    
7686                    ## NOTE: As normal, but ... optional tags
7687                  dd => 1, dt => 1, li => 1,                  dd => 1, dt => 1, li => 1,
7688    
7689                  applet => 1, button => 1, marquee => 1, object => 1,                  applet => 1, button => 1, marquee => 1, object => 1,
7690                 }->{$token->{tag_name}}) {                 }->{$token->{tag_name}}) {
7691            ## NOTE: Code for <li> start tags includes "as if </li>" code.
7692            ## Code for <dt> or <dd> start tags includes "as if </dt> or
7693            ## </dd>" code.
7694    
7695          ## has an element in scope          ## has an element in scope
7696          my $i;          my $i;
7697          INSCOPE: for (reverse 0..$#{$self->{open_elements}}) {          INSCOPE: for (reverse 0..$#{$self->{open_elements}}) {
# Line 7560  sub _tree_construction_main ($) { Line 7752  sub _tree_construction_main ($) {
7752          !!!next-token;          !!!next-token;
7753          next B;          next B;
7754        } elsif ($token->{tag_name} eq 'form') {        } elsif ($token->{tag_name} eq 'form') {
7755            ## NOTE: As normal, but interacts with the form element pointer
7756    
7757          undef $self->{form_element};          undef $self->{form_element};
7758    
7759          ## has an element in scope          ## has an element in scope
# Line 7607  sub _tree_construction_main ($) { Line 7801  sub _tree_construction_main ($) {
7801          !!!next-token;          !!!next-token;
7802          next B;          next B;
7803        } elsif ({        } elsif ({
7804                    ## NOTE: As normal, except acts as a closer for any ...
7805                  h1 => 1, h2 => 1, h3 => 1, h4 => 1, h5 => 1, h6 => 1,                  h1 => 1, h2 => 1, h3 => 1, h4 => 1, h5 => 1, h6 => 1,
7806                 }->{$token->{tag_name}}) {                 }->{$token->{tag_name}}) {
7807          ## has an element in scope          ## has an element in scope
# Line 7652  sub _tree_construction_main ($) { Line 7847  sub _tree_construction_main ($) {
7847          !!!next-token;          !!!next-token;
7848          next B;          next B;
7849        } elsif ($token->{tag_name} eq 'p') {        } elsif ($token->{tag_name} eq 'p') {
7850            ## NOTE: As normal, except </p> implies <p> and ...
7851    
7852          ## has an element in scope          ## has an element in scope
7853            my $non_optional;
7854          my $i;          my $i;
7855          INSCOPE: for (reverse 0..$#{$self->{open_elements}}) {          INSCOPE: for (reverse 0..$#{$self->{open_elements}}) {
7856            my $node = $self->{open_elements}->[$_];            my $node = $self->{open_elements}->[$_];
# Line 7663  sub _tree_construction_main ($) { Line 7861  sub _tree_construction_main ($) {
7861            } elsif ($node->[1] & SCOPING_EL) {            } elsif ($node->[1] & SCOPING_EL) {
7862              !!!cp ('t411.1');              !!!cp ('t411.1');
7863              last INSCOPE;              last INSCOPE;
7864              } elsif ($node->[1] & END_TAG_OPTIONAL_EL) {
7865                ## NOTE: |END_TAG_OPTIONAL_EL| includes "p"
7866                !!!cp ('t411.2');
7867                #
7868              } else {
7869                !!!cp ('t411.3');
7870                $non_optional ||= $node;
7871                #
7872            }            }
7873          } # INSCOPE          } # INSCOPE
7874    
7875          if (defined $i) {          if (defined $i) {
7876            if ($self->{open_elements}->[-1]->[0]->manakai_local_name            ## 1. Generate implied end tags
7877                    ne $token->{tag_name}) {            #
7878    
7879              ## 2. If current node != "p", parse error
7880              if ($non_optional) {
7881              !!!cp ('t412.1');              !!!cp ('t412.1');
7882              !!!parse-error (type => 'not closed',              !!!parse-error (type => 'not closed',
7883                              text => $self->{open_elements}->[-1]->[0]                              text => $non_optional->[0]->manakai_local_name,
                                 ->manakai_local_name,  
7884                              token => $token);                              token => $token);
7885            } else {            } else {
7886              !!!cp ('t414.1');              !!!cp ('t414.1');
7887            }            }
7888    
7889              ## 3. Pop
7890            splice @{$self->{open_elements}}, $i;            splice @{$self->{open_elements}}, $i;
7891          } else {          } else {
7892            !!!cp ('t413.1');            !!!cp ('t413.1');
# Line 7718  sub _tree_construction_main ($) { Line 7927  sub _tree_construction_main ($) {
7927          ## Ignore the token.          ## Ignore the token.
7928          !!!next-token;          !!!next-token;
7929          next B;          next B;
       } elsif ({  
                 caption => 1, col => 1, colgroup => 1, frame => 1,  
                 frameset => 1, head => 1, option => 1, optgroup => 1,  
                 tbody => 1, td => 1, tfoot => 1, th => 1,  
                 thead => 1, tr => 1,  
                 area => 1, basefont => 1, bgsound => 1,  
                 embed => 1, hr => 1, iframe => 1, image => 1,  
                 img => 1, input => 1, isindex => 1, noembed => 1,  
                 noframes => 1, param => 1, select => 1, spacer => 1,  
                 table => 1, textarea => 1, wbr => 1,  
                 noscript => 0, ## TODO: if scripting is enabled  
                }->{$token->{tag_name}}) {  
         !!!cp ('t429');  
         !!!parse-error (type => 'unmatched end tag',  
                         text => $token->{tag_name}, token => $token);  
         ## Ignore the token  
         !!!next-token;  
         next B;  
           
         ## ISSUE: Issue on HTML5 new elements in spec  
           
7930        } else {        } else {
7931            if ($token->{tag_name} eq 'sarcasm') {
7932              sleep 0.001; # take a deep breath
7933            }
7934    
7935          ## Step 1          ## Step 1
7936          my $node_i = -1;          my $node_i = -1;
7937          my $node = $self->{open_elements}->[$node_i];          my $node = $self->{open_elements}->[$node_i];
7938    
7939          ## Step 2          ## Step 2
7940          S2: {          S2: {
7941            if ($node->[0]->manakai_local_name eq $token->{tag_name}) {            my $node_tag_name = $node->[0]->manakai_local_name;
7942              $node_tag_name =~ tr/A-Z/a-z/; # for SVG camelCase tag names
7943              if ($node_tag_name eq $token->{tag_name}) {
7944              ## Step 1              ## Step 1
7945              ## generate implied end tags              ## generate implied end tags
7946              while ($self->{open_elements}->[-1]->[1] & END_TAG_OPTIONAL_EL) {              while ($self->{open_elements}->[-1]->[1] & END_TAG_OPTIONAL_EL) {
# Line 7759  sub _tree_construction_main ($) { Line 7953  sub _tree_construction_main ($) {
7953              }              }
7954                    
7955              ## Step 2              ## Step 2
7956              if ($self->{open_elements}->[-1]->[0]->manakai_local_name              my $current_tag_name
7957                      ne $token->{tag_name}) {                  = $self->{open_elements}->[-1]->[0]->manakai_local_name;
7958                $current_tag_name =~ tr/A-Z/a-z/;
7959                if ($current_tag_name ne $token->{tag_name}) {
7960                !!!cp ('t431');                !!!cp ('t431');
7961                ## NOTE: <x><y></x>                ## NOTE: <x><y></x>
7962                !!!parse-error (type => 'not closed',                !!!parse-error (type => 'not closed',
# Line 8030  sub set_inner_html ($$$$;$) { Line 8226  sub set_inner_html ($$$$;$) {
8226      push @{$p->{open_elements}}, [$root, $el_category->{html}];      push @{$p->{open_elements}}, [$root, $el_category->{html}];
8227    
8228      undef $p->{head_element};      undef $p->{head_element};
8229        undef $p->{head_element_inserted};
8230    
8231      ## Step 6 # MUST      ## Step 6 # MUST
8232      $p->_reset_insertion_mode;      $p->_reset_insertion_mode;

Legend:
Removed from v.1.194  
changed lines
  Added in v.1.202

[email protected]
ViewVC Help
Powered by ViewVC 1.1.24