N°2226: Upgrade ScssPHP to v1.0.0

This commit is contained in:
Stephen Abello
2019-06-28 14:24:56 +02:00
parent c7fe6f388a
commit a827cb7546
29 changed files with 4152 additions and 1302 deletions

View File

@@ -1,6 +1,6 @@
<?php
use Leafo\ScssPhp\Compiler;
use ScssPhp\ScssPhp\Compiler;
// Copyright (C) 2010-2017 Combodo SARL
//
@@ -1538,7 +1538,7 @@ class utils
require_once(APPROOT.'lib/scssphp/scss.inc.php');
$oScss = new Compiler();
$oScss->setImportPaths($aImportPaths);
$oScss->setFormatter('Leafo\\ScssPhp\\Formatter\\Expanded');
$oScss->setFormatter('ScssPhp\\ScssPhp\\Formatter\\Expanded');
// Temporary disabling max exec time while compiling
$iCurrentMaxExecTime = (int) ini_get('max_execution_time');
set_time_limit(0);

View File

@@ -1,4 +1,4 @@
Copyright (c) 2015 Leaf Corcoran, http://leafo.github.io/scssphp
Copyright (c) 2015 Leaf Corcoran, http://scssphp.github.io/scssphp
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the

View File

@@ -1,12 +1,12 @@
# scssphp
### <http://leafo.github.io/scssphp>
### <http://scssphp.github.io/scssphp>
[![Build](https://travis-ci.org/leafo/scssphp.svg?branch=master)](http://travis-ci.org/leafo/scssphp)
[![License](https://poser.pugx.org/leafo/scssphp/license.svg)](https://packagist.org/packages/leafo/scssphp)
[![Build](https://travis-ci.org/scssphp/scssphp.svg?branch=master)](http://travis-ci.org/scssphp/scssphp)
[![License](https://poser.pugx.org/scssphp/scssphp/license.svg)](https://packagist.org/packages/scssphp/scssphp)
`scssphp` is a compiler for SCSS written in PHP.
Checkout the homepage, <http://leafo.github.io/scssphp>, for directions on how to use.
Checkout the homepage, <http://scssphp.github.io/scssphp>, for directions on how to use.
## Running Tests

29
lib/scssphp/bin/pscss Normal file → Executable file
View File

@@ -3,11 +3,11 @@
/**
* SCSSPHP
*
* @copyright 2012-2015 Leaf Corcoran
* @copyright 2012-2019 Leaf Corcoran
*
* @license http://opensource.org/licenses/MIT MIT
*
* @link http://leafo.github.io/scssphp
* @link http://scssphp.github.io/scssphp
*/
error_reporting(E_ALL);
@@ -18,9 +18,9 @@ if (version_compare(PHP_VERSION, '5.4') < 0) {
include __DIR__ . '/../scss.inc.php';
use Leafo\ScssPhp\Compiler;
use Leafo\ScssPhp\Parser;
use Leafo\ScssPhp\Version;
use ScssPhp\ScssPhp\Compiler;
use ScssPhp\ScssPhp\Parser;
use ScssPhp\ScssPhp\Version;
$style = null;
$loadPaths = null;
@@ -32,6 +32,7 @@ $debugInfo = false;
$lineNumbers = false;
$ignoreErrors = false;
$encoding = false;
$sourceMap = false;
/**
* Parse argument
@@ -76,7 +77,8 @@ Options include:
-i=path Set import path
--iso8859-1 Use iso8859-1 encoding instead of utf-8 (default utf-8)
--line-numbers Annotate selectors with comments referring to the source file and line number
-p=precision Set decimal number precision (default 5)
-p=precision Set decimal number precision (default 10)
--sourcemap Create source map file
-T Dump formatted parse tree
-v, --version Print the version
@@ -108,6 +110,11 @@ EOT;
continue;
}
if ($argv[$i] === '--sourcemap') {
$sourceMap = true;
continue;
}
if ($argv[$i] === '-T') {
$dumpTree = true;
continue;
@@ -169,11 +176,11 @@ if ($dumpTree) {
$scss = new Compiler();
if ($debugInfo && $inputFile) {
if ($debugInfo) {
$scss->setLineNumberStyle(Compiler::DEBUG_INFO);
}
if ($lineNumbers && $inputFile) {
if ($lineNumbers) {
$scss->setLineNumberStyle(Compiler::LINE_COMMENTS);
}
@@ -190,7 +197,11 @@ if ($precision) {
}
if ($style) {
$scss->setFormatter('Leafo\\ScssPhp\\Formatter\\' . ucfirst($style));
$scss->setFormatter('ScssPhp\\ScssPhp\\Formatter\\' . ucfirst($style));
}
if ($sourceMap) {
$scss->setSourceMap(Compiler::SOURCE_MAP_INLINE);
}
if ($encoding) {

View File

@@ -1,20 +1,18 @@
<?php
/*
* Warning: The library original has been transformed to replace "short array notation" (i.e. []) with its pre-PHP 5.4 version (i.e. array())
* in order to make it run on PHP 5.3, using a script based on the excellent php-parser (https://github.com/nikic/PHP-Parser by Nikita Popov)
*
if (version_compare(PHP_VERSION, '5.4') < 0) {
throw new \Exception('scssphp requires PHP 5.4 or above');
if (version_compare(PHP_VERSION, '5.6') < 0) {
throw new \Exception('scssphp requires PHP 5.6 or above');
}
*/
if (!class_exists('scssc', false)) {
if (! class_exists('ScssPhp\ScssPhp\Version', false)) {
include_once __DIR__ . '/src/Base/Range.php';
include_once __DIR__ . '/src/Block.php';
include_once __DIR__ . '/src/Cache.php';
include_once __DIR__ . '/src/Colors.php';
include_once __DIR__ . '/src/Compiler.php';
include_once __DIR__ . '/src/Compiler/Environment.php';
include_once __DIR__ . '/src/Exception/CompilerException.php';
include_once __DIR__ . '/src/Exception/ParserException.php';
include_once __DIR__ . '/src/Exception/RangeException.php';
include_once __DIR__ . '/src/Exception/ServerException.php';
include_once __DIR__ . '/src/Formatter.php';
include_once __DIR__ . '/src/Formatter/Compact.php';
@@ -27,8 +25,10 @@ if (!class_exists('scssc', false)) {
include_once __DIR__ . '/src/Node.php';
include_once __DIR__ . '/src/Node/Number.php';
include_once __DIR__ . '/src/Parser.php';
include_once __DIR__ . '/src/SourceMap/Base64.php';
include_once __DIR__ . '/src/SourceMap/Base64VLQ.php';
include_once __DIR__ . '/src/SourceMap/SourceMapGenerator.php';
include_once __DIR__ . '/src/Type.php';
include_once __DIR__ . '/src/Util.php';
include_once __DIR__ . '/src/Version.php';
include_once __DIR__ . '/src/Server.php';
}

View File

@@ -2,13 +2,14 @@
/**
* SCSSPHP
*
* @copyright 2015 Leaf Corcoran
* @copyright 2015-2019 Leaf Corcoran
*
* @license http://opensource.org/licenses/MIT MIT
*
* @link http://leafo.github.io/scssphp
* @link http://scssphp.github.io/scssphp
*/
namespace Leafo\ScssPhp\Base;
namespace ScssPhp\ScssPhp\Base;
/**
* Range
@@ -19,6 +20,7 @@ class Range
{
public $first;
public $last;
/**
* Initialize range
*
@@ -30,6 +32,7 @@ class Range
$this->first = $first;
$this->last = $last;
}
/**
* Test for inclusion in range
*

View File

@@ -2,13 +2,14 @@
/**
* SCSSPHP
*
* @copyright 2012-2015 Leaf Corcoran
* @copyright 2012-2019 Leaf Corcoran
*
* @license http://opensource.org/licenses/MIT MIT
*
* @link http://leafo.github.io/scssphp
* @link http://scssphp.github.io/scssphp
*/
namespace Leafo\ScssPhp;
namespace ScssPhp\ScssPhp;
/**
* Block
@@ -21,32 +22,49 @@ class Block
* @var string
*/
public $type;
/**
* @var \Leafo\ScssPhp\Block
* @var \ScssPhp\ScssPhp\Block
*/
public $parent;
/**
* @var string
*/
public $sourceName;
/**
* @var integer
*/
public $sourceIndex;
/**
* @var integer
*/
public $sourceLine;
/**
* @var integer
*/
public $sourceColumn;
/**
* @var array
*/
public $selectors;
/**
* @var array
*/
public $comments;
/**
* @var array
*/
public $children;
/**
* @var \ScssPhp\ScssPhp\Block
*/
public $selfParent;
}

View File

@@ -2,13 +2,14 @@
/**
* SCSSPHP
*
* @copyright 2012-2015 Leaf Corcoran
* @copyright 2012-2019 Leaf Corcoran
*
* @license http://opensource.org/licenses/MIT MIT
*
* @link http://leafo.github.io/scssphp
* @link http://scssphp.github.io/scssphp
*/
namespace Leafo\ScssPhp;
namespace ScssPhp\ScssPhp;
/**
* CSS Colors
@@ -24,5 +25,155 @@ class Colors
*
* @var array
*/
public static $cssColors = array('aliceblue' => '240,248,255', 'antiquewhite' => '250,235,215', 'aqua' => '0,255,255', 'aquamarine' => '127,255,212', 'azure' => '240,255,255', 'beige' => '245,245,220', 'bisque' => '255,228,196', 'black' => '0,0,0', 'blanchedalmond' => '255,235,205', 'blue' => '0,0,255', 'blueviolet' => '138,43,226', 'brown' => '165,42,42', 'burlywood' => '222,184,135', 'cadetblue' => '95,158,160', 'chartreuse' => '127,255,0', 'chocolate' => '210,105,30', 'coral' => '255,127,80', 'cornflowerblue' => '100,149,237', 'cornsilk' => '255,248,220', 'crimson' => '220,20,60', 'cyan' => '0,255,255', 'darkblue' => '0,0,139', 'darkcyan' => '0,139,139', 'darkgoldenrod' => '184,134,11', 'darkgray' => '169,169,169', 'darkgreen' => '0,100,0', 'darkgrey' => '169,169,169', 'darkkhaki' => '189,183,107', 'darkmagenta' => '139,0,139', 'darkolivegreen' => '85,107,47', 'darkorange' => '255,140,0', 'darkorchid' => '153,50,204', 'darkred' => '139,0,0', 'darksalmon' => '233,150,122', 'darkseagreen' => '143,188,143', 'darkslateblue' => '72,61,139', 'darkslategray' => '47,79,79', 'darkslategrey' => '47,79,79', 'darkturquoise' => '0,206,209', 'darkviolet' => '148,0,211', 'deeppink' => '255,20,147', 'deepskyblue' => '0,191,255', 'dimgray' => '105,105,105', 'dimgrey' => '105,105,105', 'dodgerblue' => '30,144,255', 'firebrick' => '178,34,34', 'floralwhite' => '255,250,240', 'forestgreen' => '34,139,34', 'fuchsia' => '255,0,255', 'gainsboro' => '220,220,220', 'ghostwhite' => '248,248,255', 'gold' => '255,215,0', 'goldenrod' => '218,165,32', 'gray' => '128,128,128', 'green' => '0,128,0', 'greenyellow' => '173,255,47', 'grey' => '128,128,128', 'honeydew' => '240,255,240', 'hotpink' => '255,105,180', 'indianred' => '205,92,92', 'indigo' => '75,0,130', 'ivory' => '255,255,240', 'khaki' => '240,230,140', 'lavender' => '230,230,250', 'lavenderblush' => '255,240,245', 'lawngreen' => '124,252,0', 'lemonchiffon' => '255,250,205', 'lightblue' => '173,216,230', 'lightcoral' => '240,128,128', 'lightcyan' => '224,255,255', 'lightgoldenrodyellow' => '250,250,210', 'lightgray' => '211,211,211', 'lightgreen' => '144,238,144', 'lightgrey' => '211,211,211', 'lightpink' => '255,182,193', 'lightsalmon' => '255,160,122', 'lightseagreen' => '32,178,170', 'lightskyblue' => '135,206,250', 'lightslategray' => '119,136,153', 'lightslategrey' => '119,136,153', 'lightsteelblue' => '176,196,222', 'lightyellow' => '255,255,224', 'lime' => '0,255,0', 'limegreen' => '50,205,50', 'linen' => '250,240,230', 'magenta' => '255,0,255', 'maroon' => '128,0,0', 'mediumaquamarine' => '102,205,170', 'mediumblue' => '0,0,205', 'mediumorchid' => '186,85,211', 'mediumpurple' => '147,112,219', 'mediumseagreen' => '60,179,113', 'mediumslateblue' => '123,104,238', 'mediumspringgreen' => '0,250,154', 'mediumturquoise' => '72,209,204', 'mediumvioletred' => '199,21,133', 'midnightblue' => '25,25,112', 'mintcream' => '245,255,250', 'mistyrose' => '255,228,225', 'moccasin' => '255,228,181', 'navajowhite' => '255,222,173', 'navy' => '0,0,128', 'oldlace' => '253,245,230', 'olive' => '128,128,0', 'olivedrab' => '107,142,35', 'orange' => '255,165,0', 'orangered' => '255,69,0', 'orchid' => '218,112,214', 'palegoldenrod' => '238,232,170', 'palegreen' => '152,251,152', 'paleturquoise' => '175,238,238', 'palevioletred' => '219,112,147', 'papayawhip' => '255,239,213', 'peachpuff' => '255,218,185', 'peru' => '205,133,63', 'pink' => '255,192,203', 'plum' => '221,160,221', 'powderblue' => '176,224,230', 'purple' => '128,0,128', 'rebeccapurple' => '102,51,153', 'red' => '255,0,0', 'rosybrown' => '188,143,143', 'royalblue' => '65,105,225', 'saddlebrown' => '139,69,19', 'salmon' => '250,128,114', 'sandybrown' => '244,164,96', 'seagreen' => '46,139,87', 'seashell' => '255,245,238', 'sienna' => '160,82,45', 'silver' => '192,192,192', 'skyblue' => '135,206,235', 'slateblue' => '106,90,205', 'slategray' => '112,128,144', 'slategrey' => '112,128,144', 'snow' => '255,250,250', 'springgreen' => '0,255,127', 'steelblue' => '70,130,180', 'tan' => '210,180,140', 'teal' => '0,128,128', 'thistle' => '216,191,216', 'tomato' => '255,99,71', 'transparent' => '0,0,0,0', 'turquoise' => '64,224,208', 'violet' => '238,130,238', 'wheat' => '245,222,179', 'white' => '255,255,255', 'whitesmoke' => '245,245,245', 'yellow' => '255,255,0', 'yellowgreen' => '154,205,50');
public static $cssColors = [
'aliceblue' => '240,248,255',
'antiquewhite' => '250,235,215',
'aqua' => '0,255,255',
'aquamarine' => '127,255,212',
'azure' => '240,255,255',
'beige' => '245,245,220',
'bisque' => '255,228,196',
'black' => '0,0,0',
'blanchedalmond' => '255,235,205',
'blue' => '0,0,255',
'blueviolet' => '138,43,226',
'brown' => '165,42,42',
'burlywood' => '222,184,135',
'cadetblue' => '95,158,160',
'chartreuse' => '127,255,0',
'chocolate' => '210,105,30',
'coral' => '255,127,80',
'cornflowerblue' => '100,149,237',
'cornsilk' => '255,248,220',
'crimson' => '220,20,60',
'cyan' => '0,255,255',
'darkblue' => '0,0,139',
'darkcyan' => '0,139,139',
'darkgoldenrod' => '184,134,11',
'darkgray' => '169,169,169',
'darkgreen' => '0,100,0',
'darkgrey' => '169,169,169',
'darkkhaki' => '189,183,107',
'darkmagenta' => '139,0,139',
'darkolivegreen' => '85,107,47',
'darkorange' => '255,140,0',
'darkorchid' => '153,50,204',
'darkred' => '139,0,0',
'darksalmon' => '233,150,122',
'darkseagreen' => '143,188,143',
'darkslateblue' => '72,61,139',
'darkslategray' => '47,79,79',
'darkslategrey' => '47,79,79',
'darkturquoise' => '0,206,209',
'darkviolet' => '148,0,211',
'deeppink' => '255,20,147',
'deepskyblue' => '0,191,255',
'dimgray' => '105,105,105',
'dimgrey' => '105,105,105',
'dodgerblue' => '30,144,255',
'firebrick' => '178,34,34',
'floralwhite' => '255,250,240',
'forestgreen' => '34,139,34',
'fuchsia' => '255,0,255',
'gainsboro' => '220,220,220',
'ghostwhite' => '248,248,255',
'gold' => '255,215,0',
'goldenrod' => '218,165,32',
'gray' => '128,128,128',
'green' => '0,128,0',
'greenyellow' => '173,255,47',
'grey' => '128,128,128',
'honeydew' => '240,255,240',
'hotpink' => '255,105,180',
'indianred' => '205,92,92',
'indigo' => '75,0,130',
'ivory' => '255,255,240',
'khaki' => '240,230,140',
'lavender' => '230,230,250',
'lavenderblush' => '255,240,245',
'lawngreen' => '124,252,0',
'lemonchiffon' => '255,250,205',
'lightblue' => '173,216,230',
'lightcoral' => '240,128,128',
'lightcyan' => '224,255,255',
'lightgoldenrodyellow' => '250,250,210',
'lightgray' => '211,211,211',
'lightgreen' => '144,238,144',
'lightgrey' => '211,211,211',
'lightpink' => '255,182,193',
'lightsalmon' => '255,160,122',
'lightseagreen' => '32,178,170',
'lightskyblue' => '135,206,250',
'lightslategray' => '119,136,153',
'lightslategrey' => '119,136,153',
'lightsteelblue' => '176,196,222',
'lightyellow' => '255,255,224',
'lime' => '0,255,0',
'limegreen' => '50,205,50',
'linen' => '250,240,230',
'magenta' => '255,0,255',
'maroon' => '128,0,0',
'mediumaquamarine' => '102,205,170',
'mediumblue' => '0,0,205',
'mediumorchid' => '186,85,211',
'mediumpurple' => '147,112,219',
'mediumseagreen' => '60,179,113',
'mediumslateblue' => '123,104,238',
'mediumspringgreen' => '0,250,154',
'mediumturquoise' => '72,209,204',
'mediumvioletred' => '199,21,133',
'midnightblue' => '25,25,112',
'mintcream' => '245,255,250',
'mistyrose' => '255,228,225',
'moccasin' => '255,228,181',
'navajowhite' => '255,222,173',
'navy' => '0,0,128',
'oldlace' => '253,245,230',
'olive' => '128,128,0',
'olivedrab' => '107,142,35',
'orange' => '255,165,0',
'orangered' => '255,69,0',
'orchid' => '218,112,214',
'palegoldenrod' => '238,232,170',
'palegreen' => '152,251,152',
'paleturquoise' => '175,238,238',
'palevioletred' => '219,112,147',
'papayawhip' => '255,239,213',
'peachpuff' => '255,218,185',
'peru' => '205,133,63',
'pink' => '255,192,203',
'plum' => '221,160,221',
'powderblue' => '176,224,230',
'purple' => '128,0,128',
'rebeccapurple' => '102,51,153',
'red' => '255,0,0',
'rosybrown' => '188,143,143',
'royalblue' => '65,105,225',
'saddlebrown' => '139,69,19',
'salmon' => '250,128,114',
'sandybrown' => '244,164,96',
'seagreen' => '46,139,87',
'seashell' => '255,245,238',
'sienna' => '160,82,45',
'silver' => '192,192,192',
'skyblue' => '135,206,235',
'slateblue' => '106,90,205',
'slategray' => '112,128,144',
'slategrey' => '112,128,144',
'snow' => '255,250,250',
'springgreen' => '0,255,127',
'steelblue' => '70,130,180',
'tan' => '210,180,140',
'teal' => '0,128,128',
'thistle' => '216,191,216',
'tomato' => '255,99,71',
'transparent' => '0,0,0,0',
'turquoise' => '64,224,208',
'violet' => '238,130,238',
'wheat' => '245,222,179',
'white' => '255,255,255',
'whitesmoke' => '245,245,245',
'yellow' => '255,255,0',
'yellowgreen' => '154,205,50',
];
}

File diff suppressed because it is too large Load Diff

View File

@@ -2,13 +2,14 @@
/**
* SCSSPHP
*
* @copyright 2012-2015 Leaf Corcoran
* @copyright 2012-2019 Leaf Corcoran
*
* @license http://opensource.org/licenses/MIT MIT
*
* @link http://leafo.github.io/scssphp
* @link http://scssphp.github.io/scssphp
*/
namespace Leafo\ScssPhp\Compiler;
namespace ScssPhp\ScssPhp\Compiler;
/**
* Compiler environment
@@ -18,17 +19,25 @@ namespace Leafo\ScssPhp\Compiler;
class Environment
{
/**
* @var \Leafo\ScssPhp\Block
* @var \ScssPhp\ScssPhp\Block
*/
public $block;
/**
* @var \Leafo\ScssPhp\Compiler\Environment
* @var \ScssPhp\ScssPhp\Compiler\Environment
*/
public $parent;
/**
* @var array
*/
public $store;
/**
* @var array
*/
public $storeUnreduced;
/**
* @var integer
*/

View File

@@ -2,13 +2,14 @@
/**
* SCSSPHP
*
* @copyright 2012-2015 Leaf Corcoran
* @copyright 2012-2019 Leaf Corcoran
*
* @license http://opensource.org/licenses/MIT MIT
*
* @link http://leafo.github.io/scssphp
* @link http://scssphp.github.io/scssphp
*/
namespace Leafo\ScssPhp\Exception;
namespace ScssPhp\ScssPhp\Exception;
/**
* Compiler exception

View File

@@ -2,13 +2,14 @@
/**
* SCSSPHP
*
* @copyright 2012-2015 Leaf Corcoran
* @copyright 2012-2019 Leaf Corcoran
*
* @license http://opensource.org/licenses/MIT MIT
*
* @link http://leafo.github.io/scssphp
* @link http://scssphp.github.io/scssphp
*/
namespace Leafo\ScssPhp\Exception;
namespace ScssPhp\ScssPhp\Exception;
/**
* Parser Exception

View File

@@ -2,13 +2,14 @@
/**
* SCSSPHP
*
* @copyright 2012-2015 Leaf Corcoran
* @copyright 2012-2019 Leaf Corcoran
*
* @license http://opensource.org/licenses/MIT MIT
*
* @link http://leafo.github.io/scssphp
* @link http://scssphp.github.io/scssphp
*/
namespace Leafo\ScssPhp\Exception;
namespace ScssPhp\ScssPhp\Exception;
/**
* Server Exception

View File

@@ -2,15 +2,18 @@
/**
* SCSSPHP
*
* @copyright 2012-2015 Leaf Corcoran
* @copyright 2012-2019 Leaf Corcoran
*
* @license http://opensource.org/licenses/MIT MIT
*
* @link http://leafo.github.io/scssphp
* @link http://scssphp.github.io/scssphp
*/
namespace Leafo\ScssPhp;
use Leafo\ScssPhp\Formatter\OutputBlock;
namespace ScssPhp\ScssPhp;
use ScssPhp\ScssPhp\Formatter\OutputBlock;
use ScssPhp\ScssPhp\SourceMap\SourceMapGenerator;
/**
* Base formatter
*
@@ -22,40 +25,69 @@ abstract class Formatter
* @var integer
*/
public $indentLevel;
/**
* @var string
*/
public $indentChar;
/**
* @var string
*/
public $break;
/**
* @var string
*/
public $open;
/**
* @var string
*/
public $close;
/**
* @var string
*/
public $tagSeparator;
/**
* @var string
*/
public $assignSeparator;
/**
* @var boolea
* @var boolean
*/
public $keepSemicolons;
/**
* @var \ScssPhp\ScssPhp\Formatter\OutputBlock
*/
protected $currentBlock;
/**
* @var integer
*/
protected $currentLine;
/**
* @var integer
*/
protected $currentColumn;
/**
* @var \ScssPhp\ScssPhp\SourceMap\SourceMapGenerator
*/
protected $sourceMapGenerator;
/**
* Initialize formatter
*
* @api
*/
public abstract function __construct();
abstract public function __construct();
/**
* Return indentation (whitespace)
*
@@ -65,6 +97,7 @@ abstract class Formatter
{
return '';
}
/**
* Return property assignment
*
@@ -79,6 +112,7 @@ abstract class Formatter
{
return rtrim($name) . $this->assignSeparator . $value . ';';
}
/**
* Strip semi-colon appended by property(); it's a separator, not a terminator
*
@@ -91,38 +125,50 @@ abstract class Formatter
if ($this->keepSemicolons) {
return;
}
if (($count = count($lines)) && substr($lines[$count - 1], -1) === ';') {
if (($count = count($lines))
&& substr($lines[$count - 1], -1) === ';'
) {
$lines[$count - 1] = substr($lines[$count - 1], 0, -1);
}
}
/**
* Output lines inside a block
*
* @param \Leafo\ScssPhp\Formatter\OutputBlock $block
* @param \ScssPhp\ScssPhp\Formatter\OutputBlock $block
*/
protected function blockLines(OutputBlock $block)
{
$inner = $this->indentStr();
$glue = $this->break . $inner;
echo $inner . implode($glue, $block->lines);
if (!empty($block->children)) {
echo $this->break;
$this->write($inner . implode($glue, $block->lines));
if (! empty($block->children)) {
$this->write($this->break);
}
}
/**
* Output block selectors
*
* @param \Leafo\ScssPhp\Formatter\OutputBlock $block
* @param \ScssPhp\ScssPhp\Formatter\OutputBlock $block
*/
protected function blockSelectors(OutputBlock $block)
{
$inner = $this->indentStr();
echo $inner . implode($this->tagSeparator, $block->selectors) . $this->open . $this->break;
$this->write($inner
. implode($this->tagSeparator, $block->selectors)
. $this->open . $this->break);
}
/**
* Output block children
*
* @param \Leafo\ScssPhp\Formatter\OutputBlock $block
* @param \ScssPhp\ScssPhp\Formatter\OutputBlock $block
*/
protected function blockChildren(OutputBlock $block)
{
@@ -130,49 +176,100 @@ abstract class Formatter
$this->block($child);
}
}
/**
* Output non-empty block
*
* @param \Leafo\ScssPhp\Formatter\OutputBlock $block
* @param \ScssPhp\ScssPhp\Formatter\OutputBlock $block
*/
protected function block(OutputBlock $block)
{
if (empty($block->lines) && empty($block->children)) {
return;
}
$this->currentBlock = $block;
$pre = $this->indentStr();
if (!empty($block->selectors)) {
if (! empty($block->selectors)) {
$this->blockSelectors($block);
$this->indentLevel++;
}
if (!empty($block->lines)) {
if (! empty($block->lines)) {
$this->blockLines($block);
}
if (!empty($block->children)) {
if (! empty($block->children)) {
$this->blockChildren($block);
}
if (!empty($block->selectors)) {
if (! empty($block->selectors)) {
$this->indentLevel--;
if (empty($block->children)) {
echo $this->break;
$this->write($this->break);
}
echo $pre . $this->close . $this->break;
$this->write($pre . $this->close . $this->break);
}
}
/**
* Entry point to formatting a block
*
* @api
*
* @param \Leafo\ScssPhp\Formatter\OutputBlock $block An abstract syntax tree
* @param \ScssPhp\ScssPhp\Formatter\OutputBlock $block An abstract syntax tree
* @param \ScssPhp\ScssPhp\SourceMap\SourceMapGenerator|null $sourceMapGenerator Optional source map generator
*
* @return string
*/
public function format(OutputBlock $block)
public function format(OutputBlock $block, SourceMapGenerator $sourceMapGenerator = null)
{
$this->sourceMapGenerator = null;
if ($sourceMapGenerator) {
$this->currentLine = 1;
$this->currentColumn = 0;
$this->sourceMapGenerator = $sourceMapGenerator;
}
ob_start();
$this->block($block);
$out = ob_get_clean();
return $out;
}
/**
* @param string $str
*/
protected function write($str)
{
if ($this->sourceMapGenerator) {
$this->sourceMapGenerator->addMapping(
$this->currentLine,
$this->currentColumn,
$this->currentBlock->sourceLine,
//columns from parser are off by one
$this->currentBlock->sourceColumn > 0 ? $this->currentBlock->sourceColumn - 1 : 0,
$this->currentBlock->sourceName
);
$lines = explode("\n", $str);
$lineCount = count($lines);
$this->currentLine += $lineCount-1;
$lastLine = array_pop($lines);
$this->currentColumn = ($lineCount === 1 ? $this->currentColumn : 0) + strlen($lastLine);
}
echo $str;
}
}

View File

@@ -2,15 +2,17 @@
/**
* SCSSPHP
*
* @copyright 2012-2015 Leaf Corcoran
* @copyright 2012-2019 Leaf Corcoran
*
* @license http://opensource.org/licenses/MIT MIT
*
* @link http://leafo.github.io/scssphp
* @link http://scssphp.github.io/scssphp
*/
namespace Leafo\ScssPhp\Formatter;
use Leafo\ScssPhp\Formatter;
namespace ScssPhp\ScssPhp\Formatter;
use ScssPhp\ScssPhp\Formatter;
/**
* Compact formatter
*
@@ -27,13 +29,12 @@ class Compact extends Formatter
$this->indentChar = '';
$this->break = '';
$this->open = ' {';
$this->close = '}
';
$this->close = "}\n\n";
$this->tagSeparator = ',';
$this->assignSeparator = ':';
$this->keepSemicolons = true;
}
/**
* {@inheritdoc}
*/

View File

@@ -2,16 +2,18 @@
/**
* SCSSPHP
*
* @copyright 2012-2015 Leaf Corcoran
* @copyright 2012-2019 Leaf Corcoran
*
* @license http://opensource.org/licenses/MIT MIT
*
* @link http://leafo.github.io/scssphp
* @link http://scssphp.github.io/scssphp
*/
namespace Leafo\ScssPhp\Formatter;
use Leafo\ScssPhp\Formatter;
use Leafo\ScssPhp\Formatter\OutputBlock;
namespace ScssPhp\ScssPhp\Formatter;
use ScssPhp\ScssPhp\Formatter;
use ScssPhp\ScssPhp\Formatter\OutputBlock;
/**
* Compressed formatter
*
@@ -33,13 +35,16 @@ class Compressed extends Formatter
$this->assignSeparator = ':';
$this->keepSemicolons = false;
}
/**
* {@inheritdoc}
*/
public function blockLines(OutputBlock $block)
{
$inner = $this->indentStr();
$glue = $this->break . $inner;
foreach ($block->lines as $index => $line) {
if (substr($line, 0, 2) === '/*' && substr($line, 2, 1) !== '!') {
unset($block->lines[$index]);
@@ -47,9 +52,30 @@ class Compressed extends Formatter
$block->lines[$index] = '/*' . substr($line, 3);
}
}
echo $inner . implode($glue, $block->lines);
if (!empty($block->children)) {
echo $this->break;
$this->write($inner . implode($glue, $block->lines));
if (! empty($block->children)) {
$this->write($this->break);
}
}
/**
* Output block selectors
*
* @param \ScssPhp\ScssPhp\Formatter\OutputBlock $block
*/
protected function blockSelectors(OutputBlock $block)
{
$inner = $this->indentStr();
$this->write(
$inner
. implode(
$this->tagSeparator,
str_replace([' > ', ' + ', ' ~ '], ['>', '+', '~'], $block->selectors)
)
. $this->open . $this->break
);
}
}

View File

@@ -2,16 +2,18 @@
/**
* SCSSPHP
*
* @copyright 2012-2015 Leaf Corcoran
* @copyright 2012-2019 Leaf Corcoran
*
* @license http://opensource.org/licenses/MIT MIT
*
* @link http://leafo.github.io/scssphp
* @link http://scssphp.github.io/scssphp
*/
namespace Leafo\ScssPhp\Formatter;
use Leafo\ScssPhp\Formatter;
use Leafo\ScssPhp\Formatter\OutputBlock;
namespace ScssPhp\ScssPhp\Formatter;
use ScssPhp\ScssPhp\Formatter;
use ScssPhp\ScssPhp\Formatter\OutputBlock;
/**
* Crunched formatter
*
@@ -33,21 +35,45 @@ class Crunched extends Formatter
$this->assignSeparator = ':';
$this->keepSemicolons = false;
}
/**
* {@inheritdoc}
*/
public function blockLines(OutputBlock $block)
{
$inner = $this->indentStr();
$glue = $this->break . $inner;
foreach ($block->lines as $index => $line) {
if (substr($line, 0, 2) === '/*') {
unset($block->lines[$index]);
}
}
echo $inner . implode($glue, $block->lines);
if (!empty($block->children)) {
echo $this->break;
$this->write($inner . implode($glue, $block->lines));
if (! empty($block->children)) {
$this->write($this->break);
}
}
/**
* Output block selectors
*
* @param \ScssPhp\ScssPhp\Formatter\OutputBlock $block
*/
protected function blockSelectors(OutputBlock $block)
{
$inner = $this->indentStr();
$this->write(
$inner
. implode(
$this->tagSeparator,
str_replace([' > ', ' + ', ' ~ '], ['>', '+', '~'], $block->selectors)
)
. $this->open . $this->break
);
}
}

View File

@@ -2,16 +2,18 @@
/**
* SCSSPHP
*
* @copyright 2012-2015 Leaf Corcoran
* @copyright 2012-2019 Leaf Corcoran
*
* @license http://opensource.org/licenses/MIT MIT
*
* @link http://leafo.github.io/scssphp
* @link http://scssphp.github.io/scssphp
*/
namespace Leafo\ScssPhp\Formatter;
use Leafo\ScssPhp\Formatter;
use Leafo\ScssPhp\Formatter\OutputBlock;
namespace ScssPhp\ScssPhp\Formatter;
use ScssPhp\ScssPhp\Formatter;
use ScssPhp\ScssPhp\Formatter\OutputBlock;
/**
* Debug formatter
*
@@ -26,14 +28,14 @@ class Debug extends Formatter
{
$this->indentLevel = 0;
$this->indentChar = '';
$this->break = '
';
$this->break = "\n";
$this->open = ' {';
$this->close = ' }';
$this->tagSeparator = ', ';
$this->assignSeparator = ': ';
$this->keepSemicolons = true;
}
/**
* {@inheritdoc}
*/
@@ -41,57 +43,77 @@ class Debug extends Formatter
{
return str_repeat(' ', $this->indentLevel);
}
/**
* {@inheritdoc}
*/
protected function blockLines(OutputBlock $block)
{
$indent = $this->indentStr();
if (empty($block->lines)) {
echo "{$indent}block->lines: []\n";
$this->write("{$indent}block->lines: []\n");
return;
}
foreach ($block->lines as $index => $line) {
echo "{$indent}block->lines[{$index}]: {$line}\n";
$this->write("{$indent}block->lines[{$index}]: $line\n");
}
}
/**
* {@inheritdoc}
*/
protected function blockSelectors(OutputBlock $block)
{
$indent = $this->indentStr();
if (empty($block->selectors)) {
echo "{$indent}block->selectors: []\n";
$this->write("{$indent}block->selectors: []\n");
return;
}
foreach ($block->selectors as $index => $selector) {
echo "{$indent}block->selectors[{$index}]: {$selector}\n";
$this->write("{$indent}block->selectors[{$index}]: $selector\n");
}
}
/**
* {@inheritdoc}
*/
protected function blockChildren(OutputBlock $block)
{
$indent = $this->indentStr();
if (empty($block->children)) {
echo "{$indent}block->children: []\n";
$this->write("{$indent}block->children: []\n");
return;
}
$this->indentLevel++;
foreach ($block->children as $i => $child) {
$this->block($child);
}
$this->indentLevel--;
}
/**
* {@inheritdoc}
*/
protected function block(OutputBlock $block)
{
$indent = $this->indentStr();
echo "{$indent}block->type: {$block->type}\n" . "{$indent}block->depth: {$block->depth}\n";
$this->write("{$indent}block->type: {$block->type}\n" .
"{$indent}block->depth: {$block->depth}\n");
$this->currentBlock = $block;
$this->blockSelectors($block);
$this->blockLines($block);
$this->blockChildren($block);

View File

@@ -2,16 +2,18 @@
/**
* SCSSPHP
*
* @copyright 2012-2015 Leaf Corcoran
* @copyright 2012-2019 Leaf Corcoran
*
* @license http://opensource.org/licenses/MIT MIT
*
* @link http://leafo.github.io/scssphp
* @link http://scssphp.github.io/scssphp
*/
namespace Leafo\ScssPhp\Formatter;
use Leafo\ScssPhp\Formatter;
use Leafo\ScssPhp\Formatter\OutputBlock;
namespace ScssPhp\ScssPhp\Formatter;
use ScssPhp\ScssPhp\Formatter;
use ScssPhp\ScssPhp\Formatter\OutputBlock;
/**
* Expanded formatter
*
@@ -26,14 +28,14 @@ class Expanded extends Formatter
{
$this->indentLevel = 0;
$this->indentChar = ' ';
$this->break = '
';
$this->break = "\n";
$this->open = ' {';
$this->close = '}';
$this->tagSeparator = ', ';
$this->assignSeparator = ': ';
$this->keepSemicolons = true;
}
/**
* {@inheritdoc}
*/
@@ -41,21 +43,26 @@ class Expanded extends Formatter
{
return str_repeat($this->indentChar, $this->indentLevel);
}
/**
* {@inheritdoc}
*/
protected function blockLines(OutputBlock $block)
{
$inner = $this->indentStr();
$glue = $this->break . $inner;
foreach ($block->lines as $index => $line) {
if (substr($line, 0, 2) === '/*') {
$block->lines[$index] = preg_replace('/(\\r|\\n)+/', $glue, $line);
$block->lines[$index] = preg_replace('/(\r|\n)+/', $glue, $line);
}
}
echo $inner . implode($glue, $block->lines);
if (empty($block->selectors) || !empty($block->children)) {
echo $this->break;
$this->write($inner . implode($glue, $block->lines));
if (empty($block->selectors) || ! empty($block->children)) {
$this->write($this->break);
}
}
}

View File

@@ -2,16 +2,18 @@
/**
* SCSSPHP
*
* @copyright 2012-2015 Leaf Corcoran
* @copyright 2012-2019 Leaf Corcoran
*
* @license http://opensource.org/licenses/MIT MIT
*
* @link http://leafo.github.io/scssphp
* @link http://scssphp.github.io/scssphp
*/
namespace Leafo\ScssPhp\Formatter;
use Leafo\ScssPhp\Formatter;
use Leafo\ScssPhp\Formatter\OutputBlock;
namespace ScssPhp\ScssPhp\Formatter;
use ScssPhp\ScssPhp\Formatter;
use ScssPhp\ScssPhp\Formatter\OutputBlock;
/**
* Nested formatter
*
@@ -23,6 +25,7 @@ class Nested extends Formatter
* @var integer
*/
private $depth;
/**
* {@inheritdoc}
*/
@@ -30,47 +33,58 @@ class Nested extends Formatter
{
$this->indentLevel = 0;
$this->indentChar = ' ';
$this->break = '
';
$this->break = "\n";
$this->open = ' {';
$this->close = ' }';
$this->tagSeparator = ', ';
$this->assignSeparator = ': ';
$this->keepSemicolons = true;
}
/**
* {@inheritdoc}
*/
protected function indentStr()
{
$n = $this->depth - 1;
return str_repeat($this->indentChar, max($this->indentLevel + $n, 0));
}
/**
* {@inheritdoc}
*/
protected function blockLines(OutputBlock $block)
{
$inner = $this->indentStr();
$glue = $this->break . $inner;
foreach ($block->lines as $index => $line) {
if (substr($line, 0, 2) === '/*') {
$block->lines[$index] = preg_replace('/(\\r|\\n)+/', $glue, $line);
$block->lines[$index] = preg_replace('/(\r|\n)+/', $glue, $line);
}
}
echo $inner . implode($glue, $block->lines);
if (!empty($block->children)) {
echo $this->break;
$this->write($inner . implode($glue, $block->lines));
if (! empty($block->children)) {
$this->write($this->break);
}
}
/**
* {@inheritdoc}
*/
protected function blockSelectors(OutputBlock $block)
{
$inner = $this->indentStr();
echo $inner . implode($this->tagSeparator, $block->selectors) . $this->open . $this->break;
$this->write($inner
. implode($this->tagSeparator, $block->selectors)
. $this->open . $this->break);
}
/**
* {@inheritdoc}
*/
@@ -78,17 +92,21 @@ class Nested extends Formatter
{
foreach ($block->children as $i => $child) {
$this->block($child);
if ($i < count($block->children) - 1) {
echo $this->break;
$this->write($this->break);
if (isset($block->children[$i + 1])) {
$next = $block->children[$i + 1];
if ($next->depth === max($block->depth, 1) && $child->depth >= $next->depth) {
echo $this->break;
$this->write($this->break);
}
}
}
}
}
/**
* {@inheritdoc}
*/
@@ -97,52 +115,72 @@ class Nested extends Formatter
if ($block->type === 'root') {
$this->adjustAllChildren($block);
}
if (empty($block->lines) && empty($block->children)) {
return;
}
$this->currentBlock = $block;
$this->depth = $block->depth;
if (!empty($block->selectors)) {
if (! empty($block->selectors)) {
$this->blockSelectors($block);
$this->indentLevel++;
}
if (!empty($block->lines)) {
if (! empty($block->lines)) {
$this->blockLines($block);
}
if (!empty($block->children)) {
if (! empty($block->children)) {
$this->blockChildren($block);
}
if (!empty($block->selectors)) {
if (! empty($block->selectors)) {
$this->indentLevel--;
echo $this->close;
$this->write($this->close);
}
if ($block->type === 'root') {
echo $this->break;
$this->write($this->break);
}
}
/**
* Adjust the depths of all children, depth first
*
* @param \Leafo\ScssPhp\Formatter\OutputBlock $block
* @param \ScssPhp\ScssPhp\Formatter\OutputBlock $block
*/
private function adjustAllChildren(OutputBlock $block)
{
// flatten empty nested blocks
$children = array();
$children = [];
foreach ($block->children as $i => $child) {
if (empty($child->lines) && empty($child->children)) {
if (isset($block->children[$i + 1])) {
$block->children[$i + 1]->depth = $child->depth;
}
continue;
}
$children[] = $child;
}
$count = count($children);
for ($i = 0; $i < $count; $i++) {
$depth = $children[$i]->depth;
$j = $i + 1;
if (isset($children[$j]) && $depth < $children[$j]->depth) {
$childDepth = $children[$j]->depth;
for (; $j < $count; $j++) {
if ($depth < $children[$j]->depth && $childDepth >= $children[$j]->depth) {
$children[$j]->depth = $depth + 1;
@@ -150,10 +188,13 @@ class Nested extends Formatter
}
}
}
$block->children = $children;
// make relative to parent
foreach ($block->children as $child) {
$this->adjustAllChildren($child);
$child->depth = $child->depth - $block->depth;
}
}

View File

@@ -2,13 +2,14 @@
/**
* SCSSPHP
*
* @copyright 2012-2015 Leaf Corcoran
* @copyright 2012-2019 Leaf Corcoran
*
* @license http://opensource.org/licenses/MIT MIT
*
* @link http://leafo.github.io/scssphp
* @link http://scssphp.github.io/scssphp
*/
namespace Leafo\ScssPhp\Formatter;
namespace ScssPhp\ScssPhp\Formatter;
/**
* Output block
@@ -21,24 +22,44 @@ class OutputBlock
* @var string
*/
public $type;
/**
* @var integer
*/
public $depth;
/**
* @var array
*/
public $selectors;
/**
* @var array
*/
public $lines;
/**
* @var array
*/
public $children;
/**
* @var \Leafo\ScssPhp\Formatter\OutputBlock
* @var \ScssPhp\ScssPhp\Formatter\OutputBlock
*/
public $parent;
/**
* @var string
*/
public $sourceName;
/**
* @var integer
*/
public $sourceLine;
/**
* @var integer
*/
public $sourceColumn;
}

View File

@@ -2,13 +2,14 @@
/**
* SCSSPHP
*
* @copyright 2012-2015 Leaf Corcoran
* @copyright 2012-2019 Leaf Corcoran
*
* @license http://opensource.org/licenses/MIT MIT
*
* @link http://leafo.github.io/scssphp
* @link http://scssphp.github.io/scssphp
*/
namespace Leafo\ScssPhp;
namespace ScssPhp\ScssPhp;
/**
* Base node
@@ -21,14 +22,17 @@ abstract class Node
* @var string
*/
public $type;
/**
* @var integer
*/
public $sourceIndex;
/**
* @var integer
*/
public $sourceLine;
/**
* @var integer
*/

View File

@@ -2,17 +2,19 @@
/**
* SCSSPHP
*
* @copyright 2012-2015 Leaf Corcoran
* @copyright 2012-2019 Leaf Corcoran
*
* @license http://opensource.org/licenses/MIT MIT
*
* @link http://leafo.github.io/scssphp
* @link http://scssphp.github.io/scssphp
*/
namespace Leafo\ScssPhp\Node;
use Leafo\ScssPhp\Compiler;
use Leafo\ScssPhp\Node;
use Leafo\ScssPhp\Type;
namespace ScssPhp\ScssPhp\Node;
use ScssPhp\ScssPhp\Compiler;
use ScssPhp\ScssPhp\Node;
use ScssPhp\ScssPhp\Type;
/**
* Dimension + optional units
*
@@ -29,21 +31,54 @@ class Number extends Node implements \ArrayAccess
/**
* @var integer
*/
public static $precision = 5;
static public $precision = 10;
/**
* @see http://www.w3.org/TR/2012/WD-css3-values-20120308/
*
* @var array
*/
protected static $unitTable = array('in' => array('in' => 1, 'pc' => 6, 'pt' => 72, 'px' => 96, 'cm' => 2.54, 'mm' => 25.4, 'q' => 101.6), 'turn' => array('deg' => 360, 'grad' => 400, 'rad' => 6.283185307179586, 'turn' => 1), 's' => array('s' => 1, 'ms' => 1000), 'Hz' => array('Hz' => 1, 'kHz' => 0.001), 'dpi' => array('dpi' => 1, 'dpcm' => 2.54, 'dppx' => 96));
static protected $unitTable = [
'in' => [
'in' => 1,
'pc' => 6,
'pt' => 72,
'px' => 96,
'cm' => 2.54,
'mm' => 25.4,
'q' => 101.6,
],
'turn' => [
'deg' => 360,
'grad' => 400,
'rad' => 6.28318530717958647692528676, // 2 * M_PI
'turn' => 1,
],
's' => [
's' => 1,
'ms' => 1000,
],
'Hz' => [
'Hz' => 1,
'kHz' => 0.001,
],
'dpi' => [
'dpi' => 1,
'dpcm' => 2.54,
'dppx' => 96,
],
];
/**
* @var integer|float
*/
public $dimension;
/**
* @var array
*/
public $units;
/**
* Initialize number
*
@@ -52,43 +87,54 @@ class Number extends Node implements \ArrayAccess
*/
public function __construct($dimension, $initialUnit)
{
$this->type = Type::T_NUMBER;
$this->type = Type::T_NUMBER;
$this->dimension = $dimension;
$this->units = is_array($initialUnit) ? $initialUnit : ($initialUnit ? array($initialUnit => 1) : array());
$this->units = is_array($initialUnit)
? $initialUnit
: ($initialUnit ? [$initialUnit => 1]
: []);
}
/**
* Coerce number to target units
*
* @param array $units
*
* @return \Leafo\ScssPhp\Node\Number
* @return \ScssPhp\ScssPhp\Node\Number
*/
public function coerce($units)
{
if ($this->unitless()) {
return new Number($this->dimension, $units);
}
$dimension = $this->dimension;
foreach (self::$unitTable['in'] as $unit => $conv) {
$from = isset($this->units[$unit]) ? $this->units[$unit] : 0;
$to = isset($units[$unit]) ? $units[$unit] : 0;
$factor = pow($conv, $from - $to);
foreach (static::$unitTable['in'] as $unit => $conv) {
$from = isset($this->units[$unit]) ? $this->units[$unit] : 0;
$to = isset($units[$unit]) ? $units[$unit] : 0;
$factor = pow($conv, $from - $to);
$dimension /= $factor;
}
return new Number($dimension, $units);
}
/**
* Normalize number
*
* @return \Leafo\ScssPhp\Node\Number
* @return \ScssPhp\ScssPhp\Node\Number
*/
public function normalize()
{
$dimension = $this->dimension;
$units = array();
$units = [];
$this->normalizeUnits($dimension, $units, 'in');
return new Number($dimension, $units);
}
/**
* {@inheritdoc}
*/
@@ -97,14 +143,22 @@ class Number extends Node implements \ArrayAccess
if ($offset === -3) {
return $this->sourceColumn !== null;
}
if ($offset === -2) {
return $this->sourceLine !== null;
}
if ($offset === -1 || $offset === 0 || $offset === 1 || $offset === 2) {
if ($offset === -1
|| $offset === 0
|| $offset === 1
|| $offset === 2
) {
return true;
}
return false;
}
/**
* {@inheritdoc}
*/
@@ -113,18 +167,24 @@ class Number extends Node implements \ArrayAccess
switch ($offset) {
case -3:
return $this->sourceColumn;
case -2:
return $this->sourceLine;
case -1:
return $this->sourceIndex;
case 0:
return $this->type;
case 1:
return $this->dimension;
case 2:
return $this->units;
}
}
/**
* {@inheritdoc}
*/
@@ -142,6 +202,7 @@ class Number extends Node implements \ArrayAccess
$this->sourceColumn = $value;
}
}
/**
* {@inheritdoc}
*/
@@ -159,6 +220,7 @@ class Number extends Node implements \ArrayAccess
$this->sourceColumn = null;
}
}
/**
* Returns true if the number is unitless
*
@@ -166,8 +228,9 @@ class Number extends Node implements \ArrayAccess
*/
public function unitless()
{
return !array_sum($this->units);
return ! array_sum($this->units);
}
/**
* Returns unit(s) as the product of numerator units divided by the product of denominator units
*
@@ -175,50 +238,64 @@ class Number extends Node implements \ArrayAccess
*/
public function unitStr()
{
$numerators = array();
$denominators = array();
$numerators = [];
$denominators = [];
foreach ($this->units as $unit => $unitSize) {
if ($unitSize > 0) {
$numerators = array_pad($numerators, count($numerators) + $unitSize, $unit);
continue;
}
if ($unitSize < 0) {
$denominators = array_pad($denominators, count($denominators) + $unitSize, $unit);
continue;
}
}
return implode('*', $numerators) . (count($denominators) ? '/' . implode('*', $denominators) : '');
}
/**
* Output number
*
* @param \Leafo\ScssPhp\Compiler $compiler
* @param \ScssPhp\ScssPhp\Compiler $compiler
*
* @return string
*/
public function output(Compiler $compiler = null)
{
$dimension = round($this->dimension, self::$precision);
$dimension = round($this->dimension, static::$precision);
$units = array_filter($this->units, function ($unitSize) {
return $unitSize;
});
if (count($units) > 1 && array_sum($units) === 0) {
$dimension = $this->dimension;
$units = array();
$units = [];
$this->normalizeUnits($dimension, $units, 'in');
$dimension = round($dimension, self::$precision);
$units = array_filter($units, function ($unitSize) {
$dimension = round($dimension, static::$precision);
$units = array_filter($units, function ($unitSize) {
return $unitSize;
});
}
$unitSize = array_sum($units);
if ($compiler && ($unitSize > 1 || $unitSize < 0 || count($units) > 1)) {
$compiler->throwError((string) $dimension . $this->unitStr() . ' isn\'t a valid CSS value.');
$compiler->throwError((string) $dimension . $this->unitStr() . " isn't a valid CSS value.");
}
reset($units);
list($unit, ) = each($units);
return (string) $dimension . $unit;
$unit = key($units);
$dimension = number_format($dimension, static::$precision, '.', '');
return (static::$precision ? rtrim(rtrim($dimension, '0'), '.') : $dimension) . $unit;
}
/**
* {@inheritdoc}
*/
@@ -226,6 +303,7 @@ class Number extends Node implements \ArrayAccess
{
return $this->output();
}
/**
* Normalize units
*
@@ -236,13 +314,16 @@ class Number extends Node implements \ArrayAccess
private function normalizeUnits(&$dimension, &$units, $baseUnit = 'in')
{
$dimension = $this->dimension;
$units = array();
$units = [];
foreach ($this->units as $unit => $exp) {
if (isset(self::$unitTable[$baseUnit][$unit])) {
$factor = pow(self::$unitTable[$baseUnit][$unit], $exp);
if (isset(static::$unitTable[$baseUnit][$unit])) {
$factor = pow(static::$unitTable[$baseUnit][$unit], $exp);
$unit = $baseUnit;
$dimension /= $factor;
}
$units[$unit] = $exp + (isset($units[$unit]) ? $units[$unit] : 0);
}
}

Binary file not shown.

View File

@@ -1,364 +0,0 @@
<?php
/**
* SCSSPHP
*
* @copyright 2012-2015 Leaf Corcoran
*
* @license http://opensource.org/licenses/MIT MIT
*
* @link http://leafo.github.io/scssphp
*/
namespace Leafo\ScssPhp;
use Leafo\ScssPhp\Compiler;
use Leafo\ScssPhp\Exception\ServerException;
use Leafo\ScssPhp\Version;
/**
* Server
*
* @author Leaf Corcoran <leafot@gmail.com>
*/
class Server
{
/**
* @var boolean
*/
private $showErrorsAsCSS;
/**
* @var string
*/
private $dir;
/**
* @var string
*/
private $cacheDir;
/**
* @var \Leafo\ScssPhp\Compiler
*/
private $scss;
/**
* Join path components
*
* @param string $left Path component, left of the directory separator
* @param string $right Path component, right of the directory separator
*
* @return string
*/
protected function join($left, $right)
{
return rtrim($left, '/\\') . DIRECTORY_SEPARATOR . ltrim($right, '/\\');
}
/**
* Get name of requested .scss file
*
* @return string|null
*/
protected function inputName()
{
switch (true) {
case isset($_GET['p']):
return $_GET['p'];
case isset($_SERVER['PATH_INFO']):
return $_SERVER['PATH_INFO'];
case isset($_SERVER['DOCUMENT_URI']):
return substr($_SERVER['DOCUMENT_URI'], strlen($_SERVER['SCRIPT_NAME']));
}
}
/**
* Get path to requested .scss file
*
* @return string
*/
protected function findInput()
{
if (($input = $this->inputName()) && strpos($input, '..') === false && substr($input, -5) === '.scss') {
$name = $this->join($this->dir, $input);
if (is_file($name) && is_readable($name)) {
return $name;
}
}
return false;
}
/**
* Get path to cached .css file
*
* @return string
*/
protected function cacheName($fname)
{
return $this->join($this->cacheDir, md5($fname) . '.css');
}
/**
* Get path to meta data
*
* @return string
*/
protected function metadataName($out)
{
return $out . '.meta';
}
/**
* Determine whether .scss file needs to be re-compiled.
*
* @param string $out Output path
* @param string $etag ETag
*
* @return boolean True if compile required.
*/
protected function needsCompile($out, &$etag)
{
if (!is_file($out)) {
return true;
}
$mtime = filemtime($out);
$metadataName = $this->metadataName($out);
if (is_readable($metadataName)) {
$metadata = unserialize(file_get_contents($metadataName));
foreach ($metadata['imports'] as $import => $originalMtime) {
$currentMtime = filemtime($import);
if ($currentMtime !== $originalMtime || $currentMtime > $mtime) {
return true;
}
}
$metaVars = crc32(serialize($this->scss->getVariables()));
if ($metaVars !== $metadata['vars']) {
return true;
}
$etag = $metadata['etag'];
return false;
}
return true;
}
/**
* Get If-Modified-Since header from client request
*
* @return string|null
*/
protected function getIfModifiedSinceHeader()
{
$modifiedSince = null;
if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])) {
$modifiedSince = $_SERVER['HTTP_IF_MODIFIED_SINCE'];
if (false !== ($semicolonPos = strpos($modifiedSince, ';'))) {
$modifiedSince = substr($modifiedSince, 0, $semicolonPos);
}
}
return $modifiedSince;
}
/**
* Get If-None-Match header from client request
*
* @return string|null
*/
protected function getIfNoneMatchHeader()
{
$noneMatch = null;
if (isset($_SERVER['HTTP_IF_NONE_MATCH'])) {
$noneMatch = $_SERVER['HTTP_IF_NONE_MATCH'];
}
return $noneMatch;
}
/**
* Compile .scss file
*
* @param string $in Input path (.scss)
* @param string $out Output path (.css)
*
* @return array
*/
protected function compile($in, $out)
{
$start = microtime(true);
$css = $this->scss->compile(file_get_contents($in), $in);
$elapsed = round(microtime(true) - $start, 4);
$v = Version::VERSION;
$t = date('r');
$css = "/* compiled by scssphp {$v} on {$t} ({$elapsed}s) */\n\n" . $css;
$etag = md5($css);
file_put_contents($out, $css);
file_put_contents($this->metadataName($out), serialize(array('etag' => $etag, 'imports' => $this->scss->getParsedFiles(), 'vars' => crc32(serialize($this->scss->getVariables())))));
return array($css, $etag);
}
/**
* Format error as a pseudo-element in CSS
*
* @param \Exception $error
*
* @return string
*/
protected function createErrorCSS(\Exception $error)
{
$message = str_replace(array('\'', '
'), array('\\\'', '\\A'), $error->getfile() . ':
' . $error->getMessage());
return "body { display: none !important; }\n html:after {\n background: white;\n color: black;\n content: '{$message}';\n display: block !important;\n font-family: mono;\n padding: 1em;\n white-space: pre;\n }";
}
/**
* Render errors as a pseudo-element within valid CSS, displaying the errors on any
* page that includes this CSS.
*
* @param boolean $show
*/
public function showErrorsAsCSS($show = true)
{
$this->showErrorsAsCSS = $show;
}
/**
* Compile .scss file
*
* @param string $in Input file (.scss)
* @param string $out Output file (.css) optional
*
* @return string|bool
*
* @throws \Leafo\ScssPhp\Exception\ServerException
*/
public function compileFile($in, $out = null)
{
if (!is_readable($in)) {
throw new ServerException('load error: failed to find ' . $in);
}
$pi = pathinfo($in);
$this->scss->addImportPath($pi['dirname'] . '/');
$compiled = $this->scss->compile(file_get_contents($in), $in);
if ($out !== null) {
return file_put_contents($out, $compiled);
}
return $compiled;
}
/**
* Check if file need compiling
*
* @param string $in Input file (.scss)
* @param string $out Output file (.css)
*
* @return bool
*/
public function checkedCompile($in, $out)
{
if (!is_file($out) || filemtime($in) > filemtime($out)) {
$this->compileFile($in, $out);
return true;
}
return false;
}
/**
* Compile requested scss and serve css. Outputs HTTP response.
*
* @param string $salt Prefix a string to the filename for creating the cache name hash
*/
public function serve($salt = '')
{
$protocol = isset($_SERVER['SERVER_PROTOCOL']) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0';
if ($input = $this->findInput()) {
$output = $this->cacheName($salt . $input);
$etag = $noneMatch = trim($this->getIfNoneMatchHeader(), '"');
if ($this->needsCompile($output, $etag)) {
try {
list($css, $etag) = $this->compile($input, $output);
$lastModified = gmdate('D, d M Y H:i:s', filemtime($output)) . ' GMT';
header('Last-Modified: ' . $lastModified);
header('Content-type: text/css');
header('ETag: "' . $etag . '"');
echo $css;
} catch (\Exception $e) {
if ($this->showErrorsAsCSS) {
header('Content-type: text/css');
echo $this->createErrorCSS($e);
} else {
header($protocol . ' 500 Internal Server Error');
header('Content-type: text/plain');
echo 'Parse error: ' . $e->getMessage() . '
';
}
}
return;
}
header('X-SCSS-Cache: true');
header('Content-type: text/css');
header('ETag: "' . $etag . '"');
if ($etag === $noneMatch) {
header($protocol . ' 304 Not Modified');
return;
}
$modifiedSince = $this->getIfModifiedSinceHeader();
$mtime = filemtime($output);
if (strtotime($modifiedSince) === $mtime) {
header($protocol . ' 304 Not Modified');
return;
}
$lastModified = gmdate('D, d M Y H:i:s', $mtime) . ' GMT';
header('Last-Modified: ' . $lastModified);
echo file_get_contents($output);
return;
}
header($protocol . ' 404 Not Found');
header('Content-type: text/plain');
$v = Version::VERSION;
echo "/* INPUT NOT FOUND scss {$v} */\n";
}
/**
* Based on explicit input/output files does a full change check on cache before compiling.
*
* @param string $in
* @param string $out
* @param boolean $force
*
* @return string Compiled CSS results
*
* @throws \Leafo\ScssPhp\Exception\ServerException
*/
public function checkedCachedCompile($in, $out, $force = false)
{
if (!is_file($in) || !is_readable($in)) {
throw new ServerException('Invalid or unreadable input file specified.');
}
if (is_dir($out) || !is_writable(file_exists($out) ? $out : dirname($out))) {
throw new ServerException('Invalid or unwritable output file specified.');
}
if ($force || $this->needsCompile($out, $etag)) {
list($css, $etag) = $this->compile($in, $out);
} else {
$css = file_get_contents($out);
}
return $css;
}
/**
* Constructor
*
* @param string $dir Root directory to .scss files
* @param string $cacheDir Cache directory
* @param \Leafo\ScssPhp\Compiler|null $scss SCSS compiler instance
*/
public function __construct($dir, $cacheDir = null, $scss = null)
{
$this->dir = $dir;
if (!isset($cacheDir)) {
$cacheDir = $this->join($dir, 'scss_cache');
}
$this->cacheDir = $cacheDir;
if (!is_dir($this->cacheDir)) {
mkdir($this->cacheDir, 493, true);
}
if (!isset($scss)) {
$scss = new Compiler();
$scss->setImportPaths($this->dir);
}
$this->scss = $scss;
$this->showErrorsAsCSS = false;
if (!ini_get('date.timezone')) {
date_default_timezone_set('UTC');
}
}
/**
* Helper method to serve compiled scss
*
* @param string $path Root path
*/
public static function serveFrom($path)
{
$server = new self($path);
$server->serve();
}
}

View File

@@ -2,13 +2,14 @@
/**
* SCSSPHP
*
* @copyright 2012-2015 Leaf Corcoran
* @copyright 2012-2019 Leaf Corcoran
*
* @license http://opensource.org/licenses/MIT MIT
*
* @link http://leafo.github.io/scssphp
* @link http://scssphp.github.io/scssphp
*/
namespace Leafo\ScssPhp;
namespace ScssPhp\ScssPhp;
/**
* Block/node types

View File

@@ -2,17 +2,20 @@
/**
* SCSSPHP
*
* @copyright 2012-2015 Leaf Corcoran
* @copyright 2012-2019 Leaf Corcoran
*
* @license http://opensource.org/licenses/MIT MIT
*
* @link http://leafo.github.io/scssphp
* @link http://scssphp.github.io/scssphp
*/
namespace Leafo\ScssPhp;
use Leafo\ScssPhp\Base\Range;
namespace ScssPhp\ScssPhp;
use ScssPhp\ScssPhp\Base\Range;
use ScssPhp\ScssPhp\Exception\RangeException;
/**
* Utilties
* Utilty functions
*
* @author Anthon Pang <anthon.pang@gmail.com>
*/
@@ -22,28 +25,46 @@ class Util
* Asserts that `value` falls within `range` (inclusive), leaving
* room for slight floating-point errors.
*
* @param string $name The name of the value. Used in the error message.
* @param Range $range Range of values.
* @param array $value The value to check.
* @param string $unit The unit of the value. Used in error reporting.
* @param string $name The name of the value. Used in the error message.
* @param \ScssPhp\ScssPhp\Base\Range $range Range of values.
* @param array $value The value to check.
* @param string $unit The unit of the value. Used in error reporting.
*
* @return mixed `value` adjusted to fall within range, if it was outside by a floating-point margin.
*
* @throws \Exception
* @throws \ScssPhp\ScssPhp\Exception\RangeException
*/
public static function checkRange($name, Range $range, $value, $unit = '')
{
$val = $value[1];
$grace = new Range(-1.0E-5, 1.0E-5);
$grace = new Range(-0.00001, 0.00001);
if ($range->includes($val)) {
return $val;
}
if ($grace->includes($val - $range->first)) {
return $range->first;
}
if ($grace->includes($val - $range->last)) {
return $range->last;
}
throw new \Exception("{$name} {$val} must be between {$range->first} and {$range->last}{$unit}");
throw new RangeException("$name {$val} must be between {$range->first} and {$range->last}$unit");
}
/**
* Encode URI component
*
* @param string $string
*
* @return string
*/
public static function encodeURIComponent($string)
{
$revert = ['%21' => '!', '%2A' => '*', '%27' => "'", '%28' => '(', '%29' => ')'];
return strtr(rawurlencode($string), $revert);
}
}

View File

@@ -2,13 +2,14 @@
/**
* SCSSPHP
*
* @copyright 2012-2015 Leaf Corcoran
* @copyright 2012-2019 Leaf Corcoran
*
* @license http://opensource.org/licenses/MIT MIT
*
* @link http://leafo.github.io/scssphp
* @link http://scssphp.github.io/scssphp
*/
namespace Leafo\ScssPhp;
namespace ScssPhp\ScssPhp;
/**
* SCSSPHP version
@@ -17,5 +18,5 @@ namespace Leafo\ScssPhp;
*/
class Version
{
const VERSION = 'v0.6.3';
const VERSION = 'v1.0.0';
}

View File

@@ -2425,7 +2425,7 @@ END OF TERMS AND CONDITIONS
<product>scssphp</product>
<author>Leaf Corcoran</author>
<license_type>MIT</license_type>
<text><![CDATA[<pre>Copyright (c) 2015 Leaf Corcoran, http://leafo.github.io/scssphp
<text><![CDATA[<pre>Copyright (c) 2015 Leaf Corcoran, http://scssphp.github.io/scssphp
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
@@ -2558,4 +2558,4 @@ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
END OF TERMS AND CONDITIONS
</pre>]]></text>
</license>
</licenses>
</licenses>