/[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.223 by wakaba, Sun Aug 16 04:59:53 2009 UTC revision 1.244 by wakaba, Sun Sep 6 23:32:06 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 784  sub parse_char_stream ($$$;$$) { Line 789  sub parse_char_stream ($$$;$$) {
789  sub new ($) {  sub new ($) {
790    my $class = shift;    my $class = shift;
791    my $self = bless {    my $self = bless {
792      level => {must => 'm',      level => {
793                should => 's',        must => 'm',
794                warn => 'w',        should => 's',
795                info => 'i',        obc => 's', ## Obsolete but conforming, # XXX distinguish from "should"
796                uncertain => 'u'},        warn => 'w',
797          info => 'i',
798          uncertain => 'u',
799        },
800    }, $class;    }, $class;
801    $self->{set_nc} = sub {    $self->{set_nc} = sub {
802      $self->{nc} = -1;      $self->{nc} = -1;
# Line 864  sub _initialize_tree_constructor ($) { Line 872  sub _initialize_tree_constructor ($) {
872    $self->{document}->manakai_is_html (1); # MUST    $self->{document}->manakai_is_html (1); # MUST
873    $self->{document}->set_user_data (manakai_source_line => 1);    $self->{document}->set_user_data (manakai_source_line => 1);
874    $self->{document}->set_user_data (manakai_source_column => 1);    $self->{document}->set_user_data (manakai_source_column => 1);
875    
876      $self->{frameset_ok} = 1;
877  } # _initialize_tree_constructor  } # _initialize_tree_constructor
878    
879  sub _terminate_tree_constructor ($) {  sub _terminate_tree_constructor ($) {
# Line 911  sub _tree_construction_initial ($) { Line 921  sub _tree_construction_initial ($) {
921    
922    INITIAL: {    INITIAL: {
923      if ($token->{type} == DOCTYPE_TOKEN) {      if ($token->{type} == DOCTYPE_TOKEN) {
924        ## NOTE: Conformance checkers MAY, instead of reporting "not HTML5"        ## NOTE: Conformance checkers MAY, instead of reporting "not
925        ## error, switch to a conformance checking mode for another        ## HTML5" error, switch to a conformance checking mode for
926        ## language.        ## another language.  (We don't support such mode switchings; it
927          ## is nonsense to do anything different from what browsers do.)
928        my $doctype_name = $token->{name};        my $doctype_name = $token->{name};
929        $doctype_name = '' unless defined $doctype_name;        $doctype_name = '' unless defined $doctype_name;
930        $doctype_name =~ tr/a-z/A-Z/; # ASCII case-insensitive        my $doctype = $self->{document}->create_document_type_definition
931        if (not defined $token->{name} or # <!DOCTYPE>            ($doctype_name);
932            defined $token->{sysid}) {  
933          $doctype_name =~ tr/A-Z/a-z/; # ASCII case-insensitive.
934          if ($doctype_name ne 'html') {
935          !!!cp ('t1');          !!!cp ('t1');
936          !!!parse-error (type => 'not HTML5', token => $token);          !!!parse-error (type => 'not HTML5', token => $token);
       } elsif ($doctype_name ne 'HTML') {  
         !!!cp ('t2');  
         !!!parse-error (type => 'not HTML5', token => $token);  
937        } elsif (defined $token->{pubid}) {        } elsif (defined $token->{pubid}) {
938          if ($token->{pubid} eq 'XSLT-compat') {          ## Obsolete permitted DOCTYPEs (case-sensitive)
939            !!!cp ('t1.2');          my $xsysid = {
940              '-//W3C//DTD HTML 4.0//EN' => 'http://www.w3.org/TR/REC-html40/strict.dtd',
941              '-//W3C//DTD HTML 4.01//EN' => 'http://www.w3.org/TR/html4/strict.dtd',
942              '-//W3C//DTD XHTML 1.0 Strict//EN' => 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd',
943              '-//W3C//DTD XHTML 1.1//EN' => 'http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd',
944            }->{$token->{pubid}};
945            if (defined $xsysid and
946                (not defined $token->{sysid} or $token->{sysid} eq $xsysid)) {
947              !!!cp ('t2');
948              !!!parse-error (type => 'obs DOCTYPE', token => $token,
949                              level => $self->{level}->{obc}); ## XXX error type
950            } else {
951              !!!cp ('t2.1');
952              !!!parse-error (type => 'not HTML5', token => $token);
953            }
954          } elsif (defined $token->{sysid}) {
955            if ($token->{sysid} eq 'about:legacy-compat') {
956              !!!cp ('t1.2'); ## <!DOCTYPE HTML SYSTEM "about:legacy-compat">
957            !!!parse-error (type => 'XSLT-compat', token => $token,            !!!parse-error (type => 'XSLT-compat', token => $token,
958                            level => $self->{level}->{should});                            level => $self->{level}->{should});
959          } else {          } else {
960            !!!parse-error (type => 'not HTML5', token => $token);            !!!parse-error (type => 'not HTML5', token => $token);
961          }          }
962        } else {        } else { ## <!DOCTYPE HTML>
963          !!!cp ('t3');          !!!cp ('t3');
964          #          #
965        }        }
966                
       my $doctype = $self->{document}->create_document_type_definition  
         ($token->{name}); ## ISSUE: If name is missing (e.g. <!DOCTYPE>)?  
967        ## NOTE: Default value for both |public_id| and |system_id| attributes        ## NOTE: Default value for both |public_id| and |system_id| attributes
968        ## 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.
969        $doctype->public_id ($token->{pubid}) if defined $token->{pubid};        $doctype->public_id ($token->{pubid}) if defined $token->{pubid};
970        $doctype->system_id ($token->{sysid}) if defined $token->{sysid};        $doctype->system_id ($token->{sysid}) if defined $token->{sysid};
971    
972        ## NOTE: Other DocumentType attributes are null or empty lists.        ## NOTE: Other DocumentType attributes are null or empty lists.
973        ## In Firefox3, |internalSubset| attribute is set to the empty        ## In Firefox3, |internalSubset| attribute is set to the empty
974        ## string, while |null| is an allowed value for the attribute        ## string, while |null| is an allowed value for the attribute
975        ## according to DOM3 Core.        ## according to DOM3 Core.
976        $self->{document}->append_child ($doctype);        $self->{document}->append_child ($doctype);
977                
978        if ($token->{quirks} or $doctype_name ne 'HTML') {        if ($token->{quirks} or $doctype_name ne 'html') {
979          !!!cp ('t4');          !!!cp ('t4');
980          $self->{document}->manakai_compat_mode ('quirks');          $self->{document}->manakai_compat_mode ('quirks');
981        } elsif (defined $token->{pubid}) {        } elsif (defined $token->{pubid}) {
982          my $pubid = $token->{pubid};          my $pubid = $token->{pubid};
983          $pubid =~ tr/a-z/A-z/;          $pubid =~ tr/a-z/A-Z/; ## ASCII case-insensitive.
984          my $prefix = [          my $prefix = [
985            "+//SILMARIL//DTD HTML PRO V0R11 19970101//",            "+//SILMARIL//DTD HTML PRO V0R11 19970101//",
986            "-//ADVASOFT LTD//DTD HTML 3.0 ASWEDIT + EXTENSIONS//",            "-//ADVASOFT LTD//DTD HTML 3.0 ASWEDIT + EXTENSIONS//",
# Line 1046  sub _tree_construction_initial ($) { Line 1072  sub _tree_construction_initial ($) {
1072        }        }
1073        if (defined $token->{sysid}) {        if (defined $token->{sysid}) {
1074          my $sysid = $token->{sysid};          my $sysid = $token->{sysid};
1075          $sysid =~ tr/A-Z/a-z/;          $sysid =~ tr/A-Z/a-z/; ## ASCII case-insensitive.
1076          if ($sysid eq "http://www.ibm.com/data/dtd/v11/ibmxhtml1-transitional.dtd") {          if ($sysid eq "http://www.ibm.com/data/dtd/v11/ibmxhtml1-transitional.dtd") {
1077            ## NOTE: Ensure that |PUBLIC "(limited quirks)" "(quirks)"| is            ## NOTE: Ensure that |PUBLIC "(limited quirks)" "(quirks)"|
1078            ## marked as quirks.            ## is signaled as in quirks mode!
1079            $self->{document}->manakai_compat_mode ('quirks');            $self->{document}->manakai_compat_mode ('quirks');
1080            !!!cp ('t11');            !!!cp ('t11');
1081          } else {          } else {
# Line 1435  sub _tree_construction_main ($) { Line 1461  sub _tree_construction_main ($) {
1461    }; # $script_start_tag    }; # $script_start_tag
1462    
1463    ## NOTE: $open_tables->[-1]->[0] is the "current table" element node.    ## NOTE: $open_tables->[-1]->[0] is the "current table" element node.
1464    ## NOTE: $open_tables->[-1]->[1] is the "tainted" flag.    ## NOTE: $open_tables->[-1]->[1] is the "tainted" flag (OBSOLETE; unused).
1465    ## 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.
1466    my $open_tables = [[$self->{open_elements}->[0]->[0]]];    my $open_tables = [[$self->{open_elements}->[0]->[0]]];
1467    
# Line 1605  sub _tree_construction_main ($) { Line 1631  sub _tree_construction_main ($) {
1631                
1632        ## Step 8        ## Step 8
1633        if ($common_ancestor_node->[1] & TABLE_ROWS_EL) {        if ($common_ancestor_node->[1] & TABLE_ROWS_EL) {
1634            ## Foster parenting.
1635          my $foster_parent_element;          my $foster_parent_element;
1636          my $next_sibling;          my $next_sibling;
1637          OE: for (reverse 0..$#{$self->{open_elements}}) {          OE: for (reverse 0..$#{$self->{open_elements}}) {
1638            if ($self->{open_elements}->[$_]->[1] == TABLE_EL) {            if ($self->{open_elements}->[$_]->[1] == TABLE_EL) {
1639                               my $parent = $self->{open_elements}->[$_]->[0]->parent_node;              !!!cp ('t65.2');
1640                               if (defined $parent and $parent->node_type == 1) {              $foster_parent_element = $self->{open_elements}->[$_ - 1]->[0];
1641                                 !!!cp ('t65.1');              $next_sibling = $self->{open_elements}->[$_]->[0];
1642                                 $foster_parent_element = $parent;              undef $next_sibling
1643                                 $next_sibling = $self->{open_elements}->[$_]->[0];                  unless $next_sibling->parent_node eq $foster_parent_element;
1644                               } else {              last OE;
1645                                 !!!cp ('t65.2');            }
1646                                 $foster_parent_element          } # OE
1647                                   = $self->{open_elements}->[$_ - 1]->[0];          $foster_parent_element ||= $self->{open_elements}->[0]->[0];
1648                               }  
                              last OE;  
                            }  
                          } # OE  
                          $foster_parent_element = $self->{open_elements}->[0]->[0]  
                            unless defined $foster_parent_element;  
1649          $foster_parent_element->insert_before ($last_node->[0], $next_sibling);          $foster_parent_element->insert_before ($last_node->[0], $next_sibling);
1650          $open_tables->[-1]->[1] = 1; # tainted          $open_tables->[-1]->[1] = 1; # tainted
1651        } else {        } else {
# Line 1679  sub _tree_construction_main ($) { Line 1701  sub _tree_construction_main ($) {
1701      $self->{open_elements}->[-1]->[0]->append_child ($_[0]);      $self->{open_elements}->[-1]->[0]->append_child ($_[0]);
1702    }; # $insert_to_current    }; # $insert_to_current
1703    
1704      ## Foster parenting.  Note that there are three "foster parenting"
1705      ## code in the parser: for elements (this one), for texts, and for
1706      ## elements in the AAA code.
1707    my $insert_to_foster = sub {    my $insert_to_foster = sub {
1708      my $child = shift;      my $child = shift;
1709      if ($self->{open_elements}->[-1]->[1] & TABLE_ROWS_EL) {      if ($self->{open_elements}->[-1]->[1] & TABLE_ROWS_EL) {
# Line 1687  sub _tree_construction_main ($) { Line 1712  sub _tree_construction_main ($) {
1712        my $next_sibling;        my $next_sibling;
1713        OE: for (reverse 0..$#{$self->{open_elements}}) {        OE: for (reverse 0..$#{$self->{open_elements}}) {
1714          if ($self->{open_elements}->[$_]->[1] == TABLE_EL) {          if ($self->{open_elements}->[$_]->[1] == TABLE_EL) {
1715                               my $parent = $self->{open_elements}->[$_]->[0]->parent_node;            !!!cp ('t71');
1716                               if (defined $parent and $parent->node_type == 1) {            $foster_parent_element = $self->{open_elements}->[$_ - 1]->[0];
1717                                 !!!cp ('t70');            $next_sibling = $self->{open_elements}->[$_]->[0];
1718                                 $foster_parent_element = $parent;            undef $next_sibling
1719                                 $next_sibling = $self->{open_elements}->[$_]->[0];                unless $next_sibling->parent_node eq $foster_parent_element;
1720                               } else {            last OE;
1721                                 !!!cp ('t71');          }
1722                                 $foster_parent_element        } # OE
1723                                   = $self->{open_elements}->[$_ - 1]->[0];        $foster_parent_element ||= $self->{open_elements}->[0]->[0];
1724                               }  
1725                               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);  
1726        $open_tables->[-1]->[1] = 1; # tainted        $open_tables->[-1]->[1] = 1; # tainted
1727      } else {      } else {
1728        !!!cp ('t72');        !!!cp ('t72');
# Line 1731  sub _tree_construction_main ($) { Line 1750  sub _tree_construction_main ($) {
1750    ## document.write ("b")</script>|    ## document.write ("b")</script>|
1751    
1752    B: while (1) {    B: while (1) {
1753    
1754        ## The "in table text" insertion mode.
1755        if ($self->{insertion_mode} & TABLE_IMS and
1756            not $self->{insertion_mode} & IN_FOREIGN_CONTENT_IM and
1757            not $self->{insertion_mode} & IN_CDATA_RCDATA_IM) {
1758          C: {
1759            my $s;
1760            if ($token->{type} == CHARACTER_TOKEN) {
1761              !!!cp ('t194');
1762              $self->{pending_chars} ||= [];
1763              push @{$self->{pending_chars}}, $token;
1764              !!!next-token;
1765              next B;
1766            } else {
1767              if ($self->{pending_chars}) {
1768                $s = join '', map { $_->{data} } @{$self->{pending_chars}};
1769                delete $self->{pending_chars};
1770                if ($s =~ /[^\x09\x0A\x0C\x0D\x20]/) {
1771                  !!!cp ('t195');
1772                  #
1773                } else {
1774                  !!!cp ('t195.1');
1775                  #$self->{open_elements}->[-1]->[0]->manakai_append_text ($s);
1776                  $self->{open_elements}->[-1]->[0]->append_child
1777                      ($self->{document}->create_text_node ($s));
1778                  last C;
1779                }
1780              } else {
1781                !!!cp ('t195.2');
1782                last C;
1783              }
1784            }
1785    
1786            ## Foster parenting.
1787            !!!parse-error (type => 'in table:#text', token => $token);
1788    
1789            ## NOTE: As if in body, but insert into the foster parent element.
1790            $reconstruct_active_formatting_elements->($insert_to_foster);
1791                
1792            if ($self->{open_elements}->[-1]->[1] & TABLE_ROWS_EL) {
1793              # MUST
1794              my $foster_parent_element;
1795              my $next_sibling;
1796              OE: for (reverse 0..$#{$self->{open_elements}}) {
1797                if ($self->{open_elements}->[$_]->[1] == TABLE_EL) {
1798                  !!!cp ('t197');
1799                  $foster_parent_element = $self->{open_elements}->[$_ - 1]->[0];
1800                  $next_sibling = $self->{open_elements}->[$_]->[0];
1801                  undef $next_sibling
1802                    unless $next_sibling->parent_node eq $foster_parent_element;
1803                  last OE;
1804                }
1805              } # OE
1806              $foster_parent_element ||= $self->{open_elements}->[0]->[0];
1807    
1808              !!!cp ('t199');
1809              $foster_parent_element->insert_before
1810                  ($self->{document}->create_text_node ($s), $next_sibling);
1811    
1812              $open_tables->[-1]->[1] = 1; # tainted
1813              $open_tables->[-1]->[2] = 1; # ~node inserted
1814            } else {
1815              ## NOTE: Fragment case or in a foster parent'ed element
1816              ## (e.g. |<table><span>a|).  In fragment case, whether the
1817              ## character is appended to existing node or a new node is
1818              ## created is irrelevant, since the foster parent'ed nodes
1819              ## are discarded and fragment parsing does not invoke any
1820              ## script.
1821              !!!cp ('t200');
1822              $self->{open_elements}->[-1]->[0]->manakai_append_text ($s);
1823            }
1824          } # C
1825        } # TABLE_IMS
1826    
1827      if ($token->{type} == DOCTYPE_TOKEN) {      if ($token->{type} == DOCTYPE_TOKEN) {
1828        !!!cp ('t73');        !!!cp ('t73');
1829        !!!parse-error (type => 'in html:#DOCTYPE', token => $token);        !!!parse-error (type => 'in html:#DOCTYPE', token => $token);
# Line 1857  sub _tree_construction_main ($) { Line 1950  sub _tree_construction_main ($) {
1950      } elsif ($self->{insertion_mode} & IN_FOREIGN_CONTENT_IM) {      } elsif ($self->{insertion_mode} & IN_FOREIGN_CONTENT_IM) {
1951        if ($token->{type} == CHARACTER_TOKEN) {        if ($token->{type} == CHARACTER_TOKEN) {
1952          !!!cp ('t87.1');          !!!cp ('t87.1');
1953    
1954          $self->{open_elements}->[-1]->[0]->manakai_append_text ($token->{data});          $self->{open_elements}->[-1]->[0]->manakai_append_text ($token->{data});
1955    
1956            if ($token->{data} =~ /[^\x09\x0A\x0C\x0D\x20]/) {
1957              delete $self->{frameset_ok};
1958            }
1959    
1960          !!!next-token;          !!!next-token;
1961          next B;          next B;
1962        } elsif ($token->{type} == START_TAG_TOKEN) {        } elsif ($token->{type} == START_TAG_TOKEN) {
# Line 2052  sub _tree_construction_main ($) { Line 2151  sub _tree_construction_main ($) {
2151          ## As if <body>          ## As if <body>
2152          !!!insert-element ('body',, $token);          !!!insert-element ('body',, $token);
2153          $self->{insertion_mode} = IN_BODY_IM;          $self->{insertion_mode} = IN_BODY_IM;
2154          ## reprocess          ## The "frameset-ok" flag is left unchanged in this case.
2155            ## Reporcess the token.
2156          next B;          next B;
2157        } elsif ($token->{type} == START_TAG_TOKEN) {        } elsif ($token->{type} == START_TAG_TOKEN) {
2158          if ($token->{tag_name} eq 'head') {          if ($token->{tag_name} eq 'head') {
# Line 2149  sub _tree_construction_main ($) { Line 2249  sub _tree_construction_main ($) {
2249            !!!ack ('t103.1');            !!!ack ('t103.1');
2250            !!!next-token;            !!!next-token;
2251            next B;            next B;
2252          } elsif ($token->{tag_name} eq 'command' or          } elsif ($token->{tag_name} eq 'command') {
                  $token->{tag_name} eq 'eventsource') {  
2253            if ($self->{insertion_mode} == IN_HEAD_IM) {            if ($self->{insertion_mode} == IN_HEAD_IM) {
2254              ## NOTE: If the insertion mode at the time of the emission              ## NOTE: If the insertion mode at the time of the emission
2255              ## of the token was "before head", $self->{insertion_mode}              ## of the token was "before head", $self->{insertion_mode}
# Line 2265  sub _tree_construction_main ($) { Line 2364  sub _tree_construction_main ($) {
2364    
2365            ## NOTE: There is a "as if in head" code clone.            ## NOTE: There is a "as if in head" code clone.
2366            $parse_rcdata->(RCDATA_CONTENT_MODEL);            $parse_rcdata->(RCDATA_CONTENT_MODEL);
2367            ## ISSUE: A spec bug [Bug 6038]  
2368              ## NOTE: At this point the stack of open elements contain
2369              ## the |head| element (index == -2) and the |script| element
2370              ## (index == -1).  In the "after head" insertion mode the
2371              ## |head| element is inserted only for the purpose of
2372              ## providing the context for the |script| element, and
2373              ## therefore we can now and have to remove the element from
2374              ## the stack.
2375            splice @{$self->{open_elements}}, -2, 1, () # <head>            splice @{$self->{open_elements}}, -2, 1, () # <head>
2376                if ($self->{insertion_mode} & IM_MASK) == AFTER_HEAD_IM;                if ($self->{insertion_mode} & IM_MASK) == AFTER_HEAD_IM;
2377            next B;            next B;
# Line 2339  sub _tree_construction_main ($) { Line 2445  sub _tree_construction_main ($) {
2445            next B;            next B;
2446          } elsif ($token->{tag_name} eq 'body' or          } elsif ($token->{tag_name} eq 'body' or
2447                   $token->{tag_name} eq 'frameset') {                   $token->{tag_name} eq 'frameset') {
2448                if ($self->{insertion_mode} == IN_HEAD_NOSCRIPT_IM) {            if ($self->{insertion_mode} == IN_HEAD_NOSCRIPT_IM) {
2449                  !!!cp ('t122');              !!!cp ('t122');
2450                  ## As if </noscript>              ## As if </noscript>
2451                  pop @{$self->{open_elements}};              pop @{$self->{open_elements}};
2452                  !!!parse-error (type => 'in noscript',              !!!parse-error (type => 'in noscript',
2453                                  text => $token->{tag_name}, token => $token);                              text => $token->{tag_name}, token => $token);
2454                                
2455                  ## Reprocess in the "in head" insertion mode...              ## Reprocess in the "in head" insertion mode...
2456                  ## As if </head>              ## As if </head>
2457                  pop @{$self->{open_elements}};              pop @{$self->{open_elements}};
2458                                
2459                  ## Reprocess in the "after head" insertion mode...              ## Reprocess in the "after head" insertion mode...
2460                } elsif ($self->{insertion_mode} == IN_HEAD_IM) {            } elsif ($self->{insertion_mode} == IN_HEAD_IM) {
2461                  !!!cp ('t124');              !!!cp ('t124');
2462                  pop @{$self->{open_elements}};              pop @{$self->{open_elements}};
2463                                
2464                  ## Reprocess in the "after head" insertion mode...              ## Reprocess in the "after head" insertion mode...
2465                } else {            } else {
2466                  !!!cp ('t125');              !!!cp ('t125');
2467                }            }
2468    
2469                ## "after head" insertion mode            ## "after head" insertion mode
2470                !!!insert-element ($token->{tag_name}, $token->{attributes}, $token);            !!!insert-element ($token->{tag_name}, $token->{attributes}, $token);
2471                if ($token->{tag_name} eq 'body') {            if ($token->{tag_name} eq 'body') {
2472                  !!!cp ('t126');              !!!cp ('t126');
2473                  $self->{insertion_mode} = IN_BODY_IM;              delete $self->{frameset_ok};
2474                } elsif ($token->{tag_name} eq 'frameset') {              $self->{insertion_mode} = IN_BODY_IM;
2475                  !!!cp ('t127');            } elsif ($token->{tag_name} eq 'frameset') {
2476                  $self->{insertion_mode} = IN_FRAMESET_IM;              !!!cp ('t127');
2477                } else {              $self->{insertion_mode} = IN_FRAMESET_IM;
2478                  die "$0: tag name: $self->{tag_name}";            } else {
2479                }              die "$0: tag name: $self->{tag_name}";
2480                !!!nack ('t127.1');            }
2481                !!!next-token;            !!!nack ('t127.1');
2482                next B;            !!!next-token;
2483              } else {            next B;
2484                !!!cp ('t128');          } else {
2485                #            !!!cp ('t128');
2486              }            #
2487            }
2488    
2489              if ($self->{insertion_mode} == IN_HEAD_NOSCRIPT_IM) {              if ($self->{insertion_mode} == IN_HEAD_NOSCRIPT_IM) {
2490                !!!cp ('t129');                !!!cp ('t129');
# Line 2401  sub _tree_construction_main ($) { Line 2508  sub _tree_construction_main ($) {
2508                !!!cp ('t131');                !!!cp ('t131');
2509              }              }
2510    
2511              ## "after head" insertion mode          ## "after head" insertion mode
2512              ## As if <body>          ## As if <body>
2513              !!!insert-element ('body',, $token);          !!!insert-element ('body',, $token);
2514              $self->{insertion_mode} = IN_BODY_IM;          $self->{insertion_mode} = IN_BODY_IM;
2515              ## reprocess          ## The "frameset-ok" flag is not changed in this case.
2516              !!!ack-later;          ## Reprocess the token.
2517              next B;          !!!ack-later;
2518            } elsif ($token->{type} == END_TAG_TOKEN) {          next B;
2519              if ($token->{tag_name} eq 'head') {        } elsif ($token->{type} == END_TAG_TOKEN) {
2520                if ($self->{insertion_mode} == BEFORE_HEAD_IM) {          ## "Before head", "in head", and "after head" insertion modes
2521                  !!!cp ('t132');          ## ignore most of end tags.  Exceptions are "body", "html",
2522                  ## As if <head>          ## and "br" end tags.  "Before head" and "in head" insertion
2523                  !!!create-element ($self->{head_element}, $HTML_NS, 'head',, $token);          ## modes also recognize "head" end tag.  "In head noscript"
2524                  $self->{open_elements}->[-1]->[0]->append_child ($self->{head_element});          ## insertion modes ignore end tags except for "noscript" and
2525                  push @{$self->{open_elements}},          ## "br".
                     [$self->{head_element}, $el_category->{head}];  
2526    
2527                  ## Reprocess in the "in head" insertion mode...          if ($token->{tag_name} eq 'head') {
2528                  pop @{$self->{open_elements}};            if ($self->{insertion_mode} == BEFORE_HEAD_IM) {
2529                  $self->{insertion_mode} = AFTER_HEAD_IM;              !!!cp ('t132');
2530                  !!!next-token;              ## As if <head>
2531                  next B;              !!!create-element ($self->{head_element}, $HTML_NS, 'head',, $token);
2532                } elsif ($self->{insertion_mode} == IN_HEAD_NOSCRIPT_IM) {              $self->{open_elements}->[-1]->[0]->append_child ($self->{head_element});
2533                  !!!cp ('t133');              push @{$self->{open_elements}},
2534                  ## As if </noscript>                  [$self->{head_element}, $el_category->{head}];
2535                  pop @{$self->{open_elements}};  
2536                  !!!parse-error (type => 'in noscript:/',              ## Reprocess in the "in head" insertion mode...
2537                                  text => 'head', token => $token);              pop @{$self->{open_elements}};
2538                                $self->{insertion_mode} = AFTER_HEAD_IM;
2539                  ## Reprocess in the "in head" insertion mode...              !!!next-token;
2540                  pop @{$self->{open_elements}};              next B;
2541                  $self->{insertion_mode} = AFTER_HEAD_IM;            } elsif ($self->{insertion_mode} == IN_HEAD_NOSCRIPT_IM) {
2542                  !!!next-token;              !!!cp ('t133');
2543                  next B;              #
2544                } elsif ($self->{insertion_mode} == IN_HEAD_IM) {            } elsif ($self->{insertion_mode} == IN_HEAD_IM) {
2545                  !!!cp ('t134');              !!!cp ('t134');
2546                  pop @{$self->{open_elements}};              pop @{$self->{open_elements}};
2547                  $self->{insertion_mode} = AFTER_HEAD_IM;              $self->{insertion_mode} = AFTER_HEAD_IM;
2548                  !!!next-token;              !!!next-token;
2549                  next B;              next B;
2550                } elsif ($self->{insertion_mode} == AFTER_HEAD_IM) {            } elsif ($self->{insertion_mode} == AFTER_HEAD_IM) {
2551                  !!!cp ('t134.1');              !!!cp ('t134.1');
2552                  !!!parse-error (type => 'unmatched end tag', text => 'head',              #
2553                                  token => $token);            } else {
2554                  ## Ignore the token              die "$0: $self->{insertion_mode}: Unknown insertion mode";
2555                  !!!next-token;            }
2556                  next B;          } elsif ($token->{tag_name} eq 'noscript') {
2557                } else {            if ($self->{insertion_mode} == IN_HEAD_NOSCRIPT_IM) {
2558                  die "$0: $self->{insertion_mode}: Unknown insertion mode";              !!!cp ('t136');
2559                }              pop @{$self->{open_elements}};
2560              } elsif ($token->{tag_name} eq 'noscript') {              $self->{insertion_mode} = IN_HEAD_IM;
2561                if ($self->{insertion_mode} == IN_HEAD_NOSCRIPT_IM) {              !!!next-token;
2562                  !!!cp ('t136');              next B;
2563                  pop @{$self->{open_elements}};            } else {
2564                  $self->{insertion_mode} = IN_HEAD_IM;              !!!cp ('t138');
2565                  !!!next-token;              #
2566                  next B;            }
2567                } elsif ($self->{insertion_mode} == BEFORE_HEAD_IM or          } elsif ({
2568                         $self->{insertion_mode} == AFTER_HEAD_IM) {              body => ($self->{insertion_mode} != IN_HEAD_NOSCRIPT_IM),
2569                  !!!cp ('t137');              html => ($self->{insertion_mode} != IN_HEAD_NOSCRIPT_IM),
2570                  !!!parse-error (type => 'unmatched end tag',              br => 1,
2571                                  text => 'noscript', token => $token);          }->{$token->{tag_name}}) {
2572                  ## Ignore the token ## ISSUE: An issue in the spec.            if ($self->{insertion_mode} == BEFORE_HEAD_IM) {
2573                  !!!next-token;              !!!cp ('t142.2');
2574                  next B;              ## (before head) as if <head>, (in head) as if </head>
2575                } else {              !!!create-element ($self->{head_element}, $HTML_NS, 'head',, $token);
2576                  !!!cp ('t138');              $self->{open_elements}->[-1]->[0]->append_child ($self->{head_element});
2577                  #              $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;  
2578        
2579                  ## Reprocess in the "after head" insertion mode...              ## Reprocess in the "after head" insertion mode...
2580                } elsif ($self->{insertion_mode} == IN_HEAD_IM) {            } elsif ($self->{insertion_mode} == IN_HEAD_IM) {
2581                  !!!cp ('t143.2');              !!!cp ('t143.2');
2582                  ## As if </head>              ## As if </head>
2583                  pop @{$self->{open_elements}};              pop @{$self->{open_elements}};
2584                  $self->{insertion_mode} = AFTER_HEAD_IM;              $self->{insertion_mode} = AFTER_HEAD_IM;
2585        
2586                  ## Reprocess in the "after head" insertion mode...              ## Reprocess in the "after head" insertion mode...
2587                } elsif ($self->{insertion_mode} == IN_HEAD_NOSCRIPT_IM) {            } elsif ($self->{insertion_mode} == IN_HEAD_NOSCRIPT_IM) {
2588                  !!!cp ('t143.3');              !!!cp ('t143.3');
2589                  ## NOTE: Two parse errors for <head><noscript></br>              ## NOTE: Two parse errors for <head><noscript></br>
2590                  !!!parse-error (type => 'unmatched end tag',              !!!parse-error (type => 'unmatched end tag',
2591                                  text => 'br', token => $token);                              text => $token->{tag_name}, token => $token);
2592                  ## As if </noscript>              ## As if </noscript>
2593                  pop @{$self->{open_elements}};              pop @{$self->{open_elements}};
2594                  $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;  
             }  
2595    
2596              if ($self->{insertion_mode} == IN_HEAD_NOSCRIPT_IM) {              ## Reprocess in the "in head" insertion mode...
2597                !!!cp ('t146');              ## As if </head>
2598                ## As if </noscript>              pop @{$self->{open_elements}};
2599                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}};  
2600    
2601                ## Reprocess in the "after head" insertion mode...              ## Reprocess in the "after head" insertion mode...
2602              } elsif ($self->{insertion_mode} == IN_HEAD_IM) {            } elsif ($self->{insertion_mode} == AFTER_HEAD_IM) {
2603                !!!cp ('t147');              !!!cp ('t143.4');
2604                ## As if </head>              #
2605                pop @{$self->{open_elements}};            } else {
2606                die "$0: $self->{insertion_mode}: Unknown insertion mode";
2607              }
2608    
2609                ## Reprocess in the "after head" insertion mode...            ## "after head" insertion mode
2610              } elsif ($self->{insertion_mode} == BEFORE_HEAD_IM) {            ## As if <body>
2611  ## ISSUE: This case cannot be reached?            !!!insert-element ('body',, $token);
2612                !!!cp ('t148');            $self->{insertion_mode} = IN_BODY_IM;
2613                !!!parse-error (type => 'unmatched end tag',            ## The "frameset-ok" flag is left unchanged in this case.
2614                                text => $token->{tag_name}, token => $token);            ## Reprocess the token.
2615                ## Ignore the token ## ISSUE: An issue in the spec.            next B;
2616                !!!next-token;          }
               next B;  
             } else {  
               !!!cp ('t149');  
             }  
2617    
2618              ## "after head" insertion mode          ## End tags are ignored by default.
2619              ## As if <body>          !!!cp ('t145');
2620              !!!insert-element ('body',, $token);          !!!parse-error (type => 'unmatched end tag',
2621              $self->{insertion_mode} = IN_BODY_IM;                          text => $token->{tag_name}, token => $token);
2622              ## reprocess          ## Ignore the token.
2623              next B;          !!!next-token;
2624            next B;
2625        } elsif ($token->{type} == END_OF_FILE_TOKEN) {        } elsif ($token->{type} == END_OF_FILE_TOKEN) {
2626          if ($self->{insertion_mode} == BEFORE_HEAD_IM) {          if ($self->{insertion_mode} == BEFORE_HEAD_IM) {
2627            !!!cp ('t149.1');            !!!cp ('t149.1');
# Line 2641  sub _tree_construction_main ($) { Line 2674  sub _tree_construction_main ($) {
2674          ## NOTE: As if <body>          ## NOTE: As if <body>
2675          !!!insert-element ('body',, $token);          !!!insert-element ('body',, $token);
2676          $self->{insertion_mode} = IN_BODY_IM;          $self->{insertion_mode} = IN_BODY_IM;
2677          ## NOTE: Reprocess.          ## The "frameset-ok" flag is left unchanged in this case.
2678            ## Reprocess the token.
2679          next B;          next B;
2680        } else {        } else {
2681          die "$0: $token->{type}: Unknown token type";          die "$0: $token->{type}: Unknown token type";
2682        }        }
2683      } elsif ($self->{insertion_mode} & BODY_IMS) {      } elsif ($self->{insertion_mode} & BODY_IMS) {
2684            if ($token->{type} == CHARACTER_TOKEN) {        if ($token->{type} == CHARACTER_TOKEN) {
2685              !!!cp ('t150');          !!!cp ('t150');
2686              ## NOTE: There is a code clone of "character in body".          $reconstruct_active_formatting_elements->($insert_to_current);
2687              $reconstruct_active_formatting_elements->($insert_to_current);          
2688                        $self->{open_elements}->[-1]->[0]->manakai_append_text ($token->{data});
             $self->{open_elements}->[-1]->[0]->manakai_append_text ($token->{data});  
2689    
2690              !!!next-token;          if ($token->{data} =~ /[^\x09\x0A\x0C\x0D\x20]/) {
2691              next B;            delete $self->{frameset_ok};
2692            } elsif ($token->{type} == START_TAG_TOKEN) {          }
2693    
2694            !!!next-token;
2695            next B;
2696          } elsif ($token->{type} == START_TAG_TOKEN) {
2697              if ({              if ({
2698                   caption => 1, col => 1, colgroup => 1, tbody => 1,                   caption => 1, col => 1, colgroup => 1, tbody => 1,
2699                   td => 1, tfoot => 1, th => 1, thead => 1, tr => 1,                   td => 1, tfoot => 1, th => 1, thead => 1, tr => 1,
# Line 3016  sub _tree_construction_main ($) { Line 3053  sub _tree_construction_main ($) {
3053        $insert = $insert_to_current;        $insert = $insert_to_current;
3054        #        #
3055      } elsif ($self->{insertion_mode} & TABLE_IMS) {      } elsif ($self->{insertion_mode} & TABLE_IMS) {
3056        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) {  
3057          if ({          if ({
3058               tr => (($self->{insertion_mode} & IM_MASK) != IN_ROW_IM),               tr => (($self->{insertion_mode} & IM_MASK) != IN_ROW_IM),
3059               th => 1, td => 1,               th => 1, td => 1,
# Line 3356  sub _tree_construction_main ($) { Line 3321  sub _tree_construction_main ($) {
3321            !!!ack-later;            !!!ack-later;
3322            next B;            next B;
3323          } elsif ($token->{tag_name} eq 'style') {          } elsif ($token->{tag_name} eq 'style') {
3324            if (not $open_tables->[-1]->[1]) { # tainted            !!!cp ('t227.8');
3325              !!!cp ('t227.8');            ## NOTE: This is a "as if in head" code clone.
3326              ## NOTE: This is a "as if in head" code clone.            $parse_rcdata->(CDATA_CONTENT_MODEL);
3327              $parse_rcdata->(CDATA_CONTENT_MODEL);            $open_tables->[-1]->[2] = 0 if @$open_tables; # ~node inserted
3328              $open_tables->[-1]->[2] = 0 if @$open_tables; # ~node inserted            next B;
             next B;  
           } else {  
             !!!cp ('t227.7');  
             #  
           }  
3329          } elsif ($token->{tag_name} eq 'script') {          } elsif ($token->{tag_name} eq 'script') {
3330            if (not $open_tables->[-1]->[1]) { # tainted            !!!cp ('t227.6');
3331              !!!cp ('t227.6');            ## NOTE: This is a "as if in head" code clone.
3332              ## NOTE: This is a "as if in head" code clone.            $script_start_tag->();
3333              $script_start_tag->();            $open_tables->[-1]->[2] = 0 if @$open_tables; # ~node inserted
3334              $open_tables->[-1]->[2] = 0 if @$open_tables; # ~node inserted            next B;
             next B;  
           } else {  
             !!!cp ('t227.5');  
             #  
           }  
3335          } elsif ($token->{tag_name} eq 'input') {          } elsif ($token->{tag_name} eq 'input') {
3336            if (not $open_tables->[-1]->[1]) { # tainted            if ($token->{attributes}->{type}) {
3337              if ($token->{attributes}->{type}) { ## TODO: case              my $type = $token->{attributes}->{type}->{value};
3338                my $type = lc $token->{attributes}->{type}->{value};              $type =~ tr/A-Z/a-z/; ## ASCII case-insensitive.
3339                if ($type eq 'hidden') {              if ($type eq 'hidden') {
3340                  !!!cp ('t227.3');                !!!cp ('t227.3');
3341                  !!!parse-error (type => 'in table',                !!!parse-error (type => 'in table',
3342                                  text => $token->{tag_name}, token => $token);                                text => $token->{tag_name}, token => $token);
3343    
3344                  !!!insert-element ($token->{tag_name}, $token->{attributes}, $token);                !!!insert-element ($token->{tag_name}, $token->{attributes}, $token);
3345                  $open_tables->[-1]->[2] = 0 if @$open_tables; # ~node inserted                $open_tables->[-1]->[2] = 0 if @$open_tables; # ~node inserted
3346    
3347                  ## TODO: form element pointer                ## TODO: form element pointer
3348    
3349                  pop @{$self->{open_elements}};                pop @{$self->{open_elements}};
3350    
3351                  !!!next-token;                !!!next-token;
3352                  !!!ack ('t227.2.1');                !!!ack ('t227.2.1');
3353                  next B;                next B;
               } else {  
                 !!!cp ('t227.2');  
                 #  
               }  
3354              } else {              } else {
3355                !!!cp ('t227.1');                !!!cp ('t227.1');
3356                #                #
# Line 3912  sub _tree_construction_main ($) { Line 3863  sub _tree_construction_main ($) {
3863              ## Reprocess the token.              ## Reprocess the token.
3864              next B;              next B;
3865            }            }
3866            } elsif ($token->{tag_name} eq 'script') {
3867              !!!cp ('t281.3');
3868              ## NOTE: This is an "as if in head" code clone
3869              $script_start_tag->();
3870              next B;
3871          } else {          } else {
3872            !!!cp ('t282');            !!!cp ('t282');
3873            !!!parse-error (type => 'in select',            !!!parse-error (type => 'in select',
# Line 4323  sub _tree_construction_main ($) { Line 4279  sub _tree_construction_main ($) {
4279          $parse_rcdata->(CDATA_CONTENT_MODEL);          $parse_rcdata->(CDATA_CONTENT_MODEL);
4280          next B;          next B;
4281        } elsif ({        } elsif ({
4282                  base => 1, command => 1, eventsource => 1, link => 1,                  base => 1, command => 1, link => 1,
4283                 }->{$token->{tag_name}}) {                 }->{$token->{tag_name}}) {
4284          !!!cp ('t334');          !!!cp ('t334');
4285          ## 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 4413  sub _tree_construction_main ($) { Line 4369  sub _tree_construction_main ($) {
4369          !!!nack ('t343.1');          !!!nack ('t343.1');
4370          !!!next-token;          !!!next-token;
4371          next B;          next B;
4372          } elsif ($token->{tag_name} eq 'frameset') {
4373            !!!parse-error (type => 'in body', text => $token->{tag_name},
4374                            token => $token);
4375    
4376            if (@{$self->{open_elements}} == 1 or
4377                not ($self->{open_elements}->[1]->[1] == BODY_EL)) {
4378              !!!cp ('t343.2');
4379              ## Ignore the token.
4380            } elsif (not $self->{frameset_ok}) {
4381              !!!cp ('t343.3');
4382              ## Ignore the token.
4383            } else {
4384              !!!cp ('t343.4');
4385              
4386              ## 1. Remove the second element.
4387              my $body = $self->{open_elements}->[1]->[0];
4388              my $body_parent = $body->parent_node;
4389              $body_parent->remove_child ($body) if $body_parent;
4390    
4391              ## 2. Pop nodes.
4392              splice @{$self->{open_elements}}, 1;
4393    
4394              ## 3. Insert.
4395              !!!insert-element-t ($token->{tag_name}, $token->{attributes}, $token);
4396    
4397              ## 4. Switch.
4398              $self->{insertion_mode} = IN_FRAMESET_IM;
4399            }
4400    
4401            !!!nack ('t343.5');
4402            !!!next-token;
4403            next B;
4404        } elsif ({        } elsif ({
4405                  ## NOTE: Start tags for non-phrasing flow content elements                  ## NOTE: Start tags for non-phrasing flow content elements
4406    
# Line 4421  sub _tree_construction_main ($) { Line 4409  sub _tree_construction_main ($) {
4409                  center => 1, datagrid => 1, details => 1, dialog => 1,                  center => 1, datagrid => 1, details => 1, dialog => 1,
4410                  dir => 1, div => 1, dl => 1, fieldset => 1, figure => 1,                  dir => 1, div => 1, dl => 1, fieldset => 1, figure => 1,
4411                  footer => 1, h1 => 1, h2 => 1, h3 => 1, h4 => 1, h5 => 1,                  footer => 1, h1 => 1, h2 => 1, h3 => 1, h4 => 1, h5 => 1,
4412                  h6 => 1, header => 1, menu => 1, nav => 1, ol => 1, p => 1,                  h6 => 1, header => 1, hgroup => 1,
4413                    menu => 1, nav => 1, ol => 1, p => 1,
4414                  section => 1, ul => 1,                  section => 1, ul => 1,
4415                  ## NOTE: As normal, but drops leading newline                  ## NOTE: As normal, but drops leading newline
4416                  pre => 1, listing => 1,                  pre => 1, listing => 1,
# Line 4431  sub _tree_construction_main ($) { Line 4420  sub _tree_construction_main ($) {
4420                  table => 1,                  table => 1,
4421                  hr => 1,                  hr => 1,
4422                 }->{$token->{tag_name}}) {                 }->{$token->{tag_name}}) {
4423    
4424            ## 1. When there is an opening |form| element:
4425          if ($token->{tag_name} eq 'form' and defined $self->{form_element}) {          if ($token->{tag_name} eq 'form' and defined $self->{form_element}) {
4426            !!!cp ('t350');            !!!cp ('t350');
4427            !!!parse-error (type => 'in form:form', token => $token);            !!!parse-error (type => 'in form:form', token => $token);
# Line 4440  sub _tree_construction_main ($) { Line 4431  sub _tree_construction_main ($) {
4431            next B;            next B;
4432          }          }
4433    
4434            ## 2. Close the |p| element, if any.
4435          if ($token->{tag_name} ne 'table' or # The Hixie Quirk          if ($token->{tag_name} ne 'table' or # The Hixie Quirk
4436              $self->{document}->manakai_compat_mode ne 'quirks') {              $self->{document}->manakai_compat_mode ne 'quirks') {
4437            ## has a p element in scope            ## has a p element in scope
# Line 4456  sub _tree_construction_main ($) { Line 4448  sub _tree_construction_main ($) {
4448              }              }
4449            } # INSCOPE            } # INSCOPE
4450          }          }
4451              
4452            ## 3. Close the opening <hn> element, if any.
4453            if ({h1 => 1, h2 => 1, h3 => 1,
4454                 h4 => 1, h5 => 1, h6 => 1}->{$token->{tag_name}}) {
4455              if ($self->{open_elements}->[-1]->[1] == HEADING_EL) {
4456                !!!parse-error (type => 'not closed',
4457                                text => $self->{open_elements}->[-1]->[0]->manakai_local_name,
4458                                token => $token);
4459                pop @{$self->{open_elements}};
4460              }
4461            }
4462    
4463            ## 4. Insertion.
4464          !!!insert-element-t ($token->{tag_name}, $token->{attributes}, $token);          !!!insert-element-t ($token->{tag_name}, $token->{attributes}, $token);
4465          if ($token->{tag_name} eq 'pre' or $token->{tag_name} eq 'listing') {          if ($token->{tag_name} eq 'pre' or $token->{tag_name} eq 'listing') {
4466            !!!nack ('t346.1');            !!!nack ('t346.1');
# Line 4472  sub _tree_construction_main ($) { Line 4476  sub _tree_construction_main ($) {
4476            } else {            } else {
4477              !!!cp ('t348');              !!!cp ('t348');
4478            }            }
4479    
4480              delete $self->{frameset_ok};
4481          } elsif ($token->{tag_name} eq 'form') {          } elsif ($token->{tag_name} eq 'form') {
4482            !!!cp ('t347.1');            !!!cp ('t347.1');
4483            $self->{form_element} = $self->{open_elements}->[-1]->[0];            $self->{form_element} = $self->{open_elements}->[-1]->[0];
# Line 4481  sub _tree_construction_main ($) { Line 4487  sub _tree_construction_main ($) {
4487          } elsif ($token->{tag_name} eq 'table') {          } elsif ($token->{tag_name} eq 'table') {
4488            !!!cp ('t382');            !!!cp ('t382');
4489            push @{$open_tables}, [$self->{open_elements}->[-1]->[0]];            push @{$open_tables}, [$self->{open_elements}->[-1]->[0]];
4490    
4491              delete $self->{frameset_ok};
4492                        
4493            $self->{insertion_mode} = IN_TABLE_IM;            $self->{insertion_mode} = IN_TABLE_IM;
4494    
# Line 4489  sub _tree_construction_main ($) { Line 4497  sub _tree_construction_main ($) {
4497          } elsif ($token->{tag_name} eq 'hr') {          } elsif ($token->{tag_name} eq 'hr') {
4498            !!!cp ('t386');            !!!cp ('t386');
4499            pop @{$self->{open_elements}};            pop @{$self->{open_elements}};
4500                      
4501            !!!nack ('t386.1');            !!!ack ('t386.1');
4502    
4503              delete $self->{frameset_ok};
4504    
4505            !!!next-token;            !!!next-token;
4506          } else {          } else {
4507            !!!nack ('t347.1');            !!!nack ('t347.1');
# Line 4500  sub _tree_construction_main ($) { Line 4511  sub _tree_construction_main ($) {
4511        } elsif ($token->{tag_name} eq 'li') {        } elsif ($token->{tag_name} eq 'li') {
4512          ## NOTE: As normal, but imply </li> when there's another <li> ...          ## NOTE: As normal, but imply </li> when there's another <li> ...
4513    
4514          ## NOTE: Special, Scope (<li><foo><li> == <li><foo><li/></foo></li>)          ## NOTE: Special, Scope (<li><foo><li> == <li><foo><li/></foo></li>)::
4515            ## Interpreted as <li><foo/></li><li/> (non-conforming)            ## Interpreted as <li><foo/></li><li/> (non-conforming):
4516            ## blockquote (O9.27), center (O), dd (Fx3, O, S3.1.2, IE7),            ## blockquote (O9.27), center (O), dd (Fx3, O, S3.1.2, IE7),
4517            ## 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),
4518            ## 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),
4519            ## object (Fx)            ## object (Fx)
4520            ## Generate non-tree (non-conforming)            ## Generate non-tree (non-conforming):
4521            ## basefont (IE7 (where basefont is non-void)), center (IE),            ## basefont (IE7 (where basefont is non-void)), center (IE),
4522            ## form (IE), hn (IE)            ## form (IE), hn (IE)
4523          ## address, div, p (<li><foo><li> == <li><foo/></li><li/>)          ## address, div, p (<li><foo><li> == <li><foo/></li><li/>)::
4524            ## Interpreted as <li><foo><li/></foo></li> (non-conforming)            ## Interpreted as <li><foo><li/></foo></li> (non-conforming):
4525            ## div (Fx, S)            ## div (Fx, S)
4526    
4527            ## 1. Frameset-ng
4528            delete $self->{frameset_ok};
4529    
4530          my $non_optional;          my $non_optional;
4531          my $i = -1;          my $i = -1;
4532    
4533          ## 1.          ## 2.
4534          for my $node (reverse @{$self->{open_elements}}) {          for my $node (reverse @{$self->{open_elements}}) {
4535            if ($node->[1] == LI_EL) {            if ($node->[1] == LI_EL) {
4536              ## 2. (a) As if </li>              ## 3. (a) As if </li>
4537              {              {
4538                ## If no </li> - not applied                ## If no </li> - not applied
4539                #                #
# Line 4543  sub _tree_construction_main ($) { Line 4557  sub _tree_construction_main ($) {
4557                splice @{$self->{open_elements}}, $i;                splice @{$self->{open_elements}}, $i;
4558              }              }
4559    
4560              last; ## 2. (b) goto 5.              last; ## 3. (b) goto 5.
4561            } elsif (            } elsif (
4562                     ## NOTE: not "formatting" and not "phrasing"                     ## NOTE: not "formatting" and not "phrasing"
4563                     ($node->[1] & SPECIAL_EL or                     ($node->[1] & SPECIAL_EL or
# Line 4551  sub _tree_construction_main ($) { Line 4565  sub _tree_construction_main ($) {
4565                     ## NOTE: "li", "dt", and "dd" are in |SPECIAL_EL|.                     ## NOTE: "li", "dt", and "dd" are in |SPECIAL_EL|.
4566                     (not $node->[1] & ADDRESS_DIV_P_EL)                     (not $node->[1] & ADDRESS_DIV_P_EL)
4567                    ) {                    ) {
4568              ## 3.              ## 4.
4569              !!!cp ('t357');              !!!cp ('t357');
4570              last; ## goto 5.              last; ## goto 6.
4571            } elsif ($node->[1] & END_TAG_OPTIONAL_EL) {            } elsif ($node->[1] & END_TAG_OPTIONAL_EL) {
4572              !!!cp ('t358');              !!!cp ('t358');
4573              #              #
# Line 4562  sub _tree_construction_main ($) { Line 4576  sub _tree_construction_main ($) {
4576              $non_optional ||= $node;              $non_optional ||= $node;
4577              #              #
4578            }            }
4579            ## 4.            ## 5.
4580            ## goto 2.            ## goto 3.
4581            $i--;            $i--;
4582          }          }
4583    
4584          ## 5. (a) has a |p| element in scope          ## 6. (a) has a |p| element in scope
4585          INSCOPE: for (reverse @{$self->{open_elements}}) {          INSCOPE: for (reverse @{$self->{open_elements}}) {
4586            if ($_->[1] == P_EL) {            if ($_->[1] == P_EL) {
4587              !!!cp ('t353');              !!!cp ('t353');
# Line 4584  sub _tree_construction_main ($) { Line 4598  sub _tree_construction_main ($) {
4598            }            }
4599          } # INSCOPE          } # INSCOPE
4600    
4601          ## 5. (b) insert          ## 6. (b) insert
4602          !!!insert-element-t ($token->{tag_name}, $token->{attributes}, $token);          !!!insert-element-t ($token->{tag_name}, $token->{attributes}, $token);
4603          !!!nack ('t359.1');          !!!nack ('t359.1');
4604          !!!next-token;          !!!next-token;
# Line 4593  sub _tree_construction_main ($) { Line 4607  sub _tree_construction_main ($) {
4607                 $token->{tag_name} eq 'dd') {                 $token->{tag_name} eq 'dd') {
4608          ## NOTE: As normal, but imply </dt> or </dd> when ...          ## NOTE: As normal, but imply </dt> or </dd> when ...
4609    
4610            ## 1. Frameset-ng
4611            delete $self->{frameset_ok};
4612    
4613          my $non_optional;          my $non_optional;
4614          my $i = -1;          my $i = -1;
4615    
4616          ## 1.          ## 2.
4617          for my $node (reverse @{$self->{open_elements}}) {          for my $node (reverse @{$self->{open_elements}}) {
4618            if ($node->[1] == DTDD_EL) {            if ($node->[1] == DTDD_EL) {
4619              ## 2. (a) As if </li>              ## 3. (a) As if </li>
4620              {              {
4621                ## If no </li> - not applied                ## If no </li> - not applied
4622                #                #
# Line 4623  sub _tree_construction_main ($) { Line 4640  sub _tree_construction_main ($) {
4640                splice @{$self->{open_elements}}, $i;                splice @{$self->{open_elements}}, $i;
4641              }              }
4642    
4643              last; ## 2. (b) goto 5.              last; ## 3. (b) goto 5.
4644            } elsif (            } elsif (
4645                     ## NOTE: not "formatting" and not "phrasing"                     ## NOTE: not "formatting" and not "phrasing"
4646                     ($node->[1] & SPECIAL_EL or                     ($node->[1] & SPECIAL_EL or
# Line 4632  sub _tree_construction_main ($) { Line 4649  sub _tree_construction_main ($) {
4649    
4650                     (not $node->[1] & ADDRESS_DIV_P_EL)                     (not $node->[1] & ADDRESS_DIV_P_EL)
4651                    ) {                    ) {
4652              ## 3.              ## 4.
4653              !!!cp ('t357.1');              !!!cp ('t357.1');
4654              last; ## goto 5.              last; ## goto 5.
4655            } elsif ($node->[1] & END_TAG_OPTIONAL_EL) {            } elsif ($node->[1] & END_TAG_OPTIONAL_EL) {
# Line 4643  sub _tree_construction_main ($) { Line 4660  sub _tree_construction_main ($) {
4660              $non_optional ||= $node;              $non_optional ||= $node;
4661              #              #
4662            }            }
4663            ## 4.            ## 5.
4664            ## goto 2.            ## goto 3.
4665            $i--;            $i--;
4666          }          }
4667    
4668          ## 5. (a) has a |p| element in scope          ## 6. (a) has a |p| element in scope
4669          INSCOPE: for (reverse @{$self->{open_elements}}) {          INSCOPE: for (reverse @{$self->{open_elements}}) {
4670            if ($_->[1] == P_EL) {            if ($_->[1] == P_EL) {
4671              !!!cp ('t353.1');              !!!cp ('t353.1');
# Line 4662  sub _tree_construction_main ($) { Line 4679  sub _tree_construction_main ($) {
4679            }            }
4680          } # INSCOPE          } # INSCOPE
4681    
4682          ## 5. (b) insert          ## 6. (b) insert
4683          !!!insert-element-t ($token->{tag_name}, $token->{attributes}, $token);          !!!insert-element-t ($token->{tag_name}, $token->{attributes}, $token);
4684          !!!nack ('t359.2');          !!!nack ('t359.2');
4685          !!!next-token;          !!!next-token;
# Line 4782  sub _tree_construction_main ($) { Line 4799  sub _tree_construction_main ($) {
4799    
4800          push @$active_formatting_elements, ['#marker', ''];          push @$active_formatting_elements, ['#marker', ''];
4801    
4802            delete $self->{frameset_ok};
4803    
4804          !!!nack ('t379.1');          !!!nack ('t379.1');
4805          !!!next-token;          !!!next-token;
4806          next B;          next B;
# Line 4795  sub _tree_construction_main ($) { Line 4814  sub _tree_construction_main ($) {
4814          if ($token->{tag_name} eq 'xmp') {          if ($token->{tag_name} eq 'xmp') {
4815            !!!cp ('t381');            !!!cp ('t381');
4816            $reconstruct_active_formatting_elements->($insert_to_current);            $reconstruct_active_formatting_elements->($insert_to_current);
4817    
4818              delete $self->{frameset_ok};
4819            } elsif ($token->{tag_name} eq 'iframe') {
4820              !!!cp ('t381.1');
4821              delete $self->{frameset_ok};
4822          } else {          } else {
4823            !!!cp ('t399');            !!!cp ('t399');
4824          }          }
# Line 4857  sub _tree_construction_main ($) { Line 4881  sub _tree_construction_main ($) {
4881            next B;            next B;
4882          }          }
4883        } elsif ($token->{tag_name} eq 'textarea') {        } elsif ($token->{tag_name} eq 'textarea') {
4884          ## Step 1          ## 1. Insert
4885          !!!insert-element-t ($token->{tag_name}, $token->{attributes}, $token);          !!!insert-element-t ($token->{tag_name}, $token->{attributes}, $token);
4886                    
4887          ## Step 2          ## Step 2 # XXX
4888          ## TODO: $self->{form_element} if defined          ## TODO: $self->{form_element} if defined
4889    
4890          ## Step 3          ## 2. Drop U+000A LINE FEED
4891          $self->{ignore_newline} = 1;          $self->{ignore_newline} = 1;
4892    
4893          ## Step 4          ## 3. RCDATA
         ## ISSUE: This step is wrong. (r2302 enbugged)  
   
         ## Step 5  
4894          $self->{content_model} = RCDATA_CONTENT_MODEL;          $self->{content_model} = RCDATA_CONTENT_MODEL;
4895          delete $self->{escape}; # MUST          delete $self->{escape}; # MUST
4896    
4897          ## Step 6-7          ## 4., 6. Insertion mode
4898          $self->{insertion_mode} |= IN_CDATA_RCDATA_IM;          $self->{insertion_mode} |= IN_CDATA_RCDATA_IM;
4899    
4900            ## 5. Frameset-ng.
4901            delete $self->{frameset_ok};
4902    
4903          !!!nack ('t392.1');          !!!nack ('t392.1');
4904          !!!next-token;          !!!next-token;
4905          next B;          next B;
# Line 4966  sub _tree_construction_main ($) { Line 4990  sub _tree_construction_main ($) {
4990          next B;          next B;
4991        } elsif ({        } elsif ({
4992                  caption => 1, col => 1, colgroup => 1, frame => 1,                  caption => 1, col => 1, colgroup => 1, frame => 1,
4993                  frameset => 1, head => 1,                  head => 1,
4994                  tbody => 1, td => 1, tfoot => 1, th => 1,                  tbody => 1, td => 1, tfoot => 1, th => 1,
4995                  thead => 1, tr => 1,                  thead => 1, tr => 1,
4996                 }->{$token->{tag_name}}) {                 }->{$token->{tag_name}}) {
# Line 5003  sub _tree_construction_main ($) { Line 5027  sub _tree_construction_main ($) {
5027               applet => 1, marquee => 1, object => 1,               applet => 1, marquee => 1, object => 1,
5028              }->{$token->{tag_name}}) {              }->{$token->{tag_name}}) {
5029            !!!cp ('t380');            !!!cp ('t380');
5030    
5031            push @$active_formatting_elements, ['#marker', ''];            push @$active_formatting_elements, ['#marker', ''];
5032    
5033              delete $self->{frameset_ok};
5034    
5035            !!!nack ('t380.1');            !!!nack ('t380.1');
5036          } elsif ({          } elsif ({
5037                    b => 1, big => 1, em => 1, font => 1, i => 1,                    b => 1, big => 1, em => 1, font => 1, i => 1,
# Line 5021  sub _tree_construction_main ($) { Line 5049  sub _tree_construction_main ($) {
5049          } elsif ({          } elsif ({
5050                    area => 1, basefont => 1, bgsound => 1, br => 1,                    area => 1, basefont => 1, bgsound => 1, br => 1,
5051                    embed => 1, img => 1, spacer => 1, wbr => 1,                    embed => 1, img => 1, spacer => 1, wbr => 1,
5052                      keygen => 1,
5053                   }->{$token->{tag_name}}) {                   }->{$token->{tag_name}}) {
5054            !!!cp ('t388.1');            !!!cp ('t388.1');
5055    
5056            pop @{$self->{open_elements}};            pop @{$self->{open_elements}};
5057    
5058              delete $self->{frameset_ok};
5059    
5060            !!!ack ('t388.3');            !!!ack ('t388.3');
5061          } elsif ($token->{tag_name} eq 'select') {          } elsif ($token->{tag_name} eq 'select') {
5062            ## TODO: associate with $self->{form_element} if defined            ## TODO: associate with $self->{form_element} if defined
5063            
5064              delete $self->{frameset_ok};
5065              
5066            if ($self->{insertion_mode} & TABLE_IMS or            if ($self->{insertion_mode} & TABLE_IMS or
5067                $self->{insertion_mode} & BODY_TABLE_IMS or                $self->{insertion_mode} & BODY_TABLE_IMS or
5068                ($self->{insertion_mode} & IM_MASK) == IN_COLUMN_GROUP_IM) {                ($self->{insertion_mode} & IM_MASK) == IN_COLUMN_GROUP_IM) {
# Line 5046  sub _tree_construction_main ($) { Line 5081  sub _tree_construction_main ($) {
5081          next B;          next B;
5082        }        }
5083      } elsif ($token->{type} == END_TAG_TOKEN) {      } elsif ($token->{type} == END_TAG_TOKEN) {
5084        if ($token->{tag_name} eq 'body') {        if ($token->{tag_name} eq 'body' or $token->{tag_name} eq 'html') {
5085          ## has a |body| element in scope  
5086            ## 1. If not "have an element in scope":
5087            ## "has a |body| element in scope"
5088          my $i;          my $i;
5089          INSCOPE: {          INSCOPE: {
5090            for (reverse @{$self->{open_elements}}) {            for (reverse @{$self->{open_elements}}) {
# Line 5061  sub _tree_construction_main ($) { Line 5098  sub _tree_construction_main ($) {
5098              }              }
5099            }            }
5100    
5101            ## NOTE: |<marquee></body>|, |<svg><foreignobject></body>|            ## NOTE: |<marquee></body>|, |<svg><foreignobject></body>|,
5102              ## and fragment cases.
5103    
5104            !!!parse-error (type => 'unmatched end tag',            !!!parse-error (type => 'unmatched end tag',
5105                            text => $token->{tag_name}, token => $token);                            text => $token->{tag_name}, token => $token);
5106            ## NOTE: Ignore the token.            ## Ignore the token.  (</body> or </html>)
5107            !!!next-token;            !!!next-token;
5108            next B;            next B;
5109          } # INSCOPE          } # INSCOPE
5110    
5111            ## 2. If unclosed elements:
5112          for (@{$self->{open_elements}}) {          for (@{$self->{open_elements}}) {
5113            unless ($_->[1] & ALL_END_TAG_OPTIONAL_EL ||            unless ($_->[1] & ALL_END_TAG_OPTIONAL_EL ||
5114                    $_->[1] == OPTGROUP_EL ||                    $_->[1] == OPTGROUP_EL ||
# Line 5085  sub _tree_construction_main ($) { Line 5124  sub _tree_construction_main ($) {
5124            }            }
5125          }          }
5126    
5127            ## 3. Switch the insertion mode.
5128          $self->{insertion_mode} = AFTER_BODY_IM;          $self->{insertion_mode} = AFTER_BODY_IM;
5129          !!!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  
5130            !!!next-token;            !!!next-token;
5131            next B;          } else { # html
5132              ## Reprocess.
5133          }          }
5134            next B;
5135        } elsif ({        } elsif ({
5136                  ## NOTE: End tags for non-phrasing flow content elements                  ## NOTE: End tags for non-phrasing flow content elements
5137    
# Line 5120  sub _tree_construction_main ($) { Line 5139  sub _tree_construction_main ($) {
5139                  address => 1, article => 1, aside => 1, blockquote => 1,                  address => 1, article => 1, aside => 1, blockquote => 1,
5140                  center => 1, datagrid => 1, details => 1, dialog => 1,                  center => 1, datagrid => 1, details => 1, dialog => 1,
5141                  dir => 1, div => 1, dl => 1, fieldset => 1, figure => 1,                  dir => 1, div => 1, dl => 1, fieldset => 1, figure => 1,
5142                  footer => 1, header => 1, listing => 1, menu => 1, nav => 1,                  footer => 1, header => 1, hgroup => 1,
5143                    listing => 1, menu => 1, nav => 1,
5144                  ol => 1, pre => 1, section => 1, ul => 1,                  ol => 1, pre => 1, section => 1, ul => 1,
5145    
5146                  ## NOTE: As normal, but ... optional tags                  ## NOTE: As normal, but ... optional tags
# Line 5480  sub set_inner_html ($$$$;$) { Line 5500  sub set_inner_html ($$$$;$) {
5500    my $onerror = $_[1];    my $onerror = $_[1];
5501    my $get_wrapper = $_[2] || sub ($) { return $_[0] };    my $get_wrapper = $_[2] || sub ($) { return $_[0] };
5502    
   ## ISSUE: Should {confident} be true?  
   
5503    my $nt = $node->node_type;    my $nt = $node->node_type;
5504    if ($nt == 9) { # Document (invoke the algorithm with no /context/ element)    if ($nt == 9) { # Document (invoke the algorithm with no /context/ element)
5505      # MUST      # MUST
# Line 5696  sub set_inner_html ($$$$;$) { Line 5714  sub set_inner_html ($$$$;$) {
5714        $anode = $anode->parent_node;        $anode = $anode->parent_node;
5715      } # AN      } # AN
5716    
5717        ## F.5. Set the input stream.
5718        $p->{confident} = 1; ## Confident: irrelevant.
5719    
5720      ## F.6. Start the parser.      ## F.6. Start the parser.
5721      {      {
5722        my $self = $p;        my $self = $p;

Legend:
Removed from v.1.223  
changed lines
  Added in v.1.244

[email protected]
ViewVC Help
Powered by ViewVC 1.1.24