| 4956 |
|
|
| 4957 |
undef $self->{form_element}; |
undef $self->{form_element}; |
| 4958 |
undef $self->{head_element}; |
undef $self->{head_element}; |
| 4959 |
|
undef $self->{head_element_inserted}; |
| 4960 |
$self->{open_elements} = []; |
$self->{open_elements} = []; |
| 4961 |
undef $self->{inner_html_node}; |
undef $self->{inner_html_node}; |
| 4962 |
|
|
| 5623 |
|
|
| 5624 |
## NOTE: $open_tables->[-1]->[0] is the "current table" element node. |
## NOTE: $open_tables->[-1]->[0] is the "current table" element node. |
| 5625 |
## NOTE: $open_tables->[-1]->[1] is the "tainted" flag. |
## NOTE: $open_tables->[-1]->[1] is the "tainted" flag. |
| 5626 |
|
## NOTE: $open_tables->[-1]->[2] is set false when non-Text node inserted. |
| 5627 |
my $open_tables = [[$self->{open_elements}->[0]->[0]]]; |
my $open_tables = [[$self->{open_elements}->[0]->[0]]]; |
| 5628 |
|
|
| 5629 |
my $formatting_end_tag = sub { |
my $formatting_end_tag = sub { |
| 5897 |
} |
} |
| 5898 |
}; # $insert_to_foster |
}; # $insert_to_foster |
| 5899 |
|
|
| 5900 |
|
## NOTE: When a character is inserted, if the last node that was |
| 5901 |
|
## inserted by the parser is a Text node and the character has to be |
| 5902 |
|
## inserted after that node, then the character is appended to the |
| 5903 |
|
## Text node. However, if any other node is inserted by the parser, |
| 5904 |
|
## then a new Text node is created and the character is appended as |
| 5905 |
|
## that Text node. If I'm not wrong, there are only two cases where |
| 5906 |
|
## this occurs. One is the case where an element node is inserted |
| 5907 |
|
## to the |head| element. This is covered by using the |
| 5908 |
|
## |$self->{head_element_inserted}| flag. Another is the case where |
| 5909 |
|
## an element or comment is inserted into the |table| subtree while |
| 5910 |
|
## foster parenting happens. This is covered by using the [2] flag |
| 5911 |
|
## of the |$open_tables| structure. All other cases are handled |
| 5912 |
|
## simply by calling |manakai_append_text| method. |
| 5913 |
|
|
| 5914 |
B: while (1) { |
B: while (1) { |
| 5915 |
if ($token->{type} == DOCTYPE_TOKEN) { |
if ($token->{type} == DOCTYPE_TOKEN) { |
| 5916 |
|
|
| 5958 |
} else { |
} else { |
| 5959 |
|
|
| 5960 |
$self->{open_elements}->[-1]->[0]->append_child ($comment); |
$self->{open_elements}->[-1]->[0]->append_child ($comment); |
| 5961 |
|
$open_tables->[-1]->[2] = 0 if @$open_tables; # ~node inserted |
| 5962 |
} |
} |
| 5963 |
$token = $self->_get_next_token; |
$token = $self->_get_next_token; |
| 5964 |
next B; |
next B; |
| 6128 |
if ($token->{type} == CHARACTER_TOKEN) { |
if ($token->{type} == CHARACTER_TOKEN) { |
| 6129 |
if ($token->{data} =~ s/^([\x09\x0A\x0C\x20]+)//) { |
if ($token->{data} =~ s/^([\x09\x0A\x0C\x20]+)//) { |
| 6130 |
unless ($self->{insertion_mode} == BEFORE_HEAD_IM) { |
unless ($self->{insertion_mode} == BEFORE_HEAD_IM) { |
| 6131 |
|
if ($self->{head_element_inserted}) { |
| 6132 |
$self->{open_elements}->[-1]->[0]->manakai_append_text ($1); |
|
| 6133 |
# |
$self->{open_elements}->[-1]->[0]->append_child |
| 6134 |
|
($self->{document}->create_text_node ($1)); |
| 6135 |
|
delete $self->{head_element_inserted}; |
| 6136 |
|
## NOTE: |</head> <link> | |
| 6137 |
|
# |
| 6138 |
|
} else { |
| 6139 |
|
|
| 6140 |
|
$self->{open_elements}->[-1]->[0]->manakai_append_text ($1); |
| 6141 |
|
## NOTE: |</head>  | |
| 6142 |
|
# |
| 6143 |
|
} |
| 6144 |
} else { |
} else { |
| 6145 |
|
|
| 6146 |
## Ignore the token. |
## Ignore the token. |
| 6284 |
|
|
| 6285 |
} |
} |
| 6286 |
|
|
| 6287 |
if ($token->{tag_name} eq 'base') { |
if ($token->{tag_name} eq 'base') { |
| 6288 |
if ($self->{insertion_mode} == IN_HEAD_NOSCRIPT_IM) { |
if ($self->{insertion_mode} == IN_HEAD_NOSCRIPT_IM) { |
| 6289 |
|
|
| 6290 |
## As if </noscript> |
## As if </noscript> |
| 6291 |
pop @{$self->{open_elements}}; |
pop @{$self->{open_elements}}; |
| 6292 |
$self->{parse_error}->(level => $self->{level}->{must}, type => 'in noscript', text => 'base', |
$self->{parse_error}->(level => $self->{level}->{must}, type => 'in noscript', text => 'base', |
| 6293 |
token => $token); |
token => $token); |
| 6294 |
|
|
| 6295 |
$self->{insertion_mode} = IN_HEAD_IM; |
$self->{insertion_mode} = IN_HEAD_IM; |
| 6296 |
## Reprocess in the "in head" insertion mode... |
## Reprocess in the "in head" insertion mode... |
| 6297 |
} else { |
} else { |
| 6298 |
|
|
| 6299 |
} |
} |
| 6300 |
|
|
| 6301 |
## NOTE: There is a "as if in head" code clone. |
## NOTE: There is a "as if in head" code clone. |
| 6302 |
if ($self->{insertion_mode} == AFTER_HEAD_IM) { |
if ($self->{insertion_mode} == AFTER_HEAD_IM) { |
| 6303 |
|
|
| 6304 |
$self->{parse_error}->(level => $self->{level}->{must}, type => 'after head', |
$self->{parse_error}->(level => $self->{level}->{must}, type => 'after head', |
| 6305 |
text => $token->{tag_name}, token => $token); |
text => $token->{tag_name}, token => $token); |
| 6306 |
push @{$self->{open_elements}}, |
push @{$self->{open_elements}}, |
| 6307 |
[$self->{head_element}, $el_category->{head}]; |
[$self->{head_element}, $el_category->{head}]; |
| 6308 |
} else { |
$self->{head_element_inserted} = 1; |
| 6309 |
|
} else { |
| 6310 |
} |
|
| 6311 |
|
} |
| 6312 |
|
|
| 6313 |
{ |
{ |
| 6314 |
my $el; |
my $el; |
| 6315 |
|
|
| 6334 |
push @{$self->{open_elements}}, [$el, $el_category->{$token->{tag_name}} || 0]; |
push @{$self->{open_elements}}, [$el, $el_category->{$token->{tag_name}} || 0]; |
| 6335 |
} |
} |
| 6336 |
|
|
| 6337 |
pop @{$self->{open_elements}}; |
pop @{$self->{open_elements}}; |
| 6338 |
pop @{$self->{open_elements}} # <head> |
pop @{$self->{open_elements}} # <head> |
| 6339 |
if $self->{insertion_mode} == AFTER_HEAD_IM; |
if $self->{insertion_mode} == AFTER_HEAD_IM; |
| 6340 |
|
|
| 6341 |
$token = $self->_get_next_token; |
$token = $self->_get_next_token; |
| 6342 |
next B; |
next B; |
| 6343 |
} elsif ($token->{tag_name} eq 'link') { |
} elsif ($token->{tag_name} eq 'link') { |
| 6344 |
## NOTE: There is a "as if in head" code clone. |
## NOTE: There is a "as if in head" code clone. |
| 6345 |
if ($self->{insertion_mode} == AFTER_HEAD_IM) { |
if ($self->{insertion_mode} == AFTER_HEAD_IM) { |
| 6348 |
text => $token->{tag_name}, token => $token); |
text => $token->{tag_name}, token => $token); |
| 6349 |
push @{$self->{open_elements}}, |
push @{$self->{open_elements}}, |
| 6350 |
[$self->{head_element}, $el_category->{head}]; |
[$self->{head_element}, $el_category->{head}]; |
| 6351 |
|
$self->{head_element_inserted} = 1; |
| 6352 |
} else { |
} else { |
| 6353 |
|
|
| 6354 |
} |
} |
| 6429 |
|
|
| 6430 |
# |
# |
| 6431 |
} |
} |
| 6432 |
} elsif ($token->{tag_name} eq 'meta') { |
} elsif ($token->{tag_name} eq 'meta') { |
| 6433 |
## NOTE: There is a "as if in head" code clone. |
## NOTE: There is a "as if in head" code clone. |
| 6434 |
if ($self->{insertion_mode} == AFTER_HEAD_IM) { |
if ($self->{insertion_mode} == AFTER_HEAD_IM) { |
| 6435 |
|
|
| 6436 |
$self->{parse_error}->(level => $self->{level}->{must}, type => 'after head', |
$self->{parse_error}->(level => $self->{level}->{must}, type => 'after head', |
| 6437 |
text => $token->{tag_name}, token => $token); |
text => $token->{tag_name}, token => $token); |
| 6438 |
push @{$self->{open_elements}}, |
push @{$self->{open_elements}}, |
| 6439 |
[$self->{head_element}, $el_category->{head}]; |
[$self->{head_element}, $el_category->{head}]; |
| 6440 |
} else { |
$self->{head_element_inserted} = 1; |
| 6441 |
|
} else { |
| 6442 |
} |
|
| 6443 |
|
} |
| 6444 |
|
|
| 6445 |
{ |
{ |
| 6446 |
my $el; |
my $el; |
| 6447 |
|
|
| 6466 |
push @{$self->{open_elements}}, [$el, $el_category->{$token->{tag_name}} || 0]; |
push @{$self->{open_elements}}, [$el, $el_category->{$token->{tag_name}} || 0]; |
| 6467 |
} |
} |
| 6468 |
|
|
| 6469 |
my $meta_el = pop @{$self->{open_elements}}; |
my $meta_el = pop @{$self->{open_elements}}; |
| 6470 |
|
|
| 6471 |
unless ($self->{confident}) { |
unless ($self->{confident}) { |
| 6472 |
if ($token->{attributes}->{charset}) { |
if ($token->{attributes}->{charset}) { |
| 6524 |
delete $self->{self_closing}; |
delete $self->{self_closing}; |
| 6525 |
$token = $self->_get_next_token; |
$token = $self->_get_next_token; |
| 6526 |
next B; |
next B; |
| 6527 |
} elsif ($token->{tag_name} eq 'title') { |
} elsif ($token->{tag_name} eq 'title') { |
| 6528 |
if ($self->{insertion_mode} == IN_HEAD_NOSCRIPT_IM) { |
if ($self->{insertion_mode} == IN_HEAD_NOSCRIPT_IM) { |
| 6529 |
|
|
| 6530 |
## As if </noscript> |
## As if </noscript> |
| 6531 |
pop @{$self->{open_elements}}; |
pop @{$self->{open_elements}}; |
| 6532 |
$self->{parse_error}->(level => $self->{level}->{must}, type => 'in noscript', text => 'title', |
$self->{parse_error}->(level => $self->{level}->{must}, type => 'in noscript', text => 'title', |
| 6533 |
token => $token); |
token => $token); |
| 6534 |
|
|
| 6535 |
$self->{insertion_mode} = IN_HEAD_IM; |
$self->{insertion_mode} = IN_HEAD_IM; |
| 6536 |
## Reprocess in the "in head" insertion mode... |
## Reprocess in the "in head" insertion mode... |
| 6537 |
} elsif ($self->{insertion_mode} == AFTER_HEAD_IM) { |
} elsif ($self->{insertion_mode} == AFTER_HEAD_IM) { |
| 6538 |
|
|
| 6539 |
$self->{parse_error}->(level => $self->{level}->{must}, type => 'after head', |
$self->{parse_error}->(level => $self->{level}->{must}, type => 'after head', |
| 6540 |
text => $token->{tag_name}, token => $token); |
text => $token->{tag_name}, token => $token); |
| 6541 |
push @{$self->{open_elements}}, |
push @{$self->{open_elements}}, |
| 6542 |
[$self->{head_element}, $el_category->{head}]; |
[$self->{head_element}, $el_category->{head}]; |
| 6543 |
} else { |
$self->{head_element_inserted} = 1; |
| 6544 |
|
} else { |
| 6545 |
} |
|
| 6546 |
|
} |
| 6547 |
|
|
| 6548 |
## NOTE: There is a "as if in head" code clone. |
## NOTE: There is a "as if in head" code clone. |
| 6549 |
my $parent = defined $self->{head_element} ? $self->{head_element} |
$parse_rcdata->(RCDATA_CONTENT_MODEL); |
| 6550 |
: $self->{open_elements}->[-1]->[0]; |
pop @{$self->{open_elements}} # <head> |
| 6551 |
$parse_rcdata->(RCDATA_CONTENT_MODEL); |
if $self->{insertion_mode} == AFTER_HEAD_IM; |
| 6552 |
pop @{$self->{open_elements}} # <head> |
next B; |
| 6553 |
if $self->{insertion_mode} == AFTER_HEAD_IM; |
} elsif ($token->{tag_name} eq 'style' or |
| 6554 |
next B; |
$token->{tag_name} eq 'noframes') { |
| 6555 |
} elsif ($token->{tag_name} eq 'style' or |
## NOTE: Or (scripting is enabled and tag_name eq 'noscript' and |
| 6556 |
$token->{tag_name} eq 'noframes') { |
## insertion mode IN_HEAD_IM) |
| 6557 |
## NOTE: Or (scripting is enabled and tag_name eq 'noscript' and |
## NOTE: There is a "as if in head" code clone. |
| 6558 |
## insertion mode IN_HEAD_IM) |
if ($self->{insertion_mode} == AFTER_HEAD_IM) { |
| 6559 |
## NOTE: There is a "as if in head" code clone. |
|
| 6560 |
if ($self->{insertion_mode} == AFTER_HEAD_IM) { |
$self->{parse_error}->(level => $self->{level}->{must}, type => 'after head', |
| 6561 |
|
text => $token->{tag_name}, token => $token); |
| 6562 |
$self->{parse_error}->(level => $self->{level}->{must}, type => 'after head', |
push @{$self->{open_elements}}, |
| 6563 |
text => $token->{tag_name}, token => $token); |
[$self->{head_element}, $el_category->{head}]; |
| 6564 |
push @{$self->{open_elements}}, |
$self->{head_element_inserted} = 1; |
| 6565 |
[$self->{head_element}, $el_category->{head}]; |
} else { |
| 6566 |
} else { |
|
| 6567 |
|
} |
| 6568 |
} |
$parse_rcdata->(CDATA_CONTENT_MODEL); |
| 6569 |
$parse_rcdata->(CDATA_CONTENT_MODEL); |
pop @{$self->{open_elements}} # <head> |
| 6570 |
pop @{$self->{open_elements}} # <head> |
if $self->{insertion_mode} == AFTER_HEAD_IM; |
| 6571 |
if $self->{insertion_mode} == AFTER_HEAD_IM; |
next B; |
|
next B; |
|
| 6572 |
} elsif ($token->{tag_name} eq 'noscript') { |
} elsif ($token->{tag_name} eq 'noscript') { |
| 6573 |
if ($self->{insertion_mode} == IN_HEAD_IM) { |
if ($self->{insertion_mode} == IN_HEAD_IM) { |
| 6574 |
|
|
| 6614 |
|
|
| 6615 |
# |
# |
| 6616 |
} |
} |
| 6617 |
} elsif ($token->{tag_name} eq 'script') { |
} elsif ($token->{tag_name} eq 'script') { |
| 6618 |
if ($self->{insertion_mode} == IN_HEAD_NOSCRIPT_IM) { |
if ($self->{insertion_mode} == IN_HEAD_NOSCRIPT_IM) { |
| 6619 |
|
|
| 6620 |
## As if </noscript> |
## As if </noscript> |
| 6621 |
pop @{$self->{open_elements}}; |
pop @{$self->{open_elements}}; |
| 6622 |
$self->{parse_error}->(level => $self->{level}->{must}, type => 'in noscript', text => 'script', |
$self->{parse_error}->(level => $self->{level}->{must}, type => 'in noscript', text => 'script', |
| 6623 |
token => $token); |
token => $token); |
| 6624 |
|
|
| 6625 |
$self->{insertion_mode} = IN_HEAD_IM; |
$self->{insertion_mode} = IN_HEAD_IM; |
| 6626 |
## Reprocess in the "in head" insertion mode... |
## Reprocess in the "in head" insertion mode... |
| 6627 |
} elsif ($self->{insertion_mode} == AFTER_HEAD_IM) { |
} elsif ($self->{insertion_mode} == AFTER_HEAD_IM) { |
| 6628 |
|
|
| 6629 |
$self->{parse_error}->(level => $self->{level}->{must}, type => 'after head', |
$self->{parse_error}->(level => $self->{level}->{must}, type => 'after head', |
| 6630 |
text => $token->{tag_name}, token => $token); |
text => $token->{tag_name}, token => $token); |
| 6631 |
push @{$self->{open_elements}}, |
push @{$self->{open_elements}}, |
| 6632 |
[$self->{head_element}, $el_category->{head}]; |
[$self->{head_element}, $el_category->{head}]; |
| 6633 |
} else { |
$self->{head_element_inserted} = 1; |
| 6634 |
|
} else { |
| 6635 |
} |
|
| 6636 |
|
} |
| 6637 |
|
|
| 6638 |
## NOTE: There is a "as if in head" code clone. |
## NOTE: There is a "as if in head" code clone. |
| 6639 |
$script_start_tag->(); |
$script_start_tag->(); |
| 6640 |
pop @{$self->{open_elements}} # <head> |
pop @{$self->{open_elements}} # <head> |
| 6641 |
if $self->{insertion_mode} == AFTER_HEAD_IM; |
if $self->{insertion_mode} == AFTER_HEAD_IM; |
| 6642 |
next B; |
next B; |
| 6643 |
} elsif ($token->{tag_name} eq 'body' or |
} elsif ($token->{tag_name} eq 'body' or |
| 6644 |
$token->{tag_name} eq 'frameset') { |
$token->{tag_name} eq 'frameset') { |
| 6645 |
if ($self->{insertion_mode} == IN_HEAD_NOSCRIPT_IM) { |
if ($self->{insertion_mode} == IN_HEAD_NOSCRIPT_IM) { |
| 6646 |
|
|
| 6647 |
## As if </noscript> |
## As if </noscript> |
| 7434 |
|
|
| 7435 |
$self->{parse_error}->(level => $self->{level}->{must}, type => 'in table:#text', token => $token); |
$self->{parse_error}->(level => $self->{level}->{must}, type => 'in table:#text', token => $token); |
| 7436 |
|
|
| 7437 |
## As if in body, but insert into foster parent element |
## NOTE: As if in body, but insert into the foster parent element. |
| 7438 |
## ISSUE: Spec says that "whenever a node would be inserted |
$reconstruct_active_formatting_elements->($insert_to_foster); |
| 7439 |
## into the current node" while characters might not be |
|
| 7440 |
## result in a new Text node. |
if ($self->{open_elements}->[-1]->[1] & TABLE_ROWS_EL) { |
| 7441 |
$reconstruct_active_formatting_elements->($insert_to_foster); |
# MUST |
| 7442 |
|
my $foster_parent_element; |
| 7443 |
if ($self->{open_elements}->[-1]->[1] & TABLE_ROWS_EL) { |
my $next_sibling; |
| 7444 |
# MUST |
my $prev_sibling; |
| 7445 |
my $foster_parent_element; |
OE: for (reverse 0..$#{$self->{open_elements}}) { |
| 7446 |
my $next_sibling; |
if ($self->{open_elements}->[$_]->[1] & TABLE_EL) { |
| 7447 |
my $prev_sibling; |
my $parent = $self->{open_elements}->[$_]->[0]->parent_node; |
| 7448 |
OE: for (reverse 0..$#{$self->{open_elements}}) { |
if (defined $parent and $parent->node_type == 1) { |
| 7449 |
if ($self->{open_elements}->[$_]->[1] & TABLE_EL) { |
$foster_parent_element = $parent; |
|
my $parent = $self->{open_elements}->[$_]->[0]->parent_node; |
|
|
if (defined $parent and $parent->node_type == 1) { |
|
|
|
|
|
$foster_parent_element = $parent; |
|
|
$next_sibling = $self->{open_elements}->[$_]->[0]; |
|
|
$prev_sibling = $next_sibling->previous_sibling; |
|
|
} else { |
|
|
|
|
|
$foster_parent_element = $self->{open_elements}->[$_ - 1]->[0]; |
|
|
$prev_sibling = $foster_parent_element->last_child; |
|
|
} |
|
|
last OE; |
|
|
} |
|
|
} # OE |
|
|
$foster_parent_element = $self->{open_elements}->[0]->[0] and |
|
|
$prev_sibling = $foster_parent_element->last_child |
|
|
unless defined $foster_parent_element; |
|
|
if (defined $prev_sibling and |
|
|
$prev_sibling->node_type == 3) { |
|
| 7450 |
|
|
| 7451 |
$prev_sibling->manakai_append_text ($token->{data}); |
$next_sibling = $self->{open_elements}->[$_]->[0]; |
| 7452 |
|
$prev_sibling = $next_sibling->previous_sibling; |
| 7453 |
|
# |
| 7454 |
} else { |
} else { |
| 7455 |
|
|
| 7456 |
$foster_parent_element->insert_before |
$foster_parent_element = $self->{open_elements}->[$_ - 1]->[0]; |
| 7457 |
($self->{document}->create_text_node ($token->{data}), |
$prev_sibling = $foster_parent_element->last_child; |
| 7458 |
$next_sibling); |
# |
| 7459 |
} |
} |
| 7460 |
|
last OE; |
| 7461 |
|
} |
| 7462 |
|
} # OE |
| 7463 |
|
$foster_parent_element = $self->{open_elements}->[0]->[0] and |
| 7464 |
|
$prev_sibling = $foster_parent_element->last_child |
| 7465 |
|
unless defined $foster_parent_element; |
| 7466 |
|
undef $prev_sibling unless $open_tables->[-1]->[2]; # ~node inserted |
| 7467 |
|
if (defined $prev_sibling and |
| 7468 |
|
$prev_sibling->node_type == 3) { |
| 7469 |
|
|
| 7470 |
|
$prev_sibling->manakai_append_text ($token->{data}); |
| 7471 |
|
} else { |
| 7472 |
|
|
| 7473 |
|
$foster_parent_element->insert_before |
| 7474 |
|
($self->{document}->create_text_node ($token->{data}), |
| 7475 |
|
$next_sibling); |
| 7476 |
|
} |
| 7477 |
$open_tables->[-1]->[1] = 1; # tainted |
$open_tables->[-1]->[1] = 1; # tainted |
| 7478 |
|
$open_tables->[-1]->[2] = 1; # ~node inserted |
| 7479 |
} else { |
} else { |
| 7480 |
|
## NOTE: Fragment case or in a foster parent'ed element |
| 7481 |
|
## (e.g. |<table><span>a|). In fragment case, whether the |
| 7482 |
|
## character is appended to existing node or a new node is |
| 7483 |
|
## created is irrelevant, since the foster parent'ed nodes |
| 7484 |
|
## are discarded and fragment parsing does not invoke any |
| 7485 |
|
## script. |
| 7486 |
|
|
| 7487 |
$self->{open_elements}->[-1]->[0]->manakai_append_text ($token->{data}); |
$self->{open_elements}->[-1]->[0]->manakai_append_text |
| 7488 |
|
($token->{data}); |
| 7489 |
} |
} |
| 7490 |
|
|
| 7491 |
$token = $self->_get_next_token; |
$token = $self->_get_next_token; |
| 7537 |
pop @{$self->{open_elements}}; |
pop @{$self->{open_elements}}; |
| 7538 |
} |
} |
| 7539 |
|
|
| 7540 |
$self->{insertion_mode} = IN_ROW_IM; |
$self->{insertion_mode} = IN_ROW_IM; |
| 7541 |
if ($token->{tag_name} eq 'tr') { |
if ($token->{tag_name} eq 'tr') { |
| 7542 |
|
|
| 7543 |
|
|
| 7544 |
{ |
{ |
| 7545 |
my $el; |
my $el; |
| 7546 |
|
|
| 7565 |
push @{$self->{open_elements}}, [$el, $el_category->{$token->{tag_name}} || 0]; |
push @{$self->{open_elements}}, [$el, $el_category->{$token->{tag_name}} || 0]; |
| 7566 |
} |
} |
| 7567 |
|
|
| 7568 |
|
$open_tables->[-1]->[2] = 0 if @$open_tables; # ~node inserted |
| 7569 |
$token = $self->_get_next_token; |
|
| 7570 |
next B; |
$token = $self->_get_next_token; |
| 7571 |
} else { |
next B; |
| 7572 |
|
} else { |
| 7573 |
|
|
| 7574 |
|
|
| 7575 |
{ |
{ |
| 7576 |
my $el; |
my $el; |
| 7577 |
|
|
| 7587 |
push @{$self->{open_elements}}, [$el, $el_category->{'tr'} || 0]; |
push @{$self->{open_elements}}, [$el, $el_category->{'tr'} || 0]; |
| 7588 |
} |
} |
| 7589 |
|
|
| 7590 |
## reprocess in the "in row" insertion mode |
## reprocess in the "in row" insertion mode |
| 7591 |
} |
} |
| 7592 |
} else { |
} else { |
| 7593 |
|
|
| 7594 |
} |
} |
| 7595 |
|
|
| 7596 |
## Clear back to table row context |
## Clear back to table row context |
| 7597 |
while (not ($self->{open_elements}->[-1]->[1] |
while (not ($self->{open_elements}->[-1]->[1] |
| 7600 |
pop @{$self->{open_elements}}; |
pop @{$self->{open_elements}}; |
| 7601 |
} |
} |
| 7602 |
|
|
| 7603 |
|
|
| 7604 |
{ |
{ |
| 7605 |
my $el; |
my $el; |
| 7606 |
|
|
| 7625 |
push @{$self->{open_elements}}, [$el, $el_category->{$token->{tag_name}} || 0]; |
push @{$self->{open_elements}}, [$el, $el_category->{$token->{tag_name}} || 0]; |
| 7626 |
} |
} |
| 7627 |
|
|
| 7628 |
$self->{insertion_mode} = IN_CELL_IM; |
$open_tables->[-1]->[2] = 0 if @$open_tables; # ~node inserted |
| 7629 |
|
$self->{insertion_mode} = IN_CELL_IM; |
| 7630 |
|
|
| 7631 |
push @$active_formatting_elements, ['#marker', '']; |
push @$active_formatting_elements, ['#marker', '']; |
| 7632 |
|
|
| 7633 |
|
|
| 7634 |
|
$token = $self->_get_next_token; |
| 7635 |
|
next B; |
| 7636 |
|
} elsif ({ |
| 7637 |
|
caption => 1, col => 1, colgroup => 1, |
| 7638 |
|
tbody => 1, tfoot => 1, thead => 1, |
| 7639 |
|
tr => 1, # $self->{insertion_mode} == IN_ROW_IM |
| 7640 |
|
}->{$token->{tag_name}}) { |
| 7641 |
|
if ($self->{insertion_mode} == IN_ROW_IM) { |
| 7642 |
|
## As if </tr> |
| 7643 |
|
## have an element in table scope |
| 7644 |
|
my $i; |
| 7645 |
|
INSCOPE: for (reverse 0..$#{$self->{open_elements}}) { |
| 7646 |
|
my $node = $self->{open_elements}->[$_]; |
| 7647 |
|
if ($node->[1] & TABLE_ROW_EL) { |
| 7648 |
|
|
| 7649 |
|
$i = $_; |
| 7650 |
|
last INSCOPE; |
| 7651 |
|
} elsif ($node->[1] & TABLE_SCOPING_EL) { |
| 7652 |
|
|
| 7653 |
|
last INSCOPE; |
| 7654 |
|
} |
| 7655 |
|
} # INSCOPE |
| 7656 |
|
unless (defined $i) { |
| 7657 |
|
|
| 7658 |
|
## TODO: This type is wrong. |
| 7659 |
|
$self->{parse_error}->(level => $self->{level}->{must}, type => 'unmacthed end tag', |
| 7660 |
|
text => $token->{tag_name}, token => $token); |
| 7661 |
|
## Ignore the token |
| 7662 |
|
|
| 7663 |
$token = $self->_get_next_token; |
$token = $self->_get_next_token; |
| 7664 |
next B; |
next B; |
| 7665 |
} elsif ({ |
} |
|
caption => 1, col => 1, colgroup => 1, |
|
|
tbody => 1, tfoot => 1, thead => 1, |
|
|
tr => 1, # $self->{insertion_mode} == IN_ROW_IM |
|
|
}->{$token->{tag_name}}) { |
|
|
if ($self->{insertion_mode} == IN_ROW_IM) { |
|
|
## As if </tr> |
|
|
## have an element in table scope |
|
|
my $i; |
|
|
INSCOPE: for (reverse 0..$#{$self->{open_elements}}) { |
|
|
my $node = $self->{open_elements}->[$_]; |
|
|
if ($node->[1] & TABLE_ROW_EL) { |
|
|
|
|
|
$i = $_; |
|
|
last INSCOPE; |
|
|
} elsif ($node->[1] & TABLE_SCOPING_EL) { |
|
|
|
|
|
last INSCOPE; |
|
|
} |
|
|
} # INSCOPE |
|
|
unless (defined $i) { |
|
|
|
|
|
## TODO: This type is wrong. |
|
|
$self->{parse_error}->(level => $self->{level}->{must}, type => 'unmacthed end tag', |
|
|
text => $token->{tag_name}, token => $token); |
|
|
## Ignore the token |
|
|
|
|
|
$token = $self->_get_next_token; |
|
|
next B; |
|
|
} |
|
| 7666 |
|
|
| 7667 |
## Clear back to table row context |
## Clear back to table row context |
| 7668 |
while (not ($self->{open_elements}->[-1]->[1] |
while (not ($self->{open_elements}->[-1]->[1] |
| 7732 |
|
|
| 7733 |
} |
} |
| 7734 |
|
|
| 7735 |
if ($token->{tag_name} eq 'col') { |
if ($token->{tag_name} eq 'col') { |
| 7736 |
## Clear back to table context |
## Clear back to table context |
| 7737 |
while (not ($self->{open_elements}->[-1]->[1] |
while (not ($self->{open_elements}->[-1]->[1] |
| 7738 |
& TABLE_SCOPING_EL)) { |
& TABLE_SCOPING_EL)) { |
| 7739 |
|
|
| 7740 |
## ISSUE: Can this state be reached? |
## ISSUE: Can this state be reached? |
| 7741 |
pop @{$self->{open_elements}}; |
pop @{$self->{open_elements}}; |
| 7742 |
} |
} |
| 7743 |
|
|
| 7744 |
|
|
| 7745 |
{ |
{ |
| 7746 |
my $el; |
my $el; |
| 7747 |
|
|
| 7757 |
push @{$self->{open_elements}}, [$el, $el_category->{'colgroup'} || 0]; |
push @{$self->{open_elements}}, [$el, $el_category->{'colgroup'} || 0]; |
| 7758 |
} |
} |
| 7759 |
|
|
| 7760 |
$self->{insertion_mode} = IN_COLUMN_GROUP_IM; |
$self->{insertion_mode} = IN_COLUMN_GROUP_IM; |
| 7761 |
## reprocess |
## reprocess |
| 7762 |
|
$open_tables->[-1]->[2] = 0 if @$open_tables; # ~node inserted |
| 7763 |
next B; |
|
| 7764 |
} elsif ({ |
next B; |
| 7765 |
caption => 1, |
} elsif ({ |
| 7766 |
colgroup => 1, |
caption => 1, |
| 7767 |
tbody => 1, tfoot => 1, thead => 1, |
colgroup => 1, |
| 7768 |
}->{$token->{tag_name}}) { |
tbody => 1, tfoot => 1, thead => 1, |
| 7769 |
## Clear back to table context |
}->{$token->{tag_name}}) { |
| 7770 |
|
## Clear back to table context |
| 7771 |
while (not ($self->{open_elements}->[-1]->[1] |
while (not ($self->{open_elements}->[-1]->[1] |
| 7772 |
& TABLE_SCOPING_EL)) { |
& TABLE_SCOPING_EL)) { |
| 7773 |
|
|
| 7775 |
pop @{$self->{open_elements}}; |
pop @{$self->{open_elements}}; |
| 7776 |
} |
} |
| 7777 |
|
|
| 7778 |
push @$active_formatting_elements, ['#marker', ''] |
push @$active_formatting_elements, ['#marker', ''] |
| 7779 |
if $token->{tag_name} eq 'caption'; |
if $token->{tag_name} eq 'caption'; |
|
|
|
| 7780 |
|
|
| 7781 |
|
|
| 7782 |
{ |
{ |
| 7783 |
my $el; |
my $el; |
| 7784 |
|
|
| 7803 |
push @{$self->{open_elements}}, [$el, $el_category->{$token->{tag_name}} || 0]; |
push @{$self->{open_elements}}, [$el, $el_category->{$token->{tag_name}} || 0]; |
| 7804 |
} |
} |
| 7805 |
|
|
| 7806 |
$self->{insertion_mode} = { |
$open_tables->[-1]->[2] = 0 if @$open_tables; # ~node inserted |
| 7807 |
caption => IN_CAPTION_IM, |
$self->{insertion_mode} = { |
| 7808 |
colgroup => IN_COLUMN_GROUP_IM, |
caption => IN_CAPTION_IM, |
| 7809 |
tbody => IN_TABLE_BODY_IM, |
colgroup => IN_COLUMN_GROUP_IM, |
| 7810 |
tfoot => IN_TABLE_BODY_IM, |
tbody => IN_TABLE_BODY_IM, |
| 7811 |
thead => IN_TABLE_BODY_IM, |
tfoot => IN_TABLE_BODY_IM, |
| 7812 |
}->{$token->{tag_name}}; |
thead => IN_TABLE_BODY_IM, |
| 7813 |
$token = $self->_get_next_token; |
}->{$token->{tag_name}}; |
| 7814 |
|
$token = $self->_get_next_token; |
| 7815 |
next B; |
|
| 7816 |
} else { |
next B; |
| 7817 |
die "$0: in table: <>: $token->{tag_name}"; |
} else { |
| 7818 |
} |
die "$0: in table: <>: $token->{tag_name}"; |
| 7819 |
|
} |
| 7820 |
} elsif ($token->{tag_name} eq 'table') { |
} elsif ($token->{tag_name} eq 'table') { |
| 7821 |
$self->{parse_error}->(level => $self->{level}->{must}, type => 'not closed', |
$self->{parse_error}->(level => $self->{level}->{must}, type => 'not closed', |
| 7822 |
text => $self->{open_elements}->[-1]->[0] |
text => $self->{open_elements}->[-1]->[0] |
| 7879 |
|
|
| 7880 |
## NOTE: This is a "as if in head" code clone. |
## NOTE: This is a "as if in head" code clone. |
| 7881 |
$parse_rcdata->(CDATA_CONTENT_MODEL); |
$parse_rcdata->(CDATA_CONTENT_MODEL); |
| 7882 |
|
$open_tables->[-1]->[2] = 0 if @$open_tables; # ~node inserted |
| 7883 |
next B; |
next B; |
| 7884 |
} else { |
} else { |
| 7885 |
|
|
| 7890 |
|
|
| 7891 |
## NOTE: This is a "as if in head" code clone. |
## NOTE: This is a "as if in head" code clone. |
| 7892 |
$script_start_tag->(); |
$script_start_tag->(); |
| 7893 |
|
$open_tables->[-1]->[2] = 0 if @$open_tables; # ~node inserted |
| 7894 |
next B; |
next B; |
| 7895 |
} else { |
} else { |
| 7896 |
|
|
| 7930 |
push @{$self->{open_elements}}, [$el, $el_category->{$token->{tag_name}} || 0]; |
push @{$self->{open_elements}}, [$el, $el_category->{$token->{tag_name}} || 0]; |
| 7931 |
} |
} |
| 7932 |
|
|
| 7933 |
|
$open_tables->[-1]->[2] = 0 if @$open_tables; # ~node inserted |
| 7934 |
|
|
| 7935 |
## TODO: form element pointer |
## TODO: form element pointer |
| 7936 |
|
|
| 10752 |
push @{$p->{open_elements}}, [$root, $el_category->{html}]; |
push @{$p->{open_elements}}, [$root, $el_category->{html}]; |
| 10753 |
|
|
| 10754 |
undef $p->{head_element}; |
undef $p->{head_element}; |
| 10755 |
|
undef $p->{head_element_inserted}; |
| 10756 |
|
|
| 10757 |
## Step 6 # MUST |
## Step 6 # MUST |
| 10758 |
$p->_reset_insertion_mode; |
$p->_reset_insertion_mode; |