/[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.185 by wakaba, Mon Sep 15 09:27:53 2008 UTC revision 1.199 by wakaba, Sat Oct 4 09:17:54 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 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 4572  sub _tree_construction_main ($) { Line 4528  sub _tree_construction_main ($) {
4528    
4529      if ($self->{insertion_mode} & HEAD_IMS) {      if ($self->{insertion_mode} & HEAD_IMS) {
4530        if ($token->{type} == CHARACTER_TOKEN) {        if ($token->{type} == CHARACTER_TOKEN) {
4531          if ($token->{data} =~ s/^([\x09\x0A\x0B\x0C\x20]+)//) {          if ($token->{data} =~ s/^([\x09\x0A\x0C\x20]+)//) {
4532            unless ($self->{insertion_mode} == BEFORE_HEAD_IM) {            unless ($self->{insertion_mode} == BEFORE_HEAD_IM) {
4533              !!!cp ('t88.2');              !!!cp ('t88.2');
4534              $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 4653  sub _tree_construction_main ($) {
4653                  !!!cp ('t101');                  !!!cp ('t101');
4654                }                }
4655                !!!insert-element ($token->{tag_name}, $token->{attributes}, $token);                !!!insert-element ($token->{tag_name}, $token->{attributes}, $token);
4656                pop @{$self->{open_elements}}; ## ISSUE: This step is missing in the spec.                pop @{$self->{open_elements}};
4657                pop @{$self->{open_elements}} # <head>                pop @{$self->{open_elements}} # <head>
4658                    if $self->{insertion_mode} == AFTER_HEAD_IM;                    if $self->{insertion_mode} == AFTER_HEAD_IM;
4659                !!!nack ('t101.1');                !!!nack ('t101.1');
4660                !!!next-token;                !!!next-token;
4661                next B;                next B;
4662              } elsif ($token->{tag_name} eq 'link') {          } elsif ($token->{tag_name} eq 'link') {
4663                ## NOTE: There is a "as if in head" code clone.            ## NOTE: There is a "as if in head" code clone.
4664                if ($self->{insertion_mode} == AFTER_HEAD_IM) {            if ($self->{insertion_mode} == AFTER_HEAD_IM) {
4665                  !!!cp ('t102');              !!!cp ('t102');
4666                  !!!parse-error (type => 'after head',              !!!parse-error (type => 'after head',
4667                                  text => $token->{tag_name}, token => $token);                              text => $token->{tag_name}, token => $token);
4668                  push @{$self->{open_elements}},              push @{$self->{open_elements}},
4669                      [$self->{head_element}, $el_category->{head}];                  [$self->{head_element}, $el_category->{head}];
4670                } else {            } else {
4671                  !!!cp ('t103');              !!!cp ('t103');
4672                }            }
4673                !!!insert-element ($token->{tag_name}, $token->{attributes}, $token);            !!!insert-element ($token->{tag_name}, $token->{attributes}, $token);
4674                pop @{$self->{open_elements}}; ## ISSUE: This step is missing in the spec.            pop @{$self->{open_elements}};
4675                pop @{$self->{open_elements}} # <head>            pop @{$self->{open_elements}} # <head>
4676                    if $self->{insertion_mode} == AFTER_HEAD_IM;                if $self->{insertion_mode} == AFTER_HEAD_IM;
4677                !!!ack ('t103.1');            !!!ack ('t103.1');
4678                !!!next-token;            !!!next-token;
4679                next B;            next B;
4680            } elsif ($token->{tag_name} eq 'command' or
4681                     $token->{tag_name} eq 'eventsource') {
4682              if ($self->{insertion_mode} == IN_HEAD_IM) {
4683                ## NOTE: If the insertion mode at the time of the emission
4684                ## of the token was "before head", $self->{insertion_mode}
4685                ## is already changed to |IN_HEAD_IM|.
4686    
4687                ## NOTE: There is a "as if in head" code clone.
4688                !!!insert-element ($token->{tag_name}, $token->{attributes}, $token);
4689                pop @{$self->{open_elements}};
4690                pop @{$self->{open_elements}} # <head>
4691                    if $self->{insertion_mode} == AFTER_HEAD_IM;
4692                !!!ack ('t103.2');
4693                !!!next-token;
4694                next B;
4695              } else {
4696                ## NOTE: "in head noscript" or "after head" insertion mode
4697                ## - in these cases, these tags are treated as same as
4698                ## normal in-body tags.
4699                !!!cp ('t103.3');
4700                #
4701              }
4702              } elsif ($token->{tag_name} eq 'meta') {              } elsif ($token->{tag_name} eq 'meta') {
4703                ## NOTE: There is a "as if in head" code clone.                ## NOTE: There is a "as if in head" code clone.
4704                if ($self->{insertion_mode} == AFTER_HEAD_IM) {                if ($self->{insertion_mode} == AFTER_HEAD_IM) {
# Line 4733  sub _tree_construction_main ($) { Line 4711  sub _tree_construction_main ($) {
4711                  !!!cp ('t105');                  !!!cp ('t105');
4712                }                }
4713                !!!insert-element ($token->{tag_name}, $token->{attributes}, $token);                !!!insert-element ($token->{tag_name}, $token->{attributes}, $token);
4714                my $meta_el = pop @{$self->{open_elements}}; ## ISSUE: This step is missing in the spec.                my $meta_el = pop @{$self->{open_elements}};
4715    
4716                unless ($self->{confident}) {                unless ($self->{confident}) {
4717                  if ($token->{attributes}->{charset}) {                  if ($token->{attributes}->{charset}) {
# Line 4751  sub _tree_construction_main ($) { Line 4729  sub _tree_construction_main ($) {
4729                  } elsif ($token->{attributes}->{content}) {                  } elsif ($token->{attributes}->{content}) {
4730                    if ($token->{attributes}->{content}->{value}                    if ($token->{attributes}->{content}->{value}
4731                        =~ /[Cc][Hh][Aa][Rr][Ss][Ee][Tt]                        =~ /[Cc][Hh][Aa][Rr][Ss][Ee][Tt]
4732                            [\x09-\x0D\x20]*=                            [\x09\x0A\x0C\x0D\x20]*=
4733                            [\x09-\x0D\x20]*(?>"([^"]*)"|'([^']*)'|                            [\x09\x0A\x0C\x0D\x20]*(?>"([^"]*)"|'([^']*)'|
4734                            ([^"'\x09-\x0D\x20][^\x09-\x0D\x20\x3B]*))/x) {                            ([^"'\x09\x0A\x0C\x0D\x20]
4735                               [^\x09\x0A\x0C\x0D\x20\x3B]*))/x) {
4736                      !!!cp ('t107');                      !!!cp ('t107');
4737                      ## NOTE: Whether the encoding is supported or not is handled                      ## NOTE: Whether the encoding is supported or not is handled
4738                      ## in the {change_encoding} callback.                      ## in the {change_encoding} callback.
# Line 5189  sub _tree_construction_main ($) { Line 5168  sub _tree_construction_main ($) {
5168        } else {        } else {
5169          die "$0: $token->{type}: Unknown token type";          die "$0: $token->{type}: Unknown token type";
5170        }        }
   
           ## ISSUE: An issue in the spec.  
5171      } elsif ($self->{insertion_mode} & BODY_IMS) {      } elsif ($self->{insertion_mode} & BODY_IMS) {
5172            if ($token->{type} == CHARACTER_TOKEN) {            if ($token->{type} == CHARACTER_TOKEN) {
5173              !!!cp ('t150');              !!!cp ('t150');
# Line 5562  sub _tree_construction_main ($) { Line 5539  sub _tree_construction_main ($) {
5539      } elsif ($self->{insertion_mode} & TABLE_IMS) {      } elsif ($self->{insertion_mode} & TABLE_IMS) {
5540        if ($token->{type} == CHARACTER_TOKEN) {        if ($token->{type} == CHARACTER_TOKEN) {
5541          if (not $open_tables->[-1]->[1] and # tainted          if (not $open_tables->[-1]->[1] and # tainted
5542              $token->{data} =~ s/^([\x09\x0A\x0B\x0C\x20]+)//) {              $token->{data} =~ s/^([\x09\x0A\x0C\x20]+)//) {
5543            $self->{open_elements}->[-1]->[0]->manakai_append_text ($1);            $self->{open_elements}->[-1]->[0]->manakai_append_text ($1);
5544                                
5545            unless (length $token->{data}) {            unless (length $token->{data}) {
# Line 6246  sub _tree_construction_main ($) { Line 6223  sub _tree_construction_main ($) {
6223        }        }
6224      } elsif ($self->{insertion_mode} == IN_COLUMN_GROUP_IM) {      } elsif ($self->{insertion_mode} == IN_COLUMN_GROUP_IM) {
6225            if ($token->{type} == CHARACTER_TOKEN) {            if ($token->{type} == CHARACTER_TOKEN) {
6226              if ($token->{data} =~ s/^([\x09\x0A\x0B\x0C\x20]+)//) {              if ($token->{data} =~ s/^([\x09\x0A\x0C\x20]+)//) {
6227                $self->{open_elements}->[-1]->[0]->manakai_append_text ($1);                $self->{open_elements}->[-1]->[0]->manakai_append_text ($1);
6228                unless (length $token->{data}) {                unless (length $token->{data}) {
6229                  !!!cp ('t260');                  !!!cp ('t260');
# Line 6587  sub _tree_construction_main ($) { Line 6564  sub _tree_construction_main ($) {
6564        }        }
6565      } elsif ($self->{insertion_mode} & BODY_AFTER_IMS) {      } elsif ($self->{insertion_mode} & BODY_AFTER_IMS) {
6566        if ($token->{type} == CHARACTER_TOKEN) {        if ($token->{type} == CHARACTER_TOKEN) {
6567          if ($token->{data} =~ s/^([\x09\x0A\x0B\x0C\x20]+)//) {          if ($token->{data} =~ s/^([\x09\x0A\x0C\x20]+)//) {
6568            my $data = $1;            my $data = $1;
6569            ## As if in body            ## As if in body
6570            $reconstruct_active_formatting_elements->($insert_to_current);            $reconstruct_active_formatting_elements->($insert_to_current);
# Line 6604  sub _tree_construction_main ($) { Line 6581  sub _tree_construction_main ($) {
6581          if ($self->{insertion_mode} == AFTER_HTML_BODY_IM) {          if ($self->{insertion_mode} == AFTER_HTML_BODY_IM) {
6582            !!!cp ('t301');            !!!cp ('t301');
6583            !!!parse-error (type => 'after html:#text', token => $token);            !!!parse-error (type => 'after html:#text', token => $token);
6584              #
           ## Reprocess in the "after body" insertion mode.  
6585          } else {          } else {
6586            !!!cp ('t302');            !!!cp ('t302');
6587              ## "after body" insertion mode
6588              !!!parse-error (type => 'after body:#text', token => $token);
6589              #
6590          }          }
           
         ## "after body" insertion mode  
         !!!parse-error (type => 'after body:#text', token => $token);  
6591    
6592          $self->{insertion_mode} = IN_BODY_IM;          $self->{insertion_mode} = IN_BODY_IM;
6593          ## reprocess          ## reprocess
# Line 6621  sub _tree_construction_main ($) { Line 6597  sub _tree_construction_main ($) {
6597            !!!cp ('t303');            !!!cp ('t303');
6598            !!!parse-error (type => 'after html',            !!!parse-error (type => 'after html',
6599                            text => $token->{tag_name}, token => $token);                            text => $token->{tag_name}, token => $token);
6600                        #
           ## Reprocess in the "after body" insertion mode.  
6601          } else {          } else {
6602            !!!cp ('t304');            !!!cp ('t304');
6603              ## "after body" insertion mode
6604              !!!parse-error (type => 'after body',
6605                              text => $token->{tag_name}, token => $token);
6606              #
6607          }          }
6608    
         ## "after body" insertion mode  
         !!!parse-error (type => 'after body',  
                         text => $token->{tag_name}, token => $token);  
   
6609          $self->{insertion_mode} = IN_BODY_IM;          $self->{insertion_mode} = IN_BODY_IM;
6610          !!!ack-later;          !!!ack-later;
6611          ## reprocess          ## reprocess
# Line 6641  sub _tree_construction_main ($) { Line 6616  sub _tree_construction_main ($) {
6616            !!!parse-error (type => 'after html:/',            !!!parse-error (type => 'after html:/',
6617                            text => $token->{tag_name}, token => $token);                            text => $token->{tag_name}, token => $token);
6618                        
6619            $self->{insertion_mode} = AFTER_BODY_IM;            $self->{insertion_mode} = IN_BODY_IM;
6620            ## Reprocess in the "after body" insertion mode.            ## Reprocess.
6621              next B;
6622          } else {          } else {
6623            !!!cp ('t306');            !!!cp ('t306');
6624          }          }
# Line 6680  sub _tree_construction_main ($) { Line 6656  sub _tree_construction_main ($) {
6656        }        }
6657      } elsif ($self->{insertion_mode} & FRAME_IMS) {      } elsif ($self->{insertion_mode} & FRAME_IMS) {
6658        if ($token->{type} == CHARACTER_TOKEN) {        if ($token->{type} == CHARACTER_TOKEN) {
6659          if ($token->{data} =~ s/^([\x09\x0A\x0B\x0C\x20]+)//) {          if ($token->{data} =~ s/^([\x09\x0A\x0C\x20]+)//) {
6660            $self->{open_elements}->[-1]->[0]->manakai_append_text ($1);            $self->{open_elements}->[-1]->[0]->manakai_append_text ($1);
6661                        
6662            unless (length $token->{data}) {            unless (length $token->{data}) {
# Line 6690  sub _tree_construction_main ($) { Line 6666  sub _tree_construction_main ($) {
6666            }            }
6667          }          }
6668                    
6669          if ($token->{data} =~ s/^[^\x09\x0A\x0B\x0C\x20]+//) {          if ($token->{data} =~ s/^[^\x09\x0A\x0C\x20]+//) {
6670            if ($self->{insertion_mode} == IN_FRAMESET_IM) {            if ($self->{insertion_mode} == IN_FRAMESET_IM) {
6671              !!!cp ('t311');              !!!cp ('t311');
6672              !!!parse-error (type => 'in frameset:#text', token => $token);              !!!parse-error (type => 'in frameset:#text', token => $token);
# Line 6819  sub _tree_construction_main ($) { Line 6795  sub _tree_construction_main ($) {
6795        } else {        } else {
6796          die "$0: $token->{type}: Unknown token type";          die "$0: $token->{type}: Unknown token type";
6797        }        }
   
       ## ISSUE: An issue in spec here  
6798      } else {      } else {
6799        die "$0: $self->{insertion_mode}: Unknown insertion mode";        die "$0: $self->{insertion_mode}: Unknown insertion mode";
6800      }      }
# Line 6838  sub _tree_construction_main ($) { Line 6812  sub _tree_construction_main ($) {
6812          $parse_rcdata->(CDATA_CONTENT_MODEL);          $parse_rcdata->(CDATA_CONTENT_MODEL);
6813          next B;          next B;
6814        } elsif ({        } elsif ({
6815                  base => 1, link => 1,                  base => 1, command => 1, eventsource => 1, link => 1,
6816                 }->{$token->{tag_name}}) {                 }->{$token->{tag_name}}) {
6817          !!!cp ('t334');          !!!cp ('t334');
6818          ## 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
6819          !!!insert-element-t ($token->{tag_name}, $token->{attributes}, $token);          !!!insert-element-t ($token->{tag_name}, $token->{attributes}, $token);
6820          pop @{$self->{open_elements}}; ## ISSUE: This step is missing in the spec.          pop @{$self->{open_elements}};
6821          !!!ack ('t334.1');          !!!ack ('t334.1');
6822          !!!next-token;          !!!next-token;
6823          next B;          next B;
6824        } elsif ($token->{tag_name} eq 'meta') {        } elsif ($token->{tag_name} eq 'meta') {
6825          ## 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
6826          !!!insert-element-t ($token->{tag_name}, $token->{attributes}, $token);          !!!insert-element-t ($token->{tag_name}, $token->{attributes}, $token);
6827          my $meta_el = pop @{$self->{open_elements}}; ## ISSUE: This step is missing in the spec.          my $meta_el = pop @{$self->{open_elements}};
6828    
6829          unless ($self->{confident}) {          unless ($self->{confident}) {
6830            if ($token->{attributes}->{charset}) {            if ($token->{attributes}->{charset}) {
# Line 6867  sub _tree_construction_main ($) { Line 6841  sub _tree_construction_main ($) {
6841            } elsif ($token->{attributes}->{content}) {            } elsif ($token->{attributes}->{content}) {
6842              if ($token->{attributes}->{content}->{value}              if ($token->{attributes}->{content}->{value}
6843                  =~ /[Cc][Hh][Aa][Rr][Ss][Ee][Tt]                  =~ /[Cc][Hh][Aa][Rr][Ss][Ee][Tt]
6844                      [\x09-\x0D\x20]*=                      [\x09\x0A\x0C\x0D\x20]*=
6845                      [\x09-\x0D\x20]*(?>"([^"]*)"|'([^']*)'|                      [\x09\x0A\x0C\x0D\x20]*(?>"([^"]*)"|'([^']*)'|
6846                      ([^"'\x09-\x0D\x20][^\x09-\x0D\x20\x3B]*))/x) {                      ([^"'\x09\x0A\x0C\x0D\x20][^\x09\x0A\x0C\x0D\x20\x3B]*))
6847                       /x) {
6848                !!!cp ('t336');                !!!cp ('t336');
6849                ## NOTE: Whether the encoding is supported or not is handled                ## NOTE: Whether the encoding is supported or not is handled
6850                ## in the {change_encoding} callback.                ## in the {change_encoding} callback.
# Line 6928  sub _tree_construction_main ($) { Line 6903  sub _tree_construction_main ($) {
6903          !!!next-token;          !!!next-token;
6904          next B;          next B;
6905        } elsif ({        } elsif ({
6906                  address => 1, blockquote => 1, center => 1, dir => 1,                  ## NOTE: Start tags for non-phrasing flow content elements
6907                  div => 1, dl => 1, fieldset => 1,  
6908                  h1 => 1, h2 => 1, h3 => 1, h4 => 1, h5 => 1, h6 => 1,                  ## NOTE: The normal one
6909                  menu => 1, ol => 1, p => 1, ul => 1,                  address => 1, article => 1, aside => 1, blockquote => 1,
6910                    center => 1, datagrid => 1, details => 1, dialog => 1,
6911                    dir => 1, div => 1, dl => 1, fieldset => 1, figure => 1,
6912                    footer => 1, h1 => 1, h2 => 1, h3 => 1, h4 => 1, h5 => 1,
6913                    h6 => 1, header => 1, menu => 1, nav => 1, ol => 1, p => 1,
6914                    section => 1, ul => 1,
6915                    ## NOTE: As normal, but drops leading newline
6916                  pre => 1, listing => 1,                  pre => 1, listing => 1,
6917                    ## NOTE: As normal, but interacts with the form element pointer
6918                  form => 1,                  form => 1,
6919                    
6920                  table => 1,                  table => 1,
6921                  hr => 1,                  hr => 1,
6922                 }->{$token->{tag_name}}) {                 }->{$token->{tag_name}}) {
# Line 7000  sub _tree_construction_main ($) { Line 6983  sub _tree_construction_main ($) {
6983            !!!next-token;            !!!next-token;
6984          }          }
6985          next B;          next B;
6986        } elsif ({li => 1, dt => 1, dd => 1}->{$token->{tag_name}}) {        } elsif ($token->{tag_name} eq 'li') {
6987          ## has a p element in scope          ## NOTE: As normal, but imply </li> when there's another <li> ...
6988    
6989            ## NOTE: Special, Scope (<li><foo><li> == <li><foo><li/></foo></li>)
6990              ## Interpreted as <li><foo/></li><li/> (non-conforming)
6991              ## blockquote (O9.27), center (O), dd (Fx3, O, S3.1.2, IE7),
6992              ## dt (Fx, O, S, IE), dl (O), fieldset (O, S, IE), form (Fx, O, S),
6993              ## hn (O), pre (O), applet (O, S), button (O, S), marquee (Fx, O, S),
6994              ## object (Fx)
6995              ## Generate non-tree (non-conforming)
6996              ## basefont (IE7 (where basefont is non-void)), center (IE),
6997              ## form (IE), hn (IE)
6998            ## address, div, p (<li><foo><li> == <li><foo/></li><li/>)
6999              ## Interpreted as <li><foo><li/></foo></li> (non-conforming)
7000              ## div (Fx, S)
7001    
7002            my $non_optional;
7003            my $i = -1;
7004    
7005            ## 1.
7006            for my $node (reverse @{$self->{open_elements}}) {
7007              if ($node->[1] & LI_EL) {
7008                ## 2. (a) As if </li>
7009                {
7010                  ## If no </li> - not applied
7011                  #
7012    
7013                  ## Otherwise
7014    
7015                  ## 1. generate implied end tags, except for </li>
7016                  #
7017    
7018                  ## 2. If current node != "li", parse error
7019                  if ($non_optional) {
7020                    !!!parse-error (type => 'not closed',
7021                                    text => $non_optional->[0]->manakai_local_name,
7022                                    token => $token);
7023                    !!!cp ('t355');
7024                  } else {
7025                    !!!cp ('t356');
7026                  }
7027    
7028                  ## 3. Pop
7029                  splice @{$self->{open_elements}}, $i;
7030                }
7031    
7032                last; ## 2. (b) goto 5.
7033              } elsif (
7034                       ## NOTE: not "formatting" and not "phrasing"
7035                       ($node->[1] & SPECIAL_EL or
7036                        $node->[1] & SCOPING_EL) and
7037                       ## NOTE: "li", "dt", and "dd" are in |SPECIAL_EL|.
7038    
7039                       (not $node->[1] & ADDRESS_EL) &
7040                       (not $node->[1] & DIV_EL) &
7041                       (not $node->[1] & P_EL)) {
7042                ## 3.
7043                !!!cp ('t357');
7044                last; ## goto 5.
7045              } elsif ($node->[1] & END_TAG_OPTIONAL_EL) {
7046                !!!cp ('t358');
7047                #
7048              } else {
7049                !!!cp ('t359');
7050                $non_optional ||= $node;
7051                #
7052              }
7053              ## 4.
7054              ## goto 2.
7055              $i--;
7056            }
7057    
7058            ## 5. (a) has a |p| element in scope
7059          INSCOPE: for (reverse @{$self->{open_elements}}) {          INSCOPE: for (reverse @{$self->{open_elements}}) {
7060            if ($_->[1] & P_EL) {            if ($_->[1] & P_EL) {
7061              !!!cp ('t353');              !!!cp ('t353');
7062    
7063                ## NOTE: |<p><li>|, for example.
7064    
7065              !!!back-token; # <x>              !!!back-token; # <x>
7066              $token = {type => END_TAG_TOKEN, tag_name => 'p',              $token = {type => END_TAG_TOKEN, tag_name => 'p',
7067                        line => $token->{line}, column => $token->{column}};                        line => $token->{line}, column => $token->{column}};
# Line 7014  sub _tree_construction_main ($) { Line 7071  sub _tree_construction_main ($) {
7071              last INSCOPE;              last INSCOPE;
7072            }            }
7073          } # INSCOPE          } # INSCOPE
7074              
7075          ## Step 1          ## 5. (b) insert
7076            !!!insert-element-t ($token->{tag_name}, $token->{attributes}, $token);
7077            !!!nack ('t359.1');
7078            !!!next-token;
7079            next B;
7080          } elsif ($token->{tag_name} eq 'dt' or
7081                   $token->{tag_name} eq 'dd') {
7082            ## NOTE: As normal, but imply </dt> or </dd> when ...
7083    
7084            my $non_optional;
7085          my $i = -1;          my $i = -1;
7086          my $node = $self->{open_elements}->[$i];  
7087          my $li_or_dtdd = {li => {li => 1},          ## 1.
7088                            dt => {dt => 1, dd => 1},          for my $node (reverse @{$self->{open_elements}}) {
7089                            dd => {dt => 1, dd => 1}}->{$token->{tag_name}};            if ($node->[1] & DT_EL or $node->[1] & DD_EL) {
7090          LI: {              ## 2. (a) As if </li>
7091            ## Step 2              {
7092            if ($li_or_dtdd->{$node->[0]->manakai_local_name}) {                ## If no </li> - not applied
7093              if ($i != -1) {                #
7094                !!!cp ('t355');  
7095                !!!parse-error (type => 'not closed',                ## Otherwise
7096                                text => $self->{open_elements}->[-1]->[0]  
7097                                    ->manakai_local_name,                ## 1. generate implied end tags, except for </dt> or </dd>
7098                                token => $token);                #
7099              } else {  
7100                !!!cp ('t356');                ## 2. If current node != "dt"|"dd", parse error
7101                  if ($non_optional) {
7102                    !!!parse-error (type => 'not closed',
7103                                    text => $non_optional->[0]->manakai_local_name,
7104                                    token => $token);
7105                    !!!cp ('t355.1');
7106                  } else {
7107                    !!!cp ('t356.1');
7108                  }
7109    
7110                  ## 3. Pop
7111                  splice @{$self->{open_elements}}, $i;
7112              }              }
7113              splice @{$self->{open_elements}}, $i;  
7114              last LI;              last; ## 2. (b) goto 5.
7115              } elsif (
7116                       ## NOTE: not "formatting" and not "phrasing"
7117                       ($node->[1] & SPECIAL_EL or
7118                        $node->[1] & SCOPING_EL) and
7119                       ## NOTE: "li", "dt", and "dd" are in |SPECIAL_EL|.
7120    
7121                       (not $node->[1] & ADDRESS_EL) &
7122                       (not $node->[1] & DIV_EL) &
7123                       (not $node->[1] & P_EL)) {
7124                ## 3.
7125                !!!cp ('t357.1');
7126                last; ## goto 5.
7127              } elsif ($node->[1] & END_TAG_OPTIONAL_EL) {
7128                !!!cp ('t358.1');
7129                #
7130            } else {            } else {
7131              !!!cp ('t357');              !!!cp ('t359.1');
7132            }              $non_optional ||= $node;
7133                          #
           ## 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;  
7134            }            }
7135                        ## 4.
7136            !!!cp ('t359');            ## goto 2.
           ## Step 4  
7137            $i--;            $i--;
7138            $node = $self->{open_elements}->[$i];          }
7139            redo LI;  
7140          } # LI          ## 5. (a) has a |p| element in scope
7141                      INSCOPE: for (reverse @{$self->{open_elements}}) {
7142              if ($_->[1] & P_EL) {
7143                !!!cp ('t353.1');
7144                !!!back-token; # <x>
7145                $token = {type => END_TAG_TOKEN, tag_name => 'p',
7146                          line => $token->{line}, column => $token->{column}};
7147                next B;
7148              } elsif ($_->[1] & SCOPING_EL) {
7149                !!!cp ('t354.1');
7150                last INSCOPE;
7151              }
7152            } # INSCOPE
7153    
7154            ## 5. (b) insert
7155          !!!insert-element-t ($token->{tag_name}, $token->{attributes}, $token);          !!!insert-element-t ($token->{tag_name}, $token->{attributes}, $token);
7156          !!!nack ('t359.1');          !!!nack ('t359.2');
7157          !!!next-token;          !!!next-token;
7158          next B;          next B;
7159        } elsif ($token->{tag_name} eq 'plaintext') {        } elsif ($token->{tag_name} eq 'plaintext') {
7160            ## NOTE: As normal, but effectively ends parsing
7161    
7162          ## has a p element in scope          ## has a p element in scope
7163          INSCOPE: for (reverse @{$self->{open_elements}}) {          INSCOPE: for (reverse @{$self->{open_elements}}) {
7164            if ($_->[1] & P_EL) {            if ($_->[1] & P_EL) {
# Line 7370  sub _tree_construction_main ($) { Line 7467  sub _tree_construction_main ($) {
7467          !!!nack ('t401.1'); ## NOTE: |<col/>| or |<frame/>| here is an error.          !!!nack ('t401.1'); ## NOTE: |<col/>| or |<frame/>| here is an error.
7468          !!!next-token;          !!!next-token;
7469          next B;          next B;
7470                  } elsif ($token->{tag_name} eq 'param' or
7471          ## ISSUE: An issue on HTML5 new elements in the spec.                 $token->{tag_name} eq 'source') {
7472            !!!insert-element-t ($token->{tag_name}, $token->{attributes}, $token);
7473            pop @{$self->{open_elements}};
7474    
7475            !!!ack ('t398.5');
7476            !!!next-token;
7477            redo B;
7478        } else {        } else {
7479          if ($token->{tag_name} eq 'image') {          if ($token->{tag_name} eq 'image') {
7480            !!!cp ('t384');            !!!cp ('t384');
# Line 7394  sub _tree_construction_main ($) { Line 7497  sub _tree_construction_main ($) {
7497            !!!nack ('t380.1');            !!!nack ('t380.1');
7498          } elsif ({          } elsif ({
7499                    b => 1, big => 1, em => 1, font => 1, i => 1,                    b => 1, big => 1, em => 1, font => 1, i => 1,
7500                    s => 1, small => 1, strile => 1,                    s => 1, small => 1, strike => 1,
7501                    strong => 1, tt => 1, u => 1,                    strong => 1, tt => 1, u => 1,
7502                   }->{$token->{tag_name}}) {                   }->{$token->{tag_name}}) {
7503            !!!cp ('t375');            !!!cp ('t375');
# Line 7407  sub _tree_construction_main ($) { Line 7510  sub _tree_construction_main ($) {
7510            !!!ack ('t388.2');            !!!ack ('t388.2');
7511          } elsif ({          } elsif ({
7512                    area => 1, basefont => 1, bgsound => 1, br => 1,                    area => 1, basefont => 1, bgsound => 1, br => 1,
7513                    embed => 1, img => 1, param => 1, spacer => 1, wbr => 1,                    embed => 1, img => 1, spacer => 1, wbr => 1,
                   #image => 1,  
7514                   }->{$token->{tag_name}}) {                   }->{$token->{tag_name}}) {
7515            !!!cp ('t388.1');            !!!cp ('t388.1');
7516            pop @{$self->{open_elements}};            pop @{$self->{open_elements}};
# Line 7476  sub _tree_construction_main ($) { Line 7578  sub _tree_construction_main ($) {
7578          ## up-to-date, though it has same effect as speced.          ## up-to-date, though it has same effect as speced.
7579          if (@{$self->{open_elements}} > 1 and          if (@{$self->{open_elements}} > 1 and
7580              $self->{open_elements}->[1]->[1] & BODY_EL) {              $self->{open_elements}->[1]->[1] & BODY_EL) {
           ## ISSUE: There is an issue in the spec.  
7581            unless ($self->{open_elements}->[-1]->[1] & BODY_EL) {            unless ($self->{open_elements}->[-1]->[1] & BODY_EL) {
7582              !!!cp ('t406');              !!!cp ('t406');
7583              !!!parse-error (type => 'not closed',              !!!parse-error (type => 'not closed',
# Line 7498  sub _tree_construction_main ($) { Line 7599  sub _tree_construction_main ($) {
7599            next B;            next B;
7600          }          }
7601        } elsif ({        } elsif ({
7602                  address => 1, blockquote => 1, center => 1, dir => 1,                  ## NOTE: End tags for non-phrasing flow content elements
7603                  div => 1, dl => 1, fieldset => 1, listing => 1,  
7604                  menu => 1, ol => 1, pre => 1, ul => 1,                  ## NOTE: The normal ones
7605                    address => 1, article => 1, aside => 1, blockquote => 1,
7606                    center => 1, datagrid => 1, details => 1, dialog => 1,
7607                    dir => 1, div => 1, dl => 1, fieldset => 1, figure => 1,
7608                    footer => 1, header => 1, listing => 1, menu => 1, nav => 1,
7609                    ol => 1, pre => 1, section => 1, ul => 1,
7610    
7611                    ## NOTE: As normal, but ... optional tags
7612                  dd => 1, dt => 1, li => 1,                  dd => 1, dt => 1, li => 1,
7613    
7614                  applet => 1, button => 1, marquee => 1, object => 1,                  applet => 1, button => 1, marquee => 1, object => 1,
7615                 }->{$token->{tag_name}}) {                 }->{$token->{tag_name}}) {
7616            ## NOTE: Code for <li> start tags includes "as if </li>" code.
7617            ## Code for <dt> or <dd> start tags includes "as if </dt> or
7618            ## </dd>" code.
7619    
7620          ## has an element in scope          ## has an element in scope
7621          my $i;          my $i;
7622          INSCOPE: for (reverse 0..$#{$self->{open_elements}}) {          INSCOPE: for (reverse 0..$#{$self->{open_elements}}) {
# Line 7530  sub _tree_construction_main ($) { Line 7643  sub _tree_construction_main ($) {
7643                    dd => ($token->{tag_name} ne 'dd'),                    dd => ($token->{tag_name} ne 'dd'),
7644                    dt => ($token->{tag_name} ne 'dt'),                    dt => ($token->{tag_name} ne 'dt'),
7645                    li => ($token->{tag_name} ne 'li'),                    li => ($token->{tag_name} ne 'li'),
7646                      option => 1,
7647                      optgroup => 1,
7648                    p => 1,                    p => 1,
7649                    rt => 1,                    rt => 1,
7650                    rp => 1,                    rp => 1,
# Line 7562  sub _tree_construction_main ($) { Line 7677  sub _tree_construction_main ($) {
7677          !!!next-token;          !!!next-token;
7678          next B;          next B;
7679        } elsif ($token->{tag_name} eq 'form') {        } elsif ($token->{tag_name} eq 'form') {
7680            ## NOTE: As normal, but interacts with the form element pointer
7681    
7682          undef $self->{form_element};          undef $self->{form_element};
7683    
7684          ## has an element in scope          ## has an element in scope
# Line 7609  sub _tree_construction_main ($) { Line 7726  sub _tree_construction_main ($) {
7726          !!!next-token;          !!!next-token;
7727          next B;          next B;
7728        } elsif ({        } elsif ({
7729                    ## NOTE: As normal, except acts as a closer for any ...
7730                  h1 => 1, h2 => 1, h3 => 1, h4 => 1, h5 => 1, h6 => 1,                  h1 => 1, h2 => 1, h3 => 1, h4 => 1, h5 => 1, h6 => 1,
7731                 }->{$token->{tag_name}}) {                 }->{$token->{tag_name}}) {
7732          ## has an element in scope          ## has an element in scope
# Line 7654  sub _tree_construction_main ($) { Line 7772  sub _tree_construction_main ($) {
7772          !!!next-token;          !!!next-token;
7773          next B;          next B;
7774        } elsif ($token->{tag_name} eq 'p') {        } elsif ($token->{tag_name} eq 'p') {
7775            ## NOTE: As normal, except </p> implies <p> and ...
7776    
7777          ## has an element in scope          ## has an element in scope
7778            my $non_optional;
7779          my $i;          my $i;
7780          INSCOPE: for (reverse 0..$#{$self->{open_elements}}) {          INSCOPE: for (reverse 0..$#{$self->{open_elements}}) {
7781            my $node = $self->{open_elements}->[$_];            my $node = $self->{open_elements}->[$_];
# Line 7665  sub _tree_construction_main ($) { Line 7786  sub _tree_construction_main ($) {
7786            } elsif ($node->[1] & SCOPING_EL) {            } elsif ($node->[1] & SCOPING_EL) {
7787              !!!cp ('t411.1');              !!!cp ('t411.1');
7788              last INSCOPE;              last INSCOPE;
7789              } elsif ($node->[1] & END_TAG_OPTIONAL_EL) {
7790                ## NOTE: |END_TAG_OPTIONAL_EL| includes "p"
7791                !!!cp ('t411.2');
7792                #
7793              } else {
7794                !!!cp ('t411.3');
7795                $non_optional ||= $node;
7796                #
7797            }            }
7798          } # INSCOPE          } # INSCOPE
7799    
7800          if (defined $i) {          if (defined $i) {
7801            if ($self->{open_elements}->[-1]->[0]->manakai_local_name            ## 1. Generate implied end tags
7802                    ne $token->{tag_name}) {            #
7803    
7804              ## 2. If current node != "p", parse error
7805              if ($non_optional) {
7806              !!!cp ('t412.1');              !!!cp ('t412.1');
7807              !!!parse-error (type => 'not closed',              !!!parse-error (type => 'not closed',
7808                              text => $self->{open_elements}->[-1]->[0]                              text => $non_optional->[0]->manakai_local_name,
                                 ->manakai_local_name,  
7809                              token => $token);                              token => $token);
7810            } else {            } else {
7811              !!!cp ('t414.1');              !!!cp ('t414.1');
7812            }            }
7813    
7814              ## 3. Pop
7815            splice @{$self->{open_elements}}, $i;            splice @{$self->{open_elements}}, $i;
7816          } else {          } else {
7817            !!!cp ('t413.1');            !!!cp ('t413.1');
# Line 7699  sub _tree_construction_main ($) { Line 7831  sub _tree_construction_main ($) {
7831        } elsif ({        } elsif ({
7832                  a => 1,                  a => 1,
7833                  b => 1, big => 1, em => 1, font => 1, i => 1,                  b => 1, big => 1, em => 1, font => 1, i => 1,
7834                  nobr => 1, s => 1, small => 1, strile => 1,                  nobr => 1, s => 1, small => 1, strike => 1,
7835                  strong => 1, tt => 1, u => 1,                  strong => 1, tt => 1, u => 1,
7836                 }->{$token->{tag_name}}) {                 }->{$token->{tag_name}}) {
7837          !!!cp ('t427');          !!!cp ('t427');
# Line 7720  sub _tree_construction_main ($) { Line 7852  sub _tree_construction_main ($) {
7852          ## Ignore the token.          ## Ignore the token.
7853          !!!next-token;          !!!next-token;
7854          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  
           
7855        } else {        } else {
7856            if ($token->{tag_name} eq 'sarcasm') {
7857              sleep 0.001; # take a deep breath
7858            }
7859    
7860          ## Step 1          ## Step 1
7861          my $node_i = -1;          my $node_i = -1;
7862          my $node = $self->{open_elements}->[$node_i];          my $node = $self->{open_elements}->[$node_i];
# Line 7790  sub _tree_construction_main ($) { Line 7905  sub _tree_construction_main ($) {
7905                ## Ignore the token                ## Ignore the token
7906                !!!next-token;                !!!next-token;
7907                last S2;                last S2;
             }  
7908    
7909                  ## NOTE: |<span><dd></span>a|: In Safari 3.1.2 and Opera
7910                  ## 9.27, "a" is a child of <dd> (conforming).  In
7911                  ## Firefox 3.0.2, "a" is a child of <body>.  In WinIE 7,
7912                  ## "a" is a child of both <body> and <dd>.
7913                }
7914                
7915              !!!cp ('t434');              !!!cp ('t434');
7916            }            }
7917                        

Legend:
Removed from v.1.185  
changed lines
  Added in v.1.199

admin@suikawiki.org
ViewVC Help
Powered by ViewVC 1.1.24