6991 |
!!!next-token; |
!!!next-token; |
6992 |
} |
} |
6993 |
next B; |
next B; |
6994 |
} elsif ({ |
} elsif ($token->{tag_name} eq 'li') { |
6995 |
## NOTE: As normal, but imply </li> when there's another <li> |
## NOTE: As normal, but imply </li> when there's another <li> ... |
|
li => 1, |
|
|
## NOTE: As normal, but imply </dt> or </dd> when ... |
|
|
dt => 1, dd => 1, |
|
|
}->{$token->{tag_name}}) { |
|
|
## has a p element in scope |
|
|
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 |
## NOTE: As normal, but effectively ends parsing |
7168 |
|
|