/[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.122 by wakaba, Sun Apr 6 06:34:11 2008 UTC revision 1.123 by wakaba, Sun Apr 6 10:32:00 2008 UTC
# Line 12  use Error qw(:try); Line 12  use Error qw(:try);
12  ## TODO: 1252 parse error (revision 1264)  ## TODO: 1252 parse error (revision 1264)
13  ## TODO: 8859-11 = 874 (revision 1271)  ## TODO: 8859-11 = 874 (revision 1271)
14    
15    sub A_EL () { 0b1 }
16    sub ADDRESS_EL () { 0b10 }
17    sub BODY_EL () { 0b100 }
18    sub BUTTON_EL () { 0b1000 }
19    sub CAPTION_EL () { 0b10000 }
20    sub DD_EL () { 0b100000 }
21    sub DIV_EL () { 0b1000000 }
22    sub DT_EL () { 0b10000000 }
23    sub FORM_EL () { 0b100000000 }
24    sub FORMATTING_EL () { 0b1000000000 }
25    sub FRAMESET_EL () { 0b10000000000 }
26    sub HEADING_EL () { 0b100000000000 }
27    sub HTML_EL () { 0b1000000000000 }
28    sub LI_EL () { 0b10000000000000 }
29    sub NOBR_EL () { 0b100000000000000 }
30    sub OPTION_EL () { 0b1000000000000000 }
31    sub OPTGROUP_EL () { 0b10000000000000000 }
32    sub P_EL () { 0b100000000000000000 }
33    sub SELECT_EL () { 0b1000000000000000000 }
34    sub TABLE_EL () { 0b10000000000000000000 }
35    sub TABLE_CELL_EL () { 0b100000000000000000000 }
36    sub TABLE_ROW_EL () { 0b1000000000000000000000 }
37    sub TABLE_ROW_GROUP_EL () { 0b10000000000000000000000 }
38    sub MISC_SCOPING_EL () { 0b100000000000000000000000 }
39    sub MISC_SPECIAL_EL () { 0b1000000000000000000000000 }
40    
41    sub TABLE_ROWS_EL () {
42      TABLE_EL |
43      TABLE_ROW_EL |
44      TABLE_ROW_GROUP_EL
45    }
46    
47    sub END_TAG_OPTIONAL_EL () {
48      DD_EL |
49      DT_EL |
50      LI_EL |
51      P_EL
52    }
53    
54    sub ALL_END_TAG_OPTIONAL_EL () {
55      END_TAG_OPTIONAL_EL |
56      BODY_EL |
57      HTML_EL |
58      TABLE_CELL_EL |
59      TABLE_ROW_EL |
60      TABLE_ROW_GROUP_EL
61    }
62    
63    sub SCOPING_EL () {
64      BUTTON_EL |
65      CAPTION_EL |
66      HTML_EL |
67      TABLE_EL |
68      TABLE_CELL_EL |
69      MISC_SCOPING_EL
70    }
71    
72    sub TABLE_SCOPING_EL () {
73      HTML_EL |
74      TABLE_EL
75    }
76    
77    sub TABLE_ROWS_SCOPING_EL () {
78      HTML_EL |
79      TABLE_ROW_GROUP_EL
80    }
81    
82    sub TABLE_ROW_SCOPING_EL () {
83      HTML_EL |
84      TABLE_ROW_EL
85    }
86    
87    sub SPECIAL_EL () {
88      ADDRESS_EL |
89      BODY_EL |
90      DIV_EL |
91      END_TAG_OPTIONAL_EL |
92      FORM_EL |
93      FRAMESET_EL |
94      HEADING_EL |
95      OPTION_EL |
96      OPTGROUP_EL |
97      SELECT_EL |
98      TABLE_ROW_EL |
99      TABLE_ROW_GROUP_EL |
100      MISC_SPECIAL_EL
101    }
102    
103    my $el_category = {
104      a => A_EL | FORMATTING_EL,
105      address => ADDRESS_EL,
106      applet => MISC_SCOPING_EL,
107      area => MISC_SPECIAL_EL,
108      b => FORMATTING_EL,
109      base => MISC_SPECIAL_EL,
110      basefont => MISC_SPECIAL_EL,
111      bgsound => MISC_SPECIAL_EL,
112      big => FORMATTING_EL,
113      blockquote => MISC_SPECIAL_EL,
114      body => BODY_EL,
115      br => MISC_SPECIAL_EL,
116      button => BUTTON_EL,
117      caption => CAPTION_EL,
118      center => MISC_SPECIAL_EL,
119      col => MISC_SPECIAL_EL,
120      colgroup => MISC_SPECIAL_EL,
121      dd => DD_EL,
122      dir => MISC_SPECIAL_EL,
123      div => DIV_EL,
124      dl => MISC_SPECIAL_EL,
125      dt => DT_EL,
126      em => FORMATTING_EL,
127      embed => MISC_SPECIAL_EL,
128      fieldset => MISC_SPECIAL_EL,
129      font => FORMATTING_EL,
130      form => FORM_EL,
131      frame => MISC_SPECIAL_EL,
132      frameset => FRAMESET_EL,
133      h1 => HEADING_EL,
134      h2 => HEADING_EL,
135      h3 => HEADING_EL,
136      h4 => HEADING_EL,
137      h5 => HEADING_EL,
138      h6 => HEADING_EL,
139      head => MISC_SPECIAL_EL,
140      hr => MISC_SPECIAL_EL,
141      html => HTML_EL,
142      i => FORMATTING_EL,
143      iframe => MISC_SPECIAL_EL,
144      img => MISC_SPECIAL_EL,
145      input => MISC_SPECIAL_EL,
146      isindex => MISC_SPECIAL_EL,
147      li => LI_EL,
148      link => MISC_SPECIAL_EL,
149      listing => MISC_SPECIAL_EL,
150      marquee => MISC_SCOPING_EL,
151      menu => MISC_SPECIAL_EL,
152      meta => MISC_SPECIAL_EL,
153      nobr => NOBR_EL | FORMATTING_EL,
154      noembed => MISC_SPECIAL_EL,
155      noframes => MISC_SPECIAL_EL,
156      noscript => MISC_SPECIAL_EL,
157      object => MISC_SCOPING_EL,
158      ol => MISC_SPECIAL_EL,
159      optgroup => OPTGROUP_EL,
160      option => OPTION_EL,
161      p => P_EL,
162      param => MISC_SPECIAL_EL,
163      plaintext => MISC_SPECIAL_EL,
164      pre => MISC_SPECIAL_EL,
165      s => FORMATTING_EL,
166      script => MISC_SPECIAL_EL,
167      select => SELECT_EL,
168      small => FORMATTING_EL,
169      spacer => MISC_SPECIAL_EL,
170      strike => FORMATTING_EL,
171      strong => FORMATTING_EL,
172      style => MISC_SPECIAL_EL,
173      table => TABLE_EL,
174      tbody => TABLE_ROW_GROUP_EL,
175      td => TABLE_CELL_EL,
176      textarea => MISC_SPECIAL_EL,
177      tfoot => TABLE_ROW_GROUP_EL,
178      th => TABLE_CELL_EL,
179      thead => TABLE_ROW_GROUP_EL,
180      title => MISC_SPECIAL_EL,
181      tr => TABLE_ROW_EL,
182      tt => FORMATTING_EL,
183      u => FORMATTING_EL,
184      ul => MISC_SPECIAL_EL,
185      wbr => MISC_SPECIAL_EL,
186    };
187    
188  my $permitted_slash_tag_name = {  my $permitted_slash_tag_name = {
189    base => 1,    base => 1,
190    link => 1,    link => 1,
# Line 2752  sub _tree_construction_root_element ($) Line 2925  sub _tree_construction_root_element ($)
2925            my $root_element;            my $root_element;
2926            !!!create-element ($root_element, $token->{tag_name}, $token->{attributes}, $token);            !!!create-element ($root_element, $token->{tag_name}, $token->{attributes}, $token);
2927            $self->{document}->append_child ($root_element);            $self->{document}->append_child ($root_element);
2928            push @{$self->{open_elements}}, [$root_element, 'html'];            push @{$self->{open_elements}},
2929                  [$root_element, $el_category->{html}];
2930    
2931            if ($token->{attributes}->{manifest}) {            if ($token->{attributes}->{manifest}) {
2932              !!!cp ('t24');              !!!cp ('t24');
# Line 2785  sub _tree_construction_root_element ($) Line 2959  sub _tree_construction_root_element ($)
2959    
2960      my $root_element; !!!create-element ($root_element, 'html',, $token);      my $root_element; !!!create-element ($root_element, 'html',, $token);
2961      $self->{document}->append_child ($root_element);      $self->{document}->append_child ($root_element);
2962      push @{$self->{open_elements}}, [$root_element, 'html'];      push @{$self->{open_elements}}, [$root_element, $el_category->{html}];
2963    
2964      $self->{application_cache_selection}->(undef);      $self->{application_cache_selection}->(undef);
2965    
# Line 2813  sub _reset_insertion_mode ($) { Line 2987  sub _reset_insertion_mode ($) {
2987        if ($self->{open_elements}->[0]->[0] eq $node->[0]) {        if ($self->{open_elements}->[0]->[0] eq $node->[0]) {
2988          $last = 1;          $last = 1;
2989          if (defined $self->{inner_html_node}) {          if (defined $self->{inner_html_node}) {
2990            if ($self->{inner_html_node}->[1] eq 'td' or            if ($self->{inner_html_node}->[1] & TABLE_CELL_EL) {
               $self->{inner_html_node}->[1] eq 'th') {  
2991              !!!cp ('t27');              !!!cp ('t27');
2992              #              #
2993            } else {            } else {
# Line 2841  sub _reset_insertion_mode ($) { Line 3014  sub _reset_insertion_mode ($) {
3014                        head => IN_BODY_IM, # not in head!                        head => IN_BODY_IM, # not in head!
3015                        body => IN_BODY_IM,                        body => IN_BODY_IM,
3016                        frameset => IN_FRAMESET_IM,                        frameset => IN_FRAMESET_IM,
3017                       }->{$node->[1]};                       }->{$node->[0]->manakai_local_name};
3018                         ## TODO: Foreign namespace case OK?
3019        $self->{insertion_mode} = $new_mode and return if defined $new_mode;        $self->{insertion_mode} = $new_mode and return if defined $new_mode;
3020                
3021        ## Step 14        ## Step 14
3022        if ($node->[1] eq 'html') {        if ($node->[1] & HTML_EL) {
3023          unless (defined $self->{head_element}) {          unless (defined $self->{head_element}) {
3024            !!!cp ('t29');            !!!cp ('t29');
3025            $self->{insertion_mode} = BEFORE_HEAD_IM;            $self->{insertion_mode} = BEFORE_HEAD_IM;
# Line 3092  sub _tree_construction_main ($) { Line 3266  sub _tree_construction_main ($) {
3266        my $formatting_element;        my $formatting_element;
3267        my $formatting_element_i_in_active;        my $formatting_element_i_in_active;
3268        AFE: for (reverse 0..$#$active_formatting_elements) {        AFE: for (reverse 0..$#$active_formatting_elements) {
3269          if ($active_formatting_elements->[$_]->[1] eq $tag_name) {          if ($active_formatting_elements->[$_]->[0] eq '#marker') {
3270              !!!cp ('t52');
3271              last AFE;
3272            } elsif ($active_formatting_elements->[$_]->[0]->manakai_local_name
3273                         eq $tag_name) {
3274            !!!cp ('t51');            !!!cp ('t51');
3275            $formatting_element = $active_formatting_elements->[$_];            $formatting_element = $active_formatting_elements->[$_];
3276            $formatting_element_i_in_active = $_;            $formatting_element_i_in_active = $_;
3277            last AFE;            last AFE;
         } elsif ($active_formatting_elements->[$_]->[0] eq '#marker') {  
           !!!cp ('t52');  
           last AFE;  
3278          }          }
3279        } # AFE        } # AFE
3280        unless (defined $formatting_element) {        unless (defined $formatting_element) {
# Line 3127  sub _tree_construction_main ($) { Line 3302  sub _tree_construction_main ($) {
3302              !!!next-token;              !!!next-token;
3303              return;              return;
3304            }            }
3305          } elsif ({          } elsif ($node->[1] & SCOPING_EL) {
                   applet => 1, table => 1, caption => 1, td => 1, th => 1,  
                   button => 1, marquee => 1, object => 1, html => 1,  
                  }->{$node->[1]}) {  
3306            !!!cp ('t56');            !!!cp ('t56');
3307            $in_scope = 0;            $in_scope = 0;
3308          }          }
# Line 3156  sub _tree_construction_main ($) { Line 3328  sub _tree_construction_main ($) {
3328        my $furthest_block_i_in_open;        my $furthest_block_i_in_open;
3329        OE: for (reverse 0..$#{$self->{open_elements}}) {        OE: for (reverse 0..$#{$self->{open_elements}}) {
3330          my $node = $self->{open_elements}->[$_];          my $node = $self->{open_elements}->[$_];
3331          if (not $formatting_category->{$node->[1]} and          if (not ($node->[1] & FORMATTING_EL) and
3332              #not $phrasing_category->{$node->[1]} and              #not $phrasing_category->{$node->[1]} and
3333              ($special_category->{$node->[1]} or              ($node->[1] & SPECIAL_EL or
3334               $scoping_category->{$node->[1]})) { ## Scoping is redundant, maybe               $node->[1] & SCOPING_EL)) { ## Scoping is redundant, maybe
3335            !!!cp ('t59');            !!!cp ('t59');
3336            $furthest_block = $node;            $furthest_block = $node;
3337            $furthest_block_i_in_open = $_;            $furthest_block_i_in_open = $_;
# Line 3245  sub _tree_construction_main ($) { Line 3417  sub _tree_construction_main ($) {
3417        } # S7          } # S7  
3418                
3419        ## Step 8        ## Step 8
3420        if ({        if ($common_ancestor_node->[1] & TABLE_ROWS_EL) {
            table => 1, tbody => 1, tfoot => 1, thead => 1, tr => 1,  
           }->{$common_ancestor_node->[1]}) {  
3421          my $foster_parent_element;          my $foster_parent_element;
3422          my $next_sibling;          my $next_sibling;
3423                           OE: for (reverse 0..$#{$self->{open_elements}}) {          OE: for (reverse 0..$#{$self->{open_elements}}) {
3424                             if ($self->{open_elements}->[$_]->[1] eq 'table') {            if ($self->{open_elements}->[$_]->[1] & TABLE_EL) {
3425                               my $parent = $self->{open_elements}->[$_]->[0]->parent_node;                               my $parent = $self->{open_elements}->[$_]->[0]->parent_node;
3426                               if (defined $parent and $parent->node_type == 1) {                               if (defined $parent and $parent->node_type == 1) {
3427                                 !!!cp ('t65.1');                                 !!!cp ('t65.1');
# Line 3324  sub _tree_construction_main ($) { Line 3494  sub _tree_construction_main ($) {
3494    
3495    my $insert_to_foster = sub {    my $insert_to_foster = sub {
3496      my $child = shift;      my $child = shift;
3497      if ({      if ($self->{open_elements}->[-1]->[1] & TABLE_ROWS_EL) {
          table => 1, tbody => 1, tfoot => 1, thead => 1, tr => 1,  
         }->{$self->{open_elements}->[-1]->[1]}) {  
3498        # MUST        # MUST
3499        my $foster_parent_element;        my $foster_parent_element;
3500        my $next_sibling;        my $next_sibling;
3501                           OE: for (reverse 0..$#{$self->{open_elements}}) {        OE: for (reverse 0..$#{$self->{open_elements}}) {
3502                             if ($self->{open_elements}->[$_]->[1] eq 'table') {          if ($self->{open_elements}->[$_]->[1] & TABLE_EL) {
3503                               my $parent = $self->{open_elements}->[$_]->[0]->parent_node;                               my $parent = $self->{open_elements}->[$_]->[0]->parent_node;
3504                               if (defined $parent and $parent->node_type == 1) {                               if (defined $parent and $parent->node_type == 1) {
3505                                 !!!cp ('t70');                                 !!!cp ('t70');
# Line 3429  sub _tree_construction_main ($) { Line 3597  sub _tree_construction_main ($) {
3597            ## As if <head>            ## As if <head>
3598            !!!create-element ($self->{head_element}, 'head',, $token);            !!!create-element ($self->{head_element}, 'head',, $token);
3599            $self->{open_elements}->[-1]->[0]->append_child ($self->{head_element});            $self->{open_elements}->[-1]->[0]->append_child ($self->{head_element});
3600            push @{$self->{open_elements}}, [$self->{head_element}, 'head'];            push @{$self->{open_elements}},
3601                  [$self->{head_element}, $el_category->{head}];
3602    
3603            ## Reprocess in the "in head" insertion mode...            ## Reprocess in the "in head" insertion mode...
3604            pop @{$self->{open_elements}};            pop @{$self->{open_elements}};
# Line 3455  sub _tree_construction_main ($) { Line 3624  sub _tree_construction_main ($) {
3624            !!!cp ('t92');            !!!cp ('t92');
3625          }          }
3626    
3627              ## "after head" insertion mode          ## "after head" insertion mode
3628              ## As if <body>          ## As if <body>
3629              !!!insert-element ('body',, $token);          !!!insert-element ('body',, $token);
3630              $self->{insertion_mode} = IN_BODY_IM;          $self->{insertion_mode} = IN_BODY_IM;
3631              ## reprocess          ## reprocess
3632            redo B;
3633          } elsif ($token->{type} == START_TAG_TOKEN) {
3634            if ($token->{tag_name} eq 'head') {
3635              if ($self->{insertion_mode} == BEFORE_HEAD_IM) {
3636                !!!cp ('t93');
3637                !!!create-element ($self->{head_element}, $token->{tag_name}, $token->{attributes}, $token);
3638                $self->{open_elements}->[-1]->[0]->append_child
3639                    ($self->{head_element});
3640                push @{$self->{open_elements}},
3641                    [$self->{head_element}, $el_category->{head}];
3642                $self->{insertion_mode} = IN_HEAD_IM;
3643                !!!next-token;
3644              redo B;              redo B;
           } elsif ($token->{type} == START_TAG_TOKEN) {  
             if ($token->{tag_name} eq 'head') {  
               if ($self->{insertion_mode} == BEFORE_HEAD_IM) {  
                 !!!cp ('t93');  
                 !!!create-element ($self->{head_element}, $token->{tag_name}, $token->{attributes}, $token);  
                 $self->{open_elements}->[-1]->[0]->append_child ($self->{head_element});  
                 push @{$self->{open_elements}}, [$self->{head_element}, $token->{tag_name}];  
                 $self->{insertion_mode} = IN_HEAD_IM;  
                 !!!next-token;  
                 redo B;  
3645                } elsif ($self->{insertion_mode} == AFTER_HEAD_IM) {                } elsif ($self->{insertion_mode} == AFTER_HEAD_IM) {
3646                  !!!cp ('t94');                  !!!cp ('t94');
3647                  #                  #
# Line 3486  sub _tree_construction_main ($) { Line 3657  sub _tree_construction_main ($) {
3657                ## As if <head>                ## As if <head>
3658                !!!create-element ($self->{head_element}, 'head',, $token);                !!!create-element ($self->{head_element}, 'head',, $token);
3659                $self->{open_elements}->[-1]->[0]->append_child ($self->{head_element});                $self->{open_elements}->[-1]->[0]->append_child ($self->{head_element});
3660                push @{$self->{open_elements}}, [$self->{head_element}, 'head'];                push @{$self->{open_elements}},
3661                      [$self->{head_element}, $el_category->{head}];
3662    
3663                $self->{insertion_mode} = IN_HEAD_IM;                $self->{insertion_mode} = IN_HEAD_IM;
3664                ## Reprocess in the "in head" insertion mode...                ## Reprocess in the "in head" insertion mode...
# Line 3511  sub _tree_construction_main ($) { Line 3683  sub _tree_construction_main ($) {
3683                if ($self->{insertion_mode} == AFTER_HEAD_IM) {                if ($self->{insertion_mode} == AFTER_HEAD_IM) {
3684                  !!!cp ('t100');                  !!!cp ('t100');
3685                  !!!parse-error (type => 'after head:'.$token->{tag_name}, token => $token);                  !!!parse-error (type => 'after head:'.$token->{tag_name}, token => $token);
3686                  push @{$self->{open_elements}}, [$self->{head_element}, 'head'];                  push @{$self->{open_elements}},
3687                        [$self->{head_element}, $el_category->{head}];
3688                } else {                } else {
3689                  !!!cp ('t101');                  !!!cp ('t101');
3690                }                }
# Line 3526  sub _tree_construction_main ($) { Line 3699  sub _tree_construction_main ($) {
3699                if ($self->{insertion_mode} == AFTER_HEAD_IM) {                if ($self->{insertion_mode} == AFTER_HEAD_IM) {
3700                  !!!cp ('t102');                  !!!cp ('t102');
3701                  !!!parse-error (type => 'after head:'.$token->{tag_name}, token => $token);                  !!!parse-error (type => 'after head:'.$token->{tag_name}, token => $token);
3702                  push @{$self->{open_elements}}, [$self->{head_element}, 'head'];                  push @{$self->{open_elements}},
3703                        [$self->{head_element}, $el_category->{head}];
3704                } else {                } else {
3705                  !!!cp ('t103');                  !!!cp ('t103');
3706                }                }
# Line 3541  sub _tree_construction_main ($) { Line 3715  sub _tree_construction_main ($) {
3715                if ($self->{insertion_mode} == AFTER_HEAD_IM) {                if ($self->{insertion_mode} == AFTER_HEAD_IM) {
3716                  !!!cp ('t104');                  !!!cp ('t104');
3717                  !!!parse-error (type => 'after head:'.$token->{tag_name}, token => $token);                  !!!parse-error (type => 'after head:'.$token->{tag_name}, token => $token);
3718                  push @{$self->{open_elements}}, [$self->{head_element}, 'head'];                  push @{$self->{open_elements}},
3719                        [$self->{head_element}, $el_category->{head}];
3720                } else {                } else {
3721                  !!!cp ('t105');                  !!!cp ('t105');
3722                }                }
# Line 3611  sub _tree_construction_main ($) { Line 3786  sub _tree_construction_main ($) {
3786                } elsif ($self->{insertion_mode} == AFTER_HEAD_IM) {                } elsif ($self->{insertion_mode} == AFTER_HEAD_IM) {
3787                  !!!cp ('t112');                  !!!cp ('t112');
3788                  !!!parse-error (type => 'after head:'.$token->{tag_name}, token => $token);                  !!!parse-error (type => 'after head:'.$token->{tag_name}, token => $token);
3789                  push @{$self->{open_elements}}, [$self->{head_element}, 'head'];                  push @{$self->{open_elements}},
3790                        [$self->{head_element}, $el_category->{head}];
3791                } else {                } else {
3792                  !!!cp ('t113');                  !!!cp ('t113');
3793                }                }
# Line 3630  sub _tree_construction_main ($) { Line 3806  sub _tree_construction_main ($) {
3806                if ($self->{insertion_mode} == AFTER_HEAD_IM) {                if ($self->{insertion_mode} == AFTER_HEAD_IM) {
3807                  !!!cp ('t114');                  !!!cp ('t114');
3808                  !!!parse-error (type => 'after head:'.$token->{tag_name}, token => $token);                  !!!parse-error (type => 'after head:'.$token->{tag_name}, token => $token);
3809                  push @{$self->{open_elements}}, [$self->{head_element}, 'head'];                  push @{$self->{open_elements}},
3810                        [$self->{head_element}, $el_category->{head}];
3811                } else {                } else {
3812                  !!!cp ('t115');                  !!!cp ('t115');
3813                }                }
# Line 3668  sub _tree_construction_main ($) { Line 3845  sub _tree_construction_main ($) {
3845                } elsif ($self->{insertion_mode} == AFTER_HEAD_IM) {                } elsif ($self->{insertion_mode} == AFTER_HEAD_IM) {
3846                  !!!cp ('t120');                  !!!cp ('t120');
3847                  !!!parse-error (type => 'after head:'.$token->{tag_name}, token => $token);                  !!!parse-error (type => 'after head:'.$token->{tag_name}, token => $token);
3848                  push @{$self->{open_elements}}, [$self->{head_element}, 'head'];                  push @{$self->{open_elements}},
3849                        [$self->{head_element}, $el_category->{head}];
3850                } else {                } else {
3851                  !!!cp ('t121');                  !!!cp ('t121');
3852                }                }
# Line 3752  sub _tree_construction_main ($) { Line 3930  sub _tree_construction_main ($) {
3930                  ## As if <head>                  ## As if <head>
3931                  !!!create-element ($self->{head_element}, 'head',, $token);                  !!!create-element ($self->{head_element}, 'head',, $token);
3932                  $self->{open_elements}->[-1]->[0]->append_child ($self->{head_element});                  $self->{open_elements}->[-1]->[0]->append_child ($self->{head_element});
3933                  push @{$self->{open_elements}}, [$self->{head_element}, 'head'];                  push @{$self->{open_elements}},
3934                        [$self->{head_element}, $el_category->{head}];
3935    
3936                  ## Reprocess in the "in head" insertion mode...                  ## Reprocess in the "in head" insertion mode...
3937                  pop @{$self->{open_elements}};                  pop @{$self->{open_elements}};
# Line 3805  sub _tree_construction_main ($) { Line 3984  sub _tree_construction_main ($) {
3984                  ## As if <head>                  ## As if <head>
3985                  !!!create-element ($self->{head_element}, 'head',, $token);                  !!!create-element ($self->{head_element}, 'head',, $token);
3986                  $self->{open_elements}->[-1]->[0]->append_child ($self->{head_element});                  $self->{open_elements}->[-1]->[0]->append_child ($self->{head_element});
3987                  push @{$self->{open_elements}}, [$self->{head_element}, 'head'];                  push @{$self->{open_elements}},
3988                        [$self->{head_element}, $el_category->{head}];
3989    
3990                  $self->{insertion_mode} = IN_HEAD_IM;                  $self->{insertion_mode} = IN_HEAD_IM;
3991                  ## Reprocess in the "in head" insertion mode...                  ## Reprocess in the "in head" insertion mode...
# Line 3828  sub _tree_construction_main ($) { Line 4008  sub _tree_construction_main ($) {
4008                  ## As if <head>                  ## As if <head>
4009                  !!!create-element ($self->{head_element}, 'head',, $token);                  !!!create-element ($self->{head_element}, 'head',, $token);
4010                  $self->{open_elements}->[-1]->[0]->append_child ($self->{head_element});                  $self->{open_elements}->[-1]->[0]->append_child ($self->{head_element});
4011                  push @{$self->{open_elements}}, [$self->{head_element}, 'head'];                  push @{$self->{open_elements}},
4012                        [$self->{head_element}, $el_category->{head}];
4013    
4014                  $self->{insertion_mode} = IN_HEAD_IM;                  $self->{insertion_mode} = IN_HEAD_IM;
4015                  ## Reprocess in the "in head" insertion mode...                  ## Reprocess in the "in head" insertion mode...
# Line 3892  sub _tree_construction_main ($) { Line 4073  sub _tree_construction_main ($) {
4073            !!!create-element ($self->{head_element}, 'head',, $token);            !!!create-element ($self->{head_element}, 'head',, $token);
4074            $self->{open_elements}->[-1]->[0]->append_child            $self->{open_elements}->[-1]->[0]->append_child
4075                ($self->{head_element});                ($self->{head_element});
4076            #push @{$self->{open_elements}}, [$self->{head_element}, 'head'];            #push @{$self->{open_elements}},
4077              #    [$self->{head_element}, $el_category->{head}];
4078            #$self->{insertion_mode} = IN_HEAD_IM;            #$self->{insertion_mode} = IN_HEAD_IM;
4079            ## NOTE: Reprocess.            ## NOTE: Reprocess.
4080    
# Line 3961  sub _tree_construction_main ($) { Line 4143  sub _tree_construction_main ($) {
4143                  ## have an element in table scope                  ## have an element in table scope
4144                  for (reverse 0..$#{$self->{open_elements}}) {                  for (reverse 0..$#{$self->{open_elements}}) {
4145                    my $node = $self->{open_elements}->[$_];                    my $node = $self->{open_elements}->[$_];
4146                    if ($node->[1] eq 'td' or $node->[1] eq 'th') {                    if ($node->[1] & TABLE_CELL_EL) {
4147                      !!!cp ('t151');                      !!!cp ('t151');
4148    
4149                      ## Close the cell                      ## Close the cell
# Line 3971  sub _tree_construction_main ($) { Line 4153  sub _tree_construction_main ($) {
4153                                line => $token->{line},                                line => $token->{line},
4154                                column => $token->{column}};                                column => $token->{column}};
4155                      redo B;                      redo B;
4156                    } elsif ({                    } elsif ($node->[1] & TABLE_SCOPING_EL) {
                             table => 1, html => 1,  
                            }->{$node->[1]}) {  
4157                      !!!cp ('t152');                      !!!cp ('t152');
4158                      ## ISSUE: This case can never be reached, maybe.                      ## ISSUE: This case can never be reached, maybe.
4159                      last;                      last;
# Line 3995  sub _tree_construction_main ($) { Line 4175  sub _tree_construction_main ($) {
4175                  INSCOPE: {                  INSCOPE: {
4176                    for (reverse 0..$#{$self->{open_elements}}) {                    for (reverse 0..$#{$self->{open_elements}}) {
4177                      my $node = $self->{open_elements}->[$_];                      my $node = $self->{open_elements}->[$_];
4178                      if ($node->[1] eq 'caption') {                      if ($node->[1] & CAPTION_EL) {
4179                        !!!cp ('t155');                        !!!cp ('t155');
4180                        $i = $_;                        $i = $_;
4181                        last INSCOPE;                        last INSCOPE;
4182                      } elsif ({                      } elsif ($node->[1] & TABLE_SCOPING_EL) {
                               table => 1, html => 1,  
                              }->{$node->[1]}) {  
4183                        !!!cp ('t156');                        !!!cp ('t156');
4184                        last;                        last;
4185                      }                      }
# Line 4016  sub _tree_construction_main ($) { Line 4194  sub _tree_construction_main ($) {
4194                  } # INSCOPE                  } # INSCOPE
4195                                    
4196                  ## generate implied end tags                  ## generate implied end tags
4197                  while ({                  while ($self->{open_elements}->[-1]->[1]
4198                          dd => 1, dt => 1, li => 1, p => 1,                             & END_TAG_OPTIONAL_EL) {
                        }->{$self->{open_elements}->[-1]->[1]}) {  
4199                    !!!cp ('t158');                    !!!cp ('t158');
4200                    pop @{$self->{open_elements}};                    pop @{$self->{open_elements}};
4201                  }                  }
4202    
4203                  if ($self->{open_elements}->[-1]->[1] ne 'caption') {                  unless ($self->{open_elements}->[-1]->[1] & CAPTION_EL) {
4204                    !!!cp ('t159');                    !!!cp ('t159');
4205                    !!!parse-error (type => 'not closed',                    !!!parse-error (type => 'not closed',
4206                                    value => $self->{open_elements}->[-1]->[0]                                    value => $self->{open_elements}->[-1]->[0]
# Line 4056  sub _tree_construction_main ($) { Line 4233  sub _tree_construction_main ($) {
4233                  my $i;                  my $i;
4234                  INSCOPE: for (reverse 0..$#{$self->{open_elements}}) {                  INSCOPE: for (reverse 0..$#{$self->{open_elements}}) {
4235                    my $node = $self->{open_elements}->[$_];                    my $node = $self->{open_elements}->[$_];
4236                    if ($node->[1] eq $token->{tag_name}) {                    if ($node->[0]->manakai_local_name eq $token->{tag_name}) {
4237                      !!!cp ('t163');                      !!!cp ('t163');
4238                      $i = $_;                      $i = $_;
4239                      last INSCOPE;                      last INSCOPE;
4240                    } elsif ({                    } elsif ($node->[1] & TABLE_SCOPING_EL) {
                             table => 1, html => 1,  
                            }->{$node->[1]}) {  
4241                      !!!cp ('t164');                      !!!cp ('t164');
4242                      last INSCOPE;                      last INSCOPE;
4243                    }                    }
# Line 4076  sub _tree_construction_main ($) { Line 4251  sub _tree_construction_main ($) {
4251                    }                    }
4252                                    
4253                  ## generate implied end tags                  ## generate implied end tags
4254                  while ({                  while ($self->{open_elements}->[-1]->[1]
4255                          dd => 1, dt => 1, li => 1, p => 1,                             & END_TAG_OPTIONAL_EL) {
                        }->{$self->{open_elements}->[-1]->[1]}) {  
4256                    !!!cp ('t166');                    !!!cp ('t166');
4257                    pop @{$self->{open_elements}};                    pop @{$self->{open_elements}};
4258                  }                  }
4259    
4260                  if ($self->{open_elements}->[-1]->[1] ne $token->{tag_name}) {                  if ($self->{open_elements}->[-1]->[0]->manakai_local_name
4261                            ne $token->{tag_name}) {
4262                    !!!cp ('t167');                    !!!cp ('t167');
4263                    !!!parse-error (type => 'not closed',                    !!!parse-error (type => 'not closed',
4264                                    value => $self->{open_elements}->[-1]->[0]                                    value => $self->{open_elements}->[-1]->[0]
# Line 4118  sub _tree_construction_main ($) { Line 4293  sub _tree_construction_main ($) {
4293                  INSCOPE: {                  INSCOPE: {
4294                    for (reverse 0..$#{$self->{open_elements}}) {                    for (reverse 0..$#{$self->{open_elements}}) {
4295                      my $node = $self->{open_elements}->[$_];                      my $node = $self->{open_elements}->[$_];
4296                      if ($node->[1] eq $token->{tag_name}) {                      if ($node->[1] & CAPTION_EL) {
4297                        !!!cp ('t171');                        !!!cp ('t171');
4298                        $i = $_;                        $i = $_;
4299                        last INSCOPE;                        last INSCOPE;
4300                      } elsif ({                      } elsif ($node->[1] & TABLE_SCOPING_EL) {
                               table => 1, html => 1,  
                              }->{$node->[1]}) {  
4301                        !!!cp ('t172');                        !!!cp ('t172');
4302                        last;                        last;
4303                      }                      }
# Line 4139  sub _tree_construction_main ($) { Line 4312  sub _tree_construction_main ($) {
4312                  } # INSCOPE                  } # INSCOPE
4313                                    
4314                  ## generate implied end tags                  ## generate implied end tags
4315                  while ({                  while ($self->{open_elements}->[-1]->[1]
4316                          dd => 1, dt => 1, li => 1, p => 1,                             & END_TAG_OPTIONAL_EL) {
                        }->{$self->{open_elements}->[-1]->[1]}) {  
4317                    !!!cp ('t174');                    !!!cp ('t174');
4318                    pop @{$self->{open_elements}};                    pop @{$self->{open_elements}};
4319                  }                  }
4320                                    
4321                  if ($self->{open_elements}->[-1]->[1] ne 'caption') {                  unless ($self->{open_elements}->[-1]->[1] & CAPTION_EL) {
4322                    !!!cp ('t175');                    !!!cp ('t175');
4323                    !!!parse-error (type => 'not closed',                    !!!parse-error (type => 'not closed',
4324                                    value => $self->{open_elements}->[-1]->[0]                                    value => $self->{open_elements}->[-1]->[0]
# Line 4185  sub _tree_construction_main ($) { Line 4357  sub _tree_construction_main ($) {
4357                INSCOPE: {                INSCOPE: {
4358                  for (reverse 0..$#{$self->{open_elements}}) {                  for (reverse 0..$#{$self->{open_elements}}) {
4359                    my $node = $self->{open_elements}->[$_];                    my $node = $self->{open_elements}->[$_];
4360                    if ($node->[1] eq $token->{tag_name}) {                    if ($node->[0]->manakai_local_name eq $token->{tag_name}) {
4361                      !!!cp ('t179');                      !!!cp ('t179');
4362                      $i = $_;                      $i = $_;
4363    
# Line 4195  sub _tree_construction_main ($) { Line 4367  sub _tree_construction_main ($) {
4367                                line => $token->{line},                                line => $token->{line},
4368                                column => $token->{column}};                                column => $token->{column}};
4369                      redo B;                      redo B;
4370                    } elsif ($node->[1] eq 'td' or $node->[1] eq 'th') {                    } elsif ($node->[1] & TABLE_CELL_EL) {
4371                      !!!cp ('t180');                      !!!cp ('t180');
4372                      $tn = $node->[1];                      $tn = $node->[0]->manakai_local_name;
4373                      ## NOTE: There is exactly one |td| or |th| element                      ## NOTE: There is exactly one |td| or |th| element
4374                      ## in scope in the stack of open elements by definition.                      ## in scope in the stack of open elements by definition.
4375                    } elsif ({                    } elsif ($node->[1] & TABLE_SCOPING_EL) {
                             table => 1, html => 1,  
                            }->{$node->[1]}) {  
4376                      ## ISSUE: Can this be reached?                      ## ISSUE: Can this be reached?
4377                      !!!cp ('t181');                      !!!cp ('t181');
4378                      last;                      last;
# Line 4225  sub _tree_construction_main ($) { Line 4395  sub _tree_construction_main ($) {
4395                my $i;                my $i;
4396                INSCOPE: for (reverse 0..$#{$self->{open_elements}}) {                INSCOPE: for (reverse 0..$#{$self->{open_elements}}) {
4397                  my $node = $self->{open_elements}->[$_];                  my $node = $self->{open_elements}->[$_];
4398                  if ($node->[1] eq 'caption') {                  if ($node->[1] & CAPTION_EL) {
4399                    !!!cp ('t184');                    !!!cp ('t184');
4400                    $i = $_;                    $i = $_;
4401                    last INSCOPE;                    last INSCOPE;
4402                  } elsif ({                  } elsif ($node->[1] & TABLE_SCOPING_EL) {
                           table => 1, html => 1,  
                          }->{$node->[1]}) {  
4403                    !!!cp ('t185');                    !!!cp ('t185');
4404                    last INSCOPE;                    last INSCOPE;
4405                  }                  }
# Line 4245  sub _tree_construction_main ($) { Line 4413  sub _tree_construction_main ($) {
4413                }                }
4414                                
4415                ## generate implied end tags                ## generate implied end tags
4416                while ({                while ($self->{open_elements}->[-1]->[1] & END_TAG_OPTIONAL_EL) {
                       dd => 1, dt => 1, li => 1, p => 1,  
                      }->{$self->{open_elements}->[-1]->[1]}) {  
4417                  !!!cp ('t187');                  !!!cp ('t187');
4418                  pop @{$self->{open_elements}};                  pop @{$self->{open_elements}};
4419                }                }
4420    
4421                if ($self->{open_elements}->[-1]->[1] ne 'caption') {                unless ($self->{open_elements}->[-1]->[1] & CAPTION_EL) {
4422                  !!!cp ('t188');                  !!!cp ('t188');
4423                  !!!parse-error (type => 'not closed',                  !!!parse-error (type => 'not closed',
4424                                  value => $self->{open_elements}->[-1]->[0]                                  value => $self->{open_elements}->[-1]->[0]
# Line 4299  sub _tree_construction_main ($) { Line 4465  sub _tree_construction_main ($) {
4465              }              }
4466        } elsif ($token->{type} == END_OF_FILE_TOKEN) {        } elsif ($token->{type} == END_OF_FILE_TOKEN) {
4467          for my $entry (@{$self->{open_elements}}) {          for my $entry (@{$self->{open_elements}}) {
4468            if (not {            unless ($entry->[1] & ALL_END_TAG_OPTIONAL_EL) {
             dd => 1, dt => 1, li => 1, p => 1, tbody => 1, td => 1, tfoot => 1,  
             th => 1, thead => 1, tr => 1, body => 1, html => 1,  
           }->{$entry->[1]}) {  
4469              !!!cp ('t75');              !!!cp ('t75');
4470              !!!parse-error (type => 'in body:#eof', token => $token);              !!!parse-error (type => 'in body:#eof', token => $token);
4471              last;              last;
# Line 4340  sub _tree_construction_main ($) { Line 4503  sub _tree_construction_main ($) {
4503              ## result in a new Text node.              ## result in a new Text node.
4504              $reconstruct_active_formatting_elements->($insert_to_foster);              $reconstruct_active_formatting_elements->($insert_to_foster);
4505                            
4506              if ({              if ($self->{open_elements}->[-1]->[1] & TABLE_ROWS_EL) {
                  table => 1, tbody => 1, tfoot => 1,  
                  thead => 1, tr => 1,  
                 }->{$self->{open_elements}->[-1]->[1]}) {  
4507                # MUST                # MUST
4508                my $foster_parent_element;                my $foster_parent_element;
4509                my $next_sibling;                my $next_sibling;
4510                my $prev_sibling;                my $prev_sibling;
4511                OE: for (reverse 0..$#{$self->{open_elements}}) {                OE: for (reverse 0..$#{$self->{open_elements}}) {
4512                  if ($self->{open_elements}->[$_]->[1] eq 'table') {                  if ($self->{open_elements}->[$_]->[1] & TABLE_EL) {
4513                    my $parent = $self->{open_elements}->[$_]->[0]->parent_node;                    my $parent = $self->{open_elements}->[$_]->[0]->parent_node;
4514                    if (defined $parent and $parent->node_type == 1) {                    if (defined $parent and $parent->node_type == 1) {
4515                      !!!cp ('t196');                      !!!cp ('t196');
# Line 4392  sub _tree_construction_main ($) { Line 4552  sub _tree_construction_main ($) {
4552                  }->{$token->{tag_name}}) {                  }->{$token->{tag_name}}) {
4553                if ($self->{insertion_mode} == IN_TABLE_IM) {                if ($self->{insertion_mode} == IN_TABLE_IM) {
4554                  ## Clear back to table context                  ## Clear back to table context
4555                  while ($self->{open_elements}->[-1]->[1] ne 'table' and                  while (not ($self->{open_elements}->[-1]->[1]
4556                         $self->{open_elements}->[-1]->[1] ne 'html') {                                  & TABLE_SCOPING_EL)) {
4557                    !!!cp ('t201');                    !!!cp ('t201');
4558                    pop @{$self->{open_elements}};                    pop @{$self->{open_elements}};
4559                  }                  }
# Line 4410  sub _tree_construction_main ($) { Line 4570  sub _tree_construction_main ($) {
4570                  }                  }
4571                                    
4572                  ## Clear back to table body context                  ## Clear back to table body context
4573                  while (not {                  while (not ($self->{open_elements}->[-1]->[1]
4574                    tbody => 1, tfoot => 1, thead => 1, html => 1,                                  & TABLE_ROWS_SCOPING_EL)) {
                 }->{$self->{open_elements}->[-1]->[1]}) {  
4575                    !!!cp ('t203');                    !!!cp ('t203');
4576                    ## ISSUE: Can this case be reached?                    ## ISSUE: Can this case be reached?
4577                    pop @{$self->{open_elements}};                    pop @{$self->{open_elements}};
# Line 4434  sub _tree_construction_main ($) { Line 4593  sub _tree_construction_main ($) {
4593                }                }
4594    
4595                ## Clear back to table row context                ## Clear back to table row context
4596                while (not {                while (not ($self->{open_elements}->[-1]->[1]
4597                  tr => 1, html => 1,                                & TABLE_ROW_SCOPING_EL)) {
               }->{$self->{open_elements}->[-1]->[1]}) {  
4598                  !!!cp ('t207');                  !!!cp ('t207');
4599                  pop @{$self->{open_elements}};                  pop @{$self->{open_elements}};
4600                }                }
# Line 4459  sub _tree_construction_main ($) { Line 4617  sub _tree_construction_main ($) {
4617                  my $i;                  my $i;
4618                  INSCOPE: for (reverse 0..$#{$self->{open_elements}}) {                  INSCOPE: for (reverse 0..$#{$self->{open_elements}}) {
4619                    my $node = $self->{open_elements}->[$_];                    my $node = $self->{open_elements}->[$_];
4620                    if ($node->[1] eq 'tr') {                    if ($node->[1] & TABLE_ROW_EL) {
4621                      !!!cp ('t208');                      !!!cp ('t208');
4622                      $i = $_;                      $i = $_;
4623                      last INSCOPE;                      last INSCOPE;
4624                    } elsif ({                    } elsif ($node->[1] & TABLE_SCOPING_EL) {
                             html => 1,  
   
                             ## NOTE: This element does not appear here, maybe.  
                             table => 1,  
                            }->{$node->[1]}) {  
4625                      !!!cp ('t209');                      !!!cp ('t209');
4626                      last INSCOPE;                      last INSCOPE;
4627                    }                    }
# Line 4483  sub _tree_construction_main ($) { Line 4636  sub _tree_construction_main ($) {
4636                  }                  }
4637                                    
4638                  ## Clear back to table row context                  ## Clear back to table row context
4639                  while (not {                  while (not ($self->{open_elements}->[-1]->[1]
4640                    tr => 1, html => 1,                                  & TABLE_ROW_SCOPING_EL)) {
                 }->{$self->{open_elements}->[-1]->[1]}) {  
4641                    !!!cp ('t211');                    !!!cp ('t211');
4642                    ## ISSUE: Can this case be reached?                    ## ISSUE: Can this case be reached?
4643                    pop @{$self->{open_elements}};                    pop @{$self->{open_elements}};
# Line 4508  sub _tree_construction_main ($) { Line 4660  sub _tree_construction_main ($) {
4660                  my $i;                  my $i;
4661                  INSCOPE: for (reverse 0..$#{$self->{open_elements}}) {                  INSCOPE: for (reverse 0..$#{$self->{open_elements}}) {
4662                    my $node = $self->{open_elements}->[$_];                    my $node = $self->{open_elements}->[$_];
4663                    if ({                    if ($node->[1] & TABLE_ROW_GROUP_EL) {
                        tbody => 1, thead => 1, tfoot => 1,  
                       }->{$node->[1]}) {  
4664                      !!!cp ('t214');                      !!!cp ('t214');
4665                      $i = $_;                      $i = $_;
4666                      last INSCOPE;                      last INSCOPE;
4667                    } elsif ({                    } elsif ($node->[1] & TABLE_SCOPING_EL) {
                             table => 1, html => 1,  
                            }->{$node->[1]}) {  
4668                      !!!cp ('t215');                      !!!cp ('t215');
4669                      last INSCOPE;                      last INSCOPE;
4670                    }                    }
# Line 4531  sub _tree_construction_main ($) { Line 4679  sub _tree_construction_main ($) {
4679                  }                  }
4680    
4681                  ## Clear back to table body context                  ## Clear back to table body context
4682                  while (not {                  while (not ($self->{open_elements}->[-1]->[1]
4683                    tbody => 1, tfoot => 1, thead => 1, html => 1,                                  & TABLE_ROWS_SCOPING_EL)) {
                 }->{$self->{open_elements}->[-1]->[1]}) {  
4684                    !!!cp ('t217');                    !!!cp ('t217');
4685                    ## ISSUE: Can this state be reached?                    ## ISSUE: Can this state be reached?
4686                    pop @{$self->{open_elements}};                    pop @{$self->{open_elements}};
# Line 4555  sub _tree_construction_main ($) { Line 4702  sub _tree_construction_main ($) {
4702    
4703                if ($token->{tag_name} eq 'col') {                if ($token->{tag_name} eq 'col') {
4704                  ## Clear back to table context                  ## Clear back to table context
4705                  while ($self->{open_elements}->[-1]->[1] ne 'table' and                  while (not ($self->{open_elements}->[-1]->[1]
4706                         $self->{open_elements}->[-1]->[1] ne 'html') {                                  & TABLE_SCOPING_EL)) {
4707                    !!!cp ('t219');                    !!!cp ('t219');
4708                    ## ISSUE: Can this state be reached?                    ## ISSUE: Can this state be reached?
4709                    pop @{$self->{open_elements}};                    pop @{$self->{open_elements}};
# Line 4572  sub _tree_construction_main ($) { Line 4719  sub _tree_construction_main ($) {
4719                          tbody => 1, tfoot => 1, thead => 1,                          tbody => 1, tfoot => 1, thead => 1,
4720                         }->{$token->{tag_name}}) {                         }->{$token->{tag_name}}) {
4721                  ## Clear back to table context                  ## Clear back to table context
4722                  while ($self->{open_elements}->[-1]->[1] ne 'table' and                  while (not ($self->{open_elements}->[-1]->[1]
4723                         $self->{open_elements}->[-1]->[1] ne 'html') {                                  & TABLE_SCOPING_EL)) {
4724                    !!!cp ('t220');                    !!!cp ('t220');
4725                    ## ISSUE: Can this state be reached?                    ## ISSUE: Can this state be reached?
4726                    pop @{$self->{open_elements}};                    pop @{$self->{open_elements}};
# Line 4606  sub _tree_construction_main ($) { Line 4753  sub _tree_construction_main ($) {
4753                my $i;                my $i;
4754                INSCOPE: for (reverse 0..$#{$self->{open_elements}}) {                INSCOPE: for (reverse 0..$#{$self->{open_elements}}) {
4755                  my $node = $self->{open_elements}->[$_];                  my $node = $self->{open_elements}->[$_];
4756                  if ($node->[1] eq 'table') {                  if ($node->[1] & TABLE_EL) {
4757                    !!!cp ('t221');                    !!!cp ('t221');
4758                    $i = $_;                    $i = $_;
4759                    last INSCOPE;                    last INSCOPE;
4760                  } elsif ({                  } elsif ($node->[1] & TABLE_SCOPING_EL) {
                           #table => 1,  
                           html => 1,  
                          }->{$node->[1]}) {  
4761                    !!!cp ('t222');                    !!!cp ('t222');
4762                    last INSCOPE;                    last INSCOPE;
4763                  }                  }
# Line 4629  sub _tree_construction_main ($) { Line 4773  sub _tree_construction_main ($) {
4773                                
4774  ## TODO: Followings are removed from the latest spec.  ## TODO: Followings are removed from the latest spec.
4775                ## generate implied end tags                ## generate implied end tags
4776                while ({                while ($self->{open_elements}->[-1]->[1] & END_TAG_OPTIONAL_EL) {
                       dd => 1, dt => 1, li => 1, p => 1,  
                      }->{$self->{open_elements}->[-1]->[1]}) {  
4777                  !!!cp ('t224');                  !!!cp ('t224');
4778                  pop @{$self->{open_elements}};                  pop @{$self->{open_elements}};
4779                }                }
4780    
4781                if ($self->{open_elements}->[-1]->[1] ne 'table') {                unless ($self->{open_elements}->[-1]->[1] & TABLE_EL) {
4782                  !!!cp ('t225');                  !!!cp ('t225');
4783                  ## NOTE: |<table><tr><table>|                  ## NOTE: |<table><tr><table>|
4784                  !!!parse-error (type => 'not closed',                  !!!parse-error (type => 'not closed',
# Line 4718  sub _tree_construction_main ($) { Line 4860  sub _tree_construction_main ($) {
4860                my $i;                my $i;
4861                INSCOPE: for (reverse 0..$#{$self->{open_elements}}) {                INSCOPE: for (reverse 0..$#{$self->{open_elements}}) {
4862                  my $node = $self->{open_elements}->[$_];                  my $node = $self->{open_elements}->[$_];
4863                  if ($node->[1] eq $token->{tag_name}) {                  if ($node->[1] & TABLE_ROW_EL) {
4864                    !!!cp ('t228');                    !!!cp ('t228');
4865                    $i = $_;                    $i = $_;
4866                    last INSCOPE;                    last INSCOPE;
4867                  } elsif ({                  } elsif ($node->[1] & TABLE_SCOPING_EL) {
                           table => 1, html => 1,  
                          }->{$node->[1]}) {  
4868                    !!!cp ('t229');                    !!!cp ('t229');
4869                    last INSCOPE;                    last INSCOPE;
4870                  }                  }
# Line 4740  sub _tree_construction_main ($) { Line 4880  sub _tree_construction_main ($) {
4880                }                }
4881    
4882                ## Clear back to table row context                ## Clear back to table row context
4883                while (not {                while (not ($self->{open_elements}->[-1]->[1]
4884                  tr => 1, html => 1,                                & TABLE_ROW_SCOPING_EL)) {
               }->{$self->{open_elements}->[-1]->[1]}) {  
4885                  !!!cp ('t231');                  !!!cp ('t231');
4886  ## ISSUE: Can this state be reached?  ## ISSUE: Can this state be reached?
4887                  pop @{$self->{open_elements}};                  pop @{$self->{open_elements}};
# Line 4759  sub _tree_construction_main ($) { Line 4898  sub _tree_construction_main ($) {
4898                  my $i;                  my $i;
4899                  INSCOPE: for (reverse 0..$#{$self->{open_elements}}) {                  INSCOPE: for (reverse 0..$#{$self->{open_elements}}) {
4900                    my $node = $self->{open_elements}->[$_];                    my $node = $self->{open_elements}->[$_];
4901                    if ($node->[1] eq 'tr') {                    if ($node->[1] & TABLE_ROW_EL) {
4902                      !!!cp ('t233');                      !!!cp ('t233');
4903                      $i = $_;                      $i = $_;
4904                      last INSCOPE;                      last INSCOPE;
4905                    } elsif ({                    } elsif ($node->[1] & TABLE_SCOPING_EL) {
                             table => 1, html => 1,  
                            }->{$node->[1]}) {  
4906                      !!!cp ('t234');                      !!!cp ('t234');
4907                      last INSCOPE;                      last INSCOPE;
4908                    }                    }
# Line 4780  sub _tree_construction_main ($) { Line 4917  sub _tree_construction_main ($) {
4917                  }                  }
4918                                    
4919                  ## Clear back to table row context                  ## Clear back to table row context
4920                  while (not {                  while (not ($self->{open_elements}->[-1]->[1]
4921                    tr => 1, html => 1,                                  & TABLE_ROW_SCOPING_EL)) {
                 }->{$self->{open_elements}->[-1]->[1]}) {  
4922                    !!!cp ('t236');                    !!!cp ('t236');
4923  ## ISSUE: Can this state be reached?  ## ISSUE: Can this state be reached?
4924                    pop @{$self->{open_elements}};                    pop @{$self->{open_elements}};
# Line 4798  sub _tree_construction_main ($) { Line 4934  sub _tree_construction_main ($) {
4934                  my $i;                  my $i;
4935                  INSCOPE: for (reverse 0..$#{$self->{open_elements}}) {                  INSCOPE: for (reverse 0..$#{$self->{open_elements}}) {
4936                    my $node = $self->{open_elements}->[$_];                    my $node = $self->{open_elements}->[$_];
4937                    if ({                    if ($node->[1] & TABLE_ROW_GROUP_EL) {
                        tbody => 1, thead => 1, tfoot => 1,  
                       }->{$node->[1]}) {  
4938                      !!!cp ('t237');                      !!!cp ('t237');
4939                      $i = $_;                      $i = $_;
4940                      last INSCOPE;                      last INSCOPE;
4941                    } elsif ({                    } elsif ($node->[1] & TABLE_SCOPING_EL) {
                             table => 1, html => 1,  
                            }->{$node->[1]}) {  
4942                      !!!cp ('t238');                      !!!cp ('t238');
4943                      last INSCOPE;                      last INSCOPE;
4944                    }                    }
# Line 4820  sub _tree_construction_main ($) { Line 4952  sub _tree_construction_main ($) {
4952                  }                  }
4953                                    
4954                  ## Clear back to table body context                  ## Clear back to table body context
4955                  while (not {                  while (not ($self->{open_elements}->[-1]->[1]
4956                    tbody => 1, tfoot => 1, thead => 1, html => 1,                                  & TABLE_ROWS_SCOPING_EL)) {
                 }->{$self->{open_elements}->[-1]->[1]}) {  
4957                    !!!cp ('t240');                    !!!cp ('t240');
4958                    pop @{$self->{open_elements}};                    pop @{$self->{open_elements}};
4959                  }                  }
# Line 4848  sub _tree_construction_main ($) { Line 4979  sub _tree_construction_main ($) {
4979                my $i;                my $i;
4980                INSCOPE: for (reverse 0..$#{$self->{open_elements}}) {                INSCOPE: for (reverse 0..$#{$self->{open_elements}}) {
4981                  my $node = $self->{open_elements}->[$_];                  my $node = $self->{open_elements}->[$_];
4982                  if ($node->[1] eq $token->{tag_name}) {                  if ($node->[1] & TABLE_EL) {
4983                    !!!cp ('t241');                    !!!cp ('t241');
4984                    $i = $_;                    $i = $_;
4985                    last INSCOPE;                    last INSCOPE;
4986                  } elsif ({                  } elsif ($node->[1] & TABLE_SCOPING_EL) {
                           table => 1, html => 1,  
                          }->{$node->[1]}) {  
4987                    !!!cp ('t242');                    !!!cp ('t242');
4988                    last INSCOPE;                    last INSCOPE;
4989                  }                  }
# Line 4883  sub _tree_construction_main ($) { Line 5012  sub _tree_construction_main ($) {
5012                  my $i;                  my $i;
5013                  INSCOPE: for (reverse 0..$#{$self->{open_elements}}) {                  INSCOPE: for (reverse 0..$#{$self->{open_elements}}) {
5014                    my $node = $self->{open_elements}->[$_];                    my $node = $self->{open_elements}->[$_];
5015                    if ($node->[1] eq $token->{tag_name}) {                    if ($node->[0]->manakai_local_name eq $token->{tag_name}) {
5016                      !!!cp ('t247');                      !!!cp ('t247');
5017                      $i = $_;                      $i = $_;
5018                      last INSCOPE;                      last INSCOPE;
5019                    } elsif ({                    } elsif ($node->[1] & TABLE_SCOPING_EL) {
                             table => 1, html => 1,  
                            }->{$node->[1]}) {  
5020                      !!!cp ('t248');                      !!!cp ('t248');
5021                      last INSCOPE;                      last INSCOPE;
5022                    }                    }
# Line 4907  sub _tree_construction_main ($) { Line 5034  sub _tree_construction_main ($) {
5034                  my $i;                  my $i;
5035                  INSCOPE: for (reverse 0..$#{$self->{open_elements}}) {                  INSCOPE: for (reverse 0..$#{$self->{open_elements}}) {
5036                    my $node = $self->{open_elements}->[$_];                    my $node = $self->{open_elements}->[$_];
5037                    if ($node->[1] eq 'tr') {                    if ($node->[1] & TABLE_ROW_EL) {
5038                      !!!cp ('t250');                      !!!cp ('t250');
5039                      $i = $_;                      $i = $_;
5040                      last INSCOPE;                      last INSCOPE;
5041                    } elsif ({                    } elsif ($node->[1] & TABLE_SCOPING_EL) {
                             table => 1, html => 1,  
                            }->{$node->[1]}) {  
5042                      !!!cp ('t251');                      !!!cp ('t251');
5043                      last INSCOPE;                      last INSCOPE;
5044                    }                    }
# Line 4927  sub _tree_construction_main ($) { Line 5052  sub _tree_construction_main ($) {
5052                    }                    }
5053                                    
5054                  ## Clear back to table row context                  ## Clear back to table row context
5055                  while (not {                  while (not ($self->{open_elements}->[-1]->[1]
5056                    tr => 1, html => 1,                                  & TABLE_ROW_SCOPING_EL)) {
                 }->{$self->{open_elements}->[-1]->[1]}) {  
5057                    !!!cp ('t253');                    !!!cp ('t253');
5058  ## ISSUE: Can this case be reached?  ## ISSUE: Can this case be reached?
5059                    pop @{$self->{open_elements}};                    pop @{$self->{open_elements}};
# Line 4944  sub _tree_construction_main ($) { Line 5068  sub _tree_construction_main ($) {
5068                my $i;                my $i;
5069                INSCOPE: for (reverse 0..$#{$self->{open_elements}}) {                INSCOPE: for (reverse 0..$#{$self->{open_elements}}) {
5070                  my $node = $self->{open_elements}->[$_];                  my $node = $self->{open_elements}->[$_];
5071                  if ($node->[1] eq $token->{tag_name}) {                  if ($node->[0]->manakai_local_name eq $token->{tag_name}) {
5072                    !!!cp ('t254');                    !!!cp ('t254');
5073                    $i = $_;                    $i = $_;
5074                    last INSCOPE;                    last INSCOPE;
5075                  } elsif ({                  } elsif ($node->[1] & TABLE_SCOPING_EL) {
                           table => 1, html => 1,  
                          }->{$node->[1]}) {  
5076                    !!!cp ('t255');                    !!!cp ('t255');
5077                    last INSCOPE;                    last INSCOPE;
5078                  }                  }
# Line 4964  sub _tree_construction_main ($) { Line 5086  sub _tree_construction_main ($) {
5086                }                }
5087    
5088                ## Clear back to table body context                ## Clear back to table body context
5089                while (not {                while (not ($self->{open_elements}->[-1]->[1]
5090                  tbody => 1, tfoot => 1, thead => 1, html => 1,                                & TABLE_ROWS_SCOPING_EL)) {
               }->{$self->{open_elements}->[-1]->[1]}) {  
5091                  !!!cp ('t257');                  !!!cp ('t257');
5092  ## ISSUE: Can this case be reached?  ## ISSUE: Can this case be reached?
5093                  pop @{$self->{open_elements}};                  pop @{$self->{open_elements}};
# Line 4995  sub _tree_construction_main ($) { Line 5116  sub _tree_construction_main ($) {
5116            #            #
5117          }          }
5118        } elsif ($token->{type} == END_OF_FILE_TOKEN) {        } elsif ($token->{type} == END_OF_FILE_TOKEN) {
5119          unless ($self->{open_elements}->[-1]->[1] eq 'html' and          unless ($self->{open_elements}->[-1]->[1] & HTML_EL and
5120                  @{$self->{open_elements}} == 1) { # redundant, maybe                  @{$self->{open_elements}} == 1) { # redundant, maybe
5121            !!!parse-error (type => 'in body:#eof', token => $token);            !!!parse-error (type => 'in body:#eof', token => $token);
5122            !!!cp ('t259.1');            !!!cp ('t259.1');
# Line 5036  sub _tree_construction_main ($) { Line 5157  sub _tree_construction_main ($) {
5157              }              }
5158            } elsif ($token->{type} == END_TAG_TOKEN) {            } elsif ($token->{type} == END_TAG_TOKEN) {
5159              if ($token->{tag_name} eq 'colgroup') {              if ($token->{tag_name} eq 'colgroup') {
5160                if ($self->{open_elements}->[-1]->[1] eq 'html') {                if ($self->{open_elements}->[-1]->[1] & HTML_EL) {
5161                  !!!cp ('t264');                  !!!cp ('t264');
5162                  !!!parse-error (type => 'unmatched end tag:colgroup', token => $token);                  !!!parse-error (type => 'unmatched end tag:colgroup', token => $token);
5163                  ## Ignore the token                  ## Ignore the token
# Line 5060  sub _tree_construction_main ($) { Line 5181  sub _tree_construction_main ($) {
5181                #                #
5182              }              }
5183        } elsif ($token->{type} == END_OF_FILE_TOKEN) {        } elsif ($token->{type} == END_OF_FILE_TOKEN) {
5184          if ($self->{open_elements}->[-1]->[1] eq 'html' or          if ($self->{open_elements}->[-1]->[1] & HTML_EL and
5185              @{$self->{open_elements}} == 1) { # redundant, maybe              @{$self->{open_elements}} == 1) { # redundant, maybe
5186            !!!cp ('t270.2');            !!!cp ('t270.2');
5187            ## Stop parsing.            ## Stop parsing.
# Line 5078  sub _tree_construction_main ($) { Line 5199  sub _tree_construction_main ($) {
5199        }        }
5200    
5201            ## As if </colgroup>            ## As if </colgroup>
5202            if ($self->{open_elements}->[-1]->[1] eq 'html') {            if ($self->{open_elements}->[-1]->[1] & HTML_EL) {
5203              !!!cp ('t269');              !!!cp ('t269');
5204  ## TODO: Wrong error type?  ## TODO: Wrong error type?
5205              !!!parse-error (type => 'unmatched end tag:colgroup', token => $token);              !!!parse-error (type => 'unmatched end tag:colgroup', token => $token);
# Line 5099  sub _tree_construction_main ($) { Line 5220  sub _tree_construction_main ($) {
5220          !!!next-token;          !!!next-token;
5221          redo B;          redo B;
5222        } elsif ($token->{type} == START_TAG_TOKEN) {        } elsif ($token->{type} == START_TAG_TOKEN) {
5223              if ($token->{tag_name} eq 'option') {          if ($token->{tag_name} eq 'option') {
5224                if ($self->{open_elements}->[-1]->[1] eq 'option') {            if ($self->{open_elements}->[-1]->[1] & OPTION_EL) {
5225                  !!!cp ('t272');              !!!cp ('t272');
5226                  ## As if </option>              ## As if </option>
5227                  pop @{$self->{open_elements}};              pop @{$self->{open_elements}};
5228                } else {            } else {
5229                  !!!cp ('t273');              !!!cp ('t273');
5230                }            }
5231    
5232                !!!insert-element ($token->{tag_name}, $token->{attributes}, $token);            !!!insert-element ($token->{tag_name}, $token->{attributes}, $token);
5233                !!!next-token;            !!!next-token;
5234                redo B;            redo B;
5235              } elsif ($token->{tag_name} eq 'optgroup') {          } elsif ($token->{tag_name} eq 'optgroup') {
5236                if ($self->{open_elements}->[-1]->[1] eq 'option') {            if ($self->{open_elements}->[-1]->[1] & OPTION_EL) {
5237                  !!!cp ('t274');              !!!cp ('t274');
5238                  ## As if </option>              ## As if </option>
5239                  pop @{$self->{open_elements}};              pop @{$self->{open_elements}};
5240                } else {            } else {
5241                  !!!cp ('t275');              !!!cp ('t275');
5242                }            }
5243    
5244                if ($self->{open_elements}->[-1]->[1] eq 'optgroup') {            if ($self->{open_elements}->[-1]->[1] & OPTGROUP_EL) {
5245                  !!!cp ('t276');              !!!cp ('t276');
5246                  ## As if </optgroup>              ## As if </optgroup>
5247                  pop @{$self->{open_elements}};              pop @{$self->{open_elements}};
5248                } else {            } else {
5249                  !!!cp ('t277');              !!!cp ('t277');
5250                }            }
5251    
5252                !!!insert-element ($token->{tag_name}, $token->{attributes}, $token);            !!!insert-element ($token->{tag_name}, $token->{attributes}, $token);
5253                !!!next-token;            !!!next-token;
5254                redo B;            redo B;
5255          } elsif ($token->{tag_name} eq 'select' or          } elsif ($token->{tag_name} eq 'select' or
5256                   $token->{tag_name} eq 'input' or                   $token->{tag_name} eq 'input' or
5257                   ($self->{insertion_mode} == IN_SELECT_IN_TABLE_IM and                   ($self->{insertion_mode} == IN_SELECT_IN_TABLE_IM and
# Line 5143  sub _tree_construction_main ($) { Line 5264  sub _tree_construction_main ($) {
5264            !!!parse-error (type => 'not closed:select', token => $token);            !!!parse-error (type => 'not closed:select', token => $token);
5265            ## NOTE: As if the token were </select> (<select> case) or            ## NOTE: As if the token were </select> (<select> case) or
5266            ## as if there were </select> (otherwise).            ## as if there were </select> (otherwise).
5267                ## have an element in table scope            ## have an element in table scope
5268                my $i;            my $i;
5269                INSCOPE: for (reverse 0..$#{$self->{open_elements}}) {            INSCOPE: for (reverse 0..$#{$self->{open_elements}}) {
5270                  my $node = $self->{open_elements}->[$_];              my $node = $self->{open_elements}->[$_];
5271                  if ($node->[1] eq 'select') {              if ($node->[1] & SELECT_EL) {
5272                    !!!cp ('t278');                !!!cp ('t278');
5273                    $i = $_;                $i = $_;
5274                    last INSCOPE;                last INSCOPE;
5275                  } elsif ({              } elsif ($node->[1] & TABLE_SCOPING_EL) {
5276                            table => 1, html => 1,                !!!cp ('t279');
5277                           }->{$node->[1]}) {                last INSCOPE;
5278                    !!!cp ('t279');              }
5279                    last INSCOPE;            } # INSCOPE
5280                  }            unless (defined $i) {
5281                } # INSCOPE              !!!cp ('t280');
5282                unless (defined $i) {              !!!parse-error (type => 'unmatched end tag:select', token => $token);
5283                  !!!cp ('t280');              ## Ignore the token
5284                  !!!parse-error (type => 'unmatched end tag:select', token => $token);              !!!next-token;
5285                  ## Ignore the token              redo B;
5286                  !!!next-token;            }
                 redo B;  
               }  
5287                                
5288                !!!cp ('t281');            !!!cp ('t281');
5289                splice @{$self->{open_elements}}, $i;            splice @{$self->{open_elements}}, $i;
5290    
5291                $self->_reset_insertion_mode;            $self->_reset_insertion_mode;
5292    
5293            if ($token->{tag_name} eq 'select') {            if ($token->{tag_name} eq 'select') {
5294              !!!cp ('t281.2');              !!!cp ('t281.2');
# Line 5188  sub _tree_construction_main ($) { Line 5307  sub _tree_construction_main ($) {
5307            redo B;            redo B;
5308          }          }
5309        } elsif ($token->{type} == END_TAG_TOKEN) {        } elsif ($token->{type} == END_TAG_TOKEN) {
5310              if ($token->{tag_name} eq 'optgroup') {          if ($token->{tag_name} eq 'optgroup') {
5311                if ($self->{open_elements}->[-1]->[1] eq 'option' and            if ($self->{open_elements}->[-1]->[1] & OPTION_EL and
5312                    $self->{open_elements}->[-2]->[1] eq 'optgroup') {                $self->{open_elements}->[-2]->[1] & OPTGROUP_EL) {
5313                  !!!cp ('t283');              !!!cp ('t283');
5314                  ## As if </option>              ## As if </option>
5315                  splice @{$self->{open_elements}}, -2;              splice @{$self->{open_elements}}, -2;
5316                } elsif ($self->{open_elements}->[-1]->[1] eq 'optgroup') {            } elsif ($self->{open_elements}->[-1]->[1] & OPTGROUP_EL) {
5317                  !!!cp ('t284');              !!!cp ('t284');
5318                  pop @{$self->{open_elements}};              pop @{$self->{open_elements}};
5319                } else {            } else {
5320                  !!!cp ('t285');              !!!cp ('t285');
5321                  !!!parse-error (type => 'unmatched end tag:'.$token->{tag_name}, token => $token);              !!!parse-error (type => 'unmatched end tag:'.$token->{tag_name}, token => $token);
5322                  ## Ignore the token              ## Ignore the token
5323                }            }
5324                !!!next-token;            !!!next-token;
5325                redo B;            redo B;
5326              } elsif ($token->{tag_name} eq 'option') {          } elsif ($token->{tag_name} eq 'option') {
5327                if ($self->{open_elements}->[-1]->[1] eq 'option') {            if ($self->{open_elements}->[-1]->[1] & OPTION_EL) {
5328                  !!!cp ('t286');              !!!cp ('t286');
5329                  pop @{$self->{open_elements}};              pop @{$self->{open_elements}};
5330                } else {            } else {
5331                  !!!cp ('t287');              !!!cp ('t287');
5332                  !!!parse-error (type => 'unmatched end tag:'.$token->{tag_name}, token => $token);              !!!parse-error (type => 'unmatched end tag:'.$token->{tag_name}, token => $token);
5333                  ## Ignore the token              ## Ignore the token
5334                }            }
5335                !!!next-token;            !!!next-token;
5336                redo B;            redo B;
5337              } elsif ($token->{tag_name} eq 'select') {          } elsif ($token->{tag_name} eq 'select') {
5338                ## have an element in table scope            ## have an element in table scope
5339                my $i;            my $i;
5340                INSCOPE: for (reverse 0..$#{$self->{open_elements}}) {            INSCOPE: for (reverse 0..$#{$self->{open_elements}}) {
5341                  my $node = $self->{open_elements}->[$_];              my $node = $self->{open_elements}->[$_];
5342                  if ($node->[1] eq $token->{tag_name}) {              if ($node->[1] & SELECT_EL) {
5343                    !!!cp ('t288');                !!!cp ('t288');
5344                    $i = $_;                $i = $_;
5345                    last INSCOPE;                last INSCOPE;
5346                  } elsif ({              } elsif ($node->[1] & TABLE_SCOPING_EL) {
5347                            table => 1, html => 1,                !!!cp ('t289');
5348                           }->{$node->[1]}) {                last INSCOPE;
5349                    !!!cp ('t289');              }
5350                    last INSCOPE;            } # INSCOPE
5351                  }            unless (defined $i) {
5352                } # INSCOPE              !!!cp ('t290');
5353                unless (defined $i) {              !!!parse-error (type => 'unmatched end tag:'.$token->{tag_name}, token => $token);
5354                  !!!cp ('t290');              ## Ignore the token
5355                  !!!parse-error (type => 'unmatched end tag:'.$token->{tag_name}, token => $token);              !!!next-token;
5356                  ## Ignore the token              redo B;
5357                  !!!next-token;            }
                 redo B;  
               }  
5358                                
5359                !!!cp ('t291');            !!!cp ('t291');
5360                splice @{$self->{open_elements}}, $i;            splice @{$self->{open_elements}}, $i;
5361    
5362                $self->_reset_insertion_mode;            $self->_reset_insertion_mode;
5363    
5364                !!!next-token;            !!!next-token;
5365                redo B;            redo B;
5366          } elsif ($self->{insertion_mode} == IN_SELECT_IN_TABLE_IM and          } elsif ($self->{insertion_mode} == IN_SELECT_IN_TABLE_IM and
5367                   {                   {
5368                    caption => 1, table => 1, tbody => 1,                    caption => 1, table => 1, tbody => 1,
5369                    tfoot => 1, thead => 1, tr => 1, td => 1, th => 1,                    tfoot => 1, thead => 1, tr => 1, td => 1, th => 1,
5370                   }->{$token->{tag_name}}) {                   }->{$token->{tag_name}}) {
5371  ## TODO: The following is wrong?  ## TODO: The following is wrong?
5372                !!!parse-error (type => 'unmatched end tag:'.$token->{tag_name}, token => $token);            !!!parse-error (type => 'unmatched end tag:'.$token->{tag_name}, token => $token);
5373                                
5374                ## have an element in table scope            ## have an element in table scope
5375                my $i;            my $i;
5376                INSCOPE: for (reverse 0..$#{$self->{open_elements}}) {            INSCOPE: for (reverse 0..$#{$self->{open_elements}}) {
5377                  my $node = $self->{open_elements}->[$_];              my $node = $self->{open_elements}->[$_];
5378                  if ($node->[1] eq $token->{tag_name}) {              if ($node->[0]->manakai_local_name eq $token->{tag_name}) {
5379                    !!!cp ('t292');                !!!cp ('t292');
5380                    $i = $_;                $i = $_;
5381                    last INSCOPE;                last INSCOPE;
5382                  } elsif ({              } elsif ($node->[1] & TABLE_SCOPING_EL) {
5383                            table => 1, html => 1,                !!!cp ('t293');
5384                           }->{$node->[1]}) {                last INSCOPE;
5385                    !!!cp ('t293');              }
5386                    last INSCOPE;            } # INSCOPE
5387                  }            unless (defined $i) {
5388                } # INSCOPE              !!!cp ('t294');
5389                unless (defined $i) {              ## Ignore the token
5390                  !!!cp ('t294');              !!!next-token;
5391                  ## Ignore the token              redo B;
5392                  !!!next-token;            }
                 redo B;  
               }  
5393                                
5394                ## As if </select>            ## As if </select>
5395                ## have an element in table scope            ## have an element in table scope
5396                undef $i;            undef $i;
5397                INSCOPE: for (reverse 0..$#{$self->{open_elements}}) {            INSCOPE: for (reverse 0..$#{$self->{open_elements}}) {
5398                  my $node = $self->{open_elements}->[$_];              my $node = $self->{open_elements}->[$_];
5399                  if ($node->[1] eq 'select') {              if ($node->[1] & SELECT_EL) {
5400                    !!!cp ('t295');                !!!cp ('t295');
5401                    $i = $_;                $i = $_;
5402                    last INSCOPE;                last INSCOPE;
5403                  } elsif ({              } elsif ($node->[1] & TABLE_SCOPING_EL) {
                           table => 1, html => 1,  
                          }->{$node->[1]}) {  
5404  ## ISSUE: Can this state be reached?  ## ISSUE: Can this state be reached?
5405                    !!!cp ('t296');                !!!cp ('t296');
5406                    last INSCOPE;                last INSCOPE;
5407                  }              }
5408                } # INSCOPE            } # INSCOPE
5409                unless (defined $i) {            unless (defined $i) {
5410                  !!!cp ('t297');              !!!cp ('t297');
5411  ## TODO: The following error type is correct?  ## TODO: The following error type is correct?
5412                  !!!parse-error (type => 'unmatched end tag:select', token => $token);              !!!parse-error (type => 'unmatched end tag:select', token => $token);
5413                  ## Ignore the </select> token              ## Ignore the </select> token
5414                  !!!next-token; ## TODO: ok?              !!!next-token; ## TODO: ok?
5415                  redo B;              redo B;
5416                }            }
5417                                
5418                !!!cp ('t298');            !!!cp ('t298');
5419                splice @{$self->{open_elements}}, $i;            splice @{$self->{open_elements}}, $i;
5420    
5421                $self->_reset_insertion_mode;            $self->_reset_insertion_mode;
5422    
5423                ## reprocess            ## reprocess
5424                redo B;            redo B;
5425          } else {          } else {
5426            !!!cp ('t299');            !!!cp ('t299');
5427            !!!parse-error (type => 'in select:/'.$token->{tag_name}, token => $token);            !!!parse-error (type => 'in select:/'.$token->{tag_name}, token => $token);
# Line 5317  sub _tree_construction_main ($) { Line 5430  sub _tree_construction_main ($) {
5430            redo B;            redo B;
5431          }          }
5432        } elsif ($token->{type} == END_OF_FILE_TOKEN) {        } elsif ($token->{type} == END_OF_FILE_TOKEN) {
5433          unless ($self->{open_elements}->[-1]->[1] eq 'html' and          unless ($self->{open_elements}->[-1]->[1] & HTML_EL and
5434                  @{$self->{open_elements}} == 1) { # redundant, maybe                  @{$self->{open_elements}} == 1) { # redundant, maybe
5435            !!!cp ('t299.1');            !!!cp ('t299.1');
5436            !!!parse-error (type => 'in body:#eof', token => $token);            !!!parse-error (type => 'in body:#eof', token => $token);
# Line 5511  sub _tree_construction_main ($) { Line 5624  sub _tree_construction_main ($) {
5624    
5625          if ($token->{tag_name} eq 'frameset' and          if ($token->{tag_name} eq 'frameset' and
5626              $self->{insertion_mode} == IN_FRAMESET_IM) {              $self->{insertion_mode} == IN_FRAMESET_IM) {
5627            if ($self->{open_elements}->[-1]->[1] eq 'html' and            if ($self->{open_elements}->[-1]->[1] & HTML_EL and
5628                @{$self->{open_elements}} == 1) {                @{$self->{open_elements}} == 1) {
5629              !!!cp ('t325');              !!!cp ('t325');
5630              !!!parse-error (type => 'unmatched end tag:'.$token->{tag_name}, token => $token);              !!!parse-error (type => 'unmatched end tag:'.$token->{tag_name}, token => $token);
# Line 5524  sub _tree_construction_main ($) { Line 5637  sub _tree_construction_main ($) {
5637            }            }
5638    
5639            if (not defined $self->{inner_html_node} and            if (not defined $self->{inner_html_node} and
5640                $self->{open_elements}->[-1]->[1] ne 'frameset') {                not ($self->{open_elements}->[-1]->[1] & FRAMESET_EL)) {
5641              !!!cp ('t327');              !!!cp ('t327');
5642              $self->{insertion_mode} = AFTER_FRAMESET_IM;              $self->{insertion_mode} = AFTER_FRAMESET_IM;
5643            } else {            } else {
# Line 5550  sub _tree_construction_main ($) { Line 5663  sub _tree_construction_main ($) {
5663            redo B;            redo B;
5664          }          }
5665        } elsif ($token->{type} == END_OF_FILE_TOKEN) {        } elsif ($token->{type} == END_OF_FILE_TOKEN) {
5666          unless ($self->{open_elements}->[-1]->[1] eq 'html' and          unless ($self->{open_elements}->[-1]->[1] & HTML_EL and
5667                  @{$self->{open_elements}} == 1) { # redundant, maybe                  @{$self->{open_elements}} == 1) { # redundant, maybe
5668            !!!cp ('t331.1');            !!!cp ('t331.1');
5669            !!!parse-error (type => 'in body:#eof', token => $token);            !!!parse-error (type => 'in body:#eof', token => $token);
# Line 5649  sub _tree_construction_main ($) { Line 5762  sub _tree_construction_main ($) {
5762          !!!parse-error (type => 'in body:body', token => $token);          !!!parse-error (type => 'in body:body', token => $token);
5763                                
5764          if (@{$self->{open_elements}} == 1 or          if (@{$self->{open_elements}} == 1 or
5765              $self->{open_elements}->[1]->[1] ne 'body') {              not ($self->{open_elements}->[1]->[1] & BODY_EL)) {
5766            !!!cp ('t342');            !!!cp ('t342');
5767            ## Ignore the token            ## Ignore the token
5768          } else {          } else {
# Line 5685  sub _tree_construction_main ($) { Line 5798  sub _tree_construction_main ($) {
5798    
5799          ## has a p element in scope          ## has a p element in scope
5800          INSCOPE: for (reverse @{$self->{open_elements}}) {          INSCOPE: for (reverse @{$self->{open_elements}}) {
5801            if ($_->[1] eq 'p') {            if ($_->[1] & P_EL) {
5802              !!!cp ('t344');              !!!cp ('t344');
5803              !!!back-token;              !!!back-token;
5804              $token = {type => END_TAG_TOKEN, tag_name => 'p',              $token = {type => END_TAG_TOKEN, tag_name => 'p',
5805                        line => $token->{line}, column => $token->{column}};                        line => $token->{line}, column => $token->{column}};
5806              redo B;              redo B;
5807            } elsif ({            } elsif ($_->[1] & SCOPING_EL) {
                     applet => 1, table => 1, caption => 1, td => 1, th => 1,  
                     button => 1, marquee => 1, object => 1, html => 1,  
                    }->{$_->[1]}) {  
5808              !!!cp ('t345');              !!!cp ('t345');
5809              last INSCOPE;              last INSCOPE;
5810            }            }
# Line 5739  sub _tree_construction_main ($) { Line 5849  sub _tree_construction_main ($) {
5849        } elsif ({li => 1, dt => 1, dd => 1}->{$token->{tag_name}}) {        } elsif ({li => 1, dt => 1, dd => 1}->{$token->{tag_name}}) {
5850          ## has a p element in scope          ## has a p element in scope
5851          INSCOPE: for (reverse @{$self->{open_elements}}) {          INSCOPE: for (reverse @{$self->{open_elements}}) {
5852            if ($_->[1] eq 'p') {            if ($_->[1] & P_EL) {
5853              !!!cp ('t353');              !!!cp ('t353');
5854              !!!back-token;              !!!back-token;
5855              $token = {type => END_TAG_TOKEN, tag_name => 'p',              $token = {type => END_TAG_TOKEN, tag_name => 'p',
5856                        line => $token->{line}, column => $token->{column}};                        line => $token->{line}, column => $token->{column}};
5857              redo B;              redo B;
5858            } elsif ({            } elsif ($_->[1] & SCOPING_EL) {
                     applet => 1, table => 1, caption => 1, td => 1, th => 1,  
                     button => 1, marquee => 1, object => 1, html => 1,  
                    }->{$_->[1]}) {  
5859              !!!cp ('t354');              !!!cp ('t354');
5860              last INSCOPE;              last INSCOPE;
5861            }            }
# Line 5762  sub _tree_construction_main ($) { Line 5869  sub _tree_construction_main ($) {
5869                            dd => {dt => 1, dd => 1}}->{$token->{tag_name}};                            dd => {dt => 1, dd => 1}}->{$token->{tag_name}};
5870          LI: {          LI: {
5871            ## Step 2            ## Step 2
5872            if ($li_or_dtdd->{$node->[1]}) {            if ($li_or_dtdd->{$node->[0]->manakai_local_name}) {
5873              if ($i != -1) {              if ($i != -1) {
5874                !!!cp ('t355');                !!!cp ('t355');
5875                !!!parse-error (type => 'not closed',                !!!parse-error (type => 'not closed',
# Line 5779  sub _tree_construction_main ($) { Line 5886  sub _tree_construction_main ($) {
5886            }            }
5887                        
5888            ## Step 3            ## Step 3
5889            if (not $formatting_category->{$node->[1]} and            if (not ($node->[1] & FORMATTING_EL) and
5890                #not $phrasing_category->{$node->[1]} and                #not $phrasing_category->{$node->[1]} and
5891                ($special_category->{$node->[1]} or                ($node->[1] & SPECIAL_EL or
5892                 $scoping_category->{$node->[1]}) and                 $node->[1] & SCOPING_EL) and
5893                $node->[1] ne 'address' and $node->[1] ne 'div') {                not ($node->[1] & ADDRESS_EL) and
5894                  not ($node->[1] & DIV_EL)) {
5895              !!!cp ('t358');              !!!cp ('t358');
5896              last LI;              last LI;
5897            }            }
# Line 5801  sub _tree_construction_main ($) { Line 5909  sub _tree_construction_main ($) {
5909        } elsif ($token->{tag_name} eq 'plaintext') {        } elsif ($token->{tag_name} eq 'plaintext') {
5910          ## has a p element in scope          ## has a p element in scope
5911          INSCOPE: for (reverse @{$self->{open_elements}}) {          INSCOPE: for (reverse @{$self->{open_elements}}) {
5912            if ($_->[1] eq 'p') {            if ($_->[1] & P_EL) {
5913              !!!cp ('t367');              !!!cp ('t367');
5914              !!!back-token;              !!!back-token;
5915              $token = {type => END_TAG_TOKEN, tag_name => 'p',              $token = {type => END_TAG_TOKEN, tag_name => 'p',
5916                        line => $token->{line}, column => $token->{column}};                        line => $token->{line}, column => $token->{column}};
5917              redo B;              redo B;
5918            } elsif ({            } elsif ($_->[1] & SCOPING_EL) {
                     applet => 1, table => 1, caption => 1, td => 1, th => 1,  
                     button => 1, marquee => 1, object => 1, html => 1,  
                    }->{$_->[1]}) {  
5919              !!!cp ('t368');              !!!cp ('t368');
5920              last INSCOPE;              last INSCOPE;
5921            }            }
# Line 5825  sub _tree_construction_main ($) { Line 5930  sub _tree_construction_main ($) {
5930        } elsif ($token->{tag_name} eq 'a') {        } elsif ($token->{tag_name} eq 'a') {
5931          AFE: for my $i (reverse 0..$#$active_formatting_elements) {          AFE: for my $i (reverse 0..$#$active_formatting_elements) {
5932            my $node = $active_formatting_elements->[$i];            my $node = $active_formatting_elements->[$i];
5933            if ($node->[1] eq 'a') {            if ($node->[1] & A_EL) {
5934              !!!cp ('t371');              !!!cp ('t371');
5935              !!!parse-error (type => 'in a:a', token => $token);              !!!parse-error (type => 'in a:a', token => $token);
5936                            
# Line 5868  sub _tree_construction_main ($) { Line 5973  sub _tree_construction_main ($) {
5973          ## has a |nobr| element in scope          ## has a |nobr| element in scope
5974          INSCOPE: for (reverse 0..$#{$self->{open_elements}}) {          INSCOPE: for (reverse 0..$#{$self->{open_elements}}) {
5975            my $node = $self->{open_elements}->[$_];            my $node = $self->{open_elements}->[$_];
5976            if ($node->[1] eq 'nobr') {            if ($node->[1] & NOBR_EL) {
5977              !!!cp ('t376');              !!!cp ('t376');
5978              !!!parse-error (type => 'in nobr:nobr', token => $token);              !!!parse-error (type => 'in nobr:nobr', token => $token);
5979              !!!back-token;              !!!back-token;
5980              $token = {type => END_TAG_TOKEN, tag_name => 'nobr',              $token = {type => END_TAG_TOKEN, tag_name => 'nobr',
5981                        line => $token->{line}, column => $token->{column}};                        line => $token->{line}, column => $token->{column}};
5982              redo B;              redo B;
5983            } elsif ({            } elsif ($node->[1] & SCOPING_EL) {
                     applet => 1, table => 1, caption => 1, td => 1, th => 1,  
                     button => 1, marquee => 1, object => 1, html => 1,  
                    }->{$node->[1]}) {  
5984              !!!cp ('t377');              !!!cp ('t377');
5985              last INSCOPE;              last INSCOPE;
5986            }            }
# Line 5893  sub _tree_construction_main ($) { Line 5995  sub _tree_construction_main ($) {
5995          ## has a button element in scope          ## has a button element in scope
5996          INSCOPE: for (reverse 0..$#{$self->{open_elements}}) {          INSCOPE: for (reverse 0..$#{$self->{open_elements}}) {
5997            my $node = $self->{open_elements}->[$_];            my $node = $self->{open_elements}->[$_];
5998            if ($node->[1] eq 'button') {            if ($node->[1] & BUTTON_EL) {
5999              !!!cp ('t378');              !!!cp ('t378');
6000              !!!parse-error (type => 'in button:button', token => $token);              !!!parse-error (type => 'in button:button', token => $token);
6001              !!!back-token;              !!!back-token;
6002              $token = {type => END_TAG_TOKEN, tag_name => 'button',              $token = {type => END_TAG_TOKEN, tag_name => 'button',
6003                        line => $token->{line}, column => $token->{column}};                        line => $token->{line}, column => $token->{column}};
6004              redo B;              redo B;
6005            } elsif ({            } elsif ($node->[1] & SCOPING_EL) {
                     applet => 1, table => 1, caption => 1, td => 1, th => 1,  
                     button => 1, marquee => 1, object => 1, html => 1,  
                    }->{$node->[1]}) {  
6006              !!!cp ('t379');              !!!cp ('t379');
6007              last INSCOPE;              last INSCOPE;
6008            }            }
# Line 6112  sub _tree_construction_main ($) { Line 6211  sub _tree_construction_main ($) {
6211          my $i;          my $i;
6212          INSCOPE: {          INSCOPE: {
6213            for (reverse @{$self->{open_elements}}) {            for (reverse @{$self->{open_elements}}) {
6214              if ($_->[1] eq 'body') {              if ($_->[1] & BODY_EL) {
6215                !!!cp ('t405');                !!!cp ('t405');
6216                $i = $_;                $i = $_;
6217                last INSCOPE;                last INSCOPE;
6218              } elsif ({              } elsif ($_->[1] & SCOPING_EL) {
                       applet => 1, table => 1, caption => 1, td => 1, th => 1,  
                       button => 1, marquee => 1, object => 1, html => 1,  
                      }->{$_->[1]}) {  
6219                !!!cp ('t405.1');                !!!cp ('t405.1');
6220                last;                last;
6221              }              }
# Line 6133  sub _tree_construction_main ($) { Line 6229  sub _tree_construction_main ($) {
6229          } # INSCOPE          } # INSCOPE
6230    
6231          for (@{$self->{open_elements}}) {          for (@{$self->{open_elements}}) {
6232            unless ({            unless ($_->[1] & ALL_END_TAG_OPTIONAL_EL) {
                    dd => 1, dt => 1, li => 1, p => 1, td => 1,  
                    th => 1, tr => 1, body => 1, html => 1,  
                    tbody => 1, tfoot => 1, thead => 1,  
                   }->{$_->[1]}) {  
6233              !!!cp ('t403');              !!!cp ('t403');
6234              !!!parse-error (type => 'not closed',              !!!parse-error (type => 'not closed',
6235                              value => $_->[0]->manakai_local_name,                              value => $_->[0]->manakai_local_name,
# Line 6154  sub _tree_construction_main ($) { Line 6246  sub _tree_construction_main ($) {
6246        } elsif ($token->{tag_name} eq 'html') {        } elsif ($token->{tag_name} eq 'html') {
6247          ## TODO: Update this code.  It seems that the code below is not          ## TODO: Update this code.  It seems that the code below is not
6248          ## up-to-date, though it has same effect as speced.          ## up-to-date, though it has same effect as speced.
6249          if (@{$self->{open_elements}} > 1 and $self->{open_elements}->[1]->[1] eq 'body') {          if (@{$self->{open_elements}} > 1 and
6250                $self->{open_elements}->[1]->[1] & BODY_EL) {
6251            ## ISSUE: There is an issue in the spec.            ## ISSUE: There is an issue in the spec.
6252            if ($self->{open_elements}->[-1]->[1] ne 'body') {            unless ($self->{open_elements}->[-1]->[1] & BODY_EL) {
6253              !!!cp ('t406');              !!!cp ('t406');
6254              !!!parse-error (type => 'not closed',              !!!parse-error (type => 'not closed',
6255                              value => $self->{open_elements}->[1]->[0]                              value => $self->{open_elements}->[1]->[0]
# Line 6186  sub _tree_construction_main ($) { Line 6279  sub _tree_construction_main ($) {
6279          my $i;          my $i;
6280          INSCOPE: for (reverse 0..$#{$self->{open_elements}}) {          INSCOPE: for (reverse 0..$#{$self->{open_elements}}) {
6281            my $node = $self->{open_elements}->[$_];            my $node = $self->{open_elements}->[$_];
6282            if ($node->[1] eq $token->{tag_name}) {            if ($node->[0]->manakai_local_name eq $token->{tag_name}) {
6283              !!!cp ('t410');              !!!cp ('t410');
6284              $i = $_;              $i = $_;
6285              last INSCOPE;              last INSCOPE;
6286            } elsif ({            } elsif ($node->[1] & SCOPING_EL) {
                     applet => 1, table => 1, caption => 1, td => 1, th => 1,  
                     button => 1, marquee => 1, object => 1, html => 1,  
                    }->{$node->[1]}) {  
6287              !!!cp ('t411');              !!!cp ('t411');
6288              last INSCOPE;              last INSCOPE;
6289            }            }
# Line 6209  sub _tree_construction_main ($) { Line 6299  sub _tree_construction_main ($) {
6299                    dt => ($token->{tag_name} ne 'dt'),                    dt => ($token->{tag_name} ne 'dt'),
6300                    li => ($token->{tag_name} ne 'li'),                    li => ($token->{tag_name} ne 'li'),
6301                    p => 1,                    p => 1,
6302                   }->{$self->{open_elements}->[-1]->[1]}) {                   }->{$self->{open_elements}->[-1]->[0]->manakai_local_name}) {
6303              !!!cp ('t409');              !!!cp ('t409');
6304              pop @{$self->{open_elements}};              pop @{$self->{open_elements}};
6305            }            }
6306    
6307            ## Step 2.            ## Step 2.
6308            if ($self->{open_elements}->[-1]->[1] ne $token->{tag_name}) {            if ($self->{open_elements}->[-1]->[0]->manakai_local_name
6309                      ne $token->{tag_name}) {
6310              !!!cp ('t412');              !!!cp ('t412');
6311              !!!parse-error (type => 'not closed',              !!!parse-error (type => 'not closed',
6312                              value => $self->{open_elements}->[-1]->[0]                              value => $self->{open_elements}->[-1]->[0]
# Line 6243  sub _tree_construction_main ($) { Line 6334  sub _tree_construction_main ($) {
6334          my $i;          my $i;
6335          INSCOPE: for (reverse 0..$#{$self->{open_elements}}) {          INSCOPE: for (reverse 0..$#{$self->{open_elements}}) {
6336            my $node = $self->{open_elements}->[$_];            my $node = $self->{open_elements}->[$_];
6337            if ($node->[1] eq $token->{tag_name}) {            if ($node->[1] & FORM_EL) {
6338              !!!cp ('t418');              !!!cp ('t418');
6339              $i = $_;              $i = $_;
6340              last INSCOPE;              last INSCOPE;
6341            } elsif ({            } elsif ($node->[1] & SCOPING_EL) {
                     applet => 1, table => 1, caption => 1, td => 1, th => 1,  
                     button => 1, marquee => 1, object => 1, html => 1,  
                    }->{$node->[1]}) {  
6342              !!!cp ('t419');              !!!cp ('t419');
6343              last INSCOPE;              last INSCOPE;
6344            }            }
# Line 6261  sub _tree_construction_main ($) { Line 6349  sub _tree_construction_main ($) {
6349            !!!parse-error (type => 'unmatched end tag:'.$token->{tag_name}, token => $token);            !!!parse-error (type => 'unmatched end tag:'.$token->{tag_name}, token => $token);
6350          } else {          } else {
6351            ## Step 1. generate implied end tags            ## Step 1. generate implied end tags
6352            while ({            while ($self->{open_elements}->[-1]->[1] & END_TAG_OPTIONAL_EL) {
                   dd => 1, dt => 1, li => 1, p => 1,  
                  }->{$self->{open_elements}->[-1]->[1]}) {  
6353              !!!cp ('t417');              !!!cp ('t417');
6354              pop @{$self->{open_elements}};              pop @{$self->{open_elements}};
6355            }            }
6356                        
6357            ## Step 2.            ## Step 2.
6358            if ($self->{open_elements}->[-1]->[1] ne $token->{tag_name}) {            if ($self->{open_elements}->[-1]->[0]->manakai_local_name
6359                      ne $token->{tag_name}) {
6360              !!!cp ('t417.1');              !!!cp ('t417.1');
6361              !!!parse-error (type => 'not closed',              !!!parse-error (type => 'not closed',
6362                              value => $self->{open_elements}->[-1]->[0]                              value => $self->{open_elements}->[-1]->[0]
# Line 6292  sub _tree_construction_main ($) { Line 6379  sub _tree_construction_main ($) {
6379          my $i;          my $i;
6380          INSCOPE: for (reverse 0..$#{$self->{open_elements}}) {          INSCOPE: for (reverse 0..$#{$self->{open_elements}}) {
6381            my $node = $self->{open_elements}->[$_];            my $node = $self->{open_elements}->[$_];
6382            if ({            if ($node->[1] & HEADING_EL) {
                h1 => 1, h2 => 1, h3 => 1, h4 => 1, h5 => 1, h6 => 1,  
               }->{$node->[1]}) {  
6383              !!!cp ('t423');              !!!cp ('t423');
6384              $i = $_;              $i = $_;
6385              last INSCOPE;              last INSCOPE;
6386            } elsif ({            } elsif ($node->[1] & SCOPING_EL) {
                     applet => 1, table => 1, caption => 1, td => 1, th => 1,  
                     button => 1, marquee => 1, object => 1, html => 1,  
                    }->{$node->[1]}) {  
6387              !!!cp ('t424');              !!!cp ('t424');
6388              last INSCOPE;              last INSCOPE;
6389            }            }
# Line 6312  sub _tree_construction_main ($) { Line 6394  sub _tree_construction_main ($) {
6394            !!!parse-error (type => 'unmatched end tag:'.$token->{tag_name}, token => $token);            !!!parse-error (type => 'unmatched end tag:'.$token->{tag_name}, token => $token);
6395          } else {          } else {
6396            ## Step 1. generate implied end tags            ## Step 1. generate implied end tags
6397            while ({            while ($self->{open_elements}->[-1]->[1] & END_TAG_OPTIONAL_EL) {
                   dd => 1, dt => 1, li => 1, p => 1,  
                  }->{$self->{open_elements}->[-1]->[1]}) {  
6398              !!!cp ('t422');              !!!cp ('t422');
6399              pop @{$self->{open_elements}};              pop @{$self->{open_elements}};
6400            }            }
6401                        
6402            ## Step 2.            ## Step 2.
6403            if ($self->{open_elements}->[-1]->[1] ne $token->{tag_name}) {            if ($self->{open_elements}->[-1]->[0]->manakai_local_name
6404                      ne $token->{tag_name}) {
6405              !!!cp ('t425');              !!!cp ('t425');
6406              !!!parse-error (type => 'unmatched end tag:'.$token->{tag_name}, token => $token);              !!!parse-error (type => 'unmatched end tag:'.$token->{tag_name}, token => $token);
6407            } else {            } else {
# Line 6338  sub _tree_construction_main ($) { Line 6419  sub _tree_construction_main ($) {
6419          my $i;          my $i;
6420          INSCOPE: for (reverse 0..$#{$self->{open_elements}}) {          INSCOPE: for (reverse 0..$#{$self->{open_elements}}) {
6421            my $node = $self->{open_elements}->[$_];            my $node = $self->{open_elements}->[$_];
6422            if ($node->[1] eq $token->{tag_name}) {            if ($node->[1] & P_EL) {
6423              !!!cp ('t410.1');              !!!cp ('t410.1');
6424              $i = $_;              $i = $_;
6425              last INSCOPE;              last INSCOPE;
6426            } elsif ({            } elsif ($node->[1] & SCOPING_EL) {
                     applet => 1, table => 1, caption => 1, td => 1, th => 1,  
                     button => 1, marquee => 1, object => 1, html => 1,  
                    }->{$node->[1]}) {  
6427              !!!cp ('t411.1');              !!!cp ('t411.1');
6428              last INSCOPE;              last INSCOPE;
6429            }            }
6430          } # INSCOPE          } # INSCOPE
6431    
6432          if (defined $i) {          if (defined $i) {
6433            if ($self->{open_elements}->[-1]->[1] ne $token->{tag_name}) {            if ($self->{open_elements}->[-1]->[0]->manakai_local_name
6434                      ne $token->{tag_name}) {
6435              !!!cp ('t412.1');              !!!cp ('t412.1');
6436              !!!parse-error (type => 'not closed',              !!!parse-error (type => 'not closed',
6437                              value => $self->{open_elements}->[-1]->[0]                              value => $self->{open_elements}->[-1]->[0]
# Line 6427  sub _tree_construction_main ($) { Line 6506  sub _tree_construction_main ($) {
6506    
6507          ## Step 2          ## Step 2
6508          S2: {          S2: {
6509            if ($node->[1] eq $token->{tag_name}) {            if ($node->[0]->manakai_local_name eq $token->{tag_name}) {
6510              ## Step 1              ## Step 1
6511              ## generate implied end tags              ## generate implied end tags
6512              while ({              while ($self->{open_elements}->[-1]->[1] & END_TAG_OPTIONAL_EL) {
                     dd => 1, dt => 1, li => 1, p => 1,  
                    }->{$self->{open_elements}->[-1]->[1]}) {  
6513                !!!cp ('t430');                !!!cp ('t430');
6514                ## ISSUE: Can this case be reached?                ## ISSUE: Can this case be reached?
6515                pop @{$self->{open_elements}};                pop @{$self->{open_elements}};
6516              }              }
6517                    
6518              ## Step 2              ## Step 2
6519              if ($token->{tag_name} ne $self->{open_elements}->[-1]->[1]) {              if ($self->{open_elements}->[-1]->[0]->manakai_local_name
6520                        ne $token->{tag_name}) {
6521                !!!cp ('t431');                !!!cp ('t431');
6522                ## NOTE: <x><y></x>                ## NOTE: <x><y></x>
6523                !!!parse-error (type => 'not closed',                !!!parse-error (type => 'not closed',
# Line 6457  sub _tree_construction_main ($) { Line 6535  sub _tree_construction_main ($) {
6535              last S2;              last S2;
6536            } else {            } else {
6537              ## Step 3              ## Step 3
6538              if (not $formatting_category->{$node->[1]} and              if (not ($node->[1] & FORMATTING_EL) and
6539                  #not $phrasing_category->{$node->[1]} and                  #not $phrasing_category->{$node->[1]} and
6540                  ($special_category->{$node->[1]} or                  ($node->[1] & SPECIAL_EL or
6541                   $scoping_category->{$node->[1]})) {                   $node->[1] & SCOPING_EL)) {
6542                !!!cp ('t433');                !!!cp ('t433');
6543                !!!parse-error (type => 'unmatched end tag:'.$token->{tag_name}, token => $token);                !!!parse-error (type => 'unmatched end tag:'.$token->{tag_name}, token => $token);
6544                ## Ignore the token                ## Ignore the token
# Line 6598  sub set_inner_html ($$$) { Line 6676  sub set_inner_html ($$$) {
6676          unless defined $p->{content_model};          unless defined $p->{content_model};
6677          ## ISSUE: What is "the name of the element"? local name?          ## ISSUE: What is "the name of the element"? local name?
6678    
6679      $p->{inner_html_node} = [$node, $node_ln];      $p->{inner_html_node} = [$node, $el_category->{$node_ln}];
6680          ## TODO: Foreign element OK?
6681    
6682      ## Step 3      ## Step 3
6683      my $root = $doc->create_element_ns      my $root = $doc->create_element_ns
# Line 6608  sub set_inner_html ($$$) { Line 6687  sub set_inner_html ($$$) {
6687      $doc->append_child ($root);      $doc->append_child ($root);
6688    
6689      ## Step 5 # MUST      ## Step 5 # MUST
6690      push @{$p->{open_elements}}, [$root, 'html'];      push @{$p->{open_elements}}, [$root, $el_category->{html}];
6691    
6692      undef $p->{head_element};      undef $p->{head_element};
6693    

Legend:
Removed from v.1.122  
changed lines
  Added in v.1.123

admin@suikawiki.org
ViewVC Help
Powered by ViewVC 1.1.24