/[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.53 by wakaba, Sat Jul 21 12:37:57 2007 UTC revision 1.54 by wakaba, Sat Aug 11 06:37:12 2007 UTC
# Line 159  sub CDATA_CONTENT_MODEL () { CM_LIMITED_ Line 159  sub CDATA_CONTENT_MODEL () { CM_LIMITED_
159  sub RCDATA_CONTENT_MODEL () { CM_ENTITY | CM_LIMITED_MARKUP }  sub RCDATA_CONTENT_MODEL () { CM_ENTITY | CM_LIMITED_MARKUP }
160  sub PCDATA_CONTENT_MODEL () { CM_ENTITY | CM_FULL_MARKUP }  sub PCDATA_CONTENT_MODEL () { CM_ENTITY | CM_FULL_MARKUP }
161    
162    sub AFTER_HTML_IMS () { 0b100 }
163    sub HEAD_IMS ()       { 0b1000 }
164    sub BODY_IMS ()       { 0b10000 }
165    sub BODY_TABLE_IMS () { 0b100000 | BODY_IMS }
166    sub TABLE_IMS ()      { 0b1000000 }
167    sub ROW_IMS ()        { 0b10000000 | TABLE_IMS }
168    sub BODY_AFTER_IMS () { 0b100000000 }
169    sub FRAME_IMS ()      { 0b1000000000 }
170    
171    sub AFTER_HTML_BODY_IM () { AFTER_HTML_IMS | BODY_AFTER_IMS }
172    sub AFTER_HTML_FRAMESET_IM () { AFTER_HTML_IMS | FRAME_IMS }
173    sub IN_HEAD_IM () { HEAD_IMS | 0b00 }
174    sub IN_HEAD_NOSCRIPT_IM () { HEAD_IMS | 0b01 }
175    sub AFTER_HEAD_IM () { HEAD_IMS | 0b10 }
176    sub BEFORE_HEAD_IM () { HEAD_IMS | 0b11 }
177    sub IN_BODY_IM () { BODY_IMS }
178    sub IN_CELL_IM () { BODY_TABLE_IMS | 0b01 }
179    sub IN_CAPTION_IM () { BODY_TABLE_IMS | 0b10 }
180    sub IN_ROW_IM () { ROW_IMS | 0b01 }
181    sub IN_TABLE_BODY_IM () { ROW_IMS | 0b10 }
182    sub IN_TABLE_IM () { TABLE_IMS }
183    sub AFTER_BODY_IM () { BODY_AFTER_IMS }
184    sub IN_FRAMESET_IM () { FRAME_IMS | 0b01 }
185    sub AFTER_FRAMESET_IM () { FRAME_IMS | 0b10 }
186    sub IN_SELECT_IM () { 0b01 }
187    sub IN_COLUMN_GROUP_IM () { 0b10 }
188    
189  ## Implementations MUST act as if state machine in the spec  ## Implementations MUST act as if state machine in the spec
190    
191  sub _initialize_tokenizer ($) {  sub _initialize_tokenizer ($) {
# Line 1806  sub _construct_tree ($) { Line 1833  sub _construct_tree ($) {
1833        
1834    !!!next-token;    !!!next-token;
1835    
1836    $self->{insertion_mode} = 'before head';    $self->{insertion_mode} = BEFORE_HEAD_IM;
1837    undef $self->{form_element};    undef $self->{form_element};
1838    undef $self->{head_element};    undef $self->{head_element};
1839    $self->{open_elements} = [];    $self->{open_elements} = [];
# Line 2062  sub _reset_insertion_mode ($) { Line 2089  sub _reset_insertion_mode ($) {
2089            
2090        ## Step 4..13        ## Step 4..13
2091        my $new_mode = {        my $new_mode = {
2092                        select => 'in select',                        select => IN_SELECT_IM,
2093                        td => 'in cell',                        td => IN_CELL_IM,
2094                        th => 'in cell',                        th => IN_CELL_IM,
2095                        tr => 'in row',                        tr => IN_ROW_IM,
2096                        tbody => 'in table body',                        tbody => IN_TABLE_BODY_IM,
2097                        thead => 'in table body',                        thead => IN_TABLE_BODY_IM,
2098                        tfoot => 'in table body',                        tfoot => IN_TABLE_BODY_IM,
2099                        caption => 'in caption',                        caption => IN_CAPTION_IM,
2100                        colgroup => 'in column group',                        colgroup => IN_COLUMN_GROUP_IM,
2101                        table => 'in table',                        table => IN_TABLE_IM,
2102                        head => 'in body', # not in head!                        head => IN_BODY_IM, # not in head!
2103                        body => 'in body',                        body => IN_BODY_IM,
2104                        frameset => 'in frameset',                        frameset => IN_FRAMESET_IM,
2105                       }->{$node->[1]};                       }->{$node->[1]};
2106        $self->{insertion_mode} = $new_mode and return if defined $new_mode;        $self->{insertion_mode} = $new_mode and return if defined $new_mode;
2107                
2108        ## Step 14        ## Step 14
2109        if ($node->[1] eq 'html') {        if ($node->[1] eq 'html') {
2110          unless (defined $self->{head_element}) {          unless (defined $self->{head_element}) {
2111            $self->{insertion_mode} = 'before head';            $self->{insertion_mode} = BEFORE_HEAD_IM;
2112          } else {          } else {
2113            $self->{insertion_mode} = 'after head';            $self->{insertion_mode} = AFTER_HEAD_IM;
2114          }          }
2115          return;          return;
2116        }        }
2117                
2118        ## Step 15        ## Step 15
2119        $self->{insertion_mode} = 'in body' and return if $last;        $self->{insertion_mode} = IN_BODY_IM and return if $last;
2120                
2121        ## Step 16        ## Step 16
2122        $i--;        $i--;
# Line 2504  sub _tree_construction_main ($) { Line 2531  sub _tree_construction_main ($) {
2531        !!!next-token;        !!!next-token;
2532        redo B;        redo B;
2533      } elsif ($token->{type} eq 'end-of-file') {      } elsif ($token->{type} eq 'end-of-file') {
2534        if ($self->{insertion_mode} eq 'after html body' or        if ($self->{insertion_mode} == AFTER_HTML_BODY_IM or
2535            $self->{insertion_mode} eq 'after html frameset') {            $self->{insertion_mode} == AFTER_HTML_FRAMESET_IM) {
2536          #          #
2537        } else {        } else {
2538          ## Generate implied end tags          ## Generate implied end tags
# Line 2534  sub _tree_construction_main ($) { Line 2561  sub _tree_construction_main ($) {
2561        last B;        last B;
2562      } elsif ($token->{type} eq 'start tag' and      } elsif ($token->{type} eq 'start tag' and
2563               $token->{tag_name} eq 'html') {               $token->{tag_name} eq 'html') {
2564        if ($self->{insertion_mode} eq 'after html body') {        if ($self->{insertion_mode} == AFTER_HTML_BODY_IM) {
2565          ## Turn into the main phase          ## Turn into the main phase
2566          !!!parse-error (type => 'after html:html');          !!!parse-error (type => 'after html:html');
2567          $self->{insertion_mode} = 'after body';          $self->{insertion_mode} = AFTER_BODY_IM;
2568        } elsif ($self->{insertion_mode} eq 'after html frameset') {        } elsif ($self->{insertion_mode} == AFTER_HTML_FRAMESET_IM) {
2569          ## Turn into the main phase          ## Turn into the main phase
2570          !!!parse-error (type => 'after html:html');          !!!parse-error (type => 'after html:html');
2571          $self->{insertion_mode} = 'after frameset';          $self->{insertion_mode} = AFTER_FRAMESET_IM;
2572        }        }
2573    
2574  ## ISSUE: "aa<html>" is not a parse error.  ## ISSUE: "aa<html>" is not a parse error.
# Line 2561  sub _tree_construction_main ($) { Line 2588  sub _tree_construction_main ($) {
2588        redo B;        redo B;
2589      } elsif ($token->{type} eq 'comment') {      } elsif ($token->{type} eq 'comment') {
2590        my $comment = $self->{document}->create_comment ($token->{data});        my $comment = $self->{document}->create_comment ($token->{data});
2591        if ($self->{insertion_mode} eq 'after html body' or        if ($self->{insertion_mode} == AFTER_HTML_BODY_IM or
2592            $self->{insertion_mode} eq 'after html frameset') {            $self->{insertion_mode} == AFTER_HTML_FRAMESET_IM) {
2593          $self->{document}->append_child ($comment);          $self->{document}->append_child ($comment);
2594        } elsif ($self->{insertion_mode} eq 'after body') {        } elsif ($self->{insertion_mode} == AFTER_BODY_IM) {
2595          $self->{open_elements}->[0]->[0]->append_child ($comment);          $self->{open_elements}->[0]->[0]->append_child ($comment);
2596        } else {        } else {
2597          $self->{open_elements}->[-1]->[0]->append_child ($comment);          $self->{open_elements}->[-1]->[0]->append_child ($comment);
2598        }        }
2599        !!!next-token;        !!!next-token;
2600        redo B;        redo B;
2601      } elsif ($self->{insertion_mode} eq 'in head' or      } elsif ($self->{insertion_mode} == IN_HEAD_IM or
2602               $self->{insertion_mode} eq 'in head noscript' or               $self->{insertion_mode} == IN_HEAD_NOSCRIPT_IM or
2603               $self->{insertion_mode} eq 'after head' or               $self->{insertion_mode} == AFTER_HEAD_IM or
2604               $self->{insertion_mode} eq 'before head') {               $self->{insertion_mode} == BEFORE_HEAD_IM) {
2605        if ($token->{type} eq 'character') {        if ($token->{type} eq 'character') {
2606          if ($token->{data} =~ s/^([\x09\x0A\x0B\x0C\x20]+)//) {          if ($token->{data} =~ s/^([\x09\x0A\x0B\x0C\x20]+)//) {
2607            $self->{open_elements}->[-1]->[0]->manakai_append_text ($1);            $self->{open_elements}->[-1]->[0]->manakai_append_text ($1);
# Line 2584  sub _tree_construction_main ($) { Line 2611  sub _tree_construction_main ($) {
2611            }            }
2612          }          }
2613    
2614          if ($self->{insertion_mode} eq 'before head') {          if ($self->{insertion_mode} == BEFORE_HEAD_IM) {
2615            ## As if <head>            ## As if <head>
2616            !!!create-element ($self->{head_element}, 'head');            !!!create-element ($self->{head_element}, 'head');
2617            $self->{open_elements}->[-1]->[0]->append_child ($self->{head_element});            $self->{open_elements}->[-1]->[0]->append_child ($self->{head_element});
# Line 2594  sub _tree_construction_main ($) { Line 2621  sub _tree_construction_main ($) {
2621            pop @{$self->{open_elements}};            pop @{$self->{open_elements}};
2622    
2623            ## Reprocess in the "after head" insertion mode...            ## Reprocess in the "after head" insertion mode...
2624          } elsif ($self->{insertion_mode} eq 'in head noscript') {          } elsif ($self->{insertion_mode} == IN_HEAD_NOSCRIPT_IM) {
2625            ## As if </noscript>            ## As if </noscript>
2626            pop @{$self->{open_elements}};            pop @{$self->{open_elements}};
2627            !!!parse-error (type => 'in noscript:#character');            !!!parse-error (type => 'in noscript:#character');
# Line 2604  sub _tree_construction_main ($) { Line 2631  sub _tree_construction_main ($) {
2631            pop @{$self->{open_elements}};            pop @{$self->{open_elements}};
2632    
2633            ## Reprocess in the "after head" insertion mode...            ## Reprocess in the "after head" insertion mode...
2634          } elsif ($self->{insertion_mode} eq 'in head') {          } elsif ($self->{insertion_mode} == IN_HEAD_IM) {
2635            pop @{$self->{open_elements}};            pop @{$self->{open_elements}};
2636    
2637            ## Reprocess in the "after head" insertion mode...            ## Reprocess in the "after head" insertion mode...
# Line 2613  sub _tree_construction_main ($) { Line 2640  sub _tree_construction_main ($) {
2640              ## "after head" insertion mode              ## "after head" insertion mode
2641              ## As if <body>              ## As if <body>
2642              !!!insert-element ('body');              !!!insert-element ('body');
2643              $self->{insertion_mode} = 'in body';              $self->{insertion_mode} = IN_BODY_IM;
2644              ## reprocess              ## reprocess
2645              redo B;              redo B;
2646            } elsif ($token->{type} eq 'start tag') {            } elsif ($token->{type} eq 'start tag') {
2647              if ($token->{tag_name} eq 'head') {              if ($token->{tag_name} eq 'head') {
2648                if ($self->{insertion_mode} eq 'before head') {                if ($self->{insertion_mode} == BEFORE_HEAD_IM) {
2649                  !!!create-element ($self->{head_element}, $token->{tag_name}, $token->{attributes});                  !!!create-element ($self->{head_element}, $token->{tag_name}, $token->{attributes});
2650                  $self->{open_elements}->[-1]->[0]->append_child ($self->{head_element});                  $self->{open_elements}->[-1]->[0]->append_child ($self->{head_element});
2651                  push @{$self->{open_elements}}, [$self->{head_element}, $token->{tag_name}];                  push @{$self->{open_elements}}, [$self->{head_element}, $token->{tag_name}];
2652                  $self->{insertion_mode} = 'in head';                  $self->{insertion_mode} = IN_HEAD_IM;
2653                  !!!next-token;                  !!!next-token;
2654                  redo B;                  redo B;
2655                } elsif ($self->{insertion_mode} ne 'after head') {                } elsif ($self->{insertion_mode} == AFTER_HEAD_IM) {
2656                    #
2657                  } else {
2658                  !!!parse-error (type => 'in head:head'); # or in head noscript                  !!!parse-error (type => 'in head:head'); # or in head noscript
2659                  ## Ignore the token                  ## Ignore the token
2660                  !!!next-token;                  !!!next-token;
2661                  redo B;                  redo B;
               } else {  
                 #  
2662                }                }
2663              } elsif ($self->{insertion_mode} eq 'before head') {              } elsif ($self->{insertion_mode} == BEFORE_HEAD_IM) {
2664                ## As if <head>                ## As if <head>
2665                !!!create-element ($self->{head_element}, 'head');                !!!create-element ($self->{head_element}, 'head');
2666                $self->{open_elements}->[-1]->[0]->append_child ($self->{head_element});                $self->{open_elements}->[-1]->[0]->append_child ($self->{head_element});
2667                push @{$self->{open_elements}}, [$self->{head_element}, 'head'];                push @{$self->{open_elements}}, [$self->{head_element}, 'head'];
2668    
2669                $self->{insertion_mode} = 'in head';                $self->{insertion_mode} = IN_HEAD_IM;
2670                ## Reprocess in the "in head" insertion mode...                ## Reprocess in the "in head" insertion mode...
2671              }              }
2672    
2673              if ($token->{tag_name} eq 'base') {              if ($token->{tag_name} eq 'base') {
2674                if ($self->{insertion_mode} eq 'in head noscript') {                if ($self->{insertion_mode} == IN_HEAD_NOSCRIPT_IM) {
2675                  ## As if </noscript>                  ## As if </noscript>
2676                  pop @{$self->{open_elements}};                  pop @{$self->{open_elements}};
2677                  !!!parse-error (type => 'in noscript:base');                  !!!parse-error (type => 'in noscript:base');
2678                                
2679                  $self->{insertion_mode} = 'in head';                  $self->{insertion_mode} = IN_HEAD_IM;
2680                  ## Reprocess in the "in head" insertion mode...                  ## Reprocess in the "in head" insertion mode...
2681                }                }
2682    
2683                ## NOTE: There is a "as if in head" code clone.                ## NOTE: There is a "as if in head" code clone.
2684                if ($self->{insertion_mode} eq 'after head') {                if ($self->{insertion_mode} == AFTER_HEAD_IM) {
2685                  !!!parse-error (type => 'after head:'.$token->{tag_name});                  !!!parse-error (type => 'after head:'.$token->{tag_name});
2686                  push @{$self->{open_elements}}, [$self->{head_element}, 'head'];                  push @{$self->{open_elements}}, [$self->{head_element}, 'head'];
2687                }                }
2688                !!!insert-element ($token->{tag_name}, $token->{attributes});                !!!insert-element ($token->{tag_name}, $token->{attributes});
2689                pop @{$self->{open_elements}}; ## ISSUE: This step is missing in the spec.                pop @{$self->{open_elements}}; ## ISSUE: This step is missing in the spec.
2690                pop @{$self->{open_elements}}                pop @{$self->{open_elements}}
2691                    if $self->{insertion_mode} eq 'after head';                    if $self->{insertion_mode} == AFTER_HEAD_IM;
2692                !!!next-token;                !!!next-token;
2693                redo B;                redo B;
2694              } elsif ($token->{tag_name} eq 'link') {              } elsif ($token->{tag_name} eq 'link') {
2695                ## NOTE: There is a "as if in head" code clone.                ## NOTE: There is a "as if in head" code clone.
2696                if ($self->{insertion_mode} eq 'after head') {                if ($self->{insertion_mode} == AFTER_HEAD_IM) {
2697                  !!!parse-error (type => 'after head:'.$token->{tag_name});                  !!!parse-error (type => 'after head:'.$token->{tag_name});
2698                  push @{$self->{open_elements}}, [$self->{head_element}, 'head'];                  push @{$self->{open_elements}}, [$self->{head_element}, 'head'];
2699                }                }
2700                !!!insert-element ($token->{tag_name}, $token->{attributes});                !!!insert-element ($token->{tag_name}, $token->{attributes});
2701                pop @{$self->{open_elements}}; ## ISSUE: This step is missing in the spec.                pop @{$self->{open_elements}}; ## ISSUE: This step is missing in the spec.
2702                pop @{$self->{open_elements}}                pop @{$self->{open_elements}}
2703                    if $self->{insertion_mode} eq 'after head';                    if $self->{insertion_mode} == AFTER_HEAD_IM;
2704                !!!next-token;                !!!next-token;
2705                redo B;                redo B;
2706              } elsif ($token->{tag_name} eq 'meta') {              } elsif ($token->{tag_name} eq 'meta') {
2707                ## NOTE: There is a "as if in head" code clone.                ## NOTE: There is a "as if in head" code clone.
2708                if ($self->{insertion_mode} eq 'after head') {                if ($self->{insertion_mode} == AFTER_HEAD_IM) {
2709                  !!!parse-error (type => 'after head:'.$token->{tag_name});                  !!!parse-error (type => 'after head:'.$token->{tag_name});
2710                  push @{$self->{open_elements}}, [$self->{head_element}, 'head'];                  push @{$self->{open_elements}}, [$self->{head_element}, 'head'];
2711                }                }
# Line 2704  sub _tree_construction_main ($) { Line 2731  sub _tree_construction_main ($) {
2731    
2732                ## TODO: Extracting |charset| from |meta|.                ## TODO: Extracting |charset| from |meta|.
2733                pop @{$self->{open_elements}}                pop @{$self->{open_elements}}
2734                    if $self->{insertion_mode} eq 'after head';                    if $self->{insertion_mode} == AFTER_HEAD_IM;
2735                !!!next-token;                !!!next-token;
2736                redo B;                redo B;
2737              } elsif ($token->{tag_name} eq 'title') {              } elsif ($token->{tag_name} eq 'title') {
2738                if ($self->{insertion_mode} eq 'in head noscript') {                if ($self->{insertion_mode} == IN_HEAD_NOSCRIPT_IM) {
2739                  ## As if </noscript>                  ## As if </noscript>
2740                  pop @{$self->{open_elements}};                  pop @{$self->{open_elements}};
2741                  !!!parse-error (type => 'in noscript:title');                  !!!parse-error (type => 'in noscript:title');
2742                                
2743                  $self->{insertion_mode} = 'in head';                  $self->{insertion_mode} = IN_HEAD_IM;
2744                  ## Reprocess in the "in head" insertion mode...                  ## Reprocess in the "in head" insertion mode...
2745                } elsif ($self->{insertion_mode} eq 'after head') {                } elsif ($self->{insertion_mode} == AFTER_HEAD_IM) {
2746                  !!!parse-error (type => 'after head:'.$token->{tag_name});                  !!!parse-error (type => 'after head:'.$token->{tag_name});
2747                  push @{$self->{open_elements}}, [$self->{head_element}, 'head'];                  push @{$self->{open_elements}}, [$self->{head_element}, 'head'];
2748                }                }
# Line 2726  sub _tree_construction_main ($) { Line 2753  sub _tree_construction_main ($) {
2753                $parse_rcdata->(RCDATA_CONTENT_MODEL,                $parse_rcdata->(RCDATA_CONTENT_MODEL,
2754                                sub { $parent->append_child ($_[0]) });                                sub { $parent->append_child ($_[0]) });
2755                pop @{$self->{open_elements}}                pop @{$self->{open_elements}}
2756                    if $self->{insertion_mode} eq 'after head';                    if $self->{insertion_mode} == AFTER_HEAD_IM;
2757                redo B;                redo B;
2758              } elsif ($token->{tag_name} eq 'style') {              } elsif ($token->{tag_name} eq 'style') {
2759                ## NOTE: Or (scripting is enabled and tag_name eq 'noscript' and                ## NOTE: Or (scripting is enabled and tag_name eq 'noscript' and
2760                ## insertion mode 'in head')                ## insertion mode IN_HEAD_IM)
2761                ## NOTE: There is a "as if in head" code clone.                ## NOTE: There is a "as if in head" code clone.
2762                if ($self->{insertion_mode} eq 'after head') {                if ($self->{insertion_mode} == AFTER_HEAD_IM) {
2763                  !!!parse-error (type => 'after head:'.$token->{tag_name});                  !!!parse-error (type => 'after head:'.$token->{tag_name});
2764                  push @{$self->{open_elements}}, [$self->{head_element}, 'head'];                  push @{$self->{open_elements}}, [$self->{head_element}, 'head'];
2765                }                }
2766                $parse_rcdata->(CDATA_CONTENT_MODEL, $insert_to_current);                $parse_rcdata->(CDATA_CONTENT_MODEL, $insert_to_current);
2767                pop @{$self->{open_elements}}                pop @{$self->{open_elements}}
2768                    if $self->{insertion_mode} eq 'after head';                    if $self->{insertion_mode} == AFTER_HEAD_IM;
2769                redo B;                redo B;
2770              } elsif ($token->{tag_name} eq 'noscript') {              } elsif ($token->{tag_name} eq 'noscript') {
2771                if ($self->{insertion_mode} eq 'in head') {                if ($self->{insertion_mode} == IN_HEAD_IM) {
2772                  ## NOTE: and scripting is disalbed                  ## NOTE: and scripting is disalbed
2773                  !!!insert-element ($token->{tag_name}, $token->{attributes});                  !!!insert-element ($token->{tag_name}, $token->{attributes});
2774                  $self->{insertion_mode} = 'in head noscript';                  $self->{insertion_mode} = IN_HEAD_NOSCRIPT_IM;
2775                  !!!next-token;                  !!!next-token;
2776                  redo B;                  redo B;
2777                } elsif ($self->{insertion_mode} eq 'in head noscript') {                } elsif ($self->{insertion_mode} == IN_HEAD_NOSCRIPT_IM) {
2778                  !!!parse-error (type => 'in noscript:noscript');                  !!!parse-error (type => 'in noscript:noscript');
2779                  ## Ignore the token                  ## Ignore the token
2780                  !!!next-token;                  !!!next-token;
# Line 2756  sub _tree_construction_main ($) { Line 2783  sub _tree_construction_main ($) {
2783                  #                  #
2784                }                }
2785              } elsif ($token->{tag_name} eq 'script') {              } elsif ($token->{tag_name} eq 'script') {
2786                if ($self->{insertion_mode} eq 'in head noscript') {                if ($self->{insertion_mode} == IN_HEAD_NOSCRIPT_IM) {
2787                  ## As if </noscript>                  ## As if </noscript>
2788                  pop @{$self->{open_elements}};                  pop @{$self->{open_elements}};
2789                  !!!parse-error (type => 'in noscript:script');                  !!!parse-error (type => 'in noscript:script');
2790                                
2791                  $self->{insertion_mode} = 'in head';                  $self->{insertion_mode} = IN_HEAD_IM;
2792                  ## Reprocess in the "in head" insertion mode...                  ## Reprocess in the "in head" insertion mode...
2793                } elsif ($self->{insertion_mode} eq 'after head') {                } elsif ($self->{insertion_mode} == AFTER_HEAD_IM) {
2794                  !!!parse-error (type => 'after head:'.$token->{tag_name});                  !!!parse-error (type => 'after head:'.$token->{tag_name});
2795                  push @{$self->{open_elements}}, [$self->{head_element}, 'head'];                  push @{$self->{open_elements}}, [$self->{head_element}, 'head'];
2796                }                }
# Line 2771  sub _tree_construction_main ($) { Line 2798  sub _tree_construction_main ($) {
2798                ## NOTE: There is a "as if in head" code clone.                ## NOTE: There is a "as if in head" code clone.
2799                $script_start_tag->($insert_to_current);                $script_start_tag->($insert_to_current);
2800                pop @{$self->{open_elements}}                pop @{$self->{open_elements}}
2801                    if $self->{insertion_mode} eq 'after head';                    if $self->{insertion_mode} == AFTER_HEAD_IM;
2802                redo B;                redo B;
2803              } elsif ($token->{tag_name} eq 'body' or              } elsif ($token->{tag_name} eq 'body' or
2804                       $token->{tag_name} eq 'frameset') {                       $token->{tag_name} eq 'frameset') {
2805                if ($self->{insertion_mode} eq 'in head noscript') {                if ($self->{insertion_mode} == IN_HEAD_NOSCRIPT_IM) {
2806                  ## As if </noscript>                  ## As if </noscript>
2807                  pop @{$self->{open_elements}};                  pop @{$self->{open_elements}};
2808                  !!!parse-error (type => 'in noscript:'.$token->{tag_name});                  !!!parse-error (type => 'in noscript:'.$token->{tag_name});
# Line 2785  sub _tree_construction_main ($) { Line 2812  sub _tree_construction_main ($) {
2812                  pop @{$self->{open_elements}};                  pop @{$self->{open_elements}};
2813                                    
2814                  ## Reprocess in the "after head" insertion mode...                  ## Reprocess in the "after head" insertion mode...
2815                } elsif ($self->{insertion_mode} eq 'in head') {                } elsif ($self->{insertion_mode} == IN_HEAD_IM) {
2816                  pop @{$self->{open_elements}};                  pop @{$self->{open_elements}};
2817                                    
2818                  ## Reprocess in the "after head" insertion mode...                  ## Reprocess in the "after head" insertion mode...
# Line 2793  sub _tree_construction_main ($) { Line 2820  sub _tree_construction_main ($) {
2820    
2821                ## "after head" insertion mode                ## "after head" insertion mode
2822                !!!insert-element ($token->{tag_name}, $token->{attributes});                !!!insert-element ($token->{tag_name}, $token->{attributes});
2823                $self->{insertion_mode} = 'in '.$token->{tag_name};                if ($token->{tag_name} eq 'body') {
2824                    $self->{insertion_mode} = IN_BODY_IM;
2825                  } elsif ($token->{tag_name} eq 'frameset') {
2826                    $self->{insertion_mode} = IN_FRAMESET_IM;
2827                  } else {
2828                    die "$0: tag name: $self->{tag_name}";
2829                  }
2830                !!!next-token;                !!!next-token;
2831                redo B;                redo B;
2832              } else {              } else {
2833                #                #
2834              }              }
2835    
2836              if ($self->{insertion_mode} eq 'in head noscript') {              if ($self->{insertion_mode} == IN_HEAD_NOSCRIPT_IM) {
2837                ## As if </noscript>                ## As if </noscript>
2838                pop @{$self->{open_elements}};                pop @{$self->{open_elements}};
2839                !!!parse-error (type => 'in noscript:/'.$token->{tag_name});                !!!parse-error (type => 'in noscript:/'.$token->{tag_name});
# Line 2810  sub _tree_construction_main ($) { Line 2843  sub _tree_construction_main ($) {
2843                pop @{$self->{open_elements}};                pop @{$self->{open_elements}};
2844    
2845                ## Reprocess in the "after head" insertion mode...                ## Reprocess in the "after head" insertion mode...
2846              } elsif ($self->{insertion_mode} eq 'in head') {              } elsif ($self->{insertion_mode} == IN_HEAD_IM) {
2847                ## As if </head>                ## As if </head>
2848                pop @{$self->{open_elements}};                pop @{$self->{open_elements}};
2849    
# Line 2820  sub _tree_construction_main ($) { Line 2853  sub _tree_construction_main ($) {
2853              ## "after head" insertion mode              ## "after head" insertion mode
2854              ## As if <body>              ## As if <body>
2855              !!!insert-element ('body');              !!!insert-element ('body');
2856              $self->{insertion_mode} = 'in body';              $self->{insertion_mode} = IN_BODY_IM;
2857              ## reprocess              ## reprocess
2858              redo B;              redo B;
2859            } elsif ($token->{type} eq 'end tag') {            } elsif ($token->{type} eq 'end tag') {
2860              if ($token->{tag_name} eq 'head') {              if ($token->{tag_name} eq 'head') {
2861                if ($self->{insertion_mode} eq 'before head') {                if ($self->{insertion_mode} == BEFORE_HEAD_IM) {
2862                  ## As if <head>                  ## As if <head>
2863                  !!!create-element ($self->{head_element}, 'head');                  !!!create-element ($self->{head_element}, 'head');
2864                  $self->{open_elements}->[-1]->[0]->append_child ($self->{head_element});                  $self->{open_elements}->[-1]->[0]->append_child ($self->{head_element});
# Line 2833  sub _tree_construction_main ($) { Line 2866  sub _tree_construction_main ($) {
2866    
2867                  ## Reprocess in the "in head" insertion mode...                  ## Reprocess in the "in head" insertion mode...
2868                  pop @{$self->{open_elements}};                  pop @{$self->{open_elements}};
2869                  $self->{insertion_mode} = 'after head';                  $self->{insertion_mode} = AFTER_HEAD_IM;
2870                  !!!next-token;                  !!!next-token;
2871                  redo B;                  redo B;
2872                } elsif ($self->{insertion_mode} eq 'in head noscript') {                } elsif ($self->{insertion_mode} == IN_HEAD_NOSCRIPT_IM) {
2873                  ## As if </noscript>                  ## As if </noscript>
2874                  pop @{$self->{open_elements}};                  pop @{$self->{open_elements}};
2875                  !!!parse-error (type => 'in noscript:script');                  !!!parse-error (type => 'in noscript:script');
2876                                    
2877                  ## Reprocess in the "in head" insertion mode...                  ## Reprocess in the "in head" insertion mode...
2878                  pop @{$self->{open_elements}};                  pop @{$self->{open_elements}};
2879                  $self->{insertion_mode} = 'after head';                  $self->{insertion_mode} = AFTER_HEAD_IM;
2880                  !!!next-token;                  !!!next-token;
2881                  redo B;                  redo B;
2882                } elsif ($self->{insertion_mode} eq 'in head') {                } elsif ($self->{insertion_mode} == IN_HEAD_IM) {
2883                  pop @{$self->{open_elements}};                  pop @{$self->{open_elements}};
2884                  $self->{insertion_mode} = 'after head';                  $self->{insertion_mode} = AFTER_HEAD_IM;
2885                  !!!next-token;                  !!!next-token;
2886                  redo B;                  redo B;
2887                } else {                } else {
2888                  #                  #
2889                }                }
2890              } elsif ($token->{tag_name} eq 'noscript') {              } elsif ($token->{tag_name} eq 'noscript') {
2891                if ($self->{insertion_mode} eq 'in head noscript') {                if ($self->{insertion_mode} == IN_HEAD_NOSCRIPT_IM) {
2892                  pop @{$self->{open_elements}};                  pop @{$self->{open_elements}};
2893                  $self->{insertion_mode} = 'in head';                  $self->{insertion_mode} = IN_HEAD_IM;
2894                  !!!next-token;                  !!!next-token;
2895                  redo B;                  redo B;
2896                } elsif ($self->{insertion_mode} eq 'before head') {                } elsif ($self->{insertion_mode} == BEFORE_HEAD_IM) {
2897                  !!!parse-error (type => 'unmatched end tag:noscript');                  !!!parse-error (type => 'unmatched end tag:noscript');
2898                  ## Ignore the token ## ISSUE: An issue in the spec.                  ## Ignore the token ## ISSUE: An issue in the spec.
2899                  !!!next-token;                  !!!next-token;
# Line 2871  sub _tree_construction_main ($) { Line 2904  sub _tree_construction_main ($) {
2904              } elsif ({              } elsif ({
2905                        body => 1, html => 1,                        body => 1, html => 1,
2906                       }->{$token->{tag_name}}) {                       }->{$token->{tag_name}}) {
2907                if ($self->{insertion_mode} eq 'before head') {                if ($self->{insertion_mode} == BEFORE_HEAD_IM) {
2908                  ## As if <head>                  ## As if <head>
2909                  !!!create-element ($self->{head_element}, 'head');                  !!!create-element ($self->{head_element}, 'head');
2910                  $self->{open_elements}->[-1]->[0]->append_child ($self->{head_element});                  $self->{open_elements}->[-1]->[0]->append_child ($self->{head_element});
2911                  push @{$self->{open_elements}}, [$self->{head_element}, 'head'];                  push @{$self->{open_elements}}, [$self->{head_element}, 'head'];
2912    
2913                  $self->{insertion_mode} = 'in head';                  $self->{insertion_mode} = IN_HEAD_IM;
2914                  ## Reprocess in the "in head" insertion mode...                  ## Reprocess in the "in head" insertion mode...
2915                } elsif ($self->{insertion_mode} eq 'in head noscript') {                } elsif ($self->{insertion_mode} == IN_HEAD_NOSCRIPT_IM) {
2916                  !!!parse-error (type => 'unmatched end tag:'.$token->{tag_name});                  !!!parse-error (type => 'unmatched end tag:'.$token->{tag_name});
2917                  ## Ignore the token                  ## Ignore the token
2918                  !!!next-token;                  !!!next-token;
# Line 2890  sub _tree_construction_main ($) { Line 2923  sub _tree_construction_main ($) {
2923              } elsif ({              } elsif ({
2924                        p => 1, br => 1,                        p => 1, br => 1,
2925                       }->{$token->{tag_name}}) {                       }->{$token->{tag_name}}) {
2926                if ($self->{insertion_mode} eq 'before head') {                if ($self->{insertion_mode} == BEFORE_HEAD_IM) {
2927                  ## As if <head>                  ## As if <head>
2928                  !!!create-element ($self->{head_element}, 'head');                  !!!create-element ($self->{head_element}, 'head');
2929                  $self->{open_elements}->[-1]->[0]->append_child ($self->{head_element});                  $self->{open_elements}->[-1]->[0]->append_child ($self->{head_element});
2930                  push @{$self->{open_elements}}, [$self->{head_element}, 'head'];                  push @{$self->{open_elements}}, [$self->{head_element}, 'head'];
2931    
2932                  $self->{insertion_mode} = 'in head';                  $self->{insertion_mode} = IN_HEAD_IM;
2933                  ## Reprocess in the "in head" insertion mode...                  ## Reprocess in the "in head" insertion mode...
2934                }                }
2935    
2936                #                #
2937              } else {              } else {
2938                if ($self->{insertion_mode} ne 'after head') {                if ($self->{insertion_mode} == AFTER_HEAD_IM) {
2939                    #
2940                  } else {
2941                  !!!parse-error (type => 'unmatched end tag:'.$token->{tag_name});                  !!!parse-error (type => 'unmatched end tag:'.$token->{tag_name});
2942                  ## Ignore the token                  ## Ignore the token
2943                  !!!next-token;                  !!!next-token;
2944                  redo B;                  redo B;
               } else {  
                 #  
2945                }                }
2946              }              }
2947    
2948              if ($self->{insertion_mode} eq 'in head noscript') {              if ($self->{insertion_mode} == IN_HEAD_NOSCRIPT_IM) {
2949                ## As if </noscript>                ## As if </noscript>
2950                pop @{$self->{open_elements}};                pop @{$self->{open_elements}};
2951                !!!parse-error (type => 'in noscript:/'.$token->{tag_name});                !!!parse-error (type => 'in noscript:/'.$token->{tag_name});
# Line 2922  sub _tree_construction_main ($) { Line 2955  sub _tree_construction_main ($) {
2955                pop @{$self->{open_elements}};                pop @{$self->{open_elements}};
2956    
2957                ## Reprocess in the "after head" insertion mode...                ## Reprocess in the "after head" insertion mode...
2958              } elsif ($self->{insertion_mode} eq 'in head') {              } elsif ($self->{insertion_mode} == IN_HEAD_IM) {
2959                ## As if </head>                ## As if </head>
2960                pop @{$self->{open_elements}};                pop @{$self->{open_elements}};
2961    
2962                ## Reprocess in the "after head" insertion mode...                ## Reprocess in the "after head" insertion mode...
2963              } elsif ($self->{insertion_mode} eq 'before head') {              } elsif ($self->{insertion_mode} == BEFORE_HEAD_IM) {
2964                !!!parse-error (type => 'unmatched end tag:'.$token->{tag_name});                !!!parse-error (type => 'unmatched end tag:'.$token->{tag_name});
2965                ## Ignore the token ## ISSUE: An issue in the spec.                ## Ignore the token ## ISSUE: An issue in the spec.
2966                !!!next-token;                !!!next-token;
# Line 2937  sub _tree_construction_main ($) { Line 2970  sub _tree_construction_main ($) {
2970              ## "after head" insertion mode              ## "after head" insertion mode
2971              ## As if <body>              ## As if <body>
2972              !!!insert-element ('body');              !!!insert-element ('body');
2973              $self->{insertion_mode} = 'in body';              $self->{insertion_mode} = IN_BODY_IM;
2974              ## reprocess              ## reprocess
2975              redo B;              redo B;
2976            } else {            } else {
# Line 2945  sub _tree_construction_main ($) { Line 2978  sub _tree_construction_main ($) {
2978            }            }
2979    
2980            ## ISSUE: An issue in the spec.            ## ISSUE: An issue in the spec.
2981      } elsif ($self->{insertion_mode} eq 'in body' or      } elsif ($self->{insertion_mode} == IN_BODY_IM or
2982               $self->{insertion_mode} eq 'in cell' or               $self->{insertion_mode} == IN_CELL_IM or
2983               $self->{insertion_mode} eq 'in caption') {               $self->{insertion_mode} == IN_CAPTION_IM) {
2984            if ($token->{type} eq 'character') {            if ($token->{type} eq 'character') {
2985              ## NOTE: There is a code clone of "character in body".              ## NOTE: There is a code clone of "character in body".
2986              $reconstruct_active_formatting_elements->($insert_to_current);              $reconstruct_active_formatting_elements->($insert_to_current);
# Line 2961  sub _tree_construction_main ($) { Line 2994  sub _tree_construction_main ($) {
2994                   caption => 1, col => 1, colgroup => 1, tbody => 1,                   caption => 1, col => 1, colgroup => 1, tbody => 1,
2995                   td => 1, tfoot => 1, th => 1, thead => 1, tr => 1,                   td => 1, tfoot => 1, th => 1, thead => 1, tr => 1,
2996                  }->{$token->{tag_name}}) {                  }->{$token->{tag_name}}) {
2997                if ($self->{insertion_mode} eq 'in cell') {                if ($self->{insertion_mode} == IN_CELL_IM) {
2998                  ## have an element in table scope                  ## have an element in table scope
2999                  my $tn;                  my $tn;
3000                  INSCOPE: for (reverse 0..$#{$self->{open_elements}}) {                  INSCOPE: for (reverse 0..$#{$self->{open_elements}}) {
# Line 2986  sub _tree_construction_main ($) { Line 3019  sub _tree_construction_main ($) {
3019                  !!!back-token; # <?>                  !!!back-token; # <?>
3020                  $token = {type => 'end tag', tag_name => $tn};                  $token = {type => 'end tag', tag_name => $tn};
3021                  redo B;                  redo B;
3022                } elsif ($self->{insertion_mode} eq 'in caption') {                } elsif ($self->{insertion_mode} == IN_CAPTION_IM) {
3023                  !!!parse-error (type => 'not closed:caption');                  !!!parse-error (type => 'not closed:caption');
3024                                    
3025                  ## As if </caption>                  ## As if </caption>
# Line 3032  sub _tree_construction_main ($) { Line 3065  sub _tree_construction_main ($) {
3065                                    
3066                  $clear_up_to_marker->();                  $clear_up_to_marker->();
3067                                    
3068                  $self->{insertion_mode} = 'in table';                  $self->{insertion_mode} = IN_TABLE_IM;
3069                                    
3070                  ## reprocess                  ## reprocess
3071                  redo B;                  redo B;
# Line 3044  sub _tree_construction_main ($) { Line 3077  sub _tree_construction_main ($) {
3077              }              }
3078            } elsif ($token->{type} eq 'end tag') {            } elsif ($token->{type} eq 'end tag') {
3079              if ($token->{tag_name} eq 'td' or $token->{tag_name} eq 'th') {              if ($token->{tag_name} eq 'td' or $token->{tag_name} eq 'th') {
3080                if ($self->{insertion_mode} eq 'in cell') {                if ($self->{insertion_mode} == IN_CELL_IM) {
3081                  ## have an element in table scope                  ## have an element in table scope
3082                  my $i;                  my $i;
3083                  INSCOPE: for (reverse 0..$#{$self->{open_elements}}) {                  INSCOPE: for (reverse 0..$#{$self->{open_elements}}) {
# Line 3087  sub _tree_construction_main ($) { Line 3120  sub _tree_construction_main ($) {
3120                                    
3121                  $clear_up_to_marker->();                  $clear_up_to_marker->();
3122                                    
3123                  $self->{insertion_mode} = 'in row';                  $self->{insertion_mode} = IN_ROW_IM;
3124                                    
3125                  !!!next-token;                  !!!next-token;
3126                  redo B;                  redo B;
3127                } elsif ($self->{insertion_mode} eq 'in caption') {                } elsif ($self->{insertion_mode} == IN_CAPTION_IM) {
3128                  !!!parse-error (type => 'unmatched end tag:'.$token->{tag_name});                  !!!parse-error (type => 'unmatched end tag:'.$token->{tag_name});
3129                  ## Ignore the token                  ## Ignore the token
3130                  !!!next-token;                  !!!next-token;
# Line 3100  sub _tree_construction_main ($) { Line 3133  sub _tree_construction_main ($) {
3133                  #                  #
3134                }                }
3135              } elsif ($token->{tag_name} eq 'caption') {              } elsif ($token->{tag_name} eq 'caption') {
3136                if ($self->{insertion_mode} eq 'in caption') {                if ($self->{insertion_mode} == IN_CAPTION_IM) {
3137                  ## have a table element in table scope                  ## have a table element in table scope
3138                  my $i;                  my $i;
3139                  INSCOPE: for (reverse 0..$#{$self->{open_elements}}) {                  INSCOPE: for (reverse 0..$#{$self->{open_elements}}) {
# Line 3141  sub _tree_construction_main ($) { Line 3174  sub _tree_construction_main ($) {
3174                                    
3175                  $clear_up_to_marker->();                  $clear_up_to_marker->();
3176                                    
3177                  $self->{insertion_mode} = 'in table';                  $self->{insertion_mode} = IN_TABLE_IM;
3178                                    
3179                  !!!next-token;                  !!!next-token;
3180                  redo B;                  redo B;
3181                } elsif ($self->{insertion_mode} eq 'in cell') {                } elsif ($self->{insertion_mode} == IN_CELL_IM) {
3182                  !!!parse-error (type => 'unmatched end tag:'.$token->{tag_name});                  !!!parse-error (type => 'unmatched end tag:'.$token->{tag_name});
3183                  ## Ignore the token                  ## Ignore the token
3184                  !!!next-token;                  !!!next-token;
# Line 3157  sub _tree_construction_main ($) { Line 3190  sub _tree_construction_main ($) {
3190                        table => 1, tbody => 1, tfoot => 1,                        table => 1, tbody => 1, tfoot => 1,
3191                        thead => 1, tr => 1,                        thead => 1, tr => 1,
3192                       }->{$token->{tag_name}} and                       }->{$token->{tag_name}} and
3193                       $self->{insertion_mode} eq 'in cell') {                       $self->{insertion_mode} == IN_CELL_IM) {
3194                ## have an element in table scope                ## have an element in table scope
3195                my $i;                my $i;
3196                my $tn;                my $tn;
# Line 3188  sub _tree_construction_main ($) { Line 3221  sub _tree_construction_main ($) {
3221                $token = {type => 'end tag', tag_name => $tn};                $token = {type => 'end tag', tag_name => $tn};
3222                redo B;                redo B;
3223              } elsif ($token->{tag_name} eq 'table' and              } elsif ($token->{tag_name} eq 'table' and
3224                       $self->{insertion_mode} eq 'in caption') {                       $self->{insertion_mode} == IN_CAPTION_IM) {
3225                !!!parse-error (type => 'not closed:caption');                !!!parse-error (type => 'not closed:caption');
3226    
3227                ## As if </caption>                ## As if </caption>
# Line 3234  sub _tree_construction_main ($) { Line 3267  sub _tree_construction_main ($) {
3267    
3268                $clear_up_to_marker->();                $clear_up_to_marker->();
3269    
3270                $self->{insertion_mode} = 'in table';                $self->{insertion_mode} = IN_TABLE_IM;
3271    
3272                ## reprocess                ## reprocess
3273                redo B;                redo B;
3274              } elsif ({              } elsif ({
3275                        body => 1, col => 1, colgroup => 1, html => 1,                        body => 1, col => 1, colgroup => 1, html => 1,
3276                       }->{$token->{tag_name}}) {                       }->{$token->{tag_name}}) {
3277                if ($self->{insertion_mode} eq 'in cell' or                if ($self->{insertion_mode} == IN_CELL_IM or
3278                    $self->{insertion_mode} eq 'in caption') {                    $self->{insertion_mode} == IN_CAPTION_IM) {
3279                  !!!parse-error (type => 'unmatched end tag:'.$token->{tag_name});                  !!!parse-error (type => 'unmatched end tag:'.$token->{tag_name});
3280                  ## Ignore the token                  ## Ignore the token
3281                  !!!next-token;                  !!!next-token;
# Line 3254  sub _tree_construction_main ($) { Line 3287  sub _tree_construction_main ($) {
3287                        tbody => 1, tfoot => 1,                        tbody => 1, tfoot => 1,
3288                        thead => 1, tr => 1,                        thead => 1, tr => 1,
3289                       }->{$token->{tag_name}} and                       }->{$token->{tag_name}} and
3290                       $self->{insertion_mode} eq 'in caption') {                       $self->{insertion_mode} == IN_CAPTION_IM) {
3291                !!!parse-error (type => 'unmatched end tag:'.$token->{tag_name});                !!!parse-error (type => 'unmatched end tag:'.$token->{tag_name});
3292                ## Ignore the token                ## Ignore the token
3293                !!!next-token;                !!!next-token;
# Line 3268  sub _tree_construction_main ($) { Line 3301  sub _tree_construction_main ($) {
3301    
3302        $insert = $insert_to_current;        $insert = $insert_to_current;
3303        #        #
3304      } elsif ($self->{insertion_mode} eq 'in row' or      } elsif ($self->{insertion_mode} == IN_ROW_IM or
3305               $self->{insertion_mode} eq 'in table body' or               $self->{insertion_mode} == IN_TABLE_BODY_IM or
3306               $self->{insertion_mode} eq 'in table') {               $self->{insertion_mode} == IN_TABLE_IM) {
3307            if ($token->{type} eq 'character') {            if ($token->{type} eq 'character') {
3308              ## NOTE: There are "character in table" code clones.              ## NOTE: There are "character in table" code clones.
3309              if ($token->{data} =~ s/^([\x09\x0A\x0B\x0C\x20]+)//) {              if ($token->{data} =~ s/^([\x09\x0A\x0B\x0C\x20]+)//) {
# Line 3331  sub _tree_construction_main ($) { Line 3364  sub _tree_construction_main ($) {
3364              redo B;              redo B;
3365            } elsif ($token->{type} eq 'start tag') {            } elsif ($token->{type} eq 'start tag') {
3366              if ({              if ({
3367                   tr => ($self->{insertion_mode} ne 'in row'),                   tr => ($self->{insertion_mode} != IN_ROW_IM),
3368                   th => 1, td => 1,                   th => 1, td => 1,
3369                  }->{$token->{tag_name}}) {                  }->{$token->{tag_name}}) {
3370                if ($self->{insertion_mode} eq 'in table') {                if ($self->{insertion_mode} == IN_TABLE_IM) {
3371                  ## Clear back to table context                  ## Clear back to table context
3372                  while ($self->{open_elements}->[-1]->[1] ne 'table' and                  while ($self->{open_elements}->[-1]->[1] ne 'table' and
3373                         $self->{open_elements}->[-1]->[1] ne 'html') {                         $self->{open_elements}->[-1]->[1] ne 'html') {
# Line 3343  sub _tree_construction_main ($) { Line 3376  sub _tree_construction_main ($) {
3376                  }                  }
3377                                    
3378                  !!!insert-element ('tbody');                  !!!insert-element ('tbody');
3379                  $self->{insertion_mode} = 'in table body';                  $self->{insertion_mode} = IN_TABLE_BODY_IM;
3380                  ## reprocess in the "in table body" insertion mode...                  ## reprocess in the "in table body" insertion mode...
3381                }                }
3382    
3383                if ($self->{insertion_mode} eq 'in table body') {                if ($self->{insertion_mode} == IN_TABLE_BODY_IM) {
3384                  unless ($token->{tag_name} eq 'tr') {                  unless ($token->{tag_name} eq 'tr') {
3385                    !!!parse-error (type => 'missing start tag:tr');                    !!!parse-error (type => 'missing start tag:tr');
3386                  }                  }
# Line 3360  sub _tree_construction_main ($) { Line 3393  sub _tree_construction_main ($) {
3393                    pop @{$self->{open_elements}};                    pop @{$self->{open_elements}};
3394                  }                  }
3395                                    
3396                  $self->{insertion_mode} = 'in row';                  $self->{insertion_mode} = IN_ROW_IM;
3397                  if ($token->{tag_name} eq 'tr') {                  if ($token->{tag_name} eq 'tr') {
3398                    !!!insert-element ($token->{tag_name}, $token->{attributes});                    !!!insert-element ($token->{tag_name}, $token->{attributes});
3399                    !!!next-token;                    !!!next-token;
# Line 3380  sub _tree_construction_main ($) { Line 3413  sub _tree_construction_main ($) {
3413                }                }
3414                                
3415                !!!insert-element ($token->{tag_name}, $token->{attributes});                !!!insert-element ($token->{tag_name}, $token->{attributes});
3416                $self->{insertion_mode} = 'in cell';                $self->{insertion_mode} = IN_CELL_IM;
3417    
3418                push @$active_formatting_elements, ['#marker', ''];                push @$active_formatting_elements, ['#marker', ''];
3419                                
# Line 3389  sub _tree_construction_main ($) { Line 3422  sub _tree_construction_main ($) {
3422              } elsif ({              } elsif ({
3423                        caption => 1, col => 1, colgroup => 1,                        caption => 1, col => 1, colgroup => 1,
3424                        tbody => 1, tfoot => 1, thead => 1,                        tbody => 1, tfoot => 1, thead => 1,
3425                        tr => 1, # $self->{insertion_mode} eq 'in row'                        tr => 1, # $self->{insertion_mode} == IN_ROW_IM
3426                       }->{$token->{tag_name}}) {                       }->{$token->{tag_name}}) {
3427                if ($self->{insertion_mode} eq 'in row') {                if ($self->{insertion_mode} == IN_ROW_IM) {
3428                  ## As if </tr>                  ## As if </tr>
3429                  ## have an element in table scope                  ## have an element in table scope
3430                  my $i;                  my $i;
# Line 3422  sub _tree_construction_main ($) { Line 3455  sub _tree_construction_main ($) {
3455                  }                  }
3456                                    
3457                  pop @{$self->{open_elements}}; # tr                  pop @{$self->{open_elements}}; # tr
3458                  $self->{insertion_mode} = 'in table body';                  $self->{insertion_mode} = IN_TABLE_BODY_IM;
3459                  if ($token->{tag_name} eq 'tr') {                  if ($token->{tag_name} eq 'tr') {
3460                    ## reprocess                    ## reprocess
3461                    redo B;                    redo B;
# Line 3431  sub _tree_construction_main ($) { Line 3464  sub _tree_construction_main ($) {
3464                  }                  }
3465                }                }
3466    
3467                if ($self->{insertion_mode} eq 'in table body') {                if ($self->{insertion_mode} == IN_TABLE_BODY_IM) {
3468                  ## have an element in table scope                  ## have an element in table scope
3469                  my $i;                  my $i;
3470                  INSCOPE: for (reverse 0..$#{$self->{open_elements}}) {                  INSCOPE: for (reverse 0..$#{$self->{open_elements}}) {
# Line 3470  sub _tree_construction_main ($) { Line 3503  sub _tree_construction_main ($) {
3503                  ## nop by definition                  ## nop by definition
3504                                    
3505                  pop @{$self->{open_elements}};                  pop @{$self->{open_elements}};
3506                  $self->{insertion_mode} = 'in table';                  $self->{insertion_mode} = IN_TABLE_IM;
3507                  ## reprocess in "in table" insertion mode...                  ## reprocess in "in table" insertion mode...
3508                }                }
3509    
# Line 3483  sub _tree_construction_main ($) { Line 3516  sub _tree_construction_main ($) {
3516                  }                  }
3517                                    
3518                  !!!insert-element ('colgroup');                  !!!insert-element ('colgroup');
3519                  $self->{insertion_mode} = 'in column group';                  $self->{insertion_mode} = IN_COLUMN_GROUP_IM;
3520                  ## reprocess                  ## reprocess
3521                  redo B;                  redo B;
3522                } elsif ({                } elsif ({
# Line 3503  sub _tree_construction_main ($) { Line 3536  sub _tree_construction_main ($) {
3536                                    
3537                  !!!insert-element ($token->{tag_name}, $token->{attributes});                  !!!insert-element ($token->{tag_name}, $token->{attributes});
3538                  $self->{insertion_mode} = {                  $self->{insertion_mode} = {
3539                                             caption => 'in caption',                                             caption => IN_CAPTION_IM,
3540                                             colgroup => 'in column group',                                             colgroup => IN_COLUMN_GROUP_IM,
3541                                             tbody => 'in table body',                                             tbody => IN_TABLE_BODY_IM,
3542                                             tfoot => 'in table body',                                             tfoot => IN_TABLE_BODY_IM,
3543                                             thead => 'in table body',                                             thead => IN_TABLE_BODY_IM,
3544                                            }->{$token->{tag_name}};                                            }->{$token->{tag_name}};
3545                  !!!next-token;                  !!!next-token;
3546                  redo B;                  redo B;
# Line 3568  sub _tree_construction_main ($) { Line 3601  sub _tree_construction_main ($) {
3601              }              }
3602            } elsif ($token->{type} eq 'end tag') {            } elsif ($token->{type} eq 'end tag') {
3603              if ($token->{tag_name} eq 'tr' and              if ($token->{tag_name} eq 'tr' and
3604                  $self->{insertion_mode} eq 'in row') {                  $self->{insertion_mode} == IN_ROW_IM) {
3605                ## have an element in table scope                ## have an element in table scope
3606                my $i;                my $i;
3607                INSCOPE: for (reverse 0..$#{$self->{open_elements}}) {                INSCOPE: for (reverse 0..$#{$self->{open_elements}}) {
# Line 3598  sub _tree_construction_main ($) { Line 3631  sub _tree_construction_main ($) {
3631                }                }
3632    
3633                pop @{$self->{open_elements}}; # tr                pop @{$self->{open_elements}}; # tr
3634                $self->{insertion_mode} = 'in table body';                $self->{insertion_mode} = IN_TABLE_BODY_IM;
3635                !!!next-token;                !!!next-token;
3636                redo B;                redo B;
3637              } elsif ($token->{tag_name} eq 'table') {              } elsif ($token->{tag_name} eq 'table') {
3638                if ($self->{insertion_mode} eq 'in row') {                if ($self->{insertion_mode} == IN_ROW_IM) {
3639                  ## As if </tr>                  ## As if </tr>
3640                  ## have an element in table scope                  ## have an element in table scope
3641                  my $i;                  my $i;
# Line 3633  sub _tree_construction_main ($) { Line 3666  sub _tree_construction_main ($) {
3666                  }                  }
3667                                    
3668                  pop @{$self->{open_elements}}; # tr                  pop @{$self->{open_elements}}; # tr
3669                  $self->{insertion_mode} = 'in table body';                  $self->{insertion_mode} = IN_TABLE_BODY_IM;
3670                  ## reprocess in the "in table body" insertion mode...                  ## reprocess in the "in table body" insertion mode...
3671                }                }
3672    
3673                if ($self->{insertion_mode} eq 'in table body') {                if ($self->{insertion_mode} == IN_TABLE_BODY_IM) {
3674                  ## have an element in table scope                  ## have an element in table scope
3675                  my $i;                  my $i;
3676                  INSCOPE: for (reverse 0..$#{$self->{open_elements}}) {                  INSCOPE: for (reverse 0..$#{$self->{open_elements}}) {
# Line 3676  sub _tree_construction_main ($) { Line 3709  sub _tree_construction_main ($) {
3709                  ## nop by definition                  ## nop by definition
3710                                    
3711                  pop @{$self->{open_elements}};                  pop @{$self->{open_elements}};
3712                  $self->{insertion_mode} = 'in table';                  $self->{insertion_mode} = IN_TABLE_IM;
3713                  ## reprocess in the "in table" insertion mode...                  ## reprocess in the "in table" insertion mode...
3714                }                }
3715    
# Line 3725  sub _tree_construction_main ($) { Line 3758  sub _tree_construction_main ($) {
3758              } elsif ({              } elsif ({
3759                        tbody => 1, tfoot => 1, thead => 1,                        tbody => 1, tfoot => 1, thead => 1,
3760                       }->{$token->{tag_name}} and                       }->{$token->{tag_name}} and
3761                       ($self->{insertion_mode} eq 'in row' or                       ($self->{insertion_mode} == IN_ROW_IM or
3762                        $self->{insertion_mode} eq 'in table body')) {                        $self->{insertion_mode} == IN_TABLE_BODY_IM)) {
3763                if ($self->{insertion_mode} eq 'in row') {                if ($self->{insertion_mode} == IN_ROW_IM) {
3764                  ## have an element in table scope                  ## have an element in table scope
3765                  my $i;                  my $i;
3766                  INSCOPE: for (reverse 0..$#{$self->{open_elements}}) {                  INSCOPE: for (reverse 0..$#{$self->{open_elements}}) {
# Line 3778  sub _tree_construction_main ($) { Line 3811  sub _tree_construction_main ($) {
3811                  }                  }
3812                                    
3813                  pop @{$self->{open_elements}}; # tr                  pop @{$self->{open_elements}}; # tr
3814                  $self->{insertion_mode} = 'in table body';                  $self->{insertion_mode} = IN_TABLE_BODY_IM;
3815                  ## reprocess in the "in table body" insertion mode...                  ## reprocess in the "in table body" insertion mode...
3816                }                }
3817    
# Line 3811  sub _tree_construction_main ($) { Line 3844  sub _tree_construction_main ($) {
3844                }                }
3845    
3846                pop @{$self->{open_elements}};                pop @{$self->{open_elements}};
3847                $self->{insertion_mode} = 'in table';                $self->{insertion_mode} = IN_TABLE_IM;
3848                !!!next-token;                !!!next-token;
3849                redo B;                redo B;
3850              } elsif ({              } elsif ({
3851                        body => 1, caption => 1, col => 1, colgroup => 1,                        body => 1, caption => 1, col => 1, colgroup => 1,
3852                        html => 1, td => 1, th => 1,                        html => 1, td => 1, th => 1,
3853                        tr => 1, # $self->{insertion_mode} eq 'in row'                        tr => 1, # $self->{insertion_mode} == IN_ROW_IM
3854                        tbody => 1, tfoot => 1, thead => 1, # $self->{insertion_mode} eq 'in table'                        tbody => 1, tfoot => 1, thead => 1, # $self->{insertion_mode} == IN_TABLE_IM
3855                       }->{$token->{tag_name}}) {                       }->{$token->{tag_name}}) {
3856                !!!parse-error (type => 'unmatched end tag:'.$token->{tag_name});                !!!parse-error (type => 'unmatched end tag:'.$token->{tag_name});
3857                ## Ignore the token                ## Ignore the token
# Line 3835  sub _tree_construction_main ($) { Line 3868  sub _tree_construction_main ($) {
3868    
3869        $insert = $insert_to_foster;        $insert = $insert_to_foster;
3870        #        #
3871      } elsif ($self->{insertion_mode} eq 'in column group') {      } elsif ($self->{insertion_mode} == IN_COLUMN_GROUP_IM) {
3872            if ($token->{type} eq 'character') {            if ($token->{type} eq 'character') {
3873              if ($token->{data} =~ s/^([\x09\x0A\x0B\x0C\x20]+)//) {              if ($token->{data} =~ s/^([\x09\x0A\x0B\x0C\x20]+)//) {
3874                $self->{open_elements}->[-1]->[0]->manakai_append_text ($1);                $self->{open_elements}->[-1]->[0]->manakai_append_text ($1);
# Line 3864  sub _tree_construction_main ($) { Line 3897  sub _tree_construction_main ($) {
3897                  redo B;                  redo B;
3898                } else {                } else {
3899                  pop @{$self->{open_elements}}; # colgroup                  pop @{$self->{open_elements}}; # colgroup
3900                  $self->{insertion_mode} = 'in table';                  $self->{insertion_mode} = IN_TABLE_IM;
3901                  !!!next-token;                  !!!next-token;
3902                  redo B;                              redo B;            
3903                }                }
# Line 3888  sub _tree_construction_main ($) { Line 3921  sub _tree_construction_main ($) {
3921              redo B;              redo B;
3922            } else {            } else {
3923              pop @{$self->{open_elements}}; # colgroup              pop @{$self->{open_elements}}; # colgroup
3924              $self->{insertion_mode} = 'in table';              $self->{insertion_mode} = IN_TABLE_IM;
3925              ## reprocess              ## reprocess
3926              redo B;              redo B;
3927            }            }
3928      } elsif ($self->{insertion_mode} eq 'in select') {      } elsif ($self->{insertion_mode} == IN_SELECT_IM) {
3929            if ($token->{type} eq 'character') {            if ($token->{type} eq 'character') {
3930              $self->{open_elements}->[-1]->[0]->manakai_append_text ($token->{data});              $self->{open_elements}->[-1]->[0]->manakai_append_text ($token->{data});
3931              !!!next-token;              !!!next-token;
# Line 4066  sub _tree_construction_main ($) { Line 4099  sub _tree_construction_main ($) {
4099            ## Ignore the token            ## Ignore the token
4100            !!!next-token;            !!!next-token;
4101            redo B;            redo B;
4102      } elsif ($self->{insertion_mode} eq 'after body' or      } elsif ($self->{insertion_mode} == AFTER_BODY_IM or
4103               $self->{insertion_mode} eq 'after html body') {               $self->{insertion_mode} == AFTER_HTML_BODY_IM) {
4104        if ($token->{type} eq 'character') {        if ($token->{type} eq 'character') {
4105          if ($token->{data} =~ s/^([\x09\x0A\x0B\x0C\x20]+)//) {          if ($token->{data} =~ s/^([\x09\x0A\x0B\x0C\x20]+)//) {
4106            my $data = $1;            my $data = $1;
# Line 4082  sub _tree_construction_main ($) { Line 4115  sub _tree_construction_main ($) {
4115            }            }
4116          }          }
4117                    
4118          if ($self->{insertion_mode} eq 'after html body') {          if ($self->{insertion_mode} == AFTER_HTML_BODY_IM) {
4119            !!!parse-error (type => 'after html:#character');            !!!parse-error (type => 'after html:#character');
4120    
4121            ## Reprocess in the "main" phase, "after body" insertion mode...            ## Reprocess in the "main" phase, "after body" insertion mode...
# Line 4091  sub _tree_construction_main ($) { Line 4124  sub _tree_construction_main ($) {
4124          ## "after body" insertion mode          ## "after body" insertion mode
4125          !!!parse-error (type => 'after body:#character');          !!!parse-error (type => 'after body:#character');
4126    
4127          $self->{insertion_mode} = 'in body';          $self->{insertion_mode} = IN_BODY_IM;
4128          ## reprocess          ## reprocess
4129          redo B;          redo B;
4130        } elsif ($token->{type} eq 'start tag') {        } elsif ($token->{type} eq 'start tag') {
4131          if ($self->{insertion_mode} eq 'after html body') {          if ($self->{insertion_mode} == AFTER_HTML_BODY_IM) {
4132            !!!parse-error (type => 'after html:'.$token->{tag_name});            !!!parse-error (type => 'after html:'.$token->{tag_name});
4133                        
4134            ## Reprocess in the "main" phase, "after body" insertion mode...            ## Reprocess in the "main" phase, "after body" insertion mode...
# Line 4104  sub _tree_construction_main ($) { Line 4137  sub _tree_construction_main ($) {
4137          ## "after body" insertion mode          ## "after body" insertion mode
4138          !!!parse-error (type => 'after body:'.$token->{tag_name});          !!!parse-error (type => 'after body:'.$token->{tag_name});
4139    
4140          $self->{insertion_mode} = 'in body';          $self->{insertion_mode} = IN_BODY_IM;
4141          ## reprocess          ## reprocess
4142          redo B;          redo B;
4143        } elsif ($token->{type} eq 'end tag') {        } elsif ($token->{type} eq 'end tag') {
4144          if ($self->{insertion_mode} eq 'after html body') {          if ($self->{insertion_mode} == AFTER_HTML_BODY_IM) {
4145            !!!parse-error (type => 'after html:/'.$token->{tag_name});            !!!parse-error (type => 'after html:/'.$token->{tag_name});
4146                        
4147            $self->{insertion_mode} = 'after body';            $self->{insertion_mode} = AFTER_BODY_IM;
4148            ## Reprocess in the "main" phase, "after body" insertion mode...            ## Reprocess in the "main" phase, "after body" insertion mode...
4149          }          }
4150    
# Line 4123  sub _tree_construction_main ($) { Line 4156  sub _tree_construction_main ($) {
4156              !!!next-token;              !!!next-token;
4157              redo B;              redo B;
4158            } else {            } else {
4159              $self->{insertion_mode} = 'after html body';              $self->{insertion_mode} = AFTER_HTML_BODY_IM;
4160              !!!next-token;              !!!next-token;
4161              redo B;              redo B;
4162            }            }
4163          } else {          } else {
4164            !!!parse-error (type => 'after body:/'.$token->{tag_name});            !!!parse-error (type => 'after body:/'.$token->{tag_name});
4165    
4166            $self->{insertion_mode} = 'in body';            $self->{insertion_mode} = IN_BODY_IM;
4167            ## reprocess            ## reprocess
4168            redo B;            redo B;
4169          }          }
4170        } else {        } else {
4171          die "$0: $token->{type}: Unknown token type";          die "$0: $token->{type}: Unknown token type";
4172        }        }
4173      } elsif ($self->{insertion_mode} eq 'in frameset' or      } elsif ($self->{insertion_mode} == IN_FRAMESET_IM or
4174               $self->{insertion_mode} eq 'after frameset' or               $self->{insertion_mode} == AFTER_FRAMESET_IM or
4175               $self->{insertion_mode} eq 'after html frameset') {               $self->{insertion_mode} == AFTER_HTML_FRAMESET_IM) {
4176        if ($token->{type} eq 'character') {        if ($token->{type} eq 'character') {
4177          if ($token->{data} =~ s/^([\x09\x0A\x0B\x0C\x20]+)//) {          if ($token->{data} =~ s/^([\x09\x0A\x0B\x0C\x20]+)//) {
4178            $self->{open_elements}->[-1]->[0]->manakai_append_text ($1);            $self->{open_elements}->[-1]->[0]->manakai_append_text ($1);
# Line 4151  sub _tree_construction_main ($) { Line 4184  sub _tree_construction_main ($) {
4184          }          }
4185                    
4186          if ($token->{data} =~ s/^[^\x09\x0A\x0B\x0C\x20]+//) {          if ($token->{data} =~ s/^[^\x09\x0A\x0B\x0C\x20]+//) {
4187            if ($self->{insertion_mode} eq 'in frameset') {            if ($self->{insertion_mode} == IN_FRAMESET_IM) {
4188              !!!parse-error (type => 'in frameset:#character');              !!!parse-error (type => 'in frameset:#character');
4189            } elsif ($self->{insertion_mode} eq 'after frameset') {            } elsif ($self->{insertion_mode} == AFTER_FRAMESET_IM) {
4190              !!!parse-error (type => 'after frameset:#character');              !!!parse-error (type => 'after frameset:#character');
4191            } else { # "after html frameset"            } else { # "after html frameset"
4192              !!!parse-error (type => 'after html:#character');              !!!parse-error (type => 'after html:#character');
4193    
4194              $self->{insertion_mode} = 'after frameset';              $self->{insertion_mode} = AFTER_FRAMESET_IM;
4195              ## Reprocess in the "main" phase, "after frameset"...              ## Reprocess in the "main" phase, "after frameset"...
4196              !!!parse-error (type => 'after frameset:#character');              !!!parse-error (type => 'after frameset:#character');
4197            }            }
# Line 4174  sub _tree_construction_main ($) { Line 4207  sub _tree_construction_main ($) {
4207                    
4208          die qq[$0: Character "$token->{data}"];          die qq[$0: Character "$token->{data}"];
4209        } elsif ($token->{type} eq 'start tag') {        } elsif ($token->{type} eq 'start tag') {
4210          if ($self->{insertion_mode} eq 'after html frameset') {          if ($self->{insertion_mode} == AFTER_HTML_FRAMESET_IM) {
4211            !!!parse-error (type => 'after html:'.$token->{tag_name});            !!!parse-error (type => 'after html:'.$token->{tag_name});
4212    
4213            $self->{insertion_mode} = 'after frameset';            $self->{insertion_mode} = AFTER_FRAMESET_IM;
4214            ## Process in the "main" phase, "after frameset" insertion mode...            ## Process in the "main" phase, "after frameset" insertion mode...
4215          }          }
4216    
4217          if ($token->{tag_name} eq 'frameset' and          if ($token->{tag_name} eq 'frameset' and
4218              $self->{insertion_mode} eq 'in frameset') {              $self->{insertion_mode} == IN_FRAMESET_IM) {
4219            !!!insert-element ($token->{tag_name}, $token->{attributes});            !!!insert-element ($token->{tag_name}, $token->{attributes});
4220            !!!next-token;            !!!next-token;
4221            redo B;            redo B;
4222          } elsif ($token->{tag_name} eq 'frame' and          } elsif ($token->{tag_name} eq 'frame' and
4223                   $self->{insertion_mode} eq 'in frameset') {                   $self->{insertion_mode} == IN_FRAMESET_IM) {
4224            !!!insert-element ($token->{tag_name}, $token->{attributes});            !!!insert-element ($token->{tag_name}, $token->{attributes});
4225            pop @{$self->{open_elements}};            pop @{$self->{open_elements}};
4226            !!!next-token;            !!!next-token;
# Line 4197  sub _tree_construction_main ($) { Line 4230  sub _tree_construction_main ($) {
4230            $parse_rcdata->(CDATA_CONTENT_MODEL, $insert_to_current);            $parse_rcdata->(CDATA_CONTENT_MODEL, $insert_to_current);
4231            redo B;            redo B;
4232          } else {          } else {
4233            if ($self->{insertion_mode} eq 'in frameset') {            if ($self->{insertion_mode} == IN_FRAMESET_IM) {
4234              !!!parse-error (type => 'in frameset:'.$token->{tag_name});              !!!parse-error (type => 'in frameset:'.$token->{tag_name});
4235            } else {            } else {
4236              !!!parse-error (type => 'after frameset:'.$token->{tag_name});              !!!parse-error (type => 'after frameset:'.$token->{tag_name});
# Line 4207  sub _tree_construction_main ($) { Line 4240  sub _tree_construction_main ($) {
4240            redo B;            redo B;
4241          }          }
4242        } elsif ($token->{type} eq 'end tag') {        } elsif ($token->{type} eq 'end tag') {
4243          if ($self->{insertion_mode} eq 'after html frameset') {          if ($self->{insertion_mode} == AFTER_HTML_FRAMESET_IM) {
4244            !!!parse-error (type => 'after html:/'.$token->{tag_name});            !!!parse-error (type => 'after html:/'.$token->{tag_name});
4245    
4246            $self->{insertion_mode} = 'after frameset';            $self->{insertion_mode} = AFTER_FRAMESET_IM;
4247            ## Process in the "main" phase, "after frameset" insertion mode...            ## Process in the "main" phase, "after frameset" insertion mode...
4248          }          }
4249    
4250          if ($token->{tag_name} eq 'frameset' and          if ($token->{tag_name} eq 'frameset' and
4251              $self->{insertion_mode} eq 'in frameset') {              $self->{insertion_mode} == IN_FRAMESET_IM) {
4252            if ($self->{open_elements}->[-1]->[1] eq 'html' and            if ($self->{open_elements}->[-1]->[1] eq 'html' and
4253                @{$self->{open_elements}} == 1) {                @{$self->{open_elements}} == 1) {
4254              !!!parse-error (type => 'unmatched end tag:'.$token->{tag_name});              !!!parse-error (type => 'unmatched end tag:'.$token->{tag_name});
# Line 4228  sub _tree_construction_main ($) { Line 4261  sub _tree_construction_main ($) {
4261    
4262            if (not defined $self->{inner_html_node} and            if (not defined $self->{inner_html_node} and
4263                $self->{open_elements}->[-1]->[1] ne 'frameset') {                $self->{open_elements}->[-1]->[1] ne 'frameset') {
4264              $self->{insertion_mode} = 'after frameset';              $self->{insertion_mode} = AFTER_FRAMESET_IM;
4265            }            }
4266            redo B;            redo B;
4267          } elsif ($token->{tag_name} eq 'html' and          } elsif ($token->{tag_name} eq 'html' and
4268                   $self->{insertion_mode} eq 'after frameset') {                   $self->{insertion_mode} == AFTER_FRAMESET_IM) {
4269            $self->{insertion_mode} = 'after html frameset';            $self->{insertion_mode} = AFTER_HTML_FRAMESET_IM;
4270            !!!next-token;            !!!next-token;
4271            redo B;            redo B;
4272          } else {          } else {
4273            if ($self->{insertion_mode} eq 'in frameset') {            if ($self->{insertion_mode} == IN_FRAMESET_IM) {
4274              !!!parse-error (type => 'in frameset:/'.$token->{tag_name});              !!!parse-error (type => 'in frameset:/'.$token->{tag_name});
4275            } else {            } else {
4276              !!!parse-error (type => 'after frameset:/'.$token->{tag_name});              !!!parse-error (type => 'after frameset:/'.$token->{tag_name});
# Line 4670  sub _tree_construction_main ($) { Line 4703  sub _tree_construction_main ($) {
4703                        
4704          !!!insert-element-t ($token->{tag_name}, $token->{attributes});          !!!insert-element-t ($token->{tag_name}, $token->{attributes});
4705                        
4706          $self->{insertion_mode} = 'in table';          $self->{insertion_mode} = IN_TABLE_IM;
4707                        
4708          !!!next-token;          !!!next-token;
4709          redo B;          redo B;
# Line 4812  sub _tree_construction_main ($) { Line 4845  sub _tree_construction_main ($) {
4845                    
4846          !!!insert-element-t ($token->{tag_name}, $token->{attributes});          !!!insert-element-t ($token->{tag_name}, $token->{attributes});
4847                    
4848          $self->{insertion_mode} = 'in select';          $self->{insertion_mode} = IN_SELECT_IM;
4849          !!!next-token;          !!!next-token;
4850          redo B;          redo B;
4851        } elsif ({        } elsif ({
# Line 4849  sub _tree_construction_main ($) { Line 4882  sub _tree_construction_main ($) {
4882              }              }
4883            }            }
4884    
4885            $self->{insertion_mode} = 'after body';            $self->{insertion_mode} = AFTER_BODY_IM;
4886            !!!next-token;            !!!next-token;
4887            redo B;            redo B;
4888          } else {          } else {
# Line 4864  sub _tree_construction_main ($) { Line 4897  sub _tree_construction_main ($) {
4897            if ($self->{open_elements}->[-1]->[1] ne 'body') {            if ($self->{open_elements}->[-1]->[1] ne 'body') {
4898              !!!parse-error (type => 'not closed:'.$self->{open_elements}->[1]->[1]);              !!!parse-error (type => 'not closed:'.$self->{open_elements}->[1]->[1]);
4899            }            }
4900            $self->{insertion_mode} = 'after body';            $self->{insertion_mode} = AFTER_BODY_IM;
4901            ## reprocess            ## reprocess
4902            redo B;            redo B;
4903          } else {          } else {

Legend:
Removed from v.1.53  
changed lines
  Added in v.1.54

admin@suikawiki.org
ViewVC Help
Powered by ViewVC 1.1.24