/[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.186 by wakaba, Sat Sep 20 07:54:47 2008 UTC revision 1.200 by wakaba, Sat Oct 4 11:32:15 2008 UTC
# Line 66  sub TABLE_ROWS_EL () { Line 66  sub TABLE_ROWS_EL () {
66  }  }
67    
68  ## NOTE: Used in "generate implied end tags" algorithm.  ## NOTE: Used in "generate implied end tags" algorithm.
69  ## NOTE: There is a code where a modified version of END_TAG_OPTIONAL_EL  ## NOTE: There is a code where a modified version of
70  ## is used in "generate implied end tags" implementation (search for the  ## END_TAG_OPTIONAL_EL is used in "generate implied end tags"
71  ## function mae).  ## implementation (search for the algorithm name).
72  sub END_TAG_OPTIONAL_EL () {  sub END_TAG_OPTIONAL_EL () {
73    DD_EL |    DD_EL |
74    DT_EL |    DT_EL |
75    LI_EL |    LI_EL |
76      OPTION_EL |
77      OPTGROUP_EL |
78    P_EL |    P_EL |
79    RUBY_COMPONENT_EL    RUBY_COMPONENT_EL
80  }  }
# Line 141  my $el_category = { Line 143  my $el_category = {
143    address => ADDRESS_EL,    address => ADDRESS_EL,
144    applet => MISC_SCOPING_EL,    applet => MISC_SCOPING_EL,
145    area => MISC_SPECIAL_EL,    area => MISC_SPECIAL_EL,
146      article => MISC_SPECIAL_EL,
147      aside => MISC_SPECIAL_EL,
148    b => FORMATTING_EL,    b => FORMATTING_EL,
149    base => MISC_SPECIAL_EL,    base => MISC_SPECIAL_EL,
150    basefont => MISC_SPECIAL_EL,    basefont => MISC_SPECIAL_EL,
# Line 154  my $el_category = { Line 158  my $el_category = {
158    center => MISC_SPECIAL_EL,    center => MISC_SPECIAL_EL,
159    col => MISC_SPECIAL_EL,    col => MISC_SPECIAL_EL,
160    colgroup => MISC_SPECIAL_EL,    colgroup => MISC_SPECIAL_EL,
161      command => MISC_SPECIAL_EL,
162      datagrid => MISC_SPECIAL_EL,
163    dd => DD_EL,    dd => DD_EL,
164      details => MISC_SPECIAL_EL,
165      dialog => MISC_SPECIAL_EL,
166    dir => MISC_SPECIAL_EL,    dir => MISC_SPECIAL_EL,
167    div => DIV_EL,    div => DIV_EL,
168    dl => MISC_SPECIAL_EL,    dl => MISC_SPECIAL_EL,
169    dt => DT_EL,    dt => DT_EL,
170    em => FORMATTING_EL,    em => FORMATTING_EL,
171    embed => MISC_SPECIAL_EL,    embed => MISC_SPECIAL_EL,
172      eventsource => MISC_SPECIAL_EL,
173    fieldset => MISC_SPECIAL_EL,    fieldset => MISC_SPECIAL_EL,
174      figure => MISC_SPECIAL_EL,
175    font => FORMATTING_EL,    font => FORMATTING_EL,
176      footer => MISC_SPECIAL_EL,
177    form => FORM_EL,    form => FORM_EL,
178    frame => MISC_SPECIAL_EL,    frame => MISC_SPECIAL_EL,
179    frameset => FRAMESET_EL,    frameset => FRAMESET_EL,
# Line 173  my $el_category = { Line 184  my $el_category = {
184    h5 => HEADING_EL,    h5 => HEADING_EL,
185    h6 => HEADING_EL,    h6 => HEADING_EL,
186    head => MISC_SPECIAL_EL,    head => MISC_SPECIAL_EL,
187      header => MISC_SPECIAL_EL,
188    hr => MISC_SPECIAL_EL,    hr => MISC_SPECIAL_EL,
189    html => HTML_EL,    html => HTML_EL,
190    i => FORMATTING_EL,    i => FORMATTING_EL,
191    iframe => MISC_SPECIAL_EL,    iframe => MISC_SPECIAL_EL,
192    img => MISC_SPECIAL_EL,    img => MISC_SPECIAL_EL,
193      #image => MISC_SPECIAL_EL, ## NOTE: Commented out in the spec.
194    input => MISC_SPECIAL_EL,    input => MISC_SPECIAL_EL,
195    isindex => MISC_SPECIAL_EL,    isindex => MISC_SPECIAL_EL,
196    li => LI_EL,    li => LI_EL,
# Line 186  my $el_category = { Line 199  my $el_category = {
199    marquee => MISC_SCOPING_EL,    marquee => MISC_SCOPING_EL,
200    menu => MISC_SPECIAL_EL,    menu => MISC_SPECIAL_EL,
201    meta => MISC_SPECIAL_EL,    meta => MISC_SPECIAL_EL,
202      nav => MISC_SPECIAL_EL,
203    nobr => NOBR_EL | FORMATTING_EL,    nobr => NOBR_EL | FORMATTING_EL,
204    noembed => MISC_SPECIAL_EL,    noembed => MISC_SPECIAL_EL,
205    noframes => MISC_SPECIAL_EL,    noframes => MISC_SPECIAL_EL,
# Line 204  my $el_category = { Line 218  my $el_category = {
218    s => FORMATTING_EL,    s => FORMATTING_EL,
219    script => MISC_SPECIAL_EL,    script => MISC_SPECIAL_EL,
220    select => SELECT_EL,    select => SELECT_EL,
221      section => MISC_SPECIAL_EL,
222    small => FORMATTING_EL,    small => FORMATTING_EL,
223    spacer => MISC_SPECIAL_EL,    spacer => MISC_SPECIAL_EL,
224    strike => FORMATTING_EL,    strike => FORMATTING_EL,
# Line 234  my $el_category_f = { Line 249  my $el_category_f = {
249      mtext => FOREIGN_FLOW_CONTENT_EL,      mtext => FOREIGN_FLOW_CONTENT_EL,
250    },    },
251    $SVG_NS => {    $SVG_NS => {
252      foreignObject => FOREIGN_FLOW_CONTENT_EL,      foreignObject => FOREIGN_FLOW_CONTENT_EL | MISC_SCOPING_EL,
253      desc => FOREIGN_FLOW_CONTENT_EL,      desc => FOREIGN_FLOW_CONTENT_EL,
254      title => FOREIGN_FLOW_CONTENT_EL,      title => FOREIGN_FLOW_CONTENT_EL,
255    },    },
# Line 323  my $foreign_attr_xname = { Line 338  my $foreign_attr_xname = {
338    
339  ## ISSUE: xmlns:xlink="non-xlink-ns" is not an error.  ## ISSUE: xmlns:xlink="non-xlink-ns" is not an error.
340    
341  my $c1_entity_char = {  my $charref_map = {
342      0x0D => 0x000A,
343    0x80 => 0x20AC,    0x80 => 0x20AC,
344    0x81 => 0xFFFD,    0x81 => 0xFFFD,
345    0x82 => 0x201A,    0x82 => 0x201A,
# Line 356  my $c1_entity_char = { Line 372  my $c1_entity_char = {
372    0x9D => 0xFFFD,    0x9D => 0xFFFD,
373    0x9E => 0x017E,    0x9E => 0x017E,
374    0x9F => 0x0178,    0x9F => 0x0178,
375  }; # $c1_entity_char  }; # $charref_map
376    $charref_map->{$_} = 0xFFFD
377        for 0x0000..0x0008, 0x000B, 0x000E..0x001F, 0x007F,
378            0xD800..0xDFFF, 0xFDD0..0xFDDF, ## ISSUE: 0xFDEF
379            0xFFFE, 0xFFFF, 0x1FFFE, 0x1FFFF, 0x2FFFE, 0x2FFFF, 0x3FFFE, 0x3FFFF,
380            0x4FFFE, 0x4FFFF, 0x5FFFE, 0x5FFFF, 0x6FFFE, 0x6FFFF, 0x7FFFE,
381            0x7FFFF, 0x8FFFE, 0x8FFFF, 0x9FFFE, 0x9FFFF, 0xAFFFE, 0xAFFFF,
382            0xBFFFE, 0xBFFFF, 0xCFFFE, 0xCFFFF, 0xDFFFE, 0xDFFFF, 0xEFFFE,
383            0xEFFFF, 0xFFFFE, 0xFFFFF, 0x10FFFE, 0x10FFFF;
384    
385    ## TODO: Invoke the reset algorithm when a resettable element is
386    ## created (cf. HTML5 revision 2259).
387    
388  sub parse_byte_string ($$$$;$) {  sub parse_byte_string ($$$$;$) {
389    my $self = shift;    my $self = shift;
# Line 401  sub parse_byte_stream ($$$$;$$) { Line 428  sub parse_byte_stream ($$$$;$$) {
428            ## TODO: Is this ok?  Transfer protocol's parameter should be            ## TODO: Is this ok?  Transfer protocol's parameter should be
429            ## interpreted in its semantics?            ## interpreted in its semantics?
430    
       ## ISSUE: Unsupported encoding is not ignored according to the spec.  
431        ($char_stream, $e_status) = $charset->get_decode_handle        ($char_stream, $e_status) = $charset->get_decode_handle
432            ($byte_stream, allow_error_reporting => 1,            ($byte_stream, allow_error_reporting => 1,
433             allow_fallback => 1);             allow_fallback => 1);
# Line 409  sub parse_byte_stream ($$$$;$$) { Line 435  sub parse_byte_stream ($$$$;$$) {
435          $self->{confident} = 1;          $self->{confident} = 1;
436          last SNIFFING;          last SNIFFING;
437        } else {        } else {
438          ## TODO: unsupported error          !!!parse-error (type => 'charset:not supported',
439                            layer => 'encode',
440                            line => 1, column => 1,
441                            value => $charset_name,
442                            level => $self->{level}->{uncertain});
443        }        }
444      }      }
445    
# Line 458  sub parse_byte_stream ($$$$;$$) { Line 488  sub parse_byte_stream ($$$$;$$) {
488      if (defined $charset_name) {      if (defined $charset_name) {
489        $charset = Message::Charset::Info->get_by_html_name ($charset_name);        $charset = Message::Charset::Info->get_by_html_name ($charset_name);
490    
       ## ISSUE: Unsupported encoding is not ignored according to the spec.  
491        require Whatpm::Charset::DecodeHandle;        require Whatpm::Charset::DecodeHandle;
492        $buffer = Whatpm::Charset::DecodeHandle::ByteBuffer->new        $buffer = Whatpm::Charset::DecodeHandle::ByteBuffer->new
493            ($byte_stream);            ($byte_stream);
# Line 966  sub _initialize_tokenizer ($) { Line 995  sub _initialize_tokenizer ($) {
995  ## TODO: Polytheistic slash SHOULD NOT be used. (Applied only to atheists.)  ## TODO: Polytheistic slash SHOULD NOT be used. (Applied only to atheists.)
996  ## (This requirement was dropped from HTML5 spec, unfortunately.)  ## (This requirement was dropped from HTML5 spec, unfortunately.)
997    
998    my $is_space = {
999      0x0009 => 1, # CHARACTER TABULATION (HT)
1000      0x000A => 1, # LINE FEED (LF)
1001      #0x000B => 0, # LINE TABULATION (VT)
1002      0x000C => 1, # FORM FEED (FF)
1003      #0x000D => 1, # CARRIAGE RETURN (CR)
1004      0x0020 => 1, # SPACE (SP)
1005    };
1006    
1007  sub _get_next_token ($) {  sub _get_next_token ($) {
1008    my $self = shift;    my $self = shift;
1009    
# Line 1336  sub _get_next_token ($) { Line 1374  sub _get_next_token ($) {
1374            redo A;            redo A;
1375          }          }
1376        } else { # after "<{tag-name}"        } else { # after "<{tag-name}"
1377          unless ({          unless ($is_space->{$self->{nc}} or
1378                   0x0009 => 1, # HT                  {
                  0x000A => 1, # LF  
                  0x000B => 1, # VT  
                  0x000C => 1, # FF  
                  0x0020 => 1, # SP  
1379                   0x003E => 1, # >                   0x003E => 1, # >
1380                   0x002F => 1, # /                   0x002F => 1, # /
1381                   -1 => 1, # EOF                   -1 => 1, # EOF
# Line 1368  sub _get_next_token ($) { Line 1402  sub _get_next_token ($) {
1402          }          }
1403        }        }
1404      } elsif ($self->{state} == TAG_NAME_STATE) {      } elsif ($self->{state} == TAG_NAME_STATE) {
1405        if ($self->{nc} == 0x0009 or # HT        if ($is_space->{$self->{nc}}) {
           $self->{nc} == 0x000A or # LF  
           $self->{nc} == 0x000B or # VT  
           $self->{nc} == 0x000C or # FF  
           $self->{nc} == 0x0020) { # SP  
1406          !!!cp (34);          !!!cp (34);
1407          $self->{state} = BEFORE_ATTRIBUTE_NAME_STATE;          $self->{state} = BEFORE_ATTRIBUTE_NAME_STATE;
1408          !!!next-input-character;          !!!next-input-character;
# Line 1444  sub _get_next_token ($) { Line 1474  sub _get_next_token ($) {
1474          redo A;          redo A;
1475        }        }
1476      } elsif ($self->{state} == BEFORE_ATTRIBUTE_NAME_STATE) {      } elsif ($self->{state} == BEFORE_ATTRIBUTE_NAME_STATE) {
1477        if ($self->{nc} == 0x0009 or # HT        if ($is_space->{$self->{nc}}) {
           $self->{nc} == 0x000A or # LF  
           $self->{nc} == 0x000B or # VT  
           $self->{nc} == 0x000C or # FF  
           $self->{nc} == 0x0020) { # SP  
1478          !!!cp (45);          !!!cp (45);
1479          ## Stay in the state          ## Stay in the state
1480          !!!next-input-character;          !!!next-input-character;
# Line 1544  sub _get_next_token ($) { Line 1570  sub _get_next_token ($) {
1570          }          }
1571        }; # $before_leave        }; # $before_leave
1572    
1573        if ($self->{nc} == 0x0009 or # HT        if ($is_space->{$self->{nc}}) {
           $self->{nc} == 0x000A or # LF  
           $self->{nc} == 0x000B or # VT  
           $self->{nc} == 0x000C or # FF  
           $self->{nc} == 0x0020) { # SP  
1574          !!!cp (59);          !!!cp (59);
1575          $before_leave->();          $before_leave->();
1576          $self->{state} = AFTER_ATTRIBUTE_NAME_STATE;          $self->{state} = AFTER_ATTRIBUTE_NAME_STATE;
# Line 1631  sub _get_next_token ($) { Line 1653  sub _get_next_token ($) {
1653          redo A;          redo A;
1654        }        }
1655      } elsif ($self->{state} == AFTER_ATTRIBUTE_NAME_STATE) {      } elsif ($self->{state} == AFTER_ATTRIBUTE_NAME_STATE) {
1656        if ($self->{nc} == 0x0009 or # HT        if ($is_space->{$self->{nc}}) {
           $self->{nc} == 0x000A or # LF  
           $self->{nc} == 0x000B or # VT  
           $self->{nc} == 0x000C or # FF  
           $self->{nc} == 0x0020) { # SP  
1657          !!!cp (71);          !!!cp (71);
1658          ## Stay in the state          ## Stay in the state
1659          !!!next-input-character;          !!!next-input-character;
# Line 1722  sub _get_next_token ($) { Line 1740  sub _get_next_token ($) {
1740          redo A;                  redo A;        
1741        }        }
1742      } elsif ($self->{state} == BEFORE_ATTRIBUTE_VALUE_STATE) {      } elsif ($self->{state} == BEFORE_ATTRIBUTE_VALUE_STATE) {
1743        if ($self->{nc} == 0x0009 or # HT        if ($is_space->{$self->{nc}}) {
           $self->{nc} == 0x000A or # LF  
           $self->{nc} == 0x000B or # VT  
           $self->{nc} == 0x000C or # FF  
           $self->{nc} == 0x0020) { # SP        
1744          !!!cp (83);          !!!cp (83);
1745          ## Stay in the state          ## Stay in the state
1746          !!!next-input-character;          !!!next-input-character;
# Line 1907  sub _get_next_token ($) { Line 1921  sub _get_next_token ($) {
1921          redo A;          redo A;
1922        }        }
1923      } elsif ($self->{state} == ATTRIBUTE_VALUE_UNQUOTED_STATE) {      } elsif ($self->{state} == ATTRIBUTE_VALUE_UNQUOTED_STATE) {
1924        if ($self->{nc} == 0x0009 or # HT        if ($is_space->{$self->{nc}}) {
           $self->{nc} == 0x000A or # LF  
           $self->{nc} == 0x000B or # HT  
           $self->{nc} == 0x000C or # FF  
           $self->{nc} == 0x0020) { # SP  
1925          !!!cp (107);          !!!cp (107);
1926          $self->{state} = BEFORE_ATTRIBUTE_NAME_STATE;          $self->{state} = BEFORE_ATTRIBUTE_NAME_STATE;
1927          !!!next-input-character;          !!!next-input-character;
# Line 1993  sub _get_next_token ($) { Line 2003  sub _get_next_token ($) {
2003          redo A;          redo A;
2004        }        }
2005      } elsif ($self->{state} == AFTER_ATTRIBUTE_VALUE_QUOTED_STATE) {      } elsif ($self->{state} == AFTER_ATTRIBUTE_VALUE_QUOTED_STATE) {
2006        if ($self->{nc} == 0x0009 or # HT        if ($is_space->{$self->{nc}}) {
           $self->{nc} == 0x000A or # LF  
           $self->{nc} == 0x000B or # VT  
           $self->{nc} == 0x000C or # FF  
           $self->{nc} == 0x0020) { # SP  
2007          !!!cp (118);          !!!cp (118);
2008          $self->{state} = BEFORE_ATTRIBUTE_NAME_STATE;          $self->{state} = BEFORE_ATTRIBUTE_NAME_STATE;
2009          !!!next-input-character;          !!!next-input-character;
# Line 2438  sub _get_next_token ($) { Line 2444  sub _get_next_token ($) {
2444          redo A;          redo A;
2445        }        }
2446      } elsif ($self->{state} == DOCTYPE_STATE) {      } elsif ($self->{state} == DOCTYPE_STATE) {
2447        if ($self->{nc} == 0x0009 or # HT        if ($is_space->{$self->{nc}}) {
           $self->{nc} == 0x000A or # LF  
           $self->{nc} == 0x000B or # VT  
           $self->{nc} == 0x000C or # FF  
           $self->{nc} == 0x0020) { # SP  
2448          !!!cp (155);          !!!cp (155);
2449          $self->{state} = BEFORE_DOCTYPE_NAME_STATE;          $self->{state} = BEFORE_DOCTYPE_NAME_STATE;
2450          !!!next-input-character;          !!!next-input-character;
# Line 2455  sub _get_next_token ($) { Line 2457  sub _get_next_token ($) {
2457          redo A;          redo A;
2458        }        }
2459      } elsif ($self->{state} == BEFORE_DOCTYPE_NAME_STATE) {      } elsif ($self->{state} == BEFORE_DOCTYPE_NAME_STATE) {
2460        if ($self->{nc} == 0x0009 or # HT        if ($is_space->{$self->{nc}}) {
           $self->{nc} == 0x000A or # LF  
           $self->{nc} == 0x000B or # VT  
           $self->{nc} == 0x000C or # FF  
           $self->{nc} == 0x0020) { # SP  
2461          !!!cp (157);          !!!cp (157);
2462          ## Stay in the state          ## Stay in the state
2463          !!!next-input-character;          !!!next-input-character;
# Line 2486  sub _get_next_token ($) { Line 2484  sub _get_next_token ($) {
2484          !!!cp (160);          !!!cp (160);
2485          $self->{ct}->{name} = chr $self->{nc};          $self->{ct}->{name} = chr $self->{nc};
2486          delete $self->{ct}->{quirks};          delete $self->{ct}->{quirks};
 ## ISSUE: "Set the token's name name to the" in the spec  
2487          $self->{state} = DOCTYPE_NAME_STATE;          $self->{state} = DOCTYPE_NAME_STATE;
2488          !!!next-input-character;          !!!next-input-character;
2489          redo A;          redo A;
2490        }        }
2491      } elsif ($self->{state} == DOCTYPE_NAME_STATE) {      } elsif ($self->{state} == DOCTYPE_NAME_STATE) {
2492  ## ISSUE: Redundant "First," in the spec.  ## ISSUE: Redundant "First," in the spec.
2493        if ($self->{nc} == 0x0009 or # HT        if ($is_space->{$self->{nc}}) {
           $self->{nc} == 0x000A or # LF  
           $self->{nc} == 0x000B or # VT  
           $self->{nc} == 0x000C or # FF  
           $self->{nc} == 0x0020) { # SP  
2494          !!!cp (161);          !!!cp (161);
2495          $self->{state} = AFTER_DOCTYPE_NAME_STATE;          $self->{state} = AFTER_DOCTYPE_NAME_STATE;
2496          !!!next-input-character;          !!!next-input-character;
# Line 2529  sub _get_next_token ($) { Line 2522  sub _get_next_token ($) {
2522          redo A;          redo A;
2523        }        }
2524      } elsif ($self->{state} == AFTER_DOCTYPE_NAME_STATE) {      } elsif ($self->{state} == AFTER_DOCTYPE_NAME_STATE) {
2525        if ($self->{nc} == 0x0009 or # HT        if ($is_space->{$self->{nc}}) {
           $self->{nc} == 0x000A or # LF  
           $self->{nc} == 0x000B or # VT  
           $self->{nc} == 0x000C or # FF  
           $self->{nc} == 0x0020) { # SP  
2526          !!!cp (165);          !!!cp (165);
2527          ## Stay in the state          ## Stay in the state
2528          !!!next-input-character;          !!!next-input-character;
# Line 2656  sub _get_next_token ($) { Line 2645  sub _get_next_token ($) {
2645          redo A;          redo A;
2646        }        }
2647      } elsif ($self->{state} == BEFORE_DOCTYPE_PUBLIC_IDENTIFIER_STATE) {      } elsif ($self->{state} == BEFORE_DOCTYPE_PUBLIC_IDENTIFIER_STATE) {
2648        if ({        if ($is_space->{$self->{nc}}) {
             0x0009 => 1, 0x000A => 1, 0x000B => 1, 0x000C => 1, 0x0020 => 1,  
             #0x000D => 1, # HT, LF, VT, FF, SP, CR  
           }->{$self->{nc}}) {  
2649          !!!cp (181);          !!!cp (181);
2650          ## Stay in the state          ## Stay in the state
2651          !!!next-input-character;          !!!next-input-character;
# Line 2786  sub _get_next_token ($) { Line 2772  sub _get_next_token ($) {
2772          redo A;          redo A;
2773        }        }
2774      } elsif ($self->{state} == AFTER_DOCTYPE_PUBLIC_IDENTIFIER_STATE) {      } elsif ($self->{state} == AFTER_DOCTYPE_PUBLIC_IDENTIFIER_STATE) {
2775        if ({        if ($is_space->{$self->{nc}}) {
             0x0009 => 1, 0x000A => 1, 0x000B => 1, 0x000C => 1, 0x0020 => 1,  
             #0x000D => 1, # HT, LF, VT, FF, SP, CR  
           }->{$self->{nc}}) {  
2776          !!!cp (195);          !!!cp (195);
2777          ## Stay in the state          ## Stay in the state
2778          !!!next-input-character;          !!!next-input-character;
# Line 2835  sub _get_next_token ($) { Line 2818  sub _get_next_token ($) {
2818          redo A;          redo A;
2819        }        }
2820      } elsif ($self->{state} == BEFORE_DOCTYPE_SYSTEM_IDENTIFIER_STATE) {      } elsif ($self->{state} == BEFORE_DOCTYPE_SYSTEM_IDENTIFIER_STATE) {
2821        if ({        if ($is_space->{$self->{nc}}) {
             0x0009 => 1, 0x000A => 1, 0x000B => 1, 0x000C => 1, 0x0020 => 1,  
             #0x000D => 1, # HT, LF, VT, FF, SP, CR  
           }->{$self->{nc}}) {  
2822          !!!cp (201);          !!!cp (201);
2823          ## Stay in the state          ## Stay in the state
2824          !!!next-input-character;          !!!next-input-character;
# Line 2964  sub _get_next_token ($) { Line 2944  sub _get_next_token ($) {
2944          redo A;          redo A;
2945        }        }
2946      } elsif ($self->{state} == AFTER_DOCTYPE_SYSTEM_IDENTIFIER_STATE) {      } elsif ($self->{state} == AFTER_DOCTYPE_SYSTEM_IDENTIFIER_STATE) {
2947        if ({        if ($is_space->{$self->{nc}}) {
             0x0009 => 1, 0x000A => 1, 0x000B => 1, 0x000C => 1, 0x0020 => 1,  
             #0x000D => 1, # HT, LF, VT, FF, SP, CR  
           }->{$self->{nc}}) {  
2948          !!!cp (215);          !!!cp (215);
2949          ## Stay in the state          ## Stay in the state
2950          !!!next-input-character;          !!!next-input-character;
# Line 3099  sub _get_next_token ($) { Line 3076  sub _get_next_token ($) {
3076          redo A;          redo A;
3077        }        }
3078      } elsif ($self->{state} == ENTITY_STATE) {      } elsif ($self->{state} == ENTITY_STATE) {
3079        if ({        if ($is_space->{$self->{nc}} or
3080          0x0009 => 1, 0x000A => 1, 0x000B => 1, 0x000C => 1, # HT, LF, VT, FF,            {
3081          0x0020 => 1, 0x003C => 1, 0x0026 => 1, -1 => 1, # SP, <, &              0x003C => 1, 0x0026 => 1, -1 => 1, # <, &
3082          $self->{entity_add} => 1,              $self->{entity_add} => 1,
3083        }->{$self->{nc}}) {            }->{$self->{nc}}) {
3084          !!!cp (1001);          !!!cp (1001);
3085          ## Don't consume          ## Don't consume
3086          ## No error          ## No error
# Line 3222  sub _get_next_token ($) { Line 3199  sub _get_next_token ($) {
3199        my $code = $self->{s_kwd};        my $code = $self->{s_kwd};
3200        my $l = $self->{line_prev};        my $l = $self->{line_prev};
3201        my $c = $self->{column_prev};        my $c = $self->{column_prev};
3202        if ($code == 0 or (0xD800 <= $code and $code <= 0xDFFF)) {        if ($charref_map->{$code}) {
3203          !!!cp (1015);          !!!cp (1015);
3204          !!!parse-error (type => 'invalid character reference',          !!!parse-error (type => 'invalid character reference',
3205                          text => (sprintf 'U+%04X', $code),                          text => (sprintf 'U+%04X', $code),
3206                          line => $l, column => $c);                          line => $l, column => $c);
3207          $code = 0xFFFD;          $code = $charref_map->{$code};
3208        } elsif ($code > 0x10FFFF) {        } elsif ($code > 0x10FFFF) {
3209          !!!cp (1016);          !!!cp (1016);
3210          !!!parse-error (type => 'invalid character reference',          !!!parse-error (type => 'invalid character reference',
3211                          text => (sprintf 'U-%08X', $code),                          text => (sprintf 'U-%08X', $code),
3212                          line => $l, column => $c);                          line => $l, column => $c);
3213          $code = 0xFFFD;          $code = 0xFFFD;
       } elsif ($code == 0x000D) {  
         !!!cp (1017);  
         !!!parse-error (type => 'CR character reference',  
                         line => $l, column => $c);  
         $code = 0x000A;  
       } elsif (0x80 <= $code and $code <= 0x9F) {  
         !!!cp (1018);  
         !!!parse-error (type => 'C1 character reference',  
                         text => (sprintf 'U+%04X', $code),  
                         line => $l, column => $c);  
         $code = $c1_entity_char->{$code};  
3214        }        }
3215    
3216        if ($self->{prev_state} == DATA_STATE) {        if ($self->{prev_state} == DATA_STATE) {
# Line 3341  sub _get_next_token ($) { Line 3307  sub _get_next_token ($) {
3307        my $code = $self->{s_kwd};        my $code = $self->{s_kwd};
3308        my $l = $self->{line_prev};        my $l = $self->{line_prev};
3309        my $c = $self->{column_prev};        my $c = $self->{column_prev};
3310        if ($code == 0 or (0xD800 <= $code and $code <= 0xDFFF)) {        if ($charref_map->{$code}) {
3311          !!!cp (1008);          !!!cp (1008);
3312          !!!parse-error (type => 'invalid character reference',          !!!parse-error (type => 'invalid character reference',
3313                          text => (sprintf 'U+%04X', $code),                          text => (sprintf 'U+%04X', $code),
3314                          line => $l, column => $c);                          line => $l, column => $c);
3315          $code = 0xFFFD;          $code = $charref_map->{$code};
3316        } elsif ($code > 0x10FFFF) {        } elsif ($code > 0x10FFFF) {
3317          !!!cp (1009);          !!!cp (1009);
3318          !!!parse-error (type => 'invalid character reference',          !!!parse-error (type => 'invalid character reference',
3319                          text => (sprintf 'U-%08X', $code),                          text => (sprintf 'U-%08X', $code),
3320                          line => $l, column => $c);                          line => $l, column => $c);
3321          $code = 0xFFFD;          $code = 0xFFFD;
       } elsif ($code == 0x000D) {  
         !!!cp (1010);  
         !!!parse-error (type => 'CR character reference', line => $l, column => $c);  
         $code = 0x000A;  
       } elsif (0x80 <= $code and $code <= 0x9F) {  
         !!!cp (1011);  
         !!!parse-error (type => 'C1 character reference', text => (sprintf 'U+%04X', $code), line => $l, column => $c);  
         $code = $c1_entity_char->{$code};  
3322        }        }
3323    
3324        if ($self->{prev_state} == DATA_STATE) {        if ($self->{prev_state} == DATA_STATE) {
# Line 3701  sub _tree_construction_initial ($) { Line 3659  sub _tree_construction_initial ($) {
3659        !!!ack-later;        !!!ack-later;
3660        return;        return;
3661      } elsif ($token->{type} == CHARACTER_TOKEN) {      } elsif ($token->{type} == CHARACTER_TOKEN) {
3662        if ($token->{data} =~ s/^([\x09\x0A\x0B\x0C\x20]+)//) { # \x0D        if ($token->{data} =~ s/^([\x09\x0A\x0C\x20]+)//) {
3663          ## Ignore the token          ## Ignore the token
3664    
3665          unless (length $token->{data}) {          unless (length $token->{data}) {
# Line 3758  sub _tree_construction_root_element ($) Line 3716  sub _tree_construction_root_element ($)
3716          !!!next-token;          !!!next-token;
3717          redo B;          redo B;
3718        } elsif ($token->{type} == CHARACTER_TOKEN) {        } elsif ($token->{type} == CHARACTER_TOKEN) {
3719          if ($token->{data} =~ s/^([\x09\x0A\x0B\x0C\x20]+)//) { # \x0D          if ($token->{data} =~ s/^([\x09\x0A\x0C\x20]+)//) {
3720            ## Ignore the token.            ## Ignore the token.
3721    
3722            unless (length $token->{data}) {            unless (length $token->{data}) {
# Line 3825  sub _tree_construction_root_element ($) Line 3783  sub _tree_construction_root_element ($)
3783      ## NOTE: Reprocess the token.      ## NOTE: Reprocess the token.
3784      !!!ack-later;      !!!ack-later;
3785      return; ## Go to the "before head" insertion mode.      return; ## Go to the "before head" insertion mode.
   
     ## ISSUE: There is an issue in the spec  
3786    } # B    } # B
3787    
3788    die "$0: _tree_construction_root_element: This should never be reached";    die "$0: _tree_construction_root_element: This should never be reached";
# Line 4562  sub _tree_construction_main ($) { Line 4518  sub _tree_construction_main ($) {
4518          pop @{$self->{open_elements}}          pop @{$self->{open_elements}}
4519              while $self->{open_elements}->[-1]->[1] & FOREIGN_EL;              while $self->{open_elements}->[-1]->[1] & FOREIGN_EL;
4520    
4521            ## NOTE: |<span><svg>| ... two parse errors, |<svg>| ... a parse error.
4522    
4523          $self->{insertion_mode} &= ~ IN_FOREIGN_CONTENT_IM;          $self->{insertion_mode} &= ~ IN_FOREIGN_CONTENT_IM;
4524          ## Reprocess.          ## Reprocess.
4525          next B;          next B;
# Line 4572  sub _tree_construction_main ($) { Line 4530  sub _tree_construction_main ($) {
4530    
4531      if ($self->{insertion_mode} & HEAD_IMS) {      if ($self->{insertion_mode} & HEAD_IMS) {
4532        if ($token->{type} == CHARACTER_TOKEN) {        if ($token->{type} == CHARACTER_TOKEN) {
4533          if ($token->{data} =~ s/^([\x09\x0A\x0B\x0C\x20]+)//) {          if ($token->{data} =~ s/^([\x09\x0A\x0C\x20]+)//) {
4534            unless ($self->{insertion_mode} == BEFORE_HEAD_IM) {            unless ($self->{insertion_mode} == BEFORE_HEAD_IM) {
4535              !!!cp ('t88.2');              !!!cp ('t88.2');
4536              $self->{open_elements}->[-1]->[0]->manakai_append_text ($1);              $self->{open_elements}->[-1]->[0]->manakai_append_text ($1);
# Line 4697  sub _tree_construction_main ($) { Line 4655  sub _tree_construction_main ($) {
4655                  !!!cp ('t101');                  !!!cp ('t101');
4656                }                }
4657                !!!insert-element ($token->{tag_name}, $token->{attributes}, $token);                !!!insert-element ($token->{tag_name}, $token->{attributes}, $token);
4658                pop @{$self->{open_elements}}; ## ISSUE: This step is missing in the spec.                pop @{$self->{open_elements}};
4659                pop @{$self->{open_elements}} # <head>                pop @{$self->{open_elements}} # <head>
4660                    if $self->{insertion_mode} == AFTER_HEAD_IM;                    if $self->{insertion_mode} == AFTER_HEAD_IM;
4661                !!!nack ('t101.1');                !!!nack ('t101.1');
4662                !!!next-token;                !!!next-token;
4663                next B;                next B;
4664              } elsif ($token->{tag_name} eq 'link') {          } elsif ($token->{tag_name} eq 'link') {
4665                ## NOTE: There is a "as if in head" code clone.            ## NOTE: There is a "as if in head" code clone.
4666                if ($self->{insertion_mode} == AFTER_HEAD_IM) {            if ($self->{insertion_mode} == AFTER_HEAD_IM) {
4667                  !!!cp ('t102');              !!!cp ('t102');
4668                  !!!parse-error (type => 'after head',              !!!parse-error (type => 'after head',
4669                                  text => $token->{tag_name}, token => $token);                              text => $token->{tag_name}, token => $token);
4670                  push @{$self->{open_elements}},              push @{$self->{open_elements}},
4671                      [$self->{head_element}, $el_category->{head}];                  [$self->{head_element}, $el_category->{head}];
4672                } else {            } else {
4673                  !!!cp ('t103');              !!!cp ('t103');
4674                }            }
4675                !!!insert-element ($token->{tag_name}, $token->{attributes}, $token);            !!!insert-element ($token->{tag_name}, $token->{attributes}, $token);
4676                pop @{$self->{open_elements}}; ## ISSUE: This step is missing in the spec.            pop @{$self->{open_elements}};
4677                pop @{$self->{open_elements}} # <head>            pop @{$self->{open_elements}} # <head>
4678                    if $self->{insertion_mode} == AFTER_HEAD_IM;                if $self->{insertion_mode} == AFTER_HEAD_IM;
4679                !!!ack ('t103.1');            !!!ack ('t103.1');
4680                !!!next-token;            !!!next-token;
4681                next B;            next B;
4682            } elsif ($token->{tag_name} eq 'command' or
4683                     $token->{tag_name} eq 'eventsource') {
4684              if ($self->{insertion_mode} == IN_HEAD_IM) {
4685                ## NOTE: If the insertion mode at the time of the emission
4686                ## of the token was "before head", $self->{insertion_mode}
4687                ## is already changed to |IN_HEAD_IM|.
4688    
4689                ## NOTE: There is a "as if in head" code clone.
4690                !!!insert-element ($token->{tag_name}, $token->{attributes}, $token);
4691                pop @{$self->{open_elements}};
4692                pop @{$self->{open_elements}} # <head>
4693                    if $self->{insertion_mode} == AFTER_HEAD_IM;
4694                !!!ack ('t103.2');
4695                !!!next-token;
4696                next B;
4697              } else {
4698                ## NOTE: "in head noscript" or "after head" insertion mode
4699                ## - in these cases, these tags are treated as same as
4700                ## normal in-body tags.
4701                !!!cp ('t103.3');
4702                #
4703              }
4704              } elsif ($token->{tag_name} eq 'meta') {              } elsif ($token->{tag_name} eq 'meta') {
4705                ## NOTE: There is a "as if in head" code clone.                ## NOTE: There is a "as if in head" code clone.
4706                if ($self->{insertion_mode} == AFTER_HEAD_IM) {                if ($self->{insertion_mode} == AFTER_HEAD_IM) {
# Line 4733  sub _tree_construction_main ($) { Line 4713  sub _tree_construction_main ($) {
4713                  !!!cp ('t105');                  !!!cp ('t105');
4714                }                }
4715                !!!insert-element ($token->{tag_name}, $token->{attributes}, $token);                !!!insert-element ($token->{tag_name}, $token->{attributes}, $token);
4716                my $meta_el = pop @{$self->{open_elements}}; ## ISSUE: This step is missing in the spec.                my $meta_el = pop @{$self->{open_elements}};
4717    
4718                unless ($self->{confident}) {                unless ($self->{confident}) {
4719                  if ($token->{attributes}->{charset}) {                  if ($token->{attributes}->{charset}) {
# Line 5190  sub _tree_construction_main ($) { Line 5170  sub _tree_construction_main ($) {
5170        } else {        } else {
5171          die "$0: $token->{type}: Unknown token type";          die "$0: $token->{type}: Unknown token type";
5172        }        }
   
           ## ISSUE: An issue in the spec.  
5173      } elsif ($self->{insertion_mode} & BODY_IMS) {      } elsif ($self->{insertion_mode} & BODY_IMS) {
5174            if ($token->{type} == CHARACTER_TOKEN) {            if ($token->{type} == CHARACTER_TOKEN) {
5175              !!!cp ('t150');              !!!cp ('t150');
# Line 5563  sub _tree_construction_main ($) { Line 5541  sub _tree_construction_main ($) {
5541      } elsif ($self->{insertion_mode} & TABLE_IMS) {      } elsif ($self->{insertion_mode} & TABLE_IMS) {
5542        if ($token->{type} == CHARACTER_TOKEN) {        if ($token->{type} == CHARACTER_TOKEN) {
5543          if (not $open_tables->[-1]->[1] and # tainted          if (not $open_tables->[-1]->[1] and # tainted
5544              $token->{data} =~ s/^([\x09\x0A\x0B\x0C\x20]+)//) {              $token->{data} =~ s/^([\x09\x0A\x0C\x20]+)//) {
5545            $self->{open_elements}->[-1]->[0]->manakai_append_text ($1);            $self->{open_elements}->[-1]->[0]->manakai_append_text ($1);
5546                                
5547            unless (length $token->{data}) {            unless (length $token->{data}) {
# Line 6247  sub _tree_construction_main ($) { Line 6225  sub _tree_construction_main ($) {
6225        }        }
6226      } elsif ($self->{insertion_mode} == IN_COLUMN_GROUP_IM) {      } elsif ($self->{insertion_mode} == IN_COLUMN_GROUP_IM) {
6227            if ($token->{type} == CHARACTER_TOKEN) {            if ($token->{type} == CHARACTER_TOKEN) {
6228              if ($token->{data} =~ s/^([\x09\x0A\x0B\x0C\x20]+)//) {              if ($token->{data} =~ s/^([\x09\x0A\x0C\x20]+)//) {
6229                $self->{open_elements}->[-1]->[0]->manakai_append_text ($1);                $self->{open_elements}->[-1]->[0]->manakai_append_text ($1);
6230                unless (length $token->{data}) {                unless (length $token->{data}) {
6231                  !!!cp ('t260');                  !!!cp ('t260');
# Line 6588  sub _tree_construction_main ($) { Line 6566  sub _tree_construction_main ($) {
6566        }        }
6567      } elsif ($self->{insertion_mode} & BODY_AFTER_IMS) {      } elsif ($self->{insertion_mode} & BODY_AFTER_IMS) {
6568        if ($token->{type} == CHARACTER_TOKEN) {        if ($token->{type} == CHARACTER_TOKEN) {
6569          if ($token->{data} =~ s/^([\x09\x0A\x0B\x0C\x20]+)//) {          if ($token->{data} =~ s/^([\x09\x0A\x0C\x20]+)//) {
6570            my $data = $1;            my $data = $1;
6571            ## As if in body            ## As if in body
6572            $reconstruct_active_formatting_elements->($insert_to_current);            $reconstruct_active_formatting_elements->($insert_to_current);
# Line 6605  sub _tree_construction_main ($) { Line 6583  sub _tree_construction_main ($) {
6583          if ($self->{insertion_mode} == AFTER_HTML_BODY_IM) {          if ($self->{insertion_mode} == AFTER_HTML_BODY_IM) {
6584            !!!cp ('t301');            !!!cp ('t301');
6585            !!!parse-error (type => 'after html:#text', token => $token);            !!!parse-error (type => 'after html:#text', token => $token);
6586              #
           ## Reprocess in the "after body" insertion mode.  
6587          } else {          } else {
6588            !!!cp ('t302');            !!!cp ('t302');
6589              ## "after body" insertion mode
6590              !!!parse-error (type => 'after body:#text', token => $token);
6591              #
6592          }          }
           
         ## "after body" insertion mode  
         !!!parse-error (type => 'after body:#text', token => $token);  
6593    
6594          $self->{insertion_mode} = IN_BODY_IM;          $self->{insertion_mode} = IN_BODY_IM;
6595          ## reprocess          ## reprocess
# Line 6622  sub _tree_construction_main ($) { Line 6599  sub _tree_construction_main ($) {
6599            !!!cp ('t303');            !!!cp ('t303');
6600            !!!parse-error (type => 'after html',            !!!parse-error (type => 'after html',
6601                            text => $token->{tag_name}, token => $token);                            text => $token->{tag_name}, token => $token);
6602                        #
           ## Reprocess in the "after body" insertion mode.  
6603          } else {          } else {
6604            !!!cp ('t304');            !!!cp ('t304');
6605              ## "after body" insertion mode
6606              !!!parse-error (type => 'after body',
6607                              text => $token->{tag_name}, token => $token);
6608              #
6609          }          }
6610    
         ## "after body" insertion mode  
         !!!parse-error (type => 'after body',  
                         text => $token->{tag_name}, token => $token);  
   
6611          $self->{insertion_mode} = IN_BODY_IM;          $self->{insertion_mode} = IN_BODY_IM;
6612          !!!ack-later;          !!!ack-later;
6613          ## reprocess          ## reprocess
# Line 6642  sub _tree_construction_main ($) { Line 6618  sub _tree_construction_main ($) {
6618            !!!parse-error (type => 'after html:/',            !!!parse-error (type => 'after html:/',
6619                            text => $token->{tag_name}, token => $token);                            text => $token->{tag_name}, token => $token);
6620                        
6621            $self->{insertion_mode} = AFTER_BODY_IM;            $self->{insertion_mode} = IN_BODY_IM;
6622            ## Reprocess in the "after body" insertion mode.            ## Reprocess.
6623              next B;
6624          } else {          } else {
6625            !!!cp ('t306');            !!!cp ('t306');
6626          }          }
# Line 6681  sub _tree_construction_main ($) { Line 6658  sub _tree_construction_main ($) {
6658        }        }
6659      } elsif ($self->{insertion_mode} & FRAME_IMS) {      } elsif ($self->{insertion_mode} & FRAME_IMS) {
6660        if ($token->{type} == CHARACTER_TOKEN) {        if ($token->{type} == CHARACTER_TOKEN) {
6661          if ($token->{data} =~ s/^([\x09\x0A\x0B\x0C\x20]+)//) {          if ($token->{data} =~ s/^([\x09\x0A\x0C\x20]+)//) {
6662            $self->{open_elements}->[-1]->[0]->manakai_append_text ($1);            $self->{open_elements}->[-1]->[0]->manakai_append_text ($1);
6663                        
6664            unless (length $token->{data}) {            unless (length $token->{data}) {
# Line 6691  sub _tree_construction_main ($) { Line 6668  sub _tree_construction_main ($) {
6668            }            }
6669          }          }
6670                    
6671          if ($token->{data} =~ s/^[^\x09\x0A\x0B\x0C\x20]+//) {          if ($token->{data} =~ s/^[^\x09\x0A\x0C\x20]+//) {
6672            if ($self->{insertion_mode} == IN_FRAMESET_IM) {            if ($self->{insertion_mode} == IN_FRAMESET_IM) {
6673              !!!cp ('t311');              !!!cp ('t311');
6674              !!!parse-error (type => 'in frameset:#text', token => $token);              !!!parse-error (type => 'in frameset:#text', token => $token);
# Line 6820  sub _tree_construction_main ($) { Line 6797  sub _tree_construction_main ($) {
6797        } else {        } else {
6798          die "$0: $token->{type}: Unknown token type";          die "$0: $token->{type}: Unknown token type";
6799        }        }
   
       ## ISSUE: An issue in spec here  
6800      } else {      } else {
6801        die "$0: $self->{insertion_mode}: Unknown insertion mode";        die "$0: $self->{insertion_mode}: Unknown insertion mode";
6802      }      }
# Line 6839  sub _tree_construction_main ($) { Line 6814  sub _tree_construction_main ($) {
6814          $parse_rcdata->(CDATA_CONTENT_MODEL);          $parse_rcdata->(CDATA_CONTENT_MODEL);
6815          next B;          next B;
6816        } elsif ({        } elsif ({
6817                  base => 1, link => 1,                  base => 1, command => 1, eventsource => 1, link => 1,
6818                 }->{$token->{tag_name}}) {                 }->{$token->{tag_name}}) {
6819          !!!cp ('t334');          !!!cp ('t334');
6820          ## NOTE: This is an "as if in head" code clone, only "-t" differs          ## NOTE: This is an "as if in head" code clone, only "-t" differs
6821          !!!insert-element-t ($token->{tag_name}, $token->{attributes}, $token);          !!!insert-element-t ($token->{tag_name}, $token->{attributes}, $token);
6822          pop @{$self->{open_elements}}; ## ISSUE: This step is missing in the spec.          pop @{$self->{open_elements}};
6823          !!!ack ('t334.1');          !!!ack ('t334.1');
6824          !!!next-token;          !!!next-token;
6825          next B;          next B;
6826        } elsif ($token->{tag_name} eq 'meta') {        } elsif ($token->{tag_name} eq 'meta') {
6827          ## NOTE: This is an "as if in head" code clone, only "-t" differs          ## NOTE: This is an "as if in head" code clone, only "-t" differs
6828          !!!insert-element-t ($token->{tag_name}, $token->{attributes}, $token);          !!!insert-element-t ($token->{tag_name}, $token->{attributes}, $token);
6829          my $meta_el = pop @{$self->{open_elements}}; ## ISSUE: This step is missing in the spec.          my $meta_el = pop @{$self->{open_elements}};
6830    
6831          unless ($self->{confident}) {          unless ($self->{confident}) {
6832            if ($token->{attributes}->{charset}) {            if ($token->{attributes}->{charset}) {
# Line 6868  sub _tree_construction_main ($) { Line 6843  sub _tree_construction_main ($) {
6843            } elsif ($token->{attributes}->{content}) {            } elsif ($token->{attributes}->{content}) {
6844              if ($token->{attributes}->{content}->{value}              if ($token->{attributes}->{content}->{value}
6845                  =~ /[Cc][Hh][Aa][Rr][Ss][Ee][Tt]                  =~ /[Cc][Hh][Aa][Rr][Ss][Ee][Tt]
6846                      [\x09-\x0D\x20]*=                      [\x09\x0A\x0C\x0D\x20]*=
6847                      [\x09-\x0D\x20]*(?>"([^"]*)"|'([^']*)'|                      [\x09\x0A\x0C\x0D\x20]*(?>"([^"]*)"|'([^']*)'|
6848                      ([^"'\x09-\x0D\x20][^\x09-\x0D\x20\x3B]*))/x) {                      ([^"'\x09\x0A\x0C\x0D\x20][^\x09\x0A\x0C\x0D\x20\x3B]*))
6849                       /x) {
6850                !!!cp ('t336');                !!!cp ('t336');
6851                ## NOTE: Whether the encoding is supported or not is handled                ## NOTE: Whether the encoding is supported or not is handled
6852                ## in the {change_encoding} callback.                ## in the {change_encoding} callback.
# Line 6929  sub _tree_construction_main ($) { Line 6905  sub _tree_construction_main ($) {
6905          !!!next-token;          !!!next-token;
6906          next B;          next B;
6907        } elsif ({        } elsif ({
6908                  address => 1, blockquote => 1, center => 1, dir => 1,                  ## NOTE: Start tags for non-phrasing flow content elements
6909                  div => 1, dl => 1, fieldset => 1,  
6910                  h1 => 1, h2 => 1, h3 => 1, h4 => 1, h5 => 1, h6 => 1,                  ## NOTE: The normal one
6911                  menu => 1, ol => 1, p => 1, ul => 1,                  address => 1, article => 1, aside => 1, blockquote => 1,
6912                    center => 1, datagrid => 1, details => 1, dialog => 1,
6913                    dir => 1, div => 1, dl => 1, fieldset => 1, figure => 1,
6914                    footer => 1, h1 => 1, h2 => 1, h3 => 1, h4 => 1, h5 => 1,
6915                    h6 => 1, header => 1, menu => 1, nav => 1, ol => 1, p => 1,
6916                    section => 1, ul => 1,
6917                    ## NOTE: As normal, but drops leading newline
6918                  pre => 1, listing => 1,                  pre => 1, listing => 1,
6919                    ## NOTE: As normal, but interacts with the form element pointer
6920                  form => 1,                  form => 1,
6921                    
6922                  table => 1,                  table => 1,
6923                  hr => 1,                  hr => 1,
6924                 }->{$token->{tag_name}}) {                 }->{$token->{tag_name}}) {
# Line 7001  sub _tree_construction_main ($) { Line 6985  sub _tree_construction_main ($) {
6985            !!!next-token;            !!!next-token;
6986          }          }
6987          next B;          next B;
6988        } elsif ({li => 1, dt => 1, dd => 1}->{$token->{tag_name}}) {        } elsif ($token->{tag_name} eq 'li') {
6989          ## has a p element in scope          ## NOTE: As normal, but imply </li> when there's another <li> ...
6990    
6991            ## NOTE: Special, Scope (<li><foo><li> == <li><foo><li/></foo></li>)
6992              ## Interpreted as <li><foo/></li><li/> (non-conforming)
6993              ## blockquote (O9.27), center (O), dd (Fx3, O, S3.1.2, IE7),
6994              ## dt (Fx, O, S, IE), dl (O), fieldset (O, S, IE), form (Fx, O, S),
6995              ## hn (O), pre (O), applet (O, S), button (O, S), marquee (Fx, O, S),
6996              ## object (Fx)
6997              ## Generate non-tree (non-conforming)
6998              ## basefont (IE7 (where basefont is non-void)), center (IE),
6999              ## form (IE), hn (IE)
7000            ## address, div, p (<li><foo><li> == <li><foo/></li><li/>)
7001              ## Interpreted as <li><foo><li/></foo></li> (non-conforming)
7002              ## div (Fx, S)
7003    
7004            my $non_optional;
7005            my $i = -1;
7006    
7007            ## 1.
7008            for my $node (reverse @{$self->{open_elements}}) {
7009              if ($node->[1] & LI_EL) {
7010                ## 2. (a) As if </li>
7011                {
7012                  ## If no </li> - not applied
7013                  #
7014    
7015                  ## Otherwise
7016    
7017                  ## 1. generate implied end tags, except for </li>
7018                  #
7019    
7020                  ## 2. If current node != "li", parse error
7021                  if ($non_optional) {
7022                    !!!parse-error (type => 'not closed',
7023                                    text => $non_optional->[0]->manakai_local_name,
7024                                    token => $token);
7025                    !!!cp ('t355');
7026                  } else {
7027                    !!!cp ('t356');
7028                  }
7029    
7030                  ## 3. Pop
7031                  splice @{$self->{open_elements}}, $i;
7032                }
7033    
7034                last; ## 2. (b) goto 5.
7035              } elsif (
7036                       ## NOTE: not "formatting" and not "phrasing"
7037                       ($node->[1] & SPECIAL_EL or
7038                        $node->[1] & SCOPING_EL) and
7039                       ## NOTE: "li", "dt", and "dd" are in |SPECIAL_EL|.
7040    
7041                       (not $node->[1] & ADDRESS_EL) &
7042                       (not $node->[1] & DIV_EL) &
7043                       (not $node->[1] & P_EL)) {
7044                ## 3.
7045                !!!cp ('t357');
7046                last; ## goto 5.
7047              } elsif ($node->[1] & END_TAG_OPTIONAL_EL) {
7048                !!!cp ('t358');
7049                #
7050              } else {
7051                !!!cp ('t359');
7052                $non_optional ||= $node;
7053                #
7054              }
7055              ## 4.
7056              ## goto 2.
7057              $i--;
7058            }
7059    
7060            ## 5. (a) has a |p| element in scope
7061          INSCOPE: for (reverse @{$self->{open_elements}}) {          INSCOPE: for (reverse @{$self->{open_elements}}) {
7062            if ($_->[1] & P_EL) {            if ($_->[1] & P_EL) {
7063              !!!cp ('t353');              !!!cp ('t353');
7064    
7065                ## NOTE: |<p><li>|, for example.
7066    
7067              !!!back-token; # <x>              !!!back-token; # <x>
7068              $token = {type => END_TAG_TOKEN, tag_name => 'p',              $token = {type => END_TAG_TOKEN, tag_name => 'p',
7069                        line => $token->{line}, column => $token->{column}};                        line => $token->{line}, column => $token->{column}};
# Line 7015  sub _tree_construction_main ($) { Line 7073  sub _tree_construction_main ($) {
7073              last INSCOPE;              last INSCOPE;
7074            }            }
7075          } # INSCOPE          } # INSCOPE
7076              
7077          ## Step 1          ## 5. (b) insert
7078            !!!insert-element-t ($token->{tag_name}, $token->{attributes}, $token);
7079            !!!nack ('t359.1');
7080            !!!next-token;
7081            next B;
7082          } elsif ($token->{tag_name} eq 'dt' or
7083                   $token->{tag_name} eq 'dd') {
7084            ## NOTE: As normal, but imply </dt> or </dd> when ...
7085    
7086            my $non_optional;
7087          my $i = -1;          my $i = -1;
7088          my $node = $self->{open_elements}->[$i];  
7089          my $li_or_dtdd = {li => {li => 1},          ## 1.
7090                            dt => {dt => 1, dd => 1},          for my $node (reverse @{$self->{open_elements}}) {
7091                            dd => {dt => 1, dd => 1}}->{$token->{tag_name}};            if ($node->[1] & DT_EL or $node->[1] & DD_EL) {
7092          LI: {              ## 2. (a) As if </li>
7093            ## Step 2              {
7094            if ($li_or_dtdd->{$node->[0]->manakai_local_name}) {                ## If no </li> - not applied
7095              if ($i != -1) {                #
7096                !!!cp ('t355');  
7097                !!!parse-error (type => 'not closed',                ## Otherwise
7098                                text => $self->{open_elements}->[-1]->[0]  
7099                                    ->manakai_local_name,                ## 1. generate implied end tags, except for </dt> or </dd>
7100                                token => $token);                #
7101              } else {  
7102                !!!cp ('t356');                ## 2. If current node != "dt"|"dd", parse error
7103                  if ($non_optional) {
7104                    !!!parse-error (type => 'not closed',
7105                                    text => $non_optional->[0]->manakai_local_name,
7106                                    token => $token);
7107                    !!!cp ('t355.1');
7108                  } else {
7109                    !!!cp ('t356.1');
7110                  }
7111    
7112                  ## 3. Pop
7113                  splice @{$self->{open_elements}}, $i;
7114              }              }
7115              splice @{$self->{open_elements}}, $i;  
7116              last LI;              last; ## 2. (b) goto 5.
7117              } elsif (
7118                       ## NOTE: not "formatting" and not "phrasing"
7119                       ($node->[1] & SPECIAL_EL or
7120                        $node->[1] & SCOPING_EL) and
7121                       ## NOTE: "li", "dt", and "dd" are in |SPECIAL_EL|.
7122    
7123                       (not $node->[1] & ADDRESS_EL) &
7124                       (not $node->[1] & DIV_EL) &
7125                       (not $node->[1] & P_EL)) {
7126                ## 3.
7127                !!!cp ('t357.1');
7128                last; ## goto 5.
7129              } elsif ($node->[1] & END_TAG_OPTIONAL_EL) {
7130                !!!cp ('t358.1');
7131                #
7132            } else {            } else {
7133              !!!cp ('t357');              !!!cp ('t359.1');
7134            }              $non_optional ||= $node;
7135                          #
           ## Step 3  
           if (not ($node->[1] & FORMATTING_EL) and  
               #not $phrasing_category->{$node->[1]} and  
               ($node->[1] & SPECIAL_EL or  
                $node->[1] & SCOPING_EL) and  
               not ($node->[1] & ADDRESS_EL) and  
               not ($node->[1] & DIV_EL)) {  
             !!!cp ('t358');  
             last LI;  
7136            }            }
7137                        ## 4.
7138            !!!cp ('t359');            ## goto 2.
           ## Step 4  
7139            $i--;            $i--;
7140            $node = $self->{open_elements}->[$i];          }
7141            redo LI;  
7142          } # LI          ## 5. (a) has a |p| element in scope
7143                      INSCOPE: for (reverse @{$self->{open_elements}}) {
7144              if ($_->[1] & P_EL) {
7145                !!!cp ('t353.1');
7146                !!!back-token; # <x>
7147                $token = {type => END_TAG_TOKEN, tag_name => 'p',
7148                          line => $token->{line}, column => $token->{column}};
7149                next B;
7150              } elsif ($_->[1] & SCOPING_EL) {
7151                !!!cp ('t354.1');
7152                last INSCOPE;
7153              }
7154            } # INSCOPE
7155    
7156            ## 5. (b) insert
7157          !!!insert-element-t ($token->{tag_name}, $token->{attributes}, $token);          !!!insert-element-t ($token->{tag_name}, $token->{attributes}, $token);
7158          !!!nack ('t359.1');          !!!nack ('t359.2');
7159          !!!next-token;          !!!next-token;
7160          next B;          next B;
7161        } elsif ($token->{tag_name} eq 'plaintext') {        } elsif ($token->{tag_name} eq 'plaintext') {
7162            ## NOTE: As normal, but effectively ends parsing
7163    
7164          ## has a p element in scope          ## has a p element in scope
7165          INSCOPE: for (reverse @{$self->{open_elements}}) {          INSCOPE: for (reverse @{$self->{open_elements}}) {
7166            if ($_->[1] & P_EL) {            if ($_->[1] & P_EL) {
# Line 7371  sub _tree_construction_main ($) { Line 7469  sub _tree_construction_main ($) {
7469          !!!nack ('t401.1'); ## NOTE: |<col/>| or |<frame/>| here is an error.          !!!nack ('t401.1'); ## NOTE: |<col/>| or |<frame/>| here is an error.
7470          !!!next-token;          !!!next-token;
7471          next B;          next B;
7472                  } elsif ($token->{tag_name} eq 'param' or
7473          ## ISSUE: An issue on HTML5 new elements in the spec.                 $token->{tag_name} eq 'source') {
7474            !!!insert-element-t ($token->{tag_name}, $token->{attributes}, $token);
7475            pop @{$self->{open_elements}};
7476    
7477            !!!ack ('t398.5');
7478            !!!next-token;
7479            redo B;
7480        } else {        } else {
7481          if ($token->{tag_name} eq 'image') {          if ($token->{tag_name} eq 'image') {
7482            !!!cp ('t384');            !!!cp ('t384');
# Line 7395  sub _tree_construction_main ($) { Line 7499  sub _tree_construction_main ($) {
7499            !!!nack ('t380.1');            !!!nack ('t380.1');
7500          } elsif ({          } elsif ({
7501                    b => 1, big => 1, em => 1, font => 1, i => 1,                    b => 1, big => 1, em => 1, font => 1, i => 1,
7502                    s => 1, small => 1, strile => 1,                    s => 1, small => 1, strike => 1,
7503                    strong => 1, tt => 1, u => 1,                    strong => 1, tt => 1, u => 1,
7504                   }->{$token->{tag_name}}) {                   }->{$token->{tag_name}}) {
7505            !!!cp ('t375');            !!!cp ('t375');
# Line 7408  sub _tree_construction_main ($) { Line 7512  sub _tree_construction_main ($) {
7512            !!!ack ('t388.2');            !!!ack ('t388.2');
7513          } elsif ({          } elsif ({
7514                    area => 1, basefont => 1, bgsound => 1, br => 1,                    area => 1, basefont => 1, bgsound => 1, br => 1,
7515                    embed => 1, img => 1, param => 1, spacer => 1, wbr => 1,                    embed => 1, img => 1, spacer => 1, wbr => 1,
                   #image => 1,  
7516                   }->{$token->{tag_name}}) {                   }->{$token->{tag_name}}) {
7517            !!!cp ('t388.1');            !!!cp ('t388.1');
7518            pop @{$self->{open_elements}};            pop @{$self->{open_elements}};
# Line 7450  sub _tree_construction_main ($) { Line 7553  sub _tree_construction_main ($) {
7553              }              }
7554            }            }
7555    
7556            !!!parse-error (type => 'start tag not allowed',            ## NOTE: |<marquee></body>|, |<svg><foreignobject></body>|
7557    
7558              !!!parse-error (type => 'unmatched end tag',
7559                            text => $token->{tag_name}, token => $token);                            text => $token->{tag_name}, token => $token);
7560            ## NOTE: Ignore the token.            ## NOTE: Ignore the token.
7561            !!!next-token;            !!!next-token;
# Line 7477  sub _tree_construction_main ($) { Line 7582  sub _tree_construction_main ($) {
7582          ## up-to-date, though it has same effect as speced.          ## up-to-date, though it has same effect as speced.
7583          if (@{$self->{open_elements}} > 1 and          if (@{$self->{open_elements}} > 1 and
7584              $self->{open_elements}->[1]->[1] & BODY_EL) {              $self->{open_elements}->[1]->[1] & BODY_EL) {
           ## ISSUE: There is an issue in the spec.  
7585            unless ($self->{open_elements}->[-1]->[1] & BODY_EL) {            unless ($self->{open_elements}->[-1]->[1] & BODY_EL) {
7586              !!!cp ('t406');              !!!cp ('t406');
7587              !!!parse-error (type => 'not closed',              !!!parse-error (type => 'not closed',
# Line 7499  sub _tree_construction_main ($) { Line 7603  sub _tree_construction_main ($) {
7603            next B;            next B;
7604          }          }
7605        } elsif ({        } elsif ({
7606                  address => 1, blockquote => 1, center => 1, dir => 1,                  ## NOTE: End tags for non-phrasing flow content elements
7607                  div => 1, dl => 1, fieldset => 1, listing => 1,  
7608                  menu => 1, ol => 1, pre => 1, ul => 1,                  ## NOTE: The normal ones
7609                    address => 1, article => 1, aside => 1, blockquote => 1,
7610                    center => 1, datagrid => 1, details => 1, dialog => 1,
7611                    dir => 1, div => 1, dl => 1, fieldset => 1, figure => 1,
7612                    footer => 1, header => 1, listing => 1, menu => 1, nav => 1,
7613                    ol => 1, pre => 1, section => 1, ul => 1,
7614    
7615                    ## NOTE: As normal, but ... optional tags
7616                  dd => 1, dt => 1, li => 1,                  dd => 1, dt => 1, li => 1,
7617    
7618                  applet => 1, button => 1, marquee => 1, object => 1,                  applet => 1, button => 1, marquee => 1, object => 1,
7619                 }->{$token->{tag_name}}) {                 }->{$token->{tag_name}}) {
7620            ## NOTE: Code for <li> start tags includes "as if </li>" code.
7621            ## Code for <dt> or <dd> start tags includes "as if </dt> or
7622            ## </dd>" code.
7623    
7624          ## has an element in scope          ## has an element in scope
7625          my $i;          my $i;
7626          INSCOPE: for (reverse 0..$#{$self->{open_elements}}) {          INSCOPE: for (reverse 0..$#{$self->{open_elements}}) {
# Line 7531  sub _tree_construction_main ($) { Line 7647  sub _tree_construction_main ($) {
7647                    dd => ($token->{tag_name} ne 'dd'),                    dd => ($token->{tag_name} ne 'dd'),
7648                    dt => ($token->{tag_name} ne 'dt'),                    dt => ($token->{tag_name} ne 'dt'),
7649                    li => ($token->{tag_name} ne 'li'),                    li => ($token->{tag_name} ne 'li'),
7650                      option => 1,
7651                      optgroup => 1,
7652                    p => 1,                    p => 1,
7653                    rt => 1,                    rt => 1,
7654                    rp => 1,                    rp => 1,
# Line 7563  sub _tree_construction_main ($) { Line 7681  sub _tree_construction_main ($) {
7681          !!!next-token;          !!!next-token;
7682          next B;          next B;
7683        } elsif ($token->{tag_name} eq 'form') {        } elsif ($token->{tag_name} eq 'form') {
7684            ## NOTE: As normal, but interacts with the form element pointer
7685    
7686          undef $self->{form_element};          undef $self->{form_element};
7687    
7688          ## has an element in scope          ## has an element in scope
# Line 7610  sub _tree_construction_main ($) { Line 7730  sub _tree_construction_main ($) {
7730          !!!next-token;          !!!next-token;
7731          next B;          next B;
7732        } elsif ({        } elsif ({
7733                    ## NOTE: As normal, except acts as a closer for any ...
7734                  h1 => 1, h2 => 1, h3 => 1, h4 => 1, h5 => 1, h6 => 1,                  h1 => 1, h2 => 1, h3 => 1, h4 => 1, h5 => 1, h6 => 1,
7735                 }->{$token->{tag_name}}) {                 }->{$token->{tag_name}}) {
7736          ## has an element in scope          ## has an element in scope
# Line 7655  sub _tree_construction_main ($) { Line 7776  sub _tree_construction_main ($) {
7776          !!!next-token;          !!!next-token;
7777          next B;          next B;
7778        } elsif ($token->{tag_name} eq 'p') {        } elsif ($token->{tag_name} eq 'p') {
7779            ## NOTE: As normal, except </p> implies <p> and ...
7780    
7781          ## has an element in scope          ## has an element in scope
7782            my $non_optional;
7783          my $i;          my $i;
7784          INSCOPE: for (reverse 0..$#{$self->{open_elements}}) {          INSCOPE: for (reverse 0..$#{$self->{open_elements}}) {
7785            my $node = $self->{open_elements}->[$_];            my $node = $self->{open_elements}->[$_];
# Line 7666  sub _tree_construction_main ($) { Line 7790  sub _tree_construction_main ($) {
7790            } elsif ($node->[1] & SCOPING_EL) {            } elsif ($node->[1] & SCOPING_EL) {
7791              !!!cp ('t411.1');              !!!cp ('t411.1');
7792              last INSCOPE;              last INSCOPE;
7793              } elsif ($node->[1] & END_TAG_OPTIONAL_EL) {
7794                ## NOTE: |END_TAG_OPTIONAL_EL| includes "p"
7795                !!!cp ('t411.2');
7796                #
7797              } else {
7798                !!!cp ('t411.3');
7799                $non_optional ||= $node;
7800                #
7801            }            }
7802          } # INSCOPE          } # INSCOPE
7803    
7804          if (defined $i) {          if (defined $i) {
7805            if ($self->{open_elements}->[-1]->[0]->manakai_local_name            ## 1. Generate implied end tags
7806                    ne $token->{tag_name}) {            #
7807    
7808              ## 2. If current node != "p", parse error
7809              if ($non_optional) {
7810              !!!cp ('t412.1');              !!!cp ('t412.1');
7811              !!!parse-error (type => 'not closed',              !!!parse-error (type => 'not closed',
7812                              text => $self->{open_elements}->[-1]->[0]                              text => $non_optional->[0]->manakai_local_name,
                                 ->manakai_local_name,  
7813                              token => $token);                              token => $token);
7814            } else {            } else {
7815              !!!cp ('t414.1');              !!!cp ('t414.1');
7816            }            }
7817    
7818              ## 3. Pop
7819            splice @{$self->{open_elements}}, $i;            splice @{$self->{open_elements}}, $i;
7820          } else {          } else {
7821            !!!cp ('t413.1');            !!!cp ('t413.1');
# Line 7700  sub _tree_construction_main ($) { Line 7835  sub _tree_construction_main ($) {
7835        } elsif ({        } elsif ({
7836                  a => 1,                  a => 1,
7837                  b => 1, big => 1, em => 1, font => 1, i => 1,                  b => 1, big => 1, em => 1, font => 1, i => 1,
7838                  nobr => 1, s => 1, small => 1, strile => 1,                  nobr => 1, s => 1, small => 1, strike => 1,
7839                  strong => 1, tt => 1, u => 1,                  strong => 1, tt => 1, u => 1,
7840                 }->{$token->{tag_name}}) {                 }->{$token->{tag_name}}) {
7841          !!!cp ('t427');          !!!cp ('t427');
# Line 7721  sub _tree_construction_main ($) { Line 7856  sub _tree_construction_main ($) {
7856          ## Ignore the token.          ## Ignore the token.
7857          !!!next-token;          !!!next-token;
7858          next B;          next B;
       } elsif ({  
                 caption => 1, col => 1, colgroup => 1, frame => 1,  
                 frameset => 1, head => 1, option => 1, optgroup => 1,  
                 tbody => 1, td => 1, tfoot => 1, th => 1,  
                 thead => 1, tr => 1,  
                 area => 1, basefont => 1, bgsound => 1,  
                 embed => 1, hr => 1, iframe => 1, image => 1,  
                 img => 1, input => 1, isindex => 1, noembed => 1,  
                 noframes => 1, param => 1, select => 1, spacer => 1,  
                 table => 1, textarea => 1, wbr => 1,  
                 noscript => 0, ## TODO: if scripting is enabled  
                }->{$token->{tag_name}}) {  
         !!!cp ('t429');  
         !!!parse-error (type => 'unmatched end tag',  
                         text => $token->{tag_name}, token => $token);  
         ## Ignore the token  
         !!!next-token;  
         next B;  
           
         ## ISSUE: Issue on HTML5 new elements in spec  
           
7859        } else {        } else {
7860            if ($token->{tag_name} eq 'sarcasm') {
7861              sleep 0.001; # take a deep breath
7862            }
7863    
7864          ## Step 1          ## Step 1
7865          my $node_i = -1;          my $node_i = -1;
7866          my $node = $self->{open_elements}->[$node_i];          my $node = $self->{open_elements}->[$node_i];
7867    
7868          ## Step 2          ## Step 2
7869          S2: {          S2: {
7870            if ($node->[0]->manakai_local_name eq $token->{tag_name}) {            my $node_tag_name = $node->[0]->manakai_local_name;
7871              $node_tag_name =~ tr/A-Z/a-z/; # for SVG camelCase tag names
7872              if ($node_tag_name eq $token->{tag_name}) {
7873              ## Step 1              ## Step 1
7874              ## generate implied end tags              ## generate implied end tags
7875              while ($self->{open_elements}->[-1]->[1] & END_TAG_OPTIONAL_EL) {              while ($self->{open_elements}->[-1]->[1] & END_TAG_OPTIONAL_EL) {
# Line 7762  sub _tree_construction_main ($) { Line 7882  sub _tree_construction_main ($) {
7882              }              }
7883                    
7884              ## Step 2              ## Step 2
7885              if ($self->{open_elements}->[-1]->[0]->manakai_local_name              my $current_tag_name
7886                      ne $token->{tag_name}) {                  = $self->{open_elements}->[-1]->[0]->manakai_local_name;
7887                $current_tag_name =~ tr/A-Z/a-z/;
7888                if ($current_tag_name ne $token->{tag_name}) {
7889                !!!cp ('t431');                !!!cp ('t431');
7890                ## NOTE: <x><y></x>                ## NOTE: <x><y></x>
7891                !!!parse-error (type => 'not closed',                !!!parse-error (type => 'not closed',
# Line 7791  sub _tree_construction_main ($) { Line 7913  sub _tree_construction_main ($) {
7913                ## Ignore the token                ## Ignore the token
7914                !!!next-token;                !!!next-token;
7915                last S2;                last S2;
             }  
7916    
7917                  ## NOTE: |<span><dd></span>a|: In Safari 3.1.2 and Opera
7918                  ## 9.27, "a" is a child of <dd> (conforming).  In
7919                  ## Firefox 3.0.2, "a" is a child of <body>.  In WinIE 7,
7920                  ## "a" is a child of both <body> and <dd>.
7921                }
7922                
7923              !!!cp ('t434');              !!!cp ('t434');
7924            }            }
7925                        

Legend:
Removed from v.1.186  
changed lines
  Added in v.1.200

[email protected]
ViewVC Help
Powered by ViewVC 1.1.24