| Current Path : /home/azimutno/www/templates/jdirect_aviato/warp/src/Warp/Asset/Filter/ |
| Current File : /home/azimutno/www/templates/jdirect_aviato/warp/src/Warp/Asset/Filter/CssRtlFilter.php |
<?php
/**
* @package Warp Theme Framework
* @author YOOtheme http://www.yootheme.com
* @copyright Copyright (C) YOOtheme GmbH
* @license http://www.gnu.org/licenses/gpl.html GNU/GPL
*/
namespace Warp\Asset\Filter;
/**
* Convert CSS to work right to left
*/
class CssRtlFilter implements FilterInterface
{
public static $propertyMap = array(
'margin-left' => 'margin-right',
'margin-right' => 'margin-left',
'padding-left' => 'padding-right',
'padding-right' => 'padding-left',
'border-left' => 'border-right',
'border-right' => 'border-left',
'border-left-color' => 'border-right-color',
'border-right-color' => 'border-left-color',
'border-left-width' => 'border-right-width',
'border-right-width' => 'border-left-width',
'border-left-style' => 'border-right-style',
'border-right-style' => 'border-left-style',
'border-bottom-right-radius' => 'border-bottom-left-radius',
'border-bottom-left-radius' => 'border-bottom-right-radius',
'border-top-right-radius' => 'border-top-left-radius',
'border-top-left-radius' => 'border-top-right-radius',
'left' => 'right',
'right' => 'left'
);
public static $valueMap = array(
'padding' => 'quad',
'margin' => 'quad',
'text-align' => 'rtltr',
'float' => 'rtltr',
'clear' => 'rtltr',
'direction' => 'direction',
'border-radius' => 'quad_radius',
'border-color' => 'quad',
'border-width' => 'quad',
'border-style' => 'quad',
'background-position' => 'bgPosition',
'box-shadow' => 'boxShadow',
'background' => 'background',
'background-image' => 'backgroundImage',
'transform' => 'transform',
'-ms-transform' => 'transform',
'-webkit-transform' => 'transform',
);
/**
* Filter callbacks
*/
public function filterLoad($asset) {}
public function filterContent($asset)
{
$asset->setContent($this->process($asset->getContent()));
}
/**
* Convert CSS to be right to left
*
* @param string $css
*
* @return string
*/
public function process($css)
{
$css = trim($css); // give it a solid trimming to start
$css = preg_replace('/\/\*[\s\S]+?\*\//', '', $css); // comments
$css = preg_replace('/[\n\r]/', '', $css); // line breaks and carriage returns
$css = preg_replace('/\s*([:;,{}])\s*/', '$1', $css); // space between selectors, declarations, properties and values
$css = preg_replace('/\s+/', ' ', $css); // replace multiple spaces with single spaces
$that = $this;
$css = preg_replace_callback('/([^;:\{\}]+?)\:([^;:\{\}]+?)([;}])/i', function($arr) use ($that) {
list($all, $prop, $val, $end) = $arr;
$isImportant = strpos($val, '!important');
if (isset($that::$propertyMap[$prop])) {
$prop = $that::$propertyMap[$prop];
}
if (array_key_exists($prop, $that::$valueMap)) {
$method = $that::$valueMap[$prop];
$val = $that->{$method}($val);
}
if (strpos($val, '!important') === false && $isImportant) $val .= '!important';
return $prop . ':' . $val . $end;
}, $css);
return $css;
}
public function quad($v) {
// 1px 2px 3px 4px => 1px 4px 3px 2px
$m = explode(' ', trim($v));
if ($m && count($m) == 4) {
return implode(' ', array($m[0], $m[3], $m[2], $m[1]));
}
return $v;
}
public function quad_radius($v) {
$m = explode('/\s+/', trim($v));
// 1px 2px 3px 4px => 1px 2px 4px 3px
// since border-radius: top-left top-right bottom-right bottom-left
// will be border-radius: top-right top-left bottom-left bottom-right
if ($m && count($m) == 4) {
return implode(' ', array($m[1], $m[0], $m[3], $m[2]));
} else if ($m && count($m) == 3) {
// 5px 10px 20px => 10px 5px 10px 20px
return implode(' ', array($m[1], $m[0], $m[1], $m[2]));
}
return $v;
}
public function direction($v) {
return (preg_match('/ltr/', $v) ? 'rtl' : (preg_match('/rtl/', $v) ? 'ltr' : $v));
}
public function bracketCommaSplit($str) {
/* <prop1>(<args1>), <prop2>(<args2>) -> ["<prop1>(<args1>)", "<prop2>(<args2>)"]*/
$parenthesisCount = 0;
$lastSplit = 0;
$arr = array();
for($i = 0; $i<strlen($str); ++$i) {
$c = $str[$i];
$parenthesisCount += ($c == '(' ? 1 : ( $c == ')' ? -1 : 0));
if (($c==',' && $parenthesisCount==0) || $i==strlen($str)-1) {
$arr[] = trim(trim(trim(substr($str ,$lastSplit, $i-$lastSplit+1)), ','));
$lastSplit = $i+1; // +1 to get rid of the comma
}
}
return $arr;
}
public function rtltr($v) {
if (preg_match('/left/', $v)) return 'right';
if (preg_match('/right/', $v)) return 'left';
return $v;
}
public function bgPosition($v) {
if (preg_match('/\bleft\b/', $v)) {
$v = preg_replace('/\bleft\b/', 'right', $v);
} else if (preg_match('/\bright\b/', $v)) {
$v = preg_replace('/\bright\b/', 'left', $v);
}
$m = explode(' ', trim($v));
if ($m && (count($m) == 1) && preg_match('/(\d+)([a-z]{2}|%)/', $v)) {
$v = 'right ' . $v;
}
if ($m && count($m) == 2 && preg_match('/\d+%/', $m[0])) {
// 30% => 70% (100 - x)
$v = (100 - (int)$m[0]) . '% ' . $m[1];
}
preg_match('/(\-?\d+)px/', $m[0], $pxmatch);
if($m && count($m) == 2 && $pxmatch) {
$x = $pxmatch[1];
$minusX = ($x=='0' ? '0' : ((int)$x < 0 ? substr($x, 1) . 'px' : '-' . $x . 'px'));
$v = $minusX . ' ' . $m[1];
}
return $v;
}
public function boxShadow($v) {
$shadowRtl = function($shadow) {
// multiplies <left> offset with -1
$found = false;
$parts = explode(' ', $shadow);
for ($i = 0; $i<count($parts); ++$i) {
$el = $parts[$i];
if (!$found && preg_match('/\d/', $el)) {
$found = true;
$parts[$i] = ($el[0] == "0" ? 0 : ($el[0] == "-" ? substr($el, 1) : "-".$el));
}
}
return implode(' ', $parts);
};
$arr = $this->bracketCommaSplit($v);
$v = implode(',', array_map($shadowRtl, $arr));
return $v;
}
public function backgroundImage($val) {
$parseSingle = function($v) {
if(substr($v, 0, 4) == "url(") {
// dont mess with background image paths for now
return $v;
}
if (strpos($v, "gradient")) {
$v = preg_replace_callback('/(left|right)/', function($dir) {
return $dir === 'left' ? 'right' : 'left';
}, $v);
$v = preg_replace_callback('/(\d+deg)/', function($el) {
$num = (int)preg_replace('/deg/', '', $el[0]);
return (180-$num).'deg';
}, $v);
}
return $v;
};
$arr = $this->bracketCommaSplit($val);
return implode(',', array_map($parseSingle, $arr));
}
public function background($v) {
// TODO: split several background layers (divided by comma)
$that = $this;
$parseSingle = function($v) use ($that) {
// background-image
$method = function($val) use ($that) {
$str = $val[0];
return $that->backgroundImage($str);
};
$v = preg_replace_callback('/url\((.*?)\)|none|([^\s]*?gradient.*?\(.+\))/i', $method, $v);
// background-position
$v = preg_replace_callback('/\s(left|right|center|top|bottom|-?\d+([a-zA-Z]{2}|%?))\s(left|right|center|top|bottom|-?\d+([a-zA-Z]{2}|%?))[;\s]?/i',
function($arr) use ($that) {
return ' '.$that->bgPosition(trim($arr[0], ';')).(strpos($arr[0], ';') !== false ? ';' : ' ');
}, $v);
return $v;
};
$arr = $this->bracketCommaSplit($v);
return implode(',', array_map($parseSingle, $arr));
}
public function transform($val) {
$negateValue = function($valString) {
return ($valString[0] == "0" ? 0 : ($valString[0] == "-" ? substr($valString, 1) : "-".$valString));
};
// translate, translateX, translate3D
$translateRegex = '/(translate(X|x|3D|3d)?)\(([^,\)]+)([^\)]*)\)/';
$translateCallback = function($matches) use ($negateValue) {
$value = trim($matches[3]);
$remainder = $matches[4];
$res = $matches[1].'('.$negateValue($value).($remainder ? $remainder : '').')';
return $res;
};
$val = preg_replace_callback($translateRegex, $translateCallback, $val);
// rotate
$rotateRegex = '/rotate\(\s*(\d+)\s*deg\s*\)/';
$rotateCallback = function($matches) {
$angle = (int)$matches[1];
$mirrored = 180 - $angle;
return 'rotate('.$mirrored.'deg)';
};
$val = preg_replace_callback($rotateRegex, $rotateCallback, $val);
return $val;
}
}