| 6911 |
!!!next-token; |
!!!next-token; |
| 6912 |
next B; |
next B; |
| 6913 |
} elsif ({ |
} elsif ({ |
| 6914 |
address => 1, blockquote => 1, center => 1, dir => 1, |
## NOTE: Start tags for non-phrasing flow content elements |
| 6915 |
div => 1, dl => 1, fieldset => 1, |
|
| 6916 |
h1 => 1, h2 => 1, h3 => 1, h4 => 1, h5 => 1, h6 => 1, |
## NOTE: The normal one |
| 6917 |
menu => 1, ol => 1, p => 1, ul => 1, |
address => 1, article => 1, aside => 1, blockquote => 1, |
| 6918 |
|
center => 1, datagrid => 1, details => 1, dialog => 1, |
| 6919 |
|
dir => 1, div => 1, dl => 1, fieldset => 1, figure => 1, |
| 6920 |
|
footer => 1, h1 => 1, h2 => 1, h3 => 1, h4 => 1, h5 => 1, |
| 6921 |
|
h6 => 1, header => 1, menu => 1, nav => 1, ol => 1, p => 1, |
| 6922 |
|
section => 1, ul => 1, |
| 6923 |
|
## NOTE: As normal, but drops leading newline |
| 6924 |
pre => 1, listing => 1, |
pre => 1, listing => 1, |
| 6925 |
|
## NOTE: As normal, but interacts with the form element pointer |
| 6926 |
form => 1, |
form => 1, |
| 6927 |
|
|
| 6928 |
table => 1, |
table => 1, |
| 6929 |
hr => 1, |
hr => 1, |
| 6930 |
}->{$token->{tag_name}}) { |
}->{$token->{tag_name}}) { |
| 6991 |
!!!next-token; |
!!!next-token; |
| 6992 |
} |
} |
| 6993 |
next B; |
next B; |
| 6994 |
} elsif ({li => 1, dt => 1, dd => 1}->{$token->{tag_name}}) { |
} elsif ($token->{tag_name} eq 'li') { |
| 6995 |
## 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 |
|
| 6996 |
|
|
| 6997 |
## NOTE: Special, Scope (<li><foo><li> == <li><foo><li/></foo></li>) |
## NOTE: Special, Scope (<li><foo><li> == <li><foo><li/></foo></li>) |
| 6998 |
## Interpreted as <li><foo/></li><li/> (non-conforming) |
## Interpreted as <li><foo/></li><li/> (non-conforming) |
| 7006 |
## address, div, p (<li><foo><li> == <li><foo/></li><li/>) |
## address, div, p (<li><foo><li> == <li><foo/></li><li/>) |
| 7007 |
## Interpreted as <li><foo><li/></foo></li> (non-conforming) |
## Interpreted as <li><foo><li/></foo></li> (non-conforming) |
| 7008 |
## div (Fx, S) |
## div (Fx, S) |
| 7009 |
|
|
| 7010 |
## Step 1 |
my $non_optional; |
| 7011 |
my $i = -1; |
my $i = -1; |
| 7012 |
my $node = $self->{open_elements}->[$i]; |
|
| 7013 |
my $li_or_dtdd = {li => {li => 1}, |
## 1. |
| 7014 |
dt => {dt => 1, dd => 1}, |
for my $node (reverse @{$self->{open_elements}}) { |
| 7015 |
dd => {dt => 1, dd => 1}}->{$token->{tag_name}}; |
if ($node->[1] & LI_EL) { |
| 7016 |
LI: { |
## 2. (a) As if </li> |
| 7017 |
## Step 2 |
{ |
| 7018 |
if ($li_or_dtdd->{$node->[0]->manakai_local_name}) { |
## If no </li> - not applied |
| 7019 |
if ($i != -1) { |
# |
| 7020 |
!!!cp ('t355'); |
|
| 7021 |
!!!parse-error (type => 'not closed', |
## Otherwise |
| 7022 |
text => $self->{open_elements}->[-1]->[0] |
|
| 7023 |
->manakai_local_name, |
## 1. generate implied end tags, except for </li> |
| 7024 |
token => $token); |
# |
| 7025 |
} else { |
|
| 7026 |
!!!cp ('t356'); |
## 2. If current node != "li", parse error |
| 7027 |
|
if ($non_optional) { |
| 7028 |
|
!!!parse-error (type => 'not closed', |
| 7029 |
|
text => $non_optional->[0]->manakai_local_name, |
| 7030 |
|
token => $token); |
| 7031 |
|
!!!cp ('t355'); |
| 7032 |
|
} else { |
| 7033 |
|
!!!cp ('t356'); |
| 7034 |
|
} |
| 7035 |
|
|
| 7036 |
|
## 3. Pop |
| 7037 |
|
splice @{$self->{open_elements}}, $i; |
| 7038 |
} |
} |
| 7039 |
splice @{$self->{open_elements}}, $i; |
|
| 7040 |
last LI; |
last; ## 2. (b) goto 5. |
| 7041 |
} else { |
} elsif ( |
| 7042 |
|
## NOTE: not "formatting" and not "phrasing" |
| 7043 |
|
($node->[1] & SPECIAL_EL or |
| 7044 |
|
$node->[1] & SCOPING_EL) and |
| 7045 |
|
## NOTE: "li", "dt", and "dd" are in |SPECIAL_EL|. |
| 7046 |
|
|
| 7047 |
|
(not $node->[1] & ADDRESS_EL) & |
| 7048 |
|
(not $node->[1] & DIV_EL) & |
| 7049 |
|
(not $node->[1] & P_EL)) { |
| 7050 |
|
## 3. |
| 7051 |
!!!cp ('t357'); |
!!!cp ('t357'); |
| 7052 |
} |
last; ## goto 5. |
| 7053 |
|
} 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)) { |
|
| 7054 |
!!!cp ('t358'); |
!!!cp ('t358'); |
| 7055 |
last LI; |
# |
| 7056 |
|
} else { |
| 7057 |
|
!!!cp ('t359'); |
| 7058 |
|
$non_optional ||= $node; |
| 7059 |
|
# |
| 7060 |
} |
} |
| 7061 |
|
## 4. |
| 7062 |
!!!cp ('t359'); |
## goto 2. |
|
## Step 4 |
|
| 7063 |
$i--; |
$i--; |
| 7064 |
$node = $self->{open_elements}->[$i]; |
} |
| 7065 |
redo LI; |
|
| 7066 |
} # LI |
## 5. (a) has a |p| element in scope |
| 7067 |
|
## ISSUE: Is this step really necessary? |
| 7068 |
|
INSCOPE: for (reverse @{$self->{open_elements}}) { |
| 7069 |
|
if ($_->[1] & P_EL) { |
| 7070 |
|
!!!cp ('t353'); |
| 7071 |
|
!!!back-token; # <x> |
| 7072 |
|
$token = {type => END_TAG_TOKEN, tag_name => 'p', |
| 7073 |
|
line => $token->{line}, column => $token->{column}}; |
| 7074 |
|
next B; |
| 7075 |
|
} elsif ($_->[1] & SCOPING_EL) { |
| 7076 |
|
!!!cp ('t354'); |
| 7077 |
|
last INSCOPE; |
| 7078 |
|
} |
| 7079 |
|
} # INSCOPE |
| 7080 |
|
|
| 7081 |
|
## 5. (b) insert |
| 7082 |
!!!insert-element-t ($token->{tag_name}, $token->{attributes}, $token); |
!!!insert-element-t ($token->{tag_name}, $token->{attributes}, $token); |
| 7083 |
!!!nack ('t359.1'); |
!!!nack ('t359.1'); |
| 7084 |
!!!next-token; |
!!!next-token; |
| 7085 |
next B; |
next B; |
| 7086 |
|
} elsif ($token->{tag_name} eq 'dt' or |
| 7087 |
|
$token->{tag_name} eq 'dd') { |
| 7088 |
|
## NOTE: As normal, but imply </dt> or </dd> when ... |
| 7089 |
|
|
| 7090 |
|
my $non_optional; |
| 7091 |
|
my $i = -1; |
| 7092 |
|
|
| 7093 |
|
## 1. |
| 7094 |
|
for my $node (reverse @{$self->{open_elements}}) { |
| 7095 |
|
if ($node->[1] & DT_EL or $node->[1] & DD_EL) { |
| 7096 |
|
## 2. (a) As if </li> |
| 7097 |
|
{ |
| 7098 |
|
## If no </li> - not applied |
| 7099 |
|
# |
| 7100 |
|
|
| 7101 |
|
## Otherwise |
| 7102 |
|
|
| 7103 |
|
## 1. generate implied end tags, except for </dt> or </dd> |
| 7104 |
|
# |
| 7105 |
|
|
| 7106 |
|
## 2. If current node != "dt"|"dd", parse error |
| 7107 |
|
if ($non_optional) { |
| 7108 |
|
!!!parse-error (type => 'not closed', |
| 7109 |
|
text => $non_optional->[0]->manakai_local_name, |
| 7110 |
|
token => $token); |
| 7111 |
|
!!!cp ('t355.1'); |
| 7112 |
|
} else { |
| 7113 |
|
!!!cp ('t356.1'); |
| 7114 |
|
} |
| 7115 |
|
|
| 7116 |
|
## 3. Pop |
| 7117 |
|
splice @{$self->{open_elements}}, $i; |
| 7118 |
|
} |
| 7119 |
|
|
| 7120 |
|
last; ## 2. (b) goto 5. |
| 7121 |
|
} elsif ( |
| 7122 |
|
## NOTE: not "formatting" and not "phrasing" |
| 7123 |
|
($node->[1] & SPECIAL_EL or |
| 7124 |
|
$node->[1] & SCOPING_EL) and |
| 7125 |
|
## NOTE: "li", "dt", and "dd" are in |SPECIAL_EL|. |
| 7126 |
|
|
| 7127 |
|
(not $node->[1] & ADDRESS_EL) & |
| 7128 |
|
(not $node->[1] & DIV_EL) & |
| 7129 |
|
(not $node->[1] & P_EL)) { |
| 7130 |
|
## 3. |
| 7131 |
|
!!!cp ('t357.1'); |
| 7132 |
|
last; ## goto 5. |
| 7133 |
|
} elsif ($node->[1] & END_TAG_OPTIONAL_EL) { |
| 7134 |
|
!!!cp ('t358.1'); |
| 7135 |
|
# |
| 7136 |
|
} else { |
| 7137 |
|
!!!cp ('t359.1'); |
| 7138 |
|
$non_optional ||= $node; |
| 7139 |
|
# |
| 7140 |
|
} |
| 7141 |
|
## 4. |
| 7142 |
|
## goto 2. |
| 7143 |
|
$i--; |
| 7144 |
|
} |
| 7145 |
|
|
| 7146 |
|
## 5. (a) has a |p| element in scope |
| 7147 |
|
## ISSUE: Is this step really necessary? |
| 7148 |
|
INSCOPE: for (reverse @{$self->{open_elements}}) { |
| 7149 |
|
if ($_->[1] & P_EL) { |
| 7150 |
|
!!!cp ('t353.1'); |
| 7151 |
|
!!!back-token; # <x> |
| 7152 |
|
$token = {type => END_TAG_TOKEN, tag_name => 'p', |
| 7153 |
|
line => $token->{line}, column => $token->{column}}; |
| 7154 |
|
next B; |
| 7155 |
|
} elsif ($_->[1] & SCOPING_EL) { |
| 7156 |
|
!!!cp ('t354.1'); |
| 7157 |
|
last INSCOPE; |
| 7158 |
|
} |
| 7159 |
|
} # INSCOPE |
| 7160 |
|
|
| 7161 |
|
## 5. (b) insert |
| 7162 |
|
!!!insert-element-t ($token->{tag_name}, $token->{attributes}, $token); |
| 7163 |
|
!!!nack ('t359.2'); |
| 7164 |
|
!!!next-token; |
| 7165 |
|
next B; |
| 7166 |
} elsif ($token->{tag_name} eq 'plaintext') { |
} elsif ($token->{tag_name} eq 'plaintext') { |
| 7167 |
|
## NOTE: As normal, but effectively ends parsing |
| 7168 |
|
|
| 7169 |
## has a p element in scope |
## has a p element in scope |
| 7170 |
INSCOPE: for (reverse @{$self->{open_elements}}) { |
INSCOPE: for (reverse @{$self->{open_elements}}) { |
| 7171 |
if ($_->[1] & P_EL) { |
if ($_->[1] & P_EL) { |
| 7602 |
next B; |
next B; |
| 7603 |
} |
} |
| 7604 |
} elsif ({ |
} elsif ({ |
| 7605 |
address => 1, blockquote => 1, center => 1, dir => 1, |
## NOTE: End tags for non-phrasing flow content elements |
| 7606 |
div => 1, dl => 1, fieldset => 1, listing => 1, |
|
| 7607 |
menu => 1, ol => 1, pre => 1, ul => 1, |
## NOTE: The normal ones |
| 7608 |
|
address => 1, article => 1, aside => 1, blockquote => 1, |
| 7609 |
|
center => 1, datagrid => 1, details => 1, dialog => 1, |
| 7610 |
|
dir => 1, div => 1, dl => 1, fieldset => 1, figure => 1, |
| 7611 |
|
footer => 1, header => 1, listing => 1, menu => 1, nav => 1, |
| 7612 |
|
ol => 1, pre => 1, section => 1, ul => 1, |
| 7613 |
|
|
| 7614 |
|
## NOTE: As normal, but ... optional tags |
| 7615 |
dd => 1, dt => 1, li => 1, |
dd => 1, dt => 1, li => 1, |
| 7616 |
|
|
| 7617 |
applet => 1, button => 1, marquee => 1, object => 1, |
applet => 1, button => 1, marquee => 1, object => 1, |
| 7618 |
}->{$token->{tag_name}}) { |
}->{$token->{tag_name}}) { |
| 7619 |
## has an element in scope |
## has an element in scope |
| 7676 |
!!!next-token; |
!!!next-token; |
| 7677 |
next B; |
next B; |
| 7678 |
} elsif ($token->{tag_name} eq 'form') { |
} elsif ($token->{tag_name} eq 'form') { |
| 7679 |
|
## NOTE: As normal, but interacts with the form element pointer |
| 7680 |
|
|
| 7681 |
undef $self->{form_element}; |
undef $self->{form_element}; |
| 7682 |
|
|
| 7683 |
## has an element in scope |
## has an element in scope |
| 7725 |
!!!next-token; |
!!!next-token; |
| 7726 |
next B; |
next B; |
| 7727 |
} elsif ({ |
} elsif ({ |
| 7728 |
|
## NOTE: As normal, except acts as a closer for any ... |
| 7729 |
h1 => 1, h2 => 1, h3 => 1, h4 => 1, h5 => 1, h6 => 1, |
h1 => 1, h2 => 1, h3 => 1, h4 => 1, h5 => 1, h6 => 1, |
| 7730 |
}->{$token->{tag_name}}) { |
}->{$token->{tag_name}}) { |
| 7731 |
## has an element in scope |
## has an element in scope |
| 7771 |
!!!next-token; |
!!!next-token; |
| 7772 |
next B; |
next B; |
| 7773 |
} elsif ($token->{tag_name} eq 'p') { |
} elsif ($token->{tag_name} eq 'p') { |
| 7774 |
|
## NOTE: As normal, except </p> implies <p> and ... |
| 7775 |
|
|
| 7776 |
## has an element in scope |
## has an element in scope |
| 7777 |
my $i; |
my $i; |
| 7778 |
INSCOPE: for (reverse 0..$#{$self->{open_elements}}) { |
INSCOPE: for (reverse 0..$#{$self->{open_elements}}) { |
| 7857 |
## Ignore the token |
## Ignore the token |
| 7858 |
!!!next-token; |
!!!next-token; |
| 7859 |
next B; |
next B; |
|
|
|
|
## ISSUE: Issue on HTML5 new elements in spec |
|
|
|
|
| 7860 |
} else { |
} else { |
| 7861 |
|
if ($token->{tag_name} eq 'sarcasm') { |
| 7862 |
|
sleep 0.001; # take a deep breath |
| 7863 |
|
} |
| 7864 |
|
|
| 7865 |
## Step 1 |
## Step 1 |
| 7866 |
my $node_i = -1; |
my $node_i = -1; |
| 7867 |
my $node = $self->{open_elements}->[$node_i]; |
my $node = $self->{open_elements}->[$node_i]; |