| 304 |
sub BODY_AFTER_IMS () { 0b100000000 } |
sub BODY_AFTER_IMS () { 0b100000000 } |
| 305 |
sub FRAME_IMS () { 0b1000000000 } |
sub FRAME_IMS () { 0b1000000000 } |
| 306 |
|
|
| 307 |
|
## NOTE: "initial" and "before html" insertion modes have no constants. |
| 308 |
|
|
| 309 |
|
## NOTE: "after after body" insertion mode. |
| 310 |
sub AFTER_HTML_BODY_IM () { AFTER_HTML_IMS | BODY_AFTER_IMS } |
sub AFTER_HTML_BODY_IM () { AFTER_HTML_IMS | BODY_AFTER_IMS } |
| 311 |
|
|
| 312 |
|
## NOTE: "after after frameset" insertion mode. |
| 313 |
sub AFTER_HTML_FRAMESET_IM () { AFTER_HTML_IMS | FRAME_IMS } |
sub AFTER_HTML_FRAMESET_IM () { AFTER_HTML_IMS | FRAME_IMS } |
| 314 |
|
|
| 315 |
sub IN_HEAD_IM () { HEAD_IMS | 0b00 } |
sub IN_HEAD_IM () { HEAD_IMS | 0b00 } |
| 316 |
sub IN_HEAD_NOSCRIPT_IM () { HEAD_IMS | 0b01 } |
sub IN_HEAD_NOSCRIPT_IM () { HEAD_IMS | 0b01 } |
| 317 |
sub AFTER_HEAD_IM () { HEAD_IMS | 0b10 } |
sub AFTER_HEAD_IM () { HEAD_IMS | 0b10 } |
| 2426 |
|
|
| 2427 |
!!!next-token; |
!!!next-token; |
| 2428 |
|
|
|
$self->{insertion_mode} = BEFORE_HEAD_IM; |
|
| 2429 |
undef $self->{form_element}; |
undef $self->{form_element}; |
| 2430 |
undef $self->{head_element}; |
undef $self->{head_element}; |
| 2431 |
$self->{open_elements} = []; |
$self->{open_elements} = []; |
| 2432 |
undef $self->{inner_html_node}; |
undef $self->{inner_html_node}; |
| 2433 |
|
|
| 2434 |
|
## NOTE: The "initial" insertion mode. |
| 2435 |
$self->_tree_construction_initial; # MUST |
$self->_tree_construction_initial; # MUST |
| 2436 |
|
|
| 2437 |
|
## NOTE: The "before html" insertion mode. |
| 2438 |
$self->_tree_construction_root_element; |
$self->_tree_construction_root_element; |
| 2439 |
|
$self->{insertion_mode} = BEFORE_HEAD_IM; |
| 2440 |
|
|
| 2441 |
|
## NOTE: The "before head" insertion mode and so on. |
| 2442 |
$self->_tree_construction_main; |
$self->_tree_construction_main; |
| 2443 |
} # _construct_tree |
} # _construct_tree |
| 2444 |
|
|
| 2445 |
sub _tree_construction_initial ($) { |
sub _tree_construction_initial ($) { |
| 2446 |
my $self = shift; |
my $self = shift; |
| 2447 |
|
|
| 2448 |
|
## NOTE: "initial" insertion mode |
| 2449 |
|
|
| 2450 |
INITIAL: { |
INITIAL: { |
| 2451 |
if ($token->{type} == DOCTYPE_TOKEN) { |
if ($token->{type} == DOCTYPE_TOKEN) { |
| 2452 |
## NOTE: Conformance checkers MAY, instead of reporting "not HTML5" |
## NOTE: Conformance checkers MAY, instead of reporting "not HTML5" |
| 2593 |
!!!cp ('t13'); |
!!!cp ('t13'); |
| 2594 |
} |
} |
| 2595 |
|
|
| 2596 |
## Go to the root element phase. |
## Go to the "before html" insertion mode. |
| 2597 |
!!!next-token; |
!!!next-token; |
| 2598 |
return; |
return; |
| 2599 |
} elsif ({ |
} elsif ({ |
| 2604 |
!!!cp ('t14'); |
!!!cp ('t14'); |
| 2605 |
!!!parse-error (type => 'no DOCTYPE'); |
!!!parse-error (type => 'no DOCTYPE'); |
| 2606 |
$self->{document}->manakai_compat_mode ('quirks'); |
$self->{document}->manakai_compat_mode ('quirks'); |
| 2607 |
## Go to the root element phase |
## Go to the "before html" insertion mode. |
| 2608 |
## reprocess |
## reprocess |
| 2609 |
return; |
return; |
| 2610 |
} elsif ($token->{type} == CHARACTER_TOKEN) { |
} elsif ($token->{type} == CHARACTER_TOKEN) { |
| 2613 |
|
|
| 2614 |
unless (length $token->{data}) { |
unless (length $token->{data}) { |
| 2615 |
!!!cp ('t15'); |
!!!cp ('t15'); |
| 2616 |
## Stay in the phase |
## Stay in the insertion mode. |
| 2617 |
!!!next-token; |
!!!next-token; |
| 2618 |
redo INITIAL; |
redo INITIAL; |
| 2619 |
} else { |
} else { |
| 2625 |
|
|
| 2626 |
!!!parse-error (type => 'no DOCTYPE'); |
!!!parse-error (type => 'no DOCTYPE'); |
| 2627 |
$self->{document}->manakai_compat_mode ('quirks'); |
$self->{document}->manakai_compat_mode ('quirks'); |
| 2628 |
## Go to the root element phase |
## Go to the "before html" insertion mode. |
| 2629 |
## reprocess |
## reprocess |
| 2630 |
return; |
return; |
| 2631 |
} elsif ($token->{type} == COMMENT_TOKEN) { |
} elsif ($token->{type} == COMMENT_TOKEN) { |
| 2633 |
my $comment = $self->{document}->create_comment ($token->{data}); |
my $comment = $self->{document}->create_comment ($token->{data}); |
| 2634 |
$self->{document}->append_child ($comment); |
$self->{document}->append_child ($comment); |
| 2635 |
|
|
| 2636 |
## Stay in the phase. |
## Stay in the insertion mode. |
| 2637 |
!!!next-token; |
!!!next-token; |
| 2638 |
redo INITIAL; |
redo INITIAL; |
| 2639 |
} else { |
} else { |
| 2646 |
|
|
| 2647 |
sub _tree_construction_root_element ($) { |
sub _tree_construction_root_element ($) { |
| 2648 |
my $self = shift; |
my $self = shift; |
| 2649 |
|
|
| 2650 |
|
## NOTE: "before html" insertion mode. |
| 2651 |
|
|
| 2652 |
B: { |
B: { |
| 2653 |
if ($token->{type} == DOCTYPE_TOKEN) { |
if ($token->{type} == DOCTYPE_TOKEN) { |
| 2654 |
!!!cp ('t19'); |
!!!cp ('t19'); |
| 2655 |
!!!parse-error (type => 'in html:#DOCTYPE'); |
!!!parse-error (type => 'in html:#DOCTYPE'); |
| 2656 |
## Ignore the token |
## Ignore the token |
| 2657 |
## Stay in the phase |
## Stay in the insertion mode. |
| 2658 |
!!!next-token; |
!!!next-token; |
| 2659 |
redo B; |
redo B; |
| 2660 |
} elsif ($token->{type} == COMMENT_TOKEN) { |
} elsif ($token->{type} == COMMENT_TOKEN) { |
| 2661 |
!!!cp ('t20'); |
!!!cp ('t20'); |
| 2662 |
my $comment = $self->{document}->create_comment ($token->{data}); |
my $comment = $self->{document}->create_comment ($token->{data}); |
| 2663 |
$self->{document}->append_child ($comment); |
$self->{document}->append_child ($comment); |
| 2664 |
## Stay in the phase |
## Stay in the insertion mode. |
| 2665 |
!!!next-token; |
!!!next-token; |
| 2666 |
redo B; |
redo B; |
| 2667 |
} elsif ($token->{type} == CHARACTER_TOKEN) { |
} elsif ($token->{type} == CHARACTER_TOKEN) { |
| 2670 |
|
|
| 2671 |
unless (length $token->{data}) { |
unless (length $token->{data}) { |
| 2672 |
!!!cp ('t21'); |
!!!cp ('t21'); |
| 2673 |
## Stay in the phase |
## Stay in the insertion mode. |
| 2674 |
!!!next-token; |
!!!next-token; |
| 2675 |
redo B; |
redo B; |
| 2676 |
} else { |
} else { |
| 2684 |
|
|
| 2685 |
# |
# |
| 2686 |
} elsif ($token->{type} == START_TAG_TOKEN) { |
} elsif ($token->{type} == START_TAG_TOKEN) { |
| 2687 |
if ($token->{tag_name} eq 'html' and |
if ($token->{tag_name} eq 'html') { |
| 2688 |
$token->{attributes}->{manifest}) { |
my $root_element; |
| 2689 |
!!!cp ('t24'); |
!!!create-element ($root_element, $token->{tag_name}, $token->{attributes}); |
| 2690 |
$self->{application_cache_selection} |
$self->{document}->append_child ($root_element); |
| 2691 |
->($token->{attributes}->{manifest}->{value}); |
push @{$self->{open_elements}}, [$root_element, 'html']; |
| 2692 |
## ISSUE: No relative reference resolution? |
|
| 2693 |
|
if ($token->{attributes}->{manifest}) { |
| 2694 |
|
!!!cp ('t24'); |
| 2695 |
|
$self->{application_cache_selection} |
| 2696 |
|
->($token->{attributes}->{manifest}->{value}); |
| 2697 |
|
## ISSUE: No relative reference resolution? |
| 2698 |
|
} else { |
| 2699 |
|
!!!cp ('t25'); |
| 2700 |
|
$self->{application_cache_selection}->(undef); |
| 2701 |
|
} |
| 2702 |
|
|
| 2703 |
|
!!!next-token; |
| 2704 |
|
return; ## Go to the "before head" insertion mode. |
| 2705 |
} else { |
} else { |
| 2706 |
!!!cp ('t25'); |
!!!cp ('t25.1'); |
| 2707 |
$self->{application_cache_selection}->(undef); |
# |
| 2708 |
} |
} |
|
|
|
|
## ISSUE: There is an issue in the spec |
|
|
# |
|
| 2709 |
} elsif ({ |
} elsif ({ |
| 2710 |
END_TAG_TOKEN, 1, |
END_TAG_TOKEN, 1, |
| 2711 |
END_OF_FILE_TOKEN, 1, |
END_OF_FILE_TOKEN, 1, |
| 2712 |
}->{$token->{type}}) { |
}->{$token->{type}}) { |
| 2713 |
!!!cp ('t26'); |
!!!cp ('t26'); |
|
$self->{application_cache_selection}->(undef); |
|
|
|
|
|
## ISSUE: There is an issue in the spec |
|
| 2714 |
# |
# |
| 2715 |
} else { |
} else { |
| 2716 |
die "$0: $token->{type}: Unknown token type"; |
die "$0: $token->{type}: Unknown token type"; |
| 2717 |
} |
} |
| 2718 |
|
|
| 2719 |
my $root_element; !!!create-element ($root_element, 'html'); |
my $root_element; !!!create-element ($root_element, 'html'); |
| 2720 |
$self->{document}->append_child ($root_element); |
$self->{document}->append_child ($root_element); |
| 2721 |
push @{$self->{open_elements}}, [$root_element, 'html']; |
push @{$self->{open_elements}}, [$root_element, 'html']; |
| 2722 |
## reprocess |
|
| 2723 |
#redo B; |
$self->{application_cache_selection}->(undef); |
| 2724 |
return; ## Go to the main phase. |
|
| 2725 |
|
## NOTE: Reprocess the token. |
| 2726 |
|
return; ## Go to the "before head" insertion mode. |
| 2727 |
|
|
| 2728 |
|
## ISSUE: There is an issue in the spec |
| 2729 |
} # B |
} # B |
| 2730 |
|
|
| 2731 |
die "$0: _tree_construction_root_element: This should never be reached"; |
die "$0: _tree_construction_root_element: This should never be reached"; |
| 2765 |
## Step 4..13 |
## Step 4..13 |
| 2766 |
my $new_mode = { |
my $new_mode = { |
| 2767 |
select => IN_SELECT_IM, |
select => IN_SELECT_IM, |
| 2768 |
|
## NOTE: |option| and |optgroup| do not set |
| 2769 |
|
## insertion mode to "in select" by themselves. |
| 2770 |
td => IN_CELL_IM, |
td => IN_CELL_IM, |
| 2771 |
th => IN_CELL_IM, |
th => IN_CELL_IM, |
| 2772 |
tr => IN_ROW_IM, |
tr => IN_ROW_IM, |
| 3267 |
# |
# |
| 3268 |
} else { |
} else { |
| 3269 |
## Generate implied end tags |
## Generate implied end tags |
| 3270 |
if ({ |
while ({ |
| 3271 |
dd => 1, dt => 1, li => 1, p => 1, td => 1, th => 1, tr => 1, |
dd => 1, dt => 1, li => 1, p => 1, |
| 3272 |
tbody => 1, tfoot=> 1, thead => 1, |
}->{$self->{open_elements}->[-1]->[1]}) { |
|
}->{$self->{open_elements}->[-1]->[1]}) { |
|
| 3273 |
!!!cp ('t75'); |
!!!cp ('t75'); |
| 3274 |
!!!back-token; |
pop @{$self->{open_elements}}; |
|
$token = {type => END_TAG_TOKEN, tag_name => $self->{open_elements}->[-1]->[1]}; |
|
|
redo B; |
|
| 3275 |
} |
} |
| 3276 |
|
|
| 3277 |
if (@{$self->{open_elements}} > 2 or |
if (@{$self->{open_elements}} > 2 or |
| 3297 |
$token->{tag_name} eq 'html') { |
$token->{tag_name} eq 'html') { |
| 3298 |
if ($self->{insertion_mode} == AFTER_HTML_BODY_IM) { |
if ($self->{insertion_mode} == AFTER_HTML_BODY_IM) { |
| 3299 |
!!!cp ('t79'); |
!!!cp ('t79'); |
|
## Turn into the main phase |
|
| 3300 |
!!!parse-error (type => 'after html:html'); |
!!!parse-error (type => 'after html:html'); |
| 3301 |
$self->{insertion_mode} = AFTER_BODY_IM; |
$self->{insertion_mode} = AFTER_BODY_IM; |
| 3302 |
} elsif ($self->{insertion_mode} == AFTER_HTML_FRAMESET_IM) { |
} elsif ($self->{insertion_mode} == AFTER_HTML_FRAMESET_IM) { |
| 3303 |
!!!cp ('t80'); |
!!!cp ('t80'); |
|
## Turn into the main phase |
|
| 3304 |
!!!parse-error (type => 'after html:html'); |
!!!parse-error (type => 'after html:html'); |
| 3305 |
$self->{insertion_mode} = AFTER_FRAMESET_IM; |
$self->{insertion_mode} = AFTER_FRAMESET_IM; |
| 3306 |
} else { |
} else { |
| 3307 |
!!!cp ('t81'); |
!!!cp ('t81'); |
| 3308 |
} |
} |
| 3309 |
|
|
| 3310 |
## ISSUE: "aa<html>" is not a parse error. |
!!!cp ('t82'); |
| 3311 |
## ISSUE: "<html>" in fragment is not a parse error. |
!!!parse-error (type => 'not first start tag'); |
|
unless ($token->{first_start_tag}) { |
|
|
!!!cp ('t82'); |
|
|
!!!parse-error (type => 'not first start tag'); |
|
|
} else { |
|
|
!!!cp ('t83'); |
|
|
} |
|
| 3312 |
my $top_el = $self->{open_elements}->[0]->[0]; |
my $top_el = $self->{open_elements}->[0]->[0]; |
| 3313 |
for my $attr_name (keys %{$token->{attributes}}) { |
for my $attr_name (keys %{$token->{attributes}}) { |
| 3314 |
unless ($top_el->has_attribute_ns (undef, $attr_name)) { |
unless ($top_el->has_attribute_ns (undef, $attr_name)) { |
| 3683 |
!!!cp ('t133'); |
!!!cp ('t133'); |
| 3684 |
## As if </noscript> |
## As if </noscript> |
| 3685 |
pop @{$self->{open_elements}}; |
pop @{$self->{open_elements}}; |
| 3686 |
!!!parse-error (type => 'in noscript:script'); |
!!!parse-error (type => 'in noscript:/head'); |
| 3687 |
|
|
| 3688 |
## Reprocess in the "in head" insertion mode... |
## Reprocess in the "in head" insertion mode... |
| 3689 |
pop @{$self->{open_elements}}; |
pop @{$self->{open_elements}}; |
| 3788 |
|
|
| 3789 |
## Reprocess in the "after head" insertion mode... |
## Reprocess in the "after head" insertion mode... |
| 3790 |
} elsif ($self->{insertion_mode} == BEFORE_HEAD_IM) { |
} elsif ($self->{insertion_mode} == BEFORE_HEAD_IM) { |
| 3791 |
|
## ISSUE: This case cannot be reached? |
| 3792 |
!!!cp ('t148'); |
!!!cp ('t148'); |
| 3793 |
!!!parse-error (type => 'unmatched end tag:'.$token->{tag_name}); |
!!!parse-error (type => 'unmatched end tag:'.$token->{tag_name}); |
| 3794 |
## Ignore the token ## ISSUE: An issue in the spec. |
## Ignore the token ## ISSUE: An issue in the spec. |
| 3842 |
} # INSCOPE |
} # INSCOPE |
| 3843 |
unless (defined $tn) { |
unless (defined $tn) { |
| 3844 |
!!!cp ('t153'); |
!!!cp ('t153'); |
| 3845 |
|
## TODO: This error type is wrong. |
| 3846 |
!!!parse-error (type => 'unmatched end tag:'.$token->{tag_name}); |
!!!parse-error (type => 'unmatched end tag:'.$token->{tag_name}); |
| 3847 |
## Ignore the token |
## Ignore the token |
| 3848 |
!!!next-token; |
!!!next-token; |
| 3875 |
} # INSCOPE |
} # INSCOPE |
| 3876 |
unless (defined $i) { |
unless (defined $i) { |
| 3877 |
!!!cp ('t157'); |
!!!cp ('t157'); |
| 3878 |
|
## TODO: this type is wrong. |
| 3879 |
!!!parse-error (type => 'unmatched end tag:caption'); |
!!!parse-error (type => 'unmatched end tag:caption'); |
| 3880 |
## Ignore the token |
## Ignore the token |
| 3881 |
!!!next-token; |
!!!next-token; |
| 3883 |
} |
} |
| 3884 |
|
|
| 3885 |
## generate implied end tags |
## generate implied end tags |
| 3886 |
if ({ |
while ({ |
| 3887 |
dd => 1, dt => 1, li => 1, p => 1, |
dd => 1, dt => 1, li => 1, p => 1, |
| 3888 |
td => 1, th => 1, tr => 1, |
}->{$self->{open_elements}->[-1]->[1]}) { |
|
tbody => 1, tfoot=> 1, thead => 1, |
|
|
}->{$self->{open_elements}->[-1]->[1]}) { |
|
| 3889 |
!!!cp ('t158'); |
!!!cp ('t158'); |
| 3890 |
!!!back-token; # <?> |
pop @{$self->{open_elements}}; |
|
$token = {type => END_TAG_TOKEN, tag_name => 'caption'}; |
|
|
!!!back-token; |
|
|
$token = {type => END_TAG_TOKEN, |
|
|
tag_name => $self->{open_elements}->[-1]->[1]}; # MUST |
|
|
redo B; |
|
| 3891 |
} |
} |
| 3892 |
|
|
| 3893 |
if ($self->{open_elements}->[-1]->[1] ne 'caption') { |
if ($self->{open_elements}->[-1]->[1] ne 'caption') { |
| 3940 |
} |
} |
| 3941 |
|
|
| 3942 |
## generate implied end tags |
## generate implied end tags |
| 3943 |
if ({ |
while ({ |
| 3944 |
dd => 1, dt => 1, li => 1, p => 1, |
dd => 1, dt => 1, li => 1, p => 1, |
| 3945 |
td => ($token->{tag_name} eq 'th'), |
}->{$self->{open_elements}->[-1]->[1]}) { |
|
th => ($token->{tag_name} eq 'td'), |
|
|
tr => 1, |
|
|
tbody => 1, tfoot=> 1, thead => 1, |
|
|
}->{$self->{open_elements}->[-1]->[1]}) { |
|
| 3946 |
!!!cp ('t166'); |
!!!cp ('t166'); |
| 3947 |
!!!back-token; |
pop @{$self->{open_elements}}; |
|
$token = {type => END_TAG_TOKEN, |
|
|
tag_name => $self->{open_elements}->[-1]->[1]}; # MUST |
|
|
redo B; |
|
| 3948 |
} |
} |
| 3949 |
|
|
| 3950 |
if ($self->{open_elements}->[-1]->[1] ne $token->{tag_name}) { |
if ($self->{open_elements}->[-1]->[1] ne $token->{tag_name}) { |
| 3951 |
!!!cp ('t167'); |
!!!cp ('t167'); |
| 3952 |
!!!parse-error (type => 'not closed:'.$self->{open_elements}->[-1]->[1]); |
!!!parse-error (type => 'not closed:'.$self->{open_elements}->[-1]->[1]); |
| 3998 |
} |
} |
| 3999 |
|
|
| 4000 |
## generate implied end tags |
## generate implied end tags |
| 4001 |
if ({ |
while ({ |
| 4002 |
dd => 1, dt => 1, li => 1, p => 1, |
dd => 1, dt => 1, li => 1, p => 1, |
| 4003 |
td => 1, th => 1, tr => 1, |
}->{$self->{open_elements}->[-1]->[1]}) { |
|
tbody => 1, tfoot=> 1, thead => 1, |
|
|
}->{$self->{open_elements}->[-1]->[1]}) { |
|
| 4004 |
!!!cp ('t174'); |
!!!cp ('t174'); |
| 4005 |
!!!back-token; |
pop @{$self->{open_elements}}; |
|
$token = {type => END_TAG_TOKEN, |
|
|
tag_name => $self->{open_elements}->[-1]->[1]}; # MUST |
|
|
redo B; |
|
| 4006 |
} |
} |
| 4007 |
|
|
| 4008 |
if ($self->{open_elements}->[-1]->[1] ne 'caption') { |
if ($self->{open_elements}->[-1]->[1] ne 'caption') { |
| 4099 |
} |
} |
| 4100 |
|
|
| 4101 |
## generate implied end tags |
## generate implied end tags |
| 4102 |
if ({ |
while ({ |
| 4103 |
dd => 1, dt => 1, li => 1, p => 1, |
dd => 1, dt => 1, li => 1, p => 1, |
| 4104 |
td => 1, th => 1, tr => 1, |
}->{$self->{open_elements}->[-1]->[1]}) { |
|
tbody => 1, tfoot=> 1, thead => 1, |
|
|
}->{$self->{open_elements}->[-1]->[1]}) { |
|
| 4105 |
!!!cp ('t187'); |
!!!cp ('t187'); |
| 4106 |
!!!back-token; # </table> |
pop @{$self->{open_elements}}; |
|
$token = {type => END_TAG_TOKEN, tag_name => 'caption'}; |
|
|
!!!back-token; |
|
|
$token = {type => END_TAG_TOKEN, |
|
|
tag_name => $self->{open_elements}->[-1]->[1]}; # MUST |
|
|
redo B; |
|
| 4107 |
} |
} |
| 4108 |
|
|
| 4109 |
if ($self->{open_elements}->[-1]->[1] ne 'caption') { |
if ($self->{open_elements}->[-1]->[1] ne 'caption') { |
| 4250 |
tbody => 1, tfoot => 1, thead => 1, html => 1, |
tbody => 1, tfoot => 1, thead => 1, html => 1, |
| 4251 |
}->{$self->{open_elements}->[-1]->[1]}) { |
}->{$self->{open_elements}->[-1]->[1]}) { |
| 4252 |
!!!cp ('t203'); |
!!!cp ('t203'); |
| 4253 |
|
## ISSUE: Can this case be reached? |
| 4254 |
!!!parse-error (type => 'not closed:'.$self->{open_elements}->[-1]->[1]); |
!!!parse-error (type => 'not closed:'.$self->{open_elements}->[-1]->[1]); |
| 4255 |
pop @{$self->{open_elements}}; |
pop @{$self->{open_elements}}; |
| 4256 |
} |
} |
| 4302 |
$i = $_; |
$i = $_; |
| 4303 |
last INSCOPE; |
last INSCOPE; |
| 4304 |
} elsif ({ |
} elsif ({ |
| 4305 |
table => 1, html => 1, |
html => 1, |
| 4306 |
|
|
| 4307 |
|
## NOTE: This element does not appear here, maybe. |
| 4308 |
|
table => 1, |
| 4309 |
}->{$node->[1]}) { |
}->{$node->[1]}) { |
| 4310 |
!!!cp ('t209'); |
!!!cp ('t209'); |
| 4311 |
last INSCOPE; |
last INSCOPE; |
| 4313 |
} # INSCOPE |
} # INSCOPE |
| 4314 |
unless (defined $i) { |
unless (defined $i) { |
| 4315 |
!!!cp ('t210'); |
!!!cp ('t210'); |
| 4316 |
|
## TODO: This type is wrong. |
| 4317 |
!!!parse-error (type => 'unmacthed end tag:'.$token->{tag_name}); |
!!!parse-error (type => 'unmacthed end tag:'.$token->{tag_name}); |
| 4318 |
## Ignore the token |
## Ignore the token |
| 4319 |
!!!next-token; |
!!!next-token; |
| 4325 |
tr => 1, html => 1, |
tr => 1, html => 1, |
| 4326 |
}->{$self->{open_elements}->[-1]->[1]}) { |
}->{$self->{open_elements}->[-1]->[1]}) { |
| 4327 |
!!!cp ('t211'); |
!!!cp ('t211'); |
| 4328 |
|
## ISSUE: Can this case be reached? |
| 4329 |
!!!parse-error (type => 'not closed:'.$self->{open_elements}->[-1]->[1]); |
!!!parse-error (type => 'not closed:'.$self->{open_elements}->[-1]->[1]); |
| 4330 |
pop @{$self->{open_elements}}; |
pop @{$self->{open_elements}}; |
| 4331 |
} |
} |
| 4362 |
} # INSCOPE |
} # INSCOPE |
| 4363 |
unless (defined $i) { |
unless (defined $i) { |
| 4364 |
!!!cp ('t216'); |
!!!cp ('t216'); |
| 4365 |
|
## TODO: This erorr type ios wrong. |
| 4366 |
!!!parse-error (type => 'unmatched end tag:'.$token->{tag_name}); |
!!!parse-error (type => 'unmatched end tag:'.$token->{tag_name}); |
| 4367 |
## Ignore the token |
## Ignore the token |
| 4368 |
!!!next-token; |
!!!next-token; |
| 4374 |
tbody => 1, tfoot => 1, thead => 1, html => 1, |
tbody => 1, tfoot => 1, thead => 1, html => 1, |
| 4375 |
}->{$self->{open_elements}->[-1]->[1]}) { |
}->{$self->{open_elements}->[-1]->[1]}) { |
| 4376 |
!!!cp ('t217'); |
!!!cp ('t217'); |
| 4377 |
|
## ISSUE: Can this state be reached? |
| 4378 |
!!!parse-error (type => 'not closed:'.$self->{open_elements}->[-1]->[1]); |
!!!parse-error (type => 'not closed:'.$self->{open_elements}->[-1]->[1]); |
| 4379 |
pop @{$self->{open_elements}}; |
pop @{$self->{open_elements}}; |
| 4380 |
} |
} |
| 4398 |
while ($self->{open_elements}->[-1]->[1] ne 'table' and |
while ($self->{open_elements}->[-1]->[1] ne 'table' and |
| 4399 |
$self->{open_elements}->[-1]->[1] ne 'html') { |
$self->{open_elements}->[-1]->[1] ne 'html') { |
| 4400 |
!!!cp ('t219'); |
!!!cp ('t219'); |
| 4401 |
|
## ISSUE: Can this state be reached? |
| 4402 |
!!!parse-error (type => 'not closed:'.$self->{open_elements}->[-1]->[1]); |
!!!parse-error (type => 'not closed:'.$self->{open_elements}->[-1]->[1]); |
| 4403 |
pop @{$self->{open_elements}}; |
pop @{$self->{open_elements}}; |
| 4404 |
} |
} |
| 4416 |
while ($self->{open_elements}->[-1]->[1] ne 'table' and |
while ($self->{open_elements}->[-1]->[1] ne 'table' and |
| 4417 |
$self->{open_elements}->[-1]->[1] ne 'html') { |
$self->{open_elements}->[-1]->[1] ne 'html') { |
| 4418 |
!!!cp ('t220'); |
!!!cp ('t220'); |
| 4419 |
|
## ISSUE: Can this state be reached? |
| 4420 |
!!!parse-error (type => 'not closed:'.$self->{open_elements}->[-1]->[1]); |
!!!parse-error (type => 'not closed:'.$self->{open_elements}->[-1]->[1]); |
| 4421 |
pop @{$self->{open_elements}}; |
pop @{$self->{open_elements}}; |
| 4422 |
} |
} |
| 4450 |
$i = $_; |
$i = $_; |
| 4451 |
last INSCOPE; |
last INSCOPE; |
| 4452 |
} elsif ({ |
} elsif ({ |
| 4453 |
table => 1, html => 1, |
#table => 1, |
| 4454 |
|
html => 1, |
| 4455 |
}->{$node->[1]}) { |
}->{$node->[1]}) { |
| 4456 |
!!!cp ('t222'); |
!!!cp ('t222'); |
| 4457 |
last INSCOPE; |
last INSCOPE; |
| 4459 |
} # INSCOPE |
} # INSCOPE |
| 4460 |
unless (defined $i) { |
unless (defined $i) { |
| 4461 |
!!!cp ('t223'); |
!!!cp ('t223'); |
| 4462 |
|
## TODO: The following is wrong, maybe. |
| 4463 |
!!!parse-error (type => 'unmatched end tag:table'); |
!!!parse-error (type => 'unmatched end tag:table'); |
| 4464 |
## Ignore tokens </table><table> |
## Ignore tokens </table><table> |
| 4465 |
!!!next-token; |
!!!next-token; |
| 4467 |
} |
} |
| 4468 |
|
|
| 4469 |
## generate implied end tags |
## generate implied end tags |
| 4470 |
if ({ |
while ({ |
| 4471 |
dd => 1, dt => 1, li => 1, p => 1, |
dd => 1, dt => 1, li => 1, p => 1, |
| 4472 |
td => 1, th => 1, tr => 1, |
}->{$self->{open_elements}->[-1]->[1]}) { |
|
tbody => 1, tfoot=> 1, thead => 1, |
|
|
}->{$self->{open_elements}->[-1]->[1]}) { |
|
| 4473 |
!!!cp ('t224'); |
!!!cp ('t224'); |
| 4474 |
!!!back-token; # <table> |
pop @{$self->{open_elements}}; |
|
$token = {type => END_TAG_TOKEN, tag_name => 'table'}; |
|
|
!!!back-token; |
|
|
$token = {type => END_TAG_TOKEN, |
|
|
tag_name => $self->{open_elements}->[-1]->[1]}; # MUST |
|
|
redo B; |
|
| 4475 |
} |
} |
| 4476 |
|
|
| 4477 |
if ($self->{open_elements}->[-1]->[1] ne 'table') { |
if ($self->{open_elements}->[-1]->[1] ne 'table') { |
| 4478 |
!!!cp ('t225'); |
!!!cp ('t225'); |
| 4479 |
|
## ISSUE: Can this case be reached? |
| 4480 |
!!!parse-error (type => 'not closed:'.$self->{open_elements}->[-1]->[1]); |
!!!parse-error (type => 'not closed:'.$self->{open_elements}->[-1]->[1]); |
| 4481 |
} else { |
} else { |
| 4482 |
!!!cp ('t226'); |
!!!cp ('t226'); |
| 4528 |
tr => 1, html => 1, |
tr => 1, html => 1, |
| 4529 |
}->{$self->{open_elements}->[-1]->[1]}) { |
}->{$self->{open_elements}->[-1]->[1]}) { |
| 4530 |
!!!cp ('t231'); |
!!!cp ('t231'); |
| 4531 |
|
## ISSUE: Can this state be reached? |
| 4532 |
!!!parse-error (type => 'not closed:'.$self->{open_elements}->[-1]->[1]); |
!!!parse-error (type => 'not closed:'.$self->{open_elements}->[-1]->[1]); |
| 4533 |
pop @{$self->{open_elements}}; |
pop @{$self->{open_elements}}; |
| 4534 |
} |
} |
| 4557 |
} # INSCOPE |
} # INSCOPE |
| 4558 |
unless (defined $i) { |
unless (defined $i) { |
| 4559 |
!!!cp ('t235'); |
!!!cp ('t235'); |
| 4560 |
|
## TODO: The following is wrong. |
| 4561 |
!!!parse-error (type => 'unmatched end tag:'.$token->{type}); |
!!!parse-error (type => 'unmatched end tag:'.$token->{type}); |
| 4562 |
## Ignore the token |
## Ignore the token |
| 4563 |
!!!next-token; |
!!!next-token; |
| 4569 |
tr => 1, html => 1, |
tr => 1, html => 1, |
| 4570 |
}->{$self->{open_elements}->[-1]->[1]}) { |
}->{$self->{open_elements}->[-1]->[1]}) { |
| 4571 |
!!!cp ('t236'); |
!!!cp ('t236'); |
| 4572 |
|
## ISSUE: Can this state be reached? |
| 4573 |
!!!parse-error (type => 'not closed:'.$self->{open_elements}->[-1]->[1]); |
!!!parse-error (type => 'not closed:'.$self->{open_elements}->[-1]->[1]); |
| 4574 |
pop @{$self->{open_elements}}; |
pop @{$self->{open_elements}}; |
| 4575 |
} |
} |
| 4650 |
} |
} |
| 4651 |
|
|
| 4652 |
## generate implied end tags |
## generate implied end tags |
| 4653 |
if ({ |
while ({ |
| 4654 |
dd => 1, dt => 1, li => 1, p => 1, |
dd => 1, dt => 1, li => 1, p => 1, |
| 4655 |
td => 1, th => 1, tr => 1, |
}->{$self->{open_elements}->[-1]->[1]}) { |
|
tbody => 1, tfoot=> 1, thead => 1, |
|
|
}->{$self->{open_elements}->[-1]->[1]}) { |
|
| 4656 |
!!!cp ('t244'); |
!!!cp ('t244'); |
| 4657 |
!!!back-token; |
## ISSUE: Can this case be reached? |
| 4658 |
$token = {type => END_TAG_TOKEN, |
pop @{$self->{open_elements}}; |
|
tag_name => $self->{open_elements}->[-1]->[1]}; # MUST |
|
|
redo B; |
|
| 4659 |
} |
} |
| 4660 |
|
|
| 4661 |
if ($self->{open_elements}->[-1]->[1] ne 'table') { |
if ($self->{open_elements}->[-1]->[1] ne 'table') { |
| 4728 |
tr => 1, html => 1, |
tr => 1, html => 1, |
| 4729 |
}->{$self->{open_elements}->[-1]->[1]}) { |
}->{$self->{open_elements}->[-1]->[1]}) { |
| 4730 |
!!!cp ('t253'); |
!!!cp ('t253'); |
| 4731 |
|
## ISSUE: Can this case be reached? |
| 4732 |
!!!parse-error (type => 'not closed:'.$self->{open_elements}->[-1]->[1]); |
!!!parse-error (type => 'not closed:'.$self->{open_elements}->[-1]->[1]); |
| 4733 |
pop @{$self->{open_elements}}; |
pop @{$self->{open_elements}}; |
| 4734 |
} |
} |
| 4766 |
tbody => 1, tfoot => 1, thead => 1, html => 1, |
tbody => 1, tfoot => 1, thead => 1, html => 1, |
| 4767 |
}->{$self->{open_elements}->[-1]->[1]}) { |
}->{$self->{open_elements}->[-1]->[1]}) { |
| 4768 |
!!!cp ('t257'); |
!!!cp ('t257'); |
| 4769 |
|
## ISSUE: Can this case be reached? |
| 4770 |
!!!parse-error (type => 'not closed:'.$self->{open_elements}->[-1]->[1]); |
!!!parse-error (type => 'not closed:'.$self->{open_elements}->[-1]->[1]); |
| 4771 |
pop @{$self->{open_elements}}; |
pop @{$self->{open_elements}}; |
| 4772 |
} |
} |
| 4846 |
# |
# |
| 4847 |
} |
} |
| 4848 |
} else { |
} else { |
| 4849 |
!!!cp ('t268'); |
die "$0: $token->{type}: Unknown token type"; |
|
# |
|
| 4850 |
} |
} |
| 4851 |
|
|
| 4852 |
## As if </colgroup> |
## As if </colgroup> |
| 4903 |
!!!next-token; |
!!!next-token; |
| 4904 |
redo B; |
redo B; |
| 4905 |
} elsif ($token->{tag_name} eq 'select') { |
} elsif ($token->{tag_name} eq 'select') { |
| 4906 |
|
## TODO: The type below is not good - <select> is replaced by </select> |
| 4907 |
!!!parse-error (type => 'not closed:select'); |
!!!parse-error (type => 'not closed:select'); |
| 4908 |
## As if </select> instead |
## As if </select> instead |
| 4909 |
## have an element in table scope |
## have an element in table scope |
| 5006 |
caption => 1, table => 1, tbody => 1, |
caption => 1, table => 1, tbody => 1, |
| 5007 |
tfoot => 1, thead => 1, tr => 1, td => 1, th => 1, |
tfoot => 1, thead => 1, tr => 1, td => 1, th => 1, |
| 5008 |
}->{$token->{tag_name}}) { |
}->{$token->{tag_name}}) { |
| 5009 |
|
## TODO: The following is wrong? |
| 5010 |
!!!parse-error (type => 'unmatched end tag:'.$token->{tag_name}); |
!!!parse-error (type => 'unmatched end tag:'.$token->{tag_name}); |
| 5011 |
|
|
| 5012 |
## have an element in table scope |
## have an element in table scope |
| 5043 |
} elsif ({ |
} elsif ({ |
| 5044 |
table => 1, html => 1, |
table => 1, html => 1, |
| 5045 |
}->{$node->[1]}) { |
}->{$node->[1]}) { |
| 5046 |
|
## ISSUE: Can this state be reached? |
| 5047 |
!!!cp ('t296'); |
!!!cp ('t296'); |
| 5048 |
last INSCOPE; |
last INSCOPE; |
| 5049 |
} |
} |
| 5050 |
} # INSCOPE |
} # INSCOPE |
| 5051 |
unless (defined $i) { |
unless (defined $i) { |
| 5052 |
!!!cp ('t297'); |
!!!cp ('t297'); |
| 5053 |
|
## TODO: The following error type is correct? |
| 5054 |
!!!parse-error (type => 'unmatched end tag:select'); |
!!!parse-error (type => 'unmatched end tag:select'); |
| 5055 |
## Ignore the </select> token |
## Ignore the </select> token |
| 5056 |
!!!next-token; ## TODO: ok? |
!!!next-token; ## TODO: ok? |
| 5094 |
!!!cp ('t301'); |
!!!cp ('t301'); |
| 5095 |
!!!parse-error (type => 'after html:#character'); |
!!!parse-error (type => 'after html:#character'); |
| 5096 |
|
|
| 5097 |
## Reprocess in the "main" phase, "after body" insertion mode... |
## Reprocess in the "after body" insertion mode. |
| 5098 |
} else { |
} else { |
| 5099 |
!!!cp ('t302'); |
!!!cp ('t302'); |
| 5100 |
} |
} |
| 5110 |
!!!cp ('t303'); |
!!!cp ('t303'); |
| 5111 |
!!!parse-error (type => 'after html:'.$token->{tag_name}); |
!!!parse-error (type => 'after html:'.$token->{tag_name}); |
| 5112 |
|
|
| 5113 |
## Reprocess in the "main" phase, "after body" insertion mode... |
## Reprocess in the "after body" insertion mode. |
| 5114 |
} else { |
} else { |
| 5115 |
!!!cp ('t304'); |
!!!cp ('t304'); |
| 5116 |
} |
} |
| 5127 |
!!!parse-error (type => 'after html:/'.$token->{tag_name}); |
!!!parse-error (type => 'after html:/'.$token->{tag_name}); |
| 5128 |
|
|
| 5129 |
$self->{insertion_mode} = AFTER_BODY_IM; |
$self->{insertion_mode} = AFTER_BODY_IM; |
| 5130 |
## Reprocess in the "main" phase, "after body" insertion mode... |
## Reprocess in the "after body" insertion mode. |
| 5131 |
} else { |
} else { |
| 5132 |
!!!cp ('t306'); |
!!!cp ('t306'); |
| 5133 |
} |
} |
| 5181 |
!!!parse-error (type => 'after html:#character'); |
!!!parse-error (type => 'after html:#character'); |
| 5182 |
|
|
| 5183 |
$self->{insertion_mode} = AFTER_FRAMESET_IM; |
$self->{insertion_mode} = AFTER_FRAMESET_IM; |
| 5184 |
## Reprocess in the "main" phase, "after frameset"... |
## Reprocess in the "after frameset" insertion mode. |
| 5185 |
!!!parse-error (type => 'after frameset:#character'); |
!!!parse-error (type => 'after frameset:#character'); |
| 5186 |
} |
} |
| 5187 |
|
|
| 5203 |
!!!parse-error (type => 'after html:'.$token->{tag_name}); |
!!!parse-error (type => 'after html:'.$token->{tag_name}); |
| 5204 |
|
|
| 5205 |
$self->{insertion_mode} = AFTER_FRAMESET_IM; |
$self->{insertion_mode} = AFTER_FRAMESET_IM; |
| 5206 |
## Process in the "main" phase, "after frameset" insertion mode... |
## Process in the "after frameset" insertion mode. |
| 5207 |
} else { |
} else { |
| 5208 |
!!!cp ('t317'); |
!!!cp ('t317'); |
| 5209 |
} |
} |
| 5244 |
!!!parse-error (type => 'after html:/'.$token->{tag_name}); |
!!!parse-error (type => 'after html:/'.$token->{tag_name}); |
| 5245 |
|
|
| 5246 |
$self->{insertion_mode} = AFTER_FRAMESET_IM; |
$self->{insertion_mode} = AFTER_FRAMESET_IM; |
| 5247 |
## Process in the "main" phase, "after frameset" insertion mode... |
## Process in the "after frameset" insertion mode. |
| 5248 |
} else { |
} else { |
| 5249 |
!!!cp ('t324'); |
!!!cp ('t324'); |
| 5250 |
} |
} |
| 5405 |
redo B; |
redo B; |
| 5406 |
} elsif ({ |
} elsif ({ |
| 5407 |
address => 1, blockquote => 1, center => 1, dir => 1, |
address => 1, blockquote => 1, center => 1, dir => 1, |
| 5408 |
div => 1, dl => 1, fieldset => 1, listing => 1, |
div => 1, dl => 1, fieldset => 1, |
| 5409 |
menu => 1, ol => 1, p => 1, ul => 1, |
h1 => 1, h2 => 1, h3 => 1, h4 => 1, h5 => 1, h6 => 1, |
| 5410 |
|
listing => 1, menu => 1, ol => 1, p => 1, ul => 1, |
| 5411 |
pre => 1, |
pre => 1, |
| 5412 |
}->{$token->{tag_name}}) { |
}->{$token->{tag_name}}) { |
| 5413 |
## has a p element in scope |
## has a p element in scope |
| 5609 |
|
|
| 5610 |
!!!next-token; |
!!!next-token; |
| 5611 |
redo B; |
redo B; |
|
} elsif ({ |
|
|
h1 => 1, h2 => 1, h3 => 1, h4 => 1, h5 => 1, h6 => 1, |
|
|
}->{$token->{tag_name}}) { |
|
|
## has a p element in scope |
|
|
INSCOPE: for (reverse 0..$#{$self->{open_elements}}) { |
|
|
my $node = $self->{open_elements}->[$_]; |
|
|
if ($node->[1] eq 'p') { |
|
|
!!!cp ('t369'); |
|
|
!!!back-token; |
|
|
$token = {type => END_TAG_TOKEN, tag_name => 'p'}; |
|
|
redo B; |
|
|
} elsif ({ |
|
|
table => 1, caption => 1, td => 1, th => 1, |
|
|
button => 1, marquee => 1, object => 1, html => 1, |
|
|
}->{$node->[1]}) { |
|
|
!!!cp ('t370'); |
|
|
last INSCOPE; |
|
|
} |
|
|
} # INSCOPE |
|
|
|
|
|
## NOTE: See <http://html5.org/tools/web-apps-tracker?from=925&to=926> |
|
|
## has an element in scope |
|
|
#my $i; |
|
|
#INSCOPE: for (reverse 0..$#{$self->{open_elements}}) { |
|
|
# my $node = $self->{open_elements}->[$_]; |
|
|
# if ({ |
|
|
# h1 => 1, h2 => 1, h3 => 1, h4 => 1, h5 => 1, h6 => 1, |
|
|
# }->{$node->[1]}) { |
|
|
# $i = $_; |
|
|
# last INSCOPE; |
|
|
# } elsif ({ |
|
|
# table => 1, caption => 1, td => 1, th => 1, |
|
|
# button => 1, marquee => 1, object => 1, html => 1, |
|
|
# }->{$node->[1]}) { |
|
|
# last INSCOPE; |
|
|
# } |
|
|
#} # INSCOPE |
|
|
# |
|
|
#if (defined $i) { |
|
|
# !!! parse-error (type => 'in hn:hn'); |
|
|
# splice @{$self->{open_elements}}, $i; |
|
|
#} |
|
|
|
|
|
!!!insert-element-t ($token->{tag_name}, $token->{attributes}); |
|
|
|
|
|
!!!next-token; |
|
|
redo B; |
|
| 5612 |
} elsif ($token->{tag_name} eq 'a') { |
} elsif ($token->{tag_name} eq 'a') { |
| 5613 |
AFE: for my $i (reverse 0..$#$active_formatting_elements) { |
AFE: for my $i (reverse 0..$#$active_formatting_elements) { |
| 5614 |
my $node = $active_formatting_elements->[$i]; |
my $node = $active_formatting_elements->[$i]; |
| 5709 |
$reconstruct_active_formatting_elements->($insert_to_current); |
$reconstruct_active_formatting_elements->($insert_to_current); |
| 5710 |
|
|
| 5711 |
!!!insert-element-t ($token->{tag_name}, $token->{attributes}); |
!!!insert-element-t ($token->{tag_name}, $token->{attributes}); |
| 5712 |
|
|
| 5713 |
|
## TODO: associate with $self->{form_element} if defined |
| 5714 |
|
|
| 5715 |
push @$active_formatting_elements, ['#marker', '']; |
push @$active_formatting_elements, ['#marker', '']; |
| 5716 |
|
|
| 5717 |
!!!next-token; |
!!!next-token; |
| 5911 |
$reconstruct_active_formatting_elements->($insert_to_current); |
$reconstruct_active_formatting_elements->($insert_to_current); |
| 5912 |
|
|
| 5913 |
!!!insert-element-t ($token->{tag_name}, $token->{attributes}); |
!!!insert-element-t ($token->{tag_name}, $token->{attributes}); |
| 5914 |
|
|
| 5915 |
|
## TODO: associate with $self->{form_element} if defined |
| 5916 |
|
|
| 5917 |
$self->{insertion_mode} = IN_SELECT_IM; |
$self->{insertion_mode} = IN_SELECT_IM; |
| 5918 |
!!!next-token; |
!!!next-token; |
| 5989 |
address => 1, blockquote => 1, center => 1, dir => 1, |
address => 1, blockquote => 1, center => 1, dir => 1, |
| 5990 |
div => 1, dl => 1, fieldset => 1, listing => 1, |
div => 1, dl => 1, fieldset => 1, listing => 1, |
| 5991 |
menu => 1, ol => 1, pre => 1, ul => 1, |
menu => 1, ol => 1, pre => 1, ul => 1, |
|
p => 1, |
|
| 5992 |
dd => 1, dt => 1, li => 1, |
dd => 1, dt => 1, li => 1, |
| 5993 |
button => 1, marquee => 1, object => 1, |
button => 1, marquee => 1, object => 1, |
| 5994 |
}->{$token->{tag_name}}) { |
}->{$token->{tag_name}}) { |
| 5997 |
INSCOPE: for (reverse 0..$#{$self->{open_elements}}) { |
INSCOPE: for (reverse 0..$#{$self->{open_elements}}) { |
| 5998 |
my $node = $self->{open_elements}->[$_]; |
my $node = $self->{open_elements}->[$_]; |
| 5999 |
if ($node->[1] eq $token->{tag_name}) { |
if ($node->[1] eq $token->{tag_name}) { |
|
## generate implied end tags |
|
|
if ({ |
|
|
dd => ($token->{tag_name} ne 'dd'), |
|
|
dt => ($token->{tag_name} ne 'dt'), |
|
|
li => ($token->{tag_name} ne 'li'), |
|
|
p => ($token->{tag_name} ne 'p'), |
|
|
td => 1, th => 1, tr => 1, |
|
|
tbody => 1, tfoot=> 1, thead => 1, |
|
|
}->{$self->{open_elements}->[-1]->[1]}) { |
|
|
!!!cp ('t409'); |
|
|
!!!back-token; |
|
|
$token = {type => END_TAG_TOKEN, |
|
|
tag_name => $self->{open_elements}->[-1]->[1]}; # MUST |
|
|
redo B; |
|
|
} |
|
|
|
|
| 6000 |
!!!cp ('t410'); |
!!!cp ('t410'); |
| 6001 |
$i = $_; |
$i = $_; |
| 6002 |
last INSCOPE unless $token->{tag_name} eq 'p'; |
last INSCOPE; |
| 6003 |
} elsif ({ |
} elsif ({ |
| 6004 |
table => 1, caption => 1, td => 1, th => 1, |
table => 1, caption => 1, td => 1, th => 1, |
| 6005 |
button => 1, marquee => 1, object => 1, html => 1, |
button => 1, marquee => 1, object => 1, html => 1, |
| 6008 |
last INSCOPE; |
last INSCOPE; |
| 6009 |
} |
} |
| 6010 |
} # INSCOPE |
} # INSCOPE |
| 6011 |
|
|
| 6012 |
if ($self->{open_elements}->[-1]->[1] ne $token->{tag_name}) { |
unless (defined $i) { # has an element in scope |
| 6013 |
if (defined $i) { |
!!!cp ('t413'); |
| 6014 |
|
!!!parse-error (type => 'unmatched end tag:'.$token->{tag_name}); |
| 6015 |
|
} else { |
| 6016 |
|
## Step 1. generate implied end tags |
| 6017 |
|
while ({ |
| 6018 |
|
dd => ($token->{tag_name} ne 'dd'), |
| 6019 |
|
dt => ($token->{tag_name} ne 'dt'), |
| 6020 |
|
li => ($token->{tag_name} ne 'li'), |
| 6021 |
|
p => 1, |
| 6022 |
|
}->{$self->{open_elements}->[-1]->[1]}) { |
| 6023 |
|
!!!cp ('t409'); |
| 6024 |
|
pop @{$self->{open_elements}}; |
| 6025 |
|
} |
| 6026 |
|
|
| 6027 |
|
## Step 2. |
| 6028 |
|
if ($self->{open_elements}->[-1]->[1] ne $token->{tag_name}) { |
| 6029 |
!!!cp ('t412'); |
!!!cp ('t412'); |
| 6030 |
!!!parse-error (type => 'not closed:'.$self->{open_elements}->[-1]->[1]); |
!!!parse-error (type => 'not closed:'.$self->{open_elements}->[-1]->[1]); |
| 6031 |
} else { |
} else { |
| 6032 |
!!!cp ('t413'); |
!!!cp ('t414'); |
|
!!!parse-error (type => 'unmatched end tag:'.$token->{tag_name}); |
|
| 6033 |
} |
} |
| 6034 |
} |
|
| 6035 |
|
## Step 3. |
|
if (defined $i) { |
|
|
!!!cp ('t414'); |
|
| 6036 |
splice @{$self->{open_elements}}, $i; |
splice @{$self->{open_elements}}, $i; |
| 6037 |
} elsif ($token->{tag_name} eq 'p') { |
|
| 6038 |
!!!cp ('t415'); |
## Step 4. |
| 6039 |
## As if <p>, then reprocess the current token |
$clear_up_to_marker->() |
| 6040 |
my $el; |
if { |
| 6041 |
!!!create-element ($el, 'p'); |
button => 1, marquee => 1, object => 1, |
| 6042 |
$insert->($el); |
}->{$token->{tag_name}}; |
|
} else { |
|
|
!!!cp ('t416'); |
|
| 6043 |
} |
} |
|
$clear_up_to_marker->() |
|
|
if { |
|
|
button => 1, marquee => 1, object => 1, |
|
|
}->{$token->{tag_name}}; |
|
| 6044 |
!!!next-token; |
!!!next-token; |
| 6045 |
redo B; |
redo B; |
| 6046 |
} elsif ($token->{tag_name} eq 'form') { |
} elsif ($token->{tag_name} eq 'form') { |
| 6049 |
my $node = $self->{open_elements}->[$_]; |
my $node = $self->{open_elements}->[$_]; |
| 6050 |
if ($node->[1] eq $token->{tag_name}) { |
if ($node->[1] eq $token->{tag_name}) { |
| 6051 |
## generate implied end tags |
## generate implied end tags |
| 6052 |
if ({ |
while ({ |
| 6053 |
dd => 1, dt => 1, li => 1, p => 1, |
dd => 1, dt => 1, li => 1, p => 1, |
| 6054 |
td => 1, th => 1, tr => 1, |
}->{$self->{open_elements}->[-1]->[1]}) { |
|
tbody => 1, tfoot=> 1, thead => 1, |
|
|
}->{$self->{open_elements}->[-1]->[1]}) { |
|
| 6055 |
!!!cp ('t417'); |
!!!cp ('t417'); |
| 6056 |
!!!back-token; |
pop @{$self->{open_elements}}; |
|
$token = {type => END_TAG_TOKEN, |
|
|
tag_name => $self->{open_elements}->[-1]->[1]}; # MUST |
|
|
redo B; |
|
| 6057 |
} |
} |
| 6058 |
|
|
| 6059 |
!!!cp ('t418'); |
!!!cp ('t418'); |
| 6060 |
last INSCOPE; |
last INSCOPE; |
| 6061 |
} elsif ({ |
} elsif ({ |
| 6089 |
h1 => 1, h2 => 1, h3 => 1, h4 => 1, h5 => 1, h6 => 1, |
h1 => 1, h2 => 1, h3 => 1, h4 => 1, h5 => 1, h6 => 1, |
| 6090 |
}->{$node->[1]}) { |
}->{$node->[1]}) { |
| 6091 |
## generate implied end tags |
## generate implied end tags |
| 6092 |
if ({ |
while ({ |
| 6093 |
dd => 1, dt => 1, li => 1, p => 1, |
dd => 1, dt => 1, li => 1, p => 1, |
| 6094 |
td => 1, th => 1, tr => 1, |
}->{$self->{open_elements}->[-1]->[1]}) { |
|
tbody => 1, tfoot=> 1, thead => 1, |
|
|
}->{$self->{open_elements}->[-1]->[1]}) { |
|
| 6095 |
!!!cp ('t422'); |
!!!cp ('t422'); |
| 6096 |
!!!back-token; |
pop @{$self->{open_elements}}; |
|
$token = {type => END_TAG_TOKEN, |
|
|
tag_name => $self->{open_elements}->[-1]->[1]}; # MUST |
|
|
redo B; |
|
| 6097 |
} |
} |
| 6098 |
|
|
| 6099 |
!!!cp ('t423'); |
!!!cp ('t423'); |
| 6118 |
splice @{$self->{open_elements}}, $i if defined $i; |
splice @{$self->{open_elements}}, $i if defined $i; |
| 6119 |
!!!next-token; |
!!!next-token; |
| 6120 |
redo B; |
redo B; |
| 6121 |
|
} elsif ($token->{tag_name} eq 'p') { |
| 6122 |
|
## has an element in scope |
| 6123 |
|
my $i; |
| 6124 |
|
INSCOPE: for (reverse 0..$#{$self->{open_elements}}) { |
| 6125 |
|
my $node = $self->{open_elements}->[$_]; |
| 6126 |
|
if ($node->[1] eq $token->{tag_name}) { |
| 6127 |
|
## generate implied end tags |
| 6128 |
|
while ({ |
| 6129 |
|
dd => 1, dt => 1, li => 1, p => 0, |
| 6130 |
|
}->{$self->{open_elements}->[-1]->[1]}) { |
| 6131 |
|
!!!cp ('t409.1'); |
| 6132 |
|
pop @{$self->{open_elements}}; |
| 6133 |
|
} |
| 6134 |
|
|
| 6135 |
|
!!!cp ('t410.1'); |
| 6136 |
|
$i = $_; |
| 6137 |
|
last INSCOPE; |
| 6138 |
|
} elsif ({ |
| 6139 |
|
table => 1, caption => 1, td => 1, th => 1, |
| 6140 |
|
button => 1, marquee => 1, object => 1, html => 1, |
| 6141 |
|
}->{$node->[1]}) { |
| 6142 |
|
!!!cp ('t411.1'); |
| 6143 |
|
last INSCOPE; |
| 6144 |
|
} |
| 6145 |
|
} # INSCOPE |
| 6146 |
|
|
| 6147 |
|
if ($self->{open_elements}->[-1]->[1] ne $token->{tag_name}) { |
| 6148 |
|
if (defined $i) { |
| 6149 |
|
!!!cp ('t412.1'); |
| 6150 |
|
!!!parse-error (type => 'not closed:'.$self->{open_elements}->[-1]->[1]); |
| 6151 |
|
} else { |
| 6152 |
|
!!!cp ('t413.1'); |
| 6153 |
|
!!!parse-error (type => 'unmatched end tag:'.$token->{tag_name}); |
| 6154 |
|
} |
| 6155 |
|
} |
| 6156 |
|
|
| 6157 |
|
if (defined $i) { |
| 6158 |
|
!!!cp ('t414.1'); |
| 6159 |
|
splice @{$self->{open_elements}}, $i; |
| 6160 |
|
} else { |
| 6161 |
|
!!!cp ('t415.1'); |
| 6162 |
|
## As if <p>, then reprocess the current token |
| 6163 |
|
my $el; |
| 6164 |
|
!!!create-element ($el, 'p'); |
| 6165 |
|
$insert->($el); |
| 6166 |
|
} |
| 6167 |
|
!!!next-token; |
| 6168 |
|
redo B; |
| 6169 |
} elsif ({ |
} elsif ({ |
| 6170 |
a => 1, |
a => 1, |
| 6171 |
b => 1, big => 1, em => 1, font => 1, i => 1, |
b => 1, big => 1, em => 1, font => 1, i => 1, |
| 6219 |
if ($node->[1] eq $token->{tag_name}) { |
if ($node->[1] eq $token->{tag_name}) { |
| 6220 |
## Step 1 |
## Step 1 |
| 6221 |
## generate implied end tags |
## generate implied end tags |
| 6222 |
if ({ |
while ({ |
| 6223 |
dd => 1, dt => 1, li => 1, p => 1, |
dd => 1, dt => 1, li => 1, p => 1, |
| 6224 |
td => 1, th => 1, tr => 1, |
}->{$self->{open_elements}->[-1]->[1]}) { |
|
tbody => 1, tfoot => 1, thead => 1, |
|
|
}->{$self->{open_elements}->[-1]->[1]}) { |
|
| 6225 |
!!!cp ('t430'); |
!!!cp ('t430'); |
| 6226 |
!!!back-token; |
## ISSUE: Can this case be reached? |
| 6227 |
$token = {type => END_TAG_TOKEN, |
pop @{$self->{open_elements}}; |
|
tag_name => $self->{open_elements}->[-1]->[1]}; # MUST |
|
|
redo B; |
|
| 6228 |
} |
} |
| 6229 |
|
|
| 6230 |
## Step 2 |
## Step 2 |
| 6270 |
redo B; |
redo B; |
| 6271 |
} # B |
} # B |
| 6272 |
|
|
|
## NOTE: The "trailing end" phase in HTML5 is split into |
|
|
## two insertion modes: "after html body" and "after html frameset". |
|
|
## NOTE: States in the main stage is preserved while |
|
|
## the parser stays in the trailing end phase. # MUST |
|
|
|
|
| 6273 |
## Stop parsing # MUST |
## Stop parsing # MUST |
| 6274 |
|
|
| 6275 |
## TODO: script stuffs |
## TODO: script stuffs |
| 6311 |
my $p = $class->new; |
my $p = $class->new; |
| 6312 |
$p->{document} = $doc; |
$p->{document} = $doc; |
| 6313 |
|
|
| 6314 |
## Step 9 # MUST |
## Step 8 # MUST |
| 6315 |
my $i = 0; |
my $i = 0; |
| 6316 |
my $line = 1; |
my $line = 1; |
| 6317 |
my $column = 0; |
my $column = 0; |
| 6378 |
|
|
| 6379 |
$p->{inner_html_node} = [$node, $node_ln]; |
$p->{inner_html_node} = [$node, $node_ln]; |
| 6380 |
|
|
| 6381 |
## Step 4 |
## Step 3 |
| 6382 |
my $root = $doc->create_element_ns |
my $root = $doc->create_element_ns |
| 6383 |
('http://www.w3.org/1999/xhtml', [undef, 'html']); |
('http://www.w3.org/1999/xhtml', [undef, 'html']); |
| 6384 |
|
|
| 6385 |
## Step 5 # MUST |
## Step 4 # MUST |
| 6386 |
$doc->append_child ($root); |
$doc->append_child ($root); |
| 6387 |
|
|
| 6388 |
## Step 6 # MUST |
## Step 5 # MUST |
| 6389 |
push @{$p->{open_elements}}, [$root, 'html']; |
push @{$p->{open_elements}}, [$root, 'html']; |
| 6390 |
|
|
| 6391 |
undef $p->{head_element}; |
undef $p->{head_element}; |
| 6392 |
|
|
| 6393 |
## Step 7 # MUST |
## Step 6 # MUST |
| 6394 |
$p->_reset_insertion_mode; |
$p->_reset_insertion_mode; |
| 6395 |
|
|
| 6396 |
## Step 8 # MUST |
## Step 7 # MUST |
| 6397 |
my $anode = $node; |
my $anode = $node; |
| 6398 |
AN: while (defined $anode) { |
AN: while (defined $anode) { |
| 6399 |
if ($anode->node_type == 1) { |
if ($anode->node_type == 1) { |
| 6409 |
$anode = $anode->parent_node; |
$anode = $anode->parent_node; |
| 6410 |
} # AN |
} # AN |
| 6411 |
|
|
| 6412 |
## Step 3 # MUST |
## Step 9 # MUST |
|
## Step 10 # MUST |
|
| 6413 |
{ |
{ |
| 6414 |
my $self = $p; |
my $self = $p; |
| 6415 |
!!!next-token; |
!!!next-token; |
| 6416 |
} |
} |
| 6417 |
$p->_tree_construction_main; |
$p->_tree_construction_main; |
| 6418 |
|
|
| 6419 |
## Step 11 # MUST |
## Step 10 # MUST |
| 6420 |
my @cn = @{$node->child_nodes}; |
my @cn = @{$node->child_nodes}; |
| 6421 |
for (@cn) { |
for (@cn) { |
| 6422 |
$node->remove_child ($_); |
$node->remove_child ($_); |
| 6423 |
} |
} |
| 6424 |
## ISSUE: mutation events? read-only? |
## ISSUE: mutation events? read-only? |
| 6425 |
|
|
| 6426 |
## Step 12 # MUST |
## Step 11 # MUST |
| 6427 |
@cn = @{$root->child_nodes}; |
@cn = @{$root->child_nodes}; |
| 6428 |
for (@cn) { |
for (@cn) { |
| 6429 |
$this_doc->adopt_node ($_); |
$this_doc->adopt_node ($_); |