| 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 |
}, |
}, |
| 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); |
| 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; |
| 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"; |
| 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; |
| 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}) { |
| 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'); |
| 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 |
} |
} |
| 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}}) { |
| 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> ... |
|
INSCOPE: for (reverse @{$self->{open_elements}}) { |
|
|
if ($_->[1] & P_EL) { |
|
|
!!!cp ('t353'); |
|
|
!!!back-token; # <x> |
|
|
$token = {type => END_TAG_TOKEN, tag_name => 'p', |
|
|
line => $token->{line}, column => $token->{column}}; |
|
|
next B; |
|
|
} elsif ($_->[1] & SCOPING_EL) { |
|
|
!!!cp ('t354'); |
|
|
last INSCOPE; |
|
|
} |
|
|
} # INSCOPE |
|
| 6990 |
|
|
| 6991 |
## NOTE: Special, Scope (<li><foo><li> == <li><foo><li/></foo></li>) |
## NOTE: Special, Scope (<li><foo><li> == <li><foo><li/></foo></li>) |
| 6992 |
## Interpreted as <li><foo/></li><li/> (non-conforming) |
## Interpreted as <li><foo/></li><li/> (non-conforming) |
| 7000 |
## address, div, p (<li><foo><li> == <li><foo/></li><li/>) |
## address, div, p (<li><foo><li> == <li><foo/></li><li/>) |
| 7001 |
## Interpreted as <li><foo><li/></foo></li> (non-conforming) |
## Interpreted as <li><foo><li/></foo></li> (non-conforming) |
| 7002 |
## div (Fx, S) |
## div (Fx, S) |
| 7003 |
|
|
| 7004 |
## Step 1 |
my $non_optional; |
| 7005 |
my $i = -1; |
my $i = -1; |
| 7006 |
my $node = $self->{open_elements}->[$i]; |
|
| 7007 |
my $li_or_dtdd = {li => {li => 1}, |
## 1. |
| 7008 |
dt => {dt => 1, dd => 1}, |
for my $node (reverse @{$self->{open_elements}}) { |
| 7009 |
dd => {dt => 1, dd => 1}}->{$token->{tag_name}}; |
if ($node->[1] & LI_EL) { |
| 7010 |
LI: { |
## 2. (a) As if </li> |
| 7011 |
## Step 2 |
{ |
| 7012 |
if ($li_or_dtdd->{$node->[0]->manakai_local_name}) { |
## If no </li> - not applied |
| 7013 |
if ($i != -1) { |
# |
| 7014 |
!!!cp ('t355'); |
|
| 7015 |
!!!parse-error (type => 'not closed', |
## Otherwise |
| 7016 |
text => $self->{open_elements}->[-1]->[0] |
|
| 7017 |
->manakai_local_name, |
## 1. generate implied end tags, except for </li> |
| 7018 |
token => $token); |
# |
| 7019 |
} else { |
|
| 7020 |
!!!cp ('t356'); |
## 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 |
splice @{$self->{open_elements}}, $i; |
|
| 7034 |
last LI; |
last; ## 2. (b) goto 5. |
| 7035 |
} else { |
} 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'); |
!!!cp ('t357'); |
| 7046 |
} |
last; ## goto 5. |
| 7047 |
|
} elsif ($node->[1] & END_TAG_OPTIONAL_EL) { |
|
## 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)) { |
|
| 7048 |
!!!cp ('t358'); |
!!!cp ('t358'); |
| 7049 |
last LI; |
# |
| 7050 |
|
} else { |
| 7051 |
|
!!!cp ('t359'); |
| 7052 |
|
$non_optional ||= $node; |
| 7053 |
|
# |
| 7054 |
} |
} |
| 7055 |
|
## 4. |
| 7056 |
!!!cp ('t359'); |
## goto 2. |
|
## Step 4 |
|
| 7057 |
$i--; |
$i--; |
| 7058 |
$node = $self->{open_elements}->[$i]; |
} |
| 7059 |
redo LI; |
|
| 7060 |
} # LI |
## 5. (a) has a |p| element in scope |
| 7061 |
|
INSCOPE: for (reverse @{$self->{open_elements}}) { |
| 7062 |
|
if ($_->[1] & P_EL) { |
| 7063 |
|
!!!cp ('t353'); |
| 7064 |
|
|
| 7065 |
|
## NOTE: |<p><li>|, for example. |
| 7066 |
|
|
| 7067 |
|
!!!back-token; # <x> |
| 7068 |
|
$token = {type => END_TAG_TOKEN, tag_name => 'p', |
| 7069 |
|
line => $token->{line}, column => $token->{column}}; |
| 7070 |
|
next B; |
| 7071 |
|
} elsif ($_->[1] & SCOPING_EL) { |
| 7072 |
|
!!!cp ('t354'); |
| 7073 |
|
last INSCOPE; |
| 7074 |
|
} |
| 7075 |
|
} # INSCOPE |
| 7076 |
|
|
| 7077 |
|
## 5. (b) insert |
| 7078 |
!!!insert-element-t ($token->{tag_name}, $token->{attributes}, $token); |
!!!insert-element-t ($token->{tag_name}, $token->{attributes}, $token); |
| 7079 |
!!!nack ('t359.1'); |
!!!nack ('t359.1'); |
| 7080 |
!!!next-token; |
!!!next-token; |
| 7081 |
next B; |
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; |
| 7088 |
|
|
| 7089 |
|
## 1. |
| 7090 |
|
for my $node (reverse @{$self->{open_elements}}) { |
| 7091 |
|
if ($node->[1] & DT_EL or $node->[1] & DD_EL) { |
| 7092 |
|
## 2. (a) As if </li> |
| 7093 |
|
{ |
| 7094 |
|
## If no </li> - not applied |
| 7095 |
|
# |
| 7096 |
|
|
| 7097 |
|
## Otherwise |
| 7098 |
|
|
| 7099 |
|
## 1. generate implied end tags, except for </dt> or </dd> |
| 7100 |
|
# |
| 7101 |
|
|
| 7102 |
|
## 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 |
|
|
| 7116 |
|
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 { |
| 7133 |
|
!!!cp ('t359.1'); |
| 7134 |
|
$non_optional ||= $node; |
| 7135 |
|
# |
| 7136 |
|
} |
| 7137 |
|
## 4. |
| 7138 |
|
## goto 2. |
| 7139 |
|
$i--; |
| 7140 |
|
} |
| 7141 |
|
|
| 7142 |
|
## 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); |
| 7158 |
|
!!!nack ('t359.2'); |
| 7159 |
|
!!!next-token; |
| 7160 |
|
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) { |
| 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'); |
| 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}}; |
| 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; |
| 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', |
| 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}}) { |
| 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 |
| 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 |
| 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}->[$_]; |
| 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'); |
| 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) { |
| 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', |