Version Description
- Updated scssphp to version 0.6.6
Download this release
Release Info
Developer | connectthink |
Plugin | WP-SCSS |
Version | 1.2.2 |
Comparing to | |
See all releases |
Code changes from version 1.2.1 to 1.2.2
- readme.txt +5 -2
- scssphp/src/Compiler.php +277 -77
- scssphp/src/Node/Number.php +5 -5
- scssphp/src/Parser.php +38 -29
- scssphp/src/Server.php +1 -1
- scssphp/src/Version.php +1 -1
- wp-scss.php +2 -2
readme.txt
CHANGED
@@ -4,7 +4,7 @@ Tags: sass, scss, css
|
|
4 |
Plugin URI: https://github.com/ConnectThink/WP-SCSS
|
5 |
Requires at least: 3.0.1
|
6 |
Tested up to: 4.7
|
7 |
-
Stable tag: 1.2.
|
8 |
License: GPLv3 or later
|
9 |
License URI: http://www.gnu.org/copyleft/gpl.html
|
10 |
|
@@ -62,8 +62,11 @@ Make sure your directories are properly defined in the settings. Paths are defin
|
|
62 |
If you are having issues with the plugin, create an issue on [github](https://github.com/ConnectThink/WP-SCSS), and we'll do our best to help.
|
63 |
|
64 |
== Changelog ==
|
|
|
|
|
|
|
65 |
= 1.2.1 =
|
66 |
-
*
|
67 |
|
68 |
= 1.2.0 =
|
69 |
* Fixed a bug where directory inputs were not getting sanitized [@mmcev106](https://github.com/ConnectThink/WP-SCSS/pull/66)
|
4 |
Plugin URI: https://github.com/ConnectThink/WP-SCSS
|
5 |
Requires at least: 3.0.1
|
6 |
Tested up to: 4.7
|
7 |
+
Stable tag: 1.2.2
|
8 |
License: GPLv3 or later
|
9 |
License URI: http://www.gnu.org/copyleft/gpl.html
|
10 |
|
62 |
If you are having issues with the plugin, create an issue on [github](https://github.com/ConnectThink/WP-SCSS), and we'll do our best to help.
|
63 |
|
64 |
== Changelog ==
|
65 |
+
= 1.2.2 =
|
66 |
+
* Updated scssphp to version 0.6.6
|
67 |
+
|
68 |
= 1.2.1 =
|
69 |
+
* Changed set version option to update if already exists
|
70 |
|
71 |
= 1.2.0 =
|
72 |
* Fixed a bug where directory inputs were not getting sanitized [@mmcev106](https://github.com/ConnectThink/WP-SCSS/pull/66)
|
scssphp/src/Compiler.php
CHANGED
@@ -125,20 +125,21 @@ class Compiler
|
|
125 |
protected $rootEnv;
|
126 |
protected $rootBlock;
|
127 |
|
|
|
|
|
|
|
|
|
|
|
|
|
128 |
private $indentLevel;
|
129 |
private $commentsSeen;
|
130 |
private $extends;
|
131 |
private $extendsMap;
|
132 |
private $parsedFiles;
|
133 |
-
private $env;
|
134 |
-
private $scope;
|
135 |
private $parser;
|
136 |
-
private $sourceNames;
|
137 |
private $sourceIndex;
|
138 |
private $sourceLine;
|
139 |
private $sourceColumn;
|
140 |
-
private $storeEnv;
|
141 |
-
private $charsetSeen;
|
142 |
private $stderr;
|
143 |
private $shouldEvaluate;
|
144 |
private $ignoreErrors;
|
@@ -207,7 +208,7 @@ class Compiler
|
|
207 |
*
|
208 |
* @return \Leafo\ScssPhp\Parser
|
209 |
*/
|
210 |
-
|
211 |
{
|
212 |
$parser = new Parser($path, count($this->sourceNames), $this->encoding);
|
213 |
|
@@ -396,23 +397,42 @@ class Compiler
|
|
396 |
}
|
397 |
|
398 |
if ($this->matchExtendsSingle($part, $origin)) {
|
399 |
-
$before = array_slice($selector, 0, $i);
|
400 |
$after = array_slice($selector, $i + 1);
|
401 |
-
$
|
|
|
|
|
402 |
|
403 |
foreach ($origin as $new) {
|
404 |
$k = 0;
|
405 |
|
406 |
// remove shared parts
|
407 |
if ($initial) {
|
408 |
-
while ($k < $
|
409 |
$k++;
|
410 |
}
|
411 |
}
|
412 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
413 |
$result = array_merge(
|
414 |
$before,
|
415 |
-
$
|
|
|
416 |
$after
|
417 |
);
|
418 |
|
@@ -423,14 +443,22 @@ class Compiler
|
|
423 |
$out[] = $result;
|
424 |
|
425 |
// recursively check for more matches
|
426 |
-
$this->matchExtends($result, $out, $
|
427 |
|
428 |
// selector sequence merging
|
429 |
if (! empty($before) && count($new) > 1) {
|
|
|
|
|
|
|
|
|
|
|
430 |
$result2 = array_merge(
|
431 |
-
|
432 |
-
$
|
433 |
-
|
|
|
|
|
|
|
434 |
$after
|
435 |
);
|
436 |
|
@@ -467,6 +495,13 @@ class Compiler
|
|
467 |
}
|
468 |
}
|
469 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
470 |
foreach ($single as $part) {
|
471 |
if (isset($this->extendsMap[$part])) {
|
472 |
foreach ($this->extendsMap[$part] as $idx) {
|
@@ -496,7 +531,17 @@ class Compiler
|
|
496 |
return false;
|
497 |
}
|
498 |
|
499 |
-
$
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
500 |
|
501 |
if (count(array_diff($combined, $origin[$j][count($origin[$j]) - 1]))) {
|
502 |
$origin[$j][count($origin[$j]) - 1] = $combined;
|
@@ -511,6 +556,39 @@ class Compiler
|
|
511 |
return $found;
|
512 |
}
|
513 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
514 |
/**
|
515 |
* Combine selector single
|
516 |
*
|
@@ -651,7 +729,7 @@ class Compiler
|
|
651 |
{
|
652 |
$env = $this->pushEnv($block);
|
653 |
$envs = $this->compactEnv($env);
|
654 |
-
$without = isset($block->with) ? $this->compileWith($block->with) :
|
655 |
|
656 |
// wrap inline selector
|
657 |
if ($block->selector) {
|
@@ -776,12 +854,12 @@ class Compiler
|
|
776 |
];
|
777 |
|
778 |
// exclude selectors by default
|
779 |
-
$without =
|
780 |
|
781 |
-
if ($this->libMapHasKey([$with,
|
782 |
-
$without =
|
783 |
|
784 |
-
$list = $this->coerceList($this->libMapGet([$with,
|
785 |
|
786 |
foreach ($list[2] as $item) {
|
787 |
$keyword = $this->compileStringContent($this->coerceString($item));
|
@@ -792,10 +870,10 @@ class Compiler
|
|
792 |
}
|
793 |
}
|
794 |
|
795 |
-
if ($this->libMapHasKey([$with,
|
796 |
$without = 0;
|
797 |
|
798 |
-
$list = $this->coerceList($this->libMapGet([$with,
|
799 |
|
800 |
foreach ($list[2] as $item) {
|
801 |
$keyword = $this->compileStringContent($this->coerceString($item));
|
@@ -842,10 +920,10 @@ class Compiler
|
|
842 |
*/
|
843 |
private function isWithout($without, Block $block)
|
844 |
{
|
845 |
-
if ((($without &
|
846 |
-
(($without &
|
847 |
isset($block->type) && $block->type === Type::T_MEDIA) ||
|
848 |
-
(($without &
|
849 |
isset($block->type) && $block->type === Type::T_DIRECTIVE &&
|
850 |
isset($block->name) && $block->name === 'supports')
|
851 |
) {
|
@@ -936,13 +1014,16 @@ class Compiler
|
|
936 |
$line = $block->sourceLine;
|
937 |
|
938 |
switch ($this->lineNumberStyle) {
|
939 |
-
case
|
940 |
-
$annotation->lines[] = '/* line ' . $line
|
|
|
|
|
941 |
break;
|
942 |
|
943 |
-
case
|
944 |
-
$annotation->lines[] = '@media -sass-debug-info{
|
945 |
-
. '
|
|
|
946 |
break;
|
947 |
}
|
948 |
|
@@ -1283,6 +1364,37 @@ class Compiler
|
|
1283 |
return $out;
|
1284 |
}
|
1285 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1286 |
/**
|
1287 |
* Merge media types
|
1288 |
*
|
@@ -1460,9 +1572,9 @@ class Compiler
|
|
1460 |
list(, $name, $value) = $child;
|
1461 |
|
1462 |
if ($name[0] === Type::T_VARIABLE) {
|
1463 |
-
$
|
1464 |
-
$isDefault =
|
1465 |
-
$isGlobal =
|
1466 |
|
1467 |
if ($isGlobal) {
|
1468 |
$this->set($name[1], $this->reduce($value), false, $this->rootEnv);
|
@@ -1471,7 +1583,7 @@ class Compiler
|
|
1471 |
|
1472 |
$shouldSet = $isDefault &&
|
1473 |
(($result = $this->get($name[1], false)) === null
|
1474 |
-
|| $result ===
|
1475 |
|
1476 |
if (! $isDefault || $shouldSet) {
|
1477 |
$this->set($name[1], $this->reduce($value));
|
@@ -1499,7 +1611,7 @@ class Compiler
|
|
1499 |
if ($value[0] !== Type::T_NULL) {
|
1500 |
$value = $this->reduce($value);
|
1501 |
|
1502 |
-
if ($value[0] === Type::T_NULL || $value ===
|
1503 |
break;
|
1504 |
}
|
1505 |
}
|
@@ -1525,7 +1637,7 @@ class Compiler
|
|
1525 |
case Type::T_FUNCTION:
|
1526 |
list(, $block) = $child;
|
1527 |
|
1528 |
-
$this->set(
|
1529 |
break;
|
1530 |
|
1531 |
case Type::T_EXTEND:
|
@@ -1573,7 +1685,7 @@ class Compiler
|
|
1573 |
list(,, $values) = $this->coerceList($item);
|
1574 |
|
1575 |
foreach ($each->vars as $i => $var) {
|
1576 |
-
$this->set($var, isset($values[$i]) ? $values[$i] :
|
1577 |
}
|
1578 |
}
|
1579 |
|
@@ -1622,7 +1734,7 @@ class Compiler
|
|
1622 |
$end = $end[1];
|
1623 |
$d = $start < $end ? 1 : -1;
|
1624 |
|
1625 |
-
|
1626 |
if ((! $for->until && $start - $d == $end) ||
|
1627 |
($for->until && $start == $end)
|
1628 |
) {
|
@@ -1682,7 +1794,7 @@ class Compiler
|
|
1682 |
// including a mixin
|
1683 |
list(, $name, $argValues, $content) = $child;
|
1684 |
|
1685 |
-
$mixin = $this->get(
|
1686 |
|
1687 |
if (! $mixin) {
|
1688 |
$this->throwError("Undefined mixin $name");
|
@@ -1695,10 +1807,13 @@ class Compiler
|
|
1695 |
$this->pushEnv();
|
1696 |
$this->env->depth--;
|
1697 |
|
|
|
|
|
|
|
1698 |
if (isset($content)) {
|
1699 |
$content->scope = $callingScope;
|
1700 |
|
1701 |
-
$this->setRaw(
|
1702 |
}
|
1703 |
|
1704 |
if (isset($mixin->args)) {
|
@@ -1709,15 +1824,19 @@ class Compiler
|
|
1709 |
|
1710 |
$this->compileChildrenNoReturn($mixin->children, $out);
|
1711 |
|
|
|
|
|
1712 |
$this->popEnv();
|
1713 |
break;
|
1714 |
|
1715 |
case Type::T_MIXIN_CONTENT:
|
1716 |
-
$content = $this->get(
|
1717 |
-
?: $this->get(
|
1718 |
|
1719 |
if (! $content) {
|
1720 |
-
$
|
|
|
|
|
1721 |
break;
|
1722 |
}
|
1723 |
|
@@ -1742,7 +1861,7 @@ class Compiler
|
|
1742 |
|
1743 |
$line = $this->sourceLine;
|
1744 |
$value = $this->compileValue($this->reduce($value, true));
|
1745 |
-
|
1746 |
break;
|
1747 |
|
1748 |
case Type::T_ERROR:
|
@@ -1799,7 +1918,19 @@ class Compiler
|
|
1799 |
*/
|
1800 |
protected function isTruthy($value)
|
1801 |
{
|
1802 |
-
return $value !==
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1803 |
}
|
1804 |
|
1805 |
/**
|
@@ -1842,7 +1973,7 @@ class Compiler
|
|
1842 |
case Type::T_EXPRESSION:
|
1843 |
list(, $op, $left, $right, $inParens) = $value;
|
1844 |
|
1845 |
-
$opName = isset(
|
1846 |
$inExp = $inExp || $this->shouldEval($left) || $this->shouldEval($right);
|
1847 |
|
1848 |
$left = $this->reduce($left, true);
|
@@ -1958,11 +2089,11 @@ class Compiler
|
|
1958 |
|
1959 |
if ($op === 'not') {
|
1960 |
if ($inExp || $inParens) {
|
1961 |
-
if ($exp ===
|
1962 |
-
return
|
1963 |
}
|
1964 |
|
1965 |
-
return
|
1966 |
}
|
1967 |
|
1968 |
$op = $op . ' ';
|
@@ -2216,7 +2347,7 @@ class Compiler
|
|
2216 |
return;
|
2217 |
}
|
2218 |
|
2219 |
-
if ($left !==
|
2220 |
return $this->reduce($right, true);
|
2221 |
}
|
2222 |
|
@@ -2238,7 +2369,7 @@ class Compiler
|
|
2238 |
return;
|
2239 |
}
|
2240 |
|
2241 |
-
if ($left !==
|
2242 |
return $left;
|
2243 |
}
|
2244 |
|
@@ -2469,7 +2600,7 @@ class Compiler
|
|
2469 |
*/
|
2470 |
public function toBool($thing)
|
2471 |
{
|
2472 |
-
return $thing ?
|
2473 |
}
|
2474 |
|
2475 |
/**
|
@@ -2595,6 +2726,39 @@ class Compiler
|
|
2595 |
$reduced = $this->reduce($exp);
|
2596 |
|
2597 |
switch ($reduced[0]) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2598 |
case Type::T_STRING:
|
2599 |
$reduced = [Type::T_KEYWORD, $this->compileStringContent($reduced)];
|
2600 |
break;
|
@@ -2719,7 +2883,7 @@ class Compiler
|
|
2719 |
$newPart = [];
|
2720 |
|
2721 |
foreach ($part as $p) {
|
2722 |
-
if ($p ===
|
2723 |
$setSelf = true;
|
2724 |
|
2725 |
foreach ($parent as $i => $parentPart) {
|
@@ -2937,20 +3101,28 @@ class Compiler
|
|
2937 |
*/
|
2938 |
public function get($name, $shouldThrow = true, Environment $env = null)
|
2939 |
{
|
2940 |
-
$
|
|
|
2941 |
|
2942 |
if (! isset($env)) {
|
2943 |
$env = $this->getStoreEnv();
|
2944 |
}
|
2945 |
|
2946 |
-
$
|
|
|
2947 |
|
2948 |
for (;;) {
|
2949 |
-
if (array_key_exists($
|
2950 |
-
return $env->store[$
|
2951 |
}
|
2952 |
|
2953 |
if (! $hasNamespace && isset($env->marker)) {
|
|
|
|
|
|
|
|
|
|
|
|
|
2954 |
$env = $this->rootEnv;
|
2955 |
continue;
|
2956 |
}
|
@@ -3303,7 +3475,7 @@ class Compiler
|
|
3303 |
*
|
3304 |
* @throws \Exception
|
3305 |
*/
|
3306 |
-
|
3307 |
{
|
3308 |
for ($env = $this->env; $env; $env = $env->parent) {
|
3309 |
$file = $this->sourceNames[$env->block->sourceIndex];
|
@@ -3338,7 +3510,7 @@ class Compiler
|
|
3338 |
*/
|
3339 |
protected function callScssFunction($name, $argValues, &$returnValue)
|
3340 |
{
|
3341 |
-
$func = $this->get(
|
3342 |
|
3343 |
if (! $func) {
|
3344 |
return false;
|
@@ -3346,6 +3518,9 @@ class Compiler
|
|
3346 |
|
3347 |
$this->pushEnv();
|
3348 |
|
|
|
|
|
|
|
3349 |
// set the args
|
3350 |
if (isset($func->args)) {
|
3351 |
$this->applyArguments($func->args, $argValues);
|
@@ -3360,9 +3535,11 @@ class Compiler
|
|
3360 |
|
3361 |
$ret = $this->compileChildren($func->children, $tmp);
|
3362 |
|
|
|
|
|
3363 |
$this->popEnv();
|
3364 |
|
3365 |
-
$returnValue = ! isset($ret) ?
|
3366 |
|
3367 |
return true;
|
3368 |
}
|
@@ -3386,7 +3563,7 @@ class Compiler
|
|
3386 |
list($f, $prototype) = $this->userFunctions[$name];
|
3387 |
} elseif (($f = $this->getBuiltinFunction($name)) && is_callable($f)) {
|
3388 |
$libName = $f[1];
|
3389 |
-
$prototype = isset(
|
3390 |
} else {
|
3391 |
return false;
|
3392 |
}
|
@@ -3611,7 +3788,7 @@ class Compiler
|
|
3611 |
}
|
3612 |
|
3613 |
if ($value === null) {
|
3614 |
-
|
3615 |
}
|
3616 |
|
3617 |
if (is_numeric($value)) {
|
@@ -3619,7 +3796,30 @@ class Compiler
|
|
3619 |
}
|
3620 |
|
3621 |
if ($value === '') {
|
3622 |
-
return
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3623 |
}
|
3624 |
|
3625 |
return [Type::T_KEYWORD, $value];
|
@@ -3638,11 +3838,11 @@ class Compiler
|
|
3638 |
return $item;
|
3639 |
}
|
3640 |
|
3641 |
-
if ($item ===
|
3642 |
-
return
|
3643 |
}
|
3644 |
|
3645 |
-
return [Type::T_MAP, [$item], [
|
3646 |
}
|
3647 |
|
3648 |
/**
|
@@ -4012,7 +4212,7 @@ class Compiler
|
|
4012 |
list($list, $value) = $args;
|
4013 |
|
4014 |
if ($value[0] === Type::T_MAP) {
|
4015 |
-
return
|
4016 |
}
|
4017 |
|
4018 |
if ($list[0] === Type::T_MAP ||
|
@@ -4024,7 +4224,7 @@ class Compiler
|
|
4024 |
}
|
4025 |
|
4026 |
if ($list[0] !== Type::T_LIST) {
|
4027 |
-
return
|
4028 |
}
|
4029 |
|
4030 |
$values = [];
|
@@ -4035,7 +4235,7 @@ class Compiler
|
|
4035 |
|
4036 |
$key = array_search($this->normalizeValue($value), $values);
|
4037 |
|
4038 |
-
return false === $key ?
|
4039 |
}
|
4040 |
|
4041 |
protected static $libRgb = ['red', 'green', 'blue'];
|
@@ -4605,7 +4805,7 @@ class Compiler
|
|
4605 |
$n += count($list[2]);
|
4606 |
}
|
4607 |
|
4608 |
-
return isset($list[2][$n]) ? $list[2][$n] :
|
4609 |
}
|
4610 |
|
4611 |
protected static $libSetNth = ['list', 'n', 'value'];
|
@@ -4643,7 +4843,7 @@ class Compiler
|
|
4643 |
}
|
4644 |
}
|
4645 |
|
4646 |
-
return
|
4647 |
}
|
4648 |
|
4649 |
protected static $libMapKeys = ['map'];
|
@@ -4794,7 +4994,7 @@ class Compiler
|
|
4794 |
|
4795 |
switch ($value[0]) {
|
4796 |
case Type::T_KEYWORD:
|
4797 |
-
if ($value ===
|
4798 |
return 'bool';
|
4799 |
}
|
4800 |
|
@@ -4867,7 +5067,7 @@ class Compiler
|
|
4867 |
|
4868 |
$result = strpos($stringContent, $substringContent);
|
4869 |
|
4870 |
-
return $result === false ?
|
4871 |
}
|
4872 |
|
4873 |
protected static $libStrInsert = ['string', 'insert', 'index'];
|
@@ -4899,7 +5099,7 @@ class Compiler
|
|
4899 |
protected function libStrSlice($args)
|
4900 |
{
|
4901 |
if (isset($args[2]) && $args[2][1] == 0) {
|
4902 |
-
return
|
4903 |
}
|
4904 |
|
4905 |
$string = $this->coerceString($args[0]);
|
@@ -4961,7 +5161,7 @@ class Compiler
|
|
4961 |
$name = $this->compileStringContent($string);
|
4962 |
|
4963 |
// user defined functions
|
4964 |
-
if ($this->has(
|
4965 |
return true;
|
4966 |
}
|
4967 |
|
@@ -4992,7 +5192,7 @@ class Compiler
|
|
4992 |
$string = $this->coerceString($args[0]);
|
4993 |
$name = $this->compileStringContent($string);
|
4994 |
|
4995 |
-
return $this->has(
|
4996 |
}
|
4997 |
|
4998 |
protected static $libVariableExists = ['name'];
|
@@ -5050,7 +5250,7 @@ class Compiler
|
|
5050 |
protected static $libInspect = ['value'];
|
5051 |
protected function libInspect($args)
|
5052 |
{
|
5053 |
-
if ($args[0] ===
|
5054 |
return [Type::T_KEYWORD, 'null'];
|
5055 |
}
|
5056 |
|
125 |
protected $rootEnv;
|
126 |
protected $rootBlock;
|
127 |
|
128 |
+
protected $env;
|
129 |
+
protected $scope;
|
130 |
+
protected $storeEnv;
|
131 |
+
protected $charsetSeen;
|
132 |
+
protected $sourceNames;
|
133 |
+
|
134 |
private $indentLevel;
|
135 |
private $commentsSeen;
|
136 |
private $extends;
|
137 |
private $extendsMap;
|
138 |
private $parsedFiles;
|
|
|
|
|
139 |
private $parser;
|
|
|
140 |
private $sourceIndex;
|
141 |
private $sourceLine;
|
142 |
private $sourceColumn;
|
|
|
|
|
143 |
private $stderr;
|
144 |
private $shouldEvaluate;
|
145 |
private $ignoreErrors;
|
208 |
*
|
209 |
* @return \Leafo\ScssPhp\Parser
|
210 |
*/
|
211 |
+
protected function parserFactory($path)
|
212 |
{
|
213 |
$parser = new Parser($path, count($this->sourceNames), $this->encoding);
|
214 |
|
397 |
}
|
398 |
|
399 |
if ($this->matchExtendsSingle($part, $origin)) {
|
|
|
400 |
$after = array_slice($selector, $i + 1);
|
401 |
+
$before = array_slice($selector, 0, $i);
|
402 |
+
|
403 |
+
list($before, $nonBreakableBefore) = $this->extractRelationshipFromFragment($before);
|
404 |
|
405 |
foreach ($origin as $new) {
|
406 |
$k = 0;
|
407 |
|
408 |
// remove shared parts
|
409 |
if ($initial) {
|
410 |
+
while ($k < $i && isset($new[$k]) && $selector[$k] === $new[$k]) {
|
411 |
$k++;
|
412 |
}
|
413 |
}
|
414 |
|
415 |
+
$replacement = [];
|
416 |
+
$tempReplacement = $k > 0 ? array_slice($new, $k) : $new;
|
417 |
+
|
418 |
+
for ($l = count($tempReplacement) - 1; $l >= 0; $l--) {
|
419 |
+
$slice = $tempReplacement[$l];
|
420 |
+
array_unshift($replacement, $slice);
|
421 |
+
|
422 |
+
if (! $this->isImmediateRelationshipCombinator(end($slice))) {
|
423 |
+
break;
|
424 |
+
}
|
425 |
+
}
|
426 |
+
|
427 |
+
$afterBefore = $l != 0 ? array_slice($tempReplacement, 0, $l) : [];
|
428 |
+
|
429 |
+
// Merge shared direct relationships.
|
430 |
+
$mergedBefore = $this->mergeDirectRelationships($afterBefore, $nonBreakableBefore);
|
431 |
+
|
432 |
$result = array_merge(
|
433 |
$before,
|
434 |
+
$mergedBefore,
|
435 |
+
$replacement,
|
436 |
$after
|
437 |
);
|
438 |
|
443 |
$out[] = $result;
|
444 |
|
445 |
// recursively check for more matches
|
446 |
+
$this->matchExtends($result, $out, count($before) + count($mergedBefore), false);
|
447 |
|
448 |
// selector sequence merging
|
449 |
if (! empty($before) && count($new) > 1) {
|
450 |
+
$sharedParts = $k > 0 ? array_slice($before, 0, $k) : [];
|
451 |
+
$postSharedParts = $k > 0 ? array_slice($before, $k) : $before;
|
452 |
+
|
453 |
+
list($injectBetweenSharedParts, $nonBreakable2) = $this->extractRelationshipFromFragment($afterBefore);
|
454 |
+
|
455 |
$result2 = array_merge(
|
456 |
+
$sharedParts,
|
457 |
+
$injectBetweenSharedParts,
|
458 |
+
$postSharedParts,
|
459 |
+
$nonBreakable2,
|
460 |
+
$nonBreakableBefore,
|
461 |
+
$replacement,
|
462 |
$after
|
463 |
);
|
464 |
|
495 |
}
|
496 |
}
|
497 |
|
498 |
+
$extendingDecoratedTag = false;
|
499 |
+
|
500 |
+
if (count($single) > 1) {
|
501 |
+
$matches = null;
|
502 |
+
$extendingDecoratedTag = preg_match('/^[a-z0-9]+$/i', $single[0], $matches) ? $matches[0] : false;
|
503 |
+
}
|
504 |
+
|
505 |
foreach ($single as $part) {
|
506 |
if (isset($this->extendsMap[$part])) {
|
507 |
foreach ($this->extendsMap[$part] as $idx) {
|
531 |
return false;
|
532 |
}
|
533 |
|
534 |
+
$replacement = end($new);
|
535 |
+
|
536 |
+
// Extending a decorated tag with another tag is not possible.
|
537 |
+
if ($extendingDecoratedTag && $replacement[0] != $extendingDecoratedTag &&
|
538 |
+
preg_match('/^[a-z0-9]+$/i', $replacement[0])
|
539 |
+
) {
|
540 |
+
unset($origin[$j]);
|
541 |
+
continue;
|
542 |
+
}
|
543 |
+
|
544 |
+
$combined = $this->combineSelectorSingle($replacement, $rem);
|
545 |
|
546 |
if (count(array_diff($combined, $origin[$j][count($origin[$j]) - 1]))) {
|
547 |
$origin[$j][count($origin[$j]) - 1] = $combined;
|
556 |
return $found;
|
557 |
}
|
558 |
|
559 |
+
|
560 |
+
/**
|
561 |
+
* Extract a relationship from the fragment.
|
562 |
+
*
|
563 |
+
* When extracting the last portion of a selector we will be left with a
|
564 |
+
* fragment which may end with a direction relationship combinator. This
|
565 |
+
* method will extract the relationship fragment and return it along side
|
566 |
+
* the rest.
|
567 |
+
*
|
568 |
+
* @param array $fragment The selector fragment maybe ending with a direction relationship combinator.
|
569 |
+
* @return array The selector without the relationship fragment if any, the relationship fragment.
|
570 |
+
*/
|
571 |
+
protected function extractRelationshipFromFragment(array $fragment)
|
572 |
+
{
|
573 |
+
$parents = [];
|
574 |
+
$children = [];
|
575 |
+
$j = $i = count($fragment);
|
576 |
+
|
577 |
+
for (;;) {
|
578 |
+
$children = $j != $i ? array_slice($fragment, $j, $i - $j) : [];
|
579 |
+
$parents = array_slice($fragment, 0, $j);
|
580 |
+
$slice = end($parents);
|
581 |
+
|
582 |
+
if (empty($slice) || ! $this->isImmediateRelationshipCombinator($slice[0])) {
|
583 |
+
break;
|
584 |
+
}
|
585 |
+
|
586 |
+
$j -= 2;
|
587 |
+
}
|
588 |
+
|
589 |
+
return [$parents, $children];
|
590 |
+
}
|
591 |
+
|
592 |
/**
|
593 |
* Combine selector single
|
594 |
*
|
729 |
{
|
730 |
$env = $this->pushEnv($block);
|
731 |
$envs = $this->compactEnv($env);
|
732 |
+
$without = isset($block->with) ? $this->compileWith($block->with) : static::WITH_RULE;
|
733 |
|
734 |
// wrap inline selector
|
735 |
if ($block->selector) {
|
854 |
];
|
855 |
|
856 |
// exclude selectors by default
|
857 |
+
$without = static::WITH_RULE;
|
858 |
|
859 |
+
if ($this->libMapHasKey([$with, static::$with])) {
|
860 |
+
$without = static::WITH_ALL;
|
861 |
|
862 |
+
$list = $this->coerceList($this->libMapGet([$with, static::$with]));
|
863 |
|
864 |
foreach ($list[2] as $item) {
|
865 |
$keyword = $this->compileStringContent($this->coerceString($item));
|
870 |
}
|
871 |
}
|
872 |
|
873 |
+
if ($this->libMapHasKey([$with, static::$without])) {
|
874 |
$without = 0;
|
875 |
|
876 |
+
$list = $this->coerceList($this->libMapGet([$with, static::$without]));
|
877 |
|
878 |
foreach ($list[2] as $item) {
|
879 |
$keyword = $this->compileStringContent($this->coerceString($item));
|
920 |
*/
|
921 |
private function isWithout($without, Block $block)
|
922 |
{
|
923 |
+
if ((($without & static::WITH_RULE) && isset($block->selectors)) ||
|
924 |
+
(($without & static::WITH_MEDIA) &&
|
925 |
isset($block->type) && $block->type === Type::T_MEDIA) ||
|
926 |
+
(($without & static::WITH_SUPPORTS) &&
|
927 |
isset($block->type) && $block->type === Type::T_DIRECTIVE &&
|
928 |
isset($block->name) && $block->name === 'supports')
|
929 |
) {
|
1014 |
$line = $block->sourceLine;
|
1015 |
|
1016 |
switch ($this->lineNumberStyle) {
|
1017 |
+
case static::LINE_COMMENTS:
|
1018 |
+
$annotation->lines[] = '/* line ' . $line
|
1019 |
+
. ($file ? ', ' . $file : '')
|
1020 |
+
. ' */';
|
1021 |
break;
|
1022 |
|
1023 |
+
case static::DEBUG_INFO:
|
1024 |
+
$annotation->lines[] = '@media -sass-debug-info{'
|
1025 |
+
. ($file ? 'filename{font-family:"' . $file . '"}' : '')
|
1026 |
+
. 'line{font-family:' . $line . '}}';
|
1027 |
break;
|
1028 |
}
|
1029 |
|
1364 |
return $out;
|
1365 |
}
|
1366 |
|
1367 |
+
protected function mergeDirectRelationships($selectors1, $selectors2)
|
1368 |
+
{
|
1369 |
+
if (empty($selectors1) || empty($selectors2)) {
|
1370 |
+
return array_merge($selectors1, $selectors2);
|
1371 |
+
}
|
1372 |
+
|
1373 |
+
$part1 = end($selectors1);
|
1374 |
+
$part2 = end($selectors2);
|
1375 |
+
|
1376 |
+
if (! $this->isImmediateRelationshipCombinator($part1[0]) || $part1 !== $part2) {
|
1377 |
+
return array_merge($selectors1, $selectors2);
|
1378 |
+
}
|
1379 |
+
|
1380 |
+
$merged = [];
|
1381 |
+
|
1382 |
+
do {
|
1383 |
+
$part1 = array_pop($selectors1);
|
1384 |
+
$part2 = array_pop($selectors2);
|
1385 |
+
|
1386 |
+
if ($this->isImmediateRelationshipCombinator($part1[0]) && $part1 !== $part2) {
|
1387 |
+
$merged = array_merge($selectors1, [$part1], $selectors2, [$part2], $merged);
|
1388 |
+
break;
|
1389 |
+
}
|
1390 |
+
|
1391 |
+
array_unshift($merged, $part1);
|
1392 |
+
array_unshift($merged, [array_pop($selectors1)[0] . array_pop($selectors2)[0]]);
|
1393 |
+
} while (! empty($selectors1) && ! empty($selectors2));
|
1394 |
+
|
1395 |
+
return $merged;
|
1396 |
+
}
|
1397 |
+
|
1398 |
/**
|
1399 |
* Merge media types
|
1400 |
*
|
1572 |
list(, $name, $value) = $child;
|
1573 |
|
1574 |
if ($name[0] === Type::T_VARIABLE) {
|
1575 |
+
$flags = isset($child[3]) ? $child[3] : [];
|
1576 |
+
$isDefault = in_array('!default', $flags);
|
1577 |
+
$isGlobal = in_array('!global', $flags);
|
1578 |
|
1579 |
if ($isGlobal) {
|
1580 |
$this->set($name[1], $this->reduce($value), false, $this->rootEnv);
|
1583 |
|
1584 |
$shouldSet = $isDefault &&
|
1585 |
(($result = $this->get($name[1], false)) === null
|
1586 |
+
|| $result === static::$null);
|
1587 |
|
1588 |
if (! $isDefault || $shouldSet) {
|
1589 |
$this->set($name[1], $this->reduce($value));
|
1611 |
if ($value[0] !== Type::T_NULL) {
|
1612 |
$value = $this->reduce($value);
|
1613 |
|
1614 |
+
if ($value[0] === Type::T_NULL || $value === static::$nullString) {
|
1615 |
break;
|
1616 |
}
|
1617 |
}
|
1637 |
case Type::T_FUNCTION:
|
1638 |
list(, $block) = $child;
|
1639 |
|
1640 |
+
$this->set(static::$namespaces[$block->type] . $block->name, $block);
|
1641 |
break;
|
1642 |
|
1643 |
case Type::T_EXTEND:
|
1685 |
list(,, $values) = $this->coerceList($item);
|
1686 |
|
1687 |
foreach ($each->vars as $i => $var) {
|
1688 |
+
$this->set($var, isset($values[$i]) ? $values[$i] : static::$null, true);
|
1689 |
}
|
1690 |
}
|
1691 |
|
1734 |
$end = $end[1];
|
1735 |
$d = $start < $end ? 1 : -1;
|
1736 |
|
1737 |
+
for (;;) {
|
1738 |
if ((! $for->until && $start - $d == $end) ||
|
1739 |
($for->until && $start == $end)
|
1740 |
) {
|
1794 |
// including a mixin
|
1795 |
list(, $name, $argValues, $content) = $child;
|
1796 |
|
1797 |
+
$mixin = $this->get(static::$namespaces['mixin'] . $name, false);
|
1798 |
|
1799 |
if (! $mixin) {
|
1800 |
$this->throwError("Undefined mixin $name");
|
1807 |
$this->pushEnv();
|
1808 |
$this->env->depth--;
|
1809 |
|
1810 |
+
$storeEnv = $this->storeEnv;
|
1811 |
+
$this->storeEnv = $this->env;
|
1812 |
+
|
1813 |
if (isset($content)) {
|
1814 |
$content->scope = $callingScope;
|
1815 |
|
1816 |
+
$this->setRaw(static::$namespaces['special'] . 'content', $content, $this->env);
|
1817 |
}
|
1818 |
|
1819 |
if (isset($mixin->args)) {
|
1824 |
|
1825 |
$this->compileChildrenNoReturn($mixin->children, $out);
|
1826 |
|
1827 |
+
$this->storeEnv = $storeEnv;
|
1828 |
+
|
1829 |
$this->popEnv();
|
1830 |
break;
|
1831 |
|
1832 |
case Type::T_MIXIN_CONTENT:
|
1833 |
+
$content = $this->get(static::$namespaces['special'] . 'content', false, $this->getStoreEnv())
|
1834 |
+
?: $this->get(static::$namespaces['special'] . 'content', false, $this->env);
|
1835 |
|
1836 |
if (! $content) {
|
1837 |
+
$content = new \stdClass();
|
1838 |
+
$content->scope = new \stdClass();
|
1839 |
+
$content->children = $this->storeEnv->parent->block->children;
|
1840 |
break;
|
1841 |
}
|
1842 |
|
1861 |
|
1862 |
$line = $this->sourceLine;
|
1863 |
$value = $this->compileValue($this->reduce($value, true));
|
1864 |
+
fwrite($this->stderr, "Line $line WARN: $value\n");
|
1865 |
break;
|
1866 |
|
1867 |
case Type::T_ERROR:
|
1918 |
*/
|
1919 |
protected function isTruthy($value)
|
1920 |
{
|
1921 |
+
return $value !== static::$false && $value !== static::$null;
|
1922 |
+
}
|
1923 |
+
|
1924 |
+
/**
|
1925 |
+
* Is the value a direct relationship combinator?
|
1926 |
+
*
|
1927 |
+
* @param string $value
|
1928 |
+
*
|
1929 |
+
* @return bool
|
1930 |
+
*/
|
1931 |
+
protected function isImmediateRelationshipCombinator($value)
|
1932 |
+
{
|
1933 |
+
return $value === '>' || $value === '+' || $value === '~';
|
1934 |
}
|
1935 |
|
1936 |
/**
|
1973 |
case Type::T_EXPRESSION:
|
1974 |
list(, $op, $left, $right, $inParens) = $value;
|
1975 |
|
1976 |
+
$opName = isset(static::$operatorNames[$op]) ? static::$operatorNames[$op] : $op;
|
1977 |
$inExp = $inExp || $this->shouldEval($left) || $this->shouldEval($right);
|
1978 |
|
1979 |
$left = $this->reduce($left, true);
|
2089 |
|
2090 |
if ($op === 'not') {
|
2091 |
if ($inExp || $inParens) {
|
2092 |
+
if ($exp === static::$false || $exp === static::$null) {
|
2093 |
+
return static::$true;
|
2094 |
}
|
2095 |
|
2096 |
+
return static::$false;
|
2097 |
}
|
2098 |
|
2099 |
$op = $op . ' ';
|
2347 |
return;
|
2348 |
}
|
2349 |
|
2350 |
+
if ($left !== static::$false and $left !== static::$null) {
|
2351 |
return $this->reduce($right, true);
|
2352 |
}
|
2353 |
|
2369 |
return;
|
2370 |
}
|
2371 |
|
2372 |
+
if ($left !== static::$false and $left !== static::$null) {
|
2373 |
return $left;
|
2374 |
}
|
2375 |
|
2600 |
*/
|
2601 |
public function toBool($thing)
|
2602 |
{
|
2603 |
+
return $thing ? static::$true : static::$false;
|
2604 |
}
|
2605 |
|
2606 |
/**
|
2726 |
$reduced = $this->reduce($exp);
|
2727 |
|
2728 |
switch ($reduced[0]) {
|
2729 |
+
case Type::T_LIST:
|
2730 |
+
$reduced = $this->extractInterpolation($reduced);
|
2731 |
+
|
2732 |
+
if ($reduced[0] !== Type::T_LIST) {
|
2733 |
+
break;
|
2734 |
+
}
|
2735 |
+
|
2736 |
+
list(, $delim, $items) = $reduced;
|
2737 |
+
|
2738 |
+
if ($delim !== ' ') {
|
2739 |
+
$delim .= ' ';
|
2740 |
+
}
|
2741 |
+
|
2742 |
+
$filtered = [];
|
2743 |
+
|
2744 |
+
foreach ($items as $item) {
|
2745 |
+
if ($item[0] === Type::T_NULL) {
|
2746 |
+
continue;
|
2747 |
+
}
|
2748 |
+
|
2749 |
+
$temp = $this->compileValue([Type::T_KEYWORD, $item]);
|
2750 |
+
if ($temp[0] === Type::T_STRING) {
|
2751 |
+
$filtered[] = $this->compileStringContent($temp);
|
2752 |
+
} elseif ($temp[0] === Type::T_KEYWORD) {
|
2753 |
+
$filtered[] = $temp[1];
|
2754 |
+
} else {
|
2755 |
+
$filtered[] = $this->compileValue($temp);
|
2756 |
+
}
|
2757 |
+
}
|
2758 |
+
|
2759 |
+
$reduced = [Type::T_KEYWORD, implode("$delim", $filtered)];
|
2760 |
+
break;
|
2761 |
+
|
2762 |
case Type::T_STRING:
|
2763 |
$reduced = [Type::T_KEYWORD, $this->compileStringContent($reduced)];
|
2764 |
break;
|
2883 |
$newPart = [];
|
2884 |
|
2885 |
foreach ($part as $p) {
|
2886 |
+
if ($p === static::$selfSelector) {
|
2887 |
$setSelf = true;
|
2888 |
|
2889 |
foreach ($parent as $i => $parentPart) {
|
3101 |
*/
|
3102 |
public function get($name, $shouldThrow = true, Environment $env = null)
|
3103 |
{
|
3104 |
+
$normalizedName = $this->normalizeName($name);
|
3105 |
+
$specialContentKey = static::$namespaces['special'] . 'content';
|
3106 |
|
3107 |
if (! isset($env)) {
|
3108 |
$env = $this->getStoreEnv();
|
3109 |
}
|
3110 |
|
3111 |
+
$nextIsRoot = false;
|
3112 |
+
$hasNamespace = $normalizedName[0] === '^' || $normalizedName[0] === '@' || $normalizedName[0] === '%';
|
3113 |
|
3114 |
for (;;) {
|
3115 |
+
if (array_key_exists($normalizedName, $env->store)) {
|
3116 |
+
return $env->store[$normalizedName];
|
3117 |
}
|
3118 |
|
3119 |
if (! $hasNamespace && isset($env->marker)) {
|
3120 |
+
if (! $nextIsRoot && ! empty($env->store[$specialContentKey])) {
|
3121 |
+
$env = $env->store[$specialContentKey]->scope;
|
3122 |
+
$nextIsRoot = true;
|
3123 |
+
continue;
|
3124 |
+
}
|
3125 |
+
|
3126 |
$env = $this->rootEnv;
|
3127 |
continue;
|
3128 |
}
|
3475 |
*
|
3476 |
* @throws \Exception
|
3477 |
*/
|
3478 |
+
protected function handleImportLoop($name)
|
3479 |
{
|
3480 |
for ($env = $this->env; $env; $env = $env->parent) {
|
3481 |
$file = $this->sourceNames[$env->block->sourceIndex];
|
3510 |
*/
|
3511 |
protected function callScssFunction($name, $argValues, &$returnValue)
|
3512 |
{
|
3513 |
+
$func = $this->get(static::$namespaces['function'] . $name, false);
|
3514 |
|
3515 |
if (! $func) {
|
3516 |
return false;
|
3518 |
|
3519 |
$this->pushEnv();
|
3520 |
|
3521 |
+
$storeEnv = $this->storeEnv;
|
3522 |
+
$this->storeEnv = $this->env;
|
3523 |
+
|
3524 |
// set the args
|
3525 |
if (isset($func->args)) {
|
3526 |
$this->applyArguments($func->args, $argValues);
|
3535 |
|
3536 |
$ret = $this->compileChildren($func->children, $tmp);
|
3537 |
|
3538 |
+
$this->storeEnv = $storeEnv;
|
3539 |
+
|
3540 |
$this->popEnv();
|
3541 |
|
3542 |
+
$returnValue = ! isset($ret) ? static::$defaultValue : $ret;
|
3543 |
|
3544 |
return true;
|
3545 |
}
|
3563 |
list($f, $prototype) = $this->userFunctions[$name];
|
3564 |
} elseif (($f = $this->getBuiltinFunction($name)) && is_callable($f)) {
|
3565 |
$libName = $f[1];
|
3566 |
+
$prototype = isset(static::$$libName) ? static::$$libName : null;
|
3567 |
} else {
|
3568 |
return false;
|
3569 |
}
|
3788 |
}
|
3789 |
|
3790 |
if ($value === null) {
|
3791 |
+
return static::$null;
|
3792 |
}
|
3793 |
|
3794 |
if (is_numeric($value)) {
|
3796 |
}
|
3797 |
|
3798 |
if ($value === '') {
|
3799 |
+
return static::$emptyString;
|
3800 |
+
}
|
3801 |
+
|
3802 |
+
if (preg_match('/^(#([0-9a-f]{6})|#([0-9a-f]{3}))$/i', $value, $m)) {
|
3803 |
+
$color = [Type::T_COLOR];
|
3804 |
+
|
3805 |
+
if (isset($m[3])) {
|
3806 |
+
$num = hexdec($m[3]);
|
3807 |
+
|
3808 |
+
foreach ([3, 2, 1] as $i) {
|
3809 |
+
$t = $num & 0xf;
|
3810 |
+
$color[$i] = $t << 4 | $t;
|
3811 |
+
$num >>= 4;
|
3812 |
+
}
|
3813 |
+
} else {
|
3814 |
+
$num = hexdec($m[2]);
|
3815 |
+
|
3816 |
+
foreach ([3, 2, 1] as $i) {
|
3817 |
+
$color[$i] = $num & 0xff;
|
3818 |
+
$num >>= 8;
|
3819 |
+
}
|
3820 |
+
}
|
3821 |
+
|
3822 |
+
return $color;
|
3823 |
}
|
3824 |
|
3825 |
return [Type::T_KEYWORD, $value];
|
3838 |
return $item;
|
3839 |
}
|
3840 |
|
3841 |
+
if ($item === static::$emptyList) {
|
3842 |
+
return static::$emptyMap;
|
3843 |
}
|
3844 |
|
3845 |
+
return [Type::T_MAP, [$item], [static::$null]];
|
3846 |
}
|
3847 |
|
3848 |
/**
|
4212 |
list($list, $value) = $args;
|
4213 |
|
4214 |
if ($value[0] === Type::T_MAP) {
|
4215 |
+
return static::$null;
|
4216 |
}
|
4217 |
|
4218 |
if ($list[0] === Type::T_MAP ||
|
4224 |
}
|
4225 |
|
4226 |
if ($list[0] !== Type::T_LIST) {
|
4227 |
+
return static::$null;
|
4228 |
}
|
4229 |
|
4230 |
$values = [];
|
4235 |
|
4236 |
$key = array_search($this->normalizeValue($value), $values);
|
4237 |
|
4238 |
+
return false === $key ? static::$null : $key + 1;
|
4239 |
}
|
4240 |
|
4241 |
protected static $libRgb = ['red', 'green', 'blue'];
|
4805 |
$n += count($list[2]);
|
4806 |
}
|
4807 |
|
4808 |
+
return isset($list[2][$n]) ? $list[2][$n] : static::$defaultValue;
|
4809 |
}
|
4810 |
|
4811 |
protected static $libSetNth = ['list', 'n', 'value'];
|
4843 |
}
|
4844 |
}
|
4845 |
|
4846 |
+
return static::$null;
|
4847 |
}
|
4848 |
|
4849 |
protected static $libMapKeys = ['map'];
|
4994 |
|
4995 |
switch ($value[0]) {
|
4996 |
case Type::T_KEYWORD:
|
4997 |
+
if ($value === static::$true || $value === static::$false) {
|
4998 |
return 'bool';
|
4999 |
}
|
5000 |
|
5067 |
|
5068 |
$result = strpos($stringContent, $substringContent);
|
5069 |
|
5070 |
+
return $result === false ? static::$null : new Node\Number($result + 1, '');
|
5071 |
}
|
5072 |
|
5073 |
protected static $libStrInsert = ['string', 'insert', 'index'];
|
5099 |
protected function libStrSlice($args)
|
5100 |
{
|
5101 |
if (isset($args[2]) && $args[2][1] == 0) {
|
5102 |
+
return static::$nullString;
|
5103 |
}
|
5104 |
|
5105 |
$string = $this->coerceString($args[0]);
|
5161 |
$name = $this->compileStringContent($string);
|
5162 |
|
5163 |
// user defined functions
|
5164 |
+
if ($this->has(static::$namespaces['function'] . $name)) {
|
5165 |
return true;
|
5166 |
}
|
5167 |
|
5192 |
$string = $this->coerceString($args[0]);
|
5193 |
$name = $this->compileStringContent($string);
|
5194 |
|
5195 |
+
return $this->has(static::$namespaces['mixin'] . $name);
|
5196 |
}
|
5197 |
|
5198 |
protected static $libVariableExists = ['name'];
|
5250 |
protected static $libInspect = ['value'];
|
5251 |
protected function libInspect($args)
|
5252 |
{
|
5253 |
+
if ($args[0] === static::$null) {
|
5254 |
return [Type::T_KEYWORD, 'null'];
|
5255 |
}
|
5256 |
|
scssphp/src/Node/Number.php
CHANGED
@@ -110,7 +110,7 @@ class Number extends Node implements \ArrayAccess
|
|
110 |
|
111 |
$dimension = $this->dimension;
|
112 |
|
113 |
-
foreach (
|
114 |
$from = isset($this->units[$unit]) ? $this->units[$unit] : 0;
|
115 |
$to = isset($units[$unit]) ? $units[$unit] : 0;
|
116 |
$factor = pow($conv, $from - $to);
|
@@ -265,7 +265,7 @@ class Number extends Node implements \ArrayAccess
|
|
265 |
*/
|
266 |
public function output(Compiler $compiler = null)
|
267 |
{
|
268 |
-
$dimension = round($this->dimension,
|
269 |
|
270 |
$units = array_filter($this->units, function ($unitSize) {
|
271 |
return $unitSize;
|
@@ -277,7 +277,7 @@ class Number extends Node implements \ArrayAccess
|
|
277 |
|
278 |
$this->normalizeUnits($dimension, $units, 'in');
|
279 |
|
280 |
-
$dimension = round($dimension,
|
281 |
$units = array_filter($units, function ($unitSize) {
|
282 |
return $unitSize;
|
283 |
});
|
@@ -316,8 +316,8 @@ class Number extends Node implements \ArrayAccess
|
|
316 |
$units = [];
|
317 |
|
318 |
foreach ($this->units as $unit => $exp) {
|
319 |
-
if (isset(
|
320 |
-
$factor = pow(
|
321 |
|
322 |
$unit = $baseUnit;
|
323 |
$dimension /= $factor;
|
110 |
|
111 |
$dimension = $this->dimension;
|
112 |
|
113 |
+
foreach (static::$unitTable['in'] as $unit => $conv) {
|
114 |
$from = isset($this->units[$unit]) ? $this->units[$unit] : 0;
|
115 |
$to = isset($units[$unit]) ? $units[$unit] : 0;
|
116 |
$factor = pow($conv, $from - $to);
|
265 |
*/
|
266 |
public function output(Compiler $compiler = null)
|
267 |
{
|
268 |
+
$dimension = round($this->dimension, static::$precision);
|
269 |
|
270 |
$units = array_filter($this->units, function ($unitSize) {
|
271 |
return $unitSize;
|
277 |
|
278 |
$this->normalizeUnits($dimension, $units, 'in');
|
279 |
|
280 |
+
$dimension = round($dimension, static::$precision);
|
281 |
$units = array_filter($units, function ($unitSize) {
|
282 |
return $unitSize;
|
283 |
});
|
316 |
$units = [];
|
317 |
|
318 |
foreach ($this->units as $unit => $exp) {
|
319 |
+
if (isset(static::$unitTable[$baseUnit][$unit])) {
|
320 |
+
$factor = pow(static::$unitTable[$baseUnit][$unit], $exp);
|
321 |
|
322 |
$unit = $baseUnit;
|
323 |
$dimension /= $factor;
|
scssphp/src/Parser.php
CHANGED
@@ -83,17 +83,17 @@ class Parser
|
|
83 |
$this->utf8 = ! $encoding || strtolower($encoding) === 'utf-8';
|
84 |
$this->patternModifiers = $this->utf8 ? 'Aisu' : 'Ais';
|
85 |
|
86 |
-
if (empty(
|
87 |
-
|
88 |
|
89 |
$commentSingle = '\/\/';
|
90 |
$commentMultiLeft = '\/\*';
|
91 |
$commentMultiRight = '\*\/';
|
92 |
|
93 |
-
|
94 |
-
|
95 |
-
? '/' . $commentSingle . '[^\n]*\s*|(' .
|
96 |
-
: '/' . $commentSingle . '[^\n]*\s*|(' .
|
97 |
}
|
98 |
}
|
99 |
|
@@ -142,11 +142,16 @@ class Parser
|
|
142 |
*/
|
143 |
public function parse($buffer)
|
144 |
{
|
|
|
|
|
|
|
|
|
|
|
|
|
145 |
$this->count = 0;
|
146 |
$this->env = null;
|
147 |
$this->inParens = false;
|
148 |
$this->eatWhiteDefault = true;
|
149 |
-
$this->buffer = rtrim($buffer, "\x00..\x1f");
|
150 |
|
151 |
$this->saveEncoding();
|
152 |
$this->extractLineNumbers($buffer);
|
@@ -558,9 +563,9 @@ class Parser
|
|
558 |
|
559 |
list($line, $column) = $this->getSourcePosition($s);
|
560 |
|
561 |
-
$statement[
|
562 |
-
$statement[
|
563 |
-
$statement[
|
564 |
|
565 |
$this->charset = $statement;
|
566 |
}
|
@@ -617,8 +622,8 @@ class Parser
|
|
617 |
$this->end()
|
618 |
) {
|
619 |
// check for '!flag'
|
620 |
-
$
|
621 |
-
$this->append([Type::T_ASSIGN, $name, $value, $
|
622 |
|
623 |
return true;
|
624 |
}
|
@@ -895,7 +900,7 @@ class Parser
|
|
895 |
|
896 |
$len = strlen($what);
|
897 |
|
898 |
-
if (substr($this->buffer, $this->count, $len)
|
899 |
$this->count += $len;
|
900 |
|
901 |
if ($eatWhitespace) {
|
@@ -917,7 +922,7 @@ class Parser
|
|
917 |
{
|
918 |
$gotWhite = false;
|
919 |
|
920 |
-
while (preg_match(
|
921 |
if (isset($m[1]) && empty($this->commentsSeen[$this->count])) {
|
922 |
$this->appendComment([Type::T_COMMENT, $m[1]]);
|
923 |
|
@@ -954,9 +959,9 @@ class Parser
|
|
954 |
if ($pos !== null) {
|
955 |
list($line, $column) = $this->getSourcePosition($pos);
|
956 |
|
957 |
-
$statement[
|
958 |
-
$statement[
|
959 |
-
$statement[
|
960 |
}
|
961 |
|
962 |
$this->env->children[] = $statement;
|
@@ -1244,13 +1249,13 @@ class Parser
|
|
1244 |
*/
|
1245 |
protected function expHelper($lhs, $minP)
|
1246 |
{
|
1247 |
-
$operators =
|
1248 |
|
1249 |
$ss = $this->seek();
|
1250 |
$whiteBefore = isset($this->buffer[$this->count - 1]) &&
|
1251 |
ctype_space($this->buffer[$this->count - 1]);
|
1252 |
|
1253 |
-
while ($this->match($operators, $m, false) &&
|
1254 |
$whiteAfter = isset($this->buffer[$this->count]) &&
|
1255 |
ctype_space($this->buffer[$this->count]);
|
1256 |
$varAfter = isset($this->buffer[$this->count]) &&
|
@@ -1270,8 +1275,8 @@ class Parser
|
|
1270 |
}
|
1271 |
|
1272 |
// peek and see if rhs belongs to next operator
|
1273 |
-
if ($this->peek($operators, $next) &&
|
1274 |
-
$rhs = $this->expHelper($rhs,
|
1275 |
}
|
1276 |
|
1277 |
$lhs = [Type::T_EXPRESSION, $op, $lhs, $rhs, $this->inParens, $whiteBefore, $whiteAfter];
|
@@ -1807,7 +1812,7 @@ class Parser
|
|
1807 |
$oldWhite = $this->eatWhiteDefault;
|
1808 |
$this->eatWhiteDefault = false;
|
1809 |
|
1810 |
-
$patt = '(.*?)([\'"]|#\{|' . $this->pregQuote($end) . '|' .
|
1811 |
|
1812 |
$nestingLevel = 0;
|
1813 |
|
@@ -1941,7 +1946,7 @@ class Parser
|
|
1941 |
|
1942 |
// match comment hack
|
1943 |
if (preg_match(
|
1944 |
-
|
1945 |
$this->buffer,
|
1946 |
$m,
|
1947 |
null,
|
@@ -2287,25 +2292,29 @@ class Parser
|
|
2287 |
*
|
2288 |
* @param array $value
|
2289 |
*
|
2290 |
-
* @return
|
2291 |
*/
|
2292 |
-
protected function
|
2293 |
{
|
2294 |
-
$
|
2295 |
|
2296 |
for ($token = &$value; $token[0] === Type::T_LIST && ($s = count($token[2])); $token = &$lastNode) {
|
2297 |
$lastNode = &$token[2][$s - 1];
|
2298 |
|
2299 |
-
|
2300 |
array_pop($token[2]);
|
2301 |
|
|
|
|
|
2302 |
$token = $this->flattenList($token);
|
2303 |
|
2304 |
-
|
|
|
|
|
2305 |
}
|
2306 |
}
|
2307 |
|
2308 |
-
return
|
2309 |
}
|
2310 |
|
2311 |
/**
|
83 |
$this->utf8 = ! $encoding || strtolower($encoding) === 'utf-8';
|
84 |
$this->patternModifiers = $this->utf8 ? 'Aisu' : 'Ais';
|
85 |
|
86 |
+
if (empty(static::$operatorPattern)) {
|
87 |
+
static::$operatorPattern = '([*\/%+-]|[!=]\=|\>\=?|\<\=\>|\<\=?|and|or)';
|
88 |
|
89 |
$commentSingle = '\/\/';
|
90 |
$commentMultiLeft = '\/\*';
|
91 |
$commentMultiRight = '\*\/';
|
92 |
|
93 |
+
static::$commentPattern = $commentMultiLeft . '.*?' . $commentMultiRight;
|
94 |
+
static::$whitePattern = $this->utf8
|
95 |
+
? '/' . $commentSingle . '[^\n]*\s*|(' . static::$commentPattern . ')\s*|\s+/AisuS'
|
96 |
+
: '/' . $commentSingle . '[^\n]*\s*|(' . static::$commentPattern . ')\s*|\s+/AisS';
|
97 |
}
|
98 |
}
|
99 |
|
142 |
*/
|
143 |
public function parse($buffer)
|
144 |
{
|
145 |
+
// strip BOM (byte order marker)
|
146 |
+
if (substr($buffer, 0, 3) === "\xef\xbb\xbf") {
|
147 |
+
$buffer = substr($buffer, 3);
|
148 |
+
}
|
149 |
+
|
150 |
+
$this->buffer = rtrim($buffer, "\x00..\x1f");
|
151 |
$this->count = 0;
|
152 |
$this->env = null;
|
153 |
$this->inParens = false;
|
154 |
$this->eatWhiteDefault = true;
|
|
|
155 |
|
156 |
$this->saveEncoding();
|
157 |
$this->extractLineNumbers($buffer);
|
563 |
|
564 |
list($line, $column) = $this->getSourcePosition($s);
|
565 |
|
566 |
+
$statement[static::SOURCE_LINE] = $line;
|
567 |
+
$statement[static::SOURCE_COLUMN] = $column;
|
568 |
+
$statement[static::SOURCE_INDEX] = $this->sourceIndex;
|
569 |
|
570 |
$this->charset = $statement;
|
571 |
}
|
622 |
$this->end()
|
623 |
) {
|
624 |
// check for '!flag'
|
625 |
+
$assignmentFlags = $this->stripAssignmentFlags($value);
|
626 |
+
$this->append([Type::T_ASSIGN, $name, $value, $assignmentFlags], $s);
|
627 |
|
628 |
return true;
|
629 |
}
|
900 |
|
901 |
$len = strlen($what);
|
902 |
|
903 |
+
if (strcasecmp(substr($this->buffer, $this->count, $len), $what) === 0) {
|
904 |
$this->count += $len;
|
905 |
|
906 |
if ($eatWhitespace) {
|
922 |
{
|
923 |
$gotWhite = false;
|
924 |
|
925 |
+
while (preg_match(static::$whitePattern, $this->buffer, $m, null, $this->count)) {
|
926 |
if (isset($m[1]) && empty($this->commentsSeen[$this->count])) {
|
927 |
$this->appendComment([Type::T_COMMENT, $m[1]]);
|
928 |
|
959 |
if ($pos !== null) {
|
960 |
list($line, $column) = $this->getSourcePosition($pos);
|
961 |
|
962 |
+
$statement[static::SOURCE_LINE] = $line;
|
963 |
+
$statement[static::SOURCE_COLUMN] = $column;
|
964 |
+
$statement[static::SOURCE_INDEX] = $this->sourceIndex;
|
965 |
}
|
966 |
|
967 |
$this->env->children[] = $statement;
|
1249 |
*/
|
1250 |
protected function expHelper($lhs, $minP)
|
1251 |
{
|
1252 |
+
$operators = static::$operatorPattern;
|
1253 |
|
1254 |
$ss = $this->seek();
|
1255 |
$whiteBefore = isset($this->buffer[$this->count - 1]) &&
|
1256 |
ctype_space($this->buffer[$this->count - 1]);
|
1257 |
|
1258 |
+
while ($this->match($operators, $m, false) && static::$precedence[$m[1]] >= $minP) {
|
1259 |
$whiteAfter = isset($this->buffer[$this->count]) &&
|
1260 |
ctype_space($this->buffer[$this->count]);
|
1261 |
$varAfter = isset($this->buffer[$this->count]) &&
|
1275 |
}
|
1276 |
|
1277 |
// peek and see if rhs belongs to next operator
|
1278 |
+
if ($this->peek($operators, $next) && static::$precedence[$next[1]] > static::$precedence[$op]) {
|
1279 |
+
$rhs = $this->expHelper($rhs, static::$precedence[$next[1]]);
|
1280 |
}
|
1281 |
|
1282 |
$lhs = [Type::T_EXPRESSION, $op, $lhs, $rhs, $this->inParens, $whiteBefore, $whiteAfter];
|
1812 |
$oldWhite = $this->eatWhiteDefault;
|
1813 |
$this->eatWhiteDefault = false;
|
1814 |
|
1815 |
+
$patt = '(.*?)([\'"]|#\{|' . $this->pregQuote($end) . '|' . static::$commentPattern . ')';
|
1816 |
|
1817 |
$nestingLevel = 0;
|
1818 |
|
1946 |
|
1947 |
// match comment hack
|
1948 |
if (preg_match(
|
1949 |
+
static::$whitePattern,
|
1950 |
$this->buffer,
|
1951 |
$m,
|
1952 |
null,
|
2292 |
*
|
2293 |
* @param array $value
|
2294 |
*
|
2295 |
+
* @return array
|
2296 |
*/
|
2297 |
+
protected function stripAssignmentFlags(&$value)
|
2298 |
{
|
2299 |
+
$flags = [];
|
2300 |
|
2301 |
for ($token = &$value; $token[0] === Type::T_LIST && ($s = count($token[2])); $token = &$lastNode) {
|
2302 |
$lastNode = &$token[2][$s - 1];
|
2303 |
|
2304 |
+
while ($lastNode[0] === Type::T_KEYWORD && in_array($lastNode[1], ['!default', '!global'])) {
|
2305 |
array_pop($token[2]);
|
2306 |
|
2307 |
+
$node = end($token[2]);
|
2308 |
+
|
2309 |
$token = $this->flattenList($token);
|
2310 |
|
2311 |
+
$flags[] = $lastNode[1];
|
2312 |
+
|
2313 |
+
$lastNode = $node;
|
2314 |
}
|
2315 |
}
|
2316 |
|
2317 |
+
return $flags;
|
2318 |
}
|
2319 |
|
2320 |
/**
|
scssphp/src/Server.php
CHANGED
@@ -457,7 +457,7 @@ class Server
|
|
457 |
*/
|
458 |
public static function serveFrom($path)
|
459 |
{
|
460 |
-
$server = new
|
461 |
$server->serve();
|
462 |
}
|
463 |
}
|
457 |
*/
|
458 |
public static function serveFrom($path)
|
459 |
{
|
460 |
+
$server = new static($path);
|
461 |
$server->serve();
|
462 |
}
|
463 |
}
|
scssphp/src/Version.php
CHANGED
@@ -18,5 +18,5 @@ namespace Leafo\ScssPhp;
|
|
18 |
*/
|
19 |
class Version
|
20 |
{
|
21 |
-
const VERSION = 'v0.6.
|
22 |
}
|
18 |
*/
|
19 |
class Version
|
20 |
{
|
21 |
+
const VERSION = 'v0.6.6';
|
22 |
}
|
wp-scss.php
CHANGED
@@ -3,7 +3,7 @@
|
|
3 |
* Plugin Name: WP-SCSS
|
4 |
* Plugin URI: https://github.com/ConnectThink/WP-SCSS
|
5 |
* Description: Compiles scss files live on WordPress.
|
6 |
-
* Version: 1.2.
|
7 |
* Author: Connect Think
|
8 |
* Author URI: http://connectthink.com
|
9 |
* License: GPLv3
|
@@ -46,7 +46,7 @@ if (!defined('WPSCSS_VERSION_KEY'))
|
|
46 |
define('WPSCSS_VERSION_KEY', 'wpscss_version');
|
47 |
|
48 |
if (!defined('WPSCSS_VERSION_NUM'))
|
49 |
-
define('WPSCSS_VERSION_NUM', '1.2.
|
50 |
|
51 |
// Add version to options table
|
52 |
if ( get_option( WPSCSS_VERSION_KEY ) !== false ) {
|
3 |
* Plugin Name: WP-SCSS
|
4 |
* Plugin URI: https://github.com/ConnectThink/WP-SCSS
|
5 |
* Description: Compiles scss files live on WordPress.
|
6 |
+
* Version: 1.2.2
|
7 |
* Author: Connect Think
|
8 |
* Author URI: http://connectthink.com
|
9 |
* License: GPLv3
|
46 |
define('WPSCSS_VERSION_KEY', 'wpscss_version');
|
47 |
|
48 |
if (!defined('WPSCSS_VERSION_NUM'))
|
49 |
+
define('WPSCSS_VERSION_NUM', '1.2.2');
|
50 |
|
51 |
// Add version to options table
|
52 |
if ( get_option( WPSCSS_VERSION_KEY ) !== false ) {
|