mirror of
https://github.com/ezyang/htmlpurifier.git
synced 2024-11-09 15:28:40 +00:00
[3.1.0] Add support for !important, with %CSS.AllowImportant
git-svn-id: http://htmlpurifier.org/svnroot/htmlpurifier/trunk@1578 48356398-32a2-884e-a903-53898d9a118a
This commit is contained in:
parent
a2d044f58d
commit
30eb982961
2
NEWS
2
NEWS
@ -29,6 +29,8 @@ NEWS ( CHANGELOG and HISTORY ) HTMLPurifier
|
|||||||
! Limited support for proprietary HTML elements, namely <marquee>, sponsored
|
! Limited support for proprietary HTML elements, namely <marquee>, sponsored
|
||||||
by Chris. You can enable them with %HTML.Proprietary if your client
|
by Chris. You can enable them with %HTML.Proprietary if your client
|
||||||
demands them.
|
demands them.
|
||||||
|
! Support for !important CSS cascade modifier. By default, this will be stripped
|
||||||
|
from CSS, but you can enable it using %CSS.AllowImportant
|
||||||
- Autoclose now operates iteratively, i.e. <span><span><div> now has
|
- Autoclose now operates iteratively, i.e. <span><span><div> now has
|
||||||
both span tags closed.
|
both span tags closed.
|
||||||
- Various HTMLPurifier_Config convenience functions now accept another parameter
|
- Various HTMLPurifier_Config convenience functions now accept another parameter
|
||||||
|
@ -81,6 +81,7 @@ require 'HTMLPurifier/AttrDef/CSS/Composite.php';
|
|||||||
require 'HTMLPurifier/AttrDef/CSS/Filter.php';
|
require 'HTMLPurifier/AttrDef/CSS/Filter.php';
|
||||||
require 'HTMLPurifier/AttrDef/CSS/Font.php';
|
require 'HTMLPurifier/AttrDef/CSS/Font.php';
|
||||||
require 'HTMLPurifier/AttrDef/CSS/FontFamily.php';
|
require 'HTMLPurifier/AttrDef/CSS/FontFamily.php';
|
||||||
|
require 'HTMLPurifier/AttrDef/CSS/ImportantDecorator.php';
|
||||||
require 'HTMLPurifier/AttrDef/CSS/Length.php';
|
require 'HTMLPurifier/AttrDef/CSS/Length.php';
|
||||||
require 'HTMLPurifier/AttrDef/CSS/ListStyle.php';
|
require 'HTMLPurifier/AttrDef/CSS/ListStyle.php';
|
||||||
require 'HTMLPurifier/AttrDef/CSS/Multiple.php';
|
require 'HTMLPurifier/AttrDef/CSS/Multiple.php';
|
||||||
|
38
library/HTMLPurifier/AttrDef/CSS/ImportantDecorator.php
Normal file
38
library/HTMLPurifier/AttrDef/CSS/ImportantDecorator.php
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decorator which enables !important to be used in CSS values.
|
||||||
|
*/
|
||||||
|
class HTMLPurifier_AttrDef_CSS_ImportantDecorator
|
||||||
|
{
|
||||||
|
protected $def, $allow;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param $def Definition to wrap
|
||||||
|
* @param $allow Whether or not to allow !important
|
||||||
|
*/
|
||||||
|
public function __construct($def, $allow = false) {
|
||||||
|
$this->def = $def;
|
||||||
|
$this->allow = $allow;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Intercepts and removes !important if necessary
|
||||||
|
*/
|
||||||
|
public function validate($string, $config, $context) {
|
||||||
|
// test for ! and important tokens
|
||||||
|
$string = trim($string);
|
||||||
|
$is_important = false;
|
||||||
|
// :TODO: optimization: test directly for !important and ! important
|
||||||
|
if (strlen($string) >= 9 && substr($string, -9) === 'important') {
|
||||||
|
$temp = rtrim(substr($string, 0, -9));
|
||||||
|
// use a temp, because we might want to restore important
|
||||||
|
if (strlen($temp) >= 1 && substr($temp, -1) === '!') {
|
||||||
|
$string = rtrim(substr($temp, 0, -1));
|
||||||
|
$is_important = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$string = $this->def->validate($string, $config, $context);
|
||||||
|
if ($this->allow && $is_important) $string .= ' !important';
|
||||||
|
return $string;
|
||||||
|
}
|
||||||
|
}
|
@ -202,6 +202,12 @@ class HTMLPurifier_CSSDefinition extends HTMLPurifier_Definition
|
|||||||
$this->doSetupProprietary($config);
|
$this->doSetupProprietary($config);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$allow_important = $config->get('CSS', 'AllowImportant');
|
||||||
|
// wrap all attr-defs with decorator that handles !important
|
||||||
|
foreach ($this->info as $k => $v) {
|
||||||
|
$this->info[$k] = new HTMLPurifier_AttrDef_CSS_ImportantDecorator($v, $allow_important);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function doSetupProprietary($config) {
|
protected function doSetupProprietary($config) {
|
||||||
|
File diff suppressed because one or more lines are too long
@ -0,0 +1,7 @@
|
|||||||
|
CSS.AllowImportant
|
||||||
|
TYPE: bool
|
||||||
|
DEFAULT: false
|
||||||
|
VERSION: 3.1.0
|
||||||
|
--DESCRIPTION--
|
||||||
|
This parameter determines whether or not !important cascade modifiers should
|
||||||
|
be allowed in user CSS. If false, !important will stripped.
|
48
tests/HTMLPurifier/AttrDef/CSS/ImportantDecoratorTest.php
Normal file
48
tests/HTMLPurifier/AttrDef/CSS/ImportantDecoratorTest.php
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
class HTMLPurifier_AttrDef_CSS_ImportantDecoratorTest extends HTMLPurifier_AttrDefHarness
|
||||||
|
{
|
||||||
|
|
||||||
|
/** Mock AttrDef decorator is wrapping */
|
||||||
|
protected $mock;
|
||||||
|
|
||||||
|
function setUp() {
|
||||||
|
generate_mock_once('HTMLPurifier_AttrDef');
|
||||||
|
$this->mock = new HTMLPurifier_AttrDefMock();
|
||||||
|
$this->def = new HTMLPurifier_AttrDef_CSS_ImportantDecorator($this->mock, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function setMock($input, $output = null) {
|
||||||
|
if ($output === null) $output = $input;
|
||||||
|
$this->mock->expectOnce('validate', array($input, $this->config, $this->context));
|
||||||
|
$this->mock->setReturnValue('validate', $output);
|
||||||
|
}
|
||||||
|
|
||||||
|
function testImportant() {
|
||||||
|
$this->setMock('23');
|
||||||
|
$this->assertDef('23 !important');
|
||||||
|
}
|
||||||
|
|
||||||
|
function testImportantInternalDefChanged() {
|
||||||
|
$this->setMock('23', '24');
|
||||||
|
$this->assertDef('23 !important', '24 !important');
|
||||||
|
}
|
||||||
|
|
||||||
|
function testImportantWithSpace() {
|
||||||
|
$this->setMock('23');
|
||||||
|
$this->assertDef('23 ! important ', '23 !important');
|
||||||
|
}
|
||||||
|
|
||||||
|
function testFakeImportant() {
|
||||||
|
$this->setMock('! foo important');
|
||||||
|
$this->assertDef('! foo important');
|
||||||
|
}
|
||||||
|
|
||||||
|
function testStrip() {
|
||||||
|
$this->def = new HTMLPurifier_AttrDef_CSS_ImportantDecorator($this->mock, false);
|
||||||
|
$this->setMock('23');
|
||||||
|
$this->assertDef('23 ! important ', '23');
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -3,9 +3,12 @@
|
|||||||
class HTMLPurifier_AttrDef_CSSTest extends HTMLPurifier_AttrDefHarness
|
class HTMLPurifier_AttrDef_CSSTest extends HTMLPurifier_AttrDefHarness
|
||||||
{
|
{
|
||||||
|
|
||||||
function test() {
|
function setup() {
|
||||||
|
parent::setup();
|
||||||
$this->def = new HTMLPurifier_AttrDef_CSS();
|
$this->def = new HTMLPurifier_AttrDef_CSS();
|
||||||
|
}
|
||||||
|
|
||||||
|
function test() {
|
||||||
|
|
||||||
// regular cases, singular
|
// regular cases, singular
|
||||||
$this->assertDef('text-align:right;');
|
$this->assertDef('text-align:right;');
|
||||||
@ -107,11 +110,13 @@ class HTMLPurifier_AttrDef_CSSTest extends HTMLPurifier_AttrDefHarness
|
|||||||
// case-insensitivity
|
// case-insensitivity
|
||||||
$this->assertDef('FLOAT:LEFT;', 'float:left;');
|
$this->assertDef('FLOAT:LEFT;', 'float:left;');
|
||||||
|
|
||||||
|
// !important stripping
|
||||||
|
$this->assertDef('float:left !important;', 'float:left;');
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function testProprietary() {
|
function testProprietary() {
|
||||||
$this->config->set('CSS', 'Proprietary', true);
|
$this->config->set('CSS', 'Proprietary', true);
|
||||||
$this->def = new HTMLPurifier_AttrDef_CSS();
|
|
||||||
|
|
||||||
$this->assertDef('scrollbar-arrow-color:#ff0;');
|
$this->assertDef('scrollbar-arrow-color:#ff0;');
|
||||||
$this->assertDef('scrollbar-base-color:#ff6347;');
|
$this->assertDef('scrollbar-base-color:#ff6347;');
|
||||||
@ -127,5 +132,10 @@ class HTMLPurifier_AttrDef_CSSTest extends HTMLPurifier_AttrDefHarness
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function testImportant() {
|
||||||
|
$this->config->set('CSS', 'AllowImportant', true);
|
||||||
|
$this->assertDef('float:left !important;');
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,6 +18,7 @@ $test_files[] = 'HTMLPurifier/AttrDef/CSS/CompositeTest.php';
|
|||||||
$test_files[] = 'HTMLPurifier/AttrDef/CSS/FilterTest.php';
|
$test_files[] = 'HTMLPurifier/AttrDef/CSS/FilterTest.php';
|
||||||
$test_files[] = 'HTMLPurifier/AttrDef/CSS/FontFamilyTest.php';
|
$test_files[] = 'HTMLPurifier/AttrDef/CSS/FontFamilyTest.php';
|
||||||
$test_files[] = 'HTMLPurifier/AttrDef/CSS/FontTest.php';
|
$test_files[] = 'HTMLPurifier/AttrDef/CSS/FontTest.php';
|
||||||
|
$test_files[] = 'HTMLPurifier/AttrDef/CSS/ImportantDecoratorTest.php';
|
||||||
$test_files[] = 'HTMLPurifier/AttrDef/CSS/LengthTest.php';
|
$test_files[] = 'HTMLPurifier/AttrDef/CSS/LengthTest.php';
|
||||||
$test_files[] = 'HTMLPurifier/AttrDef/CSS/ListStyleTest.php';
|
$test_files[] = 'HTMLPurifier/AttrDef/CSS/ListStyleTest.php';
|
||||||
$test_files[] = 'HTMLPurifier/AttrDef/CSS/MultipleTest.php';
|
$test_files[] = 'HTMLPurifier/AttrDef/CSS/MultipleTest.php';
|
||||||
|
Loading…
Reference in New Issue
Block a user