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