#!/usr/bin/perl
our
$tests
;
BEGIN { ++
$INC
{
'tests.pm'
} }
sub
tests'VERSION {
$tests
+=
pop
};
plan
tests
=>
$tests
;
my
$doc
= new HTML::DOM;
{
(
my
$elem
=
$doc
->createElement(
'div'
))
->setAttribute(
'style'
,
'margin-top: 3px'
);
isa_ok(
$elem
->style,
'CSS::DOM::Style'
);
is
$elem
->style->marginTop,
'3px'
,
'the css dom is copied from the style attribute'
;
$elem
->style->marginTop(
'4em'
);
is
$elem
->getAttribute(
'style'
),
'margin-top: 4em'
,
'modifications to the css dom are reflected in the attr'
;
$elem
->setAttribute(
'style'
,
'margin-bottom: 2px'
);
is
$elem
->style->marginBottom(),
'2px'
,
'Subsequent changes to the attr change the dom,'
;
is
$elem
->style->marginTop,
''
,
'even deleting properties.'
;
$elem
->removeAttribute(
'style'
);
like
$elem
->style->cssText,
qr/^\s*\z/
,
'removeAttribute erases the css data'
;
$elem
->style->paddingTop(
'3in'
);
is
$elem
->getAttributeNode(
'style'
)->value,
'padding-top: 3in'
,
'getAttributeNode reads the CSS data'
;
my
$attr
=
$doc
->createAttribute(
'style'
);
$attr
->value(
'padding-top: 4cm'
);
$elem
->setAttributeNode(
$attr
);
is
$elem
->style->paddingTop,
'4cm'
,
'setAttributeNode sets the CSS data'
;
$elem
->removeAttributeNode(
$elem
->getAttributeNode(
'style'
));
like
$elem
->style->cssText,
qr/^\s*\z/
,
'removeAttributeNode erases the css data'
;
$elem
->setAttribute(
'style'
=>
''
);
$attr
=
$elem
->getAttributeNode(
'style'
);
(
my
$style
=
$elem
->style)->marginTop(
'30px'
);
is
$attr
->value,
'margin-top: 30px'
,
'changes to the style obj are reflected in the attr node'
;
is
$elem
->style,
$style
,
'without the style object getting clobbered'
;
$attr
->value(
'color:red'
);
is
$elem
->style->cssText,
'color: red'
,
'changes to the attr node are reflected in the style obj'
;
$attr
->firstChild->data(
'hand-color:red'
);
is
$elem
->style->cssText,
'hand-color: red'
,
'changes to the attr\'s child text node change the style obj'
;
$elem
->removeAttribute(
'style'
);
$elem
->setAttribute(
'style'
,
'color:red'
);
$attr
=
$elem
->getAttributeNode(
'style'
);
$elem
->style->color(
'blue'
);
is
$attr
->value,
'color: blue'
,
'style mods change the attr when attr was auto-vivved B4 style'
;
my
$new_attr
=
$doc
->createAttribute(
'style'
);
$new_attr
->value(
"foo:bar"
);
$elem
->setAttributeNode(
$new_attr
);
is
$elem
->style->cssText,
'foo: bar'
,
'replacing the attr node clobbers the style obj'
;
$elem
->removeAttribute(
'style'
);
$elem
->setAttribute(
'style'
,
'color:red'
);
$attr
=
$elem
->getAttributeNode(
'style'
);
$attr
->style
->color(
'green'
);
is
$attr
->firstChild
->data,
'color: green'
,
"an attr's text node auto-vivved after the style obj is in synch"
;
is
$elem
->getAttribute(
'style'
),
'color: green'
,
'style attr nodes stringify properly'
;
}
{
(
my
$elem
=
$doc
->createElement(
'style'
))->appendChild(
$doc
->createTextNode(
'a { color: black}'
)
);
isa_ok
$elem
->sheet,
'CSS::DOM'
,
'<style> ->sheet'
;
is +(
$elem
->sheet->cssRules)[0]->selectorText,
'a'
,
'contents are there'
;
my
$doc
= new HTML::DOM;
my
$css
;
$doc
->css_url_fetcher(
sub
{
$css
});
$doc
->
write
(
"<link href='data:text/css,'>"
);
$doc
->
write
(
"<link rel=stylesheet href='data:text/css,'>"
);
$doc
->
close
;
my
@links
=
$doc
->find(
'link'
);
is +()=
$links
[0]->sheet, 0,
'sheet returns null when rel != stylesheet'
;
is +()=
$links
[1]->sheet, 0,
'sheet returns null when rel == stylesheet, & cuf returns undef'
;
$css
=
''
;
$doc
->
write
(
"<link href='data:text/css,'>"
);
$doc
->
write
(
"<link rel=stylesheet href='data:text/css,'>"
);
$doc
->
close
;
@links
=
$doc
->find(
'link'
);
is +()=
$links
[0]->sheet, 0,
'sheet returns null when rel != stylesheet, even w/cuf'
;
isa_ok
$links
[1]->sheet,
'CSS::DOM'
,
'<link> ->sheet when rel == stylesheet and cuf returns defined'
;
$css
=
'a{color:green}'
;
$links
[1]->setAttribute(
'href'
,
'dware'
);
is
$links
[1]->sheet->cssRules->
length
, 1,
'setting the href attribute updates the sheet'
;
$css
=
'a{color:green}p{text-align:center}'
;
$links
[1]->getAttributeNode(
'href'
)->firstChild->data(
'cring'
);
is
$links
[1]->sheet->cssRules->
length
, 2,
'modifying the href attribute node updates the sheet'
;
my
$cuf
=
$doc
->css_url_fetcher;
$css
=
'ceck'
;
is
&$cuf
,
'ceck'
,
'css_url_fetcher returns the previous assigned sub'
;
is
$doc
->css_url_fetcher(
sub
{}),
$cuf
,
'css_url_fetcher returns the old value on assignment'
;
}
{
my
$doc
= new HTML::DOM;
$doc
->css_url_fetcher(
sub
{
''
});
$doc
->
write
('
<style id=stile>b { font-weight: bold }</style>
<
link
id=foo rel=stylesheet>
<
link
rel=bar>
');
$doc
->
close
;
isa_ok
my
$list
=
$doc
->styleSheets,
'CSS::DOM::StyleSheetList'
,
'retval of styleSheets'
;
is
$list
->
length
, 2,
'sheet list doesn\'t include <link rel=bar>'
;
is
my
@list
=
$doc
->styleSheets, 2,
'styleSheets in list context'
;
is refaddr
$list
->[0], refaddr
$list
[0],
'both retvals have the same first item'
;
is refaddr
$list
->[1], refaddr
$list
[1],
'both retvals have the same second item'
;
is refaddr
$list
[0], refaddr
$doc
->getElementById(
'stile'
)->sheet,
'the style elem\'s sheet is in the list'
;
is refaddr
$list
[1],
refaddr +(
my
$link
=
$doc
->getElementById(
'foo'
))->sheet,
'the link elem\'s sheet is in the list'
;
$link
->setAttribute(
rel
=>
"a nice big\xa0stylesheet\nhere"
);
is refaddr
$list
->[1], refaddr
$list
[1],
'setAttribute w/o changing whether rel contains "stylesheet"'
;
$link
->setAttribute(
rel
=>
'contents'
);
is
@$list
, 1,
'setAttribute(rel => contents) deletes the style sheet obj'
;
$link
->setAttribute(
rel
=>
'a stylesheet'
);
is
@$list
, 2,
'setAttribute adds the style sheet to the list'
;
SKIP: { skip
'What is the correct behaviour?'
,1;
isn't refaddr
$list
->[1], refaddr
$list
[1],
'creating it from scratch'
;
}
@list
=
@$list
;
(
my
$attr
=
$doc
->createAttribute(
'rel'
))->nodeValue(
'stylesheEt'
);
$link
->setAttributeNode(
$attr
);
is refaddr
$list
[1], refaddr
$list
->[1],
'setAttributeNode w/o changing whether rel =~ "stylesheet"'
;
(
my
$attr2
=
$doc
->createAttribute(
'rel'
))->nodeValue(
'contents'
);
$link
->setAttributeNode(
$attr2
);
is
@$list
, 1,
'setAttributeNode(contents) deletes the style sheet obj'
;
$link
->setAttributeNode(
$attr
);
is
@$list
, 2,
'setAttributeNode adds the style sheet to the list ...'
;
SKIP: { skip
'What is the correct behaviour?'
,1;
isn't refaddr
$list
->[1], refaddr
$list
[1],
'... creating it from scratch'
;
}
$link
->removeAttribute(
'rel'
);
is
@$list
, 1,
'removeAttribute removes the style sheet'
;
$link
->setAttribute(
rel
=>
'stylesheet'
);
$link
->removeAttributeNode(
$link
->getAttributeNode(
'rel'
));
is
@$list
, 1,
'removeAttributeNode removes the style sheet'
;
}
{
our
@ISA
= HTML::DOM::View::;
sub
new {
bless
[],
shift
}
sub
ua_style_sheet {
return
$_
[0][0] }
sub
user_style_sheet {
return
$_
[0][1] }
my
$doc
= new HTML::DOM;
(
my
$view
= new TestView) -> document (
$doc
);
VERSION CSS'DOM 0.07;
$view
->[0] = CSS
'DOM'
parse(' /* UA style sheet */
');
$view
->[1] = CSS
'DOM'
parse(' /* User style sheet */
');
$doc
->
write
(
<<'_END_');
t060401-c32-cascading-00-b.htm with some modifications. -->
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
<title>CSS Test: Cascading Order</title>
<link rel="author" href="censored in case someone is scraping this" title="Ian Hickson">
<link rel="stylesheet" href="support/c-red.css">
<style type="text/css">
body * { color: red; list-style: none; margin: 0; padding: 0; }
span { color: red; }
li span.a { color: red; }
li span.b { color: red; }
li span.c { color: red; }
li span.d { color: red; }
li span.e { color: red; }
li span.f { color: red; }
ul li span.a { color: green; }
ul li span.b { color: green; }
ul li li span.c { color: red; }
ul li li span.d { color: red; }
ul li li span.e { color: red; }
ul li li span.f { color: red; }
ul li li span.c { color: green; }
li.test1 span.d { color: green; }
ul li.test2 span.e { color: green; }
ul li.test3 span.f { color: red; }
ul li#test3 span.f { color: green; }
.test4 { color: red; }
.test4 { color: green; }
.c { color: green; }
#twelve { font-size: 5px }
</style>
</head>
<body>
<ul>
<li> <span class="a" id=one> This should be green. </span> </li>
<li> <span class="b" id=two> This should be green. </span>
<ul>
<li> <span class="c" id=three> This should be green. </span> </li>
<li> <span class="c" id=four> This should be green. </span> </li>
<li class="test1"> <span class="d" id=five> This should be green. </span> </li>
</ul>
</li>
<li class="test2"> <span class="e" id=six> This should be green. </span> </li>
<li id="test3" class="test3"> <span class="f" id=seven> This should be green. </span> </li>
<li> <span class="a" id=eight> This should be green. </span> </li>
</ul>
<p style="color: green;" id=nine> This should be green. </p>
<p class="test4" id=ten> This should be green. </p>
<p class="c" id=eleven> This should be green. </p>
<span id=twelve></span><span id=thirteen></span><span id=fourteen></span>
</body>
</html>
_END_
$doc
->
close
;
my
$green
=
qr/^(?:green|#0(?:0ff0|f)0|rgb\(0%?\s*,\s*(?:100%|255)\s*,\s*0%?\))\z/
i;
like
$view
->getComputedStyle(
$doc
->getElementById(
$_
))->color,
$green
,
"cascade test $_ from t060401-c32-cascading-00-b.htm"
for
qw/ one two three four five six seven eight nine ten
eleven /
;
is
$view
->getComputedStyle(
$doc
->getElementById(
'twelve'
))
->fontSize,
'5px'
,
'author overrides user and ua'
;
is
$view
->getComputedStyle(
$doc
->getElementById(
'thirteen'
))
->fontSize,
'4px'
,
'user overrides ua'
;
is
$view
->getComputedStyle(
$doc
->getElementById(
'fourteen'
))
->fontSize,
'15px'
,
'fallback to ua'
;
$view
->[0]=CSS
'DOM'
parse(' /* UA style sheet */
p { color: yellow ! important; }
span { font-size: 38px !important }
');
$view
->[1]=CSS
'DOM'
parse(' /* User style sheet */
a { font-size: 14px ! important }
');
$doc
->
write
(
<<'_TEMDOBEDXK>N');
html4/t060402-c31-important-00-b.htm -->
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
<title>CSS Test: important</title>
<link rel="author" href="mailto:ian at some server called hixie.ch" title="Ian Hickson">
<style type="text/css">
p { color: green ! important; }
p { color: red; }
p#id1 { color: red; }
a { font-size: 1px !important }
span { font-size: 23px }
div { text-transform: none }
div:first-line { text-transform: uppercase }
</style>
</head>
<body>
<p> This line should be green. </p>
<p id="id1"> This line should be green. </p>
<p style="color: red;"> This line should be green. </p>
<a href=""></a><span id=s></span>
<div></div>
</body>
</html>
_TEMDOBEDXK>N
$doc
->
close
;
my
$ps
=
$doc
->getElementsByTagName(
'p'
);
like
$view
->getComputedStyle(
$ps
->[0])->color,
$green
,
'!important overrides following rule with same specificiciciicty'
.
'(and also overrides an !important ua rule)'
;
like
$view
->getComputedStyle(
$ps
->[1])->color,
$green
,
'!important overrides following rule w/higher specificiciciicty'
;
like
$view
->getComputedStyle(
$ps
->[2])->color,
$green
,
'!important overrides style attr'
;
is
$view
->getComputedStyle(
$doc
->links->[0])->fontSize,
'14px'
,
'user !important overrides author !important'
;
is
$view
->getComputedStyle(
$doc
->getElementById(
's'
))->fontSize,
'38px'
,
'!important ua decl overrides un!important author decl'
;
my
$d
=
$doc
->getElementsByTagName(
'div'
)->[0];
is
$view
->getComputedStyle(
$d
)->textTransform,
'none'
,
'getComputedStyle without pseudo-elem'
;
is
$view
->getComputedStyle(
$d
,
'first-line'
)->textTransform,
'uppercase'
,
'getComputedStyle with colonless pseudo-elem'
;
is
$view
->getComputedStyle(
$d
,
':first-line'
)->textTransform,
'uppercase'
,
'getComputedStyle with monocolic pseudo-elem'
;
is
$view
->getComputedStyle(
$d
,
'::first-line'
)->textTransform,
'uppercase'
,
'getComputedStyle with dyocolic pseudo-elem'
;
}