mirror of
https://github.com/ezyang/htmlpurifier.git
synced 2024-12-23 17:01:51 +00:00
2c955af135
Signed-off-by: Edward Z. Yang <edwardzyang@thewritingpot.com>
126 lines
3.3 KiB
PHP
126 lines
3.3 KiB
PHP
<?php
|
|
|
|
/* W3C says:
|
|
[ // adjective and number must be in correct order, even if
|
|
// you could switch them without introducing ambiguity.
|
|
// some browsers support that syntax
|
|
[
|
|
<percentage> | <length> | left | center | right
|
|
]
|
|
[
|
|
<percentage> | <length> | top | center | bottom
|
|
]?
|
|
] |
|
|
[ // this signifies that the vertical and horizontal adjectives
|
|
// can be arbitrarily ordered, however, there can only be two,
|
|
// one of each, or none at all
|
|
[
|
|
left | center | right
|
|
] ||
|
|
[
|
|
top | center | bottom
|
|
]
|
|
]
|
|
top, left = 0%
|
|
center, (none) = 50%
|
|
bottom, right = 100%
|
|
*/
|
|
|
|
/* QuirksMode says:
|
|
keyword + length/percentage must be ordered correctly, as per W3C
|
|
|
|
Internet Explorer and Opera, however, support arbitrary ordering. We
|
|
should fix it up.
|
|
|
|
Minor issue though, not strictly necessary.
|
|
*/
|
|
|
|
// control freaks may appreciate the ability to convert these to
|
|
// percentages or something, but it's not necessary
|
|
|
|
/**
|
|
* Validates the value of background-position.
|
|
*/
|
|
class HTMLPurifier_AttrDef_CSS_BackgroundPosition extends HTMLPurifier_AttrDef
|
|
{
|
|
|
|
protected $length;
|
|
protected $percentage;
|
|
|
|
public function __construct() {
|
|
$this->length = new HTMLPurifier_AttrDef_CSS_Length();
|
|
$this->percentage = new HTMLPurifier_AttrDef_CSS_Percentage();
|
|
}
|
|
|
|
public function validate($string, $config, $context) {
|
|
$string = $this->parseCDATA($string);
|
|
$bits = explode(' ', $string);
|
|
|
|
$keywords = array();
|
|
$keywords['h'] = false; // left, right
|
|
$keywords['v'] = false; // top, bottom
|
|
$keywords['c'] = false; // center
|
|
$measures = array();
|
|
|
|
$i = 0;
|
|
|
|
$lookup = array(
|
|
'top' => 'v',
|
|
'bottom' => 'v',
|
|
'left' => 'h',
|
|
'right' => 'h',
|
|
'center' => 'c'
|
|
);
|
|
|
|
foreach ($bits as $bit) {
|
|
if ($bit === '') continue;
|
|
|
|
// test for keyword
|
|
$lbit = ctype_lower($bit) ? $bit : strtolower($bit);
|
|
if (isset($lookup[$lbit])) {
|
|
$status = $lookup[$lbit];
|
|
$keywords[$status] = $lbit;
|
|
$i++;
|
|
}
|
|
|
|
// test for length
|
|
$r = $this->length->validate($bit, $config, $context);
|
|
if ($r !== false) {
|
|
$measures[] = $r;
|
|
$i++;
|
|
}
|
|
|
|
// test for percentage
|
|
$r = $this->percentage->validate($bit, $config, $context);
|
|
if ($r !== false) {
|
|
$measures[] = $r;
|
|
$i++;
|
|
}
|
|
|
|
}
|
|
|
|
if (!$i) return false; // no valid values were caught
|
|
|
|
|
|
$ret = array();
|
|
|
|
// first keyword
|
|
if ($keywords['h']) $ret[] = $keywords['h'];
|
|
elseif (count($measures)) $ret[] = array_shift($measures);
|
|
elseif ($keywords['c']) {
|
|
$ret[] = $keywords['c'];
|
|
$keywords['c'] = false; // prevent re-use: center = center center
|
|
}
|
|
|
|
if ($keywords['v']) $ret[] = $keywords['v'];
|
|
elseif (count($measures)) $ret[] = array_shift($measures);
|
|
elseif ($keywords['c']) $ret[] = $keywords['c'];
|
|
|
|
if (empty($ret)) return false;
|
|
return implode(' ', $ret);
|
|
|
|
}
|
|
|
|
}
|
|
|