1 : <?php
2 :
3 : /* W3C says:
4 : [ // adjective and number must be in correct order, even if
5 : // you could switch them without introducing ambiguity.
6 : // some browsers support that syntax
7 : [
8 : <percentage> | <length> | left | center | right
9 : ]
10 : [
11 : <percentage> | <length> | top | center | bottom
12 : ]?
13 : ] |
14 : [ // this signifies that the vertical and horizontal adjectives
15 : // can be arbitrarily ordered, however, there can only be two,
16 : // one of each, or none at all
17 : [
18 : left | center | right
19 : ] ||
20 : [
21 : top | center | bottom
22 : ]
23 : ]
24 : top, left = 0%
25 : center, (none) = 50%
26 : bottom, right = 100%
27 : */
28 :
29 : /* QuirksMode says:
30 : keyword + length/percentage must be ordered correctly, as per W3C
31 :
32 : Internet Explorer and Opera, however, support arbitrary ordering. We
33 : should fix it up.
34 :
35 : Minor issue though, not strictly necessary.
36 : */
37 :
38 : // control freaks may appreciate the ability to convert these to
39 : // percentages or something, but it's not necessary
40 :
41 : /**
42 : * Validates the value of background-position.
43 : */
44 1 : class HTMLPurifier_AttrDef_CSS_BackgroundPosition extends HTMLPurifier_AttrDef
45 : {
46 :
47 : protected $length;
48 : protected $percentage;
49 :
50 : public function __construct() {
51 : $this->length = new HTMLPurifier_AttrDef_CSS_Length();
52 : $this->percentage = new HTMLPurifier_AttrDef_CSS_Percentage();
53 : }
54 :
55 : public function validate($string, $config, $context) {
56 0 : $string = $this->parseCDATA($string);
57 0 : $bits = explode(' ', $string);
58 :
59 0 : $keywords = array();
60 0 : $keywords['h'] = false; // left, right
61 0 : $keywords['v'] = false; // top, bottom
62 0 : $keywords['c'] = false; // center
63 0 : $measures = array();
64 :
65 0 : $i = 0;
66 :
67 : $lookup = array(
68 0 : 'top' => 'v',
69 0 : 'bottom' => 'v',
70 0 : 'left' => 'h',
71 0 : 'right' => 'h',
72 : 'center' => 'c'
73 0 : );
74 :
75 0 : foreach ($bits as $bit) {
76 0 : if ($bit === '') continue;
77 :
78 : // test for keyword
79 0 : $lbit = ctype_lower($bit) ? $bit : strtolower($bit);
80 0 : if (isset($lookup[$lbit])) {
81 0 : $status = $lookup[$lbit];
82 0 : $keywords[$status] = $lbit;
83 0 : $i++;
84 0 : }
85 :
86 : // test for length
87 0 : $r = $this->length->validate($bit, $config, $context);
88 0 : if ($r !== false) {
89 0 : $measures[] = $r;
90 0 : $i++;
91 0 : }
92 :
93 : // test for percentage
94 0 : $r = $this->percentage->validate($bit, $config, $context);
95 0 : if ($r !== false) {
96 0 : $measures[] = $r;
97 0 : $i++;
98 0 : }
99 :
100 0 : }
101 :
102 0 : if (!$i) return false; // no valid values were caught
103 :
104 :
105 0 : $ret = array();
106 :
107 : // first keyword
108 0 : if ($keywords['h']) $ret[] = $keywords['h'];
109 0 : elseif (count($measures)) $ret[] = array_shift($measures);
110 0 : elseif ($keywords['c']) {
111 0 : $ret[] = $keywords['c'];
112 0 : $keywords['c'] = false; // prevent re-use: center = center center
113 0 : }
114 :
115 0 : if ($keywords['v']) $ret[] = $keywords['v'];
116 0 : elseif (count($measures)) $ret[] = array_shift($measures);
117 0 : elseif ($keywords['c']) $ret[] = $keywords['c'];
118 :
119 0 : if (empty($ret)) return false;
120 0 : return implode(' ', $ret);
121 :
122 : }
123 :
124 : }
125 :
|