/[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.158 by wakaba, Sun Aug 31 12:11:42 2008 UTC revision 1.166 by wakaba, Sat Sep 13 08:21:35 2008 UTC
# Line 354  sub parse_byte_string ($$$$;$) { Line 354  sub parse_byte_string ($$$$;$) {
354    return $self->parse_byte_stream ($charset_name, $input, @_[1..$#_]);    return $self->parse_byte_stream ($charset_name, $input, @_[1..$#_]);
355  } # parse_byte_string  } # parse_byte_string
356    
357  sub parse_byte_stream ($$$$;$) {  sub parse_byte_stream ($$$$;$$) {
358      # my ($self, $charset_name, $byte_stream, $doc, $onerror, $get_wrapper) = @_;
359    my $self = ref $_[0] ? shift : shift->new;    my $self = ref $_[0] ? shift : shift->new;
360    my $charset_name = shift;    my $charset_name = shift;
361    my $byte_stream = $_[0];    my $byte_stream = $_[0];
# Line 365  sub parse_byte_stream ($$$$;$) { Line 366  sub parse_byte_stream ($$$$;$) {
366    };    };
367    $self->{parse_error} = $onerror; # updated later by parse_char_string    $self->{parse_error} = $onerror; # updated later by parse_char_string
368    
369      my $get_wrapper = $_[3] || sub ($) {
370        return $_[0]; # $_[0] = byte stream handle, returned = arg to char handle
371      };
372    
373    ## HTML5 encoding sniffing algorithm    ## HTML5 encoding sniffing algorithm
374    require Message::Charset::Info;    require Message::Charset::Info;
375    my $charset;    my $charset;
# Line 372  sub parse_byte_stream ($$$$;$) { Line 377  sub parse_byte_stream ($$$$;$) {
377    my ($char_stream, $e_status);    my ($char_stream, $e_status);
378    
379    SNIFFING: {    SNIFFING: {
380        ## NOTE: By setting |allow_fallback| option true when the
381        ## |get_decode_handle| method is invoked, we ignore what the HTML5
382        ## spec requires, i.e. unsupported encoding should be ignored.
383          ## TODO: We should not do this unless the parser is invoked
384          ## in the conformance checking mode, in which this behavior
385          ## would be useful.
386    
387      ## Step 1      ## Step 1
388      if (defined $charset_name) {      if (defined $charset_name) {
389        $charset = Message::Charset::Info->get_by_iana_name ($charset_name);        $charset = Message::Charset::Info->get_by_html_name ($charset_name);
390              ## TODO: Is this ok?  Transfer protocol's parameter should be
391              ## interpreted in its semantics?
392    
393        ## ISSUE: Unsupported encoding is not ignored according to the spec.        ## ISSUE: Unsupported encoding is not ignored according to the spec.
394        ($char_stream, $e_status) = $charset->get_decode_handle        ($char_stream, $e_status) = $charset->get_decode_handle
# Line 399  sub parse_byte_stream ($$$$;$) { Line 412  sub parse_byte_stream ($$$$;$) {
412    
413      ## Step 3      ## Step 3
414      if ($byte_buffer =~ /^\xFE\xFF/) {      if ($byte_buffer =~ /^\xFE\xFF/) {
415        $charset = Message::Charset::Info->get_by_iana_name ('utf-16be');        $charset = Message::Charset::Info->get_by_html_name ('utf-16be');
416        ($char_stream, $e_status) = $charset->get_decode_handle        ($char_stream, $e_status) = $charset->get_decode_handle
417            ($byte_stream, allow_error_reporting => 1,            ($byte_stream, allow_error_reporting => 1,
418             allow_fallback => 1, byte_buffer => \$byte_buffer);             allow_fallback => 1, byte_buffer => \$byte_buffer);
419        $self->{confident} = 1;        $self->{confident} = 1;
420        last SNIFFING;        last SNIFFING;
421      } elsif ($byte_buffer =~ /^\xFF\xFE/) {      } elsif ($byte_buffer =~ /^\xFF\xFE/) {
422        $charset = Message::Charset::Info->get_by_iana_name ('utf-16le');        $charset = Message::Charset::Info->get_by_html_name ('utf-16le');
423        ($char_stream, $e_status) = $charset->get_decode_handle        ($char_stream, $e_status) = $charset->get_decode_handle
424            ($byte_stream, allow_error_reporting => 1,            ($byte_stream, allow_error_reporting => 1,
425             allow_fallback => 1, byte_buffer => \$byte_buffer);             allow_fallback => 1, byte_buffer => \$byte_buffer);
426        $self->{confident} = 1;        $self->{confident} = 1;
427        last SNIFFING;        last SNIFFING;
428      } elsif ($byte_buffer =~ /^\xEF\xBB\xBF/) {      } elsif ($byte_buffer =~ /^\xEF\xBB\xBF/) {
429        $charset = Message::Charset::Info->get_by_iana_name ('utf-8');        $charset = Message::Charset::Info->get_by_html_name ('utf-8');
430        ($char_stream, $e_status) = $charset->get_decode_handle        ($char_stream, $e_status) = $charset->get_decode_handle
431            ($byte_stream, allow_error_reporting => 1,            ($byte_stream, allow_error_reporting => 1,
432             allow_fallback => 1, byte_buffer => \$byte_buffer);             allow_fallback => 1, byte_buffer => \$byte_buffer);
# Line 432  sub parse_byte_stream ($$$$;$) { Line 445  sub parse_byte_stream ($$$$;$) {
445      $charset_name = Whatpm::Charset::UniversalCharDet->detect_byte_string      $charset_name = Whatpm::Charset::UniversalCharDet->detect_byte_string
446          ($byte_buffer);          ($byte_buffer);
447      if (defined $charset_name) {      if (defined $charset_name) {
448        $charset = Message::Charset::Info->get_by_iana_name ($charset_name);        $charset = Message::Charset::Info->get_by_html_name ($charset_name);
449    
450        ## ISSUE: Unsupported encoding is not ignored according to the spec.        ## ISSUE: Unsupported encoding is not ignored according to the spec.
451        require Whatpm::Charset::DecodeHandle;        require Whatpm::Charset::DecodeHandle;
# Line 455  sub parse_byte_stream ($$$$;$) { Line 468  sub parse_byte_stream ($$$$;$) {
468    
469      ## Step 7: default      ## Step 7: default
470      ## TODO: Make this configurable.      ## TODO: Make this configurable.
471      $charset = Message::Charset::Info->get_by_iana_name ('windows-1252');      $charset = Message::Charset::Info->get_by_html_name ('windows-1252');
472          ## NOTE: We choose |windows-1252| here, since |utf-8| should be          ## NOTE: We choose |windows-1252| here, since |utf-8| should be
473          ## detectable in the step 6.          ## detectable in the step 6.
474      require Whatpm::Charset::DecodeHandle;      require Whatpm::Charset::DecodeHandle;
# Line 475  sub parse_byte_stream ($$$$;$) { Line 488  sub parse_byte_stream ($$$$;$) {
488      $self->{confident} = 0;      $self->{confident} = 0;
489    } # SNIFFING    } # SNIFFING
490    
   $self->{input_encoding} = $charset->get_iana_name;  
491    if ($e_status & Message::Charset::Info::FALLBACK_ENCODING_IMPL ()) {    if ($e_status & Message::Charset::Info::FALLBACK_ENCODING_IMPL ()) {
492        $self->{input_encoding} = $charset->get_iana_name; ## TODO: Should we set actual charset decoder's encoding name?
493      !!!parse-error (type => 'chardecode:fallback',      !!!parse-error (type => 'chardecode:fallback',
494                      text => $self->{input_encoding},                      #text => $self->{input_encoding},
495                      level => $self->{level}->{uncertain},                      level => $self->{level}->{uncertain},
496                      line => 1, column => 1,                      line => 1, column => 1,
497                      layer => 'encode');                      layer => 'encode');
498    } elsif (not ($e_status &    } elsif (not ($e_status &
499                  Message::Charset::Info::ERROR_REPORTING_ENCODING_IMPL())) {                  Message::Charset::Info::ERROR_REPORTING_ENCODING_IMPL())) {
500        $self->{input_encoding} = $charset->get_iana_name;
501      !!!parse-error (type => 'chardecode:no error',      !!!parse-error (type => 'chardecode:no error',
502                      text => $self->{input_encoding},                      text => $self->{input_encoding},
503                      level => $self->{level}->{uncertain},                      level => $self->{level}->{uncertain},
504                      line => 1, column => 1,                      line => 1, column => 1,
505                      layer => 'encode');                      layer => 'encode');
506      } else {
507        $self->{input_encoding} = $charset->get_iana_name;
508    }    }
509    
510    $self->{change_encoding} = sub {    $self->{change_encoding} = sub {
# Line 496  sub parse_byte_stream ($$$$;$) { Line 512  sub parse_byte_stream ($$$$;$) {
512      $charset_name = shift;      $charset_name = shift;
513      my $token = shift;      my $token = shift;
514    
515      $charset = Message::Charset::Info->get_by_iana_name ($charset_name);      $charset = Message::Charset::Info->get_by_html_name ($charset_name);
516      ($char_stream, $e_status) = $charset->get_decode_handle      ($char_stream, $e_status) = $charset->get_decode_handle
517          ($byte_stream, allow_error_reporting => 1, allow_fallback => 1,          ($byte_stream, allow_error_reporting => 1, allow_fallback => 1,
518           byte_buffer => \ $buffer->{buffer});           byte_buffer => \ $buffer->{buffer});
# Line 507  sub parse_byte_stream ($$$$;$) { Line 523  sub parse_byte_stream ($$$$;$) {
523        ## Step 1            ## Step 1    
524        if ($charset->{category} &        if ($charset->{category} &
525            Message::Charset::Info::CHARSET_CATEGORY_UTF16 ()) {            Message::Charset::Info::CHARSET_CATEGORY_UTF16 ()) {
526          $charset = Message::Charset::Info->get_by_iana_name ('utf-8');          $charset = Message::Charset::Info->get_by_html_name ('utf-8');
527          ($char_stream, $e_status) = $charset->get_decode_handle          ($char_stream, $e_status) = $charset->get_decode_handle
528              ($byte_stream,              ($byte_stream,
529               byte_buffer => \ $buffer->{buffer});               byte_buffer => \ $buffer->{buffer});
# Line 551  sub parse_byte_stream ($$$$;$) { Line 567  sub parse_byte_stream ($$$$;$) {
567        ${$opt{octets}} = "\x{FFFD}"; # relacement character        ${$opt{octets}} = "\x{FFFD}"; # relacement character
568      }      }
569    };    };
570    $char_stream->onerror ($char_onerror);  
571      my $wrapped_char_stream = $get_wrapper->($char_stream);
572      $wrapped_char_stream->onerror ($char_onerror);
573    
574    my @args = @_; shift @args; # $s    my @args = @_; shift @args; # $s
575    my $return;    my $return;
576    try {    try {
577      $return = $self->parse_char_stream ($char_stream, @args);        $return = $self->parse_char_stream ($wrapped_char_stream, @args);  
578    } catch Whatpm::HTML::RestartParser with {    } catch Whatpm::HTML::RestartParser with {
579      ## NOTE: Invoked after {change_encoding}.      ## NOTE: Invoked after {change_encoding}.
580    
     $self->{input_encoding} = $charset->get_iana_name;  
581      if ($e_status & Message::Charset::Info::FALLBACK_ENCODING_IMPL ()) {      if ($e_status & Message::Charset::Info::FALLBACK_ENCODING_IMPL ()) {
582          $self->{input_encoding} = $charset->get_iana_name; ## TODO: Should we set actual charset decoder's encoding name?
583        !!!parse-error (type => 'chardecode:fallback',        !!!parse-error (type => 'chardecode:fallback',
                       text => $self->{input_encoding},  
584                        level => $self->{level}->{uncertain},                        level => $self->{level}->{uncertain},
585                          #text => $self->{input_encoding},
586                        line => 1, column => 1,                        line => 1, column => 1,
587                        layer => 'encode');                        layer => 'encode');
588      } elsif (not ($e_status &      } elsif (not ($e_status &
589                    Message::Charset::Info::ERROR_REPORTING_ENCODING_IMPL())) {                    Message::Charset::Info::ERROR_REPORTING_ENCODING_IMPL())) {
590          $self->{input_encoding} = $charset->get_iana_name;
591        !!!parse-error (type => 'chardecode:no error',        !!!parse-error (type => 'chardecode:no error',
592                        text => $self->{input_encoding},                        text => $self->{input_encoding},
593                        level => $self->{level}->{uncertain},                        level => $self->{level}->{uncertain},
594                        line => 1, column => 1,                        line => 1, column => 1,
595                        layer => 'encode');                        layer => 'encode');
596        } else {
597          $self->{input_encoding} = $charset->get_iana_name;
598      }      }
599      $self->{confident} = 1;      $self->{confident} = 1;
600      $char_stream->onerror ($char_onerror);  
601      $return = $self->parse_char_stream ($char_stream, @args);      $wrapped_char_stream = $get_wrapper->($char_stream);
602        $wrapped_char_stream->onerror ($char_onerror);
603    
604        $return = $self->parse_char_stream ($wrapped_char_stream, @args);
605    };    };
606    return $return;    return $return;
607  } # parse_byte_stream  } # parse_byte_stream
# Line 591  sub parse_byte_stream ($$$$;$) { Line 615  sub parse_byte_stream ($$$$;$) {
615  ## such as |parse_byte_string| in this module, must ensure that it does  ## such as |parse_byte_string| in this module, must ensure that it does
616  ## strip the BOM and never strip any ZWNBSP.  ## strip the BOM and never strip any ZWNBSP.
617    
618  sub parse_char_string ($$$;$) {  sub parse_char_string ($$$;$$) {
619      #my ($self, $s, $doc, $onerror, $get_wrapper) = @_;
620    my $self = shift;    my $self = shift;
621    require utf8;    require utf8;
622    my $s = ref $_[0] ? $_[0] : \($_[0]);    my $s = ref $_[0] ? $_[0] : \($_[0]);
623    open my $input, '<' . (utf8::is_utf8 ($$s) ? ':utf8' : ''), $s;    open my $input, '<' . (utf8::is_utf8 ($$s) ? ':utf8' : ''), $s;
624      if ($_[3]) {
625        $input = $_[3]->($input);
626      }
627    return $self->parse_char_stream ($input, @_[1..$#_]);    return $self->parse_char_stream ($input, @_[1..$#_]);
628  } # parse_char_string  } # parse_char_string
629  *parse_string = \&parse_char_string;  *parse_string = \&parse_char_string; ## NOTE: Alias for backward compatibility.
630    
631  sub parse_char_stream ($$$;$) {  sub parse_char_stream ($$$;$) {
632    my $self = ref $_[0] ? shift : shift->new;    my $self = ref $_[0] ? shift : shift->new;
# Line 708  sub new ($) { Line 736  sub new ($) {
736    my $class = shift;    my $class = shift;
737    my $self = bless {    my $self = bless {
738      level => {must => 'm',      level => {must => 'm',
739                  should => 's',
740                warn => 'w',                warn => 'w',
741                info => 'i',                info => 'i',
742                uncertain => 'u'},                uncertain => 'u'},
# Line 774  sub AFTER_DOCTYPE_SYSTEM_IDENTIFIER_STAT Line 803  sub AFTER_DOCTYPE_SYSTEM_IDENTIFIER_STAT
803  sub BOGUS_DOCTYPE_STATE () { 32 }  sub BOGUS_DOCTYPE_STATE () { 32 }
804  sub AFTER_ATTRIBUTE_VALUE_QUOTED_STATE () { 33 }  sub AFTER_ATTRIBUTE_VALUE_QUOTED_STATE () { 33 }
805  sub SELF_CLOSING_START_TAG_STATE () { 34 }  sub SELF_CLOSING_START_TAG_STATE () { 34 }
806  sub CDATA_BLOCK_STATE () { 35 }  sub CDATA_SECTION_STATE () { 35 }
807    sub MD_HYPHEN_STATE () { 36 } # "markup declaration open state" in the spec
808    sub MD_DOCTYPE_STATE () { 37 } # "markup declaration open state" in the spec
809    sub MD_CDATA_STATE () { 38 } # "markup declaration open state" in the spec
810    sub CDATA_PCDATA_CLOSE_TAG_STATE () { 39 } # "close tag open state" in the spec
811    sub CDATA_SECTION_MSE1_STATE () { 40 } # "CDATA section state" in the spec
812    sub CDATA_SECTION_MSE2_STATE () { 41 } # "CDATA section state" in the spec
813    sub PUBLIC_STATE () { 42 } # "after DOCTYPE name state" in the spec
814    sub SYSTEM_STATE () { 43 } # "after DOCTYPE name state" in the spec
815    
816  sub DOCTYPE_TOKEN () { 1 }  sub DOCTYPE_TOKEN () { 1 }
817  sub COMMENT_TOKEN () { 2 }  sub COMMENT_TOKEN () { 2 }
# Line 827  sub IN_COLUMN_GROUP_IM () { 0b10 } Line 864  sub IN_COLUMN_GROUP_IM () { 0b10 }
864  sub _initialize_tokenizer ($) {  sub _initialize_tokenizer ($) {
865    my $self = shift;    my $self = shift;
866    $self->{state} = DATA_STATE; # MUST    $self->{state} = DATA_STATE; # MUST
867      #$self->{state_keyword}; # initialized when used
868    $self->{content_model} = PCDATA_CONTENT_MODEL; # be    $self->{content_model} = PCDATA_CONTENT_MODEL; # be
869    undef $self->{current_token}; # start tag, end tag, comment, or DOCTYPE    undef $self->{current_token};
870    undef $self->{current_attribute};    undef $self->{current_attribute};
871    undef $self->{last_emitted_start_tag_name};    undef $self->{last_emitted_start_tag_name};
872    undef $self->{last_attribute_value_state};    undef $self->{last_attribute_value_state};
# Line 1089  sub _get_next_token ($) { Line 1127  sub _get_next_token ($) {
1127          die "$0: $self->{content_model} in tag open";          die "$0: $self->{content_model} in tag open";
1128        }        }
1129      } elsif ($self->{state} == CLOSE_TAG_OPEN_STATE) {      } elsif ($self->{state} == CLOSE_TAG_OPEN_STATE) {
1130          ## NOTE: The "close tag open state" in the spec is implemented as
1131          ## |CLOSE_TAG_OPEN_STATE| and |CDATA_PCDATA_CLOSE_TAG_STATE|.
1132    
1133        my ($l, $c) = ($self->{line_prev}, $self->{column_prev} - 1); # "<"of"</"        my ($l, $c) = ($self->{line_prev}, $self->{column_prev} - 1); # "<"of"</"
1134        if ($self->{content_model} & CM_LIMITED_MARKUP) { # RCDATA | CDATA        if ($self->{content_model} & CM_LIMITED_MARKUP) { # RCDATA | CDATA
1135          if (defined $self->{last_emitted_start_tag_name}) {          if (defined $self->{last_emitted_start_tag_name}) {
1136              $self->{state} = CDATA_PCDATA_CLOSE_TAG_STATE;
1137            ## NOTE: <http://krijnhoetmer.nl/irc-logs/whatwg/20070626#l-564>            $self->{state_keyword} = '';
1138            my @next_char;            ## Reconsume.
1139            TAGNAME: for (my $i = 0; $i < length $self->{last_emitted_start_tag_name}; $i++) {            redo A;
             push @next_char, $self->{next_char};  
             my $c = ord substr ($self->{last_emitted_start_tag_name}, $i, 1);  
             my $C = 0x0061 <= $c && $c <= 0x007A ? $c - 0x0020 : $c;  
             if ($self->{next_char} == $c or $self->{next_char} == $C) {  
               !!!cp (24);  
               !!!next-input-character;  
               next TAGNAME;  
             } else {  
               !!!cp (25);  
               $self->{next_char} = shift @next_char; # reconsume  
               !!!back-next-input-character (@next_char);  
               $self->{state} = DATA_STATE;  
   
               !!!emit ({type => CHARACTER_TOKEN, data => '</',  
                         line => $l, column => $c,  
                        });  
     
               redo A;  
             }  
           }  
           push @next_char, $self->{next_char};  
         
           unless ($self->{next_char} == 0x0009 or # HT  
                   $self->{next_char} == 0x000A or # LF  
                   $self->{next_char} == 0x000B or # VT  
                   $self->{next_char} == 0x000C or # FF  
                   $self->{next_char} == 0x0020 or # SP  
                   $self->{next_char} == 0x003E or # >  
                   $self->{next_char} == 0x002F or # /  
                   $self->{next_char} == -1) {  
             !!!cp (26);  
             $self->{next_char} = shift @next_char; # reconsume  
             !!!back-next-input-character (@next_char);  
             $self->{state} = DATA_STATE;  
             !!!emit ({type => CHARACTER_TOKEN, data => '</',  
                       line => $l, column => $c,  
                      });  
             redo A;  
           } else {  
             !!!cp (27);  
             $self->{next_char} = shift @next_char;  
             !!!back-next-input-character (@next_char);  
             # and consume...  
           }  
1140          } else {          } else {
1141            ## No start tag token has ever been emitted            ## No start tag token has ever been emitted
1142              ## NOTE: See <http://krijnhoetmer.nl/irc-logs/whatwg/20070626#l-564>.
1143            !!!cp (28);            !!!cp (28);
           # next-input-character is already done  
1144            $self->{state} = DATA_STATE;            $self->{state} = DATA_STATE;
1145              ## Reconsume.
1146            !!!emit ({type => CHARACTER_TOKEN, data => '</',            !!!emit ({type => CHARACTER_TOKEN, data => '</',
1147                      line => $l, column => $c,                      line => $l, column => $c,
1148                     });                     });
1149            redo A;            redo A;
1150          }          }
1151        }        }
1152          
1153        if (0x0041 <= $self->{next_char} and        if (0x0041 <= $self->{next_char} and
1154            $self->{next_char} <= 0x005A) { # A..Z            $self->{next_char} <= 0x005A) { # A..Z
1155          !!!cp (29);          !!!cp (29);
# Line 1198  sub _get_next_token ($) { Line 1196  sub _get_next_token ($) {
1196                                    line => $self->{line_prev}, # "<" of "</"                                    line => $self->{line_prev}, # "<" of "</"
1197                                    column => $self->{column_prev} - 1,                                    column => $self->{column_prev} - 1,
1198                                   };                                   };
1199          ## $self->{next_char} is intentionally left as is          ## NOTE: $self->{next_char} is intentionally left as is.
1200          redo A;          ## Although the "anything else" case of the spec not explicitly
1201            ## states that the next input character is to be reconsumed,
1202            ## it will be included to the |data| of the comment token
1203            ## generated from the bogus end tag, as defined in the
1204            ## "bogus comment state" entry.
1205            redo A;
1206          }
1207        } elsif ($self->{state} == CDATA_PCDATA_CLOSE_TAG_STATE) {
1208          my $ch = substr $self->{last_emitted_start_tag_name}, length $self->{state_keyword}, 1;
1209          if (length $ch) {
1210            my $CH = $ch;
1211            $ch =~ tr/a-z/A-Z/;
1212            my $nch = chr $self->{next_char};
1213            if ($nch eq $ch or $nch eq $CH) {
1214              !!!cp (24);
1215              ## Stay in the state.
1216              $self->{state_keyword} .= $nch;
1217              !!!next-input-character;
1218              redo A;
1219            } else {
1220              !!!cp (25);
1221              $self->{state} = DATA_STATE;
1222              ## Reconsume.
1223              !!!emit ({type => CHARACTER_TOKEN,
1224                        data => '</' . $self->{state_keyword},
1225                        line => $self->{line_prev},
1226                        column => $self->{column_prev} - 1 - length $self->{state_keyword},
1227                       });
1228              redo A;
1229            }
1230          } else { # after "<{tag-name}"
1231            unless ({
1232                     0x0009 => 1, # HT
1233                     0x000A => 1, # LF
1234                     0x000B => 1, # VT
1235                     0x000C => 1, # FF
1236                     0x0020 => 1, # SP
1237                     0x003E => 1, # >
1238                     0x002F => 1, # /
1239                     -1 => 1, # EOF
1240                    }->{$self->{next_char}}) {
1241              !!!cp (26);
1242              ## Reconsume.
1243              $self->{state} = DATA_STATE;
1244              !!!emit ({type => CHARACTER_TOKEN,
1245                        data => '</' . $self->{state_keyword},
1246                        line => $self->{line_prev},
1247                        column => $self->{column_prev} - 1 - length $self->{state_keyword},
1248                       });
1249              redo A;
1250            } else {
1251              !!!cp (27);
1252              $self->{current_token}
1253                  = {type => END_TAG_TOKEN,
1254                     tag_name => $self->{last_emitted_start_tag_name},
1255                     line => $self->{line_prev},
1256                     column => $self->{column_prev} - 1 - length $self->{state_keyword}};
1257              $self->{state} = TAG_NAME_STATE;
1258              ## Reconsume.
1259              redo A;
1260            }
1261        }        }
1262      } elsif ($self->{state} == TAG_NAME_STATE) {      } elsif ($self->{state} == TAG_NAME_STATE) {
1263        if ($self->{next_char} == 0x0009 or # HT        if ($self->{next_char} == 0x0009 or # HT
# Line 1972  sub _get_next_token ($) { Line 2030  sub _get_next_token ($) {
2030        die "$0: _get_next_token: unexpected case [BC]";        die "$0: _get_next_token: unexpected case [BC]";
2031      } elsif ($self->{state} == MARKUP_DECLARATION_OPEN_STATE) {      } elsif ($self->{state} == MARKUP_DECLARATION_OPEN_STATE) {
2032        ## (only happen if PCDATA state)        ## (only happen if PCDATA state)
   
       my ($l, $c) = ($self->{line_prev}, $self->{column_prev} - 1);  
   
       my @next_char;  
       push @next_char, $self->{next_char};  
2033                
2034        if ($self->{next_char} == 0x002D) { # -        if ($self->{next_char} == 0x002D) { # -
2035            !!!cp (133);
2036            $self->{state} = MD_HYPHEN_STATE;
2037          !!!next-input-character;          !!!next-input-character;
2038          push @next_char, $self->{next_char};          redo A;
         if ($self->{next_char} == 0x002D) { # -  
           !!!cp (127);  
           $self->{current_token} = {type => COMMENT_TOKEN, data => '',  
                                     line => $l, column => $c,  
                                    };  
           $self->{state} = COMMENT_START_STATE;  
           !!!next-input-character;  
           redo A;  
         } else {  
           !!!cp (128);  
         }  
2039        } elsif ($self->{next_char} == 0x0044 or # D        } elsif ($self->{next_char} == 0x0044 or # D
2040                 $self->{next_char} == 0x0064) { # d                 $self->{next_char} == 0x0064) { # d
2041            ## ASCII case-insensitive.
2042            !!!cp (130);
2043            $self->{state} = MD_DOCTYPE_STATE;
2044            $self->{state_keyword} = chr $self->{next_char};
2045          !!!next-input-character;          !!!next-input-character;
2046          push @next_char, $self->{next_char};          redo A;
         if ($self->{next_char} == 0x004F or # O  
             $self->{next_char} == 0x006F) { # o  
           !!!next-input-character;  
           push @next_char, $self->{next_char};  
           if ($self->{next_char} == 0x0043 or # C  
               $self->{next_char} == 0x0063) { # c  
             !!!next-input-character;  
             push @next_char, $self->{next_char};  
             if ($self->{next_char} == 0x0054 or # T  
                 $self->{next_char} == 0x0074) { # t  
               !!!next-input-character;  
               push @next_char, $self->{next_char};  
               if ($self->{next_char} == 0x0059 or # Y  
                   $self->{next_char} == 0x0079) { # y  
                 !!!next-input-character;  
                 push @next_char, $self->{next_char};  
                 if ($self->{next_char} == 0x0050 or # P  
                     $self->{next_char} == 0x0070) { # p  
                   !!!next-input-character;  
                   push @next_char, $self->{next_char};  
                   if ($self->{next_char} == 0x0045 or # E  
                       $self->{next_char} == 0x0065) { # e  
                     !!!cp (129);  
                     ## TODO: What a stupid code this is!  
                     $self->{state} = DOCTYPE_STATE;  
                     $self->{current_token} = {type => DOCTYPE_TOKEN,  
                                               quirks => 1,  
                                               line => $l, column => $c,  
                                              };  
                     !!!next-input-character;  
                     redo A;  
                   } else {  
                     !!!cp (130);  
                   }  
                 } else {  
                   !!!cp (131);  
                 }  
               } else {  
                 !!!cp (132);  
               }  
             } else {  
               !!!cp (133);  
             }  
           } else {  
             !!!cp (134);  
           }  
         } else {  
           !!!cp (135);  
         }  
2047        } elsif ($self->{insertion_mode} & IN_FOREIGN_CONTENT_IM and        } elsif ($self->{insertion_mode} & IN_FOREIGN_CONTENT_IM and
2048                 $self->{open_elements}->[-1]->[1] & FOREIGN_EL and                 $self->{open_elements}->[-1]->[1] & FOREIGN_EL and
2049                 $self->{next_char} == 0x005B) { # [                 $self->{next_char} == 0x005B) { # [
2050            !!!cp (135.4);                
2051            $self->{state} = MD_CDATA_STATE;
2052            $self->{state_keyword} = '[';
2053          !!!next-input-character;          !!!next-input-character;
2054          push @next_char, $self->{next_char};          redo A;
         if ($self->{next_char} == 0x0043) { # C  
           !!!next-input-character;  
           push @next_char, $self->{next_char};  
           if ($self->{next_char} == 0x0044) { # D  
             !!!next-input-character;  
             push @next_char, $self->{next_char};  
             if ($self->{next_char} == 0x0041) { # A  
               !!!next-input-character;  
               push @next_char, $self->{next_char};  
               if ($self->{next_char} == 0x0054) { # T  
                 !!!next-input-character;  
                 push @next_char, $self->{next_char};  
                 if ($self->{next_char} == 0x0041) { # A  
                   !!!next-input-character;  
                   push @next_char, $self->{next_char};  
                   if ($self->{next_char} == 0x005B) { # [  
                     !!!cp (135.1);  
                     $self->{state} = CDATA_BLOCK_STATE;  
                     !!!next-input-character;  
                     redo A;  
                   } else {  
                     !!!cp (135.2);  
                   }  
                 } else {  
                   !!!cp (135.3);  
                 }  
               } else {  
                 !!!cp (135.4);                  
               }  
             } else {  
               !!!cp (135.5);  
             }  
           } else {  
             !!!cp (135.6);  
           }  
         } else {  
           !!!cp (135.7);  
         }  
2055        } else {        } else {
2056          !!!cp (136);          !!!cp (136);
2057        }        }
2058    
2059        !!!parse-error (type => 'bogus comment');        !!!parse-error (type => 'bogus comment',
2060        $self->{next_char} = shift @next_char;                        line => $self->{line_prev},
2061        !!!back-next-input-character (@next_char);                        column => $self->{column_prev} - 1);
2062          ## Reconsume.
2063        $self->{state} = BOGUS_COMMENT_STATE;        $self->{state} = BOGUS_COMMENT_STATE;
2064        $self->{current_token} = {type => COMMENT_TOKEN, data => '',        $self->{current_token} = {type => COMMENT_TOKEN, data => '',
2065                                  line => $l, column => $c,                                  line => $self->{line_prev},
2066                                    column => $self->{column_prev} - 1,
2067                                 };                                 };
2068        redo A;        redo A;
2069              } elsif ($self->{state} == MD_HYPHEN_STATE) {
2070        ## ISSUE: typos in spec: chacacters, is is a parse error        if ($self->{next_char} == 0x002D) { # -
2071        ## ISSUE: spec is somewhat unclear on "is the first character that will be in the comment"; what is "that will be in the comment" is what the algorithm defines, isn't it?          !!!cp (127);
2072            $self->{current_token} = {type => COMMENT_TOKEN, data => '',
2073                                      line => $self->{line_prev},
2074                                      column => $self->{column_prev} - 2,
2075                                     };
2076            $self->{state} = COMMENT_START_STATE;
2077            !!!next-input-character;
2078            redo A;
2079          } else {
2080            !!!cp (128);
2081            !!!parse-error (type => 'bogus comment',
2082                            line => $self->{line_prev},
2083                            column => $self->{column_prev} - 2);
2084            $self->{state} = BOGUS_COMMENT_STATE;
2085            ## Reconsume.
2086            $self->{current_token} = {type => COMMENT_TOKEN,
2087                                      data => '-',
2088                                      line => $self->{line_prev},
2089                                      column => $self->{column_prev} - 2,
2090                                     };
2091            redo A;
2092          }
2093        } elsif ($self->{state} == MD_DOCTYPE_STATE) {
2094          ## ASCII case-insensitive.
2095          if ($self->{next_char} == [
2096                undef,
2097                0x004F, # O
2098                0x0043, # C
2099                0x0054, # T
2100                0x0059, # Y
2101                0x0050, # P
2102              ]->[length $self->{state_keyword}] or
2103              $self->{next_char} == [
2104                undef,
2105                0x006F, # o
2106                0x0063, # c
2107                0x0074, # t
2108                0x0079, # y
2109                0x0070, # p
2110              ]->[length $self->{state_keyword}]) {
2111            !!!cp (131);
2112            ## Stay in the state.
2113            $self->{state_keyword} .= chr $self->{next_char};
2114            !!!next-input-character;
2115            redo A;
2116          } elsif ((length $self->{state_keyword}) == 6 and
2117                   ($self->{next_char} == 0x0045 or # E
2118                    $self->{next_char} == 0x0065)) { # e
2119            !!!cp (129);
2120            $self->{state} = DOCTYPE_STATE;
2121            $self->{current_token} = {type => DOCTYPE_TOKEN,
2122                                      quirks => 1,
2123                                      line => $self->{line_prev},
2124                                      column => $self->{column_prev} - 7,
2125                                     };
2126            !!!next-input-character;
2127            redo A;
2128          } else {
2129            !!!cp (132);        
2130            !!!parse-error (type => 'bogus comment',
2131                            line => $self->{line_prev},
2132                            column => $self->{column_prev} - 1 - length $self->{state_keyword});
2133            $self->{state} = BOGUS_COMMENT_STATE;
2134            ## Reconsume.
2135            $self->{current_token} = {type => COMMENT_TOKEN,
2136                                      data => $self->{state_keyword},
2137                                      line => $self->{line_prev},
2138                                      column => $self->{column_prev} - 1 - length $self->{state_keyword},
2139                                     };
2140            redo A;
2141          }
2142        } elsif ($self->{state} == MD_CDATA_STATE) {
2143          if ($self->{next_char} == {
2144                '[' => 0x0043, # C
2145                '[C' => 0x0044, # D
2146                '[CD' => 0x0041, # A
2147                '[CDA' => 0x0054, # T
2148                '[CDAT' => 0x0041, # A
2149              }->{$self->{state_keyword}}) {
2150            !!!cp (135.1);
2151            ## Stay in the state.
2152            $self->{state_keyword} .= chr $self->{next_char};
2153            !!!next-input-character;
2154            redo A;
2155          } elsif ($self->{state_keyword} eq '[CDATA' and
2156                   $self->{next_char} == 0x005B) { # [
2157            !!!cp (135.2);
2158            $self->{current_token} = {type => CHARACTER_TOKEN,
2159                                      data => '',
2160                                      line => $self->{line_prev},
2161                                      column => $self->{column_prev} - 7};
2162            $self->{state} = CDATA_SECTION_STATE;
2163            !!!next-input-character;
2164            redo A;
2165          } else {
2166            !!!cp (135.3);
2167            !!!parse-error (type => 'bogus comment',
2168                            line => $self->{line_prev},
2169                            column => $self->{column_prev} - 1 - length $self->{state_keyword});
2170            $self->{state} = BOGUS_COMMENT_STATE;
2171            ## Reconsume.
2172            $self->{current_token} = {type => COMMENT_TOKEN,
2173                                      data => $self->{state_keyword},
2174                                      line => $self->{line_prev},
2175                                      column => $self->{column_prev} - 1 - length $self->{state_keyword},
2176                                     };
2177            redo A;
2178          }
2179      } elsif ($self->{state} == COMMENT_START_STATE) {      } elsif ($self->{state} == COMMENT_START_STATE) {
2180        if ($self->{next_char} == 0x002D) { # -        if ($self->{next_char} == 0x002D) { # -
2181          !!!cp (137);          !!!cp (137);
# Line 2369  sub _get_next_token ($) { Line 2442  sub _get_next_token ($) {
2442          redo A;          redo A;
2443        } elsif ($self->{next_char} == 0x0050 or # P        } elsif ($self->{next_char} == 0x0050 or # P
2444                 $self->{next_char} == 0x0070) { # p                 $self->{next_char} == 0x0070) { # p
2445            $self->{state} = PUBLIC_STATE;
2446            $self->{state_keyword} = chr $self->{next_char};
2447          !!!next-input-character;          !!!next-input-character;
2448          if ($self->{next_char} == 0x0055 or # U          redo A;
             $self->{next_char} == 0x0075) { # u  
           !!!next-input-character;  
           if ($self->{next_char} == 0x0042 or # B  
               $self->{next_char} == 0x0062) { # b  
             !!!next-input-character;  
             if ($self->{next_char} == 0x004C or # L  
                 $self->{next_char} == 0x006C) { # l  
               !!!next-input-character;  
               if ($self->{next_char} == 0x0049 or # I  
                   $self->{next_char} == 0x0069) { # i  
                 !!!next-input-character;  
                 if ($self->{next_char} == 0x0043 or # C  
                     $self->{next_char} == 0x0063) { # c  
                   !!!cp (168);  
                   $self->{state} = BEFORE_DOCTYPE_PUBLIC_IDENTIFIER_STATE;  
                   !!!next-input-character;  
                   redo A;  
                 } else {  
                   !!!cp (169);  
                 }  
               } else {  
                 !!!cp (170);  
               }  
             } else {  
               !!!cp (171);  
             }  
           } else {  
             !!!cp (172);  
           }  
         } else {  
           !!!cp (173);  
         }  
   
         #  
2449        } elsif ($self->{next_char} == 0x0053 or # S        } elsif ($self->{next_char} == 0x0053 or # S
2450                 $self->{next_char} == 0x0073) { # s                 $self->{next_char} == 0x0073) { # s
2451            $self->{state} = SYSTEM_STATE;
2452            $self->{state_keyword} = chr $self->{next_char};
2453          !!!next-input-character;          !!!next-input-character;
2454          if ($self->{next_char} == 0x0059 or # Y          redo A;
             $self->{next_char} == 0x0079) { # y  
           !!!next-input-character;  
           if ($self->{next_char} == 0x0053 or # S  
               $self->{next_char} == 0x0073) { # s  
             !!!next-input-character;  
             if ($self->{next_char} == 0x0054 or # T  
                 $self->{next_char} == 0x0074) { # t  
               !!!next-input-character;  
               if ($self->{next_char} == 0x0045 or # E  
                   $self->{next_char} == 0x0065) { # e  
                 !!!next-input-character;  
                 if ($self->{next_char} == 0x004D or # M  
                     $self->{next_char} == 0x006D) { # m  
                   !!!cp (174);  
                   $self->{state} = BEFORE_DOCTYPE_SYSTEM_IDENTIFIER_STATE;  
                   !!!next-input-character;  
                   redo A;  
                 } else {  
                   !!!cp (175);  
                 }  
               } else {  
                 !!!cp (176);  
               }  
             } else {  
               !!!cp (177);  
             }  
           } else {  
             !!!cp (178);  
           }  
         } else {  
           !!!cp (179);  
         }  
   
         #  
2455        } else {        } else {
2456          !!!cp (180);          !!!cp (180);
2457            !!!parse-error (type => 'string after DOCTYPE name');
2458            $self->{current_token}->{quirks} = 1;
2459    
2460            $self->{state} = BOGUS_DOCTYPE_STATE;
2461          !!!next-input-character;          !!!next-input-character;
2462          #          redo A;
2463        }        }
2464        } elsif ($self->{state} == PUBLIC_STATE) {
2465          ## ASCII case-insensitive
2466          if ($self->{next_char} == [
2467                undef,
2468                0x0055, # U
2469                0x0042, # B
2470                0x004C, # L
2471                0x0049, # I
2472              ]->[length $self->{state_keyword}] or
2473              $self->{next_char} == [
2474                undef,
2475                0x0075, # u
2476                0x0062, # b
2477                0x006C, # l
2478                0x0069, # i
2479              ]->[length $self->{state_keyword}]) {
2480            !!!cp (175);
2481            ## Stay in the state.
2482            $self->{state_keyword} .= chr $self->{next_char};
2483            !!!next-input-character;
2484            redo A;
2485          } elsif ((length $self->{state_keyword}) == 5 and
2486                   ($self->{next_char} == 0x0043 or # C
2487                    $self->{next_char} == 0x0063)) { # c
2488            !!!cp (168);
2489            $self->{state} = BEFORE_DOCTYPE_PUBLIC_IDENTIFIER_STATE;
2490            !!!next-input-character;
2491            redo A;
2492          } else {
2493            !!!cp (169);
2494            !!!parse-error (type => 'string after DOCTYPE name',
2495                            line => $self->{line_prev},
2496                            column => $self->{column_prev} + 1 - length $self->{state_keyword});
2497            $self->{current_token}->{quirks} = 1;
2498    
2499        !!!parse-error (type => 'string after DOCTYPE name');          $self->{state} = BOGUS_DOCTYPE_STATE;
2500        $self->{current_token}->{quirks} = 1;          ## Reconsume.
2501            redo A;
2502          }
2503        } elsif ($self->{state} == SYSTEM_STATE) {
2504          ## ASCII case-insensitive
2505          if ($self->{next_char} == [
2506                undef,
2507                0x0059, # Y
2508                0x0053, # S
2509                0x0054, # T
2510                0x0045, # E
2511              ]->[length $self->{state_keyword}] or
2512              $self->{next_char} == [
2513                undef,
2514                0x0079, # y
2515                0x0073, # s
2516                0x0074, # t
2517                0x0065, # e
2518              ]->[length $self->{state_keyword}]) {
2519            !!!cp (170);
2520            ## Stay in the state.
2521            $self->{state_keyword} .= chr $self->{next_char};
2522            !!!next-input-character;
2523            redo A;
2524          } elsif ((length $self->{state_keyword}) == 5 and
2525                   ($self->{next_char} == 0x004D or # M
2526                    $self->{next_char} == 0x006D)) { # m
2527            !!!cp (171);
2528            $self->{state} = BEFORE_DOCTYPE_SYSTEM_IDENTIFIER_STATE;
2529            !!!next-input-character;
2530            redo A;
2531          } else {
2532            !!!cp (172);
2533            !!!parse-error (type => 'string after DOCTYPE name',
2534                            line => $self->{line_prev},
2535                            column => $self->{column_prev} + 1 - length $self->{state_keyword});
2536            $self->{current_token}->{quirks} = 1;
2537    
2538        $self->{state} = BOGUS_DOCTYPE_STATE;          $self->{state} = BOGUS_DOCTYPE_STATE;
2539        # next-input-character is already done          ## Reconsume.
2540        redo A;          redo A;
2541          }
2542      } elsif ($self->{state} == BEFORE_DOCTYPE_PUBLIC_IDENTIFIER_STATE) {      } elsif ($self->{state} == BEFORE_DOCTYPE_PUBLIC_IDENTIFIER_STATE) {
2543        if ({        if ({
2544              0x0009 => 1, 0x000A => 1, 0x000B => 1, 0x000C => 1, 0x0020 => 1,              0x0009 => 1, 0x000A => 1, 0x000B => 1, 0x000C => 1, 0x0020 => 1,
# Line 2811  sub _get_next_token ($) { Line 2895  sub _get_next_token ($) {
2895          !!!next-input-character;          !!!next-input-character;
2896          redo A;          redo A;
2897        }        }
2898      } elsif ($self->{state} == CDATA_BLOCK_STATE) {      } elsif ($self->{state} == CDATA_SECTION_STATE) {
2899        my $s = '';        ## NOTE: "CDATA section state" in the state is jointly implemented
2900          ## by three states, |CDATA_SECTION_STATE|, |CDATA_SECTION_MSE1_STATE|,
2901          ## and |CDATA_SECTION_MSE2_STATE|.
2902                
2903        my ($l, $c) = ($self->{line}, $self->{column});        if ($self->{next_char} == 0x005D) { # ]
2904            !!!cp (221.1);
2905            $self->{state} = CDATA_SECTION_MSE1_STATE;
2906            !!!next-input-character;
2907            redo A;
2908          } elsif ($self->{next_char} == -1) {
2909            $self->{state} = DATA_STATE;
2910            !!!next-input-character;
2911            if (length $self->{current_token}->{data}) { # character
2912              !!!cp (221.2);
2913              !!!emit ($self->{current_token}); # character
2914            } else {
2915              !!!cp (221.3);
2916              ## No token to emit. $self->{current_token} is discarded.
2917            }        
2918            redo A;
2919          } else {
2920            !!!cp (221.4);
2921            $self->{current_token}->{data} .= chr $self->{next_char};
2922            ## Stay in the state.
2923            !!!next-input-character;
2924            redo A;
2925          }
2926    
2927        CS: while ($self->{next_char} != -1) {        ## ISSUE: "text tokens" in spec.
2928          if ($self->{next_char} == 0x005D) { # ]      } elsif ($self->{state} == CDATA_SECTION_MSE1_STATE) {
2929            !!!next-input-character;        if ($self->{next_char} == 0x005D) { # ]
2930            if ($self->{next_char} == 0x005D) { # ]          !!!cp (221.5);
2931              !!!next-input-character;          $self->{state} = CDATA_SECTION_MSE2_STATE;
2932              MDC: {          !!!next-input-character;
2933                if ($self->{next_char} == 0x003E) { # >          redo A;
2934                  !!!cp (221.1);        } else {
2935                  !!!next-input-character;          !!!cp (221.6);
2936                  last CS;          $self->{current_token}->{data} .= ']';
2937                } elsif ($self->{next_char} == 0x005D) { # ]          $self->{state} = CDATA_SECTION_STATE;
2938                  !!!cp (221.2);          ## Reconsume.
2939                  $s .= ']';          redo A;
2940                  !!!next-input-character;        }
2941                  redo MDC;      } elsif ($self->{state} == CDATA_SECTION_MSE2_STATE) {
2942                } else {        if ($self->{next_char} == 0x003E) { # >
2943                  !!!cp (221.3);          $self->{state} = DATA_STATE;
2944                  $s .= ']]';          !!!next-input-character;
2945                  #          if (length $self->{current_token}->{data}) { # character
2946                }            !!!cp (221.7);
2947              } # MDC            !!!emit ($self->{current_token}); # character
           } else {  
             !!!cp (221.4);  
             $s .= ']';  
             #  
           }  
2948          } else {          } else {
2949            !!!cp (221.5);            !!!cp (221.8);
2950            #            ## No token to emit. $self->{current_token} is discarded.
2951          }          }
2952          $s .= chr $self->{next_char};          redo A;
2953          } elsif ($self->{next_char} == 0x005D) { # ]
2954            !!!cp (221.9); # character
2955            $self->{current_token}->{data} .= ']'; ## Add first "]" of "]]]".
2956            ## Stay in the state.
2957          !!!next-input-character;          !!!next-input-character;
2958        } # CS          redo A;
   
       $self->{state} = DATA_STATE;  
       ## next-input-character done or EOF, which is reconsumed.  
   
       if (length $s) {  
         !!!cp (221.6);  
         !!!emit ({type => CHARACTER_TOKEN, data => $s,  
                   line => $l, column => $c});  
2959        } else {        } else {
2960          !!!cp (221.7);          !!!cp (221.11);
2961            $self->{current_token}->{data} .= ']]'; # character
2962            $self->{state} = CDATA_SECTION_STATE;
2963            ## Reconsume.
2964            redo A;
2965        }        }
   
       redo A;  
   
       ## ISSUE: "text tokens" in spec.  
       ## TODO: Streaming support  
2966      } else {      } else {
2967        die "$0: $self->{state}: Unknown state";        die "$0: $self->{state}: Unknown state";
2968      }      }
# Line 3154  sub _tree_construction_initial ($) { Line 3252  sub _tree_construction_initial ($) {
3252        ## language.        ## language.
3253        my $doctype_name = $token->{name};        my $doctype_name = $token->{name};
3254        $doctype_name = '' unless defined $doctype_name;        $doctype_name = '' unless defined $doctype_name;
3255        $doctype_name =~ tr/a-z/A-Z/;        $doctype_name =~ tr/a-z/A-Z/; # ASCII case-insensitive
3256        if (not defined $token->{name} or # <!DOCTYPE>        if (not defined $token->{name} or # <!DOCTYPE>
           defined $token->{public_identifier} or  
3257            defined $token->{system_identifier}) {            defined $token->{system_identifier}) {
3258          !!!cp ('t1');          !!!cp ('t1');
3259          !!!parse-error (type => 'not HTML5', token => $token);          !!!parse-error (type => 'not HTML5', token => $token);
3260        } elsif ($doctype_name ne 'HTML') {        } elsif ($doctype_name ne 'HTML') {
3261          !!!cp ('t2');          !!!cp ('t2');
         ## ISSUE: ASCII case-insensitive? (in fact it does not matter)  
3262          !!!parse-error (type => 'not HTML5', token => $token);          !!!parse-error (type => 'not HTML5', token => $token);
3263          } elsif (defined $token->{public_identifier}) {
3264            if ($token->{public_identifier} eq 'XSLT-compat') {
3265              !!!cp ('t1.2');
3266              !!!parse-error (type => 'XSLT-compat', token => $token,
3267                              level => $self->{level}->{should});
3268            } else {
3269              !!!parse-error (type => 'not HTML5', token => $token);
3270            }
3271        } else {        } else {
3272          !!!cp ('t3');          !!!cp ('t3');
3273            #
3274        }        }
3275                
3276        my $doctype = $self->{document}->create_document_type_definition        my $doctype = $self->{document}->create_document_type_definition
# Line 7436  sub _tree_construction_main ($) { Line 7541  sub _tree_construction_main ($) {
7541    ## TODO: script stuffs    ## TODO: script stuffs
7542  } # _tree_construct_main  } # _tree_construct_main
7543    
7544  sub set_inner_html ($$$) {  sub set_inner_html ($$$;$) {
7545    my $class = shift;    my $class = shift;
7546    my $node = shift;    my $node = shift;
7547    my $s = \$_[0];    my $s = \$_[0];
7548    my $onerror = $_[1];    my $onerror = $_[1];
7549      my $get_wrapper = $_[2] || sub ($) { return $_[0] };
7550    
7551    ## ISSUE: Should {confident} be true?    ## ISSUE: Should {confident} be true?
7552    
# Line 7459  sub set_inner_html ($$$) { Line 7565  sub set_inner_html ($$$) {
7565      }      }
7566    
7567      ## Step 3, 4, 5 # MUST      ## Step 3, 4, 5 # MUST
7568      $class->parse_string ($$s => $node, $onerror);      $class->parse_char_string ($$s => $node, $onerror, $get_wrapper);
7569    } elsif ($nt == 1) {    } elsif ($nt == 1) {
7570      ## TODO: If non-html element      ## TODO: If non-html element
7571    
7572      ## NOTE: Most of this code is copied from |parse_string|      ## NOTE: Most of this code is copied from |parse_string|
7573    
7574    ## TODO: Support for $get_wrapper
7575    
7576      ## Step 1 # MUST      ## Step 1 # MUST
7577      my $this_doc = $node->owner_document;      my $this_doc = $node->owner_document;
7578      my $doc = $this_doc->implementation->create_document;      my $doc = $this_doc->implementation->create_document;

Legend:
Removed from v.1.158  
changed lines
  Added in v.1.166

admin@suikawiki.org
ViewVC Help
Powered by ViewVC 1.1.24