134 lines
3.6 KiB
PHP
134 lines
3.6 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['ch'] = false; // center (first word)
|
||
|
$keywords['cv'] = false; // center (second word)
|
||
|
$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];
|
||
|
if ($status == 'c') {
|
||
|
if ($i == 0) {
|
||
|
$status = 'ch';
|
||
|
} else {
|
||
|
$status = 'cv';
|
||
|
}
|
||
|
}
|
||
|
$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 ($keywords['ch']) {
|
||
|
$ret[] = $keywords['ch'];
|
||
|
$keywords['cv'] = false; // prevent re-use: center = center center
|
||
|
}
|
||
|
elseif (count($measures)) $ret[] = array_shift($measures);
|
||
|
|
||
|
if ($keywords['v']) $ret[] = $keywords['v'];
|
||
|
elseif ($keywords['cv']) $ret[] = $keywords['cv'];
|
||
|
elseif (count($measures)) $ret[] = array_shift($measures);
|
||
|
|
||
|
if (empty($ret)) return false;
|
||
|
return implode(' ', $ret);
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
// vim: et sw=4 sts=4
|