/[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.218 by wakaba, Sat Jul 25 03:38:42 2009 UTC revision 1.238 by wakaba, Sun Sep 6 09:53:29 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 911  sub _tree_construction_initial ($) { Line 916  sub _tree_construction_initial ($) {
916    
917    INITIAL: {    INITIAL: {
918      if ($token->{type} == DOCTYPE_TOKEN) {      if ($token->{type} == DOCTYPE_TOKEN) {
919        ## NOTE: Conformance checkers MAY, instead of reporting "not HTML5"        ## NOTE: Conformance checkers MAY, instead of reporting "not
920        ## error, switch to a conformance checking mode for another        ## HTML5" error, switch to a conformance checking mode for
921        ## language.        ## another language.  (We don't support such mode switchings; it
922          ## is nonsense to do anything different from what browsers do.)
923        my $doctype_name = $token->{name};        my $doctype_name = $token->{name};
924        $doctype_name = '' unless defined $doctype_name;        $doctype_name = '' unless defined $doctype_name;
925        $doctype_name =~ tr/a-z/A-Z/; # ASCII case-insensitive        my $doctype = $self->{document}->create_document_type_definition
926        if (not defined $token->{name} or # <!DOCTYPE>            ($doctype_name);
927            defined $token->{sysid}) {  
928          $doctype_name =~ tr/A-Z/a-z/; # ASCII case-insensitive
929          if ($doctype_name ne 'html') {
930          !!!cp ('t1');          !!!cp ('t1');
931          !!!parse-error (type => 'not HTML5', token => $token);          !!!parse-error (type => 'not HTML5', token => $token);
932        } elsif ($doctype_name ne 'HTML') {        } elsif (defined $token->{pubid}) {
933          !!!cp ('t2');          !!!cp ('t2');
934            ## XXX Obsolete permitted DOCTYPEs
935          !!!parse-error (type => 'not HTML5', token => $token);          !!!parse-error (type => 'not HTML5', token => $token);
936        } elsif (defined $token->{pubid}) {        } elsif (defined $token->{sysid}) {
937          if ($token->{pubid} eq 'XSLT-compat') {          if ($token->{sysid} eq 'about:legacy-compat') {
938            !!!cp ('t1.2');            !!!cp ('t1.2'); ## <!DOCTYPE HTML SYSTEM "about:legacy-compat">
939            !!!parse-error (type => 'XSLT-compat', token => $token,            !!!parse-error (type => 'XSLT-compat', token => $token,
940                            level => $self->{level}->{should});                            level => $self->{level}->{should});
941          } else {          } else {
942            !!!parse-error (type => 'not HTML5', token => $token);            !!!parse-error (type => 'not HTML5', token => $token);
943          }          }
944        } else {        } else { ## <!DOCTYPE HTML>
945          !!!cp ('t3');          !!!cp ('t3');
946          #          #
947        }        }
948                
       my $doctype = $self->{document}->create_document_type_definition  
         ($token->{name}); ## ISSUE: If name is missing (e.g. <!DOCTYPE>)?  
949        ## NOTE: Default value for both |public_id| and |system_id| attributes        ## NOTE: Default value for both |public_id| and |system_id| attributes
950        ## are empty strings, so that we don't set any value in missing cases.        ## are empty strings, so that we don't set any value in missing cases.
951        $doctype->public_id ($token->{pubid}) if defined $token->{pubid};        $doctype->public_id ($token->{pubid}) if defined $token->{pubid};
952        $doctype->system_id ($token->{sysid}) if defined $token->{sysid};        $doctype->system_id ($token->{sysid}) if defined $token->{sysid};
953    
954        ## NOTE: Other DocumentType attributes are null or empty lists.        ## NOTE: Other DocumentType attributes are null or empty lists.
955        ## In Firefox3, |internalSubset| attribute is set to the empty        ## In Firefox3, |internalSubset| attribute is set to the empty
956        ## string, while |null| is an allowed value for the attribute        ## string, while |null| is an allowed value for the attribute
957        ## according to DOM3 Core.        ## according to DOM3 Core.
958        $self->{document}->append_child ($doctype);        $self->{document}->append_child ($doctype);
959                
960        if ($token->{quirks} or $doctype_name ne 'HTML') {        if ($token->{quirks} or $doctype_name ne 'html') {
961          !!!cp ('t4');          !!!cp ('t4');
962          $self->{document}->manakai_compat_mode ('quirks');          $self->{document}->manakai_compat_mode ('quirks');
963        } elsif (defined $token->{pubid}) {        } elsif (defined $token->{pubid}) {
# Line 1419  sub _tree_construction_main ($) { Line 1427  sub _tree_construction_main ($) {
1427      ## Step 3      ## Step 3
1428      ## TODO: Mark as "already executed", if ...      ## TODO: Mark as "already executed", if ...
1429    
1430      ## Step 4      ## Step 4 (HTML5 revision 2702)
1431      $insert->($script_el);      $insert->($script_el);
   
     ## ISSUE: $script_el is not put into the stack  
1432      push @{$self->{open_elements}}, [$script_el, $el_category->{script}];      push @{$self->{open_elements}}, [$script_el, $el_category->{script}];
1433    
1434      ## Step 5      ## Step 5
# Line 1437  sub _tree_construction_main ($) { Line 1443  sub _tree_construction_main ($) {
1443    }; # $script_start_tag    }; # $script_start_tag
1444    
1445    ## NOTE: $open_tables->[-1]->[0] is the "current table" element node.    ## NOTE: $open_tables->[-1]->[0] is the "current table" element node.
1446    ## NOTE: $open_tables->[-1]->[1] is the "tainted" flag.    ## NOTE: $open_tables->[-1]->[1] is the "tainted" flag (OBSOLETE; unused).
1447    ## 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.
1448    my $open_tables = [[$self->{open_elements}->[0]->[0]]];    my $open_tables = [[$self->{open_elements}->[0]->[0]]];
1449    
# Line 1607  sub _tree_construction_main ($) { Line 1613  sub _tree_construction_main ($) {
1613                
1614        ## Step 8        ## Step 8
1615        if ($common_ancestor_node->[1] & TABLE_ROWS_EL) {        if ($common_ancestor_node->[1] & TABLE_ROWS_EL) {
1616            ## Foster parenting.
1617          my $foster_parent_element;          my $foster_parent_element;
1618          my $next_sibling;          my $next_sibling;
1619          OE: for (reverse 0..$#{$self->{open_elements}}) {          OE: for (reverse 0..$#{$self->{open_elements}}) {
1620            if ($self->{open_elements}->[$_]->[1] == TABLE_EL) {            if ($self->{open_elements}->[$_]->[1] == TABLE_EL) {
1621                               my $parent = $self->{open_elements}->[$_]->[0]->parent_node;              !!!cp ('t65.2');
1622                               if (defined $parent and $parent->node_type == 1) {              $foster_parent_element = $self->{open_elements}->[$_ - 1]->[0];
1623                                 !!!cp ('t65.1');              $next_sibling = $self->{open_elements}->[$_]->[0];
1624                                 $foster_parent_element = $parent;              undef $next_sibling
1625                                 $next_sibling = $self->{open_elements}->[$_]->[0];                  unless $next_sibling->parent_node eq $foster_parent_element;
1626                               } else {              last OE;
1627                                 !!!cp ('t65.2');            }
1628                                 $foster_parent_element          } # OE
1629                                   = $self->{open_elements}->[$_ - 1]->[0];          $foster_parent_element ||= $self->{open_elements}->[0]->[0];
1630                               }  
                              last OE;  
                            }  
                          } # OE  
                          $foster_parent_element = $self->{open_elements}->[0]->[0]  
                            unless defined $foster_parent_element;  
1631          $foster_parent_element->insert_before ($last_node->[0], $next_sibling);          $foster_parent_element->insert_before ($last_node->[0], $next_sibling);
1632          $open_tables->[-1]->[1] = 1; # tainted          $open_tables->[-1]->[1] = 1; # tainted
1633        } else {        } else {
# Line 1681  sub _tree_construction_main ($) { Line 1683  sub _tree_construction_main ($) {
1683      $self->{open_elements}->[-1]->[0]->append_child ($_[0]);      $self->{open_elements}->[-1]->[0]->append_child ($_[0]);
1684    }; # $insert_to_current    }; # $insert_to_current
1685    
1686      ## Foster parenting.  Note that there are three "foster parenting"
1687      ## code in the parser: for elements (this one), for texts, and for
1688      ## elements in the AAA code.
1689    my $insert_to_foster = sub {    my $insert_to_foster = sub {
1690      my $child = shift;      my $child = shift;
1691      if ($self->{open_elements}->[-1]->[1] & TABLE_ROWS_EL) {      if ($self->{open_elements}->[-1]->[1] & TABLE_ROWS_EL) {
# Line 1689  sub _tree_construction_main ($) { Line 1694  sub _tree_construction_main ($) {
1694        my $next_sibling;        my $next_sibling;
1695        OE: for (reverse 0..$#{$self->{open_elements}}) {        OE: for (reverse 0..$#{$self->{open_elements}}) {
1696          if ($self->{open_elements}->[$_]->[1] == TABLE_EL) {          if ($self->{open_elements}->[$_]->[1] == TABLE_EL) {
1697                               my $parent = $self->{open_elements}->[$_]->[0]->parent_node;            !!!cp ('t71');
1698                               if (defined $parent and $parent->node_type == 1) {            $foster_parent_element = $self->{open_elements}->[$_ - 1]->[0];
1699                                 !!!cp ('t70');            $next_sibling = $self->{open_elements}->[$_]->[0];
1700                                 $foster_parent_element = $parent;            undef $next_sibling
1701                                 $next_sibling = $self->{open_elements}->[$_]->[0];                unless $next_sibling->parent_node eq $foster_parent_element;
1702                               } else {            last OE;
1703                                 !!!cp ('t71');          }
1704                                 $foster_parent_element        } # OE
1705                                   = $self->{open_elements}->[$_ - 1]->[0];        $foster_parent_element ||= $self->{open_elements}->[0]->[0];
1706                               }  
1707                               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);  
1708        $open_tables->[-1]->[1] = 1; # tainted        $open_tables->[-1]->[1] = 1; # tainted
1709      } else {      } else {
1710        !!!cp ('t72');        !!!cp ('t72');
# Line 1733  sub _tree_construction_main ($) { Line 1732  sub _tree_construction_main ($) {
1732    ## document.write ("b")</script>|    ## document.write ("b")</script>|
1733    
1734    B: while (1) {    B: while (1) {
1735    
1736        ## The "in table text" insertion mode.
1737        if ($self->{insertion_mode} & TABLE_IMS and
1738            not $self->{insertion_mode} & IN_FOREIGN_CONTENT_IM and
1739            not $self->{insertion_mode} & IN_CDATA_RCDATA_IM) {
1740          C: {
1741            my $s;
1742            if ($token->{type} == CHARACTER_TOKEN) {
1743              !!!cp ('t194');
1744              $self->{pending_chars} ||= [];
1745              push @{$self->{pending_chars}}, $token;
1746              !!!next-token;
1747              next B;
1748            } else {
1749              if ($self->{pending_chars}) {
1750                $s = join '', map { $_->{data} } @{$self->{pending_chars}};
1751                delete $self->{pending_chars};
1752                if ($s =~ /[^\x09\x0A\x0C\x0D\x20]/) {
1753                  !!!cp ('t195');
1754                  #
1755                } else {
1756                  !!!cp ('t195.1');
1757                  #$self->{open_elements}->[-1]->[0]->manakai_append_text ($s);
1758                  $self->{open_elements}->[-1]->[0]->append_child
1759                      ($self->{document}->create_text_node ($s));
1760                  last C;
1761                }
1762              } else {
1763                !!!cp ('t195.2');
1764                last C;
1765              }
1766            }
1767    
1768            ## Foster parenting.
1769            !!!parse-error (type => 'in table:#text', token => $token);
1770    
1771            ## NOTE: As if in body, but insert into the foster parent element.
1772            $reconstruct_active_formatting_elements->($insert_to_foster);
1773                
1774            if ($self->{open_elements}->[-1]->[1] & TABLE_ROWS_EL) {
1775              # MUST
1776              my $foster_parent_element;
1777              my $next_sibling;
1778              OE: for (reverse 0..$#{$self->{open_elements}}) {
1779                if ($self->{open_elements}->[$_]->[1] == TABLE_EL) {
1780                  !!!cp ('t197');
1781                  $foster_parent_element = $self->{open_elements}->[$_ - 1]->[0];
1782                  $next_sibling = $self->{open_elements}->[$_]->[0];
1783                  undef $next_sibling
1784                    unless $next_sibling->parent_node eq $foster_parent_element;
1785                  last OE;
1786                }
1787              } # OE
1788              $foster_parent_element ||= $self->{open_elements}->[0]->[0];
1789    
1790              !!!cp ('t199');
1791              $foster_parent_element->insert_before
1792                  ($self->{document}->create_text_node ($s), $next_sibling);
1793    
1794              $open_tables->[-1]->[1] = 1; # tainted
1795              $open_tables->[-1]->[2] = 1; # ~node inserted
1796            } else {
1797              ## NOTE: Fragment case or in a foster parent'ed element
1798              ## (e.g. |<table><span>a|).  In fragment case, whether the
1799              ## character is appended to existing node or a new node is
1800              ## created is irrelevant, since the foster parent'ed nodes
1801              ## are discarded and fragment parsing does not invoke any
1802              ## script.
1803              !!!cp ('t200');
1804              $self->{open_elements}->[-1]->[0]->manakai_append_text ($s);
1805            }
1806          } # C
1807        } # TABLE_IMS
1808    
1809      if ($token->{type} == DOCTYPE_TOKEN) {      if ($token->{type} == DOCTYPE_TOKEN) {
1810        !!!cp ('t73');        !!!cp ('t73');
1811        !!!parse-error (type => 'in html:#DOCTYPE', token => $token);        !!!parse-error (type => 'in html:#DOCTYPE', token => $token);
# Line 1874  sub _tree_construction_main ($) { Line 1947  sub _tree_construction_main ($) {
1947          } elsif ({          } elsif ({
1948                    b => 1, big => 1, blockquote => 1, body => 1, br => 1,                    b => 1, big => 1, blockquote => 1, body => 1, br => 1,
1949                    center => 1, code => 1, dd => 1, div => 1, dl => 1, dt => 1,                    center => 1, code => 1, dd => 1, div => 1, dl => 1, dt => 1,
1950                    em => 1, embed => 1, font => 1, h1 => 1, h2 => 1, h3 => 1,                    em => 1, embed => 1, h1 => 1, h2 => 1, h3 => 1,
1951                    h4 => 1, h5 => 1, h6 => 1, head => 1, hr => 1, i => 1,                    h4 => 1, h5 => 1, h6 => 1, head => 1, hr => 1, i => 1,
1952                    img => 1, li => 1, listing => 1, menu => 1, meta => 1,                    img => 1, li => 1, listing => 1, menu => 1, meta => 1,
1953                    nobr => 1, ol => 1, p => 1, pre => 1, ruby => 1, s => 1,                    nobr => 1, ol => 1, p => 1, pre => 1, ruby => 1, s => 1,
1954                    small => 1, span => 1, strong => 1, strike => 1, sub => 1,                    small => 1, span => 1, strong => 1, strike => 1, sub => 1,
1955                    sup => 1, table => 1, tt => 1, u => 1, ul => 1, var => 1,                    sup => 1, table => 1, tt => 1, u => 1, ul => 1, var => 1,
1956                   }->{$token->{tag_name}}) {                   }->{$token->{tag_name}} or
1957                     ($token->{tag_name} eq 'font' and
1958                      ($token->{attributes}->{color} or
1959                       $token->{attributes}->{face} or
1960                       $token->{attributes}->{size}))) {
1961            !!!cp ('t87.2');            !!!cp ('t87.2');
1962            !!!parse-error (type => 'not closed',            !!!parse-error (type => 'not closed',
1963                            text => $self->{open_elements}->[-1]->[0]                            text => $self->{open_elements}->[-1]->[0]
# Line 1956  sub _tree_construction_main ($) { Line 2033  sub _tree_construction_main ($) {
2033          }          }
2034        } elsif ($token->{type} == END_TAG_TOKEN) {        } elsif ($token->{type} == END_TAG_TOKEN) {
2035          ## NOTE: "using the rules for secondary insertion mode" then "continue"          ## NOTE: "using the rules for secondary insertion mode" then "continue"
2036          !!!cp ('t87.5');          if ($token->{tag_name} eq 'script') {
2037          #            !!!cp ('t87.41');
2038              #
2039              ## XXXscript: Execute script here.
2040            } else {
2041              !!!cp ('t87.5');
2042              #
2043            }
2044        } elsif ($token->{type} == END_OF_FILE_TOKEN) {        } elsif ($token->{type} == END_OF_FILE_TOKEN) {
2045          !!!cp ('t87.6');          !!!cp ('t87.6');
2046          !!!parse-error (type => 'not closed',          !!!parse-error (type => 'not closed',
# Line 2141  sub _tree_construction_main ($) { Line 2224  sub _tree_construction_main ($) {
2224            !!!ack ('t103.1');            !!!ack ('t103.1');
2225            !!!next-token;            !!!next-token;
2226            next B;            next B;
2227          } elsif ($token->{tag_name} eq 'command' or          } elsif ($token->{tag_name} eq 'command') {
                  $token->{tag_name} eq 'eventsource') {  
2228            if ($self->{insertion_mode} == IN_HEAD_IM) {            if ($self->{insertion_mode} == IN_HEAD_IM) {
2229              ## NOTE: If the insertion mode at the time of the emission              ## NOTE: If the insertion mode at the time of the emission
2230              ## of the token was "before head", $self->{insertion_mode}              ## of the token was "before head", $self->{insertion_mode}
# Line 2257  sub _tree_construction_main ($) { Line 2339  sub _tree_construction_main ($) {
2339    
2340            ## NOTE: There is a "as if in head" code clone.            ## NOTE: There is a "as if in head" code clone.
2341            $parse_rcdata->(RCDATA_CONTENT_MODEL);            $parse_rcdata->(RCDATA_CONTENT_MODEL);
2342            ## ISSUE: A spec bug [Bug 6038]  
2343              ## NOTE: At this point the stack of open elements contain
2344              ## the |head| element (index == -2) and the |script| element
2345              ## (index == -1).  In the "after head" insertion mode the
2346              ## |head| element is inserted only for the purpose of
2347              ## providing the context for the |script| element, and
2348              ## therefore we can now and have to remove the element from
2349              ## the stack.
2350            splice @{$self->{open_elements}}, -2, 1, () # <head>            splice @{$self->{open_elements}}, -2, 1, () # <head>
2351                if ($self->{insertion_mode} & IM_MASK) == AFTER_HEAD_IM;                if ($self->{insertion_mode} & IM_MASK) == AFTER_HEAD_IM;
2352            next B;            next B;
# Line 2400  sub _tree_construction_main ($) { Line 2489  sub _tree_construction_main ($) {
2489              ## reprocess              ## reprocess
2490              !!!ack-later;              !!!ack-later;
2491              next B;              next B;
2492            } elsif ($token->{type} == END_TAG_TOKEN) {        } elsif ($token->{type} == END_TAG_TOKEN) {
2493              if ($token->{tag_name} eq 'head') {          ## "Before head", "in head", and "after head" insertion modes
2494                if ($self->{insertion_mode} == BEFORE_HEAD_IM) {          ## ignore most of end tags.  Exceptions are "body", "html",
2495                  !!!cp ('t132');          ## and "br" end tags.  "Before head" and "in head" insertion
2496                  ## As if <head>          ## modes also recognize "head" end tag.  "In head noscript"
2497                  !!!create-element ($self->{head_element}, $HTML_NS, 'head',, $token);          ## insertion modes ignore end tags except for "noscript" and
2498                  $self->{open_elements}->[-1]->[0]->append_child ($self->{head_element});          ## "br".
                 push @{$self->{open_elements}},  
                     [$self->{head_element}, $el_category->{head}];  
2499    
2500                  ## Reprocess in the "in head" insertion mode...          if ($token->{tag_name} eq 'head') {
2501                  pop @{$self->{open_elements}};            if ($self->{insertion_mode} == BEFORE_HEAD_IM) {
2502                  $self->{insertion_mode} = AFTER_HEAD_IM;              !!!cp ('t132');
2503                  !!!next-token;              ## As if <head>
2504                  next B;              !!!create-element ($self->{head_element}, $HTML_NS, 'head',, $token);
2505                } elsif ($self->{insertion_mode} == IN_HEAD_NOSCRIPT_IM) {              $self->{open_elements}->[-1]->[0]->append_child ($self->{head_element});
2506                  !!!cp ('t133');              push @{$self->{open_elements}},
2507                  ## As if </noscript>                  [$self->{head_element}, $el_category->{head}];
2508                  pop @{$self->{open_elements}};  
2509                  !!!parse-error (type => 'in noscript:/',              ## Reprocess in the "in head" insertion mode...
2510                                  text => 'head', token => $token);              pop @{$self->{open_elements}};
2511                                $self->{insertion_mode} = AFTER_HEAD_IM;
2512                  ## Reprocess in the "in head" insertion mode...              !!!next-token;
2513                  pop @{$self->{open_elements}};              next B;
2514                  $self->{insertion_mode} = AFTER_HEAD_IM;            } elsif ($self->{insertion_mode} == IN_HEAD_NOSCRIPT_IM) {
2515                  !!!next-token;              !!!cp ('t133');
2516                  next B;              #
2517                } elsif ($self->{insertion_mode} == IN_HEAD_IM) {            } elsif ($self->{insertion_mode} == IN_HEAD_IM) {
2518                  !!!cp ('t134');              !!!cp ('t134');
2519                  pop @{$self->{open_elements}};              pop @{$self->{open_elements}};
2520                  $self->{insertion_mode} = AFTER_HEAD_IM;              $self->{insertion_mode} = AFTER_HEAD_IM;
2521                  !!!next-token;              !!!next-token;
2522                  next B;              next B;
2523                } elsif ($self->{insertion_mode} == AFTER_HEAD_IM) {            } elsif ($self->{insertion_mode} == AFTER_HEAD_IM) {
2524                  !!!cp ('t134.1');              !!!cp ('t134.1');
2525                  !!!parse-error (type => 'unmatched end tag', text => 'head',              #
2526                                  token => $token);            } else {
2527                  ## Ignore the token              die "$0: $self->{insertion_mode}: Unknown insertion mode";
2528                  !!!next-token;            }
2529                  next B;          } elsif ($token->{tag_name} eq 'noscript') {
2530                } else {            if ($self->{insertion_mode} == IN_HEAD_NOSCRIPT_IM) {
2531                  die "$0: $self->{insertion_mode}: Unknown insertion mode";              !!!cp ('t136');
2532                }              pop @{$self->{open_elements}};
2533              } elsif ($token->{tag_name} eq 'noscript') {              $self->{insertion_mode} = IN_HEAD_IM;
2534                if ($self->{insertion_mode} == IN_HEAD_NOSCRIPT_IM) {              !!!next-token;
2535                  !!!cp ('t136');              next B;
2536                  pop @{$self->{open_elements}};            } else {
2537                  $self->{insertion_mode} = IN_HEAD_IM;              !!!cp ('t138');
2538                  !!!next-token;              #
2539                  next B;            }
2540                } elsif ($self->{insertion_mode} == BEFORE_HEAD_IM or          } elsif ({
2541                         $self->{insertion_mode} == AFTER_HEAD_IM) {              body => ($self->{insertion_mode} != IN_HEAD_NOSCRIPT_IM),
2542                  !!!cp ('t137');              html => ($self->{insertion_mode} != IN_HEAD_NOSCRIPT_IM),
2543                  !!!parse-error (type => 'unmatched end tag',              br => 1,
2544                                  text => 'noscript', token => $token);          }->{$token->{tag_name}}) {
2545                  ## Ignore the token ## ISSUE: An issue in the spec.            if ($self->{insertion_mode} == BEFORE_HEAD_IM) {
2546                  !!!next-token;              !!!cp ('t142.2');
2547                  next B;              ## (before head) as if <head>, (in head) as if </head>
2548                } else {              !!!create-element ($self->{head_element}, $HTML_NS, 'head',, $token);
2549                  !!!cp ('t138');              $self->{open_elements}->[-1]->[0]->append_child ($self->{head_element});
2550                  #              $self->{insertion_mode} = AFTER_HEAD_IM;
               }  
             } 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') {  
               if ($self->{insertion_mode} == BEFORE_HEAD_IM) {  
                 !!!cp ('t142.2');  
                 ## (before head) as if <head>, (in head) as if </head>  
                 !!!create-element ($self->{head_element}, $HTML_NS, 'head',, $token);  
                 $self->{open_elements}->[-1]->[0]->append_child ($self->{head_element});  
                 $self->{insertion_mode} = AFTER_HEAD_IM;  
2551        
2552                  ## Reprocess in the "after head" insertion mode...              ## Reprocess in the "after head" insertion mode...
2553                } elsif ($self->{insertion_mode} == IN_HEAD_IM) {            } elsif ($self->{insertion_mode} == IN_HEAD_IM) {
2554                  !!!cp ('t143.2');              !!!cp ('t143.2');
2555                  ## As if </head>              ## As if </head>
2556                  pop @{$self->{open_elements}};              pop @{$self->{open_elements}};
2557                  $self->{insertion_mode} = AFTER_HEAD_IM;              $self->{insertion_mode} = AFTER_HEAD_IM;
2558        
2559                  ## Reprocess in the "after head" insertion mode...              ## Reprocess in the "after head" insertion mode...
2560                } elsif ($self->{insertion_mode} == IN_HEAD_NOSCRIPT_IM) {            } elsif ($self->{insertion_mode} == IN_HEAD_NOSCRIPT_IM) {
2561                  !!!cp ('t143.3');              !!!cp ('t143.3');
2562                  ## NOTE: Two parse errors for <head><noscript></br>              ## NOTE: Two parse errors for <head><noscript></br>
2563                  !!!parse-error (type => 'unmatched end tag',              !!!parse-error (type => 'unmatched end tag',
2564                                  text => 'br', token => $token);                              text => $token->{tag_name}, token => $token);
2565                  ## As if </noscript>              ## As if </noscript>
2566                  pop @{$self->{open_elements}};              pop @{$self->{open_elements}};
2567                  $self->{insertion_mode} = IN_HEAD_IM;              $self->{insertion_mode} = IN_HEAD_IM;
   
                 ## Reprocess in the "in head" insertion mode...  
                 ## As if </head>  
                 pop @{$self->{open_elements}};  
                 $self->{insertion_mode} = AFTER_HEAD_IM;  
   
                 ## Reprocess in the "after head" insertion mode...  
               } elsif ($self->{insertion_mode} == AFTER_HEAD_IM) {  
                 !!!cp ('t143.4');  
                 #  
               } else {  
                 die "$0: $self->{insertion_mode}: Unknown insertion mode";  
               }  
   
               ## ISSUE: does not agree with IE7 - it doesn't ignore </br>.  
               !!!parse-error (type => 'unmatched end tag',  
                               text => 'br', token => $token);  
               ## Ignore the token  
               !!!next-token;  
               next B;  
             } else {  
               !!!cp ('t145');  
               !!!parse-error (type => 'unmatched end tag',  
                               text => $token->{tag_name}, token => $token);  
               ## Ignore the token  
               !!!next-token;  
               next B;  
             }  
2568    
2569              if ($self->{insertion_mode} == IN_HEAD_NOSCRIPT_IM) {              ## Reprocess in the "in head" insertion mode...
2570                !!!cp ('t146');              ## As if </head>
2571                ## As if </noscript>              pop @{$self->{open_elements}};
2572                pop @{$self->{open_elements}};              $self->{insertion_mode} = AFTER_HEAD_IM;
               !!!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}};  
2573    
2574                ## Reprocess in the "after head" insertion mode...              ## Reprocess in the "after head" insertion mode...
2575              } elsif ($self->{insertion_mode} == IN_HEAD_IM) {            } elsif ($self->{insertion_mode} == AFTER_HEAD_IM) {
2576                !!!cp ('t147');              !!!cp ('t143.4');
2577                ## As if </head>              #
2578                pop @{$self->{open_elements}};            } else {
2579                die "$0: $self->{insertion_mode}: Unknown insertion mode";
2580              }
2581    
2582                ## Reprocess in the "after head" insertion mode...            ## "after head" insertion mode
2583              } elsif ($self->{insertion_mode} == BEFORE_HEAD_IM) {            ## As if <body>
2584  ## ISSUE: This case cannot be reached?            !!!insert-element ('body',, $token);
2585                !!!cp ('t148');            $self->{insertion_mode} = IN_BODY_IM;
2586                !!!parse-error (type => 'unmatched end tag',            ## Reprocess.
2587                                text => $token->{tag_name}, token => $token);            next B;
2588                ## Ignore the token ## ISSUE: An issue in the spec.          }
               !!!next-token;  
               next B;  
             } else {  
               !!!cp ('t149');  
             }  
2589    
2590              ## "after head" insertion mode          ## End tags are ignored by default.
2591              ## As if <body>          !!!cp ('t145');
2592              !!!insert-element ('body',, $token);          !!!parse-error (type => 'unmatched end tag',
2593              $self->{insertion_mode} = IN_BODY_IM;                          text => $token->{tag_name}, token => $token);
2594              ## reprocess          ## Ignore the token.
2595              next B;          !!!next-token;
2596            next B;
2597        } elsif ($token->{type} == END_OF_FILE_TOKEN) {        } elsif ($token->{type} == END_OF_FILE_TOKEN) {
2598          if ($self->{insertion_mode} == BEFORE_HEAD_IM) {          if ($self->{insertion_mode} == BEFORE_HEAD_IM) {
2599            !!!cp ('t149.1');            !!!cp ('t149.1');
# Line 3008  sub _tree_construction_main ($) { Line 3021  sub _tree_construction_main ($) {
3021        $insert = $insert_to_current;        $insert = $insert_to_current;
3022        #        #
3023      } elsif ($self->{insertion_mode} & TABLE_IMS) {      } elsif ($self->{insertion_mode} & TABLE_IMS) {
3024        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) {  
3025          if ({          if ({
3026               tr => (($self->{insertion_mode} & IM_MASK) != IN_ROW_IM),               tr => (($self->{insertion_mode} & IM_MASK) != IN_ROW_IM),
3027               th => 1, td => 1,               th => 1, td => 1,
# Line 3348  sub _tree_construction_main ($) { Line 3289  sub _tree_construction_main ($) {
3289            !!!ack-later;            !!!ack-later;
3290            next B;            next B;
3291          } elsif ($token->{tag_name} eq 'style') {          } elsif ($token->{tag_name} eq 'style') {
3292            if (not $open_tables->[-1]->[1]) { # tainted            !!!cp ('t227.8');
3293              !!!cp ('t227.8');            ## NOTE: This is a "as if in head" code clone.
3294              ## NOTE: This is a "as if in head" code clone.            $parse_rcdata->(CDATA_CONTENT_MODEL);
3295              $parse_rcdata->(CDATA_CONTENT_MODEL);            $open_tables->[-1]->[2] = 0 if @$open_tables; # ~node inserted
3296              $open_tables->[-1]->[2] = 0 if @$open_tables; # ~node inserted            next B;
             next B;  
           } else {  
             !!!cp ('t227.7');  
             #  
           }  
3297          } elsif ($token->{tag_name} eq 'script') {          } elsif ($token->{tag_name} eq 'script') {
3298            if (not $open_tables->[-1]->[1]) { # tainted            !!!cp ('t227.6');
3299              !!!cp ('t227.6');            ## NOTE: This is a "as if in head" code clone.
3300              ## NOTE: This is a "as if in head" code clone.            $script_start_tag->();
3301              $script_start_tag->();            $open_tables->[-1]->[2] = 0 if @$open_tables; # ~node inserted
3302              $open_tables->[-1]->[2] = 0 if @$open_tables; # ~node inserted            next B;
             next B;  
           } else {  
             !!!cp ('t227.5');  
             #  
           }  
3303          } elsif ($token->{tag_name} eq 'input') {          } elsif ($token->{tag_name} eq 'input') {
3304            if (not $open_tables->[-1]->[1]) { # tainted            if ($token->{attributes}->{type}) {
3305              if ($token->{attributes}->{type}) { ## TODO: case              my $type = $token->{attributes}->{type}->{value};
3306                my $type = lc $token->{attributes}->{type}->{value};              $type =~ tr/A-Z/a-z/; ## ASCII case-insensitive.
3307                if ($type eq 'hidden') {              if ($type eq 'hidden') {
3308                  !!!cp ('t227.3');                !!!cp ('t227.3');
3309                  !!!parse-error (type => 'in table',                !!!parse-error (type => 'in table',
3310                                  text => $token->{tag_name}, token => $token);                                text => $token->{tag_name}, token => $token);
3311    
3312                  !!!insert-element ($token->{tag_name}, $token->{attributes}, $token);                !!!insert-element ($token->{tag_name}, $token->{attributes}, $token);
3313                  $open_tables->[-1]->[2] = 0 if @$open_tables; # ~node inserted                $open_tables->[-1]->[2] = 0 if @$open_tables; # ~node inserted
3314    
3315                  ## TODO: form element pointer                ## TODO: form element pointer
3316    
3317                  pop @{$self->{open_elements}};                pop @{$self->{open_elements}};
3318    
3319                  !!!next-token;                !!!next-token;
3320                  !!!ack ('t227.2.1');                !!!ack ('t227.2.1');
3321                  next B;                next B;
               } else {  
                 !!!cp ('t227.2');  
                 #  
               }  
3322              } else {              } else {
3323                !!!cp ('t227.1');                !!!cp ('t227.1');
3324                #                #
# Line 3846  sub _tree_construction_main ($) { Line 3773  sub _tree_construction_main ($) {
3773                     tbody => 1, tfoot => 1, thead => 1,                     tbody => 1, tfoot => 1, thead => 1,
3774                     tr => 1, td => 1, th => 1,                     tr => 1, td => 1, th => 1,
3775                    }->{$token->{tag_name}})) {                    }->{$token->{tag_name}})) {
3776            ## TODO: The type below is not good - <select> is replaced by </select>  
3777            !!!parse-error (type => 'not closed', text => 'select',            ## 1. Parse error.
3778                            token => $token);            if ($token->{tag_name} eq 'select') {
3779            ## NOTE: As if the token were </select> (<select> case) or                !!!parse-error (type => 'select in select', ## XXX: documentation
3780            ## as if there were </select> (otherwise).                                token => $token);
3781            ## have an element in table scope            } else {
3782                !!!parse-error (type => 'not closed', text => 'select',
3783                                token => $token);
3784              }
3785    
3786              ## 2./<select>-1. Unless "have an element in table scope" (select):
3787            my $i;            my $i;
3788            INSCOPE: for (reverse 0..$#{$self->{open_elements}}) {            INSCOPE: for (reverse 0..$#{$self->{open_elements}}) {
3789              my $node = $self->{open_elements}->[$_];              my $node = $self->{open_elements}->[$_];
# Line 3866  sub _tree_construction_main ($) { Line 3798  sub _tree_construction_main ($) {
3798            } # INSCOPE            } # INSCOPE
3799            unless (defined $i) {            unless (defined $i) {
3800              !!!cp ('t280');              !!!cp ('t280');
3801              !!!parse-error (type => 'unmatched end tag',              if ($token->{tag_name} eq 'select') {
3802                              text => 'select', token => $token);                ## NOTE: This error would be raised when
3803              ## Ignore the token                ## |select.innerHTML = '<select>'| is executed; in this
3804                  ## case two errors, "select in select" and "unmatched
3805                  ## end tags" are reported to the user, the latter might
3806                  ## be confusing but this is what the spec requires.
3807                  !!!parse-error (type => 'unmatched end tag',
3808                                  text => 'select',
3809                                  token => $token);
3810                }
3811                ## Ignore the token.
3812              !!!nack ('t280.1');              !!!nack ('t280.1');
3813              !!!next-token;              !!!next-token;
3814              next B;              next B;
3815            }            }
3816    
3817              ## 3. Otherwise, as if there were <select>:
3818                                
3819            !!!cp ('t281');            !!!cp ('t281');
3820            splice @{$self->{open_elements}}, $i;            splice @{$self->{open_elements}}, $i;
# Line 3889  sub _tree_construction_main ($) { Line 3831  sub _tree_construction_main ($) {
3831              ## Reprocess the token.              ## Reprocess the token.
3832              next B;              next B;
3833            }            }
3834            } elsif ($token->{tag_name} eq 'script') {
3835              !!!cp ('t281.3');
3836              ## NOTE: This is an "as if in head" code clone
3837              $script_start_tag->();
3838              next B;
3839          } else {          } else {
3840            !!!cp ('t282');            !!!cp ('t282');
3841            !!!parse-error (type => 'in select',            !!!parse-error (type => 'in select',
# Line 4300  sub _tree_construction_main ($) { Line 4247  sub _tree_construction_main ($) {
4247          $parse_rcdata->(CDATA_CONTENT_MODEL);          $parse_rcdata->(CDATA_CONTENT_MODEL);
4248          next B;          next B;
4249        } elsif ({        } elsif ({
4250                  base => 1, command => 1, eventsource => 1, link => 1,                  base => 1, command => 1, link => 1,
4251                 }->{$token->{tag_name}}) {                 }->{$token->{tag_name}}) {
4252          !!!cp ('t334');          !!!cp ('t334');
4253          ## 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 4398  sub _tree_construction_main ($) { Line 4345  sub _tree_construction_main ($) {
4345                  center => 1, datagrid => 1, details => 1, dialog => 1,                  center => 1, datagrid => 1, details => 1, dialog => 1,
4346                  dir => 1, div => 1, dl => 1, fieldset => 1, figure => 1,                  dir => 1, div => 1, dl => 1, fieldset => 1, figure => 1,
4347                  footer => 1, h1 => 1, h2 => 1, h3 => 1, h4 => 1, h5 => 1,                  footer => 1, h1 => 1, h2 => 1, h3 => 1, h4 => 1, h5 => 1,
4348                  h6 => 1, header => 1, menu => 1, nav => 1, ol => 1, p => 1,                  h6 => 1, header => 1, hgroup => 1,
4349                    menu => 1, nav => 1, ol => 1, p => 1,
4350                  section => 1, ul => 1,                  section => 1, ul => 1,
4351                  ## NOTE: As normal, but drops leading newline                  ## NOTE: As normal, but drops leading newline
4352                  pre => 1, listing => 1,                  pre => 1, listing => 1,
# Line 4408  sub _tree_construction_main ($) { Line 4356  sub _tree_construction_main ($) {
4356                  table => 1,                  table => 1,
4357                  hr => 1,                  hr => 1,
4358                 }->{$token->{tag_name}}) {                 }->{$token->{tag_name}}) {
4359    
4360            ## 1. When there is an opening |form| element:
4361          if ($token->{tag_name} eq 'form' and defined $self->{form_element}) {          if ($token->{tag_name} eq 'form' and defined $self->{form_element}) {
4362            !!!cp ('t350');            !!!cp ('t350');
4363            !!!parse-error (type => 'in form:form', token => $token);            !!!parse-error (type => 'in form:form', token => $token);
# Line 4417  sub _tree_construction_main ($) { Line 4367  sub _tree_construction_main ($) {
4367            next B;            next B;
4368          }          }
4369    
4370            ## 2. Close the |p| element, if any.
4371          if ($token->{tag_name} ne 'table' or # The Hixie Quirk          if ($token->{tag_name} ne 'table' or # The Hixie Quirk
4372              $self->{document}->manakai_compat_mode ne 'quirks') {              $self->{document}->manakai_compat_mode ne 'quirks') {
4373            ## has a p element in scope            ## has a p element in scope
# Line 4433  sub _tree_construction_main ($) { Line 4384  sub _tree_construction_main ($) {
4384              }              }
4385            } # INSCOPE            } # INSCOPE
4386          }          }
4387              
4388            ## 3. Close the opening <hn> element, if any.
4389            if ({h1 => 1, h2 => 1, h3 => 1,
4390                 h4 => 1, h5 => 1, h6 => 1}->{$token->{tag_name}}) {
4391              if ($self->{open_elements}->[-1]->[1] == HEADING_EL) {
4392                !!!parse-error (type => 'not closed',
4393                                text => $self->{open_elements}->[-1]->[0]->manakai_local_name,
4394                                token => $token);
4395                pop @{$self->{open_elements}};
4396              }
4397            }
4398    
4399            ## 4. Insertion.
4400          !!!insert-element-t ($token->{tag_name}, $token->{attributes}, $token);          !!!insert-element-t ($token->{tag_name}, $token->{attributes}, $token);
4401          if ($token->{tag_name} eq 'pre' or $token->{tag_name} eq 'listing') {          if ($token->{tag_name} eq 'pre' or $token->{tag_name} eq 'listing') {
4402            !!!nack ('t346.1');            !!!nack ('t346.1');
# Line 4477  sub _tree_construction_main ($) { Line 4440  sub _tree_construction_main ($) {
4440        } elsif ($token->{tag_name} eq 'li') {        } elsif ($token->{tag_name} eq 'li') {
4441          ## NOTE: As normal, but imply </li> when there's another <li> ...          ## NOTE: As normal, but imply </li> when there's another <li> ...
4442    
4443          ## NOTE: Special, Scope (<li><foo><li> == <li><foo><li/></foo></li>)          ## NOTE: Special, Scope (<li><foo><li> == <li><foo><li/></foo></li>)::
4444            ## Interpreted as <li><foo/></li><li/> (non-conforming)            ## Interpreted as <li><foo/></li><li/> (non-conforming):
4445            ## blockquote (O9.27), center (O), dd (Fx3, O, S3.1.2, IE7),            ## blockquote (O9.27), center (O), dd (Fx3, O, S3.1.2, IE7),
4446            ## dt (Fx, O, S, IE), dl (O), fieldset (O, S, IE), form (Fx, O, S),            ## dt (Fx, O, S, IE), dl (O), fieldset (O, S, IE), form (Fx, O, S),
4447            ## hn (O), pre (O), applet (O, S), button (O, S), marquee (Fx, O, S),            ## hn (O), pre (O), applet (O, S), button (O, S), marquee (Fx, O, S),
4448            ## object (Fx)            ## object (Fx)
4449            ## Generate non-tree (non-conforming)            ## Generate non-tree (non-conforming):
4450            ## basefont (IE7 (where basefont is non-void)), center (IE),            ## basefont (IE7 (where basefont is non-void)), center (IE),
4451            ## form (IE), hn (IE)            ## form (IE), hn (IE)
4452          ## address, div, p (<li><foo><li> == <li><foo/></li><li/>)          ## address, div, p (<li><foo><li> == <li><foo/></li><li/>)::
4453            ## Interpreted as <li><foo><li/></foo></li> (non-conforming)            ## Interpreted as <li><foo><li/></foo></li> (non-conforming):
4454            ## div (Fx, S)            ## div (Fx, S)
4455    
4456          my $non_optional;          my $non_optional;
# Line 4834  sub _tree_construction_main ($) { Line 4797  sub _tree_construction_main ($) {
4797            next B;            next B;
4798          }          }
4799        } elsif ($token->{tag_name} eq 'textarea') {        } elsif ($token->{tag_name} eq 'textarea') {
4800          ## Step 1          ## 1. Insert
4801          !!!insert-element-t ($token->{tag_name}, $token->{attributes}, $token);          !!!insert-element-t ($token->{tag_name}, $token->{attributes}, $token);
4802                    
4803          ## Step 2          ## Step 2 # XXX
4804          ## TODO: $self->{form_element} if defined          ## TODO: $self->{form_element} if defined
4805    
4806          ## Step 3          ## 2. Drop U+000A LINE FEED
4807          $self->{ignore_newline} = 1;          $self->{ignore_newline} = 1;
4808    
4809          ## Step 4          ## 3. RCDATA
         ## ISSUE: This step is wrong. (r2302 enbugged)  
   
         ## Step 5  
4810          $self->{content_model} = RCDATA_CONTENT_MODEL;          $self->{content_model} = RCDATA_CONTENT_MODEL;
4811          delete $self->{escape}; # MUST          delete $self->{escape}; # MUST
4812    
4813          ## Step 6-7          ## 4., 6. Insertion mode
4814          $self->{insertion_mode} |= IN_CDATA_RCDATA_IM;          $self->{insertion_mode} |= IN_CDATA_RCDATA_IM;
4815    
4816            ## XXX: 5. frameset-ok flag
4817    
4818          !!!nack ('t392.1');          !!!nack ('t392.1');
4819          !!!next-token;          !!!next-token;
4820          next B;          next B;
# Line 4998  sub _tree_construction_main ($) { Line 4960  sub _tree_construction_main ($) {
4960          } elsif ({          } elsif ({
4961                    area => 1, basefont => 1, bgsound => 1, br => 1,                    area => 1, basefont => 1, bgsound => 1, br => 1,
4962                    embed => 1, img => 1, spacer => 1, wbr => 1,                    embed => 1, img => 1, spacer => 1, wbr => 1,
4963                      keygen => 1,
4964                   }->{$token->{tag_name}}) {                   }->{$token->{tag_name}}) {
4965            !!!cp ('t388.1');            !!!cp ('t388.1');
4966            pop @{$self->{open_elements}};            pop @{$self->{open_elements}};
# Line 5024  sub _tree_construction_main ($) { Line 4987  sub _tree_construction_main ($) {
4987        }        }
4988      } elsif ($token->{type} == END_TAG_TOKEN) {      } elsif ($token->{type} == END_TAG_TOKEN) {
4989        if ($token->{tag_name} eq 'body') {        if ($token->{tag_name} eq 'body') {
4990          ## has a |body| element in scope  
4991            ## 1. If not "have an element in scope":
4992            ## "has a |body| element in scope"
4993          my $i;          my $i;
4994          INSCOPE: {          INSCOPE: {
4995            for (reverse @{$self->{open_elements}}) {            for (reverse @{$self->{open_elements}}) {
# Line 5047  sub _tree_construction_main ($) { Line 5012  sub _tree_construction_main ($) {
5012            next B;            next B;
5013          } # INSCOPE          } # INSCOPE
5014    
5015            ## 2. If unclosed elements:
5016          for (@{$self->{open_elements}}) {          for (@{$self->{open_elements}}) {
5017            unless ($_->[1] & ALL_END_TAG_OPTIONAL_EL) {            unless ($_->[1] & ALL_END_TAG_OPTIONAL_EL ||
5018                      $_->[1] == OPTGROUP_EL ||
5019                      $_->[1] == OPTION_EL ||
5020                      $_->[1] == RUBY_COMPONENT_EL) {
5021              !!!cp ('t403');              !!!cp ('t403');
5022              !!!parse-error (type => 'not closed',              !!!parse-error (type => 'not closed',
5023                              text => $_->[0]->manakai_local_name,                              text => $_->[0]->manakai_local_name,
# Line 5059  sub _tree_construction_main ($) { Line 5028  sub _tree_construction_main ($) {
5028            }            }
5029          }          }
5030    
5031            ## 3. Switch the insertion mode.
5032          $self->{insertion_mode} = AFTER_BODY_IM;          $self->{insertion_mode} = AFTER_BODY_IM;
5033          !!!next-token;          !!!next-token;
5034          next B;          next B;
# Line 5094  sub _tree_construction_main ($) { Line 5064  sub _tree_construction_main ($) {
5064                  address => 1, article => 1, aside => 1, blockquote => 1,                  address => 1, article => 1, aside => 1, blockquote => 1,
5065                  center => 1, datagrid => 1, details => 1, dialog => 1,                  center => 1, datagrid => 1, details => 1, dialog => 1,
5066                  dir => 1, div => 1, dl => 1, fieldset => 1, figure => 1,                  dir => 1, div => 1, dl => 1, fieldset => 1, figure => 1,
5067                  footer => 1, header => 1, listing => 1, menu => 1, nav => 1,                  footer => 1, header => 1, hgroup => 1,
5068                    listing => 1, menu => 1, nav => 1,
5069                  ol => 1, pre => 1, section => 1, ul => 1,                  ol => 1, pre => 1, section => 1, ul => 1,
5070    
5071                  ## NOTE: As normal, but ... optional tags                  ## NOTE: As normal, but ... optional tags
# Line 5454  sub set_inner_html ($$$$;$) { Line 5425  sub set_inner_html ($$$$;$) {
5425    my $onerror = $_[1];    my $onerror = $_[1];
5426    my $get_wrapper = $_[2] || sub ($) { return $_[0] };    my $get_wrapper = $_[2] || sub ($) { return $_[0] };
5427    
   ## ISSUE: Should {confident} be true?  
   
5428    my $nt = $node->node_type;    my $nt = $node->node_type;
5429    if ($nt == 9) { # Document (invoke the algorithm with no /context/ element)    if ($nt == 9) { # Document (invoke the algorithm with no /context/ element)
5430      # MUST      # MUST
# Line 5670  sub set_inner_html ($$$$;$) { Line 5639  sub set_inner_html ($$$$;$) {
5639        $anode = $anode->parent_node;        $anode = $anode->parent_node;
5640      } # AN      } # AN
5641    
5642        ## F.5. Set the input stream.
5643        $p->{confident} = 1; ## Confident: irrelevant.
5644    
5645      ## F.6. Start the parser.      ## F.6. Start the parser.
5646      {      {
5647        my $self = $p;        my $self = $p;

Legend:
Removed from v.1.218  
changed lines
  Added in v.1.238

admin@suikawiki.org
ViewVC Help
Powered by ViewVC 1.1.24