/[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.113 by wakaba, Sun Mar 16 07:07:59 2008 UTC revision 1.121 by wakaba, Thu Mar 20 08:04:58 2008 UTC
# Line 108  sub parse_byte_string ($$$$;$) { Line 108  sub parse_byte_string ($$$$;$) {
108    $self->{change_encoding} = sub {    $self->{change_encoding} = sub {
109      my $self = shift;      my $self = shift;
110      my $charset = lc shift;      my $charset = lc shift;
111        my $token = shift;
112      ## TODO: if $charset is supported      ## TODO: if $charset is supported
113      ## TODO: normalize charset name      ## TODO: normalize charset name
114    
# Line 126  sub parse_byte_string ($$$$;$) { Line 127  sub parse_byte_string ($$$$;$) {
127      }      }
128    
129      !!!parse-error (type => 'charset label detected:'.$self->{input_encoding}.      !!!parse-error (type => 'charset label detected:'.$self->{input_encoding}.
130          ':'.$charset, level => 'w');          ':'.$charset, level => 'w', token => $token);
131    
132      ## Step 3      ## Step 3
133      # if (can) {      # if (can) {
# Line 465  sub _get_next_token ($) { Line 466  sub _get_next_token ($) {
466        # Anything else        # Anything else
467        my $token = {type => CHARACTER_TOKEN,        my $token = {type => CHARACTER_TOKEN,
468                     data => chr $self->{next_char},                     data => chr $self->{next_char},
469                     line => $self->{line}, column => $self->{column}};                     line => $self->{line}, column => $self->{column},
470                      };
471        ## Stay in the data state        ## Stay in the data state
472        !!!next-input-character;        !!!next-input-character;
473    
# Line 485  sub _get_next_token ($) { Line 487  sub _get_next_token ($) {
487        unless (defined $token) {        unless (defined $token) {
488          !!!cp (13);          !!!cp (13);
489          !!!emit ({type => CHARACTER_TOKEN, data => '&',          !!!emit ({type => CHARACTER_TOKEN, data => '&',
490                    line => $l, column => $c});                    line => $l, column => $c,
491                     });
492        } else {        } else {
493          !!!cp (14);          !!!cp (14);
494          !!!emit ($token);          !!!emit ($token);
# Line 506  sub _get_next_token ($) { Line 509  sub _get_next_token ($) {
509    
510            !!!emit ({type => CHARACTER_TOKEN, data => '<',            !!!emit ({type => CHARACTER_TOKEN, data => '<',
511                      line => $self->{line_prev},                      line => $self->{line_prev},
512                      column => $self->{column_prev}});                      column => $self->{column_prev},
513                       });
514    
515            redo A;            redo A;
516          }          }
# Line 544  sub _get_next_token ($) { Line 548  sub _get_next_token ($) {
548            redo A;            redo A;
549          } elsif ($self->{next_char} == 0x003E) { # >          } elsif ($self->{next_char} == 0x003E) { # >
550            !!!cp (21);            !!!cp (21);
551            !!!parse-error (type => 'empty start tag');            !!!parse-error (type => 'empty start tag',
552                              line => $self->{line_prev},
553                              column => $self->{column_prev});
554            $self->{state} = DATA_STATE;            $self->{state} = DATA_STATE;
555            !!!next-input-character;            !!!next-input-character;
556    
557            !!!emit ({type => CHARACTER_TOKEN, data => '<>',            !!!emit ({type => CHARACTER_TOKEN, data => '<>',
558                      line => $self->{line_prev},                      line => $self->{line_prev},
559                      column => $self->{column_prev}});                      column => $self->{column_prev},
560                       });
561    
562            redo A;            redo A;
563          } elsif ($self->{next_char} == 0x003F) { # ?          } elsif ($self->{next_char} == 0x003F) { # ?
564            !!!cp (22);            !!!cp (22);
565            !!!parse-error (type => 'pio');            !!!parse-error (type => 'pio',
566                              line => $self->{line_prev},
567                              column => $self->{column_prev});
568            $self->{state} = BOGUS_COMMENT_STATE;            $self->{state} = BOGUS_COMMENT_STATE;
569            $self->{current_token} = {type => COMMENT_TOKEN, data => '',            $self->{current_token} = {type => COMMENT_TOKEN, data => '',
570                                      line => $self->{line_prev},                                      line => $self->{line_prev},
571                                      column => $self->{column_prev}};                                      column => $self->{column_prev},
572                                       };
573            ## $self->{next_char} is intentionally left as is            ## $self->{next_char} is intentionally left as is
574            redo A;            redo A;
575          } else {          } else {
# Line 570  sub _get_next_token ($) { Line 580  sub _get_next_token ($) {
580    
581            !!!emit ({type => CHARACTER_TOKEN, data => '<',            !!!emit ({type => CHARACTER_TOKEN, data => '<',
582                      line => $self->{line_prev},                      line => $self->{line_prev},
583                      column => $self->{column_prev}});                      column => $self->{column_prev},
584                       });
585    
586            redo A;            redo A;
587          }          }
# Line 599  sub _get_next_token ($) { Line 610  sub _get_next_token ($) {
610                $self->{state} = DATA_STATE;                $self->{state} = DATA_STATE;
611    
612                !!!emit ({type => CHARACTER_TOKEN, data => '</',                !!!emit ({type => CHARACTER_TOKEN, data => '</',
613                          line => $l, column => $c});                          line => $l, column => $c,
614                           });
615        
616                redo A;                redo A;
617              }              }
# Line 619  sub _get_next_token ($) { Line 631  sub _get_next_token ($) {
631              !!!back-next-input-character (@next_char);              !!!back-next-input-character (@next_char);
632              $self->{state} = DATA_STATE;              $self->{state} = DATA_STATE;
633              !!!emit ({type => CHARACTER_TOKEN, data => '</',              !!!emit ({type => CHARACTER_TOKEN, data => '</',
634                        line => $l, column => $c});                        line => $l, column => $c,
635                         });
636              redo A;              redo A;
637            } else {            } else {
638              !!!cp (27);              !!!cp (27);
# Line 633  sub _get_next_token ($) { Line 646  sub _get_next_token ($) {
646            # next-input-character is already done            # next-input-character is already done
647            $self->{state} = DATA_STATE;            $self->{state} = DATA_STATE;
648            !!!emit ({type => CHARACTER_TOKEN, data => '</',            !!!emit ({type => CHARACTER_TOKEN, data => '</',
649                      line => $l, column => $c});                      line => $l, column => $c,
650                       });
651            redo A;            redo A;
652          }          }
653        }        }
# Line 659  sub _get_next_token ($) { Line 673  sub _get_next_token ($) {
673          redo A;          redo A;
674        } elsif ($self->{next_char} == 0x003E) { # >        } elsif ($self->{next_char} == 0x003E) { # >
675          !!!cp (31);          !!!cp (31);
676          !!!parse-error (type => 'empty end tag');          !!!parse-error (type => 'empty end tag',
677                            line => $self->{line_prev}, ## "<" in "</>"
678                            column => $self->{column_prev} - 1);
679          $self->{state} = DATA_STATE;          $self->{state} = DATA_STATE;
680          !!!next-input-character;          !!!next-input-character;
681          redo A;          redo A;
# Line 670  sub _get_next_token ($) { Line 686  sub _get_next_token ($) {
686          # reconsume          # reconsume
687    
688          !!!emit ({type => CHARACTER_TOKEN, data => '</',          !!!emit ({type => CHARACTER_TOKEN, data => '</',
689                    line => $l, column => $c});                    line => $l, column => $c,
690                     });
691    
692          redo A;          redo A;
693        } else {        } else {
# Line 679  sub _get_next_token ($) { Line 696  sub _get_next_token ($) {
696          $self->{state} = BOGUS_COMMENT_STATE;          $self->{state} = BOGUS_COMMENT_STATE;
697          $self->{current_token} = {type => COMMENT_TOKEN, data => '',          $self->{current_token} = {type => COMMENT_TOKEN, data => '',
698                                    line => $self->{line_prev}, # "<" of "</"                                    line => $self->{line_prev}, # "<" of "</"
699                                    column => $self->{column_prev} - 1};                                    column => $self->{column_prev} - 1,
700                                     };
701          ## $self->{next_char} is intentionally left as is          ## $self->{next_char} is intentionally left as is
702          redo A;          redo A;
703        }        }
# Line 696  sub _get_next_token ($) { Line 714  sub _get_next_token ($) {
714        } elsif ($self->{next_char} == 0x003E) { # >        } elsif ($self->{next_char} == 0x003E) { # >
715          if ($self->{current_token}->{type} == START_TAG_TOKEN) {          if ($self->{current_token}->{type} == START_TAG_TOKEN) {
716            !!!cp (35);            !!!cp (35);
           $self->{current_token}->{first_start_tag}  
               = not defined $self->{last_emitted_start_tag_name};  
717            $self->{last_emitted_start_tag_name} = $self->{current_token}->{tag_name};            $self->{last_emitted_start_tag_name} = $self->{current_token}->{tag_name};
718          } elsif ($self->{current_token}->{type} == END_TAG_TOKEN) {          } elsif ($self->{current_token}->{type} == END_TAG_TOKEN) {
719            $self->{content_model} = PCDATA_CONTENT_MODEL; # MUST            $self->{content_model} = PCDATA_CONTENT_MODEL; # MUST
# Line 729  sub _get_next_token ($) { Line 745  sub _get_next_token ($) {
745          !!!parse-error (type => 'unclosed tag');          !!!parse-error (type => 'unclosed tag');
746          if ($self->{current_token}->{type} == START_TAG_TOKEN) {          if ($self->{current_token}->{type} == START_TAG_TOKEN) {
747            !!!cp (39);            !!!cp (39);
           $self->{current_token}->{first_start_tag}  
               = not defined $self->{last_emitted_start_tag_name};  
748            $self->{last_emitted_start_tag_name} = $self->{current_token}->{tag_name};            $self->{last_emitted_start_tag_name} = $self->{current_token}->{tag_name};
749          } elsif ($self->{current_token}->{type} == END_TAG_TOKEN) {          } elsif ($self->{current_token}->{type} == END_TAG_TOKEN) {
750            $self->{content_model} = PCDATA_CONTENT_MODEL; # MUST            $self->{content_model} = PCDATA_CONTENT_MODEL; # MUST
# Line 786  sub _get_next_token ($) { Line 800  sub _get_next_token ($) {
800        } elsif ($self->{next_char} == 0x003E) { # >        } elsif ($self->{next_char} == 0x003E) { # >
801          if ($self->{current_token}->{type} == START_TAG_TOKEN) {          if ($self->{current_token}->{type} == START_TAG_TOKEN) {
802            !!!cp (46);            !!!cp (46);
           $self->{current_token}->{first_start_tag}  
               = not defined $self->{last_emitted_start_tag_name};  
803            $self->{last_emitted_start_tag_name} = $self->{current_token}->{tag_name};            $self->{last_emitted_start_tag_name} = $self->{current_token}->{tag_name};
804          } elsif ($self->{current_token}->{type} == END_TAG_TOKEN) {          } elsif ($self->{current_token}->{type} == END_TAG_TOKEN) {
805            $self->{content_model} = PCDATA_CONTENT_MODEL; # MUST            $self->{content_model} = PCDATA_CONTENT_MODEL; # MUST
# Line 809  sub _get_next_token ($) { Line 821  sub _get_next_token ($) {
821        } elsif (0x0041 <= $self->{next_char} and        } elsif (0x0041 <= $self->{next_char} and
822                 $self->{next_char} <= 0x005A) { # A..Z                 $self->{next_char} <= 0x005A) { # A..Z
823          !!!cp (49);          !!!cp (49);
824          $self->{current_attribute} = {name => chr ($self->{next_char} + 0x0020),          $self->{current_attribute}
825                                value => ''};              = {name => chr ($self->{next_char} + 0x0020),
826                   value => '',
827                   line => $self->{line}, column => $self->{column}};
828          $self->{state} = ATTRIBUTE_NAME_STATE;          $self->{state} = ATTRIBUTE_NAME_STATE;
829          !!!next-input-character;          !!!next-input-character;
830          redo A;          redo A;
# Line 833  sub _get_next_token ($) { Line 847  sub _get_next_token ($) {
847          !!!parse-error (type => 'unclosed tag');          !!!parse-error (type => 'unclosed tag');
848          if ($self->{current_token}->{type} == START_TAG_TOKEN) {          if ($self->{current_token}->{type} == START_TAG_TOKEN) {
849            !!!cp (52);            !!!cp (52);
           $self->{current_token}->{first_start_tag}  
               = not defined $self->{last_emitted_start_tag_name};  
850            $self->{last_emitted_start_tag_name} = $self->{current_token}->{tag_name};            $self->{last_emitted_start_tag_name} = $self->{current_token}->{tag_name};
851          } elsif ($self->{current_token}->{type} == END_TAG_TOKEN) {          } elsif ($self->{current_token}->{type} == END_TAG_TOKEN) {
852            $self->{content_model} = PCDATA_CONTENT_MODEL; # MUST            $self->{content_model} = PCDATA_CONTENT_MODEL; # MUST
# Line 864  sub _get_next_token ($) { Line 876  sub _get_next_token ($) {
876          } else {          } else {
877            !!!cp (56);            !!!cp (56);
878          }          }
879          $self->{current_attribute} = {name => chr ($self->{next_char}),          $self->{current_attribute}
880                                value => ''};              = {name => chr ($self->{next_char}),
881                   value => '',
882                   line => $self->{line}, column => $self->{column}};
883          $self->{state} = ATTRIBUTE_NAME_STATE;          $self->{state} = ATTRIBUTE_NAME_STATE;
884          !!!next-input-character;          !!!next-input-character;
885          redo A;          redo A;
# Line 875  sub _get_next_token ($) { Line 889  sub _get_next_token ($) {
889          if (exists $self->{current_token}->{attributes} # start tag or end tag          if (exists $self->{current_token}->{attributes} # start tag or end tag
890              ->{$self->{current_attribute}->{name}}) { # MUST              ->{$self->{current_attribute}->{name}}) { # MUST
891            !!!cp (57);            !!!cp (57);
892            !!!parse-error (type => 'duplicate attribute:'.$self->{current_attribute}->{name});            !!!parse-error (type => 'duplicate attribute:'.$self->{current_attribute}->{name}, line => $self->{current_attribute}->{line}, column => $self->{current_attribute}->{column});
893            ## Discard $self->{current_attribute} # MUST            ## Discard $self->{current_attribute} # MUST
894          } else {          } else {
895            !!!cp (58);            !!!cp (58);
# Line 904  sub _get_next_token ($) { Line 918  sub _get_next_token ($) {
918          $before_leave->();          $before_leave->();
919          if ($self->{current_token}->{type} == START_TAG_TOKEN) {          if ($self->{current_token}->{type} == START_TAG_TOKEN) {
920            !!!cp (61);            !!!cp (61);
           $self->{current_token}->{first_start_tag}  
               = not defined $self->{last_emitted_start_tag_name};  
921            $self->{last_emitted_start_tag_name} = $self->{current_token}->{tag_name};            $self->{last_emitted_start_tag_name} = $self->{current_token}->{tag_name};
922          } elsif ($self->{current_token}->{type} == END_TAG_TOKEN) {          } elsif ($self->{current_token}->{type} == END_TAG_TOKEN) {
923            !!!cp (62);            !!!cp (62);
# Line 950  sub _get_next_token ($) { Line 962  sub _get_next_token ($) {
962          $before_leave->();          $before_leave->();
963          if ($self->{current_token}->{type} == START_TAG_TOKEN) {          if ($self->{current_token}->{type} == START_TAG_TOKEN) {
964            !!!cp (66);            !!!cp (66);
           $self->{current_token}->{first_start_tag}  
               = not defined $self->{last_emitted_start_tag_name};  
965            $self->{last_emitted_start_tag_name} = $self->{current_token}->{tag_name};            $self->{last_emitted_start_tag_name} = $self->{current_token}->{tag_name};
966          } elsif ($self->{current_token}->{type} == END_TAG_TOKEN) {          } elsif ($self->{current_token}->{type} == END_TAG_TOKEN) {
967            $self->{content_model} = PCDATA_CONTENT_MODEL; # MUST            $self->{content_model} = PCDATA_CONTENT_MODEL; # MUST
# Line 1002  sub _get_next_token ($) { Line 1012  sub _get_next_token ($) {
1012        } elsif ($self->{next_char} == 0x003E) { # >        } elsif ($self->{next_char} == 0x003E) { # >
1013          if ($self->{current_token}->{type} == START_TAG_TOKEN) {          if ($self->{current_token}->{type} == START_TAG_TOKEN) {
1014            !!!cp (73);            !!!cp (73);
           $self->{current_token}->{first_start_tag}  
               = not defined $self->{last_emitted_start_tag_name};  
1015            $self->{last_emitted_start_tag_name} = $self->{current_token}->{tag_name};            $self->{last_emitted_start_tag_name} = $self->{current_token}->{tag_name};
1016          } elsif ($self->{current_token}->{type} == END_TAG_TOKEN) {          } elsif ($self->{current_token}->{type} == END_TAG_TOKEN) {
1017            $self->{content_model} = PCDATA_CONTENT_MODEL; # MUST            $self->{content_model} = PCDATA_CONTENT_MODEL; # MUST
# Line 1026  sub _get_next_token ($) { Line 1034  sub _get_next_token ($) {
1034        } elsif (0x0041 <= $self->{next_char} and        } elsif (0x0041 <= $self->{next_char} and
1035                 $self->{next_char} <= 0x005A) { # A..Z                 $self->{next_char} <= 0x005A) { # A..Z
1036          !!!cp (76);          !!!cp (76);
1037          $self->{current_attribute} = {name => chr ($self->{next_char} + 0x0020),          $self->{current_attribute}
1038                                value => ''};              = {name => chr ($self->{next_char} + 0x0020),
1039                   value => '',
1040                   line => $self->{line}, column => $self->{column}};
1041          $self->{state} = ATTRIBUTE_NAME_STATE;          $self->{state} = ATTRIBUTE_NAME_STATE;
1042          !!!next-input-character;          !!!next-input-character;
1043          redo A;          redo A;
# Line 1051  sub _get_next_token ($) { Line 1061  sub _get_next_token ($) {
1061          !!!parse-error (type => 'unclosed tag');          !!!parse-error (type => 'unclosed tag');
1062          if ($self->{current_token}->{type} == START_TAG_TOKEN) {          if ($self->{current_token}->{type} == START_TAG_TOKEN) {
1063            !!!cp (79);            !!!cp (79);
           $self->{current_token}->{first_start_tag}  
               = not defined $self->{last_emitted_start_tag_name};  
1064            $self->{last_emitted_start_tag_name} = $self->{current_token}->{tag_name};            $self->{last_emitted_start_tag_name} = $self->{current_token}->{tag_name};
1065          } elsif ($self->{current_token}->{type} == END_TAG_TOKEN) {          } elsif ($self->{current_token}->{type} == END_TAG_TOKEN) {
1066            $self->{content_model} = PCDATA_CONTENT_MODEL; # MUST            $self->{content_model} = PCDATA_CONTENT_MODEL; # MUST
# Line 1074  sub _get_next_token ($) { Line 1082  sub _get_next_token ($) {
1082          redo A;          redo A;
1083        } else {        } else {
1084          !!!cp (82);          !!!cp (82);
1085          $self->{current_attribute} = {name => chr ($self->{next_char}),          $self->{current_attribute}
1086                                value => ''};              = {name => chr ($self->{next_char}),
1087                   value => '',
1088                   line => $self->{line}, column => $self->{column}};
1089          $self->{state} = ATTRIBUTE_NAME_STATE;          $self->{state} = ATTRIBUTE_NAME_STATE;
1090          !!!next-input-character;          !!!next-input-character;
1091          redo A;                  redo A;        
# Line 1108  sub _get_next_token ($) { Line 1118  sub _get_next_token ($) {
1118        } elsif ($self->{next_char} == 0x003E) { # >        } elsif ($self->{next_char} == 0x003E) { # >
1119          if ($self->{current_token}->{type} == START_TAG_TOKEN) {          if ($self->{current_token}->{type} == START_TAG_TOKEN) {
1120            !!!cp (87);            !!!cp (87);
           $self->{current_token}->{first_start_tag}  
               = not defined $self->{last_emitted_start_tag_name};  
1121            $self->{last_emitted_start_tag_name} = $self->{current_token}->{tag_name};            $self->{last_emitted_start_tag_name} = $self->{current_token}->{tag_name};
1122          } elsif ($self->{current_token}->{type} == END_TAG_TOKEN) {          } elsif ($self->{current_token}->{type} == END_TAG_TOKEN) {
1123            $self->{content_model} = PCDATA_CONTENT_MODEL; # MUST            $self->{content_model} = PCDATA_CONTENT_MODEL; # MUST
# Line 1133  sub _get_next_token ($) { Line 1141  sub _get_next_token ($) {
1141          !!!parse-error (type => 'unclosed tag');          !!!parse-error (type => 'unclosed tag');
1142          if ($self->{current_token}->{type} == START_TAG_TOKEN) {          if ($self->{current_token}->{type} == START_TAG_TOKEN) {
1143            !!!cp (90);            !!!cp (90);
           $self->{current_token}->{first_start_tag}  
               = not defined $self->{last_emitted_start_tag_name};  
1144            $self->{last_emitted_start_tag_name} = $self->{current_token}->{tag_name};            $self->{last_emitted_start_tag_name} = $self->{current_token}->{tag_name};
1145          } elsif ($self->{current_token}->{type} == END_TAG_TOKEN) {          } elsif ($self->{current_token}->{type} == END_TAG_TOKEN) {
1146            $self->{content_model} = PCDATA_CONTENT_MODEL; # MUST            $self->{content_model} = PCDATA_CONTENT_MODEL; # MUST
# Line 1182  sub _get_next_token ($) { Line 1188  sub _get_next_token ($) {
1188          !!!parse-error (type => 'unclosed attribute value');          !!!parse-error (type => 'unclosed attribute value');
1189          if ($self->{current_token}->{type} == START_TAG_TOKEN) {          if ($self->{current_token}->{type} == START_TAG_TOKEN) {
1190            !!!cp (97);            !!!cp (97);
           $self->{current_token}->{first_start_tag}  
               = not defined $self->{last_emitted_start_tag_name};  
1191            $self->{last_emitted_start_tag_name} = $self->{current_token}->{tag_name};            $self->{last_emitted_start_tag_name} = $self->{current_token}->{tag_name};
1192          } elsif ($self->{current_token}->{type} == END_TAG_TOKEN) {          } elsif ($self->{current_token}->{type} == END_TAG_TOKEN) {
1193            $self->{content_model} = PCDATA_CONTENT_MODEL; # MUST            $self->{content_model} = PCDATA_CONTENT_MODEL; # MUST
# Line 1226  sub _get_next_token ($) { Line 1230  sub _get_next_token ($) {
1230          !!!parse-error (type => 'unclosed attribute value');          !!!parse-error (type => 'unclosed attribute value');
1231          if ($self->{current_token}->{type} == START_TAG_TOKEN) {          if ($self->{current_token}->{type} == START_TAG_TOKEN) {
1232            !!!cp (103);            !!!cp (103);
           $self->{current_token}->{first_start_tag}  
               = not defined $self->{last_emitted_start_tag_name};  
1233            $self->{last_emitted_start_tag_name} = $self->{current_token}->{tag_name};            $self->{last_emitted_start_tag_name} = $self->{current_token}->{tag_name};
1234          } elsif ($self->{current_token}->{type} == END_TAG_TOKEN) {          } elsif ($self->{current_token}->{type} == END_TAG_TOKEN) {
1235            $self->{content_model} = PCDATA_CONTENT_MODEL; # MUST            $self->{content_model} = PCDATA_CONTENT_MODEL; # MUST
# Line 1273  sub _get_next_token ($) { Line 1275  sub _get_next_token ($) {
1275        } elsif ($self->{next_char} == 0x003E) { # >        } elsif ($self->{next_char} == 0x003E) { # >
1276          if ($self->{current_token}->{type} == START_TAG_TOKEN) {          if ($self->{current_token}->{type} == START_TAG_TOKEN) {
1277            !!!cp (109);            !!!cp (109);
           $self->{current_token}->{first_start_tag}  
               = not defined $self->{last_emitted_start_tag_name};  
1278            $self->{last_emitted_start_tag_name} = $self->{current_token}->{tag_name};            $self->{last_emitted_start_tag_name} = $self->{current_token}->{tag_name};
1279          } elsif ($self->{current_token}->{type} == END_TAG_TOKEN) {          } elsif ($self->{current_token}->{type} == END_TAG_TOKEN) {
1280            $self->{content_model} = PCDATA_CONTENT_MODEL; # MUST            $self->{content_model} = PCDATA_CONTENT_MODEL; # MUST
# Line 1298  sub _get_next_token ($) { Line 1298  sub _get_next_token ($) {
1298          !!!parse-error (type => 'unclosed tag');          !!!parse-error (type => 'unclosed tag');
1299          if ($self->{current_token}->{type} == START_TAG_TOKEN) {          if ($self->{current_token}->{type} == START_TAG_TOKEN) {
1300            !!!cp (112);            !!!cp (112);
           $self->{current_token}->{first_start_tag}  
               = not defined $self->{last_emitted_start_tag_name};  
1301            $self->{last_emitted_start_tag_name} = $self->{current_token}->{tag_name};            $self->{last_emitted_start_tag_name} = $self->{current_token}->{tag_name};
1302          } elsif ($self->{current_token}->{type} == END_TAG_TOKEN) {          } elsif ($self->{current_token}->{type} == END_TAG_TOKEN) {
1303            $self->{content_model} = PCDATA_CONTENT_MODEL; # MUST            $self->{content_model} = PCDATA_CONTENT_MODEL; # MUST
# Line 1370  sub _get_next_token ($) { Line 1368  sub _get_next_token ($) {
1368        } elsif ($self->{next_char} == 0x003E) { # >        } elsif ($self->{next_char} == 0x003E) { # >
1369          if ($self->{current_token}->{type} == START_TAG_TOKEN) {          if ($self->{current_token}->{type} == START_TAG_TOKEN) {
1370            !!!cp (119);            !!!cp (119);
           $self->{current_token}->{first_start_tag}  
               = not defined $self->{last_emitted_start_tag_name};  
1371            $self->{last_emitted_start_tag_name} = $self->{current_token}->{tag_name};            $self->{last_emitted_start_tag_name} = $self->{current_token}->{tag_name};
1372          } elsif ($self->{current_token}->{type} == END_TAG_TOKEN) {          } elsif ($self->{current_token}->{type} == END_TAG_TOKEN) {
1373            $self->{content_model} = PCDATA_CONTENT_MODEL; # MUST            $self->{content_model} = PCDATA_CONTENT_MODEL; # MUST
# Line 1459  sub _get_next_token ($) { Line 1455  sub _get_next_token ($) {
1455          if ($self->{next_char} == 0x002D) { # -          if ($self->{next_char} == 0x002D) { # -
1456            !!!cp (127);            !!!cp (127);
1457            $self->{current_token} = {type => COMMENT_TOKEN, data => '',            $self->{current_token} = {type => COMMENT_TOKEN, data => '',
1458                                      line => $l, column => $c};                                      line => $l, column => $c,
1459                                       };
1460            $self->{state} = COMMENT_START_STATE;            $self->{state} = COMMENT_START_STATE;
1461            !!!next-input-character;            !!!next-input-character;
1462            redo A;            redo A;
# Line 1497  sub _get_next_token ($) { Line 1494  sub _get_next_token ($) {
1494                      $self->{state} = DOCTYPE_STATE;                      $self->{state} = DOCTYPE_STATE;
1495                      $self->{current_token} = {type => DOCTYPE_TOKEN,                      $self->{current_token} = {type => DOCTYPE_TOKEN,
1496                                                quirks => 1,                                                quirks => 1,
1497                                                line => $l, column => $c};                                                line => $l, column => $c,
1498                                                 };
1499                      !!!next-input-character;                      !!!next-input-character;
1500                      redo A;                      redo A;
1501                    } else {                    } else {
# Line 1527  sub _get_next_token ($) { Line 1525  sub _get_next_token ($) {
1525        !!!back-next-input-character (@next_char);        !!!back-next-input-character (@next_char);
1526        $self->{state} = BOGUS_COMMENT_STATE;        $self->{state} = BOGUS_COMMENT_STATE;
1527        $self->{current_token} = {type => COMMENT_TOKEN, data => '',        $self->{current_token} = {type => COMMENT_TOKEN, data => '',
1528                                  line => $l, column => $c};                                  line => $l, column => $c,
1529                                   };
1530        redo A;        redo A;
1531                
1532        ## ISSUE: typos in spec: chacacters, is is a parse error        ## ISSUE: typos in spec: chacacters, is is a parse error
# Line 1651  sub _get_next_token ($) { Line 1650  sub _get_next_token ($) {
1650          redo A;          redo A;
1651        } elsif ($self->{next_char} == 0x002D) { # -        } elsif ($self->{next_char} == 0x002D) { # -
1652          !!!cp (152);          !!!cp (152);
1653          !!!parse-error (type => 'dash in comment');          !!!parse-error (type => 'dash in comment',
1654                            line => $self->{line_prev},
1655                            column => $self->{column_prev});
1656          $self->{current_token}->{data} .= '-'; # comment          $self->{current_token}->{data} .= '-'; # comment
1657          ## Stay in the state          ## Stay in the state
1658          !!!next-input-character;          !!!next-input-character;
# Line 1667  sub _get_next_token ($) { Line 1668  sub _get_next_token ($) {
1668          redo A;          redo A;
1669        } else {        } else {
1670          !!!cp (154);          !!!cp (154);
1671          !!!parse-error (type => 'dash in comment');          !!!parse-error (type => 'dash in comment',
1672                            line => $self->{line_prev},
1673                            column => $self->{column_prev});
1674          $self->{current_token}->{data} .= '--' . chr ($self->{next_char}); # comment          $self->{current_token}->{data} .= '--' . chr ($self->{next_char}); # comment
1675          $self->{state} = COMMENT_STATE;          $self->{state} = COMMENT_STATE;
1676          !!!next-input-character;          !!!next-input-character;
# Line 2321  sub _tokenize_attempt_to_consume_an_enti Line 2324  sub _tokenize_attempt_to_consume_an_enti
2324          }          }
2325    
2326          return {type => CHARACTER_TOKEN, data => chr $code,          return {type => CHARACTER_TOKEN, data => chr $code,
2327                  has_reference => 1, line => $l, column => $c};                  has_reference => 1,
2328                    line => $l, column => $c,
2329                   };
2330        } # X        } # X
2331      } elsif (0x0030 <= $self->{next_char} and      } elsif (0x0030 <= $self->{next_char} and
2332               $self->{next_char} <= 0x0039) { # 0..9               $self->{next_char} <= 0x0039) { # 0..9
# Line 2364  sub _tokenize_attempt_to_consume_an_enti Line 2369  sub _tokenize_attempt_to_consume_an_enti
2369        }        }
2370                
2371        return {type => CHARACTER_TOKEN, data => chr $code, has_reference => 1,        return {type => CHARACTER_TOKEN, data => chr $code, has_reference => 1,
2372                line => $l, column => $c};                line => $l, column => $c,
2373                 };
2374      } else {      } else {
2375        !!!cp (1019);        !!!cp (1019);
2376        !!!parse-error (type => 'bare nero', line => $l, column => $c);        !!!parse-error (type => 'bare nero', line => $l, column => $c);
# Line 2418  sub _tokenize_attempt_to_consume_an_enti Line 2424  sub _tokenize_attempt_to_consume_an_enti
2424      if ($match > 0) {      if ($match > 0) {
2425        !!!cp (1023);        !!!cp (1023);
2426        return {type => CHARACTER_TOKEN, data => $value, has_reference => 1,        return {type => CHARACTER_TOKEN, data => $value, has_reference => 1,
2427                line => $l, column => $c};                line => $l, column => $c,
2428                 };
2429      } elsif ($match < 0) {      } elsif ($match < 0) {
2430        !!!parse-error (type => 'no refc', line => $l, column => $c);        !!!parse-error (type => 'no refc', line => $l, column => $c);
2431        if ($in_attr and $match < -1) {        if ($in_attr and $match < -1) {
2432          !!!cp (1024);          !!!cp (1024);
2433          return {type => CHARACTER_TOKEN, data => '&'.$entity_name,          return {type => CHARACTER_TOKEN, data => '&'.$entity_name,
2434                  line => $l, column => $c};                  line => $l, column => $c,
2435                   };
2436        } else {        } else {
2437          !!!cp (1025);          !!!cp (1025);
2438          return {type => CHARACTER_TOKEN, data => $value, has_reference => 1,          return {type => CHARACTER_TOKEN, data => $value, has_reference => 1,
2439                  line => $l, column => $c};                  line => $l, column => $c,
2440                   };
2441        }        }
2442      } else {      } else {
2443        !!!cp (1026);        !!!cp (1026);
2444        !!!parse-error (type => 'bare ero', line => $l, column => $c);        !!!parse-error (type => 'bare ero', line => $l, column => $c);
2445        ## NOTE: "No characters are consumed" in the spec.        ## NOTE: "No characters are consumed" in the spec.
2446        return {type => CHARACTER_TOKEN, data => '&'.$value,        return {type => CHARACTER_TOKEN, data => '&'.$value,
2447                line => $l, column => $c};                line => $l, column => $c,
2448                 };
2449      }      }
2450    } else {    } else {
2451      !!!cp (1027);      !!!cp (1027);
# Line 2738  sub _tree_construction_root_element ($) Line 2748  sub _tree_construction_root_element ($)
2748        } elsif ($token->{type} == START_TAG_TOKEN) {        } elsif ($token->{type} == START_TAG_TOKEN) {
2749          if ($token->{tag_name} eq 'html') {          if ($token->{tag_name} eq 'html') {
2750            my $root_element;            my $root_element;
2751            !!!create-element ($root_element, $token->{tag_name}, $token->{attributes});            !!!create-element ($root_element, $token->{tag_name}, $token->{attributes}, $token);
2752            $self->{document}->append_child ($root_element);            $self->{document}->append_child ($root_element);
2753            push @{$self->{open_elements}}, [$root_element, 'html'];            push @{$self->{open_elements}}, [$root_element, 'html'];
2754    
# Line 2746  sub _tree_construction_root_element ($) Line 2756  sub _tree_construction_root_element ($)
2756              !!!cp ('t24');              !!!cp ('t24');
2757              $self->{application_cache_selection}              $self->{application_cache_selection}
2758                  ->($token->{attributes}->{manifest}->{value});                  ->($token->{attributes}->{manifest}->{value});
2759              ## ISSUE: No relative reference resolution?              ## ISSUE: Spec is unclear on relative references.
2760                ## According to Hixie (#whatwg 2008-03-19), it should be
2761                ## resolved against the base URI of the document in HTML
2762                ## or xml:base of the element in XHTML.
2763            } else {            } else {
2764              !!!cp ('t25');              !!!cp ('t25');
2765              $self->{application_cache_selection}->(undef);              $self->{application_cache_selection}->(undef);
# Line 2768  sub _tree_construction_root_element ($) Line 2781  sub _tree_construction_root_element ($)
2781          die "$0: $token->{type}: Unknown token type";          die "$0: $token->{type}: Unknown token type";
2782        }        }
2783    
2784      my $root_element; !!!create-element ($root_element, 'html');      my $root_element; !!!create-element ($root_element, 'html',, $token);
2785      $self->{document}->append_child ($root_element);      $self->{document}->append_child ($root_element);
2786      push @{$self->{open_elements}}, [$root_element, 'html'];      push @{$self->{open_elements}}, [$root_element, 'html'];
2787    
# Line 2963  sub _tree_construction_main ($) { Line 2976  sub _tree_construction_main ($) {
2976      ## Step 1      ## Step 1
2977      my $start_tag_name = $token->{tag_name};      my $start_tag_name = $token->{tag_name};
2978      my $el;      my $el;
2979      !!!create-element ($el, $start_tag_name, $token->{attributes});      !!!create-element ($el, $start_tag_name, $token->{attributes}, $token);
2980    
2981      ## Step 2      ## Step 2
2982      $insert->($el);      $insert->($el);
# Line 3013  sub _tree_construction_main ($) { Line 3026  sub _tree_construction_main ($) {
3026    
3027    my $script_start_tag = sub () {    my $script_start_tag = sub () {
3028      my $script_el;      my $script_el;
3029      !!!create-element ($script_el, 'script', $token->{attributes});      !!!create-element ($script_el, 'script', $token->{attributes}, $token);
3030      ## TODO: mark as "parser-inserted"      ## TODO: mark as "parser-inserted"
3031    
3032      $self->{content_model} = CDATA_CONTENT_MODEL;      $self->{content_model} = CDATA_CONTENT_MODEL;
# Line 3410  sub _tree_construction_main ($) { Line 3423  sub _tree_construction_main ($) {
3423          if ($self->{insertion_mode} == BEFORE_HEAD_IM) {          if ($self->{insertion_mode} == BEFORE_HEAD_IM) {
3424            !!!cp ('t89');            !!!cp ('t89');
3425            ## As if <head>            ## As if <head>
3426            !!!create-element ($self->{head_element}, 'head');            !!!create-element ($self->{head_element}, 'head',, $token);
3427            $self->{open_elements}->[-1]->[0]->append_child ($self->{head_element});            $self->{open_elements}->[-1]->[0]->append_child ($self->{head_element});
3428            push @{$self->{open_elements}}, [$self->{head_element}, 'head'];            push @{$self->{open_elements}}, [$self->{head_element}, 'head'];
3429    
# Line 3440  sub _tree_construction_main ($) { Line 3453  sub _tree_construction_main ($) {
3453    
3454              ## "after head" insertion mode              ## "after head" insertion mode
3455              ## As if <body>              ## As if <body>
3456              !!!insert-element ('body');              !!!insert-element ('body',, $token);
3457              $self->{insertion_mode} = IN_BODY_IM;              $self->{insertion_mode} = IN_BODY_IM;
3458              ## reprocess              ## reprocess
3459              redo B;              redo B;
# Line 3448  sub _tree_construction_main ($) { Line 3461  sub _tree_construction_main ($) {
3461              if ($token->{tag_name} eq 'head') {              if ($token->{tag_name} eq 'head') {
3462                if ($self->{insertion_mode} == BEFORE_HEAD_IM) {                if ($self->{insertion_mode} == BEFORE_HEAD_IM) {
3463                  !!!cp ('t93');                  !!!cp ('t93');
3464                  !!!create-element ($self->{head_element}, $token->{tag_name}, $token->{attributes});                  !!!create-element ($self->{head_element}, $token->{tag_name}, $token->{attributes}, $token);
3465                  $self->{open_elements}->[-1]->[0]->append_child ($self->{head_element});                  $self->{open_elements}->[-1]->[0]->append_child ($self->{head_element});
3466                  push @{$self->{open_elements}}, [$self->{head_element}, $token->{tag_name}];                  push @{$self->{open_elements}}, [$self->{head_element}, $token->{tag_name}];
3467                  $self->{insertion_mode} = IN_HEAD_IM;                  $self->{insertion_mode} = IN_HEAD_IM;
# Line 3467  sub _tree_construction_main ($) { Line 3480  sub _tree_construction_main ($) {
3480              } elsif ($self->{insertion_mode} == BEFORE_HEAD_IM) {              } elsif ($self->{insertion_mode} == BEFORE_HEAD_IM) {
3481                !!!cp ('t96');                !!!cp ('t96');
3482                ## As if <head>                ## As if <head>
3483                !!!create-element ($self->{head_element}, 'head');                !!!create-element ($self->{head_element}, 'head',, $token);
3484                $self->{open_elements}->[-1]->[0]->append_child ($self->{head_element});                $self->{open_elements}->[-1]->[0]->append_child ($self->{head_element});
3485                push @{$self->{open_elements}}, [$self->{head_element}, 'head'];                push @{$self->{open_elements}}, [$self->{head_element}, 'head'];
3486    
# Line 3498  sub _tree_construction_main ($) { Line 3511  sub _tree_construction_main ($) {
3511                } else {                } else {
3512                  !!!cp ('t101');                  !!!cp ('t101');
3513                }                }
3514                !!!insert-element ($token->{tag_name}, $token->{attributes});                !!!insert-element ($token->{tag_name}, $token->{attributes}, $token);
3515                pop @{$self->{open_elements}}; ## ISSUE: This step is missing in the spec.                pop @{$self->{open_elements}}; ## ISSUE: This step is missing in the spec.
3516                pop @{$self->{open_elements}} # <head>                pop @{$self->{open_elements}} # <head>
3517                    if $self->{insertion_mode} == AFTER_HEAD_IM;                    if $self->{insertion_mode} == AFTER_HEAD_IM;
# Line 3513  sub _tree_construction_main ($) { Line 3526  sub _tree_construction_main ($) {
3526                } else {                } else {
3527                  !!!cp ('t103');                  !!!cp ('t103');
3528                }                }
3529                !!!insert-element ($token->{tag_name}, $token->{attributes});                !!!insert-element ($token->{tag_name}, $token->{attributes}, $token);
3530                pop @{$self->{open_elements}}; ## ISSUE: This step is missing in the spec.                pop @{$self->{open_elements}}; ## ISSUE: This step is missing in the spec.
3531                pop @{$self->{open_elements}} # <head>                pop @{$self->{open_elements}} # <head>
3532                    if $self->{insertion_mode} == AFTER_HEAD_IM;                    if $self->{insertion_mode} == AFTER_HEAD_IM;
# Line 3528  sub _tree_construction_main ($) { Line 3541  sub _tree_construction_main ($) {
3541                } else {                } else {
3542                  !!!cp ('t105');                  !!!cp ('t105');
3543                }                }
3544                !!!insert-element ($token->{tag_name}, $token->{attributes});                !!!insert-element ($token->{tag_name}, $token->{attributes}, $token);
3545                my $meta_el = pop @{$self->{open_elements}}; ## ISSUE: This step is missing in the spec.                my $meta_el = pop @{$self->{open_elements}}; ## ISSUE: This step is missing in the spec.
3546    
3547                unless ($self->{confident}) {                unless ($self->{confident}) {
3548                  if ($token->{attributes}->{charset}) { ## TODO: And if supported                  if ($token->{attributes}->{charset}) { ## TODO: And if supported
3549                    !!!cp ('t106');                    !!!cp ('t106');
3550                    $self->{change_encoding}                    $self->{change_encoding}
3551                        ->($self, $token->{attributes}->{charset}->{value});                        ->($self, $token->{attributes}->{charset}->{value},
3552                             $token);
3553                                        
3554                    $meta_el->[0]->get_attribute_node_ns (undef, 'charset')                    $meta_el->[0]->get_attribute_node_ns (undef, 'charset')
3555                        ->set_user_data (manakai_has_reference =>                        ->set_user_data (manakai_has_reference =>
# Line 3550  sub _tree_construction_main ($) { Line 3564  sub _tree_construction_main ($) {
3564                            ([^"'\x09-\x0D\x20][^\x09-\x0D\x20]*))/x) {                            ([^"'\x09-\x0D\x20][^\x09-\x0D\x20]*))/x) {
3565                      !!!cp ('t107');                      !!!cp ('t107');
3566                      $self->{change_encoding}                      $self->{change_encoding}
3567                          ->($self, defined $1 ? $1 : defined $2 ? $2 : $3);                          ->($self, defined $1 ? $1 : defined $2 ? $2 : $3,
3568                               $token);
3569                      $meta_el->[0]->get_attribute_node_ns (undef, 'content')                      $meta_el->[0]->get_attribute_node_ns (undef, 'content')
3570                          ->set_user_data (manakai_has_reference =>                          ->set_user_data (manakai_has_reference =>
3571                                               $token->{attributes}->{content}                                               $token->{attributes}->{content}
# Line 3623  sub _tree_construction_main ($) { Line 3638  sub _tree_construction_main ($) {
3638                if ($self->{insertion_mode} == IN_HEAD_IM) {                if ($self->{insertion_mode} == IN_HEAD_IM) {
3639                  !!!cp ('t116');                  !!!cp ('t116');
3640                  ## NOTE: and scripting is disalbed                  ## NOTE: and scripting is disalbed
3641                  !!!insert-element ($token->{tag_name}, $token->{attributes});                  !!!insert-element ($token->{tag_name}, $token->{attributes}, $token);
3642                  $self->{insertion_mode} = IN_HEAD_NOSCRIPT_IM;                  $self->{insertion_mode} = IN_HEAD_NOSCRIPT_IM;
3643                  !!!next-token;                  !!!next-token;
3644                  redo B;                  redo B;
# Line 3682  sub _tree_construction_main ($) { Line 3697  sub _tree_construction_main ($) {
3697                }                }
3698    
3699                ## "after head" insertion mode                ## "after head" insertion mode
3700                !!!insert-element ($token->{tag_name}, $token->{attributes});                !!!insert-element ($token->{tag_name}, $token->{attributes}, $token);
3701                if ($token->{tag_name} eq 'body') {                if ($token->{tag_name} eq 'body') {
3702                  !!!cp ('t126');                  !!!cp ('t126');
3703                  $self->{insertion_mode} = IN_BODY_IM;                  $self->{insertion_mode} = IN_BODY_IM;
# Line 3722  sub _tree_construction_main ($) { Line 3737  sub _tree_construction_main ($) {
3737    
3738              ## "after head" insertion mode              ## "after head" insertion mode
3739              ## As if <body>              ## As if <body>
3740              !!!insert-element ('body');              !!!insert-element ('body',, $token);
3741              $self->{insertion_mode} = IN_BODY_IM;              $self->{insertion_mode} = IN_BODY_IM;
3742              ## reprocess              ## reprocess
3743              redo B;              redo B;
# Line 3731  sub _tree_construction_main ($) { Line 3746  sub _tree_construction_main ($) {
3746                if ($self->{insertion_mode} == BEFORE_HEAD_IM) {                if ($self->{insertion_mode} == BEFORE_HEAD_IM) {
3747                  !!!cp ('t132');                  !!!cp ('t132');
3748                  ## As if <head>                  ## As if <head>
3749                  !!!create-element ($self->{head_element}, 'head');                  !!!create-element ($self->{head_element}, 'head',, $token);
3750                  $self->{open_elements}->[-1]->[0]->append_child ($self->{head_element});                  $self->{open_elements}->[-1]->[0]->append_child ($self->{head_element});
3751                  push @{$self->{open_elements}}, [$self->{head_element}, 'head'];                  push @{$self->{open_elements}}, [$self->{head_element}, 'head'];
3752    
# Line 3784  sub _tree_construction_main ($) { Line 3799  sub _tree_construction_main ($) {
3799                if ($self->{insertion_mode} == BEFORE_HEAD_IM) {                if ($self->{insertion_mode} == BEFORE_HEAD_IM) {
3800                  !!!cp ('t139');                  !!!cp ('t139');
3801                  ## As if <head>                  ## As if <head>
3802                  !!!create-element ($self->{head_element}, 'head');                  !!!create-element ($self->{head_element}, 'head',, $token);
3803                  $self->{open_elements}->[-1]->[0]->append_child ($self->{head_element});                  $self->{open_elements}->[-1]->[0]->append_child ($self->{head_element});
3804                  push @{$self->{open_elements}}, [$self->{head_element}, 'head'];                  push @{$self->{open_elements}}, [$self->{head_element}, 'head'];
3805    
# Line 3807  sub _tree_construction_main ($) { Line 3822  sub _tree_construction_main ($) {
3822                if ($self->{insertion_mode} == BEFORE_HEAD_IM) {                if ($self->{insertion_mode} == BEFORE_HEAD_IM) {
3823                  !!!cp ('t142');                  !!!cp ('t142');
3824                  ## As if <head>                  ## As if <head>
3825                  !!!create-element ($self->{head_element}, 'head');                  !!!create-element ($self->{head_element}, 'head',, $token);
3826                  $self->{open_elements}->[-1]->[0]->append_child ($self->{head_element});                  $self->{open_elements}->[-1]->[0]->append_child ($self->{head_element});
3827                  push @{$self->{open_elements}}, [$self->{head_element}, 'head'];                  push @{$self->{open_elements}}, [$self->{head_element}, 'head'];
3828    
# Line 3861  sub _tree_construction_main ($) { Line 3876  sub _tree_construction_main ($) {
3876    
3877              ## "after head" insertion mode              ## "after head" insertion mode
3878              ## As if <body>              ## As if <body>
3879              !!!insert-element ('body');              !!!insert-element ('body',, $token);
3880              $self->{insertion_mode} = IN_BODY_IM;              $self->{insertion_mode} = IN_BODY_IM;
3881              ## reprocess              ## reprocess
3882              redo B;              redo B;
# Line 3870  sub _tree_construction_main ($) { Line 3885  sub _tree_construction_main ($) {
3885            !!!cp ('t149.1');            !!!cp ('t149.1');
3886    
3887            ## NOTE: As if <head>            ## NOTE: As if <head>
3888            !!!create-element ($self->{head_element}, 'head');            !!!create-element ($self->{head_element}, 'head',, $token);
3889            $self->{open_elements}->[-1]->[0]->append_child            $self->{open_elements}->[-1]->[0]->append_child
3890                ($self->{head_element});                ($self->{head_element});
3891            #push @{$self->{open_elements}}, [$self->{head_element}, 'head'];            #push @{$self->{open_elements}}, [$self->{head_element}, 'head'];
# Line 3914  sub _tree_construction_main ($) { Line 3929  sub _tree_construction_main ($) {
3929          }          }
3930    
3931          ## NOTE: As if <body>          ## NOTE: As if <body>
3932          !!!insert-element ('body');          !!!insert-element ('body',, $token);
3933          $self->{insertion_mode} = IN_BODY_IM;          $self->{insertion_mode} = IN_BODY_IM;
3934          ## NOTE: Reprocess.          ## NOTE: Reprocess.
3935          redo B;          redo B;
# Line 3947  sub _tree_construction_main ($) { Line 3962  sub _tree_construction_main ($) {
3962    
3963                      ## Close the cell                      ## Close the cell
3964                      !!!back-token; # <?>                      !!!back-token; # <?>
3965                      $token = {type => END_TAG_TOKEN, tag_name => $node->[1]};                      $token = {type => END_TAG_TOKEN, tag_name => $node->[1],
3966                                  line => $token->{line},
3967                                  column => $token->{column}};
3968                      redo B;                      redo B;
3969                    } elsif ({                    } elsif ({
3970                              table => 1, html => 1,                              table => 1, html => 1,
# Line 4160  sub _tree_construction_main ($) { Line 4177  sub _tree_construction_main ($) {
4177    
4178                      ## Close the cell                      ## Close the cell
4179                      !!!back-token; # </?>                      !!!back-token; # </?>
4180                      $token = {type => END_TAG_TOKEN, tag_name => $tn};                      $token = {type => END_TAG_TOKEN, tag_name => $tn,
4181                                  line => $token->{line},
4182                                  column => $token->{column}};
4183                      redo B;                      redo B;
4184                    } elsif ($node->[1] eq 'td' or $node->[1] eq 'th') {                    } elsif ($node->[1] eq 'td' or $node->[1] eq 'th') {
4185                      !!!cp ('t180');                      !!!cp ('t180');
# Line 4362  sub _tree_construction_main ($) { Line 4381  sub _tree_construction_main ($) {
4381                    pop @{$self->{open_elements}};                    pop @{$self->{open_elements}};
4382                  }                  }
4383                                    
4384                  !!!insert-element ('tbody');                  !!!insert-element ('tbody',, $token);
4385                  $self->{insertion_mode} = IN_TABLE_BODY_IM;                  $self->{insertion_mode} = IN_TABLE_BODY_IM;
4386                  ## reprocess in the "in table body" insertion mode...                  ## reprocess in the "in table body" insertion mode...
4387                }                }
# Line 4385  sub _tree_construction_main ($) { Line 4404  sub _tree_construction_main ($) {
4404                  $self->{insertion_mode} = IN_ROW_IM;                  $self->{insertion_mode} = IN_ROW_IM;
4405                  if ($token->{tag_name} eq 'tr') {                  if ($token->{tag_name} eq 'tr') {
4406                    !!!cp ('t204');                    !!!cp ('t204');
4407                    !!!insert-element ($token->{tag_name}, $token->{attributes});                    !!!insert-element ($token->{tag_name}, $token->{attributes}, $token);
4408                    !!!next-token;                    !!!next-token;
4409                    redo B;                    redo B;
4410                  } else {                  } else {
4411                    !!!cp ('t205');                    !!!cp ('t205');
4412                    !!!insert-element ('tr');                    !!!insert-element ('tr',, $token);
4413                    ## reprocess in the "in row" insertion mode                    ## reprocess in the "in row" insertion mode
4414                  }                  }
4415                } else {                } else {
# Line 4405  sub _tree_construction_main ($) { Line 4424  sub _tree_construction_main ($) {
4424                  pop @{$self->{open_elements}};                  pop @{$self->{open_elements}};
4425                }                }
4426                                
4427                !!!insert-element ($token->{tag_name}, $token->{attributes});                !!!insert-element ($token->{tag_name}, $token->{attributes}, $token);
4428                $self->{insertion_mode} = IN_CELL_IM;                $self->{insertion_mode} = IN_CELL_IM;
4429    
4430                push @$active_formatting_elements, ['#marker', ''];                push @$active_formatting_elements, ['#marker', ''];
# Line 4526  sub _tree_construction_main ($) { Line 4545  sub _tree_construction_main ($) {
4545                    pop @{$self->{open_elements}};                    pop @{$self->{open_elements}};
4546                  }                  }
4547                                    
4548                  !!!insert-element ('colgroup');                  !!!insert-element ('colgroup',, $token);
4549                  $self->{insertion_mode} = IN_COLUMN_GROUP_IM;                  $self->{insertion_mode} = IN_COLUMN_GROUP_IM;
4550                  ## reprocess                  ## reprocess
4551                  redo B;                  redo B;
# Line 4546  sub _tree_construction_main ($) { Line 4565  sub _tree_construction_main ($) {
4565                  push @$active_formatting_elements, ['#marker', '']                  push @$active_formatting_elements, ['#marker', '']
4566                      if $token->{tag_name} eq 'caption';                      if $token->{tag_name} eq 'caption';
4567                                    
4568                  !!!insert-element ($token->{tag_name}, $token->{attributes});                  !!!insert-element ($token->{tag_name}, $token->{attributes}, $token);
4569                  $self->{insertion_mode} = {                  $self->{insertion_mode} = {
4570                                             caption => IN_CAPTION_IM,                                             caption => IN_CAPTION_IM,
4571                                             colgroup => IN_COLUMN_GROUP_IM,                                             colgroup => IN_COLUMN_GROUP_IM,
# Line 4640  sub _tree_construction_main ($) { Line 4659  sub _tree_construction_main ($) {
4659                  !!!cp ('t227.3');                  !!!cp ('t227.3');
4660                  !!!parse-error (type => 'in table:'.$token->{tag_name}, token => $token);                  !!!parse-error (type => 'in table:'.$token->{tag_name}, token => $token);
4661    
4662                  !!!insert-element ($token->{tag_name}, $token->{attributes});                  !!!insert-element ($token->{tag_name}, $token->{attributes}, $token);
4663    
4664                  ## TODO: form element pointer                  ## TODO: form element pointer
4665    
# Line 4984  sub _tree_construction_main ($) { Line 5003  sub _tree_construction_main ($) {
5003            } elsif ($token->{type} == START_TAG_TOKEN) {            } elsif ($token->{type} == START_TAG_TOKEN) {
5004              if ($token->{tag_name} eq 'col') {              if ($token->{tag_name} eq 'col') {
5005                !!!cp ('t262');                !!!cp ('t262');
5006                !!!insert-element ($token->{tag_name}, $token->{attributes});                !!!insert-element ($token->{tag_name}, $token->{attributes}, $token);
5007                pop @{$self->{open_elements}};                pop @{$self->{open_elements}};
5008                !!!next-token;                !!!next-token;
5009                redo B;                redo B;
# Line 5066  sub _tree_construction_main ($) { Line 5085  sub _tree_construction_main ($) {
5085                  !!!cp ('t273');                  !!!cp ('t273');
5086                }                }
5087    
5088                !!!insert-element ($token->{tag_name}, $token->{attributes});                !!!insert-element ($token->{tag_name}, $token->{attributes}, $token);
5089                !!!next-token;                !!!next-token;
5090                redo B;                redo B;
5091              } elsif ($token->{tag_name} eq 'optgroup') {              } elsif ($token->{tag_name} eq 'optgroup') {
# Line 5086  sub _tree_construction_main ($) { Line 5105  sub _tree_construction_main ($) {
5105                  !!!cp ('t277');                  !!!cp ('t277');
5106                }                }
5107    
5108                !!!insert-element ($token->{tag_name}, $token->{attributes});                !!!insert-element ($token->{tag_name}, $token->{attributes}, $token);
5109                !!!next-token;                !!!next-token;
5110                redo B;                redo B;
5111          } elsif ($token->{tag_name} eq 'select' or          } elsif ($token->{tag_name} eq 'select' or
# Line 5429  sub _tree_construction_main ($) { Line 5448  sub _tree_construction_main ($) {
5448          if ($token->{tag_name} eq 'frameset' and          if ($token->{tag_name} eq 'frameset' and
5449              $self->{insertion_mode} == IN_FRAMESET_IM) {              $self->{insertion_mode} == IN_FRAMESET_IM) {
5450            !!!cp ('t318');            !!!cp ('t318');
5451            !!!insert-element ($token->{tag_name}, $token->{attributes});            !!!insert-element ($token->{tag_name}, $token->{attributes}, $token);
5452            !!!next-token;            !!!next-token;
5453            redo B;            redo B;
5454          } elsif ($token->{tag_name} eq 'frame' and          } elsif ($token->{tag_name} eq 'frame' and
5455                   $self->{insertion_mode} == IN_FRAMESET_IM) {                   $self->{insertion_mode} == IN_FRAMESET_IM) {
5456            !!!cp ('t319');            !!!cp ('t319');
5457            !!!insert-element ($token->{tag_name}, $token->{attributes});            !!!insert-element ($token->{tag_name}, $token->{attributes}, $token);
5458            pop @{$self->{open_elements}};            pop @{$self->{open_elements}};
5459            !!!next-token;            !!!next-token;
5460            redo B;            redo B;
# Line 5544  sub _tree_construction_main ($) { Line 5563  sub _tree_construction_main ($) {
5563                 }->{$token->{tag_name}}) {                 }->{$token->{tag_name}}) {
5564          !!!cp ('t334');          !!!cp ('t334');
5565          ## NOTE: This is an "as if in head" code clone, only "-t" differs          ## NOTE: This is an "as if in head" code clone, only "-t" differs
5566          !!!insert-element-t ($token->{tag_name}, $token->{attributes});          !!!insert-element-t ($token->{tag_name}, $token->{attributes}, $token);
5567          pop @{$self->{open_elements}}; ## ISSUE: This step is missing in the spec.          pop @{$self->{open_elements}}; ## ISSUE: This step is missing in the spec.
5568          !!!next-token;          !!!next-token;
5569          redo B;          redo B;
5570        } elsif ($token->{tag_name} eq 'meta') {        } elsif ($token->{tag_name} eq 'meta') {
5571          ## NOTE: This is an "as if in head" code clone, only "-t" differs          ## NOTE: This is an "as if in head" code clone, only "-t" differs
5572          !!!insert-element-t ($token->{tag_name}, $token->{attributes});          !!!insert-element-t ($token->{tag_name}, $token->{attributes}, $token);
5573          my $meta_el = pop @{$self->{open_elements}}; ## ISSUE: This step is missing in the spec.          my $meta_el = pop @{$self->{open_elements}}; ## ISSUE: This step is missing in the spec.
5574    
5575          unless ($self->{confident}) {          unless ($self->{confident}) {
5576            if ($token->{attributes}->{charset}) { ## TODO: And if supported            if ($token->{attributes}->{charset}) { ## TODO: And if supported
5577              !!!cp ('t335');              !!!cp ('t335');
5578              $self->{change_encoding}              $self->{change_encoding}
5579                  ->($self, $token->{attributes}->{charset}->{value});                  ->($self, $token->{attributes}->{charset}->{value}, $token);
5580                            
5581              $meta_el->[0]->get_attribute_node_ns (undef, 'charset')              $meta_el->[0]->get_attribute_node_ns (undef, 'charset')
5582                  ->set_user_data (manakai_has_reference =>                  ->set_user_data (manakai_has_reference =>
# Line 5572  sub _tree_construction_main ($) { Line 5591  sub _tree_construction_main ($) {
5591                      ([^"'\x09-\x0D\x20][^\x09-\x0D\x20]*))/x) {                      ([^"'\x09-\x0D\x20][^\x09-\x0D\x20]*))/x) {
5592                !!!cp ('t336');                !!!cp ('t336');
5593                $self->{change_encoding}                $self->{change_encoding}
5594                    ->($self, defined $1 ? $1 : defined $2 ? $2 : $3);                    ->($self, defined $1 ? $1 : defined $2 ? $2 : $3, $token);
5595                $meta_el->[0]->get_attribute_node_ns (undef, 'content')                $meta_el->[0]->get_attribute_node_ns (undef, 'content')
5596                    ->set_user_data (manakai_has_reference =>                    ->set_user_data (manakai_has_reference =>
5597                                         $token->{attributes}->{content}                                         $token->{attributes}->{content}
# Line 5646  sub _tree_construction_main ($) { Line 5665  sub _tree_construction_main ($) {
5665            if ($_->[1] eq 'p') {            if ($_->[1] eq 'p') {
5666              !!!cp ('t344');              !!!cp ('t344');
5667              !!!back-token;              !!!back-token;
5668              $token = {type => END_TAG_TOKEN, tag_name => 'p'};              $token = {type => END_TAG_TOKEN, tag_name => 'p',
5669                          line => $token->{line}, column => $token->{column}};
5670              redo B;              redo B;
5671            } elsif ({            } elsif ({
5672                      applet => 1, table => 1, caption => 1, td => 1, th => 1,                      applet => 1, table => 1, caption => 1, td => 1, th => 1,
# Line 5657  sub _tree_construction_main ($) { Line 5677  sub _tree_construction_main ($) {
5677            }            }
5678          } # INSCOPE          } # INSCOPE
5679                        
5680          !!!insert-element-t ($token->{tag_name}, $token->{attributes});          !!!insert-element-t ($token->{tag_name}, $token->{attributes}, $token);
5681          if ($token->{tag_name} eq 'pre' or $token->{tag_name} eq 'listing') {          if ($token->{tag_name} eq 'pre' or $token->{tag_name} eq 'listing') {
5682            !!!next-token;            !!!next-token;
5683            if ($token->{type} == CHARACTER_TOKEN) {            if ($token->{type} == CHARACTER_TOKEN) {
# Line 5699  sub _tree_construction_main ($) { Line 5719  sub _tree_construction_main ($) {
5719            if ($_->[1] eq 'p') {            if ($_->[1] eq 'p') {
5720              !!!cp ('t353');              !!!cp ('t353');
5721              !!!back-token;              !!!back-token;
5722              $token = {type => END_TAG_TOKEN, tag_name => 'p'};              $token = {type => END_TAG_TOKEN, tag_name => 'p',
5723                          line => $token->{line}, column => $token->{column}};
5724              redo B;              redo B;
5725            } elsif ({            } elsif ({
5726                      applet => 1, table => 1, caption => 1, td => 1, th => 1,                      applet => 1, table => 1, caption => 1, td => 1, th => 1,
# Line 5749  sub _tree_construction_main ($) { Line 5770  sub _tree_construction_main ($) {
5770            redo LI;            redo LI;
5771          } # LI          } # LI
5772                        
5773          !!!insert-element-t ($token->{tag_name}, $token->{attributes});          !!!insert-element-t ($token->{tag_name}, $token->{attributes}, $token);
5774          !!!next-token;          !!!next-token;
5775          redo B;          redo B;
5776        } elsif ($token->{tag_name} eq 'plaintext') {        } elsif ($token->{tag_name} eq 'plaintext') {
# Line 5758  sub _tree_construction_main ($) { Line 5779  sub _tree_construction_main ($) {
5779            if ($_->[1] eq 'p') {            if ($_->[1] eq 'p') {
5780              !!!cp ('t367');              !!!cp ('t367');
5781              !!!back-token;              !!!back-token;
5782              $token = {type => END_TAG_TOKEN, tag_name => 'p'};              $token = {type => END_TAG_TOKEN, tag_name => 'p',
5783                          line => $token->{line}, column => $token->{column}};
5784              redo B;              redo B;
5785            } elsif ({            } elsif ({
5786                      applet => 1, table => 1, caption => 1, td => 1, th => 1,                      applet => 1, table => 1, caption => 1, td => 1, th => 1,
# Line 5769  sub _tree_construction_main ($) { Line 5791  sub _tree_construction_main ($) {
5791            }            }
5792          } # INSCOPE          } # INSCOPE
5793                        
5794          !!!insert-element-t ($token->{tag_name}, $token->{attributes});          !!!insert-element-t ($token->{tag_name}, $token->{attributes}, $token);
5795                        
5796          $self->{content_model} = PLAINTEXT_CONTENT_MODEL;          $self->{content_model} = PLAINTEXT_CONTENT_MODEL;
5797                        
# Line 5783  sub _tree_construction_main ($) { Line 5805  sub _tree_construction_main ($) {
5805              !!!parse-error (type => 'in a:a', token => $token);              !!!parse-error (type => 'in a:a', token => $token);
5806                            
5807              !!!back-token;              !!!back-token;
5808              $token = {type => END_TAG_TOKEN, tag_name => 'a'};              $token = {type => END_TAG_TOKEN, tag_name => 'a',
5809                          line => $token->{line}, column => $token->{column}};
5810              $formatting_end_tag->($token);              $formatting_end_tag->($token);
5811                            
5812              AFE2: for (reverse 0..$#$active_formatting_elements) {              AFE2: for (reverse 0..$#$active_formatting_elements) {
# Line 5809  sub _tree_construction_main ($) { Line 5832  sub _tree_construction_main ($) {
5832                        
5833          $reconstruct_active_formatting_elements->($insert_to_current);          $reconstruct_active_formatting_elements->($insert_to_current);
5834    
5835          !!!insert-element-t ($token->{tag_name}, $token->{attributes});          !!!insert-element-t ($token->{tag_name}, $token->{attributes}, $token);
5836          push @$active_formatting_elements, $self->{open_elements}->[-1];          push @$active_formatting_elements, $self->{open_elements}->[-1];
5837    
5838          !!!next-token;          !!!next-token;
# Line 5824  sub _tree_construction_main ($) { Line 5847  sub _tree_construction_main ($) {
5847              !!!cp ('t376');              !!!cp ('t376');
5848              !!!parse-error (type => 'in nobr:nobr', token => $token);              !!!parse-error (type => 'in nobr:nobr', token => $token);
5849              !!!back-token;              !!!back-token;
5850              $token = {type => END_TAG_TOKEN, tag_name => 'nobr'};              $token = {type => END_TAG_TOKEN, tag_name => 'nobr',
5851                          line => $token->{line}, column => $token->{column}};
5852              redo B;              redo B;
5853            } elsif ({            } elsif ({
5854                      applet => 1, table => 1, caption => 1, td => 1, th => 1,                      applet => 1, table => 1, caption => 1, td => 1, th => 1,
# Line 5835  sub _tree_construction_main ($) { Line 5859  sub _tree_construction_main ($) {
5859            }            }
5860          } # INSCOPE          } # INSCOPE
5861                    
5862          !!!insert-element-t ($token->{tag_name}, $token->{attributes});          !!!insert-element-t ($token->{tag_name}, $token->{attributes}, $token);
5863          push @$active_formatting_elements, $self->{open_elements}->[-1];          push @$active_formatting_elements, $self->{open_elements}->[-1];
5864                    
5865          !!!next-token;          !!!next-token;
# Line 5848  sub _tree_construction_main ($) { Line 5872  sub _tree_construction_main ($) {
5872              !!!cp ('t378');              !!!cp ('t378');
5873              !!!parse-error (type => 'in button:button', token => $token);              !!!parse-error (type => 'in button:button', token => $token);
5874              !!!back-token;              !!!back-token;
5875              $token = {type => END_TAG_TOKEN, tag_name => 'button'};              $token = {type => END_TAG_TOKEN, tag_name => 'button',
5876                          line => $token->{line}, column => $token->{column}};
5877              redo B;              redo B;
5878            } elsif ({            } elsif ({
5879                      applet => 1, table => 1, caption => 1, td => 1, th => 1,                      applet => 1, table => 1, caption => 1, td => 1, th => 1,
# Line 5861  sub _tree_construction_main ($) { Line 5886  sub _tree_construction_main ($) {
5886                        
5887          $reconstruct_active_formatting_elements->($insert_to_current);          $reconstruct_active_formatting_elements->($insert_to_current);
5888                        
5889          !!!insert-element-t ($token->{tag_name}, $token->{attributes});          !!!insert-element-t ($token->{tag_name}, $token->{attributes}, $token);
5890    
5891          ## TODO: associate with $self->{form_element} if defined          ## TODO: associate with $self->{form_element} if defined
5892    
# Line 5903  sub _tree_construction_main ($) { Line 5928  sub _tree_construction_main ($) {
5928            delete $at->{prompt};            delete $at->{prompt};
5929            my @tokens = (            my @tokens = (
5930                          {type => START_TAG_TOKEN, tag_name => 'form',                          {type => START_TAG_TOKEN, tag_name => 'form',
5931                           attributes => $form_attrs},                           attributes => $form_attrs,
5932                          {type => START_TAG_TOKEN, tag_name => 'hr'},                           line => $token->{line}, column => $token->{column}},
5933                          {type => START_TAG_TOKEN, tag_name => 'p'},                          {type => START_TAG_TOKEN, tag_name => 'hr',
5934                          {type => START_TAG_TOKEN, tag_name => 'label'},                           line => $token->{line}, column => $token->{column}},
5935                            {type => START_TAG_TOKEN, tag_name => 'p',
5936                             line => $token->{line}, column => $token->{column}},
5937                            {type => START_TAG_TOKEN, tag_name => 'label',
5938                             line => $token->{line}, column => $token->{column}},
5939                         );                         );
5940            if ($prompt_attr) {            if ($prompt_attr) {
5941              !!!cp ('t390');              !!!cp ('t390');
5942              push @tokens, {type => CHARACTER_TOKEN, data => $prompt_attr->{value}};              push @tokens, {type => CHARACTER_TOKEN, data => $prompt_attr->{value},
5943                               #line => $token->{line}, column => $token->{column},
5944                              };
5945            } else {            } else {
5946              !!!cp ('t391');              !!!cp ('t391');
5947              push @tokens, {type => CHARACTER_TOKEN,              push @tokens, {type => CHARACTER_TOKEN,
5948                             data => 'This is a searchable index. Insert your search keywords here: '}; # SHOULD                             data => 'This is a searchable index. Insert your search keywords here: ',
5949                               #line => $token->{line}, column => $token->{column},
5950                              }; # SHOULD
5951              ## TODO: make this configurable              ## TODO: make this configurable
5952            }            }
5953            push @tokens,            push @tokens,
5954                          {type => START_TAG_TOKEN, tag_name => 'input', attributes => $at},                          {type => START_TAG_TOKEN, tag_name => 'input', attributes => $at,
5955                             line => $token->{line}, column => $token->{column}},
5956                          #{type => CHARACTER_TOKEN, data => ''}, # SHOULD                          #{type => CHARACTER_TOKEN, data => ''}, # SHOULD
5957                          {type => END_TAG_TOKEN, tag_name => 'label'},                          {type => END_TAG_TOKEN, tag_name => 'label',
5958                          {type => END_TAG_TOKEN, tag_name => 'p'},                           line => $token->{line}, column => $token->{column}},
5959                          {type => START_TAG_TOKEN, tag_name => 'hr'},                          {type => END_TAG_TOKEN, tag_name => 'p',
5960                          {type => END_TAG_TOKEN, tag_name => 'form'};                           line => $token->{line}, column => $token->{column}},
5961                            {type => START_TAG_TOKEN, tag_name => 'hr',
5962                             line => $token->{line}, column => $token->{column}},
5963                            {type => END_TAG_TOKEN, tag_name => 'form',
5964                             line => $token->{line}, column => $token->{column}};
5965            $token = shift @tokens;            $token = shift @tokens;
5966            !!!back-token (@tokens);            !!!back-token (@tokens);
5967            redo B;            redo B;
# Line 5931  sub _tree_construction_main ($) { Line 5969  sub _tree_construction_main ($) {
5969        } elsif ($token->{tag_name} eq 'textarea') {        } elsif ($token->{tag_name} eq 'textarea') {
5970          my $tag_name = $token->{tag_name};          my $tag_name = $token->{tag_name};
5971          my $el;          my $el;
5972          !!!create-element ($el, $token->{tag_name}, $token->{attributes});          !!!create-element ($el, $token->{tag_name}, $token->{attributes}, $token);
5973                    
5974          ## TODO: $self->{form_element} if defined          ## TODO: $self->{form_element} if defined
5975          $self->{content_model} = RCDATA_CONTENT_MODEL;          $self->{content_model} = RCDATA_CONTENT_MODEL;
# Line 5999  sub _tree_construction_main ($) { Line 6037  sub _tree_construction_main ($) {
6037          ## NOTE: There is an "as if <br>" code clone.          ## NOTE: There is an "as if <br>" code clone.
6038          $reconstruct_active_formatting_elements->($insert_to_current);          $reconstruct_active_formatting_elements->($insert_to_current);
6039                    
6040          !!!insert-element-t ($token->{tag_name}, $token->{attributes});          !!!insert-element-t ($token->{tag_name}, $token->{attributes}, $token);
6041    
6042          if ({          if ({
6043               applet => 1, marquee => 1, object => 1,               applet => 1, marquee => 1, object => 1,
# Line 6291  sub _tree_construction_main ($) { Line 6329  sub _tree_construction_main ($) {
6329            !!!cp ('t415.1');            !!!cp ('t415.1');
6330            ## As if <p>, then reprocess the current token            ## As if <p>, then reprocess the current token
6331            my $el;            my $el;
6332            !!!create-element ($el, 'p');            !!!create-element ($el, 'p',, $token);
6333            $insert->($el);            $insert->($el);
6334            ## NOTE: Not inserted into |$self->{open_elements}|.            ## NOTE: Not inserted into |$self->{open_elements}|.
6335          }          }
# Line 6315  sub _tree_construction_main ($) { Line 6353  sub _tree_construction_main ($) {
6353          $reconstruct_active_formatting_elements->($insert_to_current);          $reconstruct_active_formatting_elements->($insert_to_current);
6354                    
6355          my $el;          my $el;
6356          !!!create-element ($el, 'br');          !!!create-element ($el, 'br',, $token);
6357          $insert->($el);          $insert->($el);
6358                    
6359          ## Ignore the token.          ## Ignore the token.
# Line 6445  sub set_inner_html ($$$) { Line 6483  sub set_inner_html ($$$) {
6483    
6484      ## Step 8 # MUST      ## Step 8 # MUST
6485      my $i = 0;      my $i = 0;
6486      my $line = 1;      $p->{line_prev} = $p->{line} = 1;
6487      my $column = 0;      $p->{column_prev} = $p->{column} = 0;
6488      $p->{set_next_char} = sub {      $p->{set_next_char} = sub {
6489        my $self = shift;        my $self = shift;
6490    
# Line 6455  sub set_inner_html ($$$) { Line 6493  sub set_inner_html ($$$) {
6493    
6494        $self->{next_char} = -1 and return if $i >= length $$s;        $self->{next_char} = -1 and return if $i >= length $$s;
6495        $self->{next_char} = ord substr $$s, $i++, 1;        $self->{next_char} = ord substr $$s, $i++, 1;
6496        $column++;  
6497          ($p->{line_prev}, $p->{column_prev}) = ($p->{line}, $p->{column});
6498          $p->{column}++;
6499    
6500        if ($self->{next_char} == 0x000A) { # LF        if ($self->{next_char} == 0x000A) { # LF
6501          $line++;          $p->{line}++;
6502          $column = 0;          $p->{column} = 0;
6503          !!!cp ('i1');          !!!cp ('i1');
6504        } elsif ($self->{next_char} == 0x000D) { # CR        } elsif ($self->{next_char} == 0x000D) { # CR
6505          $i++ if substr ($$s, $i, 1) eq "\x0A";          $i++ if substr ($$s, $i, 1) eq "\x0A";
6506          $self->{next_char} = 0x000A; # LF # MUST          $self->{next_char} = 0x000A; # LF # MUST
6507          $line++;          $p->{line}++;
6508          $column = 0;          $p->{column} = 0;
6509          !!!cp ('i2');          !!!cp ('i2');
6510        } elsif ($self->{next_char} > 0x10FFFF) {        } elsif ($self->{next_char} > 0x10FFFF) {
6511          $self->{next_char} = 0xFFFD; # REPLACEMENT CHARACTER # MUST          $self->{next_char} = 0xFFFD; # REPLACEMENT CHARACTER # MUST
# Line 6481  sub set_inner_html ($$$) { Line 6521  sub set_inner_html ($$$) {
6521            
6522      my $ponerror = $onerror || sub {      my $ponerror = $onerror || sub {
6523        my (%opt) = @_;        my (%opt) = @_;
6524        warn "Parse error ($opt{type}) at line $opt{line} column $opt{column}\n";        my $line = $opt{line};
6525          my $column = $opt{column};
6526          if (defined $opt{token} and defined $opt{token}->{line}) {
6527            $line = $opt{token}->{line};
6528            $column = $opt{token}->{column};
6529          }
6530          warn "Parse error ($opt{type}) at line $line column $column\n";
6531      };      };
6532      $p->{parse_error} = sub {      $p->{parse_error} = sub {
6533        $ponerror->(@_, line => $line, column => $column);        $ponerror->(line => $p->{line}, column => $p->{column}, @_);
6534      };      };
6535            
6536      $p->_initialize_tokenizer;      $p->_initialize_tokenizer;
# Line 6564  sub set_inner_html ($$$) { Line 6610  sub set_inner_html ($$$) {
6610      ## ISSUE: mutation events?      ## ISSUE: mutation events?
6611    
6612      $p->_terminate_tree_constructor;      $p->_terminate_tree_constructor;
6613    
6614        delete $p->{parse_error}; # delete loop
6615    } else {    } else {
6616      die "$0: |set_inner_html| is not defined for node of type $nt";      die "$0: |set_inner_html| is not defined for node of type $nt";
6617    }    }

Legend:
Removed from v.1.113  
changed lines
  Added in v.1.121

[email protected]
ViewVC Help
Powered by ViewVC 1.1.24