/[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.26 by wakaba, Sun Jun 24 06:20:37 2007 UTC revision 1.31 by wakaba, Sat Jun 30 14:13:19 2007 UTC
# Line 7  our $VERSION=do{my @r=(q$Revision$=~/\d+ Line 7  our $VERSION=do{my @r=(q$Revision$=~/\d+
7  ## doc.write ('');  ## doc.write ('');
8  ## alert (doc.compatMode);  ## alert (doc.compatMode);
9    
10    ## ISSUE: HTML5 revision 967 says that the encoding layer MUST NOT
11    ## strip BOM and the HTML layer MUST ignore it.  Whether we can do it
12    ## is not yet clear.
13    ## "{U+FEFF}..." in UTF-16BE/UTF-16LE is three or four characters?
14    ## "{U+FEFF}..." in GB18030?
15    
16  my $permitted_slash_tag_name = {  my $permitted_slash_tag_name = {
17    base => 1,    base => 1,
18    link => 1,    link => 1,
# Line 327  sub _get_next_token ($) { Line 333  sub _get_next_token ($) {
333        if ($self->{content_model_flag} eq 'RCDATA' or        if ($self->{content_model_flag} eq 'RCDATA' or
334            $self->{content_model_flag} eq 'CDATA') {            $self->{content_model_flag} eq 'CDATA') {
335          if (defined $self->{last_emitted_start_tag_name}) {          if (defined $self->{last_emitted_start_tag_name}) {
336              ## NOTE: <http://krijnhoetmer.nl/irc-logs/whatwg/20070626#l-564>
337            my @next_char;            my @next_char;
338            TAGNAME: for (my $i = 0; $i < length $self->{last_emitted_start_tag_name}; $i++) {            TAGNAME: for (my $i = 0; $i < length $self->{last_emitted_start_tag_name}; $i++) {
339              push @next_char, $self->{next_input_character};              push @next_char, $self->{next_input_character};
# Line 418  sub _get_next_token ($) { Line 425  sub _get_next_token ($) {
425          redo A;          redo A;
426        } elsif ($self->{next_input_character} == 0x003E) { # >        } elsif ($self->{next_input_character} == 0x003E) { # >
427          if ($self->{current_token}->{type} eq 'start tag') {          if ($self->{current_token}->{type} eq 'start tag') {
428              $self->{current_token}->{first_start_tag}
429                  = not defined $self->{last_emitted_start_tag_name};
430            $self->{last_emitted_start_tag_name} = $self->{current_token}->{tag_name};            $self->{last_emitted_start_tag_name} = $self->{current_token}->{tag_name};
431          } elsif ($self->{current_token}->{type} eq 'end tag') {          } elsif ($self->{current_token}->{type} eq 'end tag') {
432            $self->{content_model_flag} = 'PCDATA'; # MUST            $self->{content_model_flag} = 'PCDATA'; # MUST
# Line 443  sub _get_next_token ($) { Line 452  sub _get_next_token ($) {
452        } elsif ($self->{next_input_character} == -1) {        } elsif ($self->{next_input_character} == -1) {
453          !!!parse-error (type => 'unclosed tag');          !!!parse-error (type => 'unclosed tag');
454          if ($self->{current_token}->{type} eq 'start tag') {          if ($self->{current_token}->{type} eq 'start tag') {
455              $self->{current_token}->{first_start_tag}
456                  = not defined $self->{last_emitted_start_tag_name};
457            $self->{last_emitted_start_tag_name} = $self->{current_token}->{tag_name};            $self->{last_emitted_start_tag_name} = $self->{current_token}->{tag_name};
458          } elsif ($self->{current_token}->{type} eq 'end tag') {          } elsif ($self->{current_token}->{type} eq 'end tag') {
459            $self->{content_model_flag} = 'PCDATA'; # MUST            $self->{content_model_flag} = 'PCDATA'; # MUST
# Line 489  sub _get_next_token ($) { Line 500  sub _get_next_token ($) {
500          redo A;          redo A;
501        } elsif ($self->{next_input_character} == 0x003E) { # >        } elsif ($self->{next_input_character} == 0x003E) { # >
502          if ($self->{current_token}->{type} eq 'start tag') {          if ($self->{current_token}->{type} eq 'start tag') {
503              $self->{current_token}->{first_start_tag}
504                  = not defined $self->{last_emitted_start_tag_name};
505            $self->{last_emitted_start_tag_name} = $self->{current_token}->{tag_name};            $self->{last_emitted_start_tag_name} = $self->{current_token}->{tag_name};
506          } elsif ($self->{current_token}->{type} eq 'end tag') {          } elsif ($self->{current_token}->{type} eq 'end tag') {
507            $self->{content_model_flag} = 'PCDATA'; # MUST            $self->{content_model_flag} = 'PCDATA'; # MUST
# Line 527  sub _get_next_token ($) { Line 540  sub _get_next_token ($) {
540        } elsif ($self->{next_input_character} == -1) {        } elsif ($self->{next_input_character} == -1) {
541          !!!parse-error (type => 'unclosed tag');          !!!parse-error (type => 'unclosed tag');
542          if ($self->{current_token}->{type} eq 'start tag') {          if ($self->{current_token}->{type} eq 'start tag') {
543              $self->{current_token}->{first_start_tag}
544                  = not defined $self->{last_emitted_start_tag_name};
545            $self->{last_emitted_start_tag_name} = $self->{current_token}->{tag_name};            $self->{last_emitted_start_tag_name} = $self->{current_token}->{tag_name};
546          } elsif ($self->{current_token}->{type} eq 'end tag') {          } elsif ($self->{current_token}->{type} eq 'end tag') {
547            $self->{content_model_flag} = 'PCDATA'; # MUST            $self->{content_model_flag} = 'PCDATA'; # MUST
# Line 578  sub _get_next_token ($) { Line 593  sub _get_next_token ($) {
593        } elsif ($self->{next_input_character} == 0x003E) { # >        } elsif ($self->{next_input_character} == 0x003E) { # >
594          $before_leave->();          $before_leave->();
595          if ($self->{current_token}->{type} eq 'start tag') {          if ($self->{current_token}->{type} eq 'start tag') {
596              $self->{current_token}->{first_start_tag}
597                  = not defined $self->{last_emitted_start_tag_name};
598            $self->{last_emitted_start_tag_name} = $self->{current_token}->{tag_name};            $self->{last_emitted_start_tag_name} = $self->{current_token}->{tag_name};
599          } elsif ($self->{current_token}->{type} eq 'end tag') {          } elsif ($self->{current_token}->{type} eq 'end tag') {
600            $self->{content_model_flag} = 'PCDATA'; # MUST            $self->{content_model_flag} = 'PCDATA'; # MUST
# Line 617  sub _get_next_token ($) { Line 634  sub _get_next_token ($) {
634          !!!parse-error (type => 'unclosed tag');          !!!parse-error (type => 'unclosed tag');
635          $before_leave->();          $before_leave->();
636          if ($self->{current_token}->{type} eq 'start tag') {          if ($self->{current_token}->{type} eq 'start tag') {
637              $self->{current_token}->{first_start_tag}
638                  = not defined $self->{last_emitted_start_tag_name};
639            $self->{last_emitted_start_tag_name} = $self->{current_token}->{tag_name};            $self->{last_emitted_start_tag_name} = $self->{current_token}->{tag_name};
640          } elsif ($self->{current_token}->{type} eq 'end tag') {          } elsif ($self->{current_token}->{type} eq 'end tag') {
641            $self->{content_model_flag} = 'PCDATA'; # MUST            $self->{content_model_flag} = 'PCDATA'; # MUST
# Line 653  sub _get_next_token ($) { Line 672  sub _get_next_token ($) {
672          redo A;          redo A;
673        } elsif ($self->{next_input_character} == 0x003E) { # >        } elsif ($self->{next_input_character} == 0x003E) { # >
674          if ($self->{current_token}->{type} eq 'start tag') {          if ($self->{current_token}->{type} eq 'start tag') {
675              $self->{current_token}->{first_start_tag}
676                  = not defined $self->{last_emitted_start_tag_name};
677            $self->{last_emitted_start_tag_name} = $self->{current_token}->{tag_name};            $self->{last_emitted_start_tag_name} = $self->{current_token}->{tag_name};
678          } elsif ($self->{current_token}->{type} eq 'end tag') {          } elsif ($self->{current_token}->{type} eq 'end tag') {
679            $self->{content_model_flag} = 'PCDATA'; # MUST            $self->{content_model_flag} = 'PCDATA'; # MUST
# Line 691  sub _get_next_token ($) { Line 712  sub _get_next_token ($) {
712        } elsif ($self->{next_input_character} == -1) {        } elsif ($self->{next_input_character} == -1) {
713          !!!parse-error (type => 'unclosed tag');          !!!parse-error (type => 'unclosed tag');
714          if ($self->{current_token}->{type} eq 'start tag') {          if ($self->{current_token}->{type} eq 'start tag') {
715              $self->{current_token}->{first_start_tag}
716                  = 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} eq 'end tag') {          } elsif ($self->{current_token}->{type} eq 'end tag') {
719            $self->{content_model_flag} = 'PCDATA'; # MUST            $self->{content_model_flag} = 'PCDATA'; # MUST
# Line 736  sub _get_next_token ($) { Line 759  sub _get_next_token ($) {
759          redo A;          redo A;
760        } elsif ($self->{next_input_character} == 0x003E) { # >        } elsif ($self->{next_input_character} == 0x003E) { # >
761          if ($self->{current_token}->{type} eq 'start tag') {          if ($self->{current_token}->{type} eq 'start tag') {
762              $self->{current_token}->{first_start_tag}
763                  = not defined $self->{last_emitted_start_tag_name};
764            $self->{last_emitted_start_tag_name} = $self->{current_token}->{tag_name};            $self->{last_emitted_start_tag_name} = $self->{current_token}->{tag_name};
765          } elsif ($self->{current_token}->{type} eq 'end tag') {          } elsif ($self->{current_token}->{type} eq 'end tag') {
766            $self->{content_model_flag} = 'PCDATA'; # MUST            $self->{content_model_flag} = 'PCDATA'; # MUST
# Line 754  sub _get_next_token ($) { Line 779  sub _get_next_token ($) {
779        } elsif ($self->{next_input_character} == -1) {        } elsif ($self->{next_input_character} == -1) {
780          !!!parse-error (type => 'unclosed tag');          !!!parse-error (type => 'unclosed tag');
781          if ($self->{current_token}->{type} eq 'start tag') {          if ($self->{current_token}->{type} eq 'start tag') {
782              $self->{current_token}->{first_start_tag}
783                  = not defined $self->{last_emitted_start_tag_name};
784            $self->{last_emitted_start_tag_name} = $self->{current_token}->{tag_name};            $self->{last_emitted_start_tag_name} = $self->{current_token}->{tag_name};
785          } elsif ($self->{current_token}->{type} eq 'end tag') {          } elsif ($self->{current_token}->{type} eq 'end tag') {
786            $self->{content_model_flag} = 'PCDATA'; # MUST            $self->{content_model_flag} = 'PCDATA'; # MUST
# Line 788  sub _get_next_token ($) { Line 815  sub _get_next_token ($) {
815        } elsif ($self->{next_input_character} == -1) {        } elsif ($self->{next_input_character} == -1) {
816          !!!parse-error (type => 'unclosed attribute value');          !!!parse-error (type => 'unclosed attribute value');
817          if ($self->{current_token}->{type} eq 'start tag') {          if ($self->{current_token}->{type} eq 'start tag') {
818              $self->{current_token}->{first_start_tag}
819                  = not defined $self->{last_emitted_start_tag_name};
820            $self->{last_emitted_start_tag_name} = $self->{current_token}->{tag_name};            $self->{last_emitted_start_tag_name} = $self->{current_token}->{tag_name};
821          } elsif ($self->{current_token}->{type} eq 'end tag') {          } elsif ($self->{current_token}->{type} eq 'end tag') {
822            $self->{content_model_flag} = 'PCDATA'; # MUST            $self->{content_model_flag} = 'PCDATA'; # MUST
# Line 822  sub _get_next_token ($) { Line 851  sub _get_next_token ($) {
851        } elsif ($self->{next_input_character} == -1) {        } elsif ($self->{next_input_character} == -1) {
852          !!!parse-error (type => 'unclosed attribute value');          !!!parse-error (type => 'unclosed attribute value');
853          if ($self->{current_token}->{type} eq 'start tag') {          if ($self->{current_token}->{type} eq 'start tag') {
854              $self->{current_token}->{first_start_tag}
855                  = not defined $self->{last_emitted_start_tag_name};
856            $self->{last_emitted_start_tag_name} = $self->{current_token}->{tag_name};            $self->{last_emitted_start_tag_name} = $self->{current_token}->{tag_name};
857          } elsif ($self->{current_token}->{type} eq 'end tag') {          } elsif ($self->{current_token}->{type} eq 'end tag') {
858            $self->{content_model_flag} = 'PCDATA'; # MUST            $self->{content_model_flag} = 'PCDATA'; # MUST
# Line 859  sub _get_next_token ($) { Line 890  sub _get_next_token ($) {
890          redo A;          redo A;
891        } elsif ($self->{next_input_character} == 0x003E) { # >        } elsif ($self->{next_input_character} == 0x003E) { # >
892          if ($self->{current_token}->{type} eq 'start tag') {          if ($self->{current_token}->{type} eq 'start tag') {
893              $self->{current_token}->{first_start_tag}
894                  = not defined $self->{last_emitted_start_tag_name};
895            $self->{last_emitted_start_tag_name} = $self->{current_token}->{tag_name};            $self->{last_emitted_start_tag_name} = $self->{current_token}->{tag_name};
896          } elsif ($self->{current_token}->{type} eq 'end tag') {          } elsif ($self->{current_token}->{type} eq 'end tag') {
897            $self->{content_model_flag} = 'PCDATA'; # MUST            $self->{content_model_flag} = 'PCDATA'; # MUST
# Line 877  sub _get_next_token ($) { Line 910  sub _get_next_token ($) {
910        } elsif ($self->{next_input_character} == -1) {        } elsif ($self->{next_input_character} == -1) {
911          !!!parse-error (type => 'unclosed tag');          !!!parse-error (type => 'unclosed tag');
912          if ($self->{current_token}->{type} eq 'start tag') {          if ($self->{current_token}->{type} eq 'start tag') {
913              $self->{current_token}->{first_start_tag}
914                  = not defined $self->{last_emitted_start_tag_name};
915            $self->{last_emitted_start_tag_name} = $self->{current_token}->{tag_name};            $self->{last_emitted_start_tag_name} = $self->{current_token}->{tag_name};
916          } elsif ($self->{current_token}->{type} eq 'end tag') {          } elsif ($self->{current_token}->{type} eq 'end tag') {
917            $self->{content_model_flag} = 'PCDATA'; # MUST            $self->{content_model_flag} = 'PCDATA'; # MUST
# Line 990  sub _get_next_token ($) { Line 1025  sub _get_next_token ($) {
1025          }          }
1026        }        }
1027    
1028        !!!parse-error (type => 'bogus comment open');        !!!parse-error (type => 'bogus comment');
1029        $self->{next_input_character} = shift @next_char;        $self->{next_input_character} = shift @next_char;
1030        !!!back-next-input-character (@next_char);        !!!back-next-input-character (@next_char);
1031        $self->{state} = 'bogus comment';        $self->{state} = 'bogus comment';
# Line 1459  sub _get_next_token ($) { Line 1494  sub _get_next_token ($) {
1494    
1495          redo A;          redo A;
1496        } else {        } else {
1497          !!!parse-error (type => 'string after PUBLIC literal');          !!!parse-error (type => 'string after SYSTEM');
1498          $self->{state} = 'bogus DOCTYPE';          $self->{state} = 'bogus DOCTYPE';
1499          !!!next-input-character;          !!!next-input-character;
1500          redo A;          redo A;
# Line 1627  sub _tokenize_attempt_to_consume_an_enti Line 1662  sub _tokenize_attempt_to_consume_an_enti
1662            !!!parse-error (type => 'CR character reference');            !!!parse-error (type => 'CR character reference');
1663            $code = 0x000A;            $code = 0x000A;
1664          } elsif (0x80 <= $code and $code <= 0x9F) {          } elsif (0x80 <= $code and $code <= 0x9F) {
1665            !!!parse-error (type => sprintf 'c1 entity:U+%04X', $code);            !!!parse-error (type => sprintf 'C1 character reference:U+%04X', $code);
1666            $code = $c1_entity_char->{$code};            $code = $c1_entity_char->{$code};
1667          }          }
1668    
# Line 1662  sub _tokenize_attempt_to_consume_an_enti Line 1697  sub _tokenize_attempt_to_consume_an_enti
1697          !!!parse-error (type => 'CR character reference');          !!!parse-error (type => 'CR character reference');
1698          $code = 0x000A;          $code = 0x000A;
1699        } elsif (0x80 <= $code and $code <= 0x9F) {        } elsif (0x80 <= $code and $code <= 0x9F) {
1700          !!!parse-error (type => sprintf 'c1 entity:U+%04X', $code);          !!!parse-error (type => sprintf 'C1 character reference:U+%04X', $code);
1701          $code = $c1_entity_char->{$code};          $code = $c1_entity_char->{$code};
1702        }        }
1703                
# Line 1716  sub _tokenize_attempt_to_consume_an_enti Line 1751  sub _tokenize_attempt_to_consume_an_enti
1751      if ($match > 0) {      if ($match > 0) {
1752        return {type => 'character', data => $value};        return {type => 'character', data => $value};
1753      } elsif ($match < 0) {      } elsif ($match < 0) {
1754        !!!parse-error (type => 'refc');        !!!parse-error (type => 'no refc');
1755        return {type => 'character', data => $value};        return {type => 'character', data => $value};
1756      } else {      } else {
1757        !!!parse-error (type => 'bare ero');        !!!parse-error (type => 'bare ero');
# Line 2001  sub _reset_insertion_mode ($) { Line 2036  sub _reset_insertion_mode ($) {
2036            
2037      ## Step 3      ## Step 3
2038      S3: {      S3: {
2039        $last = 1 if $self->{open_elements}->[0]->[0] eq $node->[0];        ## ISSUE: Oops! "If node is the first node in the stack of open
2040        if (defined $self->{inner_html_node}) {        ## elements, then set last to true. If the context element of the
2041          if ($self->{inner_html_node}->[1] eq 'td' or        ## HTML fragment parsing algorithm is neither a td element nor a
2042              $self->{inner_html_node}->[1] eq 'th') {        ## th element, then set node to the context element. (fragment case)":
2043            #        ## The second "if" is in the scope of the first "if"!?
2044          } else {        if ($self->{open_elements}->[0]->[0] eq $node->[0]) {
2045            $node = $self->{inner_html_node};          $last = 1;
2046            if (defined $self->{inner_html_node}) {
2047              if ($self->{inner_html_node}->[1] eq 'td' or
2048                  $self->{inner_html_node}->[1] eq 'th') {
2049                #
2050              } else {
2051                $node = $self->{inner_html_node};
2052              }
2053          }          }
2054        }        }
2055            
# Line 2466  sub _tree_construction_main ($) { Line 2508  sub _tree_construction_main ($) {
2508        } elsif ($token->{tag_name} eq 'title') {        } elsif ($token->{tag_name} eq 'title') {
2509          !!!parse-error (type => 'in body:title');          !!!parse-error (type => 'in body:title');
2510          ## NOTE: This is an "as if in head" code clone          ## NOTE: This is an "as if in head" code clone
2511          $parse_rcdata->('RCDATA', $insert);          $parse_rcdata->('RCDATA', sub {
2512              if (defined $self->{head_element}) {
2513                $self->{head_element}->append_child ($_[0]);
2514              } else {
2515                $insert->($_[0]);
2516              }
2517            });
2518          return;          return;
2519        } elsif ($token->{tag_name} eq 'body') {        } elsif ($token->{tag_name} eq 'body') {
2520          !!!parse-error (type => 'in body:body');          !!!parse-error (type => 'in body:body');
# Line 2569  sub _tree_construction_main ($) { Line 2617  sub _tree_construction_main ($) {
2617              if ($i != -1) {              if ($i != -1) {
2618                !!!parse-error (type => 'end tag missing:'.                !!!parse-error (type => 'end tag missing:'.
2619                                $self->{open_elements}->[-1]->[1]);                                $self->{open_elements}->[-1]->[1]);
               ## TODO: test  
2620              }              }
2621              splice @{$self->{open_elements}}, $i;              splice @{$self->{open_elements}}, $i;
2622              last LI;              last LI;
# Line 2617  sub _tree_construction_main ($) { Line 2664  sub _tree_construction_main ($) {
2664              if ($i != -1) {              if ($i != -1) {
2665                !!!parse-error (type => 'end tag missing:'.                !!!parse-error (type => 'end tag missing:'.
2666                                $self->{open_elements}->[-1]->[1]);                                $self->{open_elements}->[-1]->[1]);
               ## TODO: test  
2667              }              }
2668              splice @{$self->{open_elements}}, $i;              splice @{$self->{open_elements}}, $i;
2669              last LI;              last LI;
# Line 2761  sub _tree_construction_main ($) { Line 2807  sub _tree_construction_main ($) {
2807          INSCOPE: for (reverse 0..$#{$self->{open_elements}}) {          INSCOPE: for (reverse 0..$#{$self->{open_elements}}) {
2808            my $node = $self->{open_elements}->[$_];            my $node = $self->{open_elements}->[$_];
2809            if ($node->[1] eq 'nobr') {            if ($node->[1] eq 'nobr') {
2810                !!!parse-error (type => 'not closed:nobr');
2811              !!!back-token;              !!!back-token;
2812              $token = {type => 'end tag', tag_name => 'nobr'};              $token = {type => 'end tag', tag_name => 'nobr'};
2813              return;              return;
# Line 2844  sub _tree_construction_main ($) { Line 2891  sub _tree_construction_main ($) {
2891            !!!parse-error (type => 'image');            !!!parse-error (type => 'image');
2892            $token->{tag_name} = 'img';            $token->{tag_name} = 'img';
2893          }          }
2894            
2895            ## NOTE: There is an "as if <br>" code clone.
2896          $reconstruct_active_formatting_elements->($insert_to_current);          $reconstruct_active_formatting_elements->($insert_to_current);
2897                    
2898          !!!insert-element-t ($token->{tag_name}, $token->{attributes});          !!!insert-element-t ($token->{tag_name}, $token->{attributes});
# Line 3002  sub _tree_construction_main ($) { Line 3050  sub _tree_construction_main ($) {
3050              unless ({              unless ({
3051                         dd => 1, dt => 1, li => 1, p => 1, td => 1,                         dd => 1, dt => 1, li => 1, p => 1, td => 1,
3052                         th => 1, tr => 1, body => 1, html => 1,                         th => 1, tr => 1, body => 1, html => 1,
3053                         tbody => 1, tfoot => 1, thead => 1,
3054                      }->{$_->[1]}) {                      }->{$_->[1]}) {
3055                !!!parse-error (type => 'not closed:'.$_->[1]);                !!!parse-error (type => 'not closed:'.$_->[1]);
3056              }              }
# Line 3051  sub _tree_construction_main ($) { Line 3100  sub _tree_construction_main ($) {
3100                   li => ($token->{tag_name} ne 'li'),                   li => ($token->{tag_name} ne 'li'),
3101                   p => ($token->{tag_name} ne 'p'),                   p => ($token->{tag_name} ne 'p'),
3102                   td => 1, th => 1, tr => 1,                   td => 1, th => 1, tr => 1,
3103                     tbody => 1, tfoot=> 1, thead => 1,
3104                  }->{$self->{open_elements}->[-1]->[1]}) {                  }->{$self->{open_elements}->[-1]->[1]}) {
3105                !!!back-token;                !!!back-token;
3106                $token = {type => 'end tag',                $token = {type => 'end tag',
# Line 3071  sub _tree_construction_main ($) { Line 3121  sub _tree_construction_main ($) {
3121            !!!parse-error (type => 'not closed:'.$self->{open_elements}->[-1]->[1]);            !!!parse-error (type => 'not closed:'.$self->{open_elements}->[-1]->[1]);
3122          }          }
3123                    
3124          splice @{$self->{open_elements}}, $i if defined $i;          if (defined $i) {
3125              splice @{$self->{open_elements}}, $i;
3126            } elsif ($token->{tag_name} eq 'p') {
3127              ## As if <p>, then reprocess the current token
3128              my $el;
3129              !!!create-element ($el, 'p');
3130              $insert->($el);
3131            }
3132          $clear_up_to_marker->()          $clear_up_to_marker->()
3133            if {            if {
3134              button => 1, marquee => 1, object => 1,              button => 1, marquee => 1, object => 1,
# Line 3087  sub _tree_construction_main ($) { Line 3144  sub _tree_construction_main ($) {
3144              if ({              if ({
3145                   dd => 1, dt => 1, li => 1, p => 1,                   dd => 1, dt => 1, li => 1, p => 1,
3146                   td => 1, th => 1, tr => 1,                   td => 1, th => 1, tr => 1,
3147                     tbody => 1, tfoot=> 1, thead => 1,
3148                  }->{$self->{open_elements}->[-1]->[1]}) {                  }->{$self->{open_elements}->[-1]->[1]}) {
3149                !!!back-token;                !!!back-token;
3150                $token = {type => 'end tag',                $token = {type => 'end tag',
# Line 3125  sub _tree_construction_main ($) { Line 3183  sub _tree_construction_main ($) {
3183              if ({              if ({
3184                   dd => 1, dt => 1, li => 1, p => 1,                   dd => 1, dt => 1, li => 1, p => 1,
3185                   td => 1, th => 1, tr => 1,                   td => 1, th => 1, tr => 1,
3186                     tbody => 1, tfoot=> 1, thead => 1,
3187                  }->{$self->{open_elements}->[-1]->[1]}) {                  }->{$self->{open_elements}->[-1]->[1]}) {
3188                !!!back-token;                !!!back-token;
3189                $token = {type => 'end tag',                $token = {type => 'end tag',
# Line 3155  sub _tree_construction_main ($) { Line 3214  sub _tree_construction_main ($) {
3214                  strong => 1, tt => 1, u => 1,                  strong => 1, tt => 1, u => 1,
3215                 }->{$token->{tag_name}}) {                 }->{$token->{tag_name}}) {
3216          $formatting_end_tag->($token->{tag_name});          $formatting_end_tag->($token->{tag_name});
3217  ## TODO: <http://html5.org/tools/web-apps-tracker?from=883&to=884>          return;
3218          } elsif ($token->{tag_name} eq 'br') {
3219            !!!parse-error (type => 'unmatched end tag:br');
3220    
3221            ## As if <br>
3222            $reconstruct_active_formatting_elements->($insert_to_current);
3223            
3224            my $el;
3225            !!!create-element ($el, 'br');
3226            $insert->($el);
3227            
3228            ## Ignore the token.
3229            !!!next-token;
3230          return;          return;
3231        } elsif ({        } elsif ({
3232                  caption => 1, col => 1, colgroup => 1, frame => 1,                  caption => 1, col => 1, colgroup => 1, frame => 1,
3233                  frameset => 1, head => 1, option => 1, optgroup => 1,                  frameset => 1, head => 1, option => 1, optgroup => 1,
3234                  tbody => 1, td => 1, tfoot => 1, th => 1,                  tbody => 1, td => 1, tfoot => 1, th => 1,
3235                  thead => 1, tr => 1,                  thead => 1, tr => 1,
3236                  area => 1, basefont => 1, bgsound => 1, br => 1,                  area => 1, basefont => 1, bgsound => 1,
3237                  embed => 1, hr => 1, iframe => 1, image => 1,                  embed => 1, hr => 1, iframe => 1, image => 1,
3238                  img => 1, input => 1, isindex => 1, noembed => 1,                  img => 1, input => 1, isindex => 1, noembed => 1,
3239                  noframes => 1, param => 1, select => 1, spacer => 1,                  noframes => 1, param => 1, select => 1, spacer => 1,
# Line 3189  sub _tree_construction_main ($) { Line 3260  sub _tree_construction_main ($) {
3260              if ({              if ({
3261                   dd => 1, dt => 1, li => 1, p => 1,                   dd => 1, dt => 1, li => 1, p => 1,
3262                   td => 1, th => 1, tr => 1,                   td => 1, th => 1, tr => 1,
3263                     tbody => 1, tfoot=> 1, thead => 1,
3264                  }->{$self->{open_elements}->[-1]->[1]}) {                  }->{$self->{open_elements}->[-1]->[1]}) {
3265                !!!back-token;                !!!back-token;
3266                $token = {type => 'end tag',                $token = {type => 'end tag',
# Line 3241  sub _tree_construction_main ($) { Line 3313  sub _tree_construction_main ($) {
3313          redo B;          redo B;
3314        } elsif ($token->{type} eq 'start tag' and        } elsif ($token->{type} eq 'start tag' and
3315                 $token->{tag_name} eq 'html') {                 $token->{tag_name} eq 'html') {
3316          ## TODO: unless it is the first start tag token, parse-error  ## ISSUE: "aa<html>" is not a parse error.
3317    ## ISSUE: "<html>" in fragment is not a parse error.
3318            unless ($token->{first_start_tag}) {
3319              !!!parse-error (type => 'not first start tag');
3320            }
3321          my $top_el = $self->{open_elements}->[0]->[0];          my $top_el = $self->{open_elements}->[0]->[0];
3322          for my $attr_name (keys %{$token->{attributes}}) {          for my $attr_name (keys %{$token->{attributes}}) {
3323            unless ($top_el->has_attribute_ns (undef, $attr_name)) {            unless ($top_el->has_attribute_ns (undef, $attr_name)) {
# Line 3256  sub _tree_construction_main ($) { Line 3332  sub _tree_construction_main ($) {
3332          ## Generate implied end tags          ## Generate implied end tags
3333          if ({          if ({
3334               dd => 1, dt => 1, li => 1, p => 1, td => 1, th => 1, tr => 1,               dd => 1, dt => 1, li => 1, p => 1, td => 1, th => 1, tr => 1,
3335                 tbody => 1, tfoot=> 1, thead => 1,
3336              }->{$self->{open_elements}->[-1]->[1]}) {              }->{$self->{open_elements}->[-1]->[1]}) {
3337            !!!back-token;            !!!back-token;
3338            $token = {type => 'end tag', tag_name => $self->{open_elements}->[-1]->[1]};            $token = {type => 'end tag', tag_name => $self->{open_elements}->[-1]->[1]};
# Line 3315  sub _tree_construction_main ($) { Line 3392  sub _tree_construction_main ($) {
3392              }              }
3393              redo B;              redo B;
3394            } elsif ($token->{type} eq 'end tag') {            } elsif ($token->{type} eq 'end tag') {
3395              if ({head => 1, body => 1, html => 1}->{$token->{tag_name}}) {              if ({
3396                     head => 1, body => 1, html => 1,
3397                     p => 1, br => 1,
3398                    }->{$token->{tag_name}}) {
3399                ## As if <head>                ## As if <head>
3400                !!!create-element ($self->{head_element}, 'head');                !!!create-element ($self->{head_element}, 'head');
3401                $self->{open_elements}->[-1]->[0]->append_child ($self->{head_element});                $self->{open_elements}->[-1]->[0]->append_child ($self->{head_element});
# Line 3373  sub _tree_construction_main ($) { Line 3453  sub _tree_construction_main ($) {
3453                  !!!parse-error (type => 'after head:'.$token->{tag_name});                  !!!parse-error (type => 'after head:'.$token->{tag_name});
3454                  push @{$self->{open_elements}}, [$self->{head_element}, 'head'];                  push @{$self->{open_elements}}, [$self->{head_element}, 'head'];
3455                }                }
3456                $parse_rcdata->('RCDATA', $insert_to_current);                my $parent = defined $self->{head_element} ? $self->{head_element}
3457                      : $self->{open_elements}->[-1]->[0];
3458                  $parse_rcdata->('RCDATA', sub { $parent->append_child ($_[0]) });
3459                pop @{$self->{open_elements}}                pop @{$self->{open_elements}}
3460                    if $self->{insertion_mode} eq 'after head';                    if $self->{insertion_mode} eq 'after head';
3461                redo B;                redo B;
# Line 3397  sub _tree_construction_main ($) { Line 3479  sub _tree_construction_main ($) {
3479                  !!!next-token;                  !!!next-token;
3480                  redo B;                  redo B;
3481                } elsif ($self->{insertion_mode} eq 'in head noscript') {                } elsif ($self->{insertion_mode} eq 'in head noscript') {
3482                  !!!parse-error (type => 'noscript in noscript');                  !!!parse-error (type => 'in noscript:noscript');
3483                  ## Ignore the token                  ## Ignore the token
3484                  redo B;                  redo B;
3485                } else {                } else {
# Line 3449  sub _tree_construction_main ($) { Line 3531  sub _tree_construction_main ($) {
3531                !!!next-token;                !!!next-token;
3532                redo B;                redo B;
3533              } elsif ($self->{insertion_mode} eq 'in head' and              } elsif ($self->{insertion_mode} eq 'in head' and
3534                       ($token->{tag_name} eq 'body' or                       {
3535                        $token->{tag_name} eq 'html')) {                        body => 1, html => 1,
3536                          p => 1, br => 1,
3537                         }->{$token->{tag_name}}) {
3538                  #
3539                } elsif ($self->{insertion_mode} eq 'in head noscript' and
3540                         {
3541                          p => 1, br => 1,
3542                         }->{$token->{tag_name}}) {
3543                #                #
3544              } elsif ($self->{insertion_mode} ne 'after head') {              } elsif ($self->{insertion_mode} ne 'after head') {
3545                !!!parse-error (type => 'unmatched end tag:'.$token->{tag_name});                !!!parse-error (type => 'unmatched end tag:'.$token->{tag_name});
# Line 3634  sub _tree_construction_main ($) { Line 3723  sub _tree_construction_main ($) {
3723                if ({                if ({
3724                     dd => 1, dt => 1, li => 1, p => 1,                     dd => 1, dt => 1, li => 1, p => 1,
3725                     td => 1, th => 1, tr => 1,                     td => 1, th => 1, tr => 1,
3726                       tbody => 1, tfoot=> 1, thead => 1,
3727                    }->{$self->{open_elements}->[-1]->[1]}) {                    }->{$self->{open_elements}->[-1]->[1]}) {
3728                  !!!back-token; # <table>                  !!!back-token; # <table>
3729                  $token = {type => 'end tag', tag_name => 'table'};                  $token = {type => 'end tag', tag_name => 'table'};
# Line 3682  sub _tree_construction_main ($) { Line 3772  sub _tree_construction_main ($) {
3772                if ({                if ({
3773                     dd => 1, dt => 1, li => 1, p => 1,                     dd => 1, dt => 1, li => 1, p => 1,
3774                     td => 1, th => 1, tr => 1,                     td => 1, th => 1, tr => 1,
3775                       tbody => 1, tfoot=> 1, thead => 1,
3776                    }->{$self->{open_elements}->[-1]->[1]}) {                    }->{$self->{open_elements}->[-1]->[1]}) {
3777                  !!!back-token;                  !!!back-token;
3778                  $token = {type => 'end tag',                  $token = {type => 'end tag',
# Line 3765  sub _tree_construction_main ($) { Line 3856  sub _tree_construction_main ($) {
3856                if ({                if ({
3857                     dd => 1, dt => 1, li => 1, p => 1,                     dd => 1, dt => 1, li => 1, p => 1,
3858                     td => 1, th => 1, tr => 1,                     td => 1, th => 1, tr => 1,
3859                       tbody => 1, tfoot=> 1, thead => 1,
3860                    }->{$self->{open_elements}->[-1]->[1]}) {                    }->{$self->{open_elements}->[-1]->[1]}) {
3861                  !!!back-token; # <?>                  !!!back-token; # <?>
3862                  $token = {type => 'end tag', tag_name => 'caption'};                  $token = {type => 'end tag', tag_name => 'caption'};
# Line 3815  sub _tree_construction_main ($) { Line 3907  sub _tree_construction_main ($) {
3907                if ({                if ({
3908                     dd => 1, dt => 1, li => 1, p => 1,                     dd => 1, dt => 1, li => 1, p => 1,
3909                     td => 1, th => 1, tr => 1,                     td => 1, th => 1, tr => 1,
3910                       tbody => 1, tfoot=> 1, thead => 1,
3911                    }->{$self->{open_elements}->[-1]->[1]}) {                    }->{$self->{open_elements}->[-1]->[1]}) {
3912                  !!!back-token;                  !!!back-token;
3913                  $token = {type => 'end tag',                  $token = {type => 'end tag',
# Line 3862  sub _tree_construction_main ($) { Line 3955  sub _tree_construction_main ($) {
3955                if ({                if ({
3956                     dd => 1, dt => 1, li => 1, p => 1,                     dd => 1, dt => 1, li => 1, p => 1,
3957                     td => 1, th => 1, tr => 1,                     td => 1, th => 1, tr => 1,
3958                       tbody => 1, tfoot=> 1, thead => 1,
3959                    }->{$self->{open_elements}->[-1]->[1]}) {                    }->{$self->{open_elements}->[-1]->[1]}) {
3960                  !!!back-token; # </table>                  !!!back-token; # </table>
3961                  $token = {type => 'end tag', tag_name => 'caption'};                  $token = {type => 'end tag', tag_name => 'caption'};
# Line 4127  sub _tree_construction_main ($) { Line 4221  sub _tree_construction_main ($) {
4221                if ({                if ({
4222                     dd => 1, dt => 1, li => 1, p => 1,                     dd => 1, dt => 1, li => 1, p => 1,
4223                     td => 1, th => 1, tr => 1,                     td => 1, th => 1, tr => 1,
4224                       tbody => 1, tfoot=> 1, thead => 1,
4225                    }->{$self->{open_elements}->[-1]->[1]}) {                    }->{$self->{open_elements}->[-1]->[1]}) {
4226                  !!!back-token; # <table>                  !!!back-token; # <table>
4227                  $token = {type => 'end tag', tag_name => 'table'};                  $token = {type => 'end tag', tag_name => 'table'};
# Line 4395  sub _tree_construction_main ($) { Line 4490  sub _tree_construction_main ($) {
4490                if ({                if ({
4491                     dd => 1, dt => 1, li => 1, p => 1,                     dd => 1, dt => 1, li => 1, p => 1,
4492                     td => 1, th => 1, tr => 1,                     td => 1, th => 1, tr => 1,
4493                       tbody => 1, tfoot=> 1, thead => 1,
4494                    }->{$self->{open_elements}->[-1]->[1]}) {                    }->{$self->{open_elements}->[-1]->[1]}) {
4495                  !!!back-token; # <table>                  !!!back-token; # <table>
4496                  $token = {type => 'end tag', tag_name => 'table'};                  $token = {type => 'end tag', tag_name => 'table'};
# Line 4636  sub _tree_construction_main ($) { Line 4732  sub _tree_construction_main ($) {
4732                     td => ($token->{tag_name} eq 'th'),                     td => ($token->{tag_name} eq 'th'),
4733                     th => ($token->{tag_name} eq 'td'),                     th => ($token->{tag_name} eq 'td'),
4734                     tr => 1,                     tr => 1,
4735                       tbody => 1, tfoot=> 1, thead => 1,
4736                    }->{$self->{open_elements}->[-1]->[1]}) {                    }->{$self->{open_elements}->[-1]->[1]}) {
4737                  !!!back-token;                  !!!back-token;
4738                  $token = {type => 'end tag',                  $token = {type => 'end tag',
# Line 4988  sub _tree_construction_main ($) { Line 5085  sub _tree_construction_main ($) {
5085            }            }
5086                        
5087            if (defined $token->{tag_name}) {            if (defined $token->{tag_name}) {
5088              !!!parse-error (type => 'in frameset:'.$token->{tag_name});              !!!parse-error (type => 'in frameset:'.($token->{type} eq 'end tag' ? '/' : '').$token->{tag_name});
5089            } else {            } else {
5090              !!!parse-error (type => 'in frameset:#'.$token->{type});              !!!parse-error (type => 'in frameset:#'.$token->{type});
5091            }            }
# Line 5032  sub _tree_construction_main ($) { Line 5129  sub _tree_construction_main ($) {
5129            }            }
5130                        
5131            if (defined $token->{tag_name}) {            if (defined $token->{tag_name}) {
5132              !!!parse-error (type => 'after frameset:'.$token->{tag_name});              !!!parse-error (type => 'after frameset:'.($token->{tag_name} eq 'end tag' ? '/' : '').$token->{tag_name});
5133            } else {            } else {
5134              !!!parse-error (type => 'after frameset:#'.$token->{type});              !!!parse-error (type => 'after frameset:#'.$token->{type});
5135            }            }
# Line 5082  sub _tree_construction_main ($) { Line 5179  sub _tree_construction_main ($) {
5179          redo B;          redo B;
5180        } elsif ($token->{type} eq 'start tag' or        } elsif ($token->{type} eq 'start tag' or
5181                 $token->{type} eq 'end tag') {                 $token->{type} eq 'end tag') {
5182          !!!parse-error (type => 'after html:'.$token->{tag_name});          !!!parse-error (type => 'after html:'.($token->{type} eq 'end tag' ? '/' : '').$token->{tag_name});
5183          $phase = 'main';          $phase = 'main';
5184          ## reprocess          ## reprocess
5185          redo B;          redo B;
# Line 5291  sub get_inner_html ($$$) { Line 5388  sub get_inner_html ($$$) {
5388            
5389      my $nt = $child->node_type;      my $nt = $child->node_type;
5390      if ($nt == 1) { # Element      if ($nt == 1) { # Element
5391        my $tag_name = lc $child->tag_name; ## ISSUE: Definition of "lowercase"        my $tag_name = $child->tag_name; ## TODO: manakai_tag_name
5392        $s .= '<' . $tag_name;        $s .= '<' . $tag_name;
5393          ## NOTE: Non-HTML case:
5394        ## ISSUE: Non-html elements        ## <http://permalink.gmane.org/gmane.org.w3c.whatwg.discuss/11191>
5395    
5396        my @attrs = @{$child->attributes}; # sort order MUST be stable        my @attrs = @{$child->attributes}; # sort order MUST be stable
5397        for my $attr (@attrs) { # order is implementation dependent        for my $attr (@attrs) { # order is implementation dependent
5398          my $attr_name = lc $attr->name; ## ISSUE: Definition of "lowercase"          my $attr_name = $attr->name; ## TODO: manakai_name
5399          $s .= ' ' . $attr_name . '="';          $s .= ' ' . $attr_name . '="';
5400          my $attr_value = $attr->value;          my $attr_value = $attr->value;
5401          ## escape          ## escape

Legend:
Removed from v.1.26  
changed lines
  Added in v.1.31

[email protected]
ViewVC Help
Powered by ViewVC 1.1.24