| 820 |
## combined with the original insertion mode. In thie parser, |
## combined with the original insertion mode. In thie parser, |
| 821 |
## they are stored together in the bit-or'ed form. |
## they are stored together in the bit-or'ed form. |
| 822 |
|
|
| 823 |
|
sub IM_MASK () { 0b11111111111 } |
| 824 |
|
|
| 825 |
## NOTE: "initial" and "before html" insertion modes have no constants. |
## NOTE: "initial" and "before html" insertion modes have no constants. |
| 826 |
|
|
| 827 |
## NOTE: "after after body" insertion mode. |
## NOTE: "after after body" insertion mode. |
| 936 |
$doctype->public_id ($token->{pubid}) if defined $token->{pubid}; |
$doctype->public_id ($token->{pubid}) if defined $token->{pubid}; |
| 937 |
$doctype->system_id ($token->{sysid}) if defined $token->{sysid}; |
$doctype->system_id ($token->{sysid}) if defined $token->{sysid}; |
| 938 |
## NOTE: Other DocumentType attributes are null or empty lists. |
## NOTE: Other DocumentType attributes are null or empty lists. |
| 939 |
## ISSUE: internalSubset = null?? |
## In Firefox3, |internalSubset| attribute is set to the empty |
| 940 |
|
## string, while |null| is an allowed value for the attribute |
| 941 |
|
## according to DOM3 Core. |
| 942 |
$self->{document}->append_child ($doctype); |
$self->{document}->append_child ($doctype); |
| 943 |
|
|
| 944 |
if ($token->{quirks} or $doctype_name ne 'HTML') { |
if ($token->{quirks} or $doctype_name ne 'HTML') { |
| 2251 |
$parse_rcdata->(RCDATA_CONTENT_MODEL); |
$parse_rcdata->(RCDATA_CONTENT_MODEL); |
| 2252 |
## ISSUE: A spec bug [Bug 6038] |
## ISSUE: A spec bug [Bug 6038] |
| 2253 |
splice @{$self->{open_elements}}, -2, 1, () # <head> |
splice @{$self->{open_elements}}, -2, 1, () # <head> |
| 2254 |
if ($self->{insertion_mode} & AFTER_HEAD_IM) == AFTER_HEAD_IM; |
if ($self->{insertion_mode} & IM_MASK) == AFTER_HEAD_IM; |
| 2255 |
next B; |
next B; |
| 2256 |
} elsif ($token->{tag_name} eq 'style' or |
} elsif ($token->{tag_name} eq 'style' or |
| 2257 |
$token->{tag_name} eq 'noframes') { |
$token->{tag_name} eq 'noframes') { |
| 2271 |
$parse_rcdata->(CDATA_CONTENT_MODEL); |
$parse_rcdata->(CDATA_CONTENT_MODEL); |
| 2272 |
## ISSUE: A spec bug [Bug 6038] |
## ISSUE: A spec bug [Bug 6038] |
| 2273 |
splice @{$self->{open_elements}}, -2, 1, () # <head> |
splice @{$self->{open_elements}}, -2, 1, () # <head> |
| 2274 |
if ($self->{insertion_mode} & AFTER_HEAD_IM) == AFTER_HEAD_IM; |
if ($self->{insertion_mode} & IM_MASK) == AFTER_HEAD_IM; |
| 2275 |
next B; |
next B; |
| 2276 |
} elsif ($token->{tag_name} eq 'noscript') { |
} elsif ($token->{tag_name} eq 'noscript') { |
| 2277 |
if ($self->{insertion_mode} == IN_HEAD_IM) { |
if ($self->{insertion_mode} == IN_HEAD_IM) { |
| 2319 |
$script_start_tag->(); |
$script_start_tag->(); |
| 2320 |
## ISSUE: A spec bug [Bug 6038] |
## ISSUE: A spec bug [Bug 6038] |
| 2321 |
splice @{$self->{open_elements}}, -2, 1 # <head> |
splice @{$self->{open_elements}}, -2, 1 # <head> |
| 2322 |
if ($self->{insertion_mode} & AFTER_HEAD_IM) == AFTER_HEAD_IM; |
if ($self->{insertion_mode} & IM_MASK) == AFTER_HEAD_IM; |
| 2323 |
next B; |
next B; |
| 2324 |
} elsif ($token->{tag_name} eq 'body' or |
} elsif ($token->{tag_name} eq 'body' or |
| 2325 |
$token->{tag_name} eq 'frameset') { |
$token->{tag_name} eq 'frameset') { |
| 2502 |
## Reprocess in the "after head" insertion mode... |
## Reprocess in the "after head" insertion mode... |
| 2503 |
} elsif ($self->{insertion_mode} == IN_HEAD_NOSCRIPT_IM) { |
} elsif ($self->{insertion_mode} == IN_HEAD_NOSCRIPT_IM) { |
| 2504 |
!!!cp ('t143.3'); |
!!!cp ('t143.3'); |
| 2505 |
## ISSUE: Two parse errors for <head><noscript></br> |
## NOTE: Two parse errors for <head><noscript></br> |
| 2506 |
!!!parse-error (type => 'unmatched end tag', |
!!!parse-error (type => 'unmatched end tag', |
| 2507 |
text => 'br', token => $token); |
text => 'br', token => $token); |
| 2508 |
## As if </noscript> |
## As if </noscript> |
| 2645 |
caption => 1, col => 1, colgroup => 1, tbody => 1, |
caption => 1, col => 1, colgroup => 1, tbody => 1, |
| 2646 |
td => 1, tfoot => 1, th => 1, thead => 1, tr => 1, |
td => 1, tfoot => 1, th => 1, thead => 1, tr => 1, |
| 2647 |
}->{$token->{tag_name}}) { |
}->{$token->{tag_name}}) { |
| 2648 |
if ($self->{insertion_mode} == IN_CELL_IM) { |
if (($self->{insertion_mode} & IM_MASK) == IN_CELL_IM) { |
| 2649 |
## have an element in table scope |
## have an element in table scope |
| 2650 |
for (reverse 0..$#{$self->{open_elements}}) { |
for (reverse 0..$#{$self->{open_elements}}) { |
| 2651 |
my $node = $self->{open_elements}->[$_]; |
my $node = $self->{open_elements}->[$_]; |
| 2673 |
!!!nack ('t153.1'); |
!!!nack ('t153.1'); |
| 2674 |
!!!next-token; |
!!!next-token; |
| 2675 |
next B; |
next B; |
| 2676 |
} elsif ($self->{insertion_mode} & IN_CAPTION_IM) { |
} elsif (($self->{insertion_mode} & IM_MASK) == IN_CAPTION_IM) { |
| 2677 |
!!!parse-error (type => 'not closed', text => 'caption', |
!!!parse-error (type => 'not closed', text => 'caption', |
| 2678 |
token => $token); |
token => $token); |
| 2679 |
|
|
| 2738 |
} |
} |
| 2739 |
} elsif ($token->{type} == END_TAG_TOKEN) { |
} elsif ($token->{type} == END_TAG_TOKEN) { |
| 2740 |
if ($token->{tag_name} eq 'td' or $token->{tag_name} eq 'th') { |
if ($token->{tag_name} eq 'td' or $token->{tag_name} eq 'th') { |
| 2741 |
if ($self->{insertion_mode} == IN_CELL_IM) { |
if (($self->{insertion_mode} & IM_MASK) == IN_CELL_IM) { |
| 2742 |
## have an element in table scope |
## have an element in table scope |
| 2743 |
my $i; |
my $i; |
| 2744 |
INSCOPE: for (reverse 0..$#{$self->{open_elements}}) { |
INSCOPE: for (reverse 0..$#{$self->{open_elements}}) { |
| 2788 |
|
|
| 2789 |
!!!next-token; |
!!!next-token; |
| 2790 |
next B; |
next B; |
| 2791 |
} elsif ($self->{insertion_mode} == IN_CAPTION_IM) { |
} elsif (($self->{insertion_mode} & IM_MASK) == IN_CAPTION_IM) { |
| 2792 |
!!!cp ('t169'); |
!!!cp ('t169'); |
| 2793 |
!!!parse-error (type => 'unmatched end tag', |
!!!parse-error (type => 'unmatched end tag', |
| 2794 |
text => $token->{tag_name}, token => $token); |
text => $token->{tag_name}, token => $token); |
| 2800 |
# |
# |
| 2801 |
} |
} |
| 2802 |
} elsif ($token->{tag_name} eq 'caption') { |
} elsif ($token->{tag_name} eq 'caption') { |
| 2803 |
if ($self->{insertion_mode} == IN_CAPTION_IM) { |
if (($self->{insertion_mode} & IM_MASK) == IN_CAPTION_IM) { |
| 2804 |
## have a table element in table scope |
## have a table element in table scope |
| 2805 |
my $i; |
my $i; |
| 2806 |
INSCOPE: { |
INSCOPE: { |
| 2849 |
|
|
| 2850 |
!!!next-token; |
!!!next-token; |
| 2851 |
next B; |
next B; |
| 2852 |
} elsif ($self->{insertion_mode} == IN_CELL_IM) { |
} elsif (($self->{insertion_mode} & IM_MASK) == IN_CELL_IM) { |
| 2853 |
!!!cp ('t177'); |
!!!cp ('t177'); |
| 2854 |
!!!parse-error (type => 'unmatched end tag', |
!!!parse-error (type => 'unmatched end tag', |
| 2855 |
text => $token->{tag_name}, token => $token); |
text => $token->{tag_name}, token => $token); |
| 2864 |
table => 1, tbody => 1, tfoot => 1, |
table => 1, tbody => 1, tfoot => 1, |
| 2865 |
thead => 1, tr => 1, |
thead => 1, tr => 1, |
| 2866 |
}->{$token->{tag_name}} and |
}->{$token->{tag_name}} and |
| 2867 |
$self->{insertion_mode} == IN_CELL_IM) { |
($self->{insertion_mode} & IM_MASK) == IN_CELL_IM) { |
| 2868 |
## have an element in table scope |
## have an element in table scope |
| 2869 |
my $i; |
my $i; |
| 2870 |
my $tn; |
my $tn; |
| 2901 |
next B; |
next B; |
| 2902 |
} # INSCOPE |
} # INSCOPE |
| 2903 |
} elsif ($token->{tag_name} eq 'table' and |
} elsif ($token->{tag_name} eq 'table' and |
| 2904 |
$self->{insertion_mode} == IN_CAPTION_IM) { |
($self->{insertion_mode} & IM_MASK) == IN_CAPTION_IM) { |
| 2905 |
!!!parse-error (type => 'not closed', text => 'caption', |
!!!parse-error (type => 'not closed', text => 'caption', |
| 2906 |
token => $token); |
token => $token); |
| 2907 |
|
|
| 2967 |
!!!cp ('t191'); |
!!!cp ('t191'); |
| 2968 |
# |
# |
| 2969 |
} |
} |
| 2970 |
} elsif ({ |
} elsif ({ |
| 2971 |
tbody => 1, tfoot => 1, |
tbody => 1, tfoot => 1, |
| 2972 |
thead => 1, tr => 1, |
thead => 1, tr => 1, |
| 2973 |
}->{$token->{tag_name}} and |
}->{$token->{tag_name}} and |
| 2974 |
$self->{insertion_mode} == IN_CAPTION_IM) { |
($self->{insertion_mode} & IM_MASK) == IN_CAPTION_IM) { |
| 2975 |
!!!cp ('t192'); |
!!!cp ('t192'); |
| 2976 |
!!!parse-error (type => 'unmatched end tag', |
!!!parse-error (type => 'unmatched end tag', |
| 2977 |
text => $token->{tag_name}, token => $token); |
text => $token->{tag_name}, token => $token); |
| 2978 |
## Ignore the token |
## Ignore the token |
| 2979 |
!!!next-token; |
!!!next-token; |
| 2980 |
next B; |
next B; |
| 2981 |
} else { |
} else { |
| 2982 |
!!!cp ('t193'); |
!!!cp ('t193'); |
| 2983 |
# |
# |
| 2984 |
} |
} |
| 2985 |
} elsif ($token->{type} == END_OF_FILE_TOKEN) { |
} elsif ($token->{type} == END_OF_FILE_TOKEN) { |
| 2986 |
for my $entry (@{$self->{open_elements}}) { |
for my $entry (@{$self->{open_elements}}) { |
| 2987 |
unless ($entry->[1] & ALL_END_TAG_OPTIONAL_EL) { |
unless ($entry->[1] & ALL_END_TAG_OPTIONAL_EL) { |
| 3074 |
next B; |
next B; |
| 3075 |
} elsif ($token->{type} == START_TAG_TOKEN) { |
} elsif ($token->{type} == START_TAG_TOKEN) { |
| 3076 |
if ({ |
if ({ |
| 3077 |
tr => ($self->{insertion_mode} != IN_ROW_IM), |
tr => (($self->{insertion_mode} & IM_MASK) != IN_ROW_IM), |
| 3078 |
th => 1, td => 1, |
th => 1, td => 1, |
| 3079 |
}->{$token->{tag_name}}) { |
}->{$token->{tag_name}}) { |
| 3080 |
if ($self->{insertion_mode} == IN_TABLE_IM) { |
if (($self->{insertion_mode} & IM_MASK) == IN_TABLE_IM) { |
| 3081 |
## Clear back to table context |
## Clear back to table context |
| 3082 |
while (not ($self->{open_elements}->[-1]->[1] |
while (not ($self->{open_elements}->[-1]->[1] |
| 3083 |
& TABLE_SCOPING_EL)) { |
& TABLE_SCOPING_EL)) { |
| 3090 |
## reprocess in the "in table body" insertion mode... |
## reprocess in the "in table body" insertion mode... |
| 3091 |
} |
} |
| 3092 |
|
|
| 3093 |
if ($self->{insertion_mode} == IN_TABLE_BODY_IM) { |
if (($self->{insertion_mode} & IM_MASK) == IN_TABLE_BODY_IM) { |
| 3094 |
unless ($token->{tag_name} eq 'tr') { |
unless ($token->{tag_name} eq 'tr') { |
| 3095 |
!!!cp ('t202'); |
!!!cp ('t202'); |
| 3096 |
!!!parse-error (type => 'missing start tag:tr', token => $token); |
!!!parse-error (type => 'missing start tag:tr', token => $token); |
| 3142 |
tbody => 1, tfoot => 1, thead => 1, |
tbody => 1, tfoot => 1, thead => 1, |
| 3143 |
tr => 1, # $self->{insertion_mode} == IN_ROW_IM |
tr => 1, # $self->{insertion_mode} == IN_ROW_IM |
| 3144 |
}->{$token->{tag_name}}) { |
}->{$token->{tag_name}}) { |
| 3145 |
if ($self->{insertion_mode} == IN_ROW_IM) { |
if (($self->{insertion_mode} & IM_MASK) == IN_ROW_IM) { |
| 3146 |
## As if </tr> |
## As if </tr> |
| 3147 |
## have an element in table scope |
## have an element in table scope |
| 3148 |
my $i; |
my $i; |
| 3189 |
} |
} |
| 3190 |
} |
} |
| 3191 |
|
|
| 3192 |
if ($self->{insertion_mode} == IN_TABLE_BODY_IM) { |
if (($self->{insertion_mode} & IM_MASK) == IN_TABLE_BODY_IM) { |
| 3193 |
## have an element in table scope |
## have an element in table scope |
| 3194 |
my $i; |
my $i; |
| 3195 |
INSCOPE: for (reverse 0..$#{$self->{open_elements}}) { |
INSCOPE: for (reverse 0..$#{$self->{open_elements}}) { |
| 3403 |
$insert = $insert_to_foster; |
$insert = $insert_to_foster; |
| 3404 |
# |
# |
| 3405 |
} elsif ($token->{type} == END_TAG_TOKEN) { |
} elsif ($token->{type} == END_TAG_TOKEN) { |
| 3406 |
if ($token->{tag_name} eq 'tr' and |
if ($token->{tag_name} eq 'tr' and |
| 3407 |
$self->{insertion_mode} == IN_ROW_IM) { |
($self->{insertion_mode} & IM_MASK) == IN_ROW_IM) { |
| 3408 |
## have an element in table scope |
## have an element in table scope |
| 3409 |
my $i; |
my $i; |
| 3410 |
INSCOPE: for (reverse 0..$#{$self->{open_elements}}) { |
INSCOPE: for (reverse 0..$#{$self->{open_elements}}) { |
| 3411 |
my $node = $self->{open_elements}->[$_]; |
my $node = $self->{open_elements}->[$_]; |
| 3444 |
!!!nack ('t231.1'); |
!!!nack ('t231.1'); |
| 3445 |
next B; |
next B; |
| 3446 |
} elsif ($token->{tag_name} eq 'table') { |
} elsif ($token->{tag_name} eq 'table') { |
| 3447 |
if ($self->{insertion_mode} == IN_ROW_IM) { |
if (($self->{insertion_mode} & IM_MASK) == IN_ROW_IM) { |
| 3448 |
## As if </tr> |
## As if </tr> |
| 3449 |
## have an element in table scope |
## have an element in table scope |
| 3450 |
my $i; |
my $i; |
| 3483 |
## reprocess in the "in table body" insertion mode... |
## reprocess in the "in table body" insertion mode... |
| 3484 |
} |
} |
| 3485 |
|
|
| 3486 |
if ($self->{insertion_mode} == IN_TABLE_BODY_IM) { |
if (($self->{insertion_mode} & IM_MASK) == IN_TABLE_BODY_IM) { |
| 3487 |
## have an element in table scope |
## have an element in table scope |
| 3488 |
my $i; |
my $i; |
| 3489 |
INSCOPE: for (reverse 0..$#{$self->{open_elements}}) { |
INSCOPE: for (reverse 0..$#{$self->{open_elements}}) { |
| 3565 |
tbody => 1, tfoot => 1, thead => 1, |
tbody => 1, tfoot => 1, thead => 1, |
| 3566 |
}->{$token->{tag_name}} and |
}->{$token->{tag_name}} and |
| 3567 |
$self->{insertion_mode} & ROW_IMS) { |
$self->{insertion_mode} & ROW_IMS) { |
| 3568 |
if ($self->{insertion_mode} == IN_ROW_IM) { |
if (($self->{insertion_mode} & IM_MASK) == IN_ROW_IM) { |
| 3569 |
## have an element in table scope |
## have an element in table scope |
| 3570 |
my $i; |
my $i; |
| 3571 |
INSCOPE: for (reverse 0..$#{$self->{open_elements}}) { |
INSCOPE: for (reverse 0..$#{$self->{open_elements}}) { |
| 3699 |
} else { |
} else { |
| 3700 |
die "$0: $token->{type}: Unknown token type"; |
die "$0: $token->{type}: Unknown token type"; |
| 3701 |
} |
} |
| 3702 |
} elsif ($self->{insertion_mode} == IN_COLUMN_GROUP_IM) { |
} elsif (($self->{insertion_mode} & IM_MASK) == IN_COLUMN_GROUP_IM) { |
| 3703 |
if ($token->{type} == CHARACTER_TOKEN) { |
if ($token->{type} == CHARACTER_TOKEN) { |
| 3704 |
if ($token->{data} =~ s/^([\x09\x0A\x0C\x20]+)//) { |
if ($token->{data} =~ s/^([\x09\x0A\x0C\x20]+)//) { |
| 3705 |
$self->{open_elements}->[-1]->[0]->manakai_append_text ($1); |
$self->{open_elements}->[-1]->[0]->manakai_append_text ($1); |
| 3831 |
} elsif ({ |
} elsif ({ |
| 3832 |
select => 1, input => 1, textarea => 1, |
select => 1, input => 1, textarea => 1, |
| 3833 |
}->{$token->{tag_name}} or |
}->{$token->{tag_name}} or |
| 3834 |
($self->{insertion_mode} == IN_SELECT_IN_TABLE_IM and |
(($self->{insertion_mode} & IM_MASK) |
| 3835 |
|
== IN_SELECT_IN_TABLE_IM and |
| 3836 |
{ |
{ |
| 3837 |
caption => 1, table => 1, |
caption => 1, table => 1, |
| 3838 |
tbody => 1, tfoot => 1, thead => 1, |
tbody => 1, tfoot => 1, thead => 1, |
| 3954 |
!!!nack ('t291.1'); |
!!!nack ('t291.1'); |
| 3955 |
!!!next-token; |
!!!next-token; |
| 3956 |
next B; |
next B; |
| 3957 |
} elsif ($self->{insertion_mode} == IN_SELECT_IN_TABLE_IM and |
} elsif (($self->{insertion_mode} & IM_MASK) |
| 3958 |
|
== IN_SELECT_IN_TABLE_IM and |
| 3959 |
{ |
{ |
| 3960 |
caption => 1, table => 1, tbody => 1, |
caption => 1, table => 1, tbody => 1, |
| 3961 |
tfoot => 1, thead => 1, tr => 1, td => 1, th => 1, |
tfoot => 1, thead => 1, tr => 1, td => 1, th => 1, |
| 4998 |
|
|
| 4999 |
if ($self->{insertion_mode} & TABLE_IMS or |
if ($self->{insertion_mode} & TABLE_IMS or |
| 5000 |
$self->{insertion_mode} & BODY_TABLE_IMS or |
$self->{insertion_mode} & BODY_TABLE_IMS or |
| 5001 |
$self->{insertion_mode} == IN_COLUMN_GROUP_IM) { |
($self->{insertion_mode} & IM_MASK) == IN_COLUMN_GROUP_IM) { |
| 5002 |
!!!cp ('t400.1'); |
!!!cp ('t400.1'); |
| 5003 |
$self->{insertion_mode} = IN_SELECT_IN_TABLE_IM; |
$self->{insertion_mode} = IN_SELECT_IN_TABLE_IM; |
| 5004 |
} else { |
} else { |
| 5615 |
}->{$node_ln}; |
}->{$node_ln}; |
| 5616 |
$p->{content_model} = PCDATA_CONTENT_MODEL |
$p->{content_model} = PCDATA_CONTENT_MODEL |
| 5617 |
unless defined $p->{content_model}; |
unless defined $p->{content_model}; |
|
## ISSUE: What is "the name of the element"? local name? |
|
| 5618 |
|
|
| 5619 |
$p->{inner_html_node} = [$node, $el_category->{$node_ln}]; |
$p->{inner_html_node} = [$node, $el_category->{$node_ln}]; |
| 5620 |
## TODO: Foreign element OK? |
## TODO: Foreign element OK? |