HTMLPurifier 4.4.0
/home/ezyang/Dev/htmlpurifier/library/HTMLPurifier/AttrDef/CSS/BackgroundPosition.php
Go to the documentation of this file.
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