/[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.214 by wakaba, Thu Jul 2 22:08:37 2009 UTC revision 1.229 by wakaba, Sat Sep 5 13:30:43 2009 UTC
# Line 525  sub parse_byte_stream ($$$$;$$) { Line 525  sub parse_byte_stream ($$$$;$$) {
525            
526      if ($char_stream) { # if supported      if ($char_stream) { # if supported
527        ## "Change the encoding" algorithm:        ## "Change the encoding" algorithm:
528          
529          ## Step 1
530          if (defined $self->{input_encoding} and
531              $self->{input_encoding} eq $charset_name) {
532            !!!parse-error (type => 'charset label:matching',
533                            text => $charset_name,
534                            level => $self->{level}->{info});
535            $self->{confident} = 1;
536            return;
537          }
538    
539        ## Step 2 (HTML5 revision 3205)        ## Step 2 (HTML5 revision 3205)
540        if (defined $self->{input_encoding} and        if (defined $self->{input_encoding} and
# Line 543  sub parse_byte_stream ($$$$;$$) { Line 553  sub parse_byte_stream ($$$$;$$) {
553               byte_buffer => \ $buffer->{buffer});               byte_buffer => \ $buffer->{buffer});
554        }        }
555        $charset_name = $charset->get_iana_name;        $charset_name = $charset->get_iana_name;
         
       ## Step 1 XXX  
       if (defined $self->{input_encoding} and  
           $self->{input_encoding} eq $charset_name) {  
         !!!parse-error (type => 'charset label:matching',  
                         text => $charset_name,  
                         level => $self->{level}->{info});  
         $self->{confident} = 1;  
         return;  
       }  
556    
557        !!!parse-error (type => 'charset label detected',        !!!parse-error (type => 'charset label detected',
558                        text => $self->{input_encoding},                        text => $self->{input_encoding},
# Line 911  sub _tree_construction_initial ($) { Line 911  sub _tree_construction_initial ($) {
911    
912    INITIAL: {    INITIAL: {
913      if ($token->{type} == DOCTYPE_TOKEN) {      if ($token->{type} == DOCTYPE_TOKEN) {
914        ## NOTE: Conformance checkers MAY, instead of reporting "not HTML5"        ## NOTE: Conformance checkers MAY, instead of reporting "not
915        ## error, switch to a conformance checking mode for another        ## HTML5" error, switch to a conformance checking mode for
916        ## language.        ## another language.  (We don't support such mode switchings; it
917          ## is nonsense to do anything different from what browsers do.)
918        my $doctype_name = $token->{name};        my $doctype_name = $token->{name};
919        $doctype_name = '' unless defined $doctype_name;        $doctype_name = '' unless defined $doctype_name;
920        $doctype_name =~ tr/a-z/A-Z/; # ASCII case-insensitive        my $doctype = $self->{document}->create_document_type_definition
921        if (not defined $token->{name} or # <!DOCTYPE>            ($doctype_name);
922            defined $token->{sysid}) {  
923          $doctype_name =~ tr/A-Z/a-z/; # ASCII case-insensitive
924          if ($doctype_name ne 'html') {
925          !!!cp ('t1');          !!!cp ('t1');
926          !!!parse-error (type => 'not HTML5', token => $token);          !!!parse-error (type => 'not HTML5', token => $token);
927        } elsif ($doctype_name ne 'HTML') {        } elsif (defined $token->{pubid}) {
928          !!!cp ('t2');          !!!cp ('t2');
929            ## XXX Obsolete permitted DOCTYPEs
930          !!!parse-error (type => 'not HTML5', token => $token);          !!!parse-error (type => 'not HTML5', token => $token);
931        } elsif (defined $token->{pubid}) {        } elsif (defined $token->{sysid}) {
932          if ($token->{pubid} eq 'XSLT-compat') {          if ($token->{sysid} eq 'about:legacy-compat') {
933            !!!cp ('t1.2');            !!!cp ('t1.2'); ## <!DOCTYPE HTML SYSTEM "about:legacy-compat">
934            !!!parse-error (type => 'XSLT-compat', token => $token,            !!!parse-error (type => 'XSLT-compat', token => $token,
935                            level => $self->{level}->{should});                            level => $self->{level}->{should});
936          } else {          } else {
937            !!!parse-error (type => 'not HTML5', token => $token);            !!!parse-error (type => 'not HTML5', token => $token);
938          }          }
939        } else {        } else { ## <!DOCTYPE HTML>
940          !!!cp ('t3');          !!!cp ('t3');
941          #          #
942        }        }
943                
       my $doctype = $self->{document}->create_document_type_definition  
         ($token->{name}); ## ISSUE: If name is missing (e.g. <!DOCTYPE>)?  
944        ## NOTE: Default value for both |public_id| and |system_id| attributes        ## NOTE: Default value for both |public_id| and |system_id| attributes
945        ## 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.
946        $doctype->public_id ($token->{pubid}) if defined $token->{pubid};        $doctype->public_id ($token->{pubid}) if defined $token->{pubid};
947        $doctype->system_id ($token->{sysid}) if defined $token->{sysid};        $doctype->system_id ($token->{sysid}) if defined $token->{sysid};
948    
949        ## NOTE: Other DocumentType attributes are null or empty lists.        ## NOTE: Other DocumentType attributes are null or empty lists.
950        ## In Firefox3, |internalSubset| attribute is set to the empty        ## In Firefox3, |internalSubset| attribute is set to the empty
951        ## string, while |null| is an allowed value for the attribute        ## string, while |null| is an allowed value for the attribute
952        ## according to DOM3 Core.        ## according to DOM3 Core.
953        $self->{document}->append_child ($doctype);        $self->{document}->append_child ($doctype);
954                
955        if ($token->{quirks} or $doctype_name ne 'HTML') {        if ($token->{quirks} or $doctype_name ne 'html') {
956          !!!cp ('t4');          !!!cp ('t4');
957          $self->{document}->manakai_compat_mode ('quirks');          $self->{document}->manakai_compat_mode ('quirks');
958        } elsif (defined $token->{pubid}) {        } elsif (defined $token->{pubid}) {
# Line 1419  sub _tree_construction_main ($) { Line 1422  sub _tree_construction_main ($) {
1422      ## Step 3      ## Step 3
1423      ## TODO: Mark as "already executed", if ...      ## TODO: Mark as "already executed", if ...
1424    
1425      ## Step 4      ## Step 4 (HTML5 revision 2702)
1426      $insert->($script_el);      $insert->($script_el);
   
     ## ISSUE: $script_el is not put into the stack  
1427      push @{$self->{open_elements}}, [$script_el, $el_category->{script}];      push @{$self->{open_elements}}, [$script_el, $el_category->{script}];
1428    
1429      ## Step 5      ## Step 5
# Line 1437  sub _tree_construction_main ($) { Line 1438  sub _tree_construction_main ($) {
1438    }; # $script_start_tag    }; # $script_start_tag
1439    
1440    ## NOTE: $open_tables->[-1]->[0] is the "current table" element node.    ## NOTE: $open_tables->[-1]->[0] is the "current table" element node.
1441    ## NOTE: $open_tables->[-1]->[1] is the "tainted" flag.    ## NOTE: $open_tables->[-1]->[1] is the "tainted" flag (OBSOLETE; unused).
1442    ## 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.
1443    my $open_tables = [[$self->{open_elements}->[0]->[0]]];    my $open_tables = [[$self->{open_elements}->[0]->[0]]];
1444    
# Line 1874  sub _tree_construction_main ($) { Line 1875  sub _tree_construction_main ($) {
1875          } elsif ({          } elsif ({
1876                    b => 1, big => 1, blockquote => 1, body => 1, br => 1,                    b => 1, big => 1, blockquote => 1, body => 1, br => 1,
1877                    center => 1, code => 1, dd => 1, div => 1, dl => 1, dt => 1,                    center => 1, code => 1, dd => 1, div => 1, dl => 1, dt => 1,
1878                    em => 1, embed => 1, font => 1, h1 => 1, h2 => 1, h3 => 1,                    em => 1, embed => 1, h1 => 1, h2 => 1, h3 => 1,
1879                    h4 => 1, h5 => 1, h6 => 1, head => 1, hr => 1, i => 1,                    h4 => 1, h5 => 1, h6 => 1, head => 1, hr => 1, i => 1,
1880                    img => 1, li => 1, listing => 1, menu => 1, meta => 1,                    img => 1, li => 1, listing => 1, menu => 1, meta => 1,
1881                    nobr => 1, ol => 1, p => 1, pre => 1, ruby => 1, s => 1,                    nobr => 1, ol => 1, p => 1, pre => 1, ruby => 1, s => 1,
1882                    small => 1, span => 1, strong => 1, strike => 1, sub => 1,                    small => 1, span => 1, strong => 1, strike => 1, sub => 1,
1883                    sup => 1, table => 1, tt => 1, u => 1, ul => 1, var => 1,                    sup => 1, table => 1, tt => 1, u => 1, ul => 1, var => 1,
1884                   }->{$token->{tag_name}}) {                   }->{$token->{tag_name}} or
1885                     ($token->{tag_name} eq 'font' and
1886                      ($token->{attributes}->{color} or
1887                       $token->{attributes}->{face} or
1888                       $token->{attributes}->{size}))) {
1889            !!!cp ('t87.2');            !!!cp ('t87.2');
1890            !!!parse-error (type => 'not closed',            !!!parse-error (type => 'not closed',
1891                            text => $self->{open_elements}->[-1]->[0]                            text => $self->{open_elements}->[-1]->[0]
# Line 1956  sub _tree_construction_main ($) { Line 1961  sub _tree_construction_main ($) {
1961          }          }
1962        } elsif ($token->{type} == END_TAG_TOKEN) {        } elsif ($token->{type} == END_TAG_TOKEN) {
1963          ## NOTE: "using the rules for secondary insertion mode" then "continue"          ## NOTE: "using the rules for secondary insertion mode" then "continue"
1964          !!!cp ('t87.5');          if ($token->{tag_name} eq 'script') {
1965          #            !!!cp ('t87.41');
1966              #
1967              ## XXXscript: Execute script here.
1968            } else {
1969              !!!cp ('t87.5');
1970              #
1971            }
1972        } elsif ($token->{type} == END_OF_FILE_TOKEN) {        } elsif ($token->{type} == END_OF_FILE_TOKEN) {
1973          !!!cp ('t87.6');          !!!cp ('t87.6');
1974          !!!parse-error (type => 'not closed',          !!!parse-error (type => 'not closed',
# Line 2257  sub _tree_construction_main ($) { Line 2268  sub _tree_construction_main ($) {
2268    
2269            ## NOTE: There is a "as if in head" code clone.            ## NOTE: There is a "as if in head" code clone.
2270            $parse_rcdata->(RCDATA_CONTENT_MODEL);            $parse_rcdata->(RCDATA_CONTENT_MODEL);
2271            ## ISSUE: A spec bug [Bug 6038]  
2272              ## NOTE: At this point the stack of open elements contain
2273              ## the |head| element (index == -2) and the |script| element
2274              ## (index == -1).  In the "after head" insertion mode the
2275              ## |head| element is inserted only for the purpose of
2276              ## providing the context for the |script| element, and
2277              ## therefore we can now and have to remove the element from
2278              ## the stack.
2279            splice @{$self->{open_elements}}, -2, 1, () # <head>            splice @{$self->{open_elements}}, -2, 1, () # <head>
2280                if ($self->{insertion_mode} & IM_MASK) == AFTER_HEAD_IM;                if ($self->{insertion_mode} & IM_MASK) == AFTER_HEAD_IM;
2281            next B;            next B;
# Line 2492  sub _tree_construction_main ($) { Line 2510  sub _tree_construction_main ($) {
2510                ## Ignore the token                ## Ignore the token
2511                !!!next-token;                !!!next-token;
2512                next B;                next B;
2513              } elsif ($token->{tag_name} eq 'br') {          } elsif ($token->{tag_name} eq 'br') {
2514                if ($self->{insertion_mode} == BEFORE_HEAD_IM) {            if ($self->{insertion_mode} == BEFORE_HEAD_IM) {
2515                  !!!cp ('t142.2');              !!!cp ('t142.2');
2516                  ## (before head) as if <head>, (in head) as if </head>              ## (before head) as if <head>, (in head) as if </head>
2517                  !!!create-element ($self->{head_element}, $HTML_NS, 'head',, $token);              !!!create-element ($self->{head_element}, $HTML_NS, 'head',, $token);
2518                  $self->{open_elements}->[-1]->[0]->append_child ($self->{head_element});              $self->{open_elements}->[-1]->[0]->append_child ($self->{head_element});
2519                  $self->{insertion_mode} = AFTER_HEAD_IM;              $self->{insertion_mode} = AFTER_HEAD_IM;
2520        
2521                  ## Reprocess in the "after head" insertion mode...              ## Reprocess in the "after head" insertion mode...
2522                } elsif ($self->{insertion_mode} == IN_HEAD_IM) {            } elsif ($self->{insertion_mode} == IN_HEAD_IM) {
2523                  !!!cp ('t143.2');              !!!cp ('t143.2');
2524                  ## As if </head>              ## As if </head>
2525                  pop @{$self->{open_elements}};              pop @{$self->{open_elements}};
2526                  $self->{insertion_mode} = AFTER_HEAD_IM;              $self->{insertion_mode} = AFTER_HEAD_IM;
2527        
2528                  ## Reprocess in the "after head" insertion mode...              ## Reprocess in the "after head" insertion mode...
2529                } elsif ($self->{insertion_mode} == IN_HEAD_NOSCRIPT_IM) {            } elsif ($self->{insertion_mode} == IN_HEAD_NOSCRIPT_IM) {
2530                  !!!cp ('t143.3');              !!!cp ('t143.3');
2531                  ## NOTE: Two parse errors for <head><noscript></br>              ## NOTE: Two parse errors for <head><noscript></br>
2532                  !!!parse-error (type => 'unmatched end tag',              !!!parse-error (type => 'unmatched end tag',
2533                                  text => 'br', token => $token);                              text => 'br', token => $token);
2534                  ## As if </noscript>              ## As if </noscript>
2535                  pop @{$self->{open_elements}};              pop @{$self->{open_elements}};
2536                  $self->{insertion_mode} = IN_HEAD_IM;              $self->{insertion_mode} = IN_HEAD_IM;
2537    
2538                  ## Reprocess in the "in head" insertion mode...              ## Reprocess in the "in head" insertion mode...
2539                  ## As if </head>              ## As if </head>
2540                  pop @{$self->{open_elements}};              pop @{$self->{open_elements}};
2541                  $self->{insertion_mode} = AFTER_HEAD_IM;              $self->{insertion_mode} = AFTER_HEAD_IM;
2542    
2543                  ## Reprocess in the "after head" insertion mode...              ## Reprocess in the "after head" insertion mode...
2544                } elsif ($self->{insertion_mode} == AFTER_HEAD_IM) {            } elsif ($self->{insertion_mode} == AFTER_HEAD_IM) {
2545                  !!!cp ('t143.4');              !!!cp ('t143.4');
2546                  #              #
2547                } else {            } else {
2548                  die "$0: $self->{insertion_mode}: Unknown insertion mode";              die "$0: $self->{insertion_mode}: Unknown insertion mode";
2549                }            }
2550    
2551                ## ISSUE: does not agree with IE7 - it doesn't ignore </br>.            #
2552                !!!parse-error (type => 'unmatched end tag',          } else { ## Other end tags
                               text => 'br', token => $token);  
               ## Ignore the token  
               !!!next-token;  
               next B;  
             } else {  
2553                !!!cp ('t145');                !!!cp ('t145');
2554                !!!parse-error (type => 'unmatched end tag',                !!!parse-error (type => 'unmatched end tag',
2555                                text => $token->{tag_name}, token => $token);                                text => $token->{tag_name}, token => $token);
# Line 2580  sub _tree_construction_main ($) { Line 2593  sub _tree_construction_main ($) {
2593              !!!insert-element ('body',, $token);              !!!insert-element ('body',, $token);
2594              $self->{insertion_mode} = IN_BODY_IM;              $self->{insertion_mode} = IN_BODY_IM;
2595              ## reprocess              ## reprocess
2596              next B;          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) {        C: {
3025          if (not $open_tables->[-1]->[1] and # tainted          my $s;
3026              $token->{data} =~ s/^([\x09\x0A\x0C\x20]+)//) {          if ($token->{type} == CHARACTER_TOKEN) {
3027            $self->{open_elements}->[-1]->[0]->manakai_append_text ($1);            !!!cp ('t194');
3028                            $self->{pending_chars} ||= [];
3029            unless (length $token->{data}) {            push @{$self->{pending_chars}}, $token;
3030              !!!cp ('t194');            !!!next-token;
3031              !!!next-token;            next B;
3032              next B;          } else {
3033              if ($self->{pending_chars}) {
3034                $s = join '', map { $_->{data} } @{$self->{pending_chars}};
3035                delete $self->{pending_chars};
3036                if ($s =~ /[^\x09\x0A\x0C\x0D\x20]/) {
3037                  !!!cp ('t195');
3038                  #
3039                } else {
3040                  !!!cp ('t195.1');
3041                  #$self->{open_elements}->[-1]->[0]->manakai_append_text ($s);
3042                  $self->{open_elements}->[-1]->[0]->append_child
3043                      ($self->{document}->create_text_node ($s));
3044                  last C;
3045                }
3046            } else {            } else {
3047              !!!cp ('t195');              !!!cp ('t195.2');
3048                last C;
3049            }            }
3050          }          }
3051    
3052            ## Foster parenting
3053          !!!parse-error (type => 'in table:#text', token => $token);          !!!parse-error (type => 'in table:#text', token => $token);
3054    
3055          ## NOTE: As if in body, but insert into the foster parent element.          ## NOTE: As if in body, but insert into the foster parent element.
# Line 3031  sub _tree_construction_main ($) { Line 3059  sub _tree_construction_main ($) {
3059            # MUST            # MUST
3060            my $foster_parent_element;            my $foster_parent_element;
3061            my $next_sibling;            my $next_sibling;
3062            my $prev_sibling;            #my $prev_sibling;
3063            OE: for (reverse 0..$#{$self->{open_elements}}) {            OE: for (reverse 0..$#{$self->{open_elements}}) {
3064              if ($self->{open_elements}->[$_]->[1] == TABLE_EL) {              if ($self->{open_elements}->[$_]->[1] == TABLE_EL) {
3065                my $parent = $self->{open_elements}->[$_]->[0]->parent_node;                my $parent = $self->{open_elements}->[$_]->[0]->parent_node;
# Line 3039  sub _tree_construction_main ($) { Line 3067  sub _tree_construction_main ($) {
3067                  $foster_parent_element = $parent;                  $foster_parent_element = $parent;
3068                  !!!cp ('t196');                  !!!cp ('t196');
3069                  $next_sibling = $self->{open_elements}->[$_]->[0];                  $next_sibling = $self->{open_elements}->[$_]->[0];
3070                  $prev_sibling = $next_sibling->previous_sibling;            #      $prev_sibling = $next_sibling->previous_sibling;
3071                  #                  #
3072                } else {                } else {
3073                  !!!cp ('t197');                  !!!cp ('t197');
3074                  $foster_parent_element = $self->{open_elements}->[$_ - 1]->[0];                  $foster_parent_element = $self->{open_elements}->[$_ - 1]->[0];
3075                  $prev_sibling = $foster_parent_element->last_child;            #      $prev_sibling = $foster_parent_element->last_child;
3076                  #                  #
3077                }                }
3078                last OE;                last OE;
3079              }              }
3080            } # OE            } # OE
3081            $foster_parent_element = $self->{open_elements}->[0]->[0] and            $foster_parent_element = $self->{open_elements}->[0]->[0] #and
3082            $prev_sibling = $foster_parent_element->last_child            #$prev_sibling = $foster_parent_element->last_child
3083                unless defined $foster_parent_element;                unless defined $foster_parent_element;
3084            undef $prev_sibling unless $open_tables->[-1]->[2]; # ~node inserted            #undef $prev_sibling unless $open_tables->[-1]->[2]; # ~node inserted
3085            if (defined $prev_sibling and            #if (defined $prev_sibling and
3086                $prev_sibling->node_type == 3) {            #    $prev_sibling->node_type == 3) {
3087              !!!cp ('t198');            #  !!! cp ('t198');
3088              $prev_sibling->manakai_append_text ($token->{data});            #  $prev_sibling->manakai_append_text ($s);
3089            } else {            #} else {
3090              !!!cp ('t199');              !!!cp ('t199');
3091              $foster_parent_element->insert_before              $foster_parent_element->insert_before
3092                  ($self->{document}->create_text_node ($token->{data}),                  ($self->{document}->create_text_node ($s), $next_sibling);
3093                   $next_sibling);            #}
           }  
3094            $open_tables->[-1]->[1] = 1; # tainted            $open_tables->[-1]->[1] = 1; # tainted
3095            $open_tables->[-1]->[2] = 1; # ~node inserted            $open_tables->[-1]->[2] = 1; # ~node inserted
3096          } else {          } else {
# Line 3074  sub _tree_construction_main ($) { Line 3101  sub _tree_construction_main ($) {
3101            ## are discarded and fragment parsing does not invoke any            ## are discarded and fragment parsing does not invoke any
3102            ## script.            ## script.
3103            !!!cp ('t200');            !!!cp ('t200');
3104            $self->{open_elements}->[-1]->[0]->manakai_append_text            $self->{open_elements}->[-1]->[0]->manakai_append_text ($s);
               ($token->{data});  
3105          }          }
3106                      } # C
3107          !!!next-token;  
3108          next B;        if ($token->{type} == START_TAG_TOKEN) {
       } elsif ($token->{type} == START_TAG_TOKEN) {  
3109          if ({          if ({
3110               tr => (($self->{insertion_mode} & IM_MASK) != IN_ROW_IM),               tr => (($self->{insertion_mode} & IM_MASK) != IN_ROW_IM),
3111               th => 1, td => 1,               th => 1, td => 1,
# Line 3837  sub _tree_construction_main ($) { Line 3862  sub _tree_construction_main ($) {
3862            !!!next-token;            !!!next-token;
3863            next B;            next B;
3864          } elsif ({          } elsif ({
3865                     select => 1, input => 1, textarea => 1,                     select => 1, input => 1, textarea => 1, keygen => 1,
3866                   }->{$token->{tag_name}} or                   }->{$token->{tag_name}} or
3867                   (($self->{insertion_mode} & IM_MASK)                   (($self->{insertion_mode} & IM_MASK)
3868                        == IN_SELECT_IN_TABLE_IM and                        == IN_SELECT_IN_TABLE_IM and
# Line 3846  sub _tree_construction_main ($) { Line 3871  sub _tree_construction_main ($) {
3871                     tbody => 1, tfoot => 1, thead => 1,                     tbody => 1, tfoot => 1, thead => 1,
3872                     tr => 1, td => 1, th => 1,                     tr => 1, td => 1, th => 1,
3873                    }->{$token->{tag_name}})) {                    }->{$token->{tag_name}})) {
3874            ## TODO: The type below is not good - <select> is replaced by </select>  
3875            !!!parse-error (type => 'not closed', text => 'select',            ## 1. Parse error.
3876                            token => $token);            if ($token->{tag_name} eq 'select') {
3877            ## NOTE: As if the token were </select> (<select> case) or                !!!parse-error (type => 'select in select', ## XXX: documentation
3878            ## as if there were </select> (otherwise).                                token => $token);
3879            ## have an element in table scope            } else {
3880                !!!parse-error (type => 'not closed', text => 'select',
3881                                token => $token);
3882              }
3883    
3884              ## 2./<select>-1. Unless "have an element in table scope" (select):
3885            my $i;            my $i;
3886            INSCOPE: for (reverse 0..$#{$self->{open_elements}}) {            INSCOPE: for (reverse 0..$#{$self->{open_elements}}) {
3887              my $node = $self->{open_elements}->[$_];              my $node = $self->{open_elements}->[$_];
# Line 3866  sub _tree_construction_main ($) { Line 3896  sub _tree_construction_main ($) {
3896            } # INSCOPE            } # INSCOPE
3897            unless (defined $i) {            unless (defined $i) {
3898              !!!cp ('t280');              !!!cp ('t280');
3899              !!!parse-error (type => 'unmatched end tag',              if ($token->{tag_name} eq 'select') {
3900                              text => 'select', token => $token);                ## NOTE: This error would be raised when
3901              ## Ignore the token                ## |select.innerHTML = '<select>'| is executed; in this
3902                  ## case two errors, "select in select" and "unmatched
3903                  ## end tags" are reported to the user, the latter might
3904                  ## be confusing but this is what the spec requires.
3905                  !!!parse-error (type => 'unmatched end tag',
3906                                  text => 'select',
3907                                  token => $token);
3908                }
3909                ## Ignore the token.
3910              !!!nack ('t280.1');              !!!nack ('t280.1');
3911              !!!next-token;              !!!next-token;
3912              next B;              next B;
3913            }            }
3914    
3915              ## 3. Otherwise, as if there were <select>:
3916                                
3917            !!!cp ('t281');            !!!cp ('t281');
3918            splice @{$self->{open_elements}}, $i;            splice @{$self->{open_elements}}, $i;
# Line 3889  sub _tree_construction_main ($) { Line 3929  sub _tree_construction_main ($) {
3929              ## Reprocess the token.              ## Reprocess the token.
3930              next B;              next B;
3931            }            }
3932            } elsif ($token->{tag_name} eq 'script') {
3933              !!!cp ('t281.3');
3934              ## NOTE: This is an "as if in head" code clone
3935              $script_start_tag->();
3936              next B;
3937          } else {          } else {
3938            !!!cp ('t282');            !!!cp ('t282');
3939            !!!parse-error (type => 'in select',            !!!parse-error (type => 'in select',
# Line 4408  sub _tree_construction_main ($) { Line 4453  sub _tree_construction_main ($) {
4453                  table => 1,                  table => 1,
4454                  hr => 1,                  hr => 1,
4455                 }->{$token->{tag_name}}) {                 }->{$token->{tag_name}}) {
4456    
4457            ## 1. When there is an opening |form| element:
4458          if ($token->{tag_name} eq 'form' and defined $self->{form_element}) {          if ($token->{tag_name} eq 'form' and defined $self->{form_element}) {
4459            !!!cp ('t350');            !!!cp ('t350');
4460            !!!parse-error (type => 'in form:form', token => $token);            !!!parse-error (type => 'in form:form', token => $token);
# Line 4417  sub _tree_construction_main ($) { Line 4464  sub _tree_construction_main ($) {
4464            next B;            next B;
4465          }          }
4466    
4467          ## has a p element in scope          ## 2. Close the |p| element, if any.
4468          INSCOPE: for (reverse @{$self->{open_elements}}) {          if ($token->{tag_name} ne 'table' or # The Hixie Quirk
4469            if ($_->[1] == P_EL) {              $self->{document}->manakai_compat_mode ne 'quirks') {
4470              !!!cp ('t344');            ## has a p element in scope
4471              !!!back-token; # <form>            INSCOPE: for (reverse @{$self->{open_elements}}) {
4472              $token = {type => END_TAG_TOKEN, tag_name => 'p',              if ($_->[1] == P_EL) {
4473                        line => $token->{line}, column => $token->{column}};                !!!cp ('t344');
4474              next B;                !!!back-token; # <form>
4475            } elsif ($_->[1] & SCOPING_EL) {                $token = {type => END_TAG_TOKEN, tag_name => 'p',
4476              !!!cp ('t345');                          line => $token->{line}, column => $token->{column}};
4477              last INSCOPE;                next B;
4478                } elsif ($_->[1] & SCOPING_EL) {
4479                  !!!cp ('t345');
4480                  last INSCOPE;
4481                }
4482              } # INSCOPE
4483            }
4484    
4485            ## 3. Close the opening <hn> element, if any.
4486            if ({h1 => 1, h2 => 1, h3 => 1,
4487                 h4 => 1, h5 => 1, h6 => 1}->{$token->{tag_name}}) {
4488              if ($self->{open_elements}->[-1]->[1] == HEADING_EL) {
4489                !!!parse-error (type => 'not closed',
4490                                text => $self->{open_elements}->[-1]->[0]->manakai_local_name,
4491                                token => $token);
4492                pop @{$self->{open_elements}};
4493            }            }
4494          } # INSCOPE          }
4495              
4496            ## 4. Insertion.
4497          !!!insert-element-t ($token->{tag_name}, $token->{attributes}, $token);          !!!insert-element-t ($token->{tag_name}, $token->{attributes}, $token);
4498          if ($token->{tag_name} eq 'pre' or $token->{tag_name} eq 'listing') {          if ($token->{tag_name} eq 'pre' or $token->{tag_name} eq 'listing') {
4499            !!!nack ('t346.1');            !!!nack ('t346.1');
# Line 4474  sub _tree_construction_main ($) { Line 4537  sub _tree_construction_main ($) {
4537        } elsif ($token->{tag_name} eq 'li') {        } elsif ($token->{tag_name} eq 'li') {
4538          ## NOTE: As normal, but imply </li> when there's another <li> ...          ## NOTE: As normal, but imply </li> when there's another <li> ...
4539    
4540          ## NOTE: Special, Scope (<li><foo><li> == <li><foo><li/></foo></li>)          ## NOTE: Special, Scope (<li><foo><li> == <li><foo><li/></foo></li>)::
4541            ## Interpreted as <li><foo/></li><li/> (non-conforming)            ## Interpreted as <li><foo/></li><li/> (non-conforming):
4542            ## blockquote (O9.27), center (O), dd (Fx3, O, S3.1.2, IE7),            ## blockquote (O9.27), center (O), dd (Fx3, O, S3.1.2, IE7),
4543            ## 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),
4544            ## 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),
4545            ## object (Fx)            ## object (Fx)
4546            ## Generate non-tree (non-conforming)            ## Generate non-tree (non-conforming):
4547            ## basefont (IE7 (where basefont is non-void)), center (IE),            ## basefont (IE7 (where basefont is non-void)), center (IE),
4548            ## form (IE), hn (IE)            ## form (IE), hn (IE)
4549          ## address, div, p (<li><foo><li> == <li><foo/></li><li/>)          ## address, div, p (<li><foo><li> == <li><foo/></li><li/>)::
4550            ## Interpreted as <li><foo><li/></foo></li> (non-conforming)            ## Interpreted as <li><foo><li/></foo></li> (non-conforming):
4551            ## div (Fx, S)            ## div (Fx, S)
4552    
4553          my $non_optional;          my $non_optional;
# Line 4831  sub _tree_construction_main ($) { Line 4894  sub _tree_construction_main ($) {
4894            next B;            next B;
4895          }          }
4896        } elsif ($token->{tag_name} eq 'textarea') {        } elsif ($token->{tag_name} eq 'textarea') {
4897          ## Step 1          ## 1. Insert
4898          !!!insert-element-t ($token->{tag_name}, $token->{attributes}, $token);          !!!insert-element-t ($token->{tag_name}, $token->{attributes}, $token);
4899                    
4900          ## Step 2          ## Step 2 # XXX
4901          ## TODO: $self->{form_element} if defined          ## TODO: $self->{form_element} if defined
4902    
4903          ## Step 3          ## 2. Drop U+000A LINE FEED
4904          $self->{ignore_newline} = 1;          $self->{ignore_newline} = 1;
4905    
4906          ## Step 4          ## 3. RCDATA
         ## ISSUE: This step is wrong. (r2302 enbugged)  
   
         ## Step 5  
4907          $self->{content_model} = RCDATA_CONTENT_MODEL;          $self->{content_model} = RCDATA_CONTENT_MODEL;
4908          delete $self->{escape}; # MUST          delete $self->{escape}; # MUST
4909    
4910          ## Step 6-7          ## 4., 6. Insertion mode
4911          $self->{insertion_mode} |= IN_CDATA_RCDATA_IM;          $self->{insertion_mode} |= IN_CDATA_RCDATA_IM;
4912    
4913            ## XXX: 5. frameset-ok flag
4914    
4915          !!!nack ('t392.1');          !!!nack ('t392.1');
4916          !!!next-token;          !!!next-token;
4917          next B;          next B;
# Line 5021  sub _tree_construction_main ($) { Line 5083  sub _tree_construction_main ($) {
5083        }        }
5084      } elsif ($token->{type} == END_TAG_TOKEN) {      } elsif ($token->{type} == END_TAG_TOKEN) {
5085        if ($token->{tag_name} eq 'body') {        if ($token->{tag_name} eq 'body') {
5086          ## has a |body| element in scope  
5087            ## 1. If not "have an element in scope":
5088            ## "has a |body| element in scope"
5089          my $i;          my $i;
5090          INSCOPE: {          INSCOPE: {
5091            for (reverse @{$self->{open_elements}}) {            for (reverse @{$self->{open_elements}}) {
# Line 5044  sub _tree_construction_main ($) { Line 5108  sub _tree_construction_main ($) {
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 ||
5115                      $_->[1] == OPTION_EL ||
5116                      $_->[1] == RUBY_COMPONENT_EL) {
5117              !!!cp ('t403');              !!!cp ('t403');
5118              !!!parse-error (type => 'not closed',              !!!parse-error (type => 'not closed',
5119                              text => $_->[0]->manakai_local_name,                              text => $_->[0]->manakai_local_name,
# Line 5056  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;          !!!next-token;
5130          next B;          next B;
# Line 5442  sub _tree_construction_main ($) { Line 5511  sub _tree_construction_main ($) {
5511    ## TODO: script stuffs    ## TODO: script stuffs
5512  } # _tree_construct_main  } # _tree_construct_main
5513    
5514    ## XXX: How this method is organized is somewhat out of date, although
5515    ## it still does what the current spec documents.
5516  sub set_inner_html ($$$$;$) {  sub set_inner_html ($$$$;$) {
5517    my $class = shift;    my $class = shift;
5518    my $node = shift;    my $node = shift; # /context/
5519    #my $s = \$_[0];    #my $s = \$_[0];
5520    my $onerror = $_[1];    my $onerror = $_[1];
5521    my $get_wrapper = $_[2] || sub ($) { return $_[0] };    my $get_wrapper = $_[2] || sub ($) { return $_[0] };
# Line 5452  sub set_inner_html ($$$$;$) { Line 5523  sub set_inner_html ($$$$;$) {
5523    ## ISSUE: Should {confident} be true?    ## ISSUE: Should {confident} be true?
5524    
5525    my $nt = $node->node_type;    my $nt = $node->node_type;
5526    if ($nt == 9) {    if ($nt == 9) { # Document (invoke the algorithm with no /context/ element)
5527      # MUST      # MUST
5528            
5529      ## Step 1 # MUST      ## Step 1 # MUST
# Line 5467  sub set_inner_html ($$$$;$) { Line 5538  sub set_inner_html ($$$$;$) {
5538    
5539      ## Step 3, 4, 5 # MUST      ## Step 3, 4, 5 # MUST
5540      $class->parse_char_string ($_[0] => $node, $onerror, $get_wrapper);      $class->parse_char_string ($_[0] => $node, $onerror, $get_wrapper);
5541    } elsif ($nt == 1) {    } elsif ($nt == 1) { # Element (invoke the algorithm with /context/ element)
5542      ## TODO: If non-html element      ## TODO: If non-html element
5543    
5544      ## NOTE: Most of this code is copied from |parse_string|      ## NOTE: Most of this code is copied from |parse_string|
5545    
5546  ## TODO: Support for $get_wrapper  ## TODO: Support for $get_wrapper
5547    
5548      ## Step 1 # MUST      ## F1. Create an HTML document.
5549      my $this_doc = $node->owner_document;      my $this_doc = $node->owner_document;
5550      my $doc = $this_doc->implementation->create_document;      my $doc = $this_doc->implementation->create_document;
5551      $doc->manakai_is_html (1);      $doc->manakai_is_html (1);
5552    
5553        ## F2. Propagate quirkness flag
5554        my $node_doc = $node->owner_document;
5555        $doc->manakai_compat_mode ($node_doc->manakai_compat_mode);
5556    
5557        ## F3. Create an HTML parser
5558      my $p = $class->new;      my $p = $class->new;
5559      $p->{document} = $doc;      $p->{document} = $doc;
5560    
# Line 5605  sub set_inner_html ($$$$;$) { Line 5682  sub set_inner_html ($$$$;$) {
5682      $p->_initialize_tokenizer;      $p->_initialize_tokenizer;
5683      $p->_initialize_tree_constructor;      $p->_initialize_tree_constructor;
5684    
5685      ## Step 2      ## F4. If /context/ is not undef...
5686    
5687        ## F4.1. content model flag
5688      my $node_ln = $node->manakai_local_name;      my $node_ln = $node->manakai_local_name;
5689      $p->{content_model} = {      $p->{content_model} = {
5690        title => RCDATA_CONTENT_MODEL,        title => RCDATA_CONTENT_MODEL,
# Line 5625  sub set_inner_html ($$$$;$) { Line 5704  sub set_inner_html ($$$$;$) {
5704      $p->{inner_html_node} = [$node, $el_category->{$node_ln}];      $p->{inner_html_node} = [$node, $el_category->{$node_ln}];
5705        ## TODO: Foreign element OK?        ## TODO: Foreign element OK?
5706    
5707      ## Step 3      ## F4.2. Root |html| element
5708      my $root = $doc->create_element_ns      my $root = $doc->create_element_ns
5709        ('http://www.w3.org/1999/xhtml', [undef, 'html']);        ('http://www.w3.org/1999/xhtml', [undef, 'html']);
5710    
5711      ## Step 4 # MUST      ## F4.3.
5712      $doc->append_child ($root);      $doc->append_child ($root);
5713    
5714      ## Step 5 # MUST      ## F4.4.
5715      push @{$p->{open_elements}}, [$root, $el_category->{html}];      push @{$p->{open_elements}}, [$root, $el_category->{html}];
5716    
5717      undef $p->{head_element};      undef $p->{head_element};
5718      undef $p->{head_element_inserted};      undef $p->{head_element_inserted};
5719    
5720      ## Step 6 # MUST      ## F4.5.
5721      $p->_reset_insertion_mode;      $p->_reset_insertion_mode;
5722    
5723      ## Step 7 # MUST      ## F4.6.
5724      my $anode = $node;      my $anode = $node;
5725      AN: while (defined $anode) {      AN: while (defined $anode) {
5726        if ($anode->node_type == 1) {        if ($anode->node_type == 1) {
# Line 5656  sub set_inner_html ($$$$;$) { Line 5735  sub set_inner_html ($$$$;$) {
5735        }        }
5736        $anode = $anode->parent_node;        $anode = $anode->parent_node;
5737      } # AN      } # AN
5738        
5739      ## Step 9 # MUST      ## F.6. Start the parser.
5740      {      {
5741        my $self = $p;        my $self = $p;
5742        !!!next-token;        !!!next-token;
5743      }      }
5744      $p->_tree_construction_main;      $p->_tree_construction_main;
5745    
5746      ## Step 10 # MUST      ## F.7.
5747      my @cn = @{$node->child_nodes};      my @cn = @{$node->child_nodes};
5748      for (@cn) {      for (@cn) {
5749        $node->remove_child ($_);        $node->remove_child ($_);

Legend:
Removed from v.1.214  
changed lines
  Added in v.1.229

[email protected]
ViewVC Help
Powered by ViewVC 1.1.24