3 |
|
|
4 |
## ANY |
## ANY |
5 |
my $AnyChecker = sub { |
my $AnyChecker = sub { |
6 |
my ($self, $el) = @_; |
my ($self, $todo) = @_; |
7 |
my $children = []; |
my $el = $todo->{node}; |
8 |
|
my $new_todos = []; |
9 |
my @nodes = (@{$el->child_nodes}); |
my @nodes = (@{$el->child_nodes}); |
10 |
while (@nodes) { |
while (@nodes) { |
11 |
my $node = shift @nodes; |
my $node = shift @nodes; |
19 |
if ($self->{minuses}->{$node_ns}->{$node_ln}) { |
if ($self->{minuses}->{$node_ns}->{$node_ln}) { |
20 |
$self->{onerror}->(node => $node, type => 'element not allowed'); |
$self->{onerror}->(node => $node, type => 'element not allowed'); |
21 |
} |
} |
22 |
push @$children, $node; |
push @$new_todos, {type => 'element', node => $node}; |
23 |
} elsif ($nt == 5) { |
} elsif ($nt == 5) { |
24 |
unshift @nodes, @{$node->child_nodes}; |
unshift @nodes, @{$node->child_nodes}; |
25 |
} |
} |
26 |
} |
} |
27 |
return ($children); |
return ($new_todos); |
28 |
}; # $AnyChecker |
}; # $AnyChecker |
29 |
|
|
30 |
my $ElementDefault = { |
my $ElementDefault = { |
31 |
checker => sub { |
checker => sub { |
32 |
my ($self, $el) = @_; |
my ($self, $todo) = @_; |
33 |
$self->{onerror}->(node => $el, type => 'element not supported'); |
$self->{onerror}->(node => $todo->{node}, type => 'element not supported'); |
34 |
return $AnyChecker->($self, $el); |
return $AnyChecker->($self, $todo); |
35 |
}, |
}, |
36 |
}; |
}; |
37 |
|
|
171 |
|
|
172 |
## Empty |
## Empty |
173 |
my $HTMLEmptyChecker = sub { |
my $HTMLEmptyChecker = sub { |
174 |
my ($self, $el) = @_; |
my ($self, $todo) = @_; |
175 |
my $children = []; |
my $el = $todo->{node}; |
176 |
|
my $new_todos = []; |
177 |
my @nodes = (@{$el->child_nodes}); |
my @nodes = (@{$el->child_nodes}); |
178 |
|
|
179 |
while (@nodes) { |
while (@nodes) { |
186 |
$self->{onerror}->(node => $node, type => 'element not allowed'); |
$self->{onerror}->(node => $node, type => 'element not allowed'); |
187 |
my ($sib, $ch) = $self->_check_get_children ($node); |
my ($sib, $ch) = $self->_check_get_children ($node); |
188 |
unshift @nodes, @$sib; |
unshift @nodes, @$sib; |
189 |
push @$children, @$ch; |
push @$new_todos, @$ch; |
190 |
} elsif ($nt == 3 or $nt == 4) { |
} elsif ($nt == 3 or $nt == 4) { |
191 |
if ($node->data =~ /[^\x09-\x0D\x20]/) { |
if ($node->data =~ /[^\x09-\x0D\x20]/) { |
192 |
$self->{onerror}->(node => $node, type => 'character not allowed'); |
$self->{onerror}->(node => $node, type => 'character not allowed'); |
195 |
unshift @nodes, @{$node->child_nodes}; |
unshift @nodes, @{$node->child_nodes}; |
196 |
} |
} |
197 |
} |
} |
198 |
return ($children); |
return ($new_todos); |
199 |
}; |
}; |
200 |
|
|
201 |
## Text |
## Text |
202 |
my $HTMLTextChecker = sub { |
my $HTMLTextChecker = sub { |
203 |
my ($self, $el) = @_; |
my ($self, $todo) = @_; |
204 |
my $children = []; |
my $el = $todo->{node}; |
205 |
|
my $new_todos = []; |
206 |
my @nodes = (@{$el->child_nodes}); |
my @nodes = (@{$el->child_nodes}); |
207 |
|
|
208 |
while (@nodes) { |
while (@nodes) { |
215 |
$self->{onerror}->(node => $node, type => 'element not allowed'); |
$self->{onerror}->(node => $node, type => 'element not allowed'); |
216 |
my ($sib, $ch) = $self->_check_get_children ($node); |
my ($sib, $ch) = $self->_check_get_children ($node); |
217 |
unshift @nodes, @$sib; |
unshift @nodes, @$sib; |
218 |
push @$children, @$ch; |
push @$new_todos, @$ch; |
219 |
} elsif ($nt == 5) { |
} elsif ($nt == 5) { |
220 |
unshift @nodes, @{$node->child_nodes}; |
unshift @nodes, @{$node->child_nodes}; |
221 |
} |
} |
222 |
} |
} |
223 |
return ($children); |
return ($new_todos); |
224 |
}; |
}; |
225 |
|
|
226 |
## Zero or more |html:style| elements, |
## Zero or more |html:style| elements, |
227 |
## followed by zero or more block-level elements |
## followed by zero or more block-level elements |
228 |
my $HTMLStylableBlockChecker = sub { |
my $HTMLStylableBlockChecker = sub { |
229 |
my ($self, $el) = @_; |
my ($self, $todo) = @_; |
230 |
my $children = []; |
my $el = $todo->{node}; |
231 |
|
my $new_todos = []; |
232 |
my @nodes = (@{$el->child_nodes}); |
my @nodes = (@{$el->child_nodes}); |
233 |
|
|
234 |
my $has_non_style; |
my $has_non_style; |
261 |
} |
} |
262 |
my ($sib, $ch) = $self->_check_get_children ($node); |
my ($sib, $ch) = $self->_check_get_children ($node); |
263 |
unshift @nodes, @$sib; |
unshift @nodes, @$sib; |
264 |
push @$children, @$ch; |
push @$new_todos, @$ch; |
265 |
} elsif ($nt == 3 or $nt == 4) { |
} elsif ($nt == 3 or $nt == 4) { |
266 |
if ($node->data =~ /[^\x09-\x0D\x20]/) { |
if ($node->data =~ /[^\x09-\x0D\x20]/) { |
267 |
$self->{onerror}->(node => $node, type => 'character not allowed'); |
$self->{onerror}->(node => $node, type => 'character not allowed'); |
270 |
unshift @nodes, @{$node->child_nodes}; |
unshift @nodes, @{$node->child_nodes}; |
271 |
} |
} |
272 |
} |
} |
273 |
return ($children); |
return ($new_todos); |
274 |
}; # $HTMLStylableBlockChecker |
}; # $HTMLStylableBlockChecker |
275 |
|
|
276 |
## Zero or more block-level elements |
## Zero or more block-level elements |
277 |
my $HTMLBlockChecker = sub { |
my $HTMLBlockChecker = sub { |
278 |
my ($self, $el) = @_; |
my ($self, $todo) = @_; |
279 |
my $children = []; |
my $el = $todo->{node}; |
280 |
|
my $new_todos = []; |
281 |
my @nodes = (@{$el->child_nodes}); |
my @nodes = (@{$el->child_nodes}); |
282 |
|
|
283 |
while (@nodes) { |
while (@nodes) { |
302 |
} # CHK |
} # CHK |
303 |
my ($sib, $ch) = $self->_check_get_children ($node); |
my ($sib, $ch) = $self->_check_get_children ($node); |
304 |
unshift @nodes, @$sib; |
unshift @nodes, @$sib; |
305 |
push @$children, @$ch; |
push @$new_todos, @$ch; |
306 |
} elsif ($nt == 3 or $nt == 4) { |
} elsif ($nt == 3 or $nt == 4) { |
307 |
if ($node->data =~ /[^\x09-\x0D\x20]/) { |
if ($node->data =~ /[^\x09-\x0D\x20]/) { |
308 |
$self->{onerror}->(node => $node, type => 'character not allowed'); |
$self->{onerror}->(node => $node, type => 'character not allowed'); |
311 |
unshift @nodes, @{$node->child_nodes}; |
unshift @nodes, @{$node->child_nodes}; |
312 |
} |
} |
313 |
} |
} |
314 |
return ($children); |
return ($new_todos); |
315 |
}; # $HTMLBlockChecker |
}; # $HTMLBlockChecker |
316 |
|
|
317 |
## Inline-level content |
## Inline-level content |
318 |
my $HTMLInlineChecker = sub { |
my $HTMLInlineChecker = sub { |
319 |
my ($self, $el) = @_; |
my ($self, $todo) = @_; |
320 |
my $children = []; |
my $el = $todo->{node}; |
321 |
|
my $new_todos = []; |
322 |
my @nodes = (@{$el->child_nodes}); |
my @nodes = (@{$el->child_nodes}); |
323 |
|
|
324 |
while (@nodes) { |
while (@nodes) { |
344 |
} # CHK |
} # CHK |
345 |
my ($sib, $ch) = $self->_check_get_children ($node); |
my ($sib, $ch) = $self->_check_get_children ($node); |
346 |
unshift @nodes, @$sib; |
unshift @nodes, @$sib; |
347 |
push @$children, @$ch; |
push @$new_todos, @$ch; |
348 |
} elsif ($nt == 5) { |
} elsif ($nt == 5) { |
349 |
unshift @nodes, @{$node->child_nodes}; |
unshift @nodes, @{$node->child_nodes}; |
350 |
} |
} |
351 |
} |
} |
352 |
return ($children); |
|
353 |
}; # $HTMLStrictlyInlineChecker |
for (@$new_todos) { |
354 |
|
$_->{inline} = 1; |
355 |
|
} |
356 |
|
return ($new_todos); |
357 |
|
}; # $HTMLInlineChecker |
358 |
|
|
359 |
my $HTMLSignificantInlineChecker = $HTMLInlineChecker; |
my $HTMLSignificantInlineChecker = $HTMLInlineChecker; |
360 |
## TODO: check significant content |
## TODO: check significant content |
361 |
|
|
362 |
## Strictly inline-level content |
## Strictly inline-level content |
363 |
my $HTMLStrictlyInlineChecker = sub { |
my $HTMLStrictlyInlineChecker = sub { |
364 |
my ($self, $el) = @_; |
my ($self, $todo) = @_; |
365 |
my $children = []; |
my $el = $todo->{node}; |
366 |
|
my $new_todos = []; |
367 |
my @nodes = (@{$el->child_nodes}); |
my @nodes = (@{$el->child_nodes}); |
368 |
|
|
369 |
while (@nodes) { |
while (@nodes) { |
388 |
} # CHK |
} # CHK |
389 |
my ($sib, $ch) = $self->_check_get_children ($node); |
my ($sib, $ch) = $self->_check_get_children ($node); |
390 |
unshift @nodes, @$sib; |
unshift @nodes, @$sib; |
391 |
push @$children, @$ch; |
push @$new_todos, @$ch; |
392 |
} elsif ($nt == 5) { |
} elsif ($nt == 5) { |
393 |
unshift @nodes, @{$node->child_nodes}; |
unshift @nodes, @{$node->child_nodes}; |
394 |
} |
} |
395 |
} |
} |
396 |
return ($children); |
|
397 |
|
for (@$new_todos) { |
398 |
|
$_->{inline} = 1; |
399 |
|
$_->{strictly_inline} = 1; |
400 |
|
} |
401 |
|
return ($new_todos); |
402 |
}; # $HTMLStrictlyInlineChecker |
}; # $HTMLStrictlyInlineChecker |
403 |
|
|
404 |
my $HTMLSignificantStrictlyInlineChecker = $HTMLStrictlyInlineChecker; |
my $HTMLSignificantStrictlyInlineChecker = $HTMLStrictlyInlineChecker; |
405 |
## TODO: check significant content |
## TODO: check significant content |
406 |
|
|
407 |
|
## Inline-level or strictly inline-kevek content |
408 |
|
my $HTMLInlineOrStrictlyInlineChecker = sub { |
409 |
|
my ($self, $todo) = @_; |
410 |
|
my $el = $todo->{node}; |
411 |
|
my $new_todos = []; |
412 |
|
my @nodes = (@{$el->child_nodes}); |
413 |
|
|
414 |
|
while (@nodes) { |
415 |
|
my $node = shift @nodes; |
416 |
|
$self->_remove_minuses ($node) and next if ref $node eq 'HASH'; |
417 |
|
|
418 |
|
my $nt = $node->node_type; |
419 |
|
if ($nt == 1) { |
420 |
|
my $node_ns = $node->namespace_uri; |
421 |
|
$node_ns = '' unless defined $node_ns; |
422 |
|
my $node_ln = $node->manakai_local_name; |
423 |
|
if ($self->{minuses}->{$node_ns}->{$node_ln}) { |
424 |
|
$self->{onerror}->(node => $node, type => 'element not allowed'); |
425 |
|
} |
426 |
|
CHK: { |
427 |
|
for (@{$HTMLStrictlyInlineLevelElements}, |
428 |
|
$todo->{strictly_inline} ? () : @{$HTMLStructuredInlineLevelElements}) { |
429 |
|
if ($node->manakai_element_type_match ($_->[0], $_->[1])) { |
430 |
|
last CHK; |
431 |
|
} |
432 |
|
} |
433 |
|
$self->{onerror}->(node => $node, type => 'element not allowed'); |
434 |
|
} # CHK |
435 |
|
my ($sib, $ch) = $self->_check_get_children ($node); |
436 |
|
unshift @nodes, @$sib; |
437 |
|
push @$new_todos, @$ch; |
438 |
|
} elsif ($nt == 5) { |
439 |
|
unshift @nodes, @{$node->child_nodes}; |
440 |
|
} |
441 |
|
} |
442 |
|
|
443 |
|
for (@$new_todos) { |
444 |
|
$_->{inline} = 1; |
445 |
|
$_->{strictly_inline} = 1; |
446 |
|
} |
447 |
|
return ($new_todos); |
448 |
|
}; # $HTMLInlineOrStrictlyInlineChecker |
449 |
|
|
450 |
my $HTMLBlockOrInlineChecker = sub { |
my $HTMLBlockOrInlineChecker = sub { |
451 |
my ($self, $el) = @_; |
my ($self, $todo) = @_; |
452 |
my $children = []; |
my $el = $todo->{node}; |
453 |
|
my $new_todos = []; |
454 |
my @nodes = (@{$el->child_nodes}); |
my @nodes = (@{$el->child_nodes}); |
455 |
|
|
456 |
my $content = 'block-or-inline'; # or 'block' or 'inline' |
my $content = 'block-or-inline'; # or 'block' or 'inline' |
517 |
} |
} |
518 |
my ($sib, $ch) = $self->_check_get_children ($node); |
my ($sib, $ch) = $self->_check_get_children ($node); |
519 |
unshift @nodes, @$sib; |
unshift @nodes, @$sib; |
520 |
push @$children, @$ch; |
push @$new_todos, @$ch; |
521 |
} elsif ($nt == 3 or $nt == 4) { |
} elsif ($nt == 3 or $nt == 4) { |
522 |
if ($node->data =~ /[^\x09-\x0D\x20]/) { |
if ($node->data =~ /[^\x09-\x0D\x20]/) { |
523 |
if ($content eq 'block') { |
if ($content eq 'block') { |
533 |
unshift @nodes, @{$node->child_nodes}; |
unshift @nodes, @{$node->child_nodes}; |
534 |
} |
} |
535 |
} |
} |
536 |
return ($children); |
|
537 |
|
if ($content eq 'inline') { |
538 |
|
for (@$new_todos) { |
539 |
|
$_->{inline} = 1; |
540 |
|
} |
541 |
|
} |
542 |
|
return ($new_todos); |
543 |
}; |
}; |
544 |
|
|
545 |
## Zero or more XXX element, then either block-level or inline-level |
## Zero or more XXX element, then either block-level or inline-level |
546 |
my $GetHTMLZeroOrMoreThenBlockOrInlineChecker = sub ($$) { |
my $GetHTMLZeroOrMoreThenBlockOrInlineChecker = sub ($$) { |
547 |
my ($elnsuri, $ellname) = @_; |
my ($elnsuri, $ellname) = @_; |
548 |
return sub { |
return sub { |
549 |
my ($self, $el) = @_; |
my ($self, $todo) = @_; |
550 |
my $children = []; |
my $el = $todo->{node}; |
551 |
|
my $new_todos = []; |
552 |
my @nodes = (@{$el->child_nodes}); |
my @nodes = (@{$el->child_nodes}); |
553 |
|
|
554 |
my $has_non_style; |
my $has_non_style; |
623 |
} |
} |
624 |
my ($sib, $ch) = $self->_check_get_children ($node); |
my ($sib, $ch) = $self->_check_get_children ($node); |
625 |
unshift @nodes, @$sib; |
unshift @nodes, @$sib; |
626 |
push @$children, @$ch; |
push @$new_todos, @$ch; |
627 |
} elsif ($nt == 3 or $nt == 4) { |
} elsif ($nt == 3 or $nt == 4) { |
628 |
if ($node->data =~ /[^\x09-\x0D\x20]/) { |
if ($node->data =~ /[^\x09-\x0D\x20]/) { |
629 |
$has_non_style = 1; |
$has_non_style = 1; |
640 |
unshift @nodes, @{$node->child_nodes}; |
unshift @nodes, @{$node->child_nodes}; |
641 |
} |
} |
642 |
} |
} |
643 |
return ($children); |
|
644 |
|
if ($content eq 'inline') { |
645 |
|
for (@$new_todos) { |
646 |
|
$_->{inline} = 1; |
647 |
|
} |
648 |
|
} |
649 |
|
return ($new_todos); |
650 |
}; |
}; |
651 |
}; # $GetHTMLZeroOrMoreThenBlockOrInlineChecker |
}; # $GetHTMLZeroOrMoreThenBlockOrInlineChecker |
652 |
|
|
654 |
|
|
655 |
$Element->{$HTML_NS}->{html} = { |
$Element->{$HTML_NS}->{html} = { |
656 |
checker => sub { |
checker => sub { |
657 |
my ($self, $el) = @_; |
my ($self, $todo) = @_; |
658 |
my $children = []; |
my $el = $todo->{node}; |
659 |
|
my $new_todos = []; |
660 |
my @nodes = (@{$el->child_nodes}); |
my @nodes = (@{$el->child_nodes}); |
661 |
|
|
662 |
my $phase = 'before head'; |
my $phase = 'before head'; |
696 |
} |
} |
697 |
my ($sib, $ch) = $self->_check_get_children ($node); |
my ($sib, $ch) = $self->_check_get_children ($node); |
698 |
unshift @nodes, @$sib; |
unshift @nodes, @$sib; |
699 |
push @$children, @$ch; |
push @$new_todos, @$ch; |
700 |
} elsif ($nt == 3 or $nt == 4) { |
} elsif ($nt == 3 or $nt == 4) { |
701 |
if ($node->data =~ /[^\x09-\x0D\x20]/) { |
if ($node->data =~ /[^\x09-\x0D\x20]/) { |
702 |
$self->{onerror}->(node => $node, type => 'character not allowed'); |
$self->{onerror}->(node => $node, type => 'character not allowed'); |
713 |
$self->{onerror}->(node => $el, type => 'child element missing:body'); |
$self->{onerror}->(node => $el, type => 'child element missing:body'); |
714 |
} |
} |
715 |
|
|
716 |
return ($children); |
return ($new_todos); |
717 |
}, |
}, |
718 |
}; |
}; |
719 |
|
|
720 |
$Element->{$HTML_NS}->{head} = { |
$Element->{$HTML_NS}->{head} = { |
721 |
checker => sub { |
checker => sub { |
722 |
my ($self, $el) = @_; |
my ($self, $todo) = @_; |
723 |
my $children = []; |
my $el = $todo->{node}; |
724 |
|
my $new_todos = []; |
725 |
my @nodes = (@{$el->child_nodes}); |
my @nodes = (@{$el->child_nodes}); |
726 |
|
|
727 |
my $has_title; |
my $has_title; |
775 |
} |
} |
776 |
my ($sib, $ch) = $self->_check_get_children ($node); |
my ($sib, $ch) = $self->_check_get_children ($node); |
777 |
unshift @nodes, @$sib; |
unshift @nodes, @$sib; |
778 |
push @$children, @$ch; |
push @$new_todos, @$ch; |
779 |
} elsif ($nt == 3 or $nt == 4) { |
} elsif ($nt == 3 or $nt == 4) { |
780 |
if ($node->data =~ /[^\x09-\x0D\x20]/) { |
if ($node->data =~ /[^\x09-\x0D\x20]/) { |
781 |
$self->{onerror}->(node => $node, type => 'character not allowed'); |
$self->{onerror}->(node => $node, type => 'character not allowed'); |
787 |
unless ($has_title) { |
unless ($has_title) { |
788 |
$self->{onerror}->(node => $el, type => 'child element missing:title'); |
$self->{onerror}->(node => $el, type => 'child element missing:title'); |
789 |
} |
} |
790 |
return ($children); |
return ($new_todos); |
791 |
}, |
}, |
792 |
}; |
}; |
793 |
|
|
864 |
|
|
865 |
$Element->{$HTML_NS}->{footer} = { |
$Element->{$HTML_NS}->{footer} = { |
866 |
checker => sub { ## block -hn -header -footer -sectioning or inline |
checker => sub { ## block -hn -header -footer -sectioning or inline |
867 |
my ($self, $el) = @_; |
my ($self, $todo) = @_; |
868 |
my $children = []; |
my $el = $todo->{node}; |
869 |
|
my $new_todos = []; |
870 |
my @nodes = (@{$el->child_nodes}); |
my @nodes = (@{$el->child_nodes}); |
871 |
|
|
872 |
my $content = 'block-or-inline'; # or 'block' or 'inline' |
my $content = 'block-or-inline'; # or 'block' or 'inline' |
940 |
} |
} |
941 |
my ($sib, $ch) = $self->_check_get_children ($node); |
my ($sib, $ch) = $self->_check_get_children ($node); |
942 |
unshift @nodes, @$sib; |
unshift @nodes, @$sib; |
943 |
push @$children, @$ch; |
push @$new_todos, @$ch; |
944 |
} elsif ($nt == 3 or $nt == 4) { |
} elsif ($nt == 3 or $nt == 4) { |
945 |
if ($node->data =~ /[^\x09-\x0D\x20]/) { |
if ($node->data =~ /[^\x09-\x0D\x20]/) { |
946 |
if ($content eq 'block') { |
if ($content eq 'block') { |
960 |
my $end = $self->_add_minuses |
my $end = $self->_add_minuses |
961 |
({$HTML_NS => {qw/h1 1 h2 1 h3 1 h4 1 h5 1 h6 1/}}, |
({$HTML_NS => {qw/h1 1 h2 1 h3 1 h4 1 h5 1 h6 1/}}, |
962 |
$HTMLSectioningElements); |
$HTMLSectioningElements); |
963 |
push @$children, $end; |
push @$new_todos, $end; |
964 |
|
|
965 |
return ($children); |
if ($content eq 'inline') { |
966 |
|
for (@$new_todos) { |
967 |
|
$_->{inline} = 1; |
968 |
|
} |
969 |
|
} |
970 |
|
|
971 |
|
return ($new_todos); |
972 |
}, |
}, |
973 |
}; |
}; |
974 |
|
|
990 |
|
|
991 |
$Element->{$HTML_NS}->{dialog} = { |
$Element->{$HTML_NS}->{dialog} = { |
992 |
checker => sub { |
checker => sub { |
993 |
my ($self, $el) = @_; |
my ($self, $todo) = @_; |
994 |
my $children = []; |
my $el = $todo->{node}; |
995 |
|
my $new_todos = []; |
996 |
my @nodes = (@{$el->child_nodes}); |
my @nodes = (@{$el->child_nodes}); |
997 |
|
|
998 |
my $phase = 'before dt'; |
my $phase = 'before dt'; |
1026 |
} |
} |
1027 |
my ($sib, $ch) = $self->_check_get_children ($node); |
my ($sib, $ch) = $self->_check_get_children ($node); |
1028 |
unshift @nodes, @$sib; |
unshift @nodes, @$sib; |
1029 |
push @$children, @$ch; |
push @$new_todos, @$ch; |
1030 |
} elsif ($nt == 3 or $nt == 4) { |
} elsif ($nt == 3 or $nt == 4) { |
1031 |
if ($node->data =~ /[^\x09-\x0D\x20]/) { |
if ($node->data =~ /[^\x09-\x0D\x20]/) { |
1032 |
$self->{onerror}->(node => $node, type => 'character not allowed'); |
$self->{onerror}->(node => $node, type => 'character not allowed'); |
1038 |
if ($phase eq 'before dd') { |
if ($phase eq 'before dd') { |
1039 |
$self->{onerror}->(node => $el, type => 'ps element missing:dd'); |
$self->{onerror}->(node => $el, type => 'ps element missing:dd'); |
1040 |
} |
} |
1041 |
return ($children); |
return ($new_todos); |
1042 |
}, |
}, |
1043 |
}; |
}; |
1044 |
|
|
1048 |
|
|
1049 |
$Element->{$HTML_NS}->{ol} = { |
$Element->{$HTML_NS}->{ol} = { |
1050 |
checker => sub { |
checker => sub { |
1051 |
my ($self, $el) = @_; |
my ($self, $todo) = @_; |
1052 |
my $children = []; |
my $el = $todo->{node}; |
1053 |
|
my $new_todos = []; |
1054 |
my @nodes = (@{$el->child_nodes}); |
my @nodes = (@{$el->child_nodes}); |
1055 |
|
|
1056 |
while (@nodes) { |
while (@nodes) { |
1065 |
} |
} |
1066 |
my ($sib, $ch) = $self->_check_get_children ($node); |
my ($sib, $ch) = $self->_check_get_children ($node); |
1067 |
unshift @nodes, @$sib; |
unshift @nodes, @$sib; |
1068 |
push @$children, @$ch; |
push @$new_todos, @$ch; |
1069 |
} elsif ($nt == 3 or $nt == 4) { |
} elsif ($nt == 3 or $nt == 4) { |
1070 |
if ($node->data =~ /[^\x09-\x0D\x20]/) { |
if ($node->data =~ /[^\x09-\x0D\x20]/) { |
1071 |
$self->{onerror}->(node => $node, type => 'character not allowed'); |
$self->{onerror}->(node => $node, type => 'character not allowed'); |
1074 |
unshift @nodes, @{$node->child_nodes}; |
unshift @nodes, @{$node->child_nodes}; |
1075 |
} |
} |
1076 |
} |
} |
1077 |
return ($children); |
|
1078 |
|
if ($todo->{inline}) { |
1079 |
|
for (@$new_todos) { |
1080 |
|
$_->{inline} = 1; |
1081 |
|
} |
1082 |
|
} |
1083 |
|
return ($new_todos); |
1084 |
}, |
}, |
1085 |
}; |
}; |
1086 |
|
|
1092 |
|
|
1093 |
$Element->{$HTML_NS}->{dl} = { |
$Element->{$HTML_NS}->{dl} = { |
1094 |
checker => sub { |
checker => sub { |
1095 |
my ($self, $el) = @_; |
my ($self, $todo) = @_; |
1096 |
my $children = []; |
my $el = $todo->{node}; |
1097 |
|
my $new_todos = []; |
1098 |
my @nodes = (@{$el->child_nodes}); |
my @nodes = (@{$el->child_nodes}); |
1099 |
|
|
1100 |
my $phase = 'before dt'; |
my $phase = 'before dt'; |
1134 |
} |
} |
1135 |
my ($sib, $ch) = $self->_check_get_children ($node); |
my ($sib, $ch) = $self->_check_get_children ($node); |
1136 |
unshift @nodes, @$sib; |
unshift @nodes, @$sib; |
1137 |
push @$children, @$ch; |
push @$new_todos, @$ch; |
1138 |
} elsif ($nt == 3 or $nt == 4) { |
} elsif ($nt == 3 or $nt == 4) { |
1139 |
if ($node->data =~ /[^\x09-\x0D\x20]/) { |
if ($node->data =~ /[^\x09-\x0D\x20]/) { |
1140 |
$self->{onerror}->(node => $node, type => 'character not allowed'); |
$self->{onerror}->(node => $node, type => 'character not allowed'); |
1146 |
if ($phase eq 'in dts') { |
if ($phase eq 'in dts') { |
1147 |
$self->{onerror}->(node => $el, type => 'ps element missing:dd'); |
$self->{onerror}->(node => $el, type => 'ps element missing:dd'); |
1148 |
} |
} |
1149 |
return ($children); |
|
1150 |
|
if ($todo->{inline}) { |
1151 |
|
for (@$new_todos) { |
1152 |
|
$_->{inline} = 1; |
1153 |
|
} |
1154 |
|
} |
1155 |
|
return ($new_todos); |
1156 |
}, |
}, |
1157 |
}; |
}; |
1158 |
|
|
1160 |
checker => $HTMLStrictlyInlineChecker, |
checker => $HTMLStrictlyInlineChecker, |
1161 |
}; |
}; |
1162 |
|
|
1163 |
## TODO: dd |
$Element->{$HTML_NS}->{dd} = { |
1164 |
|
checker => sub { |
1165 |
|
my ($self, $todo) = @_; |
1166 |
|
if ($todo->{inline}) { |
1167 |
|
return $HTMLInlineChecker->($self, $todo); |
1168 |
|
} else { |
1169 |
|
return $HTMLBlockOrInlineChecker->($self, $todo); |
1170 |
|
} |
1171 |
|
}, |
1172 |
|
}; |
1173 |
|
|
1174 |
## TODO: a |
## TODO: a |
1175 |
|
|
1176 |
## TODO: q |
$Element->{$HTML_NS}->{q} = { |
1177 |
|
checker => $HTMLInlineOrStrictlyInlineChecker, |
1178 |
|
}; |
1179 |
|
|
1180 |
$Element->{$HTML_NS}->{cite} = { |
$Element->{$HTML_NS}->{cite} = { |
1181 |
checker => $HTMLStrictlyInlineChecker, |
checker => $HTMLStrictlyInlineChecker, |
1182 |
}; |
}; |
1183 |
|
|
1184 |
## TODO: em |
$Element->{$HTML_NS}->{em} = { |
1185 |
|
checker => $HTMLInlineOrStrictlyInlineChecker, |
1186 |
|
}; |
1187 |
|
|
1188 |
|
$Element->{$HTML_NS}->{strong} = { |
1189 |
|
checker => $HTMLInlineOrStrictlyInlineChecker, |
1190 |
|
}; |
1191 |
|
|
1192 |
## TODO: strong, small, m, dfn |
$Element->{$HTML_NS}->{small} = { |
1193 |
|
checker => $HTMLInlineOrStrictlyInlineChecker, |
1194 |
|
}; |
1195 |
|
|
1196 |
|
$Element->{$HTML_NS}->{m} = { |
1197 |
|
checker => $HTMLInlineOrStrictlyInlineChecker, |
1198 |
|
}; |
1199 |
|
|
1200 |
|
$Element->{$HTML_NS}->{dfn} = { |
1201 |
|
checker => sub { |
1202 |
|
my ($self, $todo) = @_; |
1203 |
|
|
1204 |
|
my $end = $self->_add_minuses ({$HTML_NS => {dfn => 1}}); |
1205 |
|
my ($sib, $ch) = $HTMLStrictlyInlineChecker->($self, $todo); |
1206 |
|
push @$sib, $end; |
1207 |
|
return ($sib, $ch); |
1208 |
|
}, |
1209 |
|
}; |
1210 |
|
|
1211 |
$Element->{$HTML_NS}->{abbr} = { |
$Element->{$HTML_NS}->{abbr} = { |
1212 |
checker => $HTMLStrictlyInlineChecker, |
checker => $HTMLStrictlyInlineChecker, |
1224 |
checker => $HTMLStrictlyInlineChecker, |
checker => $HTMLStrictlyInlineChecker, |
1225 |
}; |
}; |
1226 |
|
|
1227 |
## TODO: code |
$Element->{$HTML_NS}->{code} = { |
1228 |
|
checker => $HTMLInlineOrStrictlyInlineChecker, |
1229 |
|
}; |
1230 |
|
|
1231 |
$Element->{$HTML_NS}->{var} = { |
$Element->{$HTML_NS}->{var} = { |
1232 |
checker => $HTMLStrictlyInlineChecker, |
checker => $HTMLStrictlyInlineChecker, |
1233 |
}; |
}; |
1234 |
|
|
1235 |
## TODO: samp |
$Element->{$HTML_NS}->{samp} = { |
1236 |
|
checker => $HTMLInlineOrStrictlyInlineChecker, |
1237 |
|
}; |
1238 |
|
|
1239 |
$Element->{$HTML_NS}->{kbd} = { |
$Element->{$HTML_NS}->{kbd} = { |
1240 |
checker => $HTMLStrictlyInlineChecker, |
checker => $HTMLStrictlyInlineChecker, |
1248 |
checker => $HTMLStrictlyInlineChecker, |
checker => $HTMLStrictlyInlineChecker, |
1249 |
}; |
}; |
1250 |
|
|
1251 |
## TODO: span |
$Element->{$HTML_NS}->{span} = { |
1252 |
|
checker => $HTMLInlineOrStrictlyInlineChecker, |
1253 |
|
}; |
1254 |
|
|
1255 |
$Element->{$HTML_NS}->{i} = { |
$Element->{$HTML_NS}->{i} = { |
1256 |
checker => $HTMLStrictlyInlineChecker, |
checker => $HTMLStrictlyInlineChecker, |
1270 |
|
|
1271 |
$Element->{$HTML_NS}->{del} = { |
$Element->{$HTML_NS}->{del} = { |
1272 |
checker => sub { |
checker => sub { |
1273 |
my ($self, $el) = @_; |
my ($self, $todo) = @_; |
1274 |
|
|
1275 |
my $parent = $el->manakai_parent_element; |
my $parent = $todo->{node}->manakai_parent_element; |
1276 |
if (defined $parent) { |
if (defined $parent) { |
1277 |
my $nsuri = $parent->namespace_uri; |
my $nsuri = $parent->namespace_uri; |
1278 |
$nsuri = '' unless defined $nsuri; |
$nsuri = '' unless defined $nsuri; |
1280 |
my $eldef = $Element->{$nsuri}->{$ln} || |
my $eldef = $Element->{$nsuri}->{$ln} || |
1281 |
$Element->{$nsuri}->{''} || |
$Element->{$nsuri}->{''} || |
1282 |
$ElementDefault; |
$ElementDefault; |
1283 |
return $eldef->{checker}->($self, $el); |
return $eldef->{checker}->($self, $todo); |
1284 |
} else { |
} else { |
1285 |
return $HTMLBlockOrInlineChecker->($self, $el); |
return $HTMLBlockOrInlineChecker->($self, $todo); |
1286 |
} |
} |
1287 |
}, |
}, |
1288 |
}; |
}; |
1309 |
|
|
1310 |
$Element->{$HTML_NS}->{video} = { |
$Element->{$HTML_NS}->{video} = { |
1311 |
checker => sub { |
checker => sub { |
1312 |
my ($self, $el) = @_; |
my ($self, $todo) = @_; |
1313 |
|
|
1314 |
if ($el->has_attribute_ns (undef, 'src')) { |
if ($todo->{node}->has_attribute_ns (undef, 'src')) { |
1315 |
return $HTMLBlockOrInlineChecker->($self, $el); |
return $HTMLBlockOrInlineChecker->($self, $todo); |
1316 |
} else { |
} else { |
1317 |
return $GetHTMLZeroOrMoreThenBlockOrInlineChecker->($HTML_NS, 'source') |
return $GetHTMLZeroOrMoreThenBlockOrInlineChecker->($HTML_NS, 'source') |
1318 |
->($self, $el); |
->($self, $todo); |
1319 |
} |
} |
1320 |
}, |
}, |
1321 |
}; |
}; |
1343 |
|
|
1344 |
$Element->{$HTML_NS}->{table} = { |
$Element->{$HTML_NS}->{table} = { |
1345 |
checker => sub { |
checker => sub { |
1346 |
my ($self, $el) = @_; |
my ($self, $todo) = @_; |
1347 |
my $children = []; |
my $el = $todo->{node}; |
1348 |
|
my $new_todos = []; |
1349 |
my @nodes = (@{$el->child_nodes}); |
my @nodes = (@{$el->child_nodes}); |
1350 |
|
|
1351 |
my $phase = 'before caption'; |
my $phase = 'before caption'; |
1425 |
} |
} |
1426 |
my ($sib, $ch) = $self->_check_get_children ($node); |
my ($sib, $ch) = $self->_check_get_children ($node); |
1427 |
unshift @nodes, @$sib; |
unshift @nodes, @$sib; |
1428 |
push @$children, @$ch; |
push @$new_todos, @$ch; |
1429 |
} elsif ($nt == 3 or $nt == 4) { |
} elsif ($nt == 3 or $nt == 4) { |
1430 |
if ($node->data =~ /[^\x09-\x0D\x20]/) { |
if ($node->data =~ /[^\x09-\x0D\x20]/) { |
1431 |
$self->{onerror}->(node => $node, type => 'character not allowed'); |
$self->{onerror}->(node => $node, type => 'character not allowed'); |
1434 |
unshift @nodes, @{$node->child_nodes}; |
unshift @nodes, @{$node->child_nodes}; |
1435 |
} |
} |
1436 |
} |
} |
1437 |
return ($children); |
return ($new_todos); |
1438 |
}, |
}, |
1439 |
}; |
}; |
1440 |
|
|
1444 |
|
|
1445 |
$Element->{$HTML_NS}->{colgroup} = { |
$Element->{$HTML_NS}->{colgroup} = { |
1446 |
checker => sub { |
checker => sub { |
1447 |
my ($self, $el) = @_; |
my ($self, $todo) = @_; |
1448 |
my $children = []; |
my $el = $todo->{node}; |
1449 |
|
my $new_todos = []; |
1450 |
my @nodes = (@{$el->child_nodes}); |
my @nodes = (@{$el->child_nodes}); |
1451 |
|
|
1452 |
while (@nodes) { |
while (@nodes) { |
1461 |
} |
} |
1462 |
my ($sib, $ch) = $self->_check_get_children ($node); |
my ($sib, $ch) = $self->_check_get_children ($node); |
1463 |
unshift @nodes, @$sib; |
unshift @nodes, @$sib; |
1464 |
push @$children, @$ch; |
push @$new_todos, @$ch; |
1465 |
} elsif ($nt == 3 or $nt == 4) { |
} elsif ($nt == 3 or $nt == 4) { |
1466 |
if ($node->data =~ /[^\x09-\x0D\x20]/) { |
if ($node->data =~ /[^\x09-\x0D\x20]/) { |
1467 |
$self->{onerror}->(node => $node, type => 'character not allowed'); |
$self->{onerror}->(node => $node, type => 'character not allowed'); |
1470 |
unshift @nodes, @{$node->child_nodes}; |
unshift @nodes, @{$node->child_nodes}; |
1471 |
} |
} |
1472 |
} |
} |
1473 |
return ($children); |
return ($new_todos); |
1474 |
}, |
}, |
1475 |
}; |
}; |
1476 |
|
|
1480 |
|
|
1481 |
$Element->{$HTML_NS}->{tbody} = { |
$Element->{$HTML_NS}->{tbody} = { |
1482 |
checker => sub { |
checker => sub { |
1483 |
my ($self, $el) = @_; |
my ($self, $todo) = @_; |
1484 |
my $children = []; |
my $el = $todo->{node}; |
1485 |
|
my $new_todos = []; |
1486 |
my @nodes = (@{$el->child_nodes}); |
my @nodes = (@{$el->child_nodes}); |
1487 |
|
|
1488 |
my $has_tr; |
my $has_tr; |
1500 |
} |
} |
1501 |
my ($sib, $ch) = $self->_check_get_children ($node); |
my ($sib, $ch) = $self->_check_get_children ($node); |
1502 |
unshift @nodes, @$sib; |
unshift @nodes, @$sib; |
1503 |
push @$children, @$ch; |
push @$new_todos, @$ch; |
1504 |
} elsif ($nt == 3 or $nt == 4) { |
} elsif ($nt == 3 or $nt == 4) { |
1505 |
if ($node->data =~ /[^\x09-\x0D\x20]/) { |
if ($node->data =~ /[^\x09-\x0D\x20]/) { |
1506 |
$self->{onerror}->(node => $node, type => 'character not allowed'); |
$self->{onerror}->(node => $node, type => 'character not allowed'); |
1512 |
unless ($has_tr) { |
unless ($has_tr) { |
1513 |
$self->{onerror}->(node => $el, type => 'child element missing:tr'); |
$self->{onerror}->(node => $el, type => 'child element missing:tr'); |
1514 |
} |
} |
1515 |
return ($children); |
return ($new_todos); |
1516 |
}, |
}, |
1517 |
}; |
}; |
1518 |
|
|
1526 |
|
|
1527 |
$Element->{$HTML_NS}->{tr} = { |
$Element->{$HTML_NS}->{tr} = { |
1528 |
checker => sub { |
checker => sub { |
1529 |
my ($self, $el) = @_; |
my ($self, $todo) = @_; |
1530 |
my $children = []; |
my $el = $todo->{node}; |
1531 |
|
my $new_todos = []; |
1532 |
my @nodes = (@{$el->child_nodes}); |
my @nodes = (@{$el->child_nodes}); |
1533 |
|
|
1534 |
my $has_td; |
my $has_td; |
1547 |
} |
} |
1548 |
my ($sib, $ch) = $self->_check_get_children ($node); |
my ($sib, $ch) = $self->_check_get_children ($node); |
1549 |
unshift @nodes, @$sib; |
unshift @nodes, @$sib; |
1550 |
push @$children, @$ch; |
push @$new_todos, @$ch; |
1551 |
} elsif ($nt == 3 or $nt == 4) { |
} elsif ($nt == 3 or $nt == 4) { |
1552 |
if ($node->data =~ /[^\x09-\x0D\x20]/) { |
if ($node->data =~ /[^\x09-\x0D\x20]/) { |
1553 |
$self->{onerror}->(node => $node, type => 'character not allowed'); |
$self->{onerror}->(node => $node, type => 'character not allowed'); |
1559 |
unless ($has_td) { |
unless ($has_td) { |
1560 |
$self->{onerror}->(node => $el, type => 'child element missing:td|th'); |
$self->{onerror}->(node => $el, type => 'child element missing:td|th'); |
1561 |
} |
} |
1562 |
return ($children); |
return ($new_todos); |
1563 |
}, |
}, |
1564 |
}; |
}; |
1565 |
|
|
1575 |
|
|
1576 |
$Element->{$HTML_NS}->{script} = { |
$Element->{$HTML_NS}->{script} = { |
1577 |
checker => sub { |
checker => sub { |
1578 |
my ($self, $el) = @_; |
my ($self, $todo) = @_; |
1579 |
|
|
1580 |
if ($el->has_attribute_ns (undef, 'src')) { |
if ($todo->{node}->has_attribute_ns (undef, 'src')) { |
1581 |
return $HTMLEmptyChecker->($self, $el); |
return $HTMLEmptyChecker->($self, $todo); |
1582 |
} else { |
} else { |
1583 |
## NOTE: No content model conformance in HTML5 spec. |
## NOTE: No content model conformance in HTML5 spec. |
1584 |
return $AnyChecker->($self, $el); |
return $AnyChecker->($self, $todo); |
1585 |
} |
} |
1586 |
}, |
}, |
1587 |
}; |
}; |
1589 |
## NOTE: When script is disabled. |
## NOTE: When script is disabled. |
1590 |
$Element->{$HTML_NS}->{noscript} = { |
$Element->{$HTML_NS}->{noscript} = { |
1591 |
checker => sub { |
checker => sub { |
1592 |
my ($self, $el) = @_; |
my ($self, $todo) = @_; |
1593 |
|
|
1594 |
my $end = $self->_add_minuses ({$HTML_NS => {noscript => 1}}); |
my $end = $self->_add_minuses ({$HTML_NS => {noscript => 1}}); |
1595 |
my ($sib, $ch) = $HTMLBlockOrInlineChecker->($self, $el); |
my ($sib, $ch) = $HTMLBlockOrInlineChecker->($self, $todo); |
1596 |
push @$sib, $end; |
push @$sib, $end; |
1597 |
return ($sib, $ch); |
return ($sib, $ch); |
1598 |
}, |
}, |
1599 |
}; |
}; |
|
## TODO: noscript |
|
1600 |
|
|
1601 |
$Element->{$HTML_NS}->{'event-source'} = { |
$Element->{$HTML_NS}->{'event-source'} = { |
1602 |
checker => $HTMLEmptyChecker, |
checker => $HTMLEmptyChecker, |
1616 |
|
|
1617 |
$Element->{$HTML_NS}->{menu} = { |
$Element->{$HTML_NS}->{menu} = { |
1618 |
checker => sub { |
checker => sub { |
1619 |
my ($self, $el) = @_; |
my ($self, $todo) = @_; |
1620 |
my $children = []; |
my $el = $todo->{node}; |
1621 |
|
my $new_todos = []; |
1622 |
my @nodes = (@{$el->child_nodes}); |
my @nodes = (@{$el->child_nodes}); |
1623 |
|
|
1624 |
my $content = 'li or inline'; |
my $content = 'li or inline'; |
1654 |
} |
} |
1655 |
my ($sib, $ch) = $self->_check_get_children ($node); |
my ($sib, $ch) = $self->_check_get_children ($node); |
1656 |
unshift @nodes, @$sib; |
unshift @nodes, @$sib; |
1657 |
push @$children, @$ch; |
push @$new_todos, @$ch; |
1658 |
} elsif ($nt == 3 or $nt == 4) { |
} elsif ($nt == 3 or $nt == 4) { |
1659 |
if ($node->data =~ /[^\x09-\x0D\x20]/) { |
if ($node->data =~ /[^\x09-\x0D\x20]/) { |
1660 |
if ($content eq 'li') { |
if ($content eq 'li') { |
1667 |
unshift @nodes, @{$node->child_nodes}; |
unshift @nodes, @{$node->child_nodes}; |
1668 |
} |
} |
1669 |
} |
} |
1670 |
return ($children); |
|
1671 |
|
for (@$new_todos) { |
1672 |
|
$_->{inline} = 1; |
1673 |
|
} |
1674 |
|
return ($new_todos); |
1675 |
}, |
}, |
1676 |
}; |
}; |
1677 |
|
|
1699 |
$self->{minuses} = {}; |
$self->{minuses} = {}; |
1700 |
$self->{onerror} = $onerror; |
$self->{onerror} = $onerror; |
1701 |
|
|
1702 |
my @nodes = ($el); |
my @todo = ({type => 'element', node => $el}); |
1703 |
while (@nodes) { |
while (@todo) { |
1704 |
my $node = shift @nodes; |
my $todo = shift @todo; |
1705 |
$self->_remove_minuses ($node) and next if ref $node eq 'HASH'; |
if ($todo->{type} eq 'element') { |
1706 |
|
my $nsuri = $todo->{node}->namespace_uri; |
1707 |
my $nsuri = $node->namespace_uri; |
$nsuri = '' unless defined $nsuri; |
1708 |
$nsuri = '' unless defined $nsuri; |
my $ln = $todo->{node}->manakai_local_name; |
1709 |
my $ln = $node->manakai_local_name; |
my $eldef = $Element->{$nsuri}->{$ln} || |
1710 |
my $eldef = $Element->{$nsuri}->{$ln} || |
$Element->{$nsuri}->{''} || |
1711 |
$Element->{$nsuri}->{''} || |
$ElementDefault; |
1712 |
$ElementDefault; |
my ($new_todos) = $eldef->{checker}->($self, $todo); |
1713 |
my ($children) = $eldef->{checker}->($self, $node); |
push @todo, @$new_todos; |
1714 |
push @nodes, @$children; |
} elsif ($todo->{type} eq 'plus') { |
1715 |
|
$self->_remove_minuses ($todo); |
1716 |
|
} |
1717 |
} |
} |
1718 |
} # check_element |
} # check_element |
1719 |
|
|
1730 |
} |
} |
1731 |
} |
} |
1732 |
} |
} |
1733 |
return $r; |
return {type => 'plus', list => $r}; |
1734 |
} # _add_minuses |
} # _add_minuses |
1735 |
|
|
1736 |
sub _remove_minuses ($$) { |
sub _remove_minuses ($$) { |
1737 |
my ($self, $list) = @_; |
my ($self, $todo) = @_; |
1738 |
for my $ns (keys %{$list}) { |
for my $ns (keys %{$todo->{list}}) { |
1739 |
for my $ln (keys %{$list->{$ns}}) { |
for my $ln (keys %{$todo->{list}->{$ns}}) { |
1740 |
delete $self->{minuses}->{$ns}->{$ln} if $list->{$ns}->{$ln}; |
delete $self->{minuses}->{$ns}->{$ln} if $todo->{list}->{$ns}->{$ln}; |
1741 |
} |
} |
1742 |
} |
} |
1743 |
1; |
1; |
1745 |
|
|
1746 |
sub _check_get_children ($$) { |
sub _check_get_children ($$) { |
1747 |
my ($self, $node) = @_; |
my ($self, $node) = @_; |
1748 |
my $ch = []; |
my $new_todos = []; |
1749 |
my $sib = []; |
my $sib = []; |
1750 |
TP: { |
TP: { |
1751 |
my $node_ns = $node->namespace_uri; |
my $node_ns = $node->namespace_uri; |
1788 |
unshift @$sib, @cn; |
unshift @$sib, @cn; |
1789 |
} |
} |
1790 |
} |
} |
1791 |
push @$ch, $node; |
push @$new_todos, {type => 'element', node => $node}; |
1792 |
} # TP |
} # TP |
1793 |
return ($sib, $ch); |
return ($sib, $new_todos); |
1794 |
} # _check_get_children |
} # _check_get_children |
1795 |
|
|
1796 |
1; |
1; |