| 8 |
## doc.write (''); |
## doc.write (''); |
| 9 |
## alert (doc.compatMode); |
## alert (doc.compatMode); |
| 10 |
|
|
|
## TODO: Control charcters and noncharacters are not allowed (HTML5 revision 1263) |
|
| 11 |
## TODO: 1252 parse error (revision 1264) |
## TODO: 1252 parse error (revision 1264) |
| 12 |
## TODO: 8859-11 = 874 (revision 1271) |
## TODO: 8859-11 = 874 (revision 1271) |
| 13 |
|
|
| 204 |
mtext => FOREIGN_FLOW_CONTENT_EL, |
mtext => FOREIGN_FLOW_CONTENT_EL, |
| 205 |
}, |
}, |
| 206 |
$SVG_NS => { |
$SVG_NS => { |
| 207 |
foreignobject => FOREIGN_FLOW_CONTENT_EL, ## TODO: case |
foreignObject => FOREIGN_FLOW_CONTENT_EL, |
| 208 |
desc => FOREIGN_FLOW_CONTENT_EL, |
desc => FOREIGN_FLOW_CONTENT_EL, |
| 209 |
title => FOREIGN_FLOW_CONTENT_EL, |
title => FOREIGN_FLOW_CONTENT_EL, |
| 210 |
}, |
}, |
| 211 |
## NOTE: In addition, FOREIGN_EL is set to non-HTML elements. |
## NOTE: In addition, FOREIGN_EL is set to non-HTML elements. |
| 212 |
}; |
}; |
| 213 |
|
|
| 214 |
|
my $svg_attr_name = { |
| 215 |
|
attributetype => 'attributeType', |
| 216 |
|
basefrequency => 'baseFrequency', |
| 217 |
|
baseprofile => 'baseProfile', |
| 218 |
|
calcmode => 'calcMode', |
| 219 |
|
clippathunits => 'clipPathUnits', |
| 220 |
|
contentscripttype => 'contentScriptType', |
| 221 |
|
contentstyletype => 'contentStyleType', |
| 222 |
|
diffuseconstant => 'diffuseConstant', |
| 223 |
|
edgemode => 'edgeMode', |
| 224 |
|
externalresourcesrequired => 'externalResourcesRequired', |
| 225 |
|
fecolormatrix => 'feColorMatrix', |
| 226 |
|
fecomposite => 'feComposite', |
| 227 |
|
fegaussianblur => 'feGaussianBlur', |
| 228 |
|
femorphology => 'feMorphology', |
| 229 |
|
fetile => 'feTile', |
| 230 |
|
filterres => 'filterRes', |
| 231 |
|
filterunits => 'filterUnits', |
| 232 |
|
glyphref => 'glyphRef', |
| 233 |
|
gradienttransform => 'gradientTransform', |
| 234 |
|
gradientunits => 'gradientUnits', |
| 235 |
|
kernelmatrix => 'kernelMatrix', |
| 236 |
|
kernelunitlength => 'kernelUnitLength', |
| 237 |
|
keypoints => 'keyPoints', |
| 238 |
|
keysplines => 'keySplines', |
| 239 |
|
keytimes => 'keyTimes', |
| 240 |
|
lengthadjust => 'lengthAdjust', |
| 241 |
|
limitingconeangle => 'limitingConeAngle', |
| 242 |
|
markerheight => 'markerHeight', |
| 243 |
|
markerunits => 'markerUnits', |
| 244 |
|
markerwidth => 'markerWidth', |
| 245 |
|
maskcontentunits => 'maskContentUnits', |
| 246 |
|
maskunits => 'maskUnits', |
| 247 |
|
numoctaves => 'numOctaves', |
| 248 |
|
pathlength => 'pathLength', |
| 249 |
|
patterncontentunits => 'patternContentUnits', |
| 250 |
|
patterntransform => 'patternTransform', |
| 251 |
|
patternunits => 'patternUnits', |
| 252 |
|
pointsatx => 'pointsAtX', |
| 253 |
|
pointsaty => 'pointsAtY', |
| 254 |
|
pointsatz => 'pointsAtZ', |
| 255 |
|
preservealpha => 'preserveAlpha', |
| 256 |
|
preserveaspectratio => 'preserveAspectRatio', |
| 257 |
|
primitiveunits => 'primitiveUnits', |
| 258 |
|
refx => 'refX', |
| 259 |
|
refy => 'refY', |
| 260 |
|
repeatcount => 'repeatCount', |
| 261 |
|
repeatdur => 'repeatDur', |
| 262 |
|
requiredextensions => 'requiredExtensions', |
| 263 |
|
specularconstant => 'specularConstant', |
| 264 |
|
specularexponent => 'specularExponent', |
| 265 |
|
spreadmethod => 'spreadMethod', |
| 266 |
|
startoffset => 'startOffset', |
| 267 |
|
stddeviation => 'stdDeviation', |
| 268 |
|
stitchtiles => 'stitchTiles', |
| 269 |
|
surfacescale => 'surfaceScale', |
| 270 |
|
systemlanguage => 'systemLanguage', |
| 271 |
|
tablevalues => 'tableValues', |
| 272 |
|
targetx => 'targetX', |
| 273 |
|
targety => 'targetY', |
| 274 |
|
textlength => 'textLength', |
| 275 |
|
viewbox => 'viewBox', |
| 276 |
|
viewtarget => 'viewTarget', |
| 277 |
|
xchannelselector => 'xChannelSelector', |
| 278 |
|
ychannelselector => 'yChannelSelector', |
| 279 |
|
zoomandpan => 'zoomAndPan', |
| 280 |
|
}; |
| 281 |
|
|
| 282 |
|
my $foreign_attr_xname = { |
| 283 |
|
'xlink:actuate' => [$XLINK_NS, ['xlink', 'actuate']], |
| 284 |
|
'xlink:arcrole' => [$XLINK_NS, ['xlink', 'arcrole']], |
| 285 |
|
'xlink:href' => [$XLINK_NS, ['xlink', 'href']], |
| 286 |
|
'xlink:role' => [$XLINK_NS, ['xlink', 'role']], |
| 287 |
|
'xlink:show' => [$XLINK_NS, ['xlink', 'show']], |
| 288 |
|
'xlink:title' => [$XLINK_NS, ['xlink', 'title']], |
| 289 |
|
'xlink:type' => [$XLINK_NS, ['xlink', 'type']], |
| 290 |
|
'xml:base' => [$XML_NS, ['xml', 'base']], |
| 291 |
|
'xml:lang' => [$XML_NS, ['xml', 'lang']], |
| 292 |
|
'xml:space' => [$XML_NS, ['xml', 'space']], |
| 293 |
|
'xmlns' => [$XMLNS_NS, [undef, 'xmlns']], |
| 294 |
|
'xmlns:xlink' => [$XMLNS_NS, ['xmlns', 'xlink']], |
| 295 |
|
}; |
| 296 |
|
|
| 297 |
|
## ISSUE: xmlns:xlink="non-xlink-ns" is not an error. |
| 298 |
|
|
| 299 |
my $c1_entity_char = { |
my $c1_entity_char = { |
| 300 |
0x80 => 0x20AC, |
0x80 => 0x20AC, |
| 301 |
0x81 => 0xFFFD, |
0x81 => 0xFFFD, |
| 442 |
$self->{column}++; |
$self->{column}++; |
| 443 |
|
|
| 444 |
if ($self->{next_char} == 0x000A) { # LF |
if ($self->{next_char} == 0x000A) { # LF |
| 445 |
|
!!!cp ('j1'); |
| 446 |
$self->{line}++; |
$self->{line}++; |
| 447 |
$self->{column} = 0; |
$self->{column} = 0; |
| 448 |
} elsif ($self->{next_char} == 0x000D) { # CR |
} elsif ($self->{next_char} == 0x000D) { # CR |
| 449 |
|
!!!cp ('j2'); |
| 450 |
$i++ if substr ($$s, $i, 1) eq "\x0A"; |
$i++ if substr ($$s, $i, 1) eq "\x0A"; |
| 451 |
$self->{next_char} = 0x000A; # LF # MUST |
$self->{next_char} = 0x000A; # LF # MUST |
| 452 |
$self->{line}++; |
$self->{line}++; |
| 453 |
$self->{column} = 0; |
$self->{column} = 0; |
| 454 |
} elsif ($self->{next_char} > 0x10FFFF) { |
} elsif ($self->{next_char} > 0x10FFFF) { |
| 455 |
|
!!!cp ('j3'); |
| 456 |
$self->{next_char} = 0xFFFD; # REPLACEMENT CHARACTER # MUST |
$self->{next_char} = 0xFFFD; # REPLACEMENT CHARACTER # MUST |
| 457 |
} elsif ($self->{next_char} == 0x0000) { # NULL |
} elsif ($self->{next_char} == 0x0000) { # NULL |
| 458 |
|
!!!cp ('j4'); |
| 459 |
!!!parse-error (type => 'NULL'); |
!!!parse-error (type => 'NULL'); |
| 460 |
$self->{next_char} = 0xFFFD; # REPLACEMENT CHARACTER # MUST |
$self->{next_char} = 0xFFFD; # REPLACEMENT CHARACTER # MUST |
| 461 |
|
} elsif ($self->{next_char} <= 0x0008 or |
| 462 |
|
(0x000E <= $self->{next_char} and $self->{next_char} <= 0x001F) or |
| 463 |
|
(0x007F <= $self->{next_char} and $self->{next_char} <= 0x009F) or |
| 464 |
|
(0xD800 <= $self->{next_char} and $self->{next_char} <= 0xDFFF) or |
| 465 |
|
(0xFDD0 <= $self->{next_char} and $self->{next_char} <= 0xFDDF) or |
| 466 |
|
{ |
| 467 |
|
0xFFFE => 1, 0xFFFF => 1, 0x1FFFE => 1, 0x1FFFF => 1, |
| 468 |
|
0x2FFFE => 1, 0x2FFFF => 1, 0x3FFFE => 1, 0x3FFFF => 1, |
| 469 |
|
0x4FFFE => 1, 0x4FFFF => 1, 0x5FFFE => 1, 0x5FFFF => 1, |
| 470 |
|
0x6FFFE => 1, 0x6FFFF => 1, 0x7FFFE => 1, 0x7FFFF => 1, |
| 471 |
|
0x8FFFE => 1, 0x8FFFF => 1, 0x9FFFE => 1, 0x9FFFF => 1, |
| 472 |
|
0xAFFFE => 1, 0xAFFFF => 1, 0xBFFFE => 1, 0xBFFFF => 1, |
| 473 |
|
0xCFFFE => 1, 0xCFFFF => 1, 0xDFFFE => 1, 0xDFFFF => 1, |
| 474 |
|
0xEFFFE => 1, 0xEFFFF => 1, 0xFFFFE => 1, 0xFFFFF => 1, |
| 475 |
|
0x10FFFE => 1, 0x10FFFF => 1, |
| 476 |
|
}->{$self->{next_char}}) { |
| 477 |
|
!!!cp ('j5'); |
| 478 |
|
!!!parse-error (type => 'control char', level => $self->{must_level}); |
| 479 |
|
## TODO: error type documentation |
| 480 |
} |
} |
| 481 |
}; |
}; |
| 482 |
$self->{prev_char} = [-1, -1, -1]; |
$self->{prev_char} = [-1, -1, -1]; |
| 3806 |
!!!cp ('t87.2'); |
!!!cp ('t87.2'); |
| 3807 |
# |
# |
| 3808 |
} elsif ({ |
} elsif ({ |
| 3809 |
## TODO: |
b => 1, big => 1, blockquote => 1, body => 1, br => 1, |
| 3810 |
|
center => 1, code => 1, dd => 1, div => 1, dl => 1, em => 1, |
| 3811 |
|
embed => 1, font => 1, h1 => 1, h2 => 1, h3 => 1, ## No h4! |
| 3812 |
|
h5 => 1, h6 => 1, head => 1, hr => 1, i => 1, img => 1, |
| 3813 |
|
li => 1, menu => 1, meta => 1, nobr => 1, p => 1, pre => 1, |
| 3814 |
|
ruby => 1, s => 1, small => 1, span => 1, strong => 1, |
| 3815 |
|
sub => 1, sup => 1, table => 1, tt => 1, u => 1, ul => 1, |
| 3816 |
|
var => 1, |
| 3817 |
}->{$token->{tag_name}}) { |
}->{$token->{tag_name}}) { |
| 3818 |
!!!cp ('t87.2'); |
!!!cp ('t87.2'); |
| 3819 |
!!!parse-error (type => 'not closed', |
!!!parse-error (type => 'not closed', |
| 3824 |
pop @{$self->{open_elements}} |
pop @{$self->{open_elements}} |
| 3825 |
while $self->{open_elements}->[-1]->[1] & FOREIGN_EL; |
while $self->{open_elements}->[-1]->[1] & FOREIGN_EL; |
| 3826 |
|
|
| 3827 |
$self->{insertion_mode} &= ~ $self->{insertion_mode}; |
$self->{insertion_mode} &= ~ IN_FOREIGN_CONTENT_IM; |
| 3828 |
## Reprocess. |
## Reprocess. |
| 3829 |
next B; |
next B; |
| 3830 |
} else { |
} else { |
| 3831 |
## TODO: case fixup |
my $nsuri = $self->{open_elements}->[-1]->[0]->namespace_uri; |
| 3832 |
|
my $tag_name = $token->{tag_name}; |
| 3833 |
|
if ($nsuri eq $SVG_NS) { |
| 3834 |
|
$tag_name = { |
| 3835 |
|
altglyph => 'altGlyph', |
| 3836 |
|
altglyphdef => 'altGlyphDef', |
| 3837 |
|
altglyphitem => 'altGlyphItem', |
| 3838 |
|
animatecolor => 'animateColor', |
| 3839 |
|
animatemotion => 'animateMotion', |
| 3840 |
|
animatetransform => 'animateTransform', |
| 3841 |
|
clippath => 'clipPath', |
| 3842 |
|
feblend => 'feBlend', |
| 3843 |
|
fecolormatrix => 'feColorMatrix', |
| 3844 |
|
fecomponenttransfer => 'feComponentTransfer', |
| 3845 |
|
fecomposite => 'feComposite', |
| 3846 |
|
feconvolvematrix => 'feConvolveMatrix', |
| 3847 |
|
fediffuselighting => 'feDiffuseLighting', |
| 3848 |
|
fedisplacementmap => 'feDisplacementMap', |
| 3849 |
|
fedistantlight => 'feDistantLight', |
| 3850 |
|
feflood => 'feFlood', |
| 3851 |
|
fefunca => 'feFuncA', |
| 3852 |
|
fefuncb => 'feFuncB', |
| 3853 |
|
fefuncg => 'feFuncG', |
| 3854 |
|
fefuncr => 'feFuncR', |
| 3855 |
|
fegaussianblur => 'feGaussianBlur', |
| 3856 |
|
feimage => 'feImage', |
| 3857 |
|
femerge => 'feMerge', |
| 3858 |
|
femergenode => 'feMergeNode', |
| 3859 |
|
femorphology => 'feMorphology', |
| 3860 |
|
feoffset => 'feOffset', |
| 3861 |
|
fepointlight => 'fePointLight', |
| 3862 |
|
fespecularlighting => 'feSpecularLighting', |
| 3863 |
|
fespotlight => 'feSpotLight', |
| 3864 |
|
fetile => 'feTile', |
| 3865 |
|
feturbulence => 'feTurbulence', |
| 3866 |
|
foreignobject => 'foreignObject', |
| 3867 |
|
glyphref => 'glyphRef', |
| 3868 |
|
lineargradient => 'linearGradient', |
| 3869 |
|
radialgradient => 'radialGradient', |
| 3870 |
|
#solidcolor => 'solidColor', ## NOTE: Commented in spec (SVG1.2) |
| 3871 |
|
textpath => 'textPath', |
| 3872 |
|
}->{$tag_name} || $tag_name; |
| 3873 |
|
} |
| 3874 |
|
|
| 3875 |
|
## "adjust SVG attributes" (SVG only) - done in insert-element-f |
| 3876 |
|
|
| 3877 |
|
## "adjust foreign attributes" - done in insert-element-f |
| 3878 |
|
|
| 3879 |
!!!insert-element-f ($self->{open_elements}->[-1]->[0]->namespace_uri, $token); |
!!!insert-element-f ($nsuri, $tag_name, $token->{attributes}, $token); |
| 3880 |
|
|
| 3881 |
if ($self->{self_closing}) { |
if ($self->{self_closing}) { |
| 3882 |
pop @{$self->{open_elements}}; |
pop @{$self->{open_elements}}; |
| 6536 |
} elsif ($token->{tag_name} eq 'math' or |
} elsif ($token->{tag_name} eq 'math' or |
| 6537 |
$token->{tag_name} eq 'svg') { |
$token->{tag_name} eq 'svg') { |
| 6538 |
$reconstruct_active_formatting_elements->($insert_to_current); |
$reconstruct_active_formatting_elements->($insert_to_current); |
| 6539 |
|
|
| 6540 |
|
## "adjust SVG attributes" ('svg' only) - done in insert-element-f |
| 6541 |
|
|
| 6542 |
|
## "adjust foreign attributes" - done in insert-element-f |
| 6543 |
|
|
| 6544 |
!!!insert-element-f ($token->{tag_name} eq 'math' ? $MML_NS : $SVG_NS, $token); |
!!!insert-element-f ($token->{tag_name} eq 'math' ? $MML_NS : $SVG_NS, $token->{tag_name}, $token->{attributes}, $token); |
| 6545 |
|
|
| 6546 |
if ($self->{self_closing}) { |
if ($self->{self_closing}) { |
| 6547 |
pop @{$self->{open_elements}}; |
pop @{$self->{open_elements}}; |
| 7081 |
!!!cp ('i4'); |
!!!cp ('i4'); |
| 7082 |
!!!parse-error (type => 'NULL'); |
!!!parse-error (type => 'NULL'); |
| 7083 |
$self->{next_char} = 0xFFFD; # REPLACEMENT CHARACTER # MUST |
$self->{next_char} = 0xFFFD; # REPLACEMENT CHARACTER # MUST |
| 7084 |
|
} elsif ($self->{next_char} <= 0x0008 or |
| 7085 |
|
(0x000E <= $self->{next_char} and |
| 7086 |
|
$self->{next_char} <= 0x001F) or |
| 7087 |
|
(0x007F <= $self->{next_char} and |
| 7088 |
|
$self->{next_char} <= 0x009F) or |
| 7089 |
|
(0xD800 <= $self->{next_char} and |
| 7090 |
|
$self->{next_char} <= 0xDFFF) or |
| 7091 |
|
(0xFDD0 <= $self->{next_char} and |
| 7092 |
|
$self->{next_char} <= 0xFDDF) or |
| 7093 |
|
{ |
| 7094 |
|
0xFFFE => 1, 0xFFFF => 1, 0x1FFFE => 1, 0x1FFFF => 1, |
| 7095 |
|
0x2FFFE => 1, 0x2FFFF => 1, 0x3FFFE => 1, 0x3FFFF => 1, |
| 7096 |
|
0x4FFFE => 1, 0x4FFFF => 1, 0x5FFFE => 1, 0x5FFFF => 1, |
| 7097 |
|
0x6FFFE => 1, 0x6FFFF => 1, 0x7FFFE => 1, 0x7FFFF => 1, |
| 7098 |
|
0x8FFFE => 1, 0x8FFFF => 1, 0x9FFFE => 1, 0x9FFFF => 1, |
| 7099 |
|
0xAFFFE => 1, 0xAFFFF => 1, 0xBFFFE => 1, 0xBFFFF => 1, |
| 7100 |
|
0xCFFFE => 1, 0xCFFFF => 1, 0xDFFFE => 1, 0xDFFFF => 1, |
| 7101 |
|
0xEFFFE => 1, 0xEFFFF => 1, 0xFFFFE => 1, 0xFFFFF => 1, |
| 7102 |
|
0x10FFFE => 1, 0x10FFFF => 1, |
| 7103 |
|
}->{$self->{next_char}}) { |
| 7104 |
|
!!!cp ('i4.1'); |
| 7105 |
|
!!!parse-error (type => 'control char', level => $self->{must_level}); |
| 7106 |
|
## TODO: error type documentation |
| 7107 |
} |
} |
| 7108 |
}; |
}; |
| 7109 |
$p->{prev_char} = [-1, -1, -1]; |
$p->{prev_char} = [-1, -1, -1]; |