4 * @todo Assimilate CSSTidy into our library
6 class HTMLPurifier_Filter_ExtractStyleBlocksTest
extends HTMLPurifier_Harness
10 public function test_tokenizeHTML_extractStyleBlocks()
12 $this->config
->set('Filter.ExtractStyleBlocks', true);
13 $purifier = new HTMLPurifier($this->config
);
14 $result = $purifier->purify('<style type="text/css">.foo {text-align:center;bogus:remove-me;} body.class[foo="attr"] {text-align:right;}</style>Test<style>* {font-size:12pt;}</style>');
15 $this->assertIdentical($result, 'Test');
16 $this->assertIdentical($purifier->context
->get('StyleBlocks'),
18 ".foo {\ntext-align:center\n}",
19 "* {\nfont-size:12pt\n}"
24 public function assertExtractStyleBlocks($html, $expect = true, $styles = array())
26 $filter = new HTMLPurifier_Filter_ExtractStyleBlocks(); // disable cleaning
27 if ($expect === true) $expect = $html;
28 $this->config
->set('Filter.ExtractStyleBlocks.TidyImpl', false);
29 $result = $filter->preFilter($html, $this->config
, $this->context
);
30 $this->assertIdentical($result, $expect);
31 $this->assertIdentical($this->context
->get('StyleBlocks'), $styles);
34 public function test_extractStyleBlocks_preserve()
36 $this->assertExtractStyleBlocks('Foobar');
39 public function test_extractStyleBlocks_allStyle()
41 $this->assertExtractStyleBlocks('<style>foo</style>', '', array('foo'));
44 public function test_extractStyleBlocks_multipleBlocks()
46 $this->assertExtractStyleBlocks(
47 "<style>1</style><style>2</style>NOP<style>4</style>",
53 public function test_extractStyleBlocks_blockWithAttributes()
55 $this->assertExtractStyleBlocks(
56 '<style type="text/css">css</style>',
62 public function test_extractStyleBlocks_styleWithPadding()
64 $this->assertExtractStyleBlocks(
65 "Alas<styled>Awesome</styled>\n<style>foo</style> Trendy!",
66 "Alas<styled>Awesome</styled>\n Trendy!",
71 public function assertCleanCSS($input, $expect = true)
73 $filter = new HTMLPurifier_Filter_ExtractStyleBlocks();
74 if ($expect === true) $expect = $input;
75 $this->normalize($input);
76 $this->normalize($expect);
77 $result = $filter->cleanCSS($input, $this->config
, $this->context
);
78 $this->assertIdentical($result, $expect);
81 public function test_cleanCSS_malformed()
83 $this->assertCleanCSS('</style>', '');
86 public function test_cleanCSS_selector()
88 $this->assertCleanCSS("a .foo #id div.cl#foo {\nfont-weight:700\n}");
91 public function test_cleanCSS_angledBrackets()
93 // [Content] No longer can smuggle in angled brackets using
94 // font-family; when we add support for 'content', reinstate
96 //$this->assertCleanCSS(
97 // ".class {\nfont-family:'</style>';\n}",
98 // ".class {\nfont-family:\"\\3C /style\\3E \";\n}"
102 public function test_cleanCSS_angledBrackets2()
104 // CSSTidy's behavior in this case is wrong, and should be fixed
105 //$this->assertCleanCSS(
106 // "span[title=\"</style>\"] {\nfont-size:12pt;\n}",
107 // "span[title=\"\\3C /style\\3E \"] {\nfont-size:12pt;\n}"
111 public function test_cleanCSS_bogus()
113 $this->assertCleanCSS("div {bogus:tree}", "div {\n}");
117 public function test_cleanCSS_escapeCodes()
119 $this->assertCleanCSS(
120 ".class {\nfont-family:\"\\3C /style\\3E \";\n}"
124 public function test_cleanCSS_noEscapeCodes()
126 $this->config->set('Filter.ExtractStyleBlocks.Escaping', false);
127 $this->assertCleanCSS(
128 ".class {\nfont-family:\"</style>\";\n}"
133 public function test_cleanCSS_scope()
135 $this->config
->set('Filter.ExtractStyleBlocks.Scope', '#foo');
136 $this->assertCleanCSS(
137 "p {\ntext-indent:1em\n}",
138 "#foo p {\ntext-indent:1em\n}"
142 public function test_cleanCSS_scopeWithSelectorCommas()
144 $this->config
->set('Filter.ExtractStyleBlocks.Scope', '#foo');
145 $this->assertCleanCSS(
146 "b, i {\ntext-decoration:underline\n}",
147 "#foo b, #foo i {\ntext-decoration:underline\n}"
151 public function test_cleanCSS_scopeWithNaughtySelector()
153 $this->config
->set('Filter.ExtractStyleBlocks.Scope', '#foo');
154 $this->assertCleanCSS(" + p {\ntext-indent:1em\n}", "#foo p {\ntext-indent:1em\n}");
157 public function test_cleanCSS_scopeWithMultipleNaughtySelectors()
159 $this->config
->set('Filter.ExtractStyleBlocks.Scope', '#foo');
160 $this->assertCleanCSS(" ++ ++ p {\ntext-indent:1em\n}", "#foo p {\ntext-indent:1em\n}");
163 public function test_cleanCSS_scopeWithCommas()
165 $this->config
->set('Filter.ExtractStyleBlocks.Scope', '#foo, .bar');
166 $this->assertCleanCSS(
167 "p {\ntext-indent:1em\n}",
168 "#foo p, .bar p {\ntext-indent:1em\n}"
172 public function test_cleanCSS_scopeAllWithCommas()
174 $this->config
->set('Filter.ExtractStyleBlocks.Scope', '#foo, .bar');
175 $this->assertCleanCSS(
176 "p, div {\ntext-indent:1em\n}",
177 "#foo p, .bar p, #foo div, .bar div {\ntext-indent:1em\n}"
181 public function test_cleanCSS_scopeWithConflicts()
183 $this->config
->set('Filter.ExtractStyleBlocks.Scope', 'p');
184 $this->assertCleanCSS(
203 public function test_removeComments()
205 $this->assertCleanCSS(
217 public function test_atSelector()
219 $this->assertCleanCSS(
221 b { text-align: center }
227 public function test_selectorValidation()
229 $this->assertCleanCSS(
235 $this->assertCleanCSS(
243 $this->assertCleanCSS(
244 "& a #foo:hover.bar +b > i {
247 "a #foo:hover.bar + b \\3E i {
251 $this->assertCleanCSS("doesnt-exist { text-align:center }", "");
254 public function test_cleanCSS_caseSensitive()
256 $this->assertCleanCSS("a .foo #ID div.cl#foo {\nbackground:url(\"http://foo/BAR\")\n}");
259 public function test_extractStyleBlocks_backtracking()
261 $goo = str_repeat("a", 1000000); // 1M to trigger, sometimes it's less!
262 $this->assertExtractStyleBlocks("<style></style>" . $goo, $goo, array(''));
267 // vim: et sw=4 sts=4