| 147 |
$self->{parse_error} = sub { |
$self->{parse_error} = sub { |
| 148 |
# |
# |
| 149 |
}; |
}; |
| 150 |
|
$self->{application_cache_selection} = sub { |
| 151 |
|
# |
| 152 |
|
}; |
| 153 |
return $self; |
return $self; |
| 154 |
} # new |
} # new |
| 155 |
|
|
| 266 |
## has completed loading. If one has, then it MUST be executed |
## has completed loading. If one has, then it MUST be executed |
| 267 |
## and removed from the list. |
## and removed from the list. |
| 268 |
|
|
| 269 |
|
## NOTE: HTML5 "Writing HTML documents" section, applied to |
| 270 |
|
## documents and not to user agents and conformance checkers, |
| 271 |
|
## contains some requirements that are not detected by the |
| 272 |
|
## parsing algorithm: |
| 273 |
|
## - Some requirements on character encoding declarations. ## TODO |
| 274 |
|
## - "Elements MUST NOT contain content that their content model disallows." |
| 275 |
|
## ... Some are parse error, some are not (will be reported by c.c.). |
| 276 |
|
## - Polytheistic slash SHOULD NOT be used. (Applied only to atheists.) ## TODO |
| 277 |
|
## - Text (in elements, attributes, and comments) SHOULD NOT contain |
| 278 |
|
## control characters other than space characters. ## TODO: (what is control character? C0, C1 and DEL? Unicode control character?) |
| 279 |
|
|
| 280 |
|
## TODO: HTML5 poses authors two SHOULD-level requirements that cannot |
| 281 |
|
## be detected by the HTML5 parsing algorithm: |
| 282 |
|
## - Text, |
| 283 |
|
|
| 284 |
sub _get_next_token ($) { |
sub _get_next_token ($) { |
| 285 |
my $self = shift; |
my $self = shift; |
| 286 |
if (@{$self->{token}}) { |
if (@{$self->{token}}) { |
| 2098 |
redo B; |
redo B; |
| 2099 |
} |
} |
| 2100 |
} |
} |
| 2101 |
|
|
| 2102 |
|
$self->{application_cache_selection}->(undef); |
| 2103 |
|
|
| 2104 |
|
# |
| 2105 |
|
} elsif ($token->{type} == START_TAG_TOKEN) { |
| 2106 |
|
if ($token->{tag_name} eq 'html' and |
| 2107 |
|
$token->{attributes}->{manifest}) { ## ISSUE: Spec spells as "application" |
| 2108 |
|
$self->{application_cache_selection} |
| 2109 |
|
->($token->{attributes}->{manifest}->{value}); |
| 2110 |
|
## ISSUE: No relative reference resolution? |
| 2111 |
|
} else { |
| 2112 |
|
$self->{application_cache_selection}->(undef); |
| 2113 |
|
} |
| 2114 |
|
|
| 2115 |
|
## ISSUE: There is an issue in the spec |
| 2116 |
# |
# |
| 2117 |
} elsif ({ |
} elsif ({ |
|
START_TAG_TOKEN, 1, |
|
| 2118 |
END_TAG_TOKEN, 1, |
END_TAG_TOKEN, 1, |
| 2119 |
END_OF_FILE_TOKEN, 1, |
END_OF_FILE_TOKEN, 1, |
| 2120 |
}->{$token->{type}}) { |
}->{$token->{type}}) { |
| 2121 |
|
$self->{application_cache_selection}->(undef); |
| 2122 |
|
|
| 2123 |
## ISSUE: There is an issue in the spec |
## ISSUE: There is an issue in the spec |
| 2124 |
# |
# |
| 2125 |
} else { |
} else { |
| 2126 |
die "$0: $token->{type}: Unknown token type"; |
die "$0: $token->{type}: Unknown token type"; |
| 2127 |
} |
} |
| 2128 |
|
|
| 2129 |
my $root_element; !!!create-element ($root_element, 'html'); |
my $root_element; !!!create-element ($root_element, 'html'); |
| 2130 |
$self->{document}->append_child ($root_element); |
$self->{document}->append_child ($root_element); |
| 2131 |
push @{$self->{open_elements}}, [$root_element, 'html']; |
push @{$self->{open_elements}}, [$root_element, 'html']; |
| 5366 |
|
|
| 5367 |
} # tree construction stage |
} # tree construction stage |
| 5368 |
|
|
|
sub get_inner_html ($$$) { |
|
|
my (undef, $node, $on_error) = @_; |
|
|
|
|
|
## Step 1 |
|
|
my $s = ''; |
|
|
|
|
|
my $in_cdata; |
|
|
my $parent = $node; |
|
|
while (defined $parent) { |
|
|
if ($parent->node_type == 1 and |
|
|
$parent->namespace_uri eq 'http://www.w3.org/1999/xhtml' and |
|
|
{ |
|
|
style => 1, script => 1, xmp => 1, iframe => 1, |
|
|
noembed => 1, noframes => 1, noscript => 1, |
|
|
}->{$parent->local_name}) { ## TODO: case thingy |
|
|
$in_cdata = 1; |
|
|
} |
|
|
$parent = $parent->parent_node; |
|
|
} |
|
|
|
|
|
## Step 2 |
|
|
my @node = @{$node->child_nodes}; |
|
|
C: while (@node) { |
|
|
my $child = shift @node; |
|
|
unless (ref $child) { |
|
|
if ($child eq 'cdata-out') { |
|
|
$in_cdata = 0; |
|
|
} else { |
|
|
$s .= $child; # end tag |
|
|
} |
|
|
next C; |
|
|
} |
|
|
|
|
|
my $nt = $child->node_type; |
|
|
if ($nt == 1) { # Element |
|
|
my $tag_name = $child->tag_name; ## TODO: manakai_tag_name |
|
|
$s .= '<' . $tag_name; |
|
|
## NOTE: Non-HTML case: |
|
|
## <http://permalink.gmane.org/gmane.org.w3c.whatwg.discuss/11191> |
|
|
|
|
|
my @attrs = @{$child->attributes}; # sort order MUST be stable |
|
|
for my $attr (@attrs) { # order is implementation dependent |
|
|
my $attr_name = $attr->name; ## TODO: manakai_name |
|
|
$s .= ' ' . $attr_name . '="'; |
|
|
my $attr_value = $attr->value; |
|
|
## escape |
|
|
$attr_value =~ s/&/&/g; |
|
|
$attr_value =~ s/</</g; |
|
|
$attr_value =~ s/>/>/g; |
|
|
$attr_value =~ s/"/"/g; |
|
|
$s .= $attr_value . '"'; |
|
|
} |
|
|
$s .= '>'; |
|
|
|
|
|
next C if { |
|
|
area => 1, base => 1, basefont => 1, bgsound => 1, |
|
|
br => 1, col => 1, embed => 1, frame => 1, hr => 1, |
|
|
img => 1, input => 1, link => 1, meta => 1, param => 1, |
|
|
spacer => 1, wbr => 1, |
|
|
}->{$tag_name}; |
|
|
|
|
|
$s .= "\x0A" if $tag_name eq 'pre' or $tag_name eq 'textarea'; |
|
|
|
|
|
if (not $in_cdata and { |
|
|
style => 1, script => 1, xmp => 1, iframe => 1, |
|
|
noembed => 1, noframes => 1, noscript => 1, |
|
|
plaintext => 1, |
|
|
}->{$tag_name}) { |
|
|
unshift @node, 'cdata-out'; |
|
|
$in_cdata = 1; |
|
|
} |
|
|
|
|
|
unshift @node, @{$child->child_nodes}, '</' . $tag_name . '>'; |
|
|
} elsif ($nt == 3 or $nt == 4) { |
|
|
if ($in_cdata) { |
|
|
$s .= $child->data; |
|
|
} else { |
|
|
my $value = $child->data; |
|
|
$value =~ s/&/&/g; |
|
|
$value =~ s/</</g; |
|
|
$value =~ s/>/>/g; |
|
|
$value =~ s/"/"/g; |
|
|
$s .= $value; |
|
|
} |
|
|
} elsif ($nt == 8) { |
|
|
$s .= '<!--' . $child->data . '-->'; |
|
|
} elsif ($nt == 10) { |
|
|
$s .= '<!DOCTYPE ' . $child->name . '>'; |
|
|
} elsif ($nt == 5) { # entrefs |
|
|
push @node, @{$child->child_nodes}; |
|
|
} else { |
|
|
$on_error->($child) if defined $on_error; |
|
|
} |
|
|
## ISSUE: This code does not support PIs. |
|
|
} # C |
|
|
|
|
|
## Step 3 |
|
|
return \$s; |
|
|
} # get_inner_html |
|
|
|
|
| 5369 |
1; |
1; |
| 5370 |
# $Date$ |
# $Date$ |