| 1925 |
checker => $HTMLStrictlyInlineChecker, |
checker => $HTMLStrictlyInlineChecker, |
| 1926 |
}; |
}; |
| 1927 |
|
|
| 1928 |
$Element->{$HTML_NS}->{time} = { ## TODO: validate content |
$Element->{$HTML_NS}->{time} = { |
| 1929 |
attrs_checker => $GetHTMLAttrsChecker->({}), ## TODO: datetime |
attrs_checker => $GetHTMLAttrsChecker->({ |
| 1930 |
checker => $HTMLStrictlyInlineChecker, |
datetime => sub { 1 }, # checked in |checker| |
| 1931 |
|
}), |
| 1932 |
|
## TODO: Write tests |
| 1933 |
|
checker => sub { |
| 1934 |
|
my ($self, $todo) = @_; |
| 1935 |
|
|
| 1936 |
|
my $attr = $todo->{node}->get_attribute_node_ns (undef, 'datetime'); |
| 1937 |
|
my $input; |
| 1938 |
|
my $reg_sp; |
| 1939 |
|
my $input_node; |
| 1940 |
|
if ($attr) { |
| 1941 |
|
$input = $attr->value; |
| 1942 |
|
$reg_sp = qr/[\x09-\x0D\x20]*/; |
| 1943 |
|
$input_node = $attr; |
| 1944 |
|
} else { |
| 1945 |
|
$input = $todo->{node}->text_content; |
| 1946 |
|
$reg_sp = qr/\p{Zs}*/; |
| 1947 |
|
$input_node = $todo->{node}; |
| 1948 |
|
|
| 1949 |
|
## ISSUE: What is the definition for "successfully extracts a date |
| 1950 |
|
## or time"? If the algorithm says the string is invalid but |
| 1951 |
|
## return some date or time, is it "successfully"? |
| 1952 |
|
} |
| 1953 |
|
|
| 1954 |
|
my $hour; |
| 1955 |
|
my $minute; |
| 1956 |
|
my $second; |
| 1957 |
|
if ($input =~ / |
| 1958 |
|
\A |
| 1959 |
|
[\x09-\x0D\x20]* |
| 1960 |
|
([0-9]+) # 1 |
| 1961 |
|
(?> |
| 1962 |
|
-([0-9]+) # 2 |
| 1963 |
|
-([0-9]+) # 3 |
| 1964 |
|
[\x09-\x0D\x20]* |
| 1965 |
|
(?> |
| 1966 |
|
T |
| 1967 |
|
[\x09-\x0D\x20]* |
| 1968 |
|
)? |
| 1969 |
|
([0-9]+) # 4 |
| 1970 |
|
:([0-9]+) # 5 |
| 1971 |
|
(?> |
| 1972 |
|
:([0-9]+(?>\.[0-9]*)?|\.[0-9]*) # 6 |
| 1973 |
|
)? |
| 1974 |
|
[\x09-\x0D\x20]* |
| 1975 |
|
(?> |
| 1976 |
|
Z |
| 1977 |
|
[\x09-\x0D\x20]* |
| 1978 |
|
| |
| 1979 |
|
[+-]([0-9]+):([0-9]+) # 7, 8 |
| 1980 |
|
[\x09-\x0D\x20]* |
| 1981 |
|
)? |
| 1982 |
|
\z |
| 1983 |
|
| |
| 1984 |
|
:([0-9]+) # 9 |
| 1985 |
|
(?> |
| 1986 |
|
:([0-9]+(?>\.[0-9]*)?|\.[0-9]*) # 10 |
| 1987 |
|
)? |
| 1988 |
|
[\x09-\x0D\x20]*\z |
| 1989 |
|
) |
| 1990 |
|
/x) { |
| 1991 |
|
if (defined $2) { ## YYYY-MM-DD T? hh:mm |
| 1992 |
|
if (length $1 != 4 or length $2 != 2 or length $3 != 2 or |
| 1993 |
|
length $4 != 2 or length $5 != 2) { |
| 1994 |
|
$self->{onerror}->(node => $input_node, |
| 1995 |
|
type => 'dateortime:syntax error'); |
| 1996 |
|
} |
| 1997 |
|
|
| 1998 |
|
if (1 <= $2 and $2 <= 12) { |
| 1999 |
|
$self->{onerror}->(node => $input_node, type => 'datetime:bad day') |
| 2000 |
|
if $3 < 1 or |
| 2001 |
|
$3 > [0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]->[$2]; |
| 2002 |
|
$self->{onerror}->(node => $input_node, type => 'datetime:bad day') |
| 2003 |
|
if $2 == 2 and $3 == 29 and |
| 2004 |
|
not ($1 % 400 == 0 or ($1 % 4 == 0 and $1 % 100 != 0)); |
| 2005 |
|
} else { |
| 2006 |
|
$self->{onerror}->(node => $input_node, |
| 2007 |
|
type => 'datetime:bad month'); |
| 2008 |
|
} |
| 2009 |
|
|
| 2010 |
|
($hour, $minute, $second) = ($4, $5, $6); |
| 2011 |
|
|
| 2012 |
|
if (defined $7) { ## [+-]hh:mm |
| 2013 |
|
if (length $7 != 2 or length $8 != 2) { |
| 2014 |
|
$self->{onerror}->(node => $input_node, |
| 2015 |
|
type => 'dateortime:syntax error'); |
| 2016 |
|
} |
| 2017 |
|
|
| 2018 |
|
$self->{onerror}->(node => $input_node, |
| 2019 |
|
type => 'datetime:bad timezone hour') |
| 2020 |
|
if $7 > 23; |
| 2021 |
|
$self->{onerror}->(node => $input_node, |
| 2022 |
|
type => 'datetime:bad timezone minute') |
| 2023 |
|
if $8 > 59; |
| 2024 |
|
} |
| 2025 |
|
} else { ## hh:mm |
| 2026 |
|
if (length $1 != 2 or length $9 != 2) { |
| 2027 |
|
$self->{onerror}->(node => $input_node, |
| 2028 |
|
type => qq'dateortime:syntax error'); |
| 2029 |
|
} |
| 2030 |
|
|
| 2031 |
|
($hour, $minute, $second) = ($1, $9, $10); |
| 2032 |
|
} |
| 2033 |
|
|
| 2034 |
|
$self->{onerror}->(node => $input_node, type => 'datetime:bad hour') |
| 2035 |
|
if $hour > 23; |
| 2036 |
|
$self->{onerror}->(node => $input_node, type => 'datetime:bad minute') |
| 2037 |
|
if $minute > 59; |
| 2038 |
|
|
| 2039 |
|
if (defined $second) { ## s |
| 2040 |
|
## NOTE: Integer part of second don't have to have length of two. |
| 2041 |
|
|
| 2042 |
|
if (substr ($second, 0, 1) eq '.') { |
| 2043 |
|
$self->{onerror}->(node => $input_node, |
| 2044 |
|
type => 'dateortime:syntax error'); |
| 2045 |
|
} |
| 2046 |
|
|
| 2047 |
|
$self->{onerror}->(node => $input_node, type => 'datetime:bad second') |
| 2048 |
|
if $second >= 60; |
| 2049 |
|
} |
| 2050 |
|
} else { |
| 2051 |
|
$self->{onerror}->(node => $input_node, |
| 2052 |
|
type => 'dateortime:syntax error'); |
| 2053 |
|
} |
| 2054 |
|
|
| 2055 |
|
return $HTMLStrictlyInlineChecker->($self, $todo); |
| 2056 |
|
}, |
| 2057 |
}; |
}; |
| 2058 |
|
|
| 2059 |
$Element->{$HTML_NS}->{meter} = { ## TODO: "The recommended way of giving the value is to include it as contents of the element" |
$Element->{$HTML_NS}->{meter} = { ## TODO: "The recommended way of giving the value is to include it as contents of the element" |