HTMLPurifier 4.4.0
|
00001 <?php 00002 00003 /* W3C says: 00004 [ // adjective and number must be in correct order, even if 00005 // you could switch them without introducing ambiguity. 00006 // some browsers support that syntax 00007 [ 00008 <percentage> | <length> | left | center | right 00009 ] 00010 [ 00011 <percentage> | <length> | top | center | bottom 00012 ]? 00013 ] | 00014 [ // this signifies that the vertical and horizontal adjectives 00015 // can be arbitrarily ordered, however, there can only be two, 00016 // one of each, or none at all 00017 [ 00018 left | center | right 00019 ] || 00020 [ 00021 top | center | bottom 00022 ] 00023 ] 00024 top, left = 0% 00025 center, (none) = 50% 00026 bottom, right = 100% 00027 */ 00028 00029 /* QuirksMode says: 00030 keyword + length/percentage must be ordered correctly, as per W3C 00031 00032 Internet Explorer and Opera, however, support arbitrary ordering. We 00033 should fix it up. 00034 00035 Minor issue though, not strictly necessary. 00036 */ 00037 00038 // control freaks may appreciate the ability to convert these to 00039 // percentages or something, but it's not necessary 00040 00044 class HTMLPurifier_AttrDef_CSS_BackgroundPosition extends HTMLPurifier_AttrDef 00045 { 00046 00047 protected $length; 00048 protected $percentage; 00049 00050 public function __construct() { 00051 $this->length = new HTMLPurifier_AttrDef_CSS_Length(); 00052 $this->percentage = new HTMLPurifier_AttrDef_CSS_Percentage(); 00053 } 00054 00055 public function validate($string, $config, $context) { 00056 $string = $this->parseCDATA($string); 00057 $bits = explode(' ', $string); 00058 00059 $keywords = array(); 00060 $keywords['h'] = false; // left, right 00061 $keywords['v'] = false; // top, bottom 00062 $keywords['ch'] = false; // center (first word) 00063 $keywords['cv'] = false; // center (second word) 00064 $measures = array(); 00065 00066 $i = 0; 00067 00068 $lookup = array( 00069 'top' => 'v', 00070 'bottom' => 'v', 00071 'left' => 'h', 00072 'right' => 'h', 00073 'center' => 'c' 00074 ); 00075 00076 foreach ($bits as $bit) { 00077 if ($bit === '') continue; 00078 00079 // test for keyword 00080 $lbit = ctype_lower($bit) ? $bit : strtolower($bit); 00081 if (isset($lookup[$lbit])) { 00082 $status = $lookup[$lbit]; 00083 if ($status == 'c') { 00084 if ($i == 0) { 00085 $status = 'ch'; 00086 } else { 00087 $status = 'cv'; 00088 } 00089 } 00090 $keywords[$status] = $lbit; 00091 $i++; 00092 } 00093 00094 // test for length 00095 $r = $this->length->validate($bit, $config, $context); 00096 if ($r !== false) { 00097 $measures[] = $r; 00098 $i++; 00099 } 00100 00101 // test for percentage 00102 $r = $this->percentage->validate($bit, $config, $context); 00103 if ($r !== false) { 00104 $measures[] = $r; 00105 $i++; 00106 } 00107 00108 } 00109 00110 if (!$i) return false; // no valid values were caught 00111 00112 $ret = array(); 00113 00114 // first keyword 00115 if ($keywords['h']) $ret[] = $keywords['h']; 00116 elseif ($keywords['ch']) { 00117 $ret[] = $keywords['ch']; 00118 $keywords['cv'] = false; // prevent re-use: center = center center 00119 } 00120 elseif (count($measures)) $ret[] = array_shift($measures); 00121 00122 if ($keywords['v']) $ret[] = $keywords['v']; 00123 elseif ($keywords['cv']) $ret[] = $keywords['cv']; 00124 elseif (count($measures)) $ret[] = array_shift($measures); 00125 00126 if (empty($ret)) return false; 00127 return implode(' ', $ret); 00128 00129 } 00130 00131 } 00132 00133 // vim: et sw=4 sts=4