aboutsummaryrefslogtreecommitdiffstats
path: root/vendor/scssphp/scssphp/src/SourceMap
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/scssphp/scssphp/src/SourceMap')
-rw-r--r--vendor/scssphp/scssphp/src/SourceMap/Base64.php187
-rw-r--r--vendor/scssphp/scssphp/src/SourceMap/Base64VLQ.php151
-rw-r--r--vendor/scssphp/scssphp/src/SourceMap/SourceMapGenerator.php390
3 files changed, 728 insertions, 0 deletions
diff --git a/vendor/scssphp/scssphp/src/SourceMap/Base64.php b/vendor/scssphp/scssphp/src/SourceMap/Base64.php
new file mode 100644
index 000000000..00b6b4545
--- /dev/null
+++ b/vendor/scssphp/scssphp/src/SourceMap/Base64.php
@@ -0,0 +1,187 @@
+<?php
+
+/**
+ * SCSSPHP
+ *
+ * @copyright 2012-2020 Leaf Corcoran
+ *
+ * @license http://opensource.org/licenses/MIT MIT
+ *
+ * @link http://scssphp.github.io/scssphp
+ */
+
+namespace ScssPhp\ScssPhp\SourceMap;
+
+/**
+ * Base 64 Encode/Decode
+ *
+ * @author Anthon Pang <anthon.pang@gmail.com>
+ *
+ * @internal
+ */
+class Base64
+{
+ /**
+ * @var array<int, string>
+ */
+ private static $encodingMap = [
+ 0 => 'A',
+ 1 => 'B',
+ 2 => 'C',
+ 3 => 'D',
+ 4 => 'E',
+ 5 => 'F',
+ 6 => 'G',
+ 7 => 'H',
+ 8 => 'I',
+ 9 => 'J',
+ 10 => 'K',
+ 11 => 'L',
+ 12 => 'M',
+ 13 => 'N',
+ 14 => 'O',
+ 15 => 'P',
+ 16 => 'Q',
+ 17 => 'R',
+ 18 => 'S',
+ 19 => 'T',
+ 20 => 'U',
+ 21 => 'V',
+ 22 => 'W',
+ 23 => 'X',
+ 24 => 'Y',
+ 25 => 'Z',
+ 26 => 'a',
+ 27 => 'b',
+ 28 => 'c',
+ 29 => 'd',
+ 30 => 'e',
+ 31 => 'f',
+ 32 => 'g',
+ 33 => 'h',
+ 34 => 'i',
+ 35 => 'j',
+ 36 => 'k',
+ 37 => 'l',
+ 38 => 'm',
+ 39 => 'n',
+ 40 => 'o',
+ 41 => 'p',
+ 42 => 'q',
+ 43 => 'r',
+ 44 => 's',
+ 45 => 't',
+ 46 => 'u',
+ 47 => 'v',
+ 48 => 'w',
+ 49 => 'x',
+ 50 => 'y',
+ 51 => 'z',
+ 52 => '0',
+ 53 => '1',
+ 54 => '2',
+ 55 => '3',
+ 56 => '4',
+ 57 => '5',
+ 58 => '6',
+ 59 => '7',
+ 60 => '8',
+ 61 => '9',
+ 62 => '+',
+ 63 => '/',
+ ];
+
+ /**
+ * @var array<string|int, int>
+ */
+ private static $decodingMap = [
+ 'A' => 0,
+ 'B' => 1,
+ 'C' => 2,
+ 'D' => 3,
+ 'E' => 4,
+ 'F' => 5,
+ 'G' => 6,
+ 'H' => 7,
+ 'I' => 8,
+ 'J' => 9,
+ 'K' => 10,
+ 'L' => 11,
+ 'M' => 12,
+ 'N' => 13,
+ 'O' => 14,
+ 'P' => 15,
+ 'Q' => 16,
+ 'R' => 17,
+ 'S' => 18,
+ 'T' => 19,
+ 'U' => 20,
+ 'V' => 21,
+ 'W' => 22,
+ 'X' => 23,
+ 'Y' => 24,
+ 'Z' => 25,
+ 'a' => 26,
+ 'b' => 27,
+ 'c' => 28,
+ 'd' => 29,
+ 'e' => 30,
+ 'f' => 31,
+ 'g' => 32,
+ 'h' => 33,
+ 'i' => 34,
+ 'j' => 35,
+ 'k' => 36,
+ 'l' => 37,
+ 'm' => 38,
+ 'n' => 39,
+ 'o' => 40,
+ 'p' => 41,
+ 'q' => 42,
+ 'r' => 43,
+ 's' => 44,
+ 't' => 45,
+ 'u' => 46,
+ 'v' => 47,
+ 'w' => 48,
+ 'x' => 49,
+ 'y' => 50,
+ 'z' => 51,
+ 0 => 52,
+ 1 => 53,
+ 2 => 54,
+ 3 => 55,
+ 4 => 56,
+ 5 => 57,
+ 6 => 58,
+ 7 => 59,
+ 8 => 60,
+ 9 => 61,
+ '+' => 62,
+ '/' => 63,
+ ];
+
+ /**
+ * Convert to base64
+ *
+ * @param int $value
+ *
+ * @return string
+ */
+ public static function encode($value)
+ {
+ return self::$encodingMap[$value];
+ }
+
+ /**
+ * Convert from base64
+ *
+ * @param string $value
+ *
+ * @return int
+ */
+ public static function decode($value)
+ {
+ return self::$decodingMap[$value];
+ }
+}
diff --git a/vendor/scssphp/scssphp/src/SourceMap/Base64VLQ.php b/vendor/scssphp/scssphp/src/SourceMap/Base64VLQ.php
new file mode 100644
index 000000000..2a5210c68
--- /dev/null
+++ b/vendor/scssphp/scssphp/src/SourceMap/Base64VLQ.php
@@ -0,0 +1,151 @@
+<?php
+
+/**
+ * SCSSPHP
+ *
+ * @copyright 2012-2020 Leaf Corcoran
+ *
+ * @license http://opensource.org/licenses/MIT MIT
+ *
+ * @link http://scssphp.github.io/scssphp
+ */
+
+namespace ScssPhp\ScssPhp\SourceMap;
+
+/**
+ * Base 64 VLQ
+ *
+ * Based on the Base 64 VLQ implementation in Closure Compiler:
+ * https://github.com/google/closure-compiler/blob/master/src/com/google/debugging/sourcemap/Base64VLQ.java
+ *
+ * Copyright 2011 The Closure Compiler Authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @author John Lenz <johnlenz@google.com>
+ * @author Anthon Pang <anthon.pang@gmail.com>
+ *
+ * @internal
+ */
+class Base64VLQ
+{
+ // A Base64 VLQ digit can represent 5 bits, so it is base-32.
+ const VLQ_BASE_SHIFT = 5;
+
+ // A mask of bits for a VLQ digit (11111), 31 decimal.
+ const VLQ_BASE_MASK = 31;
+
+ // The continuation bit is the 6th bit.
+ const VLQ_CONTINUATION_BIT = 32;
+
+ /**
+ * Returns the VLQ encoded value.
+ *
+ * @param int $value
+ *
+ * @return string
+ */
+ public static function encode($value)
+ {
+ $encoded = '';
+ $vlq = self::toVLQSigned($value);
+
+ do {
+ $digit = $vlq & self::VLQ_BASE_MASK;
+
+ //$vlq >>>= self::VLQ_BASE_SHIFT; // unsigned right shift
+ $vlq = (($vlq >> 1) & PHP_INT_MAX) >> (self::VLQ_BASE_SHIFT - 1);
+
+ if ($vlq > 0) {
+ $digit |= self::VLQ_CONTINUATION_BIT;
+ }
+
+ $encoded .= Base64::encode($digit);
+ } while ($vlq > 0);
+
+ return $encoded;
+ }
+
+ /**
+ * Decodes VLQValue.
+ *
+ * @param string $str
+ * @param int $index
+ *
+ * @return int
+ */
+ public static function decode($str, &$index)
+ {
+ $result = 0;
+ $shift = 0;
+
+ do {
+ $c = $str[$index++];
+ $digit = Base64::decode($c);
+ $continuation = ($digit & self::VLQ_CONTINUATION_BIT) != 0;
+ $digit &= self::VLQ_BASE_MASK;
+ $result = $result + ($digit << $shift);
+ $shift = $shift + self::VLQ_BASE_SHIFT;
+ } while ($continuation);
+
+ return self::fromVLQSigned($result);
+ }
+
+ /**
+ * Converts from a two-complement value to a value where the sign bit is
+ * is placed in the least significant bit. For example, as decimals:
+ * 1 becomes 2 (10 binary), -1 becomes 3 (11 binary)
+ * 2 becomes 4 (100 binary), -2 becomes 5 (101 binary)
+ *
+ * @param int $value
+ *
+ * @return int
+ */
+ private static function toVLQSigned($value)
+ {
+ if ($value < 0) {
+ return ((-$value) << 1) + 1;
+ }
+
+ return ($value << 1) + 0;
+ }
+
+ /**
+ * Converts to a two-complement value from a value where the sign bit is
+ * is placed in the least significant bit. For example, as decimals:
+ * 2 (10 binary) becomes 1, 3 (11 binary) becomes -1
+ * 4 (100 binary) becomes 2, 5 (101 binary) becomes -2
+ *
+ * @param int $value
+ *
+ * @return int
+ */
+ private static function fromVLQSigned($value)
+ {
+ $negate = ($value & 1) === 1;
+
+ //$value >>>= 1; // unsigned right shift
+ $value = ($value >> 1) & PHP_INT_MAX;
+
+ if (! $negate) {
+ return $value;
+ }
+
+ // We need to OR 0x80000000 here to ensure the 32nd bit (the sign bit) is
+ // always set for negative numbers. If `value` were 1, (meaning `negate` is
+ // true and all other bits were zeros), `value` would now be 0. -0 is just
+ // 0, and doesn't flip the 32nd bit as intended. All positive numbers will
+ // successfully flip the 32nd bit without issue, so it's a noop for them.
+ return -$value | 0x80000000;
+ }
+}
diff --git a/vendor/scssphp/scssphp/src/SourceMap/SourceMapGenerator.php b/vendor/scssphp/scssphp/src/SourceMap/SourceMapGenerator.php
new file mode 100644
index 000000000..ccd4f0261
--- /dev/null
+++ b/vendor/scssphp/scssphp/src/SourceMap/SourceMapGenerator.php
@@ -0,0 +1,390 @@
+<?php
+
+/**
+ * SCSSPHP
+ *
+ * @copyright 2012-2020 Leaf Corcoran
+ *
+ * @license http://opensource.org/licenses/MIT MIT
+ *
+ * @link http://scssphp.github.io/scssphp
+ */
+
+namespace ScssPhp\ScssPhp\SourceMap;
+
+use ScssPhp\ScssPhp\Exception\CompilerException;
+
+/**
+ * Source Map Generator
+ *
+ * {@internal Derivative of oyejorge/less.php's lib/SourceMap/Generator.php, relicensed with permission. }}
+ *
+ * @author Josh Schmidt <oyejorge@gmail.com>
+ * @author Nicolas FRANÇOIS <nicolas.francois@frog-labs.com>
+ *
+ * @internal
+ */
+class SourceMapGenerator
+{
+ /**
+ * What version of source map does the generator generate?
+ */
+ const VERSION = 3;
+
+ /**
+ * Array of default options
+ *
+ * @var array
+ * @phpstan-var array{sourceRoot: string, sourceMapFilename: string|null, sourceMapURL: string|null, sourceMapWriteTo: string|null, outputSourceFiles: bool, sourceMapRootpath: string, sourceMapBasepath: string}
+ */
+ protected $defaultOptions = [
+ // an optional source root, useful for relocating source files
+ // on a server or removing repeated values in the 'sources' entry.
+ // This value is prepended to the individual entries in the 'source' field.
+ 'sourceRoot' => '',
+
+ // an optional name of the generated code that this source map is associated with.
+ 'sourceMapFilename' => null,
+
+ // url of the map
+ 'sourceMapURL' => null,
+
+ // absolute path to a file to write the map to
+ 'sourceMapWriteTo' => null,
+
+ // output source contents?
+ 'outputSourceFiles' => false,
+
+ // base path for filename normalization
+ 'sourceMapRootpath' => '',
+
+ // base path for filename normalization
+ 'sourceMapBasepath' => ''
+ ];
+
+ /**
+ * The base64 VLQ encoder
+ *
+ * @var \ScssPhp\ScssPhp\SourceMap\Base64VLQ
+ */
+ protected $encoder;
+
+ /**
+ * Array of mappings
+ *
+ * @var array
+ * @phpstan-var list<array{generated_line: int, generated_column: int, original_line: int, original_column: int, source_file: string}>
+ */
+ protected $mappings = [];
+
+ /**
+ * Array of contents map
+ *
+ * @var array
+ */
+ protected $contentsMap = [];
+
+ /**
+ * File to content map
+ *
+ * @var array<string, string>
+ */
+ protected $sources = [];
+
+ /**
+ * @var array<string, int>
+ */
+ protected $sourceKeys = [];
+
+ /**
+ * @var array
+ * @phpstan-var array{sourceRoot: string, sourceMapFilename: string|null, sourceMapURL: string|null, sourceMapWriteTo: string|null, outputSourceFiles: bool, sourceMapRootpath: string, sourceMapBasepath: string}
+ */
+ private $options;
+
+ /**
+ * @phpstan-param array{sourceRoot?: string, sourceMapFilename?: string|null, sourceMapURL?: string|null, sourceMapWriteTo?: string|null, outputSourceFiles?: bool, sourceMapRootpath?: string, sourceMapBasepath?: string} $options
+ */
+ public function __construct(array $options = [])
+ {
+ $this->options = array_replace($this->defaultOptions, $options);
+ $this->encoder = new Base64VLQ();
+ }
+
+ /**
+ * Adds a mapping
+ *
+ * @param int $generatedLine The line number in generated file
+ * @param int $generatedColumn The column number in generated file
+ * @param int $originalLine The line number in original file
+ * @param int $originalColumn The column number in original file
+ * @param string $sourceFile The original source file
+ *
+ * @return void
+ */
+ public function addMapping($generatedLine, $generatedColumn, $originalLine, $originalColumn, $sourceFile)
+ {
+ $this->mappings[] = [
+ 'generated_line' => $generatedLine,
+ 'generated_column' => $generatedColumn,
+ 'original_line' => $originalLine,
+ 'original_column' => $originalColumn,
+ 'source_file' => $sourceFile
+ ];
+
+ $this->sources[$sourceFile] = $sourceFile;
+ }
+
+ /**
+ * Saves the source map to a file
+ *
+ * @param string $content The content to write
+ *
+ * @return string|null
+ *
+ * @throws \ScssPhp\ScssPhp\Exception\CompilerException If the file could not be saved
+ * @deprecated
+ */
+ public function saveMap($content)
+ {
+ $file = $this->options['sourceMapWriteTo'];
+ assert($file !== null);
+ $dir = \dirname($file);
+
+ // directory does not exist
+ if (! is_dir($dir)) {
+ // FIXME: create the dir automatically?
+ throw new CompilerException(
+ sprintf('The directory "%s" does not exist. Cannot save the source map.', $dir)
+ );
+ }
+
+ // FIXME: proper saving, with dir write check!
+ if (file_put_contents($file, $content) === false) {
+ throw new CompilerException(sprintf('Cannot save the source map to "%s"', $file));
+ }
+
+ return $this->options['sourceMapURL'];
+ }
+
+ /**
+ * Generates the JSON source map
+ *
+ * @param string $prefix A prefix added in the output file, which needs to shift mappings
+ *
+ * @return string
+ *
+ * @see https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit#
+ */
+ public function generateJson($prefix = '')
+ {
+ $sourceMap = [];
+ $mappings = $this->generateMappings($prefix);
+
+ // File version (always the first entry in the object) and must be a positive integer.
+ $sourceMap['version'] = self::VERSION;
+
+ // An optional name of the generated code that this source map is associated with.
+ $file = $this->options['sourceMapFilename'];
+
+ if ($file) {
+ $sourceMap['file'] = $file;
+ }
+
+ // An optional source root, useful for relocating source files on a server or removing repeated values in the
+ // 'sources' entry. This value is prepended to the individual entries in the 'source' field.
+ $root = $this->options['sourceRoot'];
+
+ if ($root) {
+ $sourceMap['sourceRoot'] = $root;
+ }
+
+ // A list of original sources used by the 'mappings' entry.
+ $sourceMap['sources'] = [];
+
+ foreach ($this->sources as $sourceFilename) {
+ $sourceMap['sources'][] = $this->normalizeFilename($sourceFilename);
+ }
+
+ // A list of symbol names used by the 'mappings' entry.
+ $sourceMap['names'] = [];
+
+ // A string with the encoded mapping data.
+ $sourceMap['mappings'] = $mappings;
+
+ if ($this->options['outputSourceFiles']) {
+ // An optional list of source content, useful when the 'source' can't be hosted.
+ // The contents are listed in the same order as the sources above.
+ // 'null' may be used if some original sources should be retrieved by name.
+ $sourceMap['sourcesContent'] = $this->getSourcesContent();
+ }
+
+ // less.js compat fixes
+ if (\count($sourceMap['sources']) && empty($sourceMap['sourceRoot'])) {
+ unset($sourceMap['sourceRoot']);
+ }
+
+ $jsonSourceMap = json_encode($sourceMap, JSON_UNESCAPED_SLASHES);
+
+ if (json_last_error() !== JSON_ERROR_NONE) {
+ throw new \RuntimeException(json_last_error_msg());
+ }
+
+ assert($jsonSourceMap !== false);
+
+ return $jsonSourceMap;
+ }
+
+ /**
+ * Returns the sources contents
+ *
+ * @return string[]|null
+ */
+ protected function getSourcesContent()
+ {
+ if (empty($this->sources)) {
+ return null;
+ }
+
+ $content = [];
+
+ foreach ($this->sources as $sourceFile) {
+ $content[] = file_get_contents($sourceFile);
+ }
+
+ return $content;
+ }
+
+ /**
+ * Generates the mappings string
+ *
+ * @param string $prefix A prefix added in the output file, which needs to shift mappings
+ *
+ * @return string
+ */
+ public function generateMappings($prefix = '')
+ {
+ if (! \count($this->mappings)) {
+ return '';
+ }
+
+ $prefixLines = substr_count($prefix, "\n");
+ $lastPrefixNewLine = strrpos($prefix, "\n");
+ $lastPrefixLineStart = false === $lastPrefixNewLine ? 0 : $lastPrefixNewLine + 1;
+ $prefixColumn = strlen($prefix) - $lastPrefixLineStart;
+
+ $this->sourceKeys = array_flip(array_keys($this->sources));
+
+ // group mappings by generated line number.
+ $groupedMap = $groupedMapEncoded = [];
+
+ foreach ($this->mappings as $m) {
+ $groupedMap[$m['generated_line']][] = $m;
+ }
+
+ ksort($groupedMap);
+
+ $lastGeneratedLine = $lastOriginalIndex = $lastOriginalLine = $lastOriginalColumn = 0;
+
+ foreach ($groupedMap as $lineNumber => $lineMap) {
+ if ($lineNumber > 1) {
+ // The prefix only impacts the column for the first line of the original output
+ $prefixColumn = 0;
+ }
+ $lineNumber += $prefixLines;
+
+ while (++$lastGeneratedLine < $lineNumber) {
+ $groupedMapEncoded[] = ';';
+ }
+
+ $lineMapEncoded = [];
+ $lastGeneratedColumn = 0;
+
+ foreach ($lineMap as $m) {
+ $generatedColumn = $m['generated_column'] + $prefixColumn;
+
+ $mapEncoded = $this->encoder->encode($generatedColumn - $lastGeneratedColumn);
+ $lastGeneratedColumn = $generatedColumn;
+
+ // find the index
+ if ($m['source_file']) {
+ $index = $this->findFileIndex($m['source_file']);
+
+ if ($index !== false) {
+ $mapEncoded .= $this->encoder->encode($index - $lastOriginalIndex);
+ $lastOriginalIndex = $index;
+ // lines are stored 0-based in SourceMap spec version 3
+ $mapEncoded .= $this->encoder->encode($m['original_line'] - 1 - $lastOriginalLine);
+ $lastOriginalLine = $m['original_line'] - 1;
+ $mapEncoded .= $this->encoder->encode($m['original_column'] - $lastOriginalColumn);
+ $lastOriginalColumn = $m['original_column'];
+ }
+ }
+
+ $lineMapEncoded[] = $mapEncoded;
+ }
+
+ $groupedMapEncoded[] = implode(',', $lineMapEncoded) . ';';
+ }
+
+ return rtrim(implode($groupedMapEncoded), ';');
+ }
+
+ /**
+ * Finds the index for the filename
+ *
+ * @param string $filename
+ *
+ * @return int|false
+ */
+ protected function findFileIndex($filename)
+ {
+ return $this->sourceKeys[$filename];
+ }
+
+ /**
+ * Normalize filename
+ *
+ * @param string $filename
+ *
+ * @return string
+ */
+ protected function normalizeFilename($filename)
+ {
+ $filename = $this->fixWindowsPath($filename);
+ $rootpath = $this->options['sourceMapRootpath'];
+ $basePath = $this->options['sourceMapBasepath'];
+
+ // "Trim" the 'sourceMapBasepath' from the output filename.
+ if (\strlen($basePath) && strpos($filename, $basePath) === 0) {
+ $filename = substr($filename, \strlen($basePath));
+ }
+
+ // Remove extra leading path separators.
+ if (strpos($filename, '\\') === 0 || strpos($filename, '/') === 0) {
+ $filename = substr($filename, 1);
+ }
+
+ return $rootpath . $filename;
+ }
+
+ /**
+ * Fix windows paths
+ *
+ * @param string $path
+ * @param bool $addEndSlash
+ *
+ * @return string
+ */
+ public function fixWindowsPath($path, $addEndSlash = false)
+ {
+ $slash = ($addEndSlash) ? '/' : '';
+
+ if (! empty($path)) {
+ $path = str_replace('\\', '/', $path);
+ $path = rtrim($path, '/') . $slash;
+ }
+
+ return $path;
+ }
+}