1<?php 2// The background-position value is an array containing two array for X and Y position correspondingly 3// each coordinate-position array, in its turn containes two values: 4// first, the numeric value of percentage or units 5// second, flag indication that this value is a percentage (true) or plain unit value (false) 6 7define('LENGTH_REGEXP',"(?:-?\d*\.?\d+(?:em|ex|px|in|cm|mm|pt|pc)\b|-?\d+(?:em|ex|px|in|cm|mm|pt|pc)\b)"); 8define('PERCENTAGE_REGEXP',"\b\d+%"); 9define('TEXT_REGEXP',"\b(?:top|bottom|left|right|center)\b"); 10 11define('BG_POSITION_SUBVALUE_TYPE_HORZ',1); 12define('BG_POSITION_SUBVALUE_TYPE_VERT',2); 13 14class CSSBackgroundPosition extends CSSSubFieldProperty { 15 function get_property_code() { 16 return CSS_BACKGROUND_POSITION; 17 } 18 19 function get_property_name() { 20 return 'background-position'; 21 } 22 23 function default_value() { 24 return new BackgroundPosition(0,true, 25 0,true); 26 } 27 28 function build_subvalue($value) { 29 if ($value === "left" || 30 $value === "top") { 31 return array(0, true); 32 }; 33 34 if ($value === "right" || 35 $value === "bottom") { 36 return array(100, true); 37 }; 38 39 if ($value === "center") { 40 return array(50, true); 41 }; 42 43 if (substr($value, strlen($value)-1,1) === "%") { 44 return array((int)$value, true); 45 } else { 46 return array($value, false); 47 }; 48 } 49 50 function build_value($x, $y) { 51 return array(CSSBackgroundPosition::build_subvalue($x), 52 CSSBackgroundPosition::build_subvalue($y)); 53 } 54 55 function detect_type($value) { 56 if ($value === "left" || $value === "right") { return BG_POSITION_SUBVALUE_TYPE_HORZ; }; 57 if ($value === "top" || $value === "bottom") { return BG_POSITION_SUBVALUE_TYPE_VERT; }; 58 return null; 59 } 60 61 // See CSS 2.1 'background-position' for description of possible values 62 // 63 function parse_in($value) { 64 if (preg_match("/(".LENGTH_REGEXP."|".PERCENTAGE_REGEXP."|".TEXT_REGEXP."|\b0\b)\s+(".LENGTH_REGEXP."|".PERCENTAGE_REGEXP."|".TEXT_REGEXP."|\b0\b)/", $value, $matches)) { 65 $x = $matches[1]; 66 $y = $matches[2]; 67 68 $type_x = CSSBackgroundPosition::detect_type($x); 69 $type_y = CSSBackgroundPosition::detect_type($y); 70 71 if (is_null($type_x) && is_null($type_y)) { 72 return CSSBackgroundPosition::build_value($x,$y); 73 }; 74 75 if ($type_x == BG_POSITION_SUBVALUE_TYPE_HORZ || 76 $type_y == BG_POSITION_SUBVALUE_TYPE_VERT) { 77 return CSSBackgroundPosition::build_value($x,$y); 78 }; 79 80 return CSSBackgroundPosition::build_value($y,$x); 81 }; 82 83 // These values should be processed separately at lastt 84 if (preg_match("/\b(top)\b/",$value)) { return array(array(50, true), array(0, true)); }; 85 if (preg_match("/\b(center)\b/",$value)) { return array(array(50, true), array(50, true)); }; 86 if (preg_match("/\b(bottom)\b/",$value)) { return array(array(50, true), array(100, true)); }; 87 if (preg_match("/\b(left)\b/",$value)) { return array(array(0, true), array(50, true)); }; 88 if (preg_match("/\b(right)\b/",$value)) { return array(array(100, true), array(50, true)); }; 89 90 if (preg_match("/".LENGTH_REGEXP."|".PERCENTAGE_REGEXP."/", $value, $matches)) { 91 $x = $matches[0]; 92 return CSSBackgroundPosition::build_value($x,"50%"); 93 }; 94 95 return null; 96 } 97 98 function parse($value) { 99 if ($value === 'inherit') { 100 return CSS_PROPERTY_INHERIT; 101 }; 102 103 $value = CSSBackgroundPosition::parse_in($value); 104 return new BackgroundPosition($value[0][0], $value[0][1], 105 $value[1][0], $value[1][1]); 106 } 107} 108?>