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 class HTMLPurifier_AttrDef_CSS_BackgroundPosition extends HTMLPurifier_AttrDef 45 { 46 47 /** 48 * @type HTMLPurifier_AttrDef_CSS_Length 49 */ 50 protected $length; 51 52 /** 53 * @type HTMLPurifier_AttrDef_CSS_Percentage 54 */ 55 protected $percentage; 56 57 public function __construct() 58 { 59 $this->length = new HTMLPurifier_AttrDef_CSS_Length(); 60 $this->percentage = new HTMLPurifier_AttrDef_CSS_Percentage(); 61 } 62 63 /** 64 * @param string $string 65 * @param HTMLPurifier_Config $config 66 * @param HTMLPurifier_Context $context 67 * @return bool|string 68 */ 69 public function validate($string, $config, $context) 70 { 71 $string = $this->parseCDATA($string); 72 $bits = explode(' ', $string); 73 74 $keywords = array(); 75 $keywords['h'] = false; // left, right 76 $keywords['v'] = false; // top, bottom 77 $keywords['ch'] = false; // center (first word) 78 $keywords['cv'] = false; // center (second word) 79 $measures = array(); 80 81 $i = 0; 82 83 $lookup = array( 84 'top' => 'v', 85 'bottom' => 'v', 86 'left' => 'h', 87 'right' => 'h', 88 'center' => 'c' 89 ); 90 91 foreach ($bits as $bit) { 92 if ($bit === '') { 93 continue; 94 } 95 96 // test for keyword 97 $lbit = ctype_lower($bit) ? $bit : strtolower($bit); 98 if (isset($lookup[$lbit])) { 99 $status = $lookup[$lbit]; 100 if ($status == 'c') { 101 if ($i == 0) { 102 $status = 'ch'; 103 } else { 104 $status = 'cv'; 105 } 106 } 107 $keywords[$status] = $lbit; 108 $i++; 109 } 110 111 // test for length 112 $r = $this->length->validate($bit, $config, $context); 113 if ($r !== false) { 114 $measures[] = $r; 115 $i++; 116 } 117 118 // test for percentage 119 $r = $this->percentage->validate($bit, $config, $context); 120 if ($r !== false) { 121 $measures[] = $r; 122 $i++; 123 } 124 } 125 126 if (!$i) { 127 return false; 128 } // no valid values were caught 129 130 $ret = array(); 131 132 // first keyword 133 if ($keywords['h']) { 134 $ret[] = $keywords['h']; 135 } elseif ($keywords['ch']) { 136 $ret[] = $keywords['ch']; 137 $keywords['cv'] = false; // prevent re-use: center = center center 138 } elseif (count($measures)) { 139 $ret[] = array_shift($measures); 140 } 141 142 if ($keywords['v']) { 143 $ret[] = $keywords['v']; 144 } elseif ($keywords['cv']) { 145 $ret[] = $keywords['cv']; 146 } elseif (count($measures)) { 147 $ret[] = array_shift($measures); 148 } 149 150 if (empty($ret)) { 151 return false; 152 } 153 return implode(' ', $ret); 154 } 155 } 156 157 // vim: et sw=4 sts=4
title
Description
Body
title
Description
Body
title
Description
Body
title
Body