6 |
|
|
7 |
my $ATOM_NS = q<http://www.w3.org/2005/Atom>; |
my $ATOM_NS = q<http://www.w3.org/2005/Atom>; |
8 |
my $THR_NS = q<http://purl.org/syndication/thread/1.0>; |
my $THR_NS = q<http://purl.org/syndication/thread/1.0>; |
9 |
|
my $FH_NS = q<http://purl.org/syndication/history/1.0>; |
10 |
my $LINK_REL = q<http://www.iana.org/assignments/relation/>; |
my $LINK_REL = q<http://www.iana.org/assignments/relation/>; |
11 |
|
|
12 |
sub FEATURE_RFC4287 () { |
sub FEATURE_RFC4287 () { |
451 |
## ISSUE: Where |thr:in-reply-to| is allowed is not explicit;y |
## ISSUE: Where |thr:in-reply-to| is allowed is not explicit;y |
452 |
## defined in RFC 4685. |
## defined in RFC 4685. |
453 |
# |
# |
454 |
|
} elsif ($child_nsuri eq $THR_NS and $child_ln eq 'total') { |
455 |
|
# |
456 |
} else { |
} else { |
457 |
## TODO: extension element |
## TODO: extension element |
458 |
$self->{onerror}->(node => $child_el, type => 'element not allowed'); |
$self->{onerror}->(node => $child_el, type => 'element not allowed'); |
706 |
} |
} |
707 |
} |
} |
708 |
|
|
709 |
if ($value =~ m![+/][Xx][Mm][Ll]\z!) { |
if ({text => 1, html => 1, xhtml => 1}->{$value}) { |
710 |
|
# |
711 |
|
} elsif ($value =~ m![+/][Xx][Mm][Ll]\z!) { |
712 |
## ISSUE: There is no definition for "XML media type" in RFC 3023. |
## ISSUE: There is no definition for "XML media type" in RFC 3023. |
713 |
## Is |application/xml-dtd| an XML media type? |
## Is |application/xml-dtd| an XML media type? |
714 |
$value = 'xml'; |
$value = 'xml'; |
1043 |
}); |
}); |
1044 |
|
|
1045 |
## TODO: Warn if unregistered |
## TODO: Warn if unregistered |
1046 |
|
|
1047 |
|
## TODO: rel=license [RFC 4946] |
1048 |
|
## MUST NOT multiple rel=license with same href="",type="" pairs |
1049 |
|
## href="" SHOULD be dereferencable |
1050 |
|
## title="" SHOULD be there if multiple rel=license |
1051 |
|
## MUST NOT "unspecified" and other rel=license |
1052 |
}, |
}, |
1053 |
title => sub { }, # No MUST |
title => sub { }, # No MUST |
1054 |
type => $AtomIMTAttrChecker, |
type => $AtomIMTAttrChecker, |
1060 |
rel => FEATURE_RFC4287, |
rel => FEATURE_RFC4287, |
1061 |
title => FEATURE_RFC4287, |
title => FEATURE_RFC4287, |
1062 |
type => FEATURE_RFC4287, |
type => FEATURE_RFC4287, |
1063 |
|
|
1064 |
|
## TODO: thr:count |
1065 |
|
## TODO: thr:updated |
1066 |
}), |
}), |
1067 |
check_start => sub { |
check_start => sub { |
1068 |
my ($self, $item, $element_state) = @_; |
my ($self, $item, $element_state) = @_; |
1111 |
|
|
1112 |
$Element->{$ATOM_NS}->{published} = \%AtomDateConstruct; |
$Element->{$ATOM_NS}->{published} = \%AtomDateConstruct; |
1113 |
|
|
1114 |
$Element->{$ATOM_NS}->{rights} = \%AtomDateConstruct; |
$Element->{$ATOM_NS}->{rights} = \%AtomTextConstruct; |
1115 |
## NOTE: SHOULD NOT be used to convey machine-readable information. |
## NOTE: SHOULD NOT be used to convey machine-readable information. |
1116 |
|
|
1117 |
$Element->{$ATOM_NS}->{source} = { |
$Element->{$ATOM_NS}->{source} = { |
1147 |
$not_allowed = 1; |
$not_allowed = 1; |
1148 |
} |
} |
1149 |
} elsif ($child_ln eq 'link') { |
} elsif ($child_ln eq 'link') { |
1150 |
if ($child_ln->rel eq $LINK_REL . 'alternate') { |
if ($child_el->rel eq $LINK_REL . 'alternate') { |
1151 |
my $type = $child_ln->get_attribute_ns (undef, 'type'); |
my $type = $child_el->get_attribute_ns (undef, 'type'); |
1152 |
$type = '' unless defined $type; |
$type = '' unless defined $type; |
1153 |
my $hreflang = $child_ln->get_attribute_ns (undef, 'hreflang'); |
my $hreflang = $child_el->get_attribute_ns (undef, 'hreflang'); |
1154 |
$hreflang = '' unless defined $hreflang; |
$hreflang = '' unless defined $hreflang; |
1155 |
my $key = 'link:'.(defined $type ? ':'.$type : '').':'. |
my $key = 'link:'.(defined $type ? ':'.$type : '').':'. |
1156 |
(defined $hreflang ? ':'.$hreflang : ''); |
(defined $hreflang ? ':'.$hreflang : ''); |
1258 |
## NOTE: Content model has no constraint. |
## NOTE: Content model has no constraint. |
1259 |
}; |
}; |
1260 |
|
|
1261 |
|
$Element->{$THR_NS}->{total} = { |
1262 |
|
%AtomChecker, |
1263 |
|
check_start => sub { |
1264 |
|
my ($self, $item, $element_state) = @_; |
1265 |
|
$element_state->{value} = ''; |
1266 |
|
}, |
1267 |
|
check_child_element => sub { |
1268 |
|
my ($self, $item, $child_el, $child_nsuri, $child_ln, |
1269 |
|
$child_is_transparent, $element_state) = @_; |
1270 |
|
|
1271 |
|
if ($self->{minus_elements}->{$child_nsuri}->{$child_ln}) { |
1272 |
|
$self->{onerror}->(node => $child_el, |
1273 |
|
type => 'element not allowed:minus', |
1274 |
|
level => $self->{must_level}); |
1275 |
|
} elsif ($self->{plus_elements}->{$child_nsuri}->{$child_ln}) { |
1276 |
|
# |
1277 |
|
} else { |
1278 |
|
$self->{onerror}->(node => $child_el, |
1279 |
|
type => 'element not allowed', |
1280 |
|
level => $self->{must_level}); |
1281 |
|
} |
1282 |
|
}, |
1283 |
|
check_child_text => sub { |
1284 |
|
my ($self, $item, $child_node, $has_significant, $element_state) = @_; |
1285 |
|
$element_state->{value} .= $child_node->data; |
1286 |
|
}, |
1287 |
|
check_end => sub { |
1288 |
|
my ($self, $item, $element_state) = @_; |
1289 |
|
|
1290 |
|
## NOTE: xsd:nonNegativeInteger |
1291 |
|
unless ($element_state->{value} =~ /\A(?>[0-9]+|-0+)\z/) { |
1292 |
|
$self->{onerror}->(node => $item->{node}, |
1293 |
|
type => 'syntax error', ## TODO: |
1294 |
|
level => $self->{must_level}); |
1295 |
|
} |
1296 |
|
|
1297 |
|
$AtomChecker{check_end}->(@_); |
1298 |
|
}, |
1299 |
|
}; |
1300 |
|
|
1301 |
|
## TODO: fh:complete |
1302 |
|
|
1303 |
|
## TODO: fh:archive |
1304 |
|
|
1305 |
|
## TODO: Check as archive document, page feed document, ... |
1306 |
|
|
1307 |
|
## TODO: APP [RFC 5023] |
1308 |
|
|
1309 |
$Whatpm::ContentChecker::Namespace->{$ATOM_NS}->{loaded} = 1; |
$Whatpm::ContentChecker::Namespace->{$ATOM_NS}->{loaded} = 1; |
1310 |
$Whatpm::ContentChecker::Namespace->{$THR_NS}->{loaded} = 1; |
$Whatpm::ContentChecker::Namespace->{$THR_NS}->{loaded} = 1; |
1311 |
|
|