%PDF- %PDF-
Direktori : /home/q/g/b/qgbqkvz/www/wp-content/plugins/wp-scss/scssphp/src/Value/ |
Current File : /home/q/g/b/qgbqkvz/www/wp-content/plugins/wp-scss/scssphp/src/Value/SassString.php |
<?php /** * SCSSPHP * * @copyright 2012-2020 Leaf Corcoran * * @license http://opensource.org/licenses/MIT MIT * * @link http://scssphp.github.io/scssphp */ namespace ScssPhp\ScssPhp\Value; use ScssPhp\ScssPhp\Exception\SassScriptException; use ScssPhp\ScssPhp\Util; use ScssPhp\ScssPhp\Visitor\ValueVisitor; /** * A SassScript string. * * Strings can either be quoted or unquoted. Unquoted strings are usually CSS * identifiers, but they may contain any text. */ final class SassString extends Value { /** * The contents of the string. * * For quoted strings, this is the semantic content—any escape sequences that * were been written in the source text are resolved to their Unicode values. * For unquoted strings, though, escape sequences are preserved as literal * backslashes. * * This difference allows us to distinguish between identifiers with escapes, * such as `url\u28 http://example.com\u29`, and unquoted strings that * contain characters that aren't valid in identifiers, such as * `url(http://example.com)`. Unfortunately, it also means that we don't * consider `foo` and `f\6F\6F` the same string. * * @var string * @readonly */ private $text; /** * Whether this string has quotes. * * @var bool * @readonly */ private $quotes; public function __construct(string $text, bool $quotes = true) { $this->text = $text; $this->quotes = $quotes; } public function getText(): string { return $this->text; } public function hasQuotes(): bool { return $this->quotes; } public function getSassLength(): int { return Util::mbStrlen($this->text); } public function isSpecialNumber(): bool { if ($this->quotes) { return false; } if (\strlen($this->text) < \strlen('min(_)')) { return false; } $first = $this->text[0]; if ($first === 'c' || $first === 'C') { $second = $this->text[1]; if ($second === 'l' || $second === 'L') { return ($this->text[2] === 'a' || $this->text[2] === 'A') && ($this->text[3] === 'm' || $this->text[3] === 'M') && ($this->text[4] === 'p' || $this->text[4] === 'P') && $this->text[5] === '('; } if ($second === 'a' || $second === 'A') { return ($this->text[2] === 'l' || $this->text[2] === 'L') && ($this->text[3] === 'c' || $this->text[3] === 'C') && $this->text[4] === '('; } return false; } if ($first === 'v' || $first === 'V') { return ($this->text[1] === 'a' || $this->text[1] === 'A') && ($this->text[2] === 'r' || $this->text[2] === 'R') && $this->text[3] === '('; } if ($first === 'e' || $first === 'E') { return ($this->text[1] === 'n' || $this->text[1] === 'N') && ($this->text[2] === 'v' || $this->text[2] === 'V') && $this->text[3] === '('; } if ($first === 'm' || $first === 'M') { $second = $this->text[1]; if ($second === 'a' || $second === 'A') { return ($this->text[2] === 'x' || $this->text[2] === 'X') && $this->text[3] === '('; } if ($second === 'i' || $second === 'I') { return ($this->text[2] === 'n' || $this->text[2] === 'N') && $this->text[3] === '('; } return false; } return false; } public function isVar(): bool { if ($this->quotes) { return false; } if (\strlen($this->text) < \strlen('var(--_)')) { return false; } return ($this->text[0] === 'v' || $this->text[0] === 'V') && ($this->text[1] === 'a' || $this->text[1] === 'A') && ($this->text[2] === 'r' || $this->text[2] === 'R') && $this->text[3] === '('; } public function isBlank(): bool { return !$this->quotes && $this->text === ''; } /** * Converts $sassIndex into a PHP-style index into {@see text}. * * Sass indexes are one-based, while PHP indexes are zero-based. Sass * indexes may also be negative in order to index from the end of the string. * * In addition, Sass indices refer to Unicode code points while PHP string * indices refer to bytes. For example, the character U+1F60A, * Smiling Face With Smiling Eyes, is a single Unicode code point but is * represented in UTF-8 as several bytes (`0xF0`, `0x9F`, `0x98` and `0x8A`). So in * PHP, `substr("a😊b", 1, 1)` returns `"\xF0"`, whereas in Sass * `str-slice("a😊b", 1, 1)` returns `"😊"`. * * @throws SassScriptException if $sassIndex isn't a number, if that * number isn't an integer, or if that integer isn't a valid index for this * string. If $sassIndex came from a function argument, $name is the * argument name (without the `$`). It's used for error reporting. */ public function sassIndexToStringIndex(Value $sassIndex, ?string $name = null): int { $codepointIndex = $this->sassIndexToCodePointIndex($sassIndex, $name); if ($codepointIndex === 0) { return 0; } return \strlen(Util::mbSubstr($this->text, 0, $codepointIndex)); } /** * Converts $sassIndex into a PHP-style index into codepoints. * * This index is suitable to use with functions dealing with codepoints * (i.e. the mbstring functions). * * Sass indexes are one-based, while PHP indexes are zero-based. Sass * indexes may also be negative in order to index from the end of the string. * * See also {@see sassIndexToStringIndex}, which is an index into {@see getText} directly. * * @throws SassScriptException if $sassIndex isn't a number, if that * number isn't an integer, or if that integer isn't a valid index for this * string. If $sassIndex came from a function argument, $name is the * argument name (without the `$`). It's used for error reporting. */ public function sassIndexToCodePointIndex(Value $sassIndex, ?string $name = null): int { $index = $sassIndex->assertNumber($name)->assertInt($name); if ($index === 0) { throw SassScriptException::forArgument('String index may not be 0.', $name); } $sassLength = $this->getSassLength(); if (abs($index) > $sassLength) { throw SassScriptException::forArgument("Invalid index $sassIndex for a string with $sassLength characters.", $name); } return $index < 0 ? $sassLength + $index : $index - 1; } public function accept(ValueVisitor $visitor) { return $visitor->visitString($this); } public function assertString(?string $name = null): SassString { return $this; } public function plus(Value $other): Value { if ($other instanceof SassString) { return new SassString($this->text . $other->getText(), $this->quotes); } return new SassString($this->text . $other->toCssString(), $this->quotes); } public function equals(object $other): bool { return $other instanceof SassString && $this->text === $other->text; } }