PageRenderTime 48ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/sass/20130424-ead0ac1897/Extensions/Compass/Compass.php

https://github.com/vivid-planet/library
PHP | 511 lines | 495 code | 7 blank | 9 comment | 1 complexity | 3bc8aaa37ae61b7bce0dc5fc0f16112e MD5 | raw file
  1. <?php
  2. require_once dirname(__FILE__) . '/../ExtensionInterface.php';
  3. class Compass implements ExtensionInterface
  4. {
  5. public static $filesFolder = 'stylesheets';
  6. public static $filePaths = null;
  7. /**
  8. * List with alias functions in Compass
  9. * @var array
  10. */
  11. public static $functions = array(
  12. 'resolve-path',
  13. 'adjust-lightness',
  14. 'scale-lightness',
  15. 'adjust-saturation',
  16. 'scale-saturation',
  17. 'scale-color-value',
  18. 'is-position',
  19. 'is-position-list',
  20. 'opposite-position',
  21. '-webkit',
  22. '-moz',
  23. '-o',
  24. '-ms',
  25. '-svg',
  26. '-pie',
  27. '-css2',
  28. 'owg',
  29. 'prefixed',
  30. 'prefix',
  31. 'elements-of-type',
  32. 'enumerate',
  33. 'font-files',
  34. 'image-width',
  35. 'image-height',
  36. 'inline-image',
  37. 'inline-font-files',
  38. 'blank',
  39. 'compact',
  40. '-compass-nth',
  41. '-compass-list',
  42. '-compass-list',
  43. '-compass-space-list',
  44. '-compass-list-size',
  45. '-compass-slice',
  46. 'first-value-of',
  47. 'nest',
  48. 'append-selector',
  49. 'headers',
  50. 'pi',
  51. 'sin',
  52. 'cos',
  53. 'tan',
  54. 'comma-list',
  55. 'prefixed-for-transition',
  56. 'stylesheet-url',
  57. 'font-url',
  58. 'image-url'
  59. );
  60. public static function getFunctions($namespace)
  61. {
  62. $output = array();
  63. foreach (self::$functions as $function) {
  64. $originalFunction = $function;
  65. $function[0] = strtoupper($function[0]);
  66. $func = create_function('$c', 'return strtoupper($c[1]);');
  67. $function = preg_replace_callback('/-([a-z])/', $func, $function);
  68. $output[$originalFunction] = $namespace . strtolower(__CLASS__) . $function;
  69. }
  70. return $output;
  71. }
  72. /**
  73. * Returns an array with all files in $root path recursively and assign each array Key with clean alias
  74. * @param $root
  75. * @return array
  76. */
  77. public static function getFilesArray($root)
  78. {
  79. $alias = array();
  80. $directories = array();
  81. $last_letter = $root[strlen($root) - 1];
  82. $root = ($last_letter == '\\' || $last_letter == '/') ? $root : $root . DIRECTORY_SEPARATOR;
  83. $directories[] = $root;
  84. while (sizeof($directories)) {
  85. $dir = array_pop($directories);
  86. if ($handle = opendir($dir)) {
  87. while (false !== ($file = readdir($handle))) {
  88. if ($file == '.' || $file == '..') {
  89. continue;
  90. }
  91. $file = $dir . $file;
  92. if (is_dir($file)) {
  93. $directory_path = $file . DIRECTORY_SEPARATOR;
  94. array_push($directories, $directory_path);
  95. } elseif (is_file($file)) {
  96. $key = basename($file);
  97. $alias[substr($key, 1, strpos($key, '.') - 1)] = $file;
  98. }
  99. }
  100. closedir($handle);
  101. }
  102. }
  103. return $alias;
  104. }
  105. /**
  106. * Implementation of hook_resolve_path_NAMESPACE().
  107. */
  108. public static function resolveExtensionPath($callerImport, $parser, $syntax = 'scss')
  109. {
  110. $alias = str_replace('/_', '/', str_replace(array('.scss', '.sass'), '', $callerImport));
  111. if (strrpos($alias, '/') !== false) {
  112. $alias = substr($alias, strrpos($alias, '/') + 1);
  113. }
  114. if (self::$filePaths == null) {
  115. self::$filePaths = self::getFilesArray(dirname(__FILE__) . '/' . self::$filesFolder . '/');
  116. }
  117. if (isset(self::$filePaths[$alias])) {
  118. return self::$filePaths[$alias];
  119. }
  120. }
  121. /**
  122. * Resolves requires to the compass namespace (eg namespace/css3/border-radius)
  123. */
  124. public static function compassResolvePath($file)
  125. {
  126. if ($file{0} == '/') {
  127. return $file;
  128. }
  129. if (!$path = realpath($file)) {
  130. $path = SassScriptFunction::$context->node->token->filename;
  131. $path = substr($path, 0, strrpos($path, '/')) . '/';
  132. $path = $path . $file;
  133. $last = '';
  134. while ($path != $last) {
  135. $last = $path;
  136. $path = preg_replace('`(^|/)(?!\.\./)([^/]+)/\.\./`', '$1', $path);
  137. }
  138. $path = realpath($path);
  139. }
  140. if ($path) {
  141. return $path;
  142. }
  143. return false;
  144. }
  145. public static function compassImageWidth($file)
  146. {
  147. if ($info = self::compassImageInfo($file)) {
  148. return new SassNumber($info[0] . 'px');
  149. }
  150. return new SassNumber('0px');
  151. }
  152. public static function compassImageHeight($file)
  153. {
  154. if ($info = self::compassImageInfo($file)) {
  155. return new SassNumber($info[1] . 'px');
  156. }
  157. return new SassNumber('0px');
  158. }
  159. public static function compassImageInfo($file)
  160. {
  161. if ($path = self::compassResolvePath($file)) {
  162. if ($info = getimagesize($path)) {
  163. return $info;
  164. }
  165. }
  166. return false;
  167. }
  168. public static function compassInlineImage($file, $mime = null)
  169. {
  170. if ($path = self::compassUrl($file, true, false)) {
  171. $info = getimagesize($path);
  172. $mime = $info['mime'];
  173. $data = base64_encode(file_get_contents($path));
  174. # todo - do not return encoded if file size > 32kb
  175. return new SassString("url('data:$mime;base64,$data')");
  176. }
  177. return new SassString('');
  178. }
  179. public static function compassInlineFontFiles($file)
  180. {
  181. $args = func_get_args();
  182. $files = array();
  183. $mimes = array(
  184. 'otf' => 'font.opentype',
  185. 'ttf' => 'font.truetype',
  186. 'woff' => 'font.woff',
  187. 'off' => 'font.openfont',
  188. );
  189. while (count($args)) {
  190. $path = self::compassResolvePath(array_shift($args));
  191. $data = base64_encode(file_get_contents($path));
  192. $format = array_shift($args);
  193. $ext = array_pop(explode('.', $file));
  194. if (isset($mimes[$ext])) {
  195. $mime = $mimes[$ext];
  196. } else {
  197. continue;
  198. }
  199. $files[] = "url('data:$mime;base64,$data') format('$format')";
  200. }
  201. return new SassString(implode(', ', $files));
  202. }
  203. public static function compassBlank($object)
  204. {
  205. if (is_object($object)) {
  206. $object = $object->value;
  207. }
  208. $result = false;
  209. if (is_bool($object)) {
  210. $result = !$object;
  211. }
  212. if (is_string($object)) {
  213. $result = (strlen(trim($object, ' ,')) === 0);
  214. }
  215. return new SassBoolean($result);
  216. }
  217. public static function compassCompact()
  218. {
  219. $sep = ', ';
  220. $args = func_get_args();
  221. $list = array();
  222. // remove blank entries
  223. // append non-blank entries to list
  224. foreach ($args as $k => $v) {
  225. if (is_object($v)) {
  226. $string = (isset($v->value) ? $v->value : false);
  227. } else {
  228. $string = (string)$v;
  229. }
  230. if (empty($string) || $string == 'false') {
  231. unset($args[$k]);
  232. continue;
  233. }
  234. $list[] = $string;
  235. }
  236. return new SassString(implode($sep, $list));
  237. }
  238. public static function compassCompassNth()
  239. {
  240. $args = func_get_args();
  241. $place = array_pop($args);
  242. $list = array();
  243. foreach ($args as $arg) {
  244. $list = array_merge($list, self::compassList($arg));
  245. }
  246. if ($place == 'first') {
  247. $place = 0;
  248. }
  249. if ($place == 'last') {
  250. $place = count($list) - 1;
  251. }
  252. if (isset($list[$place])) {
  253. return current(SassScriptLexer::$instance->lex($list[$place], new SassContext()));
  254. }
  255. return new SassBoolean(false);
  256. }
  257. public static function compassCompassList()
  258. {
  259. $args = func_get_args();
  260. $list = array();
  261. foreach ($args as $arg) {
  262. $list = array_merge($list, self::compassList($arg));
  263. }
  264. return new SassString(implode(', ', $list));
  265. }
  266. public static function compassCompassSpaceList()
  267. {
  268. $args = func_get_args();
  269. $list = self::compassList($args, ',');
  270. return new SassString(implode(' ', $list));
  271. }
  272. public static function compassCompassListSize()
  273. {
  274. $args = func_get_args();
  275. $list = self::compassList($args, ',');
  276. return new SassNumber(count($list));
  277. }
  278. public static function compassCompassListSlice($list, $start, $end)
  279. {
  280. $args = func_get_args();
  281. $end = array_pop($args);
  282. $start = array_pop($args);
  283. $list = self::compassList($args, ',');
  284. return implode(',', array_slice($list, $start, $end));
  285. }
  286. public static function compassFirstValueOf()
  287. {
  288. $args = array();
  289. $args[] = 'first';
  290. return call_user_func_array('self::compassCompassNth', $args);
  291. }
  292. public static function compassList($list, $seperator = ',')
  293. {
  294. if (is_object($list)) {
  295. $list = $list->value;
  296. }
  297. if (is_array($list)) {
  298. $newlist = array();
  299. foreach ($list as $listlet) {
  300. $newlist = array_merge($newlist, self::compassList($listlet, $seperator));
  301. }
  302. $list = implode(', ', $newlist);
  303. }
  304. $out = array();
  305. $size = 0;
  306. $braces = 0;
  307. $stack = '';
  308. for ($i = 0; $i < strlen($list); $i++) {
  309. $char = substr($list, $i, 1);
  310. switch ($char) {
  311. case '(':
  312. $braces++;
  313. $stack .= $char;
  314. break;
  315. case ')':
  316. $braces--;
  317. $stack .= $char;
  318. break;
  319. case $seperator:
  320. if ($braces === 0) {
  321. $out[] = $stack;
  322. $stack = '';
  323. $size++;
  324. break;
  325. }
  326. default:
  327. $stack .= $char;
  328. }
  329. }
  330. $out[] = $stack;
  331. return $out;
  332. }
  333. // http://compass-style.org/reference/compass/helpers/selectors/#nest
  334. public static function compassNest()
  335. {
  336. $args = func_get_args();
  337. $output = explode(',', array_pop($args));
  338. for ($i = count($args) - 1; $i >= 0; $i--) {
  339. $current = explode(',', $args[$i]);
  340. $size = count($output);
  341. foreach ($current as $selector) {
  342. for ($j = 0; $j < $size; $j++) {
  343. $output[] = trim($selector) . " " . trim($output[$j]);
  344. }
  345. }
  346. $output = array_slice($output, $size);
  347. }
  348. return new SassString(implode(', ', $output));
  349. }
  350. public static function compassAppendSelector($initial, $new)
  351. {
  352. $list = explode(',', $initial);
  353. foreach ($list as $k => $selector) {
  354. $list[$k] = trim($selector) . $new;
  355. }
  356. return new SassString(implode(', ', $list));
  357. }
  358. public static function compassHeaders($from = false, $to = false)
  359. {
  360. if (is_object($from)) {
  361. $from = $from->value;
  362. }
  363. if (is_object($to)) {
  364. $to = $to->value;
  365. }
  366. if (!$from || !is_numeric($from)) {
  367. $from = 1;
  368. }
  369. if (!$to || !is_numeric($to)) {
  370. $to = 6;
  371. }
  372. $from = (int)$from;
  373. $to = (int)$to;
  374. $output = array();
  375. for ($i = $from; $i <= $to; $i++) {
  376. $output[] = 'h' . $i;
  377. }
  378. return new SassString(implode(', ', $output));
  379. }
  380. public static function compassCommaList()
  381. {
  382. print_r(func_get_args());
  383. die;
  384. }
  385. public static function compassPrefixedForTransition($prefix, $property)
  386. {
  387. }
  388. public static function compassPi()
  389. {
  390. return pi();
  391. }
  392. public static function compassSin($number)
  393. {
  394. return new SassNumber(sin($number));
  395. }
  396. public static function compassCos($number)
  397. {
  398. return new SassNumber(sin($number));
  399. }
  400. public static function compassTan($number)
  401. {
  402. return new SassNumber(sin($number));
  403. }
  404. # not sure what should happen with these
  405. public static function compassStylesheetUrl($path, $only_path = false)
  406. {
  407. return self::compassUrl($path, $only_path);
  408. }
  409. public static function compassFontUrl($path, $only_path = false)
  410. {
  411. return self::compassUrl($path, $only_path);
  412. }
  413. public static function compassImageUrl($path, $only_path = false)
  414. {
  415. return self::compassUrl($path, $only_path);
  416. }
  417. public static function compassUrl($path, $only_path = false, $web_path = true)
  418. {
  419. $opath = $path;
  420. if (!$path = SassFile::get_file($path, SassParser::$instance, false)) {
  421. throw new Exception('File not found: ' . $opath);
  422. }
  423. $path = $path[0];
  424. if ($web_path) {
  425. $webroot = realpath($_SERVER['DOCUMENT_ROOT']);
  426. $path = str_replace($webroot, '', $path);
  427. }
  428. if ($only_path) {
  429. return new SassString($path);
  430. }
  431. return new SassString("url('$path')");
  432. }
  433. public static function compassOppositePosition($from)
  434. {
  435. $ret = '';
  436. if ($from == 'top') {
  437. $ret = 'bottom';
  438. } else if ($from == 'bottom') {
  439. $ret = 'top';
  440. } else if ($from == 'left') {
  441. $ret = 'right';
  442. } else if ($from == 'right') {
  443. $ret = 'left';
  444. } else if ($from == 'center') {
  445. $ret = 'center';
  446. }
  447. return $ret;
  448. }
  449. }