| 121 |
## no author requirement on conformance in the XML Base specification. |
## no author requirement on conformance in the XML Base specification. |
| 122 |
}, |
}, |
| 123 |
id => sub { |
id => sub { |
| 124 |
my ($self, $attr) = @_; |
my ($self, $attr, $item, $element_state) = @_; |
| 125 |
my $value = $attr->value; |
my $value = $attr->value; |
| 126 |
$value =~ s/[\x09\x0A\x0D\x20]+/ /g; |
$value =~ s/[\x09\x0A\x0D\x20]+/ /g; |
| 127 |
$value =~ s/^\x20//; |
$value =~ s/^\x20//; |
| 135 |
push @{$self->{id}->{$value}}, $attr; |
push @{$self->{id}->{$value}}, $attr; |
| 136 |
} else { |
} else { |
| 137 |
$self->{id}->{$value} = [$attr]; |
$self->{id}->{$value} = [$attr]; |
| 138 |
|
$self->{id_type}->{$value} = $element_state->{id_type} || ''; |
| 139 |
} |
} |
| 140 |
}, |
}, |
| 141 |
}, |
}, |
| 221 |
## TODO: xsi:schemaLocation for XHTML2 support (very, very low priority) |
## TODO: xsi:schemaLocation for XHTML2 support (very, very low priority) |
| 222 |
|
|
| 223 |
our %AnyChecker = ( |
our %AnyChecker = ( |
| 224 |
|
## NOTE: |check_start| is invoked before anything on the element's |
| 225 |
|
## attributes and contents is checked. |
| 226 |
check_start => sub { }, |
check_start => sub { }, |
| 227 |
|
## NOTE: |check_attrs| and |check_attrs2| are invoked after |
| 228 |
|
## |check_start| and before anything on the element's contents is |
| 229 |
|
## checked. |check_attrs| is invoked immediately before |
| 230 |
|
## |check_attrs2|. |
| 231 |
check_attrs => sub { |
check_attrs => sub { |
| 232 |
my ($self, $item, $element_state) = @_; |
my ($self, $item, $element_state) = @_; |
| 233 |
for my $attr (@{$item->{node}->attributes}) { |
for my $attr (@{$item->{node}->attributes}) { |
| 262 |
$self->_attr_status_info ($attr, $status); |
$self->_attr_status_info ($attr, $status); |
| 263 |
} |
} |
| 264 |
}, |
}, |
| 265 |
|
check_attrs2 => sub { }, |
| 266 |
|
## NOTE: |check_child_element| is invoked for each occurence of |
| 267 |
|
## child elements. It is invoked after |check_attrs| and before |
| 268 |
|
## |check_end|. |check_child_element| and |check_child_text| are |
| 269 |
|
## invoked for each child elements and text nodes in tree order. |
| 270 |
check_child_element => sub { |
check_child_element => sub { |
| 271 |
my ($self, $item, $child_el, $child_nsuri, $child_ln, |
my ($self, $item, $child_el, $child_nsuri, $child_ln, |
| 272 |
$child_is_transparent, $element_state) = @_; |
$child_is_transparent, $element_state) = @_; |
| 280 |
# |
# |
| 281 |
} |
} |
| 282 |
}, |
}, |
| 283 |
|
## NOTE: |check_child_text| is invoked for each occurence of child |
| 284 |
|
## text nodes. It is invoked after |check_attrs| and before |
| 285 |
|
## |check_end|. |check_child_element| and |check_child_text| are |
| 286 |
|
## invoked for each child elements and text nodes in tree order. |
| 287 |
check_child_text => sub { }, |
check_child_text => sub { }, |
| 288 |
|
## NOTE: |check_end| is invoked after everything on the element's |
| 289 |
|
## attributes and contents are checked. |
| 290 |
check_end => sub { |
check_end => sub { |
| 291 |
my ($self, $item, $element_state) = @_; |
my ($self, $item, $element_state) = @_; |
| 292 |
## NOTE: There is a modified copy of the code below for |html:ruby|. |
## NOTE: There is a modified copy of the code below for |html:ruby|. |
| 329 |
## Whatpm::ContentChecler::HTML for the list of all (conditionally |
## Whatpm::ContentChecler::HTML for the list of all (conditionally |
| 330 |
## or permanently) interactive content. |
## or permanently) interactive content. |
| 331 |
|
|
| 332 |
|
## The variable name is not good, since this method also returns |
| 333 |
|
## true for non-interactive content as long as the element cannot be |
| 334 |
|
## interactive content. |
| 335 |
|
|
| 336 |
if ($nsuri eq $HTML_NS and ($ln eq 'video' or $ln eq 'audio')) { |
if ($nsuri eq $HTML_NS and ($ln eq 'video' or $ln eq 'audio')) { |
| 337 |
return $el->has_attribute ('controls'); |
return $el->has_attribute_ns (undef, 'controls'); |
| 338 |
} elsif ($nsuri eq $HTML_NS and $ln eq 'menu') { |
} elsif ($nsuri eq $HTML_NS and $ln eq 'menu') { |
| 339 |
my $value = $el->get_attribute ('type'); |
my $value = $el->get_attribute_ns (undef, 'type'); |
| 340 |
$value =~ tr/A-Z/a-z/; # ASCII case-insensitive |
$value =~ tr/A-Z/a-z/; # ASCII case-insensitive |
| 341 |
return ($value eq 'toolbar'); |
return ($value eq 'toolbar'); |
| 342 |
} else { |
} else { |
| 343 |
return 1; |
return 1; |
| 344 |
} |
} |
| 345 |
|
|
| 346 |
|
## TODO: input:not([type=hidden]) |
| 347 |
}; # $IsInHTMLInteractiveContent |
}; # $IsInHTMLInteractiveContent |
| 348 |
|
|
| 349 |
my $HTMLTransparentElements = { |
my $HTMLTransparentElements = { |
| 350 |
$HTML_NS => {qw/ins 1 del 1 font 1 noscript 1 canvas 1 a 1/}, |
$HTML_NS => { |
| 351 |
## NOTE: |html:noscript| is transparent if scripting is disabled |
ins => 1, del => 1, |
| 352 |
## and not in |head|. |
font => 1, ## dropped from the spec |
| 353 |
}; |
noscript => 1, |
| 354 |
|
## NOTE: |html:noscript| is transparent if scripting is disabled |
| 355 |
|
## and not in |head|. |
| 356 |
|
canvas => 1, |
| 357 |
|
a => 1, |
| 358 |
|
map => 1, |
| 359 |
|
}, |
| 360 |
|
}; # $HTMLTransparentElements |
| 361 |
|
|
| 362 |
|
## NOTE: Now that the term "semi-transparent content model" is dropped |
| 363 |
|
## from the spec, but the concept is not. |
| 364 |
my $HTMLSemiTransparentElements = { |
my $HTMLSemiTransparentElements = { |
| 365 |
$HTML_NS => {object => 1, video => 1, audio => 1}, |
$HTML_NS => {object => 1, video => 1, audio => 1}, |
| 366 |
}; |
}; # $HTMLSemiTransparentElements |
| 367 |
|
|
| 368 |
our $Element = {}; |
our $Element = {}; |
| 369 |
|
|
| 423 |
|
|
| 424 |
html4_fact => 'm', |
html4_fact => 'm', |
| 425 |
html5_no_may => 'm', |
html5_no_may => 'm', |
| 426 |
|
html5_fact => 'm', |
| 427 |
|
|
| 428 |
xml_error => 'm', ## TODO: correct? |
xml_error => 'm', ## TODO: correct? |
| 429 |
xml_id_error => 'm', ## TODO: ? |
xml_id_error => 'm', ## TODO: ? |
| 521 |
if ($doc->manakai_is_html) { |
if ($doc->manakai_is_html) { |
| 522 |
if (not $doc->manakai_has_bom and |
if (not $doc->manakai_has_bom and |
| 523 |
not defined $doc->manakai_charset) { |
not defined $doc->manakai_charset) { |
| 524 |
unless ($charset->{is_html_ascii_superset}) { |
unless ($charset->{category} |
| 525 |
|
& Message::Charset::Info::CHARSET_CATEGORY_ASCII_COMPAT ()) { |
| 526 |
$onerror->(node => $doc, |
$onerror->(node => $doc, |
| 527 |
level => $self->{level}->{must}, |
level => $self->{level}->{must}, |
| 528 |
type => 'non ascii superset', |
type => 'non ascii superset', |
| 550 |
level => $self->{level}->{should}, |
level => $self->{level}->{should}, |
| 551 |
layer => 'encode'); |
layer => 'encode'); |
| 552 |
} elsif ($charset->{iana_names}->{'cesu-8'} or |
} elsif ($charset->{iana_names}->{'cesu-8'} or |
| 553 |
$charset->{iana_names}->{'utf-8'} or ## ISSUE: UNICODE-1-1-UTF-7? |
$charset->{iana_names}->{'utf-7'} or ## ISSUE: UNICODE-1-1-UTF-7? |
| 554 |
$charset->{iana_names}->{'bocu-1'} or |
$charset->{iana_names}->{'bocu-1'} or |
| 555 |
$charset->{iana_names}->{'scsu'}) { |
$charset->{iana_names}->{'scsu'}) { |
| 556 |
$onerror->(node => $doc, |
$onerror->(node => $doc, |
| 593 |
$self->{plus_elements} = {}; |
$self->{plus_elements} = {}; |
| 594 |
$self->{minus_elements} = {}; |
$self->{minus_elements} = {}; |
| 595 |
$self->{id} = {}; |
$self->{id} = {}; |
| 596 |
$self->{form} = {}; |
$self->{id_type} = {}; # 'form' / 'labelable' / 'menu' |
| 597 |
|
$self->{form} = {}; # form/@name |
| 598 |
|
#$self->{has_autofocus}; |
| 599 |
|
$self->{idref} = []; # @form, @for, @contextmenu |
| 600 |
$self->{term} = {}; |
$self->{term} = {}; |
| 601 |
$self->{usemap} = []; |
$self->{usemap} = []; |
| 602 |
$self->{ref} = []; # datetemplate data references |
$self->{ref} = []; # datetemplate data references |
| 603 |
$self->{template} = []; # datatemplate template references |
$self->{template} = []; # datatemplate template references |
|
$self->{contextmenu} = []; |
|
| 604 |
$self->{map} = {}; |
$self->{map} = {}; |
|
$self->{menu} = {}; |
|
| 605 |
$self->{has_link_type} = {}; |
$self->{has_link_type} = {}; |
| 606 |
$self->{flag} = {}; |
$self->{flag} = {}; |
| 607 |
#$self->{has_uri_attr}; |
#$self->{has_uri_attr}; |
| 671 |
my @new_item; |
my @new_item; |
| 672 |
push @new_item, [$eldef->{check_start}, $self, $item, $element_state]; |
push @new_item, [$eldef->{check_start}, $self, $item, $element_state]; |
| 673 |
push @new_item, [$eldef->{check_attrs}, $self, $item, $element_state]; |
push @new_item, [$eldef->{check_attrs}, $self, $item, $element_state]; |
| 674 |
|
push @new_item, [$eldef->{check_attrs2}, $self, $item, $element_state]; |
| 675 |
|
|
| 676 |
my @child = @{$item->{node}->child_nodes}; |
my @child = @{$item->{node}->child_nodes}; |
| 677 |
while (@child) { |
while (@child) { |
| 814 |
} |
} |
| 815 |
} |
} |
| 816 |
|
|
| 817 |
for (@{$self->{contextmenu}}) { |
for (@{$self->{idref}}) { |
| 818 |
unless ($self->{menu}->{$_->[0]}) { |
if ($self->{id}->{$_->[1]} and $self->{id_type}->{$_->[1]} eq $_->[0]) { |
| 819 |
$self->{onerror}->(node => $_->[1], type => 'no referenced menu', |
# |
| 820 |
|
} elsif ($_->[0] eq 'any' and $self->{id}->{$_->[1]}) { |
| 821 |
|
# |
| 822 |
|
} else { |
| 823 |
|
$self->{onerror}->(node => $_->[2], |
| 824 |
|
type => { |
| 825 |
|
any => 'no referenced element', ## TODOC: type |
| 826 |
|
form => 'no referenced form', |
| 827 |
|
labelable => 'no referenced control', |
| 828 |
|
menu => 'no referenced menu', |
| 829 |
|
datalist => 'no referenced datalist', ## TODOC: type |
| 830 |
|
}->{$_->[0]}, |
| 831 |
|
value => $_->[1], |
| 832 |
level => $self->{level}->{must}); |
level => $self->{level}->{must}); |
| 833 |
} |
} |
| 834 |
} |
} |
| 837 |
delete $self->{minus_elements}; |
delete $self->{minus_elements}; |
| 838 |
delete $self->{onerror}; |
delete $self->{onerror}; |
| 839 |
delete $self->{id}; |
delete $self->{id}; |
| 840 |
|
delete $self->{id_type}; |
| 841 |
delete $self->{form}; |
delete $self->{form}; |
| 842 |
|
delete $self->{has_autofocus}; |
| 843 |
|
delete $self->{idref}; |
| 844 |
delete $self->{usemap}; |
delete $self->{usemap}; |
| 845 |
delete $self->{ref}; |
delete $self->{ref}; |
| 846 |
delete $self->{template}; |
delete $self->{template}; |