File indexing completed on 2024-12-22 05:36:18
0001 <?php 0002 0003 /* W3C says: 0004 [ // adjective and number must be in correct order, even if 0005 // you could switch them without introducing ambiguity. 0006 // some browsers support that syntax 0007 [ 0008 <percentage> | <length> | left | center | right 0009 ] 0010 [ 0011 <percentage> | <length> | top | center | bottom 0012 ]? 0013 ] | 0014 [ // this signifies that the vertical and horizontal adjectives 0015 // can be arbitrarily ordered, however, there can only be two, 0016 // one of each, or none at all 0017 [ 0018 left | center | right 0019 ] || 0020 [ 0021 top | center | bottom 0022 ] 0023 ] 0024 top, left = 0% 0025 center, (none) = 50% 0026 bottom, right = 100% 0027 */ 0028 0029 /* QuirksMode says: 0030 keyword + length/percentage must be ordered correctly, as per W3C 0031 0032 Internet Explorer and Opera, however, support arbitrary ordering. We 0033 should fix it up. 0034 0035 Minor issue though, not strictly necessary. 0036 */ 0037 0038 // control freaks may appreciate the ability to convert these to 0039 // percentages or something, but it's not necessary 0040 0041 /** 0042 * Validates the value of background-position. 0043 */ 0044 class HTMLPurifier_AttrDef_CSS_BackgroundPosition extends HTMLPurifier_AttrDef 0045 { 0046 0047 /** 0048 * @type HTMLPurifier_AttrDef_CSS_Length 0049 */ 0050 protected $length; 0051 0052 /** 0053 * @type HTMLPurifier_AttrDef_CSS_Percentage 0054 */ 0055 protected $percentage; 0056 0057 public function __construct() 0058 { 0059 $this->length = new HTMLPurifier_AttrDef_CSS_Length(); 0060 $this->percentage = new HTMLPurifier_AttrDef_CSS_Percentage(); 0061 } 0062 0063 /** 0064 * @param string $string 0065 * @param HTMLPurifier_Config $config 0066 * @param HTMLPurifier_Context $context 0067 * @return bool|string 0068 */ 0069 public function validate($string, $config, $context) 0070 { 0071 $string = $this->parseCDATA($string); 0072 $bits = explode(' ', $string); 0073 0074 $keywords = array(); 0075 $keywords['h'] = false; // left, right 0076 $keywords['v'] = false; // top, bottom 0077 $keywords['ch'] = false; // center (first word) 0078 $keywords['cv'] = false; // center (second word) 0079 $measures = array(); 0080 0081 $i = 0; 0082 0083 $lookup = array( 0084 'top' => 'v', 0085 'bottom' => 'v', 0086 'left' => 'h', 0087 'right' => 'h', 0088 'center' => 'c' 0089 ); 0090 0091 foreach ($bits as $bit) { 0092 if ($bit === '') { 0093 continue; 0094 } 0095 0096 // test for keyword 0097 $lbit = ctype_lower($bit) ? $bit : strtolower($bit); 0098 if (isset($lookup[$lbit])) { 0099 $status = $lookup[$lbit]; 0100 if ($status == 'c') { 0101 if ($i == 0) { 0102 $status = 'ch'; 0103 } else { 0104 $status = 'cv'; 0105 } 0106 } 0107 $keywords[$status] = $lbit; 0108 $i++; 0109 } 0110 0111 // test for length 0112 $r = $this->length->validate($bit, $config, $context); 0113 if ($r !== false) { 0114 $measures[] = $r; 0115 $i++; 0116 } 0117 0118 // test for percentage 0119 $r = $this->percentage->validate($bit, $config, $context); 0120 if ($r !== false) { 0121 $measures[] = $r; 0122 $i++; 0123 } 0124 } 0125 0126 if (!$i) { 0127 return false; 0128 } // no valid values were caught 0129 0130 $ret = array(); 0131 0132 // first keyword 0133 if ($keywords['h']) { 0134 $ret[] = $keywords['h']; 0135 } elseif ($keywords['ch']) { 0136 $ret[] = $keywords['ch']; 0137 $keywords['cv'] = false; // prevent re-use: center = center center 0138 } elseif (count($measures)) { 0139 $ret[] = array_shift($measures); 0140 } 0141 0142 if ($keywords['v']) { 0143 $ret[] = $keywords['v']; 0144 } elseif ($keywords['cv']) { 0145 $ret[] = $keywords['cv']; 0146 } elseif (count($measures)) { 0147 $ret[] = array_shift($measures); 0148 } 0149 0150 if (empty($ret)) { 0151 return false; 0152 } 0153 return implode(' ', $ret); 0154 } 0155 } 0156 0157 // vim: et sw=4 sts=4