| 2987 |
redo A; |
redo A; |
| 2988 |
} elsif ($self->{nc} == -1) { |
} elsif ($self->{nc} == -1) { |
| 2989 |
!!!cp (220); |
!!!cp (220); |
|
!!!parse-error (type => 'unclosed DOCTYPE'); |
|
| 2990 |
$self->{state} = DATA_STATE; |
$self->{state} = DATA_STATE; |
| 2991 |
## reconsume |
## reconsume |
| 2992 |
|
|
| 3466 |
## When an interactive UA render the $self->{document} available |
## When an interactive UA render the $self->{document} available |
| 3467 |
## to the user, or when it begin accepting user input, are |
## to the user, or when it begin accepting user input, are |
| 3468 |
## not defined. |
## not defined. |
|
|
|
|
## Append a character: collect it and all subsequent consecutive |
|
|
## characters and insert one Text node whose data is concatenation |
|
|
## of all those characters. # MUST |
|
| 3469 |
|
|
| 3470 |
!!!next-token; |
!!!next-token; |
| 3471 |
|
|
| 3472 |
undef $self->{form_element}; |
undef $self->{form_element}; |
| 3473 |
undef $self->{head_element}; |
undef $self->{head_element}; |
| 3474 |
|
undef $self->{head_element_inserted}; |
| 3475 |
$self->{open_elements} = []; |
$self->{open_elements} = []; |
| 3476 |
undef $self->{inner_html_node}; |
undef $self->{inner_html_node}; |
| 3477 |
|
|
| 4079 |
|
|
| 4080 |
## NOTE: $open_tables->[-1]->[0] is the "current table" element node. |
## NOTE: $open_tables->[-1]->[0] is the "current table" element node. |
| 4081 |
## NOTE: $open_tables->[-1]->[1] is the "tainted" flag. |
## NOTE: $open_tables->[-1]->[1] is the "tainted" flag. |
| 4082 |
|
## NOTE: $open_tables->[-1]->[2] is set false when non-Text node inserted. |
| 4083 |
my $open_tables = [[$self->{open_elements}->[0]->[0]]]; |
my $open_tables = [[$self->{open_elements}->[0]->[0]]]; |
| 4084 |
|
|
| 4085 |
my $formatting_end_tag = sub { |
my $formatting_end_tag = sub { |
| 4164 |
!!!cp ('t59'); |
!!!cp ('t59'); |
| 4165 |
$furthest_block = $node; |
$furthest_block = $node; |
| 4166 |
$furthest_block_i_in_open = $_; |
$furthest_block_i_in_open = $_; |
| 4167 |
|
## NOTE: The topmost (eldest) node. |
| 4168 |
} elsif ($node->[0] eq $formatting_element->[0]) { |
} elsif ($node->[0] eq $formatting_element->[0]) { |
| 4169 |
!!!cp ('t60'); |
!!!cp ('t60'); |
| 4170 |
last OE; |
last OE; |
| 4311 |
$i = $_; |
$i = $_; |
| 4312 |
} |
} |
| 4313 |
} # OE |
} # OE |
| 4314 |
splice @{$self->{open_elements}}, $i + 1, 1, $clone; |
splice @{$self->{open_elements}}, $i + 1, 0, $clone; |
| 4315 |
|
|
| 4316 |
## Step 14 |
## Step 14 |
| 4317 |
redo FET; |
redo FET; |
| 4354 |
} |
} |
| 4355 |
}; # $insert_to_foster |
}; # $insert_to_foster |
| 4356 |
|
|
| 4357 |
|
## NOTE: Insert a character (MUST): When a character is inserted, if |
| 4358 |
|
## the last node that was inserted by the parser is a Text node and |
| 4359 |
|
## the character has to be inserted after that node, then the |
| 4360 |
|
## character is appended to the Text node. However, if any other |
| 4361 |
|
## node is inserted by the parser, then a new Text node is created |
| 4362 |
|
## and the character is appended as that Text node. If I'm not |
| 4363 |
|
## wrong, for a parser with scripting disabled, there are only two |
| 4364 |
|
## cases where this occurs. One is the case where an element node |
| 4365 |
|
## is inserted to the |head| element. This is covered by using the |
| 4366 |
|
## |$self->{head_element_inserted}| flag. Another is the case where |
| 4367 |
|
## an element or comment is inserted into the |table| subtree while |
| 4368 |
|
## foster parenting happens. This is covered by using the [2] flag |
| 4369 |
|
## of the |$open_tables| structure. All other cases are handled |
| 4370 |
|
## simply by calling |manakai_append_text| method. |
| 4371 |
|
|
| 4372 |
|
## TODO: |<body><script>document.write("a<br>"); |
| 4373 |
|
## document.body.removeChild (document.body.lastChild); |
| 4374 |
|
## document.write ("b")</script>| |
| 4375 |
|
|
| 4376 |
B: while (1) { |
B: while (1) { |
| 4377 |
if ($token->{type} == DOCTYPE_TOKEN) { |
if ($token->{type} == DOCTYPE_TOKEN) { |
| 4378 |
!!!cp ('t73'); |
!!!cp ('t73'); |
| 4420 |
} else { |
} else { |
| 4421 |
!!!cp ('t87'); |
!!!cp ('t87'); |
| 4422 |
$self->{open_elements}->[-1]->[0]->append_child ($comment); |
$self->{open_elements}->[-1]->[0]->append_child ($comment); |
| 4423 |
|
$open_tables->[-1]->[2] = 0 if @$open_tables; # ~node inserted |
| 4424 |
} |
} |
| 4425 |
!!!next-token; |
!!!next-token; |
| 4426 |
next B; |
next B; |
| 4550 |
if ($token->{type} == CHARACTER_TOKEN) { |
if ($token->{type} == CHARACTER_TOKEN) { |
| 4551 |
if ($token->{data} =~ s/^([\x09\x0A\x0C\x20]+)//) { |
if ($token->{data} =~ s/^([\x09\x0A\x0C\x20]+)//) { |
| 4552 |
unless ($self->{insertion_mode} == BEFORE_HEAD_IM) { |
unless ($self->{insertion_mode} == BEFORE_HEAD_IM) { |
| 4553 |
!!!cp ('t88.2'); |
if ($self->{head_element_inserted}) { |
| 4554 |
$self->{open_elements}->[-1]->[0]->manakai_append_text ($1); |
!!!cp ('t88.3'); |
| 4555 |
# |
$self->{open_elements}->[-1]->[0]->append_child |
| 4556 |
|
($self->{document}->create_text_node ($1)); |
| 4557 |
|
delete $self->{head_element_inserted}; |
| 4558 |
|
## NOTE: |</head> <link> | |
| 4559 |
|
# |
| 4560 |
|
} else { |
| 4561 |
|
!!!cp ('t88.2'); |
| 4562 |
|
$self->{open_elements}->[-1]->[0]->manakai_append_text ($1); |
| 4563 |
|
## NOTE: |</head>  | |
| 4564 |
|
# |
| 4565 |
|
} |
| 4566 |
} else { |
} else { |
| 4567 |
!!!cp ('t88.1'); |
!!!cp ('t88.1'); |
| 4568 |
## Ignore the token. |
## Ignore the token. |
| 4658 |
!!!cp ('t97'); |
!!!cp ('t97'); |
| 4659 |
} |
} |
| 4660 |
|
|
| 4661 |
if ($token->{tag_name} eq 'base') { |
if ($token->{tag_name} eq 'base') { |
| 4662 |
if ($self->{insertion_mode} == IN_HEAD_NOSCRIPT_IM) { |
if ($self->{insertion_mode} == IN_HEAD_NOSCRIPT_IM) { |
| 4663 |
!!!cp ('t98'); |
!!!cp ('t98'); |
| 4664 |
## As if </noscript> |
## As if </noscript> |
| 4665 |
pop @{$self->{open_elements}}; |
pop @{$self->{open_elements}}; |
| 4666 |
!!!parse-error (type => 'in noscript', text => 'base', |
!!!parse-error (type => 'in noscript', text => 'base', |
| 4667 |
token => $token); |
token => $token); |
| 4668 |
|
|
| 4669 |
$self->{insertion_mode} = IN_HEAD_IM; |
$self->{insertion_mode} = IN_HEAD_IM; |
| 4670 |
## Reprocess in the "in head" insertion mode... |
## Reprocess in the "in head" insertion mode... |
| 4671 |
} else { |
} else { |
| 4672 |
!!!cp ('t99'); |
!!!cp ('t99'); |
| 4673 |
} |
} |
| 4674 |
|
|
| 4675 |
## NOTE: There is a "as if in head" code clone. |
## NOTE: There is a "as if in head" code clone. |
| 4676 |
if ($self->{insertion_mode} == AFTER_HEAD_IM) { |
if ($self->{insertion_mode} == AFTER_HEAD_IM) { |
| 4677 |
!!!cp ('t100'); |
!!!cp ('t100'); |
| 4678 |
!!!parse-error (type => 'after head', |
!!!parse-error (type => 'after head', |
| 4679 |
text => $token->{tag_name}, token => $token); |
text => $token->{tag_name}, token => $token); |
| 4680 |
push @{$self->{open_elements}}, |
push @{$self->{open_elements}}, |
| 4681 |
[$self->{head_element}, $el_category->{head}]; |
[$self->{head_element}, $el_category->{head}]; |
| 4682 |
} else { |
$self->{head_element_inserted} = 1; |
| 4683 |
!!!cp ('t101'); |
} else { |
| 4684 |
} |
!!!cp ('t101'); |
| 4685 |
!!!insert-element ($token->{tag_name}, $token->{attributes}, $token); |
} |
| 4686 |
pop @{$self->{open_elements}}; |
!!!insert-element ($token->{tag_name}, $token->{attributes}, $token); |
| 4687 |
pop @{$self->{open_elements}} # <head> |
pop @{$self->{open_elements}}; |
| 4688 |
if $self->{insertion_mode} == AFTER_HEAD_IM; |
pop @{$self->{open_elements}} # <head> |
| 4689 |
!!!nack ('t101.1'); |
if $self->{insertion_mode} == AFTER_HEAD_IM; |
| 4690 |
!!!next-token; |
!!!nack ('t101.1'); |
| 4691 |
next B; |
!!!next-token; |
| 4692 |
|
next B; |
| 4693 |
} elsif ($token->{tag_name} eq 'link') { |
} elsif ($token->{tag_name} eq 'link') { |
| 4694 |
## NOTE: There is a "as if in head" code clone. |
## NOTE: There is a "as if in head" code clone. |
| 4695 |
if ($self->{insertion_mode} == AFTER_HEAD_IM) { |
if ($self->{insertion_mode} == AFTER_HEAD_IM) { |
| 4698 |
text => $token->{tag_name}, token => $token); |
text => $token->{tag_name}, token => $token); |
| 4699 |
push @{$self->{open_elements}}, |
push @{$self->{open_elements}}, |
| 4700 |
[$self->{head_element}, $el_category->{head}]; |
[$self->{head_element}, $el_category->{head}]; |
| 4701 |
|
$self->{head_element_inserted} = 1; |
| 4702 |
} else { |
} else { |
| 4703 |
!!!cp ('t103'); |
!!!cp ('t103'); |
| 4704 |
} |
} |
| 4731 |
!!!cp ('t103.3'); |
!!!cp ('t103.3'); |
| 4732 |
# |
# |
| 4733 |
} |
} |
| 4734 |
} elsif ($token->{tag_name} eq 'meta') { |
} elsif ($token->{tag_name} eq 'meta') { |
| 4735 |
## NOTE: There is a "as if in head" code clone. |
## NOTE: There is a "as if in head" code clone. |
| 4736 |
if ($self->{insertion_mode} == AFTER_HEAD_IM) { |
if ($self->{insertion_mode} == AFTER_HEAD_IM) { |
| 4737 |
!!!cp ('t104'); |
!!!cp ('t104'); |
| 4738 |
!!!parse-error (type => 'after head', |
!!!parse-error (type => 'after head', |
| 4739 |
text => $token->{tag_name}, token => $token); |
text => $token->{tag_name}, token => $token); |
| 4740 |
push @{$self->{open_elements}}, |
push @{$self->{open_elements}}, |
| 4741 |
[$self->{head_element}, $el_category->{head}]; |
[$self->{head_element}, $el_category->{head}]; |
| 4742 |
} else { |
$self->{head_element_inserted} = 1; |
| 4743 |
!!!cp ('t105'); |
} else { |
| 4744 |
} |
!!!cp ('t105'); |
| 4745 |
!!!insert-element ($token->{tag_name}, $token->{attributes}, $token); |
} |
| 4746 |
my $meta_el = pop @{$self->{open_elements}}; |
!!!insert-element ($token->{tag_name}, $token->{attributes}, $token); |
| 4747 |
|
my $meta_el = pop @{$self->{open_elements}}; |
| 4748 |
|
|
| 4749 |
unless ($self->{confident}) { |
unless ($self->{confident}) { |
| 4750 |
if ($token->{attributes}->{charset}) { |
if ($token->{attributes}->{charset}) { |
| 4802 |
!!!ack ('t110.1'); |
!!!ack ('t110.1'); |
| 4803 |
!!!next-token; |
!!!next-token; |
| 4804 |
next B; |
next B; |
| 4805 |
} elsif ($token->{tag_name} eq 'title') { |
} elsif ($token->{tag_name} eq 'title') { |
| 4806 |
if ($self->{insertion_mode} == IN_HEAD_NOSCRIPT_IM) { |
if ($self->{insertion_mode} == IN_HEAD_NOSCRIPT_IM) { |
| 4807 |
!!!cp ('t111'); |
!!!cp ('t111'); |
| 4808 |
## As if </noscript> |
## As if </noscript> |
| 4809 |
pop @{$self->{open_elements}}; |
pop @{$self->{open_elements}}; |
| 4810 |
!!!parse-error (type => 'in noscript', text => 'title', |
!!!parse-error (type => 'in noscript', text => 'title', |
| 4811 |
token => $token); |
token => $token); |
| 4812 |
|
|
| 4813 |
$self->{insertion_mode} = IN_HEAD_IM; |
$self->{insertion_mode} = IN_HEAD_IM; |
| 4814 |
## Reprocess in the "in head" insertion mode... |
## Reprocess in the "in head" insertion mode... |
| 4815 |
} elsif ($self->{insertion_mode} == AFTER_HEAD_IM) { |
} elsif ($self->{insertion_mode} == AFTER_HEAD_IM) { |
| 4816 |
!!!cp ('t112'); |
!!!cp ('t112'); |
| 4817 |
!!!parse-error (type => 'after head', |
!!!parse-error (type => 'after head', |
| 4818 |
text => $token->{tag_name}, token => $token); |
text => $token->{tag_name}, token => $token); |
| 4819 |
push @{$self->{open_elements}}, |
push @{$self->{open_elements}}, |
| 4820 |
[$self->{head_element}, $el_category->{head}]; |
[$self->{head_element}, $el_category->{head}]; |
| 4821 |
} else { |
$self->{head_element_inserted} = 1; |
| 4822 |
!!!cp ('t113'); |
} else { |
| 4823 |
} |
!!!cp ('t113'); |
| 4824 |
|
} |
| 4825 |
|
|
| 4826 |
## NOTE: There is a "as if in head" code clone. |
## NOTE: There is a "as if in head" code clone. |
| 4827 |
my $parent = defined $self->{head_element} ? $self->{head_element} |
$parse_rcdata->(RCDATA_CONTENT_MODEL); |
| 4828 |
: $self->{open_elements}->[-1]->[0]; |
pop @{$self->{open_elements}} # <head> |
| 4829 |
$parse_rcdata->(RCDATA_CONTENT_MODEL); |
if $self->{insertion_mode} == AFTER_HEAD_IM; |
| 4830 |
pop @{$self->{open_elements}} # <head> |
next B; |
| 4831 |
if $self->{insertion_mode} == AFTER_HEAD_IM; |
} elsif ($token->{tag_name} eq 'style' or |
| 4832 |
next B; |
$token->{tag_name} eq 'noframes') { |
| 4833 |
} elsif ($token->{tag_name} eq 'style' or |
## NOTE: Or (scripting is enabled and tag_name eq 'noscript' and |
| 4834 |
$token->{tag_name} eq 'noframes') { |
## insertion mode IN_HEAD_IM) |
| 4835 |
## NOTE: Or (scripting is enabled and tag_name eq 'noscript' and |
## NOTE: There is a "as if in head" code clone. |
| 4836 |
## insertion mode IN_HEAD_IM) |
if ($self->{insertion_mode} == AFTER_HEAD_IM) { |
| 4837 |
## NOTE: There is a "as if in head" code clone. |
!!!cp ('t114'); |
| 4838 |
if ($self->{insertion_mode} == AFTER_HEAD_IM) { |
!!!parse-error (type => 'after head', |
| 4839 |
!!!cp ('t114'); |
text => $token->{tag_name}, token => $token); |
| 4840 |
!!!parse-error (type => 'after head', |
push @{$self->{open_elements}}, |
| 4841 |
text => $token->{tag_name}, token => $token); |
[$self->{head_element}, $el_category->{head}]; |
| 4842 |
push @{$self->{open_elements}}, |
$self->{head_element_inserted} = 1; |
| 4843 |
[$self->{head_element}, $el_category->{head}]; |
} else { |
| 4844 |
} else { |
!!!cp ('t115'); |
| 4845 |
!!!cp ('t115'); |
} |
| 4846 |
} |
$parse_rcdata->(CDATA_CONTENT_MODEL); |
| 4847 |
$parse_rcdata->(CDATA_CONTENT_MODEL); |
pop @{$self->{open_elements}} # <head> |
| 4848 |
pop @{$self->{open_elements}} # <head> |
if $self->{insertion_mode} == AFTER_HEAD_IM; |
| 4849 |
if $self->{insertion_mode} == AFTER_HEAD_IM; |
next B; |
|
next B; |
|
| 4850 |
} elsif ($token->{tag_name} eq 'noscript') { |
} elsif ($token->{tag_name} eq 'noscript') { |
| 4851 |
if ($self->{insertion_mode} == IN_HEAD_IM) { |
if ($self->{insertion_mode} == IN_HEAD_IM) { |
| 4852 |
!!!cp ('t116'); |
!!!cp ('t116'); |
| 4868 |
!!!cp ('t118'); |
!!!cp ('t118'); |
| 4869 |
# |
# |
| 4870 |
} |
} |
| 4871 |
} elsif ($token->{tag_name} eq 'script') { |
} elsif ($token->{tag_name} eq 'script') { |
| 4872 |
if ($self->{insertion_mode} == IN_HEAD_NOSCRIPT_IM) { |
if ($self->{insertion_mode} == IN_HEAD_NOSCRIPT_IM) { |
| 4873 |
!!!cp ('t119'); |
!!!cp ('t119'); |
| 4874 |
## As if </noscript> |
## As if </noscript> |
| 4875 |
pop @{$self->{open_elements}}; |
pop @{$self->{open_elements}}; |
| 4876 |
!!!parse-error (type => 'in noscript', text => 'script', |
!!!parse-error (type => 'in noscript', text => 'script', |
| 4877 |
token => $token); |
token => $token); |
| 4878 |
|
|
| 4879 |
$self->{insertion_mode} = IN_HEAD_IM; |
$self->{insertion_mode} = IN_HEAD_IM; |
| 4880 |
## Reprocess in the "in head" insertion mode... |
## Reprocess in the "in head" insertion mode... |
| 4881 |
} elsif ($self->{insertion_mode} == AFTER_HEAD_IM) { |
} elsif ($self->{insertion_mode} == AFTER_HEAD_IM) { |
| 4882 |
!!!cp ('t120'); |
!!!cp ('t120'); |
| 4883 |
!!!parse-error (type => 'after head', |
!!!parse-error (type => 'after head', |
| 4884 |
text => $token->{tag_name}, token => $token); |
text => $token->{tag_name}, token => $token); |
| 4885 |
push @{$self->{open_elements}}, |
push @{$self->{open_elements}}, |
| 4886 |
[$self->{head_element}, $el_category->{head}]; |
[$self->{head_element}, $el_category->{head}]; |
| 4887 |
} else { |
$self->{head_element_inserted} = 1; |
| 4888 |
!!!cp ('t121'); |
} else { |
| 4889 |
} |
!!!cp ('t121'); |
| 4890 |
|
} |
| 4891 |
|
|
| 4892 |
## NOTE: There is a "as if in head" code clone. |
## NOTE: There is a "as if in head" code clone. |
| 4893 |
$script_start_tag->(); |
$script_start_tag->(); |
| 4894 |
pop @{$self->{open_elements}} # <head> |
pop @{$self->{open_elements}} # <head> |
| 4895 |
if $self->{insertion_mode} == AFTER_HEAD_IM; |
if $self->{insertion_mode} == AFTER_HEAD_IM; |
| 4896 |
next B; |
next B; |
| 4897 |
} elsif ($token->{tag_name} eq 'body' or |
} elsif ($token->{tag_name} eq 'body' or |
| 4898 |
$token->{tag_name} eq 'frameset') { |
$token->{tag_name} eq 'frameset') { |
| 4899 |
if ($self->{insertion_mode} == IN_HEAD_NOSCRIPT_IM) { |
if ($self->{insertion_mode} == IN_HEAD_NOSCRIPT_IM) { |
| 4900 |
!!!cp ('t122'); |
!!!cp ('t122'); |
| 4901 |
## As if </noscript> |
## As if </noscript> |
| 5030 |
} elsif ({ |
} elsif ({ |
| 5031 |
body => 1, html => 1, |
body => 1, html => 1, |
| 5032 |
}->{$token->{tag_name}}) { |
}->{$token->{tag_name}}) { |
| 5033 |
if ($self->{insertion_mode} == BEFORE_HEAD_IM or |
## TODO: This branch is entirely redundant. |
| 5034 |
|
if ($self->{insertion_mode} == BEFORE_HEAD_IM or |
| 5035 |
$self->{insertion_mode} == IN_HEAD_IM or |
$self->{insertion_mode} == IN_HEAD_IM or |
| 5036 |
$self->{insertion_mode} == IN_HEAD_NOSCRIPT_IM) { |
$self->{insertion_mode} == IN_HEAD_NOSCRIPT_IM) { |
| 5037 |
!!!cp ('t140'); |
!!!cp ('t140'); |
| 5588 |
|
|
| 5589 |
!!!parse-error (type => 'in table:#text', token => $token); |
!!!parse-error (type => 'in table:#text', token => $token); |
| 5590 |
|
|
| 5591 |
## As if in body, but insert into foster parent element |
## NOTE: As if in body, but insert into the foster parent element. |
| 5592 |
## ISSUE: Spec says that "whenever a node would be inserted |
$reconstruct_active_formatting_elements->($insert_to_foster); |
|
## into the current node" while characters might not be |
|
|
## result in a new Text node. |
|
|
$reconstruct_active_formatting_elements->($insert_to_foster); |
|
| 5593 |
|
|
| 5594 |
if ($self->{open_elements}->[-1]->[1] & TABLE_ROWS_EL) { |
if ($self->{open_elements}->[-1]->[1] & TABLE_ROWS_EL) { |
| 5595 |
# MUST |
# MUST |
| 5596 |
my $foster_parent_element; |
my $foster_parent_element; |
| 5597 |
my $next_sibling; |
my $next_sibling; |
| 5598 |
my $prev_sibling; |
my $prev_sibling; |
| 5599 |
OE: for (reverse 0..$#{$self->{open_elements}}) { |
OE: for (reverse 0..$#{$self->{open_elements}}) { |
| 5600 |
if ($self->{open_elements}->[$_]->[1] & TABLE_EL) { |
if ($self->{open_elements}->[$_]->[1] & TABLE_EL) { |
| 5601 |
my $parent = $self->{open_elements}->[$_]->[0]->parent_node; |
my $parent = $self->{open_elements}->[$_]->[0]->parent_node; |
| 5602 |
if (defined $parent and $parent->node_type == 1) { |
if (defined $parent and $parent->node_type == 1) { |
| 5603 |
!!!cp ('t196'); |
$foster_parent_element = $parent; |
| 5604 |
$foster_parent_element = $parent; |
!!!cp ('t196'); |
| 5605 |
$next_sibling = $self->{open_elements}->[$_]->[0]; |
$next_sibling = $self->{open_elements}->[$_]->[0]; |
| 5606 |
$prev_sibling = $next_sibling->previous_sibling; |
$prev_sibling = $next_sibling->previous_sibling; |
| 5607 |
} else { |
# |
|
!!!cp ('t197'); |
|
|
$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) { |
|
|
!!!cp ('t198'); |
|
|
$prev_sibling->manakai_append_text ($token->{data}); |
|
| 5608 |
} else { |
} else { |
| 5609 |
!!!cp ('t199'); |
!!!cp ('t197'); |
| 5610 |
$foster_parent_element->insert_before |
$foster_parent_element = $self->{open_elements}->[$_ - 1]->[0]; |
| 5611 |
($self->{document}->create_text_node ($token->{data}), |
$prev_sibling = $foster_parent_element->last_child; |
| 5612 |
$next_sibling); |
# |
| 5613 |
} |
} |
| 5614 |
|
last OE; |
| 5615 |
|
} |
| 5616 |
|
} # OE |
| 5617 |
|
$foster_parent_element = $self->{open_elements}->[0]->[0] and |
| 5618 |
|
$prev_sibling = $foster_parent_element->last_child |
| 5619 |
|
unless defined $foster_parent_element; |
| 5620 |
|
undef $prev_sibling unless $open_tables->[-1]->[2]; # ~node inserted |
| 5621 |
|
if (defined $prev_sibling and |
| 5622 |
|
$prev_sibling->node_type == 3) { |
| 5623 |
|
!!!cp ('t198'); |
| 5624 |
|
$prev_sibling->manakai_append_text ($token->{data}); |
| 5625 |
|
} else { |
| 5626 |
|
!!!cp ('t199'); |
| 5627 |
|
$foster_parent_element->insert_before |
| 5628 |
|
($self->{document}->create_text_node ($token->{data}), |
| 5629 |
|
$next_sibling); |
| 5630 |
|
} |
| 5631 |
$open_tables->[-1]->[1] = 1; # tainted |
$open_tables->[-1]->[1] = 1; # tainted |
| 5632 |
|
$open_tables->[-1]->[2] = 1; # ~node inserted |
| 5633 |
} else { |
} else { |
| 5634 |
|
## NOTE: Fragment case or in a foster parent'ed element |
| 5635 |
|
## (e.g. |<table><span>a|). In fragment case, whether the |
| 5636 |
|
## character is appended to existing node or a new node is |
| 5637 |
|
## created is irrelevant, since the foster parent'ed nodes |
| 5638 |
|
## are discarded and fragment parsing does not invoke any |
| 5639 |
|
## script. |
| 5640 |
!!!cp ('t200'); |
!!!cp ('t200'); |
| 5641 |
$self->{open_elements}->[-1]->[0]->manakai_append_text ($token->{data}); |
$self->{open_elements}->[-1]->[0]->manakai_append_text |
| 5642 |
|
($token->{data}); |
| 5643 |
} |
} |
| 5644 |
|
|
| 5645 |
!!!next-token; |
!!!next-token; |
| 5676 |
pop @{$self->{open_elements}}; |
pop @{$self->{open_elements}}; |
| 5677 |
} |
} |
| 5678 |
|
|
| 5679 |
$self->{insertion_mode} = IN_ROW_IM; |
$self->{insertion_mode} = IN_ROW_IM; |
| 5680 |
if ($token->{tag_name} eq 'tr') { |
if ($token->{tag_name} eq 'tr') { |
| 5681 |
!!!cp ('t204'); |
!!!cp ('t204'); |
| 5682 |
!!!insert-element ($token->{tag_name}, $token->{attributes}, $token); |
!!!insert-element ($token->{tag_name}, $token->{attributes}, $token); |
| 5683 |
!!!nack ('t204'); |
$open_tables->[-1]->[2] = 0 if @$open_tables; # ~node inserted |
| 5684 |
!!!next-token; |
!!!nack ('t204'); |
| 5685 |
next B; |
!!!next-token; |
| 5686 |
} else { |
next B; |
| 5687 |
!!!cp ('t205'); |
} else { |
| 5688 |
!!!insert-element ('tr',, $token); |
!!!cp ('t205'); |
| 5689 |
## reprocess in the "in row" insertion mode |
!!!insert-element ('tr',, $token); |
| 5690 |
} |
## reprocess in the "in row" insertion mode |
| 5691 |
} else { |
} |
| 5692 |
!!!cp ('t206'); |
} else { |
| 5693 |
} |
!!!cp ('t206'); |
| 5694 |
|
} |
| 5695 |
|
|
| 5696 |
## Clear back to table row context |
## Clear back to table row context |
| 5697 |
while (not ($self->{open_elements}->[-1]->[1] |
while (not ($self->{open_elements}->[-1]->[1] |
| 5700 |
pop @{$self->{open_elements}}; |
pop @{$self->{open_elements}}; |
| 5701 |
} |
} |
| 5702 |
|
|
| 5703 |
!!!insert-element ($token->{tag_name}, $token->{attributes}, $token); |
!!!insert-element ($token->{tag_name}, $token->{attributes}, $token); |
| 5704 |
$self->{insertion_mode} = IN_CELL_IM; |
$open_tables->[-1]->[2] = 0 if @$open_tables; # ~node inserted |
| 5705 |
|
$self->{insertion_mode} = IN_CELL_IM; |
| 5706 |
|
|
| 5707 |
push @$active_formatting_elements, ['#marker', '']; |
push @$active_formatting_elements, ['#marker', '']; |
| 5708 |
|
|
| 5709 |
!!!nack ('t207.1'); |
!!!nack ('t207.1'); |
| 5710 |
|
!!!next-token; |
| 5711 |
|
next B; |
| 5712 |
|
} elsif ({ |
| 5713 |
|
caption => 1, col => 1, colgroup => 1, |
| 5714 |
|
tbody => 1, tfoot => 1, thead => 1, |
| 5715 |
|
tr => 1, # $self->{insertion_mode} == IN_ROW_IM |
| 5716 |
|
}->{$token->{tag_name}}) { |
| 5717 |
|
if ($self->{insertion_mode} == IN_ROW_IM) { |
| 5718 |
|
## As if </tr> |
| 5719 |
|
## have an element in table scope |
| 5720 |
|
my $i; |
| 5721 |
|
INSCOPE: for (reverse 0..$#{$self->{open_elements}}) { |
| 5722 |
|
my $node = $self->{open_elements}->[$_]; |
| 5723 |
|
if ($node->[1] & TABLE_ROW_EL) { |
| 5724 |
|
!!!cp ('t208'); |
| 5725 |
|
$i = $_; |
| 5726 |
|
last INSCOPE; |
| 5727 |
|
} elsif ($node->[1] & TABLE_SCOPING_EL) { |
| 5728 |
|
!!!cp ('t209'); |
| 5729 |
|
last INSCOPE; |
| 5730 |
|
} |
| 5731 |
|
} # INSCOPE |
| 5732 |
|
unless (defined $i) { |
| 5733 |
|
!!!cp ('t210'); |
| 5734 |
|
## TODO: This type is wrong. |
| 5735 |
|
!!!parse-error (type => 'unmacthed end tag', |
| 5736 |
|
text => $token->{tag_name}, token => $token); |
| 5737 |
|
## Ignore the token |
| 5738 |
|
!!!nack ('t210.1'); |
| 5739 |
!!!next-token; |
!!!next-token; |
| 5740 |
next B; |
next B; |
| 5741 |
} 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) { |
|
|
!!!cp ('t208'); |
|
|
$i = $_; |
|
|
last INSCOPE; |
|
|
} elsif ($node->[1] & TABLE_SCOPING_EL) { |
|
|
!!!cp ('t209'); |
|
|
last INSCOPE; |
|
|
} |
|
|
} # INSCOPE |
|
|
unless (defined $i) { |
|
|
!!!cp ('t210'); |
|
|
## TODO: This type is wrong. |
|
|
!!!parse-error (type => 'unmacthed end tag', |
|
|
text => $token->{tag_name}, token => $token); |
|
|
## Ignore the token |
|
|
!!!nack ('t210.1'); |
|
|
!!!next-token; |
|
|
next B; |
|
|
} |
|
| 5742 |
|
|
| 5743 |
## Clear back to table row context |
## Clear back to table row context |
| 5744 |
while (not ($self->{open_elements}->[-1]->[1] |
while (not ($self->{open_elements}->[-1]->[1] |
| 5808 |
!!!cp ('t218'); |
!!!cp ('t218'); |
| 5809 |
} |
} |
| 5810 |
|
|
| 5811 |
if ($token->{tag_name} eq 'col') { |
if ($token->{tag_name} eq 'col') { |
| 5812 |
## Clear back to table context |
## Clear back to table context |
| 5813 |
while (not ($self->{open_elements}->[-1]->[1] |
while (not ($self->{open_elements}->[-1]->[1] |
| 5814 |
& TABLE_SCOPING_EL)) { |
& TABLE_SCOPING_EL)) { |
| 5815 |
!!!cp ('t219'); |
!!!cp ('t219'); |
| 5816 |
## ISSUE: Can this state be reached? |
## ISSUE: Can this state be reached? |
| 5817 |
pop @{$self->{open_elements}}; |
pop @{$self->{open_elements}}; |
| 5818 |
} |
} |
| 5819 |
|
|
| 5820 |
!!!insert-element ('colgroup',, $token); |
!!!insert-element ('colgroup',, $token); |
| 5821 |
$self->{insertion_mode} = IN_COLUMN_GROUP_IM; |
$self->{insertion_mode} = IN_COLUMN_GROUP_IM; |
| 5822 |
## reprocess |
## reprocess |
| 5823 |
!!!ack-later; |
$open_tables->[-1]->[2] = 0 if @$open_tables; # ~node inserted |
| 5824 |
next B; |
!!!ack-later; |
| 5825 |
} elsif ({ |
next B; |
| 5826 |
caption => 1, |
} elsif ({ |
| 5827 |
colgroup => 1, |
caption => 1, |
| 5828 |
tbody => 1, tfoot => 1, thead => 1, |
colgroup => 1, |
| 5829 |
}->{$token->{tag_name}}) { |
tbody => 1, tfoot => 1, thead => 1, |
| 5830 |
## Clear back to table context |
}->{$token->{tag_name}}) { |
| 5831 |
|
## Clear back to table context |
| 5832 |
while (not ($self->{open_elements}->[-1]->[1] |
while (not ($self->{open_elements}->[-1]->[1] |
| 5833 |
& TABLE_SCOPING_EL)) { |
& TABLE_SCOPING_EL)) { |
| 5834 |
!!!cp ('t220'); |
!!!cp ('t220'); |
| 5836 |
pop @{$self->{open_elements}}; |
pop @{$self->{open_elements}}; |
| 5837 |
} |
} |
| 5838 |
|
|
| 5839 |
push @$active_formatting_elements, ['#marker', ''] |
push @$active_formatting_elements, ['#marker', ''] |
| 5840 |
if $token->{tag_name} eq 'caption'; |
if $token->{tag_name} eq 'caption'; |
| 5841 |
|
|
| 5842 |
!!!insert-element ($token->{tag_name}, $token->{attributes}, $token); |
!!!insert-element ($token->{tag_name}, $token->{attributes}, $token); |
| 5843 |
$self->{insertion_mode} = { |
$open_tables->[-1]->[2] = 0 if @$open_tables; # ~node inserted |
| 5844 |
caption => IN_CAPTION_IM, |
$self->{insertion_mode} = { |
| 5845 |
colgroup => IN_COLUMN_GROUP_IM, |
caption => IN_CAPTION_IM, |
| 5846 |
tbody => IN_TABLE_BODY_IM, |
colgroup => IN_COLUMN_GROUP_IM, |
| 5847 |
tfoot => IN_TABLE_BODY_IM, |
tbody => IN_TABLE_BODY_IM, |
| 5848 |
thead => IN_TABLE_BODY_IM, |
tfoot => IN_TABLE_BODY_IM, |
| 5849 |
}->{$token->{tag_name}}; |
thead => IN_TABLE_BODY_IM, |
| 5850 |
!!!next-token; |
}->{$token->{tag_name}}; |
| 5851 |
!!!nack ('t220.1'); |
!!!next-token; |
| 5852 |
next B; |
!!!nack ('t220.1'); |
| 5853 |
} else { |
next B; |
| 5854 |
die "$0: in table: <>: $token->{tag_name}"; |
} else { |
| 5855 |
} |
die "$0: in table: <>: $token->{tag_name}"; |
| 5856 |
|
} |
| 5857 |
} elsif ($token->{tag_name} eq 'table') { |
} elsif ($token->{tag_name} eq 'table') { |
| 5858 |
!!!parse-error (type => 'not closed', |
!!!parse-error (type => 'not closed', |
| 5859 |
text => $self->{open_elements}->[-1]->[0] |
text => $self->{open_elements}->[-1]->[0] |
| 5916 |
!!!cp ('t227.8'); |
!!!cp ('t227.8'); |
| 5917 |
## NOTE: This is a "as if in head" code clone. |
## NOTE: This is a "as if in head" code clone. |
| 5918 |
$parse_rcdata->(CDATA_CONTENT_MODEL); |
$parse_rcdata->(CDATA_CONTENT_MODEL); |
| 5919 |
|
$open_tables->[-1]->[2] = 0 if @$open_tables; # ~node inserted |
| 5920 |
next B; |
next B; |
| 5921 |
} else { |
} else { |
| 5922 |
!!!cp ('t227.7'); |
!!!cp ('t227.7'); |
| 5927 |
!!!cp ('t227.6'); |
!!!cp ('t227.6'); |
| 5928 |
## NOTE: This is a "as if in head" code clone. |
## NOTE: This is a "as if in head" code clone. |
| 5929 |
$script_start_tag->(); |
$script_start_tag->(); |
| 5930 |
|
$open_tables->[-1]->[2] = 0 if @$open_tables; # ~node inserted |
| 5931 |
next B; |
next B; |
| 5932 |
} else { |
} else { |
| 5933 |
!!!cp ('t227.5'); |
!!!cp ('t227.5'); |
| 5943 |
text => $token->{tag_name}, token => $token); |
text => $token->{tag_name}, token => $token); |
| 5944 |
|
|
| 5945 |
!!!insert-element ($token->{tag_name}, $token->{attributes}, $token); |
!!!insert-element ($token->{tag_name}, $token->{attributes}, $token); |
| 5946 |
|
$open_tables->[-1]->[2] = 0 if @$open_tables; # ~node inserted |
| 5947 |
|
|
| 5948 |
## TODO: form element pointer |
## TODO: form element pointer |
| 5949 |
|
|
| 8228 |
push @{$p->{open_elements}}, [$root, $el_category->{html}]; |
push @{$p->{open_elements}}, [$root, $el_category->{html}]; |
| 8229 |
|
|
| 8230 |
undef $p->{head_element}; |
undef $p->{head_element}; |
| 8231 |
|
undef $p->{head_element_inserted}; |
| 8232 |
|
|
| 8233 |
## Step 6 # MUST |
## Step 6 # MUST |
| 8234 |
$p->_reset_insertion_mode; |
$p->_reset_insertion_mode; |