/[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.228 by wakaba, Sun Aug 16 06:47:59 2009 UTC revision 1.241 by wakaba, Sun Sep 6 12:53:19 2009 UTC
# Line 179  my $el_category = { Line 179  my $el_category = {
179    dt => DTDD_EL,    dt => DTDD_EL,
180    em => FORMATTING_EL,    em => FORMATTING_EL,
181    embed => MISC_SPECIAL_EL,    embed => MISC_SPECIAL_EL,
   eventsource => MISC_SPECIAL_EL,  
182    fieldset => MISC_SPECIAL_EL,    fieldset => MISC_SPECIAL_EL,
183    figure => MISC_SPECIAL_EL,    figure => MISC_SPECIAL_EL,
184    font => FORMATTING_EL,    font => FORMATTING_EL,
# Line 195  my $el_category = { Line 194  my $el_category = {
194    h6 => HEADING_EL,    h6 => HEADING_EL,
195    head => MISC_SPECIAL_EL,    head => MISC_SPECIAL_EL,
196    header => MISC_SPECIAL_EL,    header => MISC_SPECIAL_EL,
197      hgroup => MISC_SPECIAL_EL,
198    hr => MISC_SPECIAL_EL,    hr => MISC_SPECIAL_EL,
199    html => HTML_EL,    html => HTML_EL,
200    i => FORMATTING_EL,    i => FORMATTING_EL,
# Line 203  my $el_category = { Line 203  my $el_category = {
203    #image => MISC_SPECIAL_EL, ## NOTE: Commented out in the spec.    #image => MISC_SPECIAL_EL, ## NOTE: Commented out in the spec.
204    input => MISC_SPECIAL_EL,    input => MISC_SPECIAL_EL,
205    isindex => MISC_SPECIAL_EL,    isindex => MISC_SPECIAL_EL,
206      ## XXX keygen? (Whether a void element is in Special or not does not
207      ## affect to the processing, however.)
208    li => LI_EL,    li => LI_EL,
209    link => MISC_SPECIAL_EL,    link => MISC_SPECIAL_EL,
210    listing => MISC_SPECIAL_EL,    listing => MISC_SPECIAL_EL,
# Line 247  my $el_category = { Line 249  my $el_category = {
249    u => FORMATTING_EL,    u => FORMATTING_EL,
250    ul => MISC_SPECIAL_EL,    ul => MISC_SPECIAL_EL,
251    wbr => MISC_SPECIAL_EL,    wbr => MISC_SPECIAL_EL,
252      xmp => MISC_SPECIAL_EL,
253  };  };
254    
255  my $el_category_f = {  my $el_category_f = {
# Line 647  sub parse_char_stream ($$$;$$) { Line 650  sub parse_char_stream ($$$;$$) {
650    
651    ## NOTE: |set_inner_html| copies most of this method's code    ## NOTE: |set_inner_html| copies most of this method's code
652    
653      ## Confidence: irrelevant.
654    $self->{confident} = 1 unless exists $self->{confident};    $self->{confident} = 1 unless exists $self->{confident};
655    
656    $self->{document}->input_encoding ($self->{input_encoding})    $self->{document}->input_encoding ($self->{input_encoding})
657        if defined $self->{input_encoding};        if defined $self->{input_encoding};
658  ## TODO: |{input_encoding}| is needless?  ## TODO: |{input_encoding}| is needless?
# Line 864  sub _initialize_tree_constructor ($) { Line 869  sub _initialize_tree_constructor ($) {
869    $self->{document}->manakai_is_html (1); # MUST    $self->{document}->manakai_is_html (1); # MUST
870    $self->{document}->set_user_data (manakai_source_line => 1);    $self->{document}->set_user_data (manakai_source_line => 1);
871    $self->{document}->set_user_data (manakai_source_column => 1);    $self->{document}->set_user_data (manakai_source_column => 1);
872    
873      $self->{frameset_ok} = 1;
874  } # _initialize_tree_constructor  } # _initialize_tree_constructor
875    
876  sub _terminate_tree_constructor ($) {  sub _terminate_tree_constructor ($) {
# Line 1438  sub _tree_construction_main ($) { Line 1445  sub _tree_construction_main ($) {
1445    }; # $script_start_tag    }; # $script_start_tag
1446    
1447    ## NOTE: $open_tables->[-1]->[0] is the "current table" element node.    ## NOTE: $open_tables->[-1]->[0] is the "current table" element node.
1448    ## NOTE: $open_tables->[-1]->[1] is the "tainted" flag.    ## NOTE: $open_tables->[-1]->[1] is the "tainted" flag (OBSOLETE; unused).
1449    ## NOTE: $open_tables->[-1]->[2] is set false when non-Text node inserted.    ## NOTE: $open_tables->[-1]->[2] is set false when non-Text node inserted.
1450    my $open_tables = [[$self->{open_elements}->[0]->[0]]];    my $open_tables = [[$self->{open_elements}->[0]->[0]]];
1451    
# Line 1608  sub _tree_construction_main ($) { Line 1615  sub _tree_construction_main ($) {
1615                
1616        ## Step 8        ## Step 8
1617        if ($common_ancestor_node->[1] & TABLE_ROWS_EL) {        if ($common_ancestor_node->[1] & TABLE_ROWS_EL) {
1618            ## Foster parenting.
1619          my $foster_parent_element;          my $foster_parent_element;
1620          my $next_sibling;          my $next_sibling;
1621          OE: for (reverse 0..$#{$self->{open_elements}}) {          OE: for (reverse 0..$#{$self->{open_elements}}) {
1622            if ($self->{open_elements}->[$_]->[1] == TABLE_EL) {            if ($self->{open_elements}->[$_]->[1] == TABLE_EL) {
1623                               my $parent = $self->{open_elements}->[$_]->[0]->parent_node;              !!!cp ('t65.2');
1624                               if (defined $parent and $parent->node_type == 1) {              $foster_parent_element = $self->{open_elements}->[$_ - 1]->[0];
1625                                 !!!cp ('t65.1');              $next_sibling = $self->{open_elements}->[$_]->[0];
1626                                 $foster_parent_element = $parent;              undef $next_sibling
1627                                 $next_sibling = $self->{open_elements}->[$_]->[0];                  unless $next_sibling->parent_node eq $foster_parent_element;
1628                               } else {              last OE;
1629                                 !!!cp ('t65.2');            }
1630                                 $foster_parent_element          } # OE
1631                                   = $self->{open_elements}->[$_ - 1]->[0];          $foster_parent_element ||= $self->{open_elements}->[0]->[0];
1632                               }  
                              last OE;  
                            }  
                          } # OE  
                          $foster_parent_element = $self->{open_elements}->[0]->[0]  
                            unless defined $foster_parent_element;  
1633          $foster_parent_element->insert_before ($last_node->[0], $next_sibling);          $foster_parent_element->insert_before ($last_node->[0], $next_sibling);
1634          $open_tables->[-1]->[1] = 1; # tainted          $open_tables->[-1]->[1] = 1; # tainted
1635        } else {        } else {
# Line 1682  sub _tree_construction_main ($) { Line 1685  sub _tree_construction_main ($) {
1685      $self->{open_elements}->[-1]->[0]->append_child ($_[0]);      $self->{open_elements}->[-1]->[0]->append_child ($_[0]);
1686    }; # $insert_to_current    }; # $insert_to_current
1687    
1688      ## Foster parenting.  Note that there are three "foster parenting"
1689      ## code in the parser: for elements (this one), for texts, and for
1690      ## elements in the AAA code.
1691    my $insert_to_foster = sub {    my $insert_to_foster = sub {
1692      my $child = shift;      my $child = shift;
1693      if ($self->{open_elements}->[-1]->[1] & TABLE_ROWS_EL) {      if ($self->{open_elements}->[-1]->[1] & TABLE_ROWS_EL) {
# Line 1690  sub _tree_construction_main ($) { Line 1696  sub _tree_construction_main ($) {
1696        my $next_sibling;        my $next_sibling;
1697        OE: for (reverse 0..$#{$self->{open_elements}}) {        OE: for (reverse 0..$#{$self->{open_elements}}) {
1698          if ($self->{open_elements}->[$_]->[1] == TABLE_EL) {          if ($self->{open_elements}->[$_]->[1] == TABLE_EL) {
1699                               my $parent = $self->{open_elements}->[$_]->[0]->parent_node;            !!!cp ('t71');
1700                               if (defined $parent and $parent->node_type == 1) {            $foster_parent_element = $self->{open_elements}->[$_ - 1]->[0];
1701                                 !!!cp ('t70');            $next_sibling = $self->{open_elements}->[$_]->[0];
1702                                 $foster_parent_element = $parent;            undef $next_sibling
1703                                 $next_sibling = $self->{open_elements}->[$_]->[0];                unless $next_sibling->parent_node eq $foster_parent_element;
1704                               } else {            last OE;
1705                                 !!!cp ('t71');          }
1706                                 $foster_parent_element        } # OE
1707                                   = $self->{open_elements}->[$_ - 1]->[0];        $foster_parent_element ||= $self->{open_elements}->[0]->[0];
1708                               }  
1709                               last OE;        $foster_parent_element->insert_before ($child, $next_sibling);
                            }  
                          } # OE  
                          $foster_parent_element = $self->{open_elements}->[0]->[0]  
                            unless defined $foster_parent_element;  
                          $foster_parent_element->insert_before  
                            ($child, $next_sibling);  
1710        $open_tables->[-1]->[1] = 1; # tainted        $open_tables->[-1]->[1] = 1; # tainted
1711      } else {      } else {
1712        !!!cp ('t72');        !!!cp ('t72');
# Line 1734  sub _tree_construction_main ($) { Line 1734  sub _tree_construction_main ($) {
1734    ## document.write ("b")</script>|    ## document.write ("b")</script>|
1735    
1736    B: while (1) {    B: while (1) {
1737    
1738        ## The "in table text" insertion mode.
1739        if ($self->{insertion_mode} & TABLE_IMS and
1740            not $self->{insertion_mode} & IN_FOREIGN_CONTENT_IM and
1741            not $self->{insertion_mode} & IN_CDATA_RCDATA_IM) {
1742          C: {
1743            my $s;
1744            if ($token->{type} == CHARACTER_TOKEN) {
1745              !!!cp ('t194');
1746              $self->{pending_chars} ||= [];
1747              push @{$self->{pending_chars}}, $token;
1748              !!!next-token;
1749              next B;
1750            } else {
1751              if ($self->{pending_chars}) {
1752                $s = join '', map { $_->{data} } @{$self->{pending_chars}};
1753                delete $self->{pending_chars};
1754                if ($s =~ /[^\x09\x0A\x0C\x0D\x20]/) {
1755                  !!!cp ('t195');
1756                  #
1757                } else {
1758                  !!!cp ('t195.1');
1759                  #$self->{open_elements}->[-1]->[0]->manakai_append_text ($s);
1760                  $self->{open_elements}->[-1]->[0]->append_child
1761                      ($self->{document}->create_text_node ($s));
1762                  last C;
1763                }
1764              } else {
1765                !!!cp ('t195.2');
1766                last C;
1767              }
1768            }
1769    
1770            ## Foster parenting.
1771            !!!parse-error (type => 'in table:#text', token => $token);
1772    
1773            ## NOTE: As if in body, but insert into the foster parent element.
1774            $reconstruct_active_formatting_elements->($insert_to_foster);
1775                
1776            if ($self->{open_elements}->[-1]->[1] & TABLE_ROWS_EL) {
1777              # MUST
1778              my $foster_parent_element;
1779              my $next_sibling;
1780              OE: for (reverse 0..$#{$self->{open_elements}}) {
1781                if ($self->{open_elements}->[$_]->[1] == TABLE_EL) {
1782                  !!!cp ('t197');
1783                  $foster_parent_element = $self->{open_elements}->[$_ - 1]->[0];
1784                  $next_sibling = $self->{open_elements}->[$_]->[0];
1785                  undef $next_sibling
1786                    unless $next_sibling->parent_node eq $foster_parent_element;
1787                  last OE;
1788                }
1789              } # OE
1790              $foster_parent_element ||= $self->{open_elements}->[0]->[0];
1791    
1792              !!!cp ('t199');
1793              $foster_parent_element->insert_before
1794                  ($self->{document}->create_text_node ($s), $next_sibling);
1795    
1796              $open_tables->[-1]->[1] = 1; # tainted
1797              $open_tables->[-1]->[2] = 1; # ~node inserted
1798            } else {
1799              ## NOTE: Fragment case or in a foster parent'ed element
1800              ## (e.g. |<table><span>a|).  In fragment case, whether the
1801              ## character is appended to existing node or a new node is
1802              ## created is irrelevant, since the foster parent'ed nodes
1803              ## are discarded and fragment parsing does not invoke any
1804              ## script.
1805              !!!cp ('t200');
1806              $self->{open_elements}->[-1]->[0]->manakai_append_text ($s);
1807            }
1808          } # C
1809        } # TABLE_IMS
1810    
1811      if ($token->{type} == DOCTYPE_TOKEN) {      if ($token->{type} == DOCTYPE_TOKEN) {
1812        !!!cp ('t73');        !!!cp ('t73');
1813        !!!parse-error (type => 'in html:#DOCTYPE', token => $token);        !!!parse-error (type => 'in html:#DOCTYPE', token => $token);
# Line 2152  sub _tree_construction_main ($) { Line 2226  sub _tree_construction_main ($) {
2226            !!!ack ('t103.1');            !!!ack ('t103.1');
2227            !!!next-token;            !!!next-token;
2228            next B;            next B;
2229          } elsif ($token->{tag_name} eq 'command' or          } elsif ($token->{tag_name} eq 'command') {
                  $token->{tag_name} eq 'eventsource') {  
2230            if ($self->{insertion_mode} == IN_HEAD_IM) {            if ($self->{insertion_mode} == IN_HEAD_IM) {
2231              ## NOTE: If the insertion mode at the time of the emission              ## NOTE: If the insertion mode at the time of the emission
2232              ## of the token was "before head", $self->{insertion_mode}              ## of the token was "before head", $self->{insertion_mode}
# Line 2418  sub _tree_construction_main ($) { Line 2491  sub _tree_construction_main ($) {
2491              ## reprocess              ## reprocess
2492              !!!ack-later;              !!!ack-later;
2493              next B;              next B;
2494            } elsif ($token->{type} == END_TAG_TOKEN) {        } elsif ($token->{type} == END_TAG_TOKEN) {
2495              if ($token->{tag_name} eq 'head') {          ## "Before head", "in head", and "after head" insertion modes
2496                if ($self->{insertion_mode} == BEFORE_HEAD_IM) {          ## ignore most of end tags.  Exceptions are "body", "html",
2497                  !!!cp ('t132');          ## and "br" end tags.  "Before head" and "in head" insertion
2498                  ## As if <head>          ## modes also recognize "head" end tag.  "In head noscript"
2499                  !!!create-element ($self->{head_element}, $HTML_NS, 'head',, $token);          ## insertion modes ignore end tags except for "noscript" and
2500                  $self->{open_elements}->[-1]->[0]->append_child ($self->{head_element});          ## "br".
                 push @{$self->{open_elements}},  
                     [$self->{head_element}, $el_category->{head}];  
2501    
2502                  ## Reprocess in the "in head" insertion mode...          if ($token->{tag_name} eq 'head') {
2503                  pop @{$self->{open_elements}};            if ($self->{insertion_mode} == BEFORE_HEAD_IM) {
2504                  $self->{insertion_mode} = AFTER_HEAD_IM;              !!!cp ('t132');
2505                  !!!next-token;              ## As if <head>
2506                  next B;              !!!create-element ($self->{head_element}, $HTML_NS, 'head',, $token);
2507                } elsif ($self->{insertion_mode} == IN_HEAD_NOSCRIPT_IM) {              $self->{open_elements}->[-1]->[0]->append_child ($self->{head_element});
2508                  !!!cp ('t133');              push @{$self->{open_elements}},
2509                  ## As if </noscript>                  [$self->{head_element}, $el_category->{head}];
2510                  pop @{$self->{open_elements}};  
2511                  !!!parse-error (type => 'in noscript:/',              ## Reprocess in the "in head" insertion mode...
2512                                  text => 'head', token => $token);              pop @{$self->{open_elements}};
2513                                $self->{insertion_mode} = AFTER_HEAD_IM;
2514                  ## Reprocess in the "in head" insertion mode...              !!!next-token;
2515                  pop @{$self->{open_elements}};              next B;
2516                  $self->{insertion_mode} = AFTER_HEAD_IM;            } elsif ($self->{insertion_mode} == IN_HEAD_NOSCRIPT_IM) {
2517                  !!!next-token;              !!!cp ('t133');
2518                  next B;              #
2519                } elsif ($self->{insertion_mode} == IN_HEAD_IM) {            } elsif ($self->{insertion_mode} == IN_HEAD_IM) {
2520                  !!!cp ('t134');              !!!cp ('t134');
2521                  pop @{$self->{open_elements}};              pop @{$self->{open_elements}};
2522                  $self->{insertion_mode} = AFTER_HEAD_IM;              $self->{insertion_mode} = AFTER_HEAD_IM;
2523                  !!!next-token;              !!!next-token;
2524                  next B;              next B;
2525                } elsif ($self->{insertion_mode} == AFTER_HEAD_IM) {            } elsif ($self->{insertion_mode} == AFTER_HEAD_IM) {
2526                  !!!cp ('t134.1');              !!!cp ('t134.1');
2527                  !!!parse-error (type => 'unmatched end tag', text => 'head',              #
2528                                  token => $token);            } else {
2529                  ## Ignore the token              die "$0: $self->{insertion_mode}: Unknown insertion mode";
2530                  !!!next-token;            }
2531                  next B;          } elsif ($token->{tag_name} eq 'noscript') {
2532                } else {            if ($self->{insertion_mode} == IN_HEAD_NOSCRIPT_IM) {
2533                  die "$0: $self->{insertion_mode}: Unknown insertion mode";              !!!cp ('t136');
2534                }              pop @{$self->{open_elements}};
2535              } elsif ($token->{tag_name} eq 'noscript') {              $self->{insertion_mode} = IN_HEAD_IM;
2536                if ($self->{insertion_mode} == IN_HEAD_NOSCRIPT_IM) {              !!!next-token;
2537                  !!!cp ('t136');              next B;
2538                  pop @{$self->{open_elements}};            } else {
2539                  $self->{insertion_mode} = IN_HEAD_IM;              !!!cp ('t138');
2540                  !!!next-token;              #
2541                  next B;            }
2542                } elsif ($self->{insertion_mode} == BEFORE_HEAD_IM or          } elsif ({
2543                         $self->{insertion_mode} == AFTER_HEAD_IM) {              body => ($self->{insertion_mode} != IN_HEAD_NOSCRIPT_IM),
2544                  !!!cp ('t137');              html => ($self->{insertion_mode} != IN_HEAD_NOSCRIPT_IM),
2545                  !!!parse-error (type => 'unmatched end tag',              br => 1,
2546                                  text => 'noscript', token => $token);          }->{$token->{tag_name}}) {
                 ## Ignore the token ## ISSUE: An issue in the spec.  
                 !!!next-token;  
                 next B;  
               } else {  
                 !!!cp ('t138');  
                 #  
               }  
             } elsif ({  
                       body => 1, html => 1,  
                      }->{$token->{tag_name}}) {  
               ## TODO: This branch is entirely redundant.  
               if ($self->{insertion_mode} == BEFORE_HEAD_IM or  
                   $self->{insertion_mode} == IN_HEAD_IM or  
                   $self->{insertion_mode} == IN_HEAD_NOSCRIPT_IM) {  
                 !!!cp ('t140');  
                 !!!parse-error (type => 'unmatched end tag',  
                                 text => $token->{tag_name}, token => $token);  
                 ## Ignore the token  
                 !!!next-token;  
                 next B;  
               } elsif ($self->{insertion_mode} == AFTER_HEAD_IM) {  
                 !!!cp ('t140.1');  
                 !!!parse-error (type => 'unmatched end tag',  
                                 text => $token->{tag_name}, token => $token);  
                 ## Ignore the token  
                 !!!next-token;  
                 next B;  
               } else {  
                 die "$0: $self->{insertion_mode}: Unknown insertion mode";  
               }  
             } elsif ($token->{tag_name} eq 'p') {  
               !!!cp ('t142');  
               !!!parse-error (type => 'unmatched end tag',  
                               text => $token->{tag_name}, token => $token);  
               ## Ignore the token  
               !!!next-token;  
               next B;  
         } elsif ($token->{tag_name} eq 'br') {  
2547            if ($self->{insertion_mode} == BEFORE_HEAD_IM) {            if ($self->{insertion_mode} == BEFORE_HEAD_IM) {
2548              !!!cp ('t142.2');              !!!cp ('t142.2');
2549              ## (before head) as if <head>, (in head) as if </head>              ## (before head) as if <head>, (in head) as if </head>
# Line 2530  sub _tree_construction_main ($) { Line 2563  sub _tree_construction_main ($) {
2563              !!!cp ('t143.3');              !!!cp ('t143.3');
2564              ## NOTE: Two parse errors for <head><noscript></br>              ## NOTE: Two parse errors for <head><noscript></br>
2565              !!!parse-error (type => 'unmatched end tag',              !!!parse-error (type => 'unmatched end tag',
2566                              text => 'br', token => $token);                              text => $token->{tag_name}, token => $token);
2567              ## As if </noscript>              ## As if </noscript>
2568              pop @{$self->{open_elements}};              pop @{$self->{open_elements}};
2569              $self->{insertion_mode} = IN_HEAD_IM;              $self->{insertion_mode} = IN_HEAD_IM;
# Line 2548  sub _tree_construction_main ($) { Line 2581  sub _tree_construction_main ($) {
2581              die "$0: $self->{insertion_mode}: Unknown insertion mode";              die "$0: $self->{insertion_mode}: Unknown insertion mode";
2582            }            }
2583    
2584            #            ## "after head" insertion mode
2585          } else { ## Other end tags            ## As if <body>
2586                !!!cp ('t145');            !!!insert-element ('body',, $token);
2587                !!!parse-error (type => 'unmatched end tag',            $self->{insertion_mode} = IN_BODY_IM;
2588                                text => $token->{tag_name}, token => $token);            ## Reprocess.
2589                ## Ignore the token            next B;
2590                !!!next-token;          }
               next B;  
             }  
   
             if ($self->{insertion_mode} == IN_HEAD_NOSCRIPT_IM) {  
               !!!cp ('t146');  
               ## As if </noscript>  
               pop @{$self->{open_elements}};  
               !!!parse-error (type => 'in noscript:/',  
                               text => $token->{tag_name}, token => $token);  
                 
               ## Reprocess in the "in head" insertion mode...  
               ## As if </head>  
               pop @{$self->{open_elements}};  
   
               ## Reprocess in the "after head" insertion mode...  
             } elsif ($self->{insertion_mode} == IN_HEAD_IM) {  
               !!!cp ('t147');  
               ## As if </head>  
               pop @{$self->{open_elements}};  
   
               ## Reprocess in the "after head" insertion mode...  
             } elsif ($self->{insertion_mode} == BEFORE_HEAD_IM) {  
 ## ISSUE: This case cannot be reached?  
               !!!cp ('t148');  
               !!!parse-error (type => 'unmatched end tag',  
                               text => $token->{tag_name}, token => $token);  
               ## Ignore the token ## ISSUE: An issue in the spec.  
               !!!next-token;  
               next B;  
             } else {  
               !!!cp ('t149');  
             }  
2591    
2592              ## "after head" insertion mode          ## End tags are ignored by default.
2593              ## As if <body>          !!!cp ('t145');
2594              !!!insert-element ('body',, $token);          !!!parse-error (type => 'unmatched end tag',
2595              $self->{insertion_mode} = IN_BODY_IM;                          text => $token->{tag_name}, token => $token);
2596              ## reprocess          ## Ignore the token.
2597            !!!next-token;
2598          next B;          next B;
2599        } elsif ($token->{type} == END_OF_FILE_TOKEN) {        } elsif ($token->{type} == END_OF_FILE_TOKEN) {
2600          if ($self->{insertion_mode} == BEFORE_HEAD_IM) {          if ($self->{insertion_mode} == BEFORE_HEAD_IM) {
# Line 3021  sub _tree_construction_main ($) { Line 3023  sub _tree_construction_main ($) {
3023        $insert = $insert_to_current;        $insert = $insert_to_current;
3024        #        #
3025      } elsif ($self->{insertion_mode} & TABLE_IMS) {      } elsif ($self->{insertion_mode} & TABLE_IMS) {
3026        if ($token->{type} == CHARACTER_TOKEN) {        if ($token->{type} == START_TAG_TOKEN) {
         if (not $open_tables->[-1]->[1] and # tainted  
             $token->{data} =~ s/^([\x09\x0A\x0C\x20]+)//) {  
           $self->{open_elements}->[-1]->[0]->manakai_append_text ($1);  
                 
           unless (length $token->{data}) {  
             !!!cp ('t194');  
             !!!next-token;  
             next B;  
           } else {  
             !!!cp ('t195');  
           }  
         }  
   
         !!!parse-error (type => 'in table:#text', token => $token);  
   
         ## NOTE: As if in body, but insert into the foster parent element.  
         $reconstruct_active_formatting_elements->($insert_to_foster);  
               
         if ($self->{open_elements}->[-1]->[1] & TABLE_ROWS_EL) {  
           # MUST  
           my $foster_parent_element;  
           my $next_sibling;  
           my $prev_sibling;  
           OE: for (reverse 0..$#{$self->{open_elements}}) {  
             if ($self->{open_elements}->[$_]->[1] == TABLE_EL) {  
               my $parent = $self->{open_elements}->[$_]->[0]->parent_node;  
               if (defined $parent and $parent->node_type == 1) {  
                 $foster_parent_element = $parent;  
                 !!!cp ('t196');  
                 $next_sibling = $self->{open_elements}->[$_]->[0];  
                 $prev_sibling = $next_sibling->previous_sibling;  
                 #  
               } 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;  
           undef $prev_sibling unless $open_tables->[-1]->[2]; # ~node inserted  
           if (defined $prev_sibling and  
               $prev_sibling->node_type == 3) {  
             !!!cp ('t198');  
             $prev_sibling->manakai_append_text ($token->{data});  
           } else {  
             !!!cp ('t199');  
             $foster_parent_element->insert_before  
                 ($self->{document}->create_text_node ($token->{data}),  
                  $next_sibling);  
           }  
           $open_tables->[-1]->[1] = 1; # tainted  
           $open_tables->[-1]->[2] = 1; # ~node inserted  
         } else {  
           ## NOTE: Fragment case or in a foster parent'ed element  
           ## (e.g. |<table><span>a|).  In fragment case, whether the  
           ## character is appended to existing node or a new node is  
           ## created is irrelevant, since the foster parent'ed nodes  
           ## are discarded and fragment parsing does not invoke any  
           ## script.  
           !!!cp ('t200');  
           $self->{open_elements}->[-1]->[0]->manakai_append_text  
               ($token->{data});  
         }  
               
         !!!next-token;  
         next B;  
       } elsif ($token->{type} == START_TAG_TOKEN) {  
3027          if ({          if ({
3028               tr => (($self->{insertion_mode} & IM_MASK) != IN_ROW_IM),               tr => (($self->{insertion_mode} & IM_MASK) != IN_ROW_IM),
3029               th => 1, td => 1,               th => 1, td => 1,
# Line 3361  sub _tree_construction_main ($) { Line 3291  sub _tree_construction_main ($) {
3291            !!!ack-later;            !!!ack-later;
3292            next B;            next B;
3293          } elsif ($token->{tag_name} eq 'style') {          } elsif ($token->{tag_name} eq 'style') {
3294            if (not $open_tables->[-1]->[1]) { # tainted            !!!cp ('t227.8');
3295              !!!cp ('t227.8');            ## NOTE: This is a "as if in head" code clone.
3296              ## NOTE: This is a "as if in head" code clone.            $parse_rcdata->(CDATA_CONTENT_MODEL);
3297              $parse_rcdata->(CDATA_CONTENT_MODEL);            $open_tables->[-1]->[2] = 0 if @$open_tables; # ~node inserted
3298              $open_tables->[-1]->[2] = 0 if @$open_tables; # ~node inserted            next B;
             next B;  
           } else {  
             !!!cp ('t227.7');  
             #  
           }  
3299          } elsif ($token->{tag_name} eq 'script') {          } elsif ($token->{tag_name} eq 'script') {
3300            if (not $open_tables->[-1]->[1]) { # tainted            !!!cp ('t227.6');
3301              !!!cp ('t227.6');            ## NOTE: This is a "as if in head" code clone.
3302              ## NOTE: This is a "as if in head" code clone.            $script_start_tag->();
3303              $script_start_tag->();            $open_tables->[-1]->[2] = 0 if @$open_tables; # ~node inserted
3304              $open_tables->[-1]->[2] = 0 if @$open_tables; # ~node inserted            next B;
             next B;  
           } else {  
             !!!cp ('t227.5');  
             #  
           }  
3305          } elsif ($token->{tag_name} eq 'input') {          } elsif ($token->{tag_name} eq 'input') {
3306            if (not $open_tables->[-1]->[1]) { # tainted            if ($token->{attributes}->{type}) {
3307              if ($token->{attributes}->{type}) { ## TODO: case              my $type = $token->{attributes}->{type}->{value};
3308                my $type = lc $token->{attributes}->{type}->{value};              $type =~ tr/A-Z/a-z/; ## ASCII case-insensitive.
3309                if ($type eq 'hidden') {              if ($type eq 'hidden') {
3310                  !!!cp ('t227.3');                !!!cp ('t227.3');
3311                  !!!parse-error (type => 'in table',                !!!parse-error (type => 'in table',
3312                                  text => $token->{tag_name}, token => $token);                                text => $token->{tag_name}, token => $token);
3313    
3314                  !!!insert-element ($token->{tag_name}, $token->{attributes}, $token);                !!!insert-element ($token->{tag_name}, $token->{attributes}, $token);
3315                  $open_tables->[-1]->[2] = 0 if @$open_tables; # ~node inserted                $open_tables->[-1]->[2] = 0 if @$open_tables; # ~node inserted
3316    
3317                  ## TODO: form element pointer                ## TODO: form element pointer
3318    
3319                  pop @{$self->{open_elements}};                pop @{$self->{open_elements}};
3320    
3321                  !!!next-token;                !!!next-token;
3322                  !!!ack ('t227.2.1');                !!!ack ('t227.2.1');
3323                  next B;                next B;
               } else {  
                 !!!cp ('t227.2');  
                 #  
               }  
3324              } else {              } else {
3325                !!!cp ('t227.1');                !!!cp ('t227.1');
3326                #                #
# Line 4333  sub _tree_construction_main ($) { Line 4249  sub _tree_construction_main ($) {
4249          $parse_rcdata->(CDATA_CONTENT_MODEL);          $parse_rcdata->(CDATA_CONTENT_MODEL);
4250          next B;          next B;
4251        } elsif ({        } elsif ({
4252                  base => 1, command => 1, eventsource => 1, link => 1,                  base => 1, command => 1, link => 1,
4253                 }->{$token->{tag_name}}) {                 }->{$token->{tag_name}}) {
4254          !!!cp ('t334');          !!!cp ('t334');
4255          ## NOTE: This is an "as if in head" code clone, only "-t" differs          ## NOTE: This is an "as if in head" code clone, only "-t" differs
# Line 4423  sub _tree_construction_main ($) { Line 4339  sub _tree_construction_main ($) {
4339          !!!nack ('t343.1');          !!!nack ('t343.1');
4340          !!!next-token;          !!!next-token;
4341          next B;          next B;
4342          } elsif ($token->{tag_nane} eq 'frameset') {
4343            !!!parse-error (type => 'in body', text => $token->{tag_name},
4344                            token => $token);
4345    
4346            if (@{$self->{open_elements}} == 1 or
4347                not ($self->{open_elements}->[1]->[1] != BODY_EL)) {
4348              !!!cp ('t343.2');
4349              ## Ignore the token.
4350            } elsif (not $self->{frameset_ok}) {
4351              !!!cp ('t343.3');
4352              ## Ignore the token.
4353            } else {
4354              !!!cp ('t343.4');
4355              
4356              ## 1. Remove the second element.
4357              my $body = $self->{open_elements}->[1]->[0];
4358              my $body_parent = $body->parent_node;
4359              $body_parent->remove_child ($body) if $body_parent;
4360    
4361              ## 2. Pop nodes.
4362              splice @{$self->{open_elements}}, 1;
4363    
4364              ## 3. Insert.
4365              !!!insert-element-t ($token->{tag_name}, $token->{attributes}, $token);
4366    
4367              ## 4. Switch.
4368              $self->{insertion_mode} = IN_FRAMESET_IM;
4369            }
4370    
4371            !!!nack ('t343.5');
4372            !!!next-token;
4373            next B;
4374        } elsif ({        } elsif ({
4375                  ## NOTE: Start tags for non-phrasing flow content elements                  ## NOTE: Start tags for non-phrasing flow content elements
4376    
# Line 4431  sub _tree_construction_main ($) { Line 4379  sub _tree_construction_main ($) {
4379                  center => 1, datagrid => 1, details => 1, dialog => 1,                  center => 1, datagrid => 1, details => 1, dialog => 1,
4380                  dir => 1, div => 1, dl => 1, fieldset => 1, figure => 1,                  dir => 1, div => 1, dl => 1, fieldset => 1, figure => 1,
4381                  footer => 1, h1 => 1, h2 => 1, h3 => 1, h4 => 1, h5 => 1,                  footer => 1, h1 => 1, h2 => 1, h3 => 1, h4 => 1, h5 => 1,
4382                  h6 => 1, header => 1, menu => 1, nav => 1, ol => 1, p => 1,                  h6 => 1, header => 1, hgroup => 1,
4383                    menu => 1, nav => 1, ol => 1, p => 1,
4384                  section => 1, ul => 1,                  section => 1, ul => 1,
4385                  ## NOTE: As normal, but drops leading newline                  ## NOTE: As normal, but drops leading newline
4386                  pre => 1, listing => 1,                  pre => 1, listing => 1,
# Line 4515  sub _tree_construction_main ($) { Line 4464  sub _tree_construction_main ($) {
4464            !!!cp ('t386');            !!!cp ('t386');
4465            pop @{$self->{open_elements}};            pop @{$self->{open_elements}};
4466                    
4467            !!!nack ('t386.1');            !!!ack ('t386.1');
4468            !!!next-token;            !!!next-token;
4469          } else {          } else {
4470            !!!nack ('t347.1');            !!!nack ('t347.1');
# Line 5045  sub _tree_construction_main ($) { Line 4994  sub _tree_construction_main ($) {
4994          } elsif ({          } elsif ({
4995                    area => 1, basefont => 1, bgsound => 1, br => 1,                    area => 1, basefont => 1, bgsound => 1, br => 1,
4996                    embed => 1, img => 1, spacer => 1, wbr => 1,                    embed => 1, img => 1, spacer => 1, wbr => 1,
4997                      keygen => 1,
4998                   }->{$token->{tag_name}}) {                   }->{$token->{tag_name}}) {
4999            !!!cp ('t388.1');            !!!cp ('t388.1');
5000            pop @{$self->{open_elements}};            pop @{$self->{open_elements}};
# Line 5070  sub _tree_construction_main ($) { Line 5020  sub _tree_construction_main ($) {
5020          next B;          next B;
5021        }        }
5022      } elsif ($token->{type} == END_TAG_TOKEN) {      } elsif ($token->{type} == END_TAG_TOKEN) {
5023        if ($token->{tag_name} eq 'body') {        if ($token->{tag_name} eq 'body' or $token->{tag_name} eq 'html') {
5024    
5025          ## 1. If not "have an element in scope":          ## 1. If not "have an element in scope":
5026          ## "has a |body| element in scope"          ## "has a |body| element in scope"
# Line 5087  sub _tree_construction_main ($) { Line 5037  sub _tree_construction_main ($) {
5037              }              }
5038            }            }
5039    
5040            ## NOTE: |<marquee></body>|, |<svg><foreignobject></body>|            ## NOTE: |<marquee></body>|, |<svg><foreignobject></body>|,
5041              ## and fragment cases.
5042    
5043            !!!parse-error (type => 'unmatched end tag',            !!!parse-error (type => 'unmatched end tag',
5044                            text => $token->{tag_name}, token => $token);                            text => $token->{tag_name}, token => $token);
5045            ## NOTE: Ignore the token.            ## Ignore the token.  (</body> or </html>)
5046            !!!next-token;            !!!next-token;
5047            next B;            next B;
5048          } # INSCOPE          } # INSCOPE
# Line 5114  sub _tree_construction_main ($) { Line 5065  sub _tree_construction_main ($) {
5065    
5066          ## 3. Switch the insertion mode.          ## 3. Switch the insertion mode.
5067          $self->{insertion_mode} = AFTER_BODY_IM;          $self->{insertion_mode} = AFTER_BODY_IM;
5068          !!!next-token;          if ($token->{tag_name} eq 'body') {
         next B;  
       } elsif ($token->{tag_name} eq 'html') {  
         ## TODO: Update this code.  It seems that the code below is not  
         ## up-to-date, though it has same effect as speced.  
         if (@{$self->{open_elements}} > 1 and  
             $self->{open_elements}->[1]->[1] == BODY_EL) {  
           unless ($self->{open_elements}->[-1]->[1] == BODY_EL) {  
             !!!cp ('t406');  
             !!!parse-error (type => 'not closed',  
                             text => $self->{open_elements}->[1]->[0]  
                                 ->manakai_local_name,  
                             token => $token);  
           } else {  
             !!!cp ('t407');  
           }  
           $self->{insertion_mode} = AFTER_BODY_IM;  
           ## reprocess  
           next B;  
         } else {  
           !!!cp ('t408');  
           !!!parse-error (type => 'unmatched end tag',  
                           text => $token->{tag_name}, token => $token);  
           ## Ignore the token  
5069            !!!next-token;            !!!next-token;
5070            next B;          } else { # html
5071              ## Reprocess.
5072          }          }
5073            next B;
5074        } elsif ({        } elsif ({
5075                  ## NOTE: End tags for non-phrasing flow content elements                  ## NOTE: End tags for non-phrasing flow content elements
5076    
# Line 5148  sub _tree_construction_main ($) { Line 5078  sub _tree_construction_main ($) {
5078                  address => 1, article => 1, aside => 1, blockquote => 1,                  address => 1, article => 1, aside => 1, blockquote => 1,
5079                  center => 1, datagrid => 1, details => 1, dialog => 1,                  center => 1, datagrid => 1, details => 1, dialog => 1,
5080                  dir => 1, div => 1, dl => 1, fieldset => 1, figure => 1,                  dir => 1, div => 1, dl => 1, fieldset => 1, figure => 1,
5081                  footer => 1, header => 1, listing => 1, menu => 1, nav => 1,                  footer => 1, header => 1, hgroup => 1,
5082                    listing => 1, menu => 1, nav => 1,
5083                  ol => 1, pre => 1, section => 1, ul => 1,                  ol => 1, pre => 1, section => 1, ul => 1,
5084    
5085                  ## NOTE: As normal, but ... optional tags                  ## NOTE: As normal, but ... optional tags
# Line 5508  sub set_inner_html ($$$$;$) { Line 5439  sub set_inner_html ($$$$;$) {
5439    my $onerror = $_[1];    my $onerror = $_[1];
5440    my $get_wrapper = $_[2] || sub ($) { return $_[0] };    my $get_wrapper = $_[2] || sub ($) { return $_[0] };
5441    
   ## ISSUE: Should {confident} be true?  
   
5442    my $nt = $node->node_type;    my $nt = $node->node_type;
5443    if ($nt == 9) { # Document (invoke the algorithm with no /context/ element)    if ($nt == 9) { # Document (invoke the algorithm with no /context/ element)
5444      # MUST      # MUST
# Line 5724  sub set_inner_html ($$$$;$) { Line 5653  sub set_inner_html ($$$$;$) {
5653        $anode = $anode->parent_node;        $anode = $anode->parent_node;
5654      } # AN      } # AN
5655    
5656        ## F.5. Set the input stream.
5657        $p->{confident} = 1; ## Confident: irrelevant.
5658    
5659      ## F.6. Start the parser.      ## F.6. Start the parser.
5660      {      {
5661        my $self = $p;        my $self = $p;

Legend:
Removed from v.1.228  
changed lines
  Added in v.1.241

[email protected]
ViewVC Help
Powered by ViewVC 1.1.24