Changeset 115183 in spip-zone


Ignore:
Timestamp:
May 2, 2019, 12:19:31 PM (3 weeks ago)
Author:
cedric@…
Message:

Mise a jour de la lib ScssPHP en version 0.8.0.1 en provenance de https://github.com/Cerdic/scssphp/tree/maint/leafo/master
(c'est la version 0.8.0 de leafo/scssphp + la gestion du cache)

Cette nouvelle version compile maintenant integralement BS4 et Foundation,
et la compilation de BS4 a ete entierement verifiee comme conforme au fichier css dist fourni par Bootstrap

Location:
_plugins_/scssphp/trunk
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • _plugins_/scssphp/trunk/lib/scssphp/composer.json

    r115043 r115183  
    2626    "require-dev": {
    2727        "squizlabs/php_codesniffer": "~2.5",
    28         "phpunit/phpunit": "~4.6"
     28        "phpunit/phpunit": "~4.6",
     29        "twbs/bootstrap": "~4.3",
     30        "zurb/foundation": "~6.5"
    2931    },
    3032    "bin": ["bin/pscss"],
  • _plugins_/scssphp/trunk/lib/scssphp/src/Compiler.php

    r115044 r115183  
    162162    protected $ignoreErrors;
    163163
     164    protected $callStack = [];
     165
    164166    /**
    165167     * Constructor
     
    184186            'sourceMap' => serialize($this->sourceMap),
    185187            'sourceMapOptions' => $this->sourceMapOptions,
     188            'formater' => $this->formatter,
    186189        );
    187190        return $options;
     
    850853
    851854            $block->children = [[Type::T_BLOCK, $wrapped]];
     855            $block->selector = null;
     856        }
     857
     858        $selfParent = $block->selfParent;
     859        if (! $block->selfParent->selectors && isset($block->parent) && $block->parent && isset($block->parent->selectors) && $block->parent->selectors) {
     860            $selfParent = $block->parent;
    852861        }
    853862
    854863        $this->env = $this->filterWithout($envs, $without);
    855         $newBlock  = $this->spliceTree($envs, $block, $without);
    856864
    857865        $saveScope   = $this->scope;
    858         $this->scope = $this->rootBlock;
    859 
    860         $this->compileChild($newBlock, $this->scope);
    861 
     866        $this->scope = $this->filterScopeWithout($saveScope, $without);
     867
     868        // propagate selfParent to the children where they still can be useful
     869        $this->compileChildrenNoReturn($block->children, $this->scope, $selfParent);
     870
     871        $this->scope = $this->completeScope($this->scope, $saveScope);
    862872        $this->scope = $saveScope;
    863873        $this->env   = $this->extractEnv($envs);
     
    867877
    868878    /**
    869      * Splice parse tree
    870      *
    871      * @param array                $envs
    872      * @param \Leafo\ScssPhp\Block $block
    873      * @param integer              $without
    874      *
     879     * Filter at-root scope depending of with/without option
     880     * @param $scope
     881     * @param $without
     882     * @return mixed
     883     */
     884    protected function filterScopeWithout($scope, $without)
     885    {
     886        $filteredScopes = [];
     887
     888        if ($scope->type === TYPE::T_ROOT) {
     889            return $scope;
     890        }
     891
     892        // start from the root
     893        while ($scope->parent && $scope->parent->type !== TYPE::T_ROOT) {
     894            $scope = $scope->parent;
     895        }
     896
     897        for (;;) {
     898            if (! $scope) {
     899                break;
     900            }
     901            if (! $this->isWithout($without, $scope)) {
     902                $s = clone $scope;
     903                $s->children = [];
     904                $s->lines = [];
     905                $s->parent = null;
     906                if ($s->type !== Type::T_MEDIA && $s->type !== Type::T_DIRECTIVE) {
     907                    $s->selectors = [];
     908                }
     909                $filteredScopes[] = $s;
     910            }
     911
     912            if ($scope->children) {
     913                $scope = end($scope->children);
     914            } else {
     915                $scope = null;
     916            }
     917        }
     918        if (!count($filteredScopes)) {
     919            return $this->rootBlock;
     920        }
     921
     922        $newScope = array_shift($filteredScopes);
     923        $newScope->parent = $this->rootBlock;
     924        $this->rootBlock->children[] = $newScope;
     925
     926        $p = &$newScope;
     927        while (count($filteredScopes)) {
     928            $s = array_shift($filteredScopes);
     929            $s->parent = $p;
     930            $p->children[] = &$s;
     931            $p = $s;
     932        }
     933
     934        return $newScope;
     935    }
     936
     937    /**
     938     * found missing selector from a at-root compilation in the previous scope
     939     * (if at-root is just enclosing a property, the selector is in the parent tree)
     940     * @param $scope
     941     * @param $previousScope
     942     * @return mixed
     943     */
     944    protected function completeScope($scope, $previousScope)
     945    {
     946        if (! $scope->type && (! $scope->selectors || ! count($scope->selectors)) && count($scope->lines)) {
     947            $scope->selectors = $this->findScopeSelectors($previousScope, $scope->depth);
     948        }
     949        if ($scope->children) {
     950            foreach ($scope->children as $k => $c) {
     951                $scope->children[$k] = $this->completeScope($c, $previousScope);
     952            }
     953        }
     954
     955        return $scope;
     956    }
     957
     958    /**
     959     * Find a selector by the depth node in the scope
     960     * @param $scope
     961     * @param $depth
    875962     * @return array
    876963     */
    877     protected function spliceTree($envs, Block $block, $without)
    878     {
    879         $newBlock = null;
    880 
    881         foreach ($envs as $e) {
    882             if (! isset($e->block)) {
    883                 continue;
    884             }
    885 
    886             if ($e->block === $block) {
    887                 continue;
    888             }
    889 
    890             if (isset($e->block->type) && $e->block->type === Type::T_AT_ROOT) {
    891                 continue;
    892             }
    893 
    894             if ($e->block && $this->isWithout($without, $e->block)) {
    895                 continue;
    896             }
    897 
    898             $b = new Block;
    899             $b->sourceName   = $e->block->sourceName;
    900             $b->sourceIndex  = $e->block->sourceIndex;
    901             $b->sourceLine   = $e->block->sourceLine;
    902             $b->sourceColumn = $e->block->sourceColumn;
    903             $b->selectors    = [];
    904             $b->comments     = $e->block->comments;
    905             $b->parent       = null;
    906 
    907             if ($newBlock) {
    908                 $type = isset($newBlock->type) ? $newBlock->type : Type::T_BLOCK;
    909 
    910                 $b->children = [[$type, $newBlock]];
    911 
    912                 $newBlock->parent = $b;
    913             } elseif (count($block->children)) {
    914                 foreach ($block->children as $child) {
    915                     if ($child[0] === Type::T_BLOCK) {
    916                         $child[1]->parent = $b;
    917                     }
    918                 }
    919 
    920                 $b->children = $block->children;
    921             }
    922 
    923             if (isset($e->block->type)) {
    924                 $b->type = $e->block->type;
    925             }
    926 
    927             if (isset($e->block->name)) {
    928                 $b->name = $e->block->name;
    929             }
    930 
    931             if (isset($e->block->queryList)) {
    932                 $b->queryList = $e->block->queryList;
    933             }
    934 
    935             if (isset($e->block->value)) {
    936                 $b->value = $e->block->value;
    937             }
    938 
    939             $newBlock = $b;
    940         }
    941 
    942         $newBlock->selfParent   = $block->selfParent;
    943         $type = isset($newBlock->type) ? $newBlock->type : Type::T_BLOCK;
    944 
    945         return [$type, $newBlock];
     964    protected function findScopeSelectors($scope, $depth)
     965    {
     966        if ($scope->depth === $depth && $scope->selectors) {
     967            return $scope->selectors;
     968        }
     969        if ($scope->children) {
     970            foreach (array_reverse($scope->children) as $c) {
     971                if ($s = $this->findScopeSelectors($c, $depth)) {
     972                    return $s;
     973                }
     974            }
     975        }
     976        return [];
    946977    }
    947978
     
    10231054     *
    10241055     * @param integer              $without
    1025      * @param \Leafo\ScssPhp\Block $block
     1056     * @param \Leafo\ScssPhp\Block|\Leafo\ScssPhp\Formatter\OutputBlock $block
    10261057     *
    10271058     * @return boolean
    10281059     */
    1029     protected function isWithout($without, Block $block)
    1030     {
    1031         if ((($without & static::WITH_RULE) && isset($block->selectors)) ||
    1032             (($without & static::WITH_MEDIA) &&
    1033                 isset($block->type) && $block->type === Type::T_MEDIA) ||
    1034             (($without & static::WITH_SUPPORTS) &&
    1035                 isset($block->type) && $block->type === Type::T_DIRECTIVE &&
    1036                 isset($block->name) && $block->name === 'supports')
    1037         ) {
     1060    protected function isWithout($without, $block)
     1061    {
     1062        if (isset($block->type)) {
     1063            if ($block->type === Type::T_MEDIA) {
     1064                return ($without & static::WITH_MEDIA) ? true : false;
     1065            }
     1066
     1067            if ($block->type === Type::T_DIRECTIVE) {
     1068                if (isset($block->name) && $block->name === 'supports') {
     1069                    return ($without & static::WITH_SUPPORTS) ? true : false;
     1070                }
     1071                if (isset($block->selectors) && strpos(serialize($block->selectors), '@supports') !== false) {
     1072                    return ($without & static::WITH_SUPPORTS) ? true : false;
     1073                }
     1074            }
     1075        }
     1076        if ((($without & static::WITH_RULE) && isset($block->selectors))) {
    10381077            return true;
    10391078        }
     
    10821121        $this->scope = $this->makeOutputBlock($block->type, $selectors);
    10831122        $this->scope->parent->children[] = $this->scope;
     1123
     1124        // wrap assign children in a block
     1125        foreach ($block->children as $k => $child) {
     1126            if ($child[0] === Type::T_ASSIGN) {
     1127                $wrapped = new Block;
     1128                $wrapped->sourceName   = $block->sourceName;
     1129                $wrapped->sourceIndex  = $block->sourceIndex;
     1130                $wrapped->sourceLine   = $block->sourceLine;
     1131                $wrapped->sourceColumn = $block->sourceColumn;
     1132                $wrapped->selectors    = [];
     1133                $wrapped->comments     = [];
     1134                $wrapped->parent       = $block;
     1135                $wrapped->children     = [$child];
     1136                $wrapped->selfParent   = $block->selfParent;
     1137
     1138                $block->children[$k] = [Type::T_BLOCK, $wrapped];
     1139            }
     1140        }
    10841141
    10851142        $this->compileChildrenNoReturn($block->children, $this->scope);
     
    11431200        if (count($block->children)) {
    11441201            $out->selectors = $this->multiplySelectors($env, $block->selfParent);
    1145 
    1146             $this->compileChildrenNoReturn($block->children, $out);
     1202            // propagate selfParent to the children where they still can be useful
     1203            $selfParentSelectors = null;
     1204            if (isset($block->selfParent->selectors)) {
     1205                $selfParentSelectors = $block->selfParent->selectors;
     1206                $block->selfParent->selectors = $out->selectors;
     1207            }
     1208            $this->compileChildrenNoReturn($block->children, $out, $block->selfParent);
     1209            // and revert for the following childs of the same block
     1210            if ($selfParentSelectors) {
     1211                $block->selfParent->selectors = $selfParentSelectors;
     1212            }
    11471213        }
    11481214
     
    13611427    }
    13621428
     1429    protected function pushCallStack($name = '')
     1430    {
     1431        $this->callStack[] = [
     1432          'n' => $name,
     1433          Parser::SOURCE_INDEX => $this->sourceIndex,
     1434          Parser::SOURCE_LINE => $this->sourceLine,
     1435          Parser::SOURCE_COLUMN => $this->sourceColumn
     1436        ];
     1437    }
     1438
     1439    protected function popCallStack()
     1440    {
     1441        array_pop($this->callStack);
     1442    }
     1443
    13631444    /**
    13641445     * Compile children and return result
     
    13861467     * @param array                                $stms
    13871468     * @param \Leafo\ScssPhp\Formatter\OutputBlock $out
     1469     * @param \Leafo\ScssPhp\Block $selfParent
    13881470     *
    13891471     * @throws \Exception
    13901472     */
    1391     protected function compileChildrenNoReturn($stms, OutputBlock $out)
    1392     {
     1473    protected function compileChildrenNoReturn($stms, OutputBlock $out, $selfParent = null)
     1474    {
     1475
    13931476        foreach ($stms as $stm) {
    1394             $ret = $this->compileChild($stm, $out);
     1477            if ($selfParent && isset($stm[1]) && is_object($stm[1]) && get_class($stm[1]) == 'Leafo\ScssPhp\Block') {
     1478                $stm[1]->selfParent = $selfParent;
     1479                $ret = $this->compileChild($stm, $out);
     1480                $stm[1]->selfParent = null;
     1481            }
     1482            elseif ($selfParent && $stm[0] === TYPE::T_INCLUDE) {
     1483                $stm['selfParent'] = $selfParent;
     1484                $ret = $this->compileChild($stm, $out);
     1485                unset($stm['selfParent']);
     1486            } else {
     1487                $ret = $this->compileChild($stm, $out);
     1488            }
    13951489
    13961490            if (isset($ret)) {
     
    16291723    protected function compileChild($child, OutputBlock $out)
    16301724    {
    1631         $this->sourceIndex  = isset($child[Parser::SOURCE_INDEX]) ? $child[Parser::SOURCE_INDEX] : null;
    1632         $this->sourceLine   = isset($child[Parser::SOURCE_LINE]) ? $child[Parser::SOURCE_LINE] : -1;
    1633         $this->sourceColumn = isset($child[Parser::SOURCE_COLUMN]) ? $child[Parser::SOURCE_COLUMN] : -1;
     1725        if (isset($child[Parser::SOURCE_LINE])) {
     1726            $this->sourceIndex = isset($child[Parser::SOURCE_INDEX]) ? $child[Parser::SOURCE_INDEX] : null;
     1727            $this->sourceLine = isset($child[Parser::SOURCE_LINE]) ? $child[Parser::SOURCE_LINE] : -1;
     1728            $this->sourceColumn = isset($child[Parser::SOURCE_COLUMN]) ? $child[Parser::SOURCE_COLUMN] : -1;
     1729        } elseif (is_array($child) and isset($child[1]->sourceLine)) {
     1730            $this->sourceIndex = $child[1]->sourceIndex;
     1731            $this->sourceLine = $child[1]->sourceLine;
     1732            $this->sourceColumn = $child[1]->sourceColumn;
     1733        } elseif (! empty($out->sourceLine) and ! empty($out->sourceName)) {
     1734            $this->sourceLine = $out->sourceLine;
     1735            $this->sourceIndex = array_search($out->sourceName, $this->sourceNames);
     1736            if ($this->sourceIndex === false) {
     1737                $this->sourceIndex = null;
     1738            }
     1739        }
    16341740
    16351741        switch ($child[0]) {
     
    16921798
    16931799                    if (! $isDefault || $shouldSet) {
    1694                         $this->set($name[1], $this->reduce($value), false, null, $value);
     1800                        $this->set($name[1], $this->reduce($value), true, null, $value);
    16951801                    }
    16961802                    break;
     
    19362042                $this->storeEnv = $this->env;
    19372043
     2044                // Find the parent selectors in the env to be able to know what '&' refers to in the mixin
     2045                // and assign this fake parent to childs
     2046                $selfParent = null;
     2047                if (isset($child['selfParent']) && isset($child['selfParent']->selectors)) {
     2048                    $selfParent = $child['selfParent'];
     2049                }
     2050                else {
     2051                    $parentSelectors = $this->multiplySelectors($this->env);
     2052                    if ($parentSelectors) {
     2053                        $parent = new Block();
     2054                        $parent->selectors = $parentSelectors;
     2055                        foreach ($mixin->children as $k => $child) {
     2056                            if (isset($child[1]) && is_object($child[1]) && get_class($child[1]) == 'Leafo\ScssPhp\Block') {
     2057                                $mixin->children[$k][1]->parent = $parent;
     2058                            }
     2059                        }
     2060                    }
     2061                }
     2062
    19382063                if (isset($content)) {
    19392064                    $content->scope = $callingScope;
     
    19482073                $this->env->marker = 'mixin';
    19492074
    1950                 $this->compileChildrenNoReturn($mixin->children, $out);
     2075                $this->pushCallStack($this->env->marker . " " . $name);
     2076                $this->compileChildrenNoReturn($mixin->children, $out, $selfParent);
     2077                $this->popCallStack();
    19512078
    19522079                $this->storeEnv = $storeEnv;
     
    22672394                return $this->fncall($value[1], $value[2]);
    22682395
     2396            case Type::T_SELF:
     2397                $selfSelector = $this->multiplySelectors($this->env);
     2398                $selfSelector = $this->collapseSelectors($selfSelector);
     2399                return [Type::T_STRING, '', [$selfSelector]];
     2400
    22692401            default:
    22702402                return $value;
     
    29833115            foreach ($env->selectors as $selector) {
    29843116                foreach ($parentSelectors as $parent) {
    2985                     $selectors[] = $this->joinSelectors($parent, $selector, $selfParentSelectors);
     3117                    if ($selfParentSelectors) {
     3118                        $previous = null;
     3119                        foreach ($selfParentSelectors as $selfParent) {
     3120                            // if no '&' in the selector, each call will give same result, only add once
     3121                            $s = $this->joinSelectors($parent, $selector, $selfParent);
     3122                            if ($s !== $previous) {
     3123                                $selectors[serialize($s)] = $s;
     3124                            }
     3125                            $previous = $s;
     3126                        }
     3127                    } else {
     3128                        $s = $this->joinSelectors($parent, $selector);
     3129                        $selectors[serialize($s)] = $s;
     3130                    }
    29863131                }
    29873132            }
     
    29903135        }
    29913136
     3137        $selectors = array_values($selectors);
    29923138        return $selectors;
    29933139    }
     
    30223168
    30233169                        foreach ($parentPart as $pp) {
    3024                             $newPart[] = (is_array($pp) ? implode($pp) : $pp);
     3170                            if (is_array($pp)) {
     3171                                $flatten = [];
     3172                                array_walk_recursive($pp, function ($a) use (&$flatten) {
     3173                                    $flatten[] = $a;
     3174                                });
     3175                                $pp = implode($flatten);
     3176                            }
     3177                            $newPart[] = $pp;
    30253178                        }
    30263179                    }
     
    32613414                if (! $nextIsRoot && ! empty($env->store[$specialContentKey])) {
    32623415                    $env = $env->store[$specialContentKey]->scope;
    3263                     $nextIsRoot = true;
    32643416                    continue;
    32653417                }
     
    36383790        $loc = isset($this->sourceNames[$this->sourceIndex]) ? $this->sourceNames[$this->sourceIndex] . " on line $line" : "line: $line";
    36393791        $msg = "$msg: $loc";
     3792        if ($this->callStack) {
     3793            $msg .= "\nCall Stack:\n";
     3794            $ncall = 0;
     3795            foreach (array_reverse($this->callStack) as $call) {
     3796                $msg .= "#" . $ncall++ . " " . $call['n'] . " ";
     3797                $msg .= (isset($this->sourceNames[$call[Parser::SOURCE_INDEX]]) ? $this->sourceNames[$call[Parser::SOURCE_INDEX]] : '(unknown file)');
     3798                $msg .= " on line " . $call[Parser::SOURCE_LINE] . "\n";
     3799            }
     3800        }
    36403801
    36413802        throw new CompilerException($msg);
     
    37063867
    37073868        $this->env->marker = 'function';
     3869        $this->pushCallStack($this->env->marker . " " . $name);
    37083870
    37093871        $ret = $this->compileChildren($func->children, $tmp);
     3872
     3873        $this->popCallStack();
    37103874
    37113875        $this->storeEnv = $storeEnv;
  • _plugins_/scssphp/trunk/lib/scssphp/src/Parser.php

    r115044 r115183  
    14271427        }
    14281428
     1429        if ($this->matchChar('&', true)) {
     1430            $out = [Type::T_SELF];
     1431            return true;
     1432        }
     1433
    14291434        if ($char === '$' && $this->variable($out)) {
    14301435            return true;
     
    17941799
    17951800        if ($this->match('([0-9]*(\.)?[0-9]+)([%a-zA-Z]+)?', $m, false)) {
    1796             if (strlen($this->buffer) == $this->count || ! ctype_digit($this->buffer[$this->count])) {
     1801            if (strlen($this->buffer) === $this->count || ! ctype_digit($this->buffer[$this->count])) {
    17971802                $this->whitespace();
    17981803
     
    18041809            $this->seek($s);
    18051810        }
    1806 /*
    1807         if ($this->match('([0-9][0-9a-fA-F]+)', $m)) {
    1808             $unit = new Node\Number($m[1], '');
    1809 
    1810             return true;
    1811         }
    1812 */
    18131811
    18141812        return false;
     
    20232021
    20242022        if ($this->literal('#{', 2) && $this->valueList($value) && $this->matchChar('}', false)) {
    2025             if ($lookWhite) {
    2026                 $left = preg_match('/\s/', $this->buffer[$s - 1]) ? ' ' : '';
    2027                 $right = preg_match('/\s/', $this->buffer[$this->count]) ? ' ': '';
     2023            if ($value === [Type::T_SELF]) {
     2024                $out = $value;
    20282025            } else {
    2029                 $left = $right = false;
    2030             }
    2031 
    2032             $out = [Type::T_INTERPOLATE, $value, $left, $right];
     2026                if ($lookWhite) {
     2027                    $left = preg_match('/\s/', $this->buffer[$s - 1]) ? ' ' : '';
     2028                    $right = preg_match('/\s/', $this->buffer[$this->count]) ? ' ': '';
     2029                } else {
     2030                    $left = $right = false;
     2031                }
     2032
     2033                $out = [Type::T_INTERPOLATE, $value, $left, $right];
     2034            }
    20332035            $this->eatWhiteDefault = $oldWhite;
    20342036
     
    20422044        $this->seek($s);
    20432045
    2044         if ($this->literal('#{', 2) && $this->selectorSingle($sel) && $this->matchChar('}', false)) {
    2045             $out = $sel[0];
    2046 
    2047             $this->eatWhiteDefault = $oldWhite;
    2048 
    2049             if ($this->eatWhiteDefault) {
    2050                 $this->whitespace();
    2051             }
    2052 
    2053             return true;
    2054         }
    2055 
    2056         $this->seek($s);
    20572046        $this->eatWhiteDefault = $oldWhite;
    20582047
  • _plugins_/scssphp/trunk/lib/scssphp/src/Version.php

    r115044 r115183  
    1919class Version
    2020{
    21     const VERSION = 'v0.7.9';
     21    const VERSION = 'v0.8.0.1';
    2222}
  • _plugins_/scssphp/trunk/paquet.xml

    r115044 r115183  
    22        prefix="scssphp"
    33        categorie="outil"
    4         version="1.8.1"
     4        version="1.9.0"
    55        etat="test"
    66        compatibilite="[2.1.0;3.2.*]"
     
    2222        <pipeline nom="formulaire_admin"  inclure="scssphp_pipelines.php" />
    2323
    24         <procure nom="scssphp" version="0.7.9.1" />
     24        <procure nom="scssphp" version="0.8.0.1" />
    2525
    2626        <spip compatibilite="[3.1.0;[">
Note: See TracChangeset for help on using the changeset viewer.