Merge branch 'release/1.10.32'

This commit is contained in:
Andy Miller
2022-03-28 11:34:57 -06:00
29 changed files with 370 additions and 235 deletions

View File

@@ -1,3 +1,14 @@
# v1.10.32
## 03/28/2022
1. [](#new)
* Require **Grav 1.7.32**, **Form 6.0.0**, **Login 3.7.0**, **Email 3.1.6** and **Flex Objects 1.2.0**
2. [](#improved)
* List field: Support for default values other than key/value [#2255](https://github.com/getgrav/grav-plugin-admin/issues/2255)
* Added question icon to admin fields with help text [#2261](https://github.com/getgrav/grav-plugin-admin/issues/2261)
3. [](#bugfix)
* Fix nested `toggleable`: originalValue now checks with `??` instead of `is defined`
# v1.10.31
## 03/14/2022

View File

@@ -82,7 +82,6 @@ class AdminPlugin extends Plugin
{
return [
'onPluginsInitialized' => [
['autoload', 100001],
['setup', 100000],
['onPluginsInitialized', 1001]
],
@@ -176,8 +175,6 @@ class AdminPlugin extends Plugin
}
/**
* [onPluginsInitialized:100000] Composer autoload.
*
* @return ClassLoader
*/
public function autoload(): ClassLoader

View File

@@ -1,7 +1,7 @@
name: Admin Panel
slug: admin
type: plugin
version: 1.10.31
version: 1.10.32
description: Adds an advanced administration panel to manage your site
icon: empire
author:
@@ -15,11 +15,11 @@ docs: https://github.com/getgrav/grav-plugin-admin/blob/develop/README.md
license: MIT
dependencies:
- { name: grav, version: '>=1.7.31' }
- { name: form, version: '>=5.1.0' }
- { name: login, version: '>=3.6.2' }
- { name: email, version: '>=3.1.0' }
- { name: flex-objects, version: '>=1.1.0' }
- { name: grav, version: '>=1.7.32' }
- { name: form, version: '>=6.0.0' }
- { name: login, version: '>=3.7.0' }
- { name: email, version: '>=3.1.6' }
- { name: flex-objects, version: '>=1.2.0' }
form:
validation: loose

153
composer.lock generated
View File

@@ -190,16 +190,16 @@
},
{
"name": "scssphp/scssphp",
"version": "v1.10.0",
"version": "v1.10.2",
"source": {
"type": "git",
"url": "https://github.com/scssphp/scssphp.git",
"reference": "9699a52a862da4efb43985943afa17150155dd3d"
"reference": "387f4f4abf5d99f16be16314c5ab856f81c82f46"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/scssphp/scssphp/zipball/9699a52a862da4efb43985943afa17150155dd3d",
"reference": "9699a52a862da4efb43985943afa17150155dd3d",
"url": "https://api.github.com/repos/scssphp/scssphp/zipball/387f4f4abf5d99f16be16314c5ab856f81c82f46",
"reference": "387f4f4abf5d99f16be16314c5ab856f81c82f46",
"shasum": ""
},
"require": {
@@ -258,9 +258,9 @@
],
"support": {
"issues": "https://github.com/scssphp/scssphp/issues",
"source": "https://github.com/scssphp/scssphp/tree/v1.10.0"
"source": "https://github.com/scssphp/scssphp/tree/v1.10.2"
},
"time": "2022-01-06T18:16:18+00:00"
"time": "2022-03-02T21:15:09+00:00"
}
],
"packages-dev": [
@@ -506,29 +506,30 @@
},
{
"name": "doctrine/instantiator",
"version": "1.4.0",
"version": "1.4.1",
"source": {
"type": "git",
"url": "https://github.com/doctrine/instantiator.git",
"reference": "d56bf6102915de5702778fe20f2de3b2fe570b5b"
"reference": "10dcfce151b967d20fde1b34ae6640712c3891bc"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/doctrine/instantiator/zipball/d56bf6102915de5702778fe20f2de3b2fe570b5b",
"reference": "d56bf6102915de5702778fe20f2de3b2fe570b5b",
"url": "https://api.github.com/repos/doctrine/instantiator/zipball/10dcfce151b967d20fde1b34ae6640712c3891bc",
"reference": "10dcfce151b967d20fde1b34ae6640712c3891bc",
"shasum": ""
},
"require": {
"php": "^7.1 || ^8.0"
},
"require-dev": {
"doctrine/coding-standard": "^8.0",
"doctrine/coding-standard": "^9",
"ext-pdo": "*",
"ext-phar": "*",
"phpbench/phpbench": "^0.13 || 1.0.0-alpha2",
"phpstan/phpstan": "^0.12",
"phpstan/phpstan-phpunit": "^0.12",
"phpunit/phpunit": "^7.0 || ^8.0 || ^9.0"
"phpbench/phpbench": "^0.16 || ^1",
"phpstan/phpstan": "^1.4",
"phpstan/phpstan-phpunit": "^1",
"phpunit/phpunit": "^7.5 || ^8.5 || ^9.5",
"vimeo/psalm": "^4.22"
},
"type": "library",
"autoload": {
@@ -555,7 +556,7 @@
],
"support": {
"issues": "https://github.com/doctrine/instantiator/issues",
"source": "https://github.com/doctrine/instantiator/tree/1.4.0"
"source": "https://github.com/doctrine/instantiator/tree/1.4.1"
},
"funding": [
{
@@ -571,7 +572,7 @@
"type": "tidelift"
}
],
"time": "2020-11-10T18:47:58+00:00"
"time": "2022-03-03T08:28:38+00:00"
},
{
"name": "facebook/webdriver",
@@ -730,12 +731,12 @@
}
},
"autoload": {
"psr-4": {
"GuzzleHttp\\": "src/"
},
"files": [
"src/functions_include.php"
]
],
"psr-4": {
"GuzzleHttp\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
@@ -792,12 +793,12 @@
}
},
"autoload": {
"psr-4": {
"GuzzleHttp\\Promise\\": "src/"
},
"files": [
"src/functions_include.php"
]
],
"psr-4": {
"GuzzleHttp\\Promise\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
@@ -851,16 +852,16 @@
},
{
"name": "guzzlehttp/psr7",
"version": "1.8.3",
"version": "1.8.5",
"source": {
"type": "git",
"url": "https://github.com/guzzle/psr7.git",
"reference": "1afdd860a2566ed3c2b0b4a3de6e23434a79ec85"
"reference": "337e3ad8e5716c15f9657bd214d16cc5e69df268"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/guzzle/psr7/zipball/1afdd860a2566ed3c2b0b4a3de6e23434a79ec85",
"reference": "1afdd860a2566ed3c2b0b4a3de6e23434a79ec85",
"url": "https://api.github.com/repos/guzzle/psr7/zipball/337e3ad8e5716c15f9657bd214d16cc5e69df268",
"reference": "337e3ad8e5716c15f9657bd214d16cc5e69df268",
"shasum": ""
},
"require": {
@@ -941,7 +942,7 @@
],
"support": {
"issues": "https://github.com/guzzle/psr7/issues",
"source": "https://github.com/guzzle/psr7/tree/1.8.3"
"source": "https://github.com/guzzle/psr7/tree/1.8.5"
},
"funding": [
{
@@ -957,29 +958,33 @@
"type": "tidelift"
}
],
"time": "2021-10-05T13:56:00+00:00"
"time": "2022-03-20T21:51:18+00:00"
},
{
"name": "myclabs/deep-copy",
"version": "1.10.2",
"version": "1.11.0",
"source": {
"type": "git",
"url": "https://github.com/myclabs/DeepCopy.git",
"reference": "776f831124e9c62e1a2c601ecc52e776d8bb7220"
"reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/776f831124e9c62e1a2c601ecc52e776d8bb7220",
"reference": "776f831124e9c62e1a2c601ecc52e776d8bb7220",
"url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/14daed4296fae74d9e3201d2c4925d1acb7aa614",
"reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614",
"shasum": ""
},
"require": {
"php": "^7.1 || ^8.0"
},
"conflict": {
"doctrine/collections": "<1.6.8",
"doctrine/common": "<2.13.3 || >=3,<3.2.2"
},
"require-dev": {
"doctrine/collections": "^1.0",
"doctrine/common": "^2.6",
"phpunit/phpunit": "^7.1"
"doctrine/collections": "^1.6.8",
"doctrine/common": "^2.13.3 || ^3.2.2",
"phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13"
},
"type": "library",
"autoload": {
@@ -1004,7 +1009,7 @@
],
"support": {
"issues": "https://github.com/myclabs/DeepCopy/issues",
"source": "https://github.com/myclabs/DeepCopy/tree/1.10.2"
"source": "https://github.com/myclabs/DeepCopy/tree/1.11.0"
},
"funding": [
{
@@ -1012,7 +1017,7 @@
"type": "tidelift"
}
],
"time": "2020-11-13T09:40:50+00:00"
"time": "2022-03-03T13:19:32+00:00"
},
{
"name": "phar-io/manifest",
@@ -2613,16 +2618,16 @@
},
{
"name": "symfony/console",
"version": "v4.4.37",
"version": "v4.4.38",
"source": {
"type": "git",
"url": "https://github.com/symfony/console.git",
"reference": "0259f01dbf9d77badddbbf4c2abb681f24c9cac6"
"reference": "5a50085bf5460f0c0d60a50b58388c1249826b8a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/console/zipball/0259f01dbf9d77badddbbf4c2abb681f24c9cac6",
"reference": "0259f01dbf9d77badddbbf4c2abb681f24c9cac6",
"url": "https://api.github.com/repos/symfony/console/zipball/5a50085bf5460f0c0d60a50b58388c1249826b8a",
"reference": "5a50085bf5460f0c0d60a50b58388c1249826b8a",
"shasum": ""
},
"require": {
@@ -2683,7 +2688,7 @@
"description": "Eases the creation of beautiful and testable command line interfaces",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/console/tree/v4.4.37"
"source": "https://github.com/symfony/console/tree/v4.4.38"
},
"funding": [
{
@@ -2699,7 +2704,7 @@
"type": "tidelift"
}
],
"time": "2022-01-26T16:15:26+00:00"
"time": "2022-01-30T21:23:57+00:00"
},
{
"name": "symfony/css-selector",
@@ -2836,16 +2841,16 @@
},
{
"name": "symfony/dom-crawler",
"version": "v4.4.37",
"version": "v4.4.39",
"source": {
"type": "git",
"url": "https://github.com/symfony/dom-crawler.git",
"reference": "60d36408a3a48500bcc6e30d9f831e51d04d7fa4"
"reference": "4e9215a8b533802ba84a3cc5bd3c43103e7a6dc3"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/dom-crawler/zipball/60d36408a3a48500bcc6e30d9f831e51d04d7fa4",
"reference": "60d36408a3a48500bcc6e30d9f831e51d04d7fa4",
"url": "https://api.github.com/repos/symfony/dom-crawler/zipball/4e9215a8b533802ba84a3cc5bd3c43103e7a6dc3",
"reference": "4e9215a8b533802ba84a3cc5bd3c43103e7a6dc3",
"shasum": ""
},
"require": {
@@ -2890,7 +2895,7 @@
"description": "Eases DOM navigation for HTML and XML documents",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/dom-crawler/tree/v4.4.37"
"source": "https://github.com/symfony/dom-crawler/tree/v4.4.39"
},
"funding": [
{
@@ -2906,7 +2911,7 @@
"type": "tidelift"
}
],
"time": "2022-01-02T09:41:36+00:00"
"time": "2022-02-25T10:38:15+00:00"
},
{
"name": "symfony/event-dispatcher",
@@ -3135,7 +3140,7 @@
},
{
"name": "symfony/polyfill-ctype",
"version": "v1.24.0",
"version": "v1.25.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-ctype.git",
@@ -3167,12 +3172,12 @@
}
},
"autoload": {
"psr-4": {
"Symfony\\Polyfill\\Ctype\\": ""
},
"files": [
"bootstrap.php"
]
],
"psr-4": {
"Symfony\\Polyfill\\Ctype\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
@@ -3197,7 +3202,7 @@
"portable"
],
"support": {
"source": "https://github.com/symfony/polyfill-ctype/tree/v1.24.0"
"source": "https://github.com/symfony/polyfill-ctype/tree/v1.25.0"
},
"funding": [
{
@@ -3217,7 +3222,7 @@
},
{
"name": "symfony/polyfill-intl-idn",
"version": "v1.24.0",
"version": "v1.25.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-intl-idn.git",
@@ -3284,7 +3289,7 @@
"shim"
],
"support": {
"source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.24.0"
"source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.25.0"
},
"funding": [
{
@@ -3304,7 +3309,7 @@
},
{
"name": "symfony/polyfill-intl-normalizer",
"version": "v1.24.0",
"version": "v1.25.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-intl-normalizer.git",
@@ -3368,7 +3373,7 @@
"shim"
],
"support": {
"source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.24.0"
"source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.25.0"
},
"funding": [
{
@@ -3388,7 +3393,7 @@
},
{
"name": "symfony/polyfill-mbstring",
"version": "v1.24.0",
"version": "v1.25.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-mbstring.git",
@@ -3420,12 +3425,12 @@
}
},
"autoload": {
"psr-4": {
"Symfony\\Polyfill\\Mbstring\\": ""
},
"files": [
"bootstrap.php"
]
],
"psr-4": {
"Symfony\\Polyfill\\Mbstring\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
@@ -3451,7 +3456,7 @@
"shim"
],
"support": {
"source": "https://github.com/symfony/polyfill-mbstring/tree/v1.24.0"
"source": "https://github.com/symfony/polyfill-mbstring/tree/v1.25.0"
},
"funding": [
{
@@ -3471,16 +3476,16 @@
},
{
"name": "symfony/polyfill-php80",
"version": "v1.24.0",
"version": "v1.25.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-php80.git",
"reference": "57b712b08eddb97c762a8caa32c84e037892d2e9"
"reference": "4407588e0d3f1f52efb65fbe92babe41f37fe50c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/57b712b08eddb97c762a8caa32c84e037892d2e9",
"reference": "57b712b08eddb97c762a8caa32c84e037892d2e9",
"url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/4407588e0d3f1f52efb65fbe92babe41f37fe50c",
"reference": "4407588e0d3f1f52efb65fbe92babe41f37fe50c",
"shasum": ""
},
"require": {
@@ -3534,7 +3539,7 @@
"shim"
],
"support": {
"source": "https://github.com/symfony/polyfill-php80/tree/v1.24.0"
"source": "https://github.com/symfony/polyfill-php80/tree/v1.25.0"
},
"funding": [
{
@@ -3550,7 +3555,7 @@
"type": "tidelift"
}
],
"time": "2021-09-13T13:58:33+00:00"
"time": "2022-03-04T08:16:47+00:00"
},
{
"name": "symfony/process",

View File

@@ -1514,4 +1514,7 @@ span.range-append {
.jqCron-container.disable .jqCron-selector-title {
background: #ffffff !important; }
.hint-icon {
color: #06A599; }
/*# sourceMappingURL=preset.css.map */

File diff suppressed because one or more lines are too long

View File

@@ -1004,6 +1004,11 @@ form label {
margin: 0; }
form label [data-hint] {
display: inline; }
form label .hint-icon {
opacity: 0.7;
transition: 0.5s opacity; }
form label:hover .hint-icon {
opacity: 1.0; }
form label.inline {
display: inline;
vertical-align: middle;

File diff suppressed because one or more lines are too long

View File

@@ -2366,3 +2366,7 @@ body .bootstrap-datetimepicker-widget {
.jqCron-container.disable .jqCron-selector-title {
background: $content-bg !important;
}
.hint-icon {
color: $notice_bg;
}

View File

@@ -164,6 +164,14 @@ form {
display: inline;
}
.hint-icon {
opacity: 0.7;
transition: 0.5s opacity;
}
&:hover .hint-icon {
opacity: 1.0;
}
&.inline {
display: inline;
vertical-align: middle;
@@ -484,7 +492,6 @@ form {
position: relative;
padding: 0 0 0 2rem;
margin-right: 15px;
}
label:before {
content:"";

View File

@@ -4,7 +4,7 @@
{% set default = field.default %}
{% set toggleable = field.toggleable ?? false %}
{% if toggleable %}
{% set originalValue = originalValue is defined ? originalValue : value %}
{% set originalValue = originalValue ?? value %}
{% set toggleableChecked = originalValue is not null %}
{% endif %}
@@ -48,7 +48,7 @@
{% if field.markdown %}
<span class="hint--bottom" data-hint="{{ field.help|t|markdown(false) }}">{{ field.label|t|markdown(false)|raw }}</span>
{% else %}
<span class="hint--bottom" data-hint="{{ field.help|t }}">{{ field.label|t|raw }}</span>
<span class="hint--bottom" data-hint="{{ field.help|t }}">{{ field.label|t|raw }} <i class="hint-icon fa fa-question-circle" aria-hidden="true"></i></span>
{% endif %}
{% else %}
{% if field.markdown %}

View File

@@ -1,6 +1,5 @@
{% extends "forms/field.html.twig" %}
{% set originalValue = originalValue is defined ? originalValue : value %}
{% set value = (value is null ? field.default : value) %}
{% set pattern = '^#([a-fA-F0-9]{6})|(rgba\\(\\s*(0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])\\s*,\\s*(0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])\\s*,\\s*(0|[1-9]\\d?|1\\d\\d?|2[0-4]\\d|25[0-5])\\s*,\\s*((0.[0-9]+)|(1.00)|1.0|1)\\s*\\))$' %}
{% block input %}

View File

@@ -1,8 +1,5 @@
{% extends "forms/field.html.twig" %}
{% set originalValue = value %}
{% set value = (value is null ? field.default : value) %}
{% block input %}
<div class="colorbar current-scheme">
{% include 'forms/default/fields.html.twig' with {name: field.name, fields: field.fields} %}

View File

@@ -70,10 +70,7 @@
{% endif %}
{% set field_templates = include_form_field(child.type, field_layout, default_layout) %}
{% if default_layout != 'key' %}
{% set originalValue = child_value %}
{% endif %}
{% include field_templates with { field: child, value: child_value } %}
{% include field_templates with { field: child, value: child_value, originalValue: null } %}
{% endif %}
{% endfor %}
{% endif %}

View File

@@ -1,6 +1,4 @@
{% extends "forms/field.html.twig" %}
{% set originalValue = originalValue is defined ? originalValue : value %}
{% set value = (value is null ? field.default : value) %}
{% block global_attributes %}
data-grav-iconpicker

View File

@@ -90,17 +90,20 @@
{% set child_value = val %}
{% else %}
{% set child_value = form ? form.value(child.name) : data.value(child.name) %}
{# Look for a default value for that field #}
{% if child_value is null and val[child_name|trim('.', 'left')] is defined %}
{% set child_value = val[child_name|trim('.', 'left')] %}
{% endif %}
{% endif %}
{% set field_templates = include_form_field(child.type, field_layout, default_layout) %}
{% set template_data = { field: child, value: child_value } %}
{% set template_data = { field: child, value: child_value, originalValue: null } %}
{% if default_layout != 'key' %}
{% set originalValue = child_value %}
{% if child.type == 'fieldset' %}
{% set template_data = template_data|merge({val: child_value}) %}
{% endif %}
{% endif %}
{%- include field_templates with template_data -%}
{% endif %}
{% endfor %}

View File

@@ -1,8 +1,5 @@
{% extends "forms/fields/text/text.html.twig" %}
{% set originalValue = value %}
{% set value = (value is null ? field.default : value) %}
{% set unique_identifier = random_string() %}
{% block global_attributes %}

View File

@@ -193,17 +193,17 @@
},
{
"name": "scssphp/scssphp",
"version": "v1.10.0",
"version_normalized": "1.10.0.0",
"version": "v1.10.2",
"version_normalized": "1.10.2.0",
"source": {
"type": "git",
"url": "https://github.com/scssphp/scssphp.git",
"reference": "9699a52a862da4efb43985943afa17150155dd3d"
"reference": "387f4f4abf5d99f16be16314c5ab856f81c82f46"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/scssphp/scssphp/zipball/9699a52a862da4efb43985943afa17150155dd3d",
"reference": "9699a52a862da4efb43985943afa17150155dd3d",
"url": "https://api.github.com/repos/scssphp/scssphp/zipball/387f4f4abf5d99f16be16314c5ab856f81c82f46",
"reference": "387f4f4abf5d99f16be16314c5ab856f81c82f46",
"shasum": ""
},
"require": {
@@ -226,7 +226,7 @@
"ext-iconv": "Can be used as fallback when ext-mbstring is not available",
"ext-mbstring": "For best performance, mbstring should be installed as it is faster than ext-iconv"
},
"time": "2022-01-06T18:16:18+00:00",
"time": "2022-03-02T21:15:09+00:00",
"bin": [
"bin/pscss"
],
@@ -264,7 +264,7 @@
],
"support": {
"issues": "https://github.com/scssphp/scssphp/issues",
"source": "https://github.com/scssphp/scssphp/tree/v1.10.0"
"source": "https://github.com/scssphp/scssphp/tree/v1.10.2"
},
"install-path": "../scssphp/scssphp"
}

View File

@@ -5,7 +5,7 @@
'type' => 'grav-plugin',
'install_path' => __DIR__ . '/../../',
'aliases' => array(),
'reference' => '9317a497fbe62505ab8159be67cc6d365d21201f',
'reference' => '5c1e6d6d52f8fc8e0540b5599e736e25ea20c446',
'name' => 'getgrav/grav-plugin-admin',
'dev' => false,
),
@@ -16,7 +16,7 @@
'type' => 'grav-plugin',
'install_path' => __DIR__ . '/../../',
'aliases' => array(),
'reference' => '9317a497fbe62505ab8159be67cc6d365d21201f',
'reference' => '5c1e6d6d52f8fc8e0540b5599e736e25ea20c446',
'dev_requirement' => false,
),
'laminas/laminas-xml' => array(
@@ -53,12 +53,12 @@
'dev_requirement' => false,
),
'scssphp/scssphp' => array(
'pretty_version' => 'v1.10.0',
'version' => '1.10.0.0',
'pretty_version' => 'v1.10.2',
'version' => '1.10.2.0',
'type' => 'library',
'install_path' => __DIR__ . '/../scssphp/scssphp',
'aliases' => array(),
'reference' => '9699a52a862da4efb43985943afa17150155dd3d',
'reference' => '387f4f4abf5d99f16be16314c5ab856f81c82f46',
'dev_requirement' => false,
),
'symfony/polyfill-php72' => array(

View File

@@ -50,16 +50,16 @@
"type": "package",
"package": {
"name": "sass/sass-spec",
"version": "2021.11.30",
"version": "2022.02.24",
"source": {
"type": "git",
"url": "https://github.com/sass/sass-spec.git",
"reference": "ee5b460ac84b1ce27b86e22c0252b4296444cf3a"
"reference": "f41b9bfb9a3013392f2136c79f7f3356f15fb8ba"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sass/sass-spec/zipball/ee5b460ac84b1ce27b86e22c0252b4296444cf3a",
"reference": "ee5b460ac84b1ce27b86e22c0252b4296444cf3a",
"url": "https://api.github.com/repos/sass/sass-spec/zipball/f41b9bfb9a3013392f2136c79f7f3356f15fb8ba",
"reference": "f41b9bfb9a3013392f2136c79f7f3356f15fb8ba",
"shasum": ""
}
}

View File

@@ -166,7 +166,7 @@ class Compiler
/**
* @var array
* @phpstan-var array<string, array{0: callable, 1: array|null}>
* @phpstan-var array<string, array{0: callable, 1: string[]|null}>
*/
protected $userFunctions = [];
/**
@@ -211,9 +211,15 @@ class Compiler
private $charset = true;
/**
* @var string|\ScssPhp\ScssPhp\Formatter
* @var Formatter
*/
protected $formatter = Expanded::class;
protected $formatter;
/**
* @var string
* @phpstan-var class-string<Formatter>
*/
private $configuredFormatter = Expanded::class;
/**
* @var Environment
@@ -381,7 +387,7 @@ class Compiler
'encoding' => $this->encoding,
'sourceMap' => serialize($this->sourceMap),
'sourceMapOptions' => $this->sourceMapOptions,
'formatter' => $this->formatter,
'formatter' => $this->configuredFormatter,
'legacyImportPath' => $this->legacyCwdImportPath,
];
@@ -502,7 +508,7 @@ class Compiler
$tree = $this->parser->parse($source);
$this->parser = null;
$this->formatter = new $this->formatter();
$this->formatter = new $this->configuredFormatter();
$this->rootBlock = null;
$this->rootEnv = $this->pushEnv($tree);
@@ -529,6 +535,7 @@ class Compiler
$sourceMapGenerator = new SourceMapGenerator($this->sourceMapOptions);
}
}
assert($this->scope !== null);
$out = $this->formatter->format($this->scope, $sourceMapGenerator);
@@ -542,6 +549,7 @@ class Compiler
$sourceMap = null;
if (! empty($out) && $this->sourceMap && $this->sourceMap !== self::SOURCE_MAP_NONE) {
assert($sourceMapGenerator !== null);
$sourceMap = $sourceMapGenerator->generateJson($prefix);
$sourceMapUrl = null;
@@ -671,7 +679,7 @@ class Compiler
/**
* Push extends
*
* @param array $target
* @param string[] $target
* @param array $origin
* @param array|null $block
*
@@ -714,9 +722,9 @@ class Compiler
$out->sourceLine = $this->env->block->sourceLine;
$out->sourceColumn = $this->env->block->sourceColumn;
} else {
$out->sourceName = null;
$out->sourceLine = null;
$out->sourceColumn = null;
$out->sourceName = isset($this->sourceNames[$this->sourceIndex]) ? $this->sourceNames[$this->sourceIndex] : '(stdin)';
$out->sourceLine = $this->sourceLine;
$out->sourceColumn = $this->sourceColumn;
}
return $out;
@@ -734,6 +742,7 @@ class Compiler
$this->rootBlock = $this->scope = $this->makeOutputBlock(Type::T_ROOT);
$this->compileChildrenNoReturn($rootBlock->children, $this->scope);
assert($this->scope !== null);
$this->flattenSelectors($this->scope);
$this->missingSelectors();
}
@@ -815,6 +824,7 @@ class Compiler
}
if ($placeholderSelector && 0 === \count($block->selectors) && null !== $parentKey) {
assert($block->parent !== null);
unset($block->parent->children[$parentKey]);
return;
@@ -1287,6 +1297,7 @@ class Compiler
$mediaQueries = $this->compileMediaQuery($this->multiplyMedia($this->env));
if (! empty($mediaQueries)) {
assert($this->scope !== null);
$previousScope = $this->scope;
$parentScope = $this->mediaParent($this->scope);
@@ -1452,7 +1463,7 @@ class Compiler
if (
! $selfParent->selectors &&
isset($block->parent) && $block->parent &&
isset($block->parent) &&
isset($block->parent->selectors) && $block->parent->selectors
) {
$selfParent = $block->parent;
@@ -1460,13 +1471,15 @@ class Compiler
$this->env = $this->filterWithWithout($envs, $with, $without);
assert($this->scope !== null);
$saveScope = $this->scope;
$this->scope = $this->filterScopeWithWithout($saveScope, $with, $without);
// propagate selfParent to the children where they still can be useful
$this->compileChildrenNoReturn($block->children, $this->scope, $selfParent);
$this->scope = $this->completeScope($this->scope, $saveScope);
assert($this->scope !== null);
$this->completeScope($this->scope, $saveScope);
$this->scope = $saveScope;
$this->env = $this->extractEnv($envs);
@@ -1490,6 +1503,7 @@ class Compiler
if ($scope->type === Type::T_ROOT) {
return $scope;
}
assert($this->rootBlock !== null);
// start from the root
while ($scope->parent && $scope->parent->type !== Type::T_ROOT) {
@@ -1557,7 +1571,7 @@ class Compiler
*/
protected function completeScope($scope, $previousScope)
{
if (! $scope->type && (! $scope->selectors || ! \count($scope->selectors)) && \count($scope->lines)) {
if (! $scope->type && ! $scope->selectors && \count($scope->lines)) {
$scope->selectors = $this->findScopeSelectors($previousScope, $scope->depth);
}
@@ -1768,10 +1782,12 @@ class Compiler
$this->scope = $this->makeOutputBlock($block->type, $selectors);
$this->scope->depth = 1;
assert($this->scope->parent !== null);
$this->scope->parent->children[] = $this->scope;
$this->compileChildrenNoReturn($block->children, $this->scope);
assert($this->scope !== null);
$this->scope = $this->scope->parent;
$this->env = $this->extractEnv($envs);
@@ -1829,6 +1845,7 @@ class Compiler
$this->pushEnv($block);
$this->scope = $this->makeOutputBlock($block->type, $selectors);
assert($this->scope->parent !== null);
$this->scope->parent->children[] = $this->scope;
// wrap assign children in a block
@@ -1862,6 +1879,7 @@ class Compiler
$this->compileChildrenNoReturn($block->children, $this->scope);
assert($this->scope !== null);
$this->scope = $this->scope->parent;
$this->popEnv();
@@ -1890,10 +1908,12 @@ class Compiler
protected function compileBlock(Block $block)
{
$env = $this->pushEnv($block);
assert($block->selectors !== null);
$env->selectors = $this->evalSelectors($block->selectors);
$out = $this->makeOutputBlock(null);
assert($this->scope !== null);
$this->scope->children[] = $out;
if (\count($block->children)) {
@@ -1911,6 +1931,7 @@ class Compiler
// and revert for the following children of the same block
if ($selfParentSelectors) {
assert($block->selfParent !== null);
$block->selfParent->selectors = $selfParentSelectors;
}
}
@@ -1966,6 +1987,7 @@ class Compiler
$out = $this->makeOutputBlock(Type::T_COMMENT);
$out->lines[] = $this->compileCommentValue($block, true);
assert($this->scope !== null);
$this->scope->children[] = $out;
}
@@ -1980,7 +2002,11 @@ class Compiler
{
$this->shouldEvaluate = false;
$selectors = array_map([$this, 'evalSelector'], $selectors);
$evaluatedSelectors = [];
foreach ($selectors as $selector) {
$evaluatedSelectors[] = $this->evalSelector($selector);
}
$selectors = $evaluatedSelectors;
// after evaluating interpolates, we might need a second pass
if ($this->shouldEvaluate) {
@@ -2008,6 +2034,8 @@ class Compiler
* @param array $selector
*
* @return array
*
* @phpstan-impure
*/
protected function evalSelector($selector)
{
@@ -2020,6 +2048,8 @@ class Compiler
* @param array $part
*
* @return array
*
* @phpstan-impure
*/
protected function evalSelectorPart($part)
{
@@ -2033,8 +2063,8 @@ class Compiler
}
} elseif (
\is_string($p) && \strlen($p) >= 2 &&
($first = $p[0]) && ($first === '"' || $first === "'") &&
substr($p, -1) === $first
($p[0] === '"' || $p[0] === "'") &&
substr($p, -1) === $p[0]
) {
$p = substr($p, 1, -1);
}
@@ -2401,7 +2431,7 @@ class Compiler
$queryString = $this->compileMediaQuery([$queryList[$kql]]);
$queryString = reset($queryString);
if (strpos($queryString, '@media ') === 0) {
if ($queryString !== false && strpos($queryString, '@media ') === 0) {
$queryString = substr($queryString, 7);
$queries = [];
@@ -2857,7 +2887,7 @@ class Compiler
$this->sourceIndex = isset($child[Parser::SOURCE_INDEX]) ? $child[Parser::SOURCE_INDEX] : null;
$this->sourceLine = isset($child[Parser::SOURCE_LINE]) ? $child[Parser::SOURCE_LINE] : -1;
$this->sourceColumn = isset($child[Parser::SOURCE_COLUMN]) ? $child[Parser::SOURCE_COLUMN] : -1;
} elseif (\is_array($child) && isset($child[1]->sourceLine)) {
} elseif (\is_array($child) && isset($child[1]->sourceLine) && $child[1] instanceof Block) {
$this->sourceIndex = $child[1]->sourceIndex;
$this->sourceLine = $child[1]->sourceLine;
$this->sourceColumn = $child[1]->sourceColumn;
@@ -3093,6 +3123,7 @@ class Compiler
if (! $selectors && isset($child['selfParent'])) {
$selectors = $this->multiplySelectors($this->env, $child['selfParent']);
}
assert($selectors !== null);
if (\count($result) > 1) {
$replacement = implode(', ', $result);
@@ -3255,7 +3286,7 @@ EOL;
// and assign this fake parent to childs
$selfParent = null;
if (isset($child['selfParent']) && isset($child['selfParent']->selectors)) {
if (isset($child['selfParent']) && $child['selfParent'] instanceof Block && isset($child['selfParent']->selectors)) {
$selfParent = $child['selfParent'];
} else {
$parentSelectors = $this->multiplySelectors($this->env);
@@ -3265,7 +3296,7 @@ EOL;
$parent->selectors = $parentSelectors;
foreach ($mixin->children as $k => $child) {
if (isset($child[1]) && \is_object($child[1]) && $child[1] instanceof Block) {
if (isset($child[1]) && $child[1] instanceof Block) {
$mixin->children[$k][1]->parent = $parent;
}
}
@@ -3371,6 +3402,8 @@ EOL;
default:
throw $this->error("unknown child type: $child[0]");
}
return null;
}
/**
@@ -3505,32 +3538,24 @@ EOL;
$ucLType = ucfirst($ltype);
$ucRType = ucfirst($rtype);
$shouldEval = $inParens || $inExp;
// this tries:
// 1. op[op name][left type][right type]
// 2. op[left type][right type] (passing the op as first arg
// 2. op[left type][right type] (passing the op as first arg)
// 3. op[op name]
$fn = "op${ucOpName}${ucLType}${ucRType}";
if (\is_callable([$this, $fn = "op${ucOpName}${ucLType}${ucRType}"])) {
$out = $this->$fn($left, $right, $shouldEval);
} elseif (\is_callable([$this, $fn = "op${ucLType}${ucRType}"])) {
$out = $this->$fn($op, $left, $right, $shouldEval);
} elseif (\is_callable([$this, $fn = "op${ucOpName}"])) {
$out = $this->$fn($left, $right, $shouldEval);
} else {
$out = null;
}
if (
\is_callable([$this, $fn]) ||
(($fn = "op${ucLType}${ucRType}") &&
\is_callable([$this, $fn]) &&
$passOp = true) ||
(($fn = "op${ucOpName}") &&
\is_callable([$this, $fn]) &&
$genOp = true)
) {
$shouldEval = $inParens || $inExp;
if (isset($passOp)) {
$out = $this->$fn($op, $left, $right, $shouldEval);
} else {
$out = $this->$fn($left, $right, $shouldEval);
}
if (isset($out)) {
return $out;
}
if (isset($out)) {
return $out;
}
return $this->expToString($value);
@@ -3872,6 +3897,7 @@ EOL;
}
if (($f = $this->getBuiltinFunction($normalizedName)) && \is_callable($f)) {
/** @var string $libName */
$libName = $f[1];
$prototype = isset(static::$$libName) ? static::$$libName : null;
@@ -5517,11 +5543,11 @@ EOL;
{
switch ($style) {
case OutputStyle::EXPANDED:
$this->formatter = Expanded::class;
$this->configuredFormatter = Expanded::class;
break;
case OutputStyle::COMPRESSED:
$this->formatter = Compressed::class;
$this->configuredFormatter = Compressed::class;
break;
default:
@@ -5539,6 +5565,8 @@ EOL;
* @return void
*
* @deprecated Use {@see setOutputStyle} instead.
*
* @phpstan-param class-string<Formatter> $formatterName
*/
public function setFormatter($formatterName)
{
@@ -5547,7 +5575,7 @@ EOL;
}
@trigger_error('The method "setFormatter" is deprecated. Use "setOutputStyle" instead.', E_USER_DEPRECATED);
$this->formatter = $formatterName;
$this->configuredFormatter = $formatterName;
}
/**
@@ -5688,6 +5716,10 @@ EOL;
// see if tree is cached
$realPath = realpath($path);
if ($realPath === false) {
$realPath = $path;
}
if (substr($path, -5) === '.sass') {
$this->sourceIndex = \count($this->sourceNames);
$this->sourceNames[] = $path;
@@ -6031,6 +6063,8 @@ EOL;
*
* @param string $msg Message with optional sprintf()-style vararg parameters
*
* @return never
*
* @throws \ScssPhp\ScssPhp\Exception\CompilerException
*
* @deprecated use "error" and throw the exception in the caller instead.
@@ -6050,7 +6084,8 @@ EOL;
*
* @internal
*
* @param string $msg Message with optional sprintf()-style vararg parameters
* @param string $msg Message with optional sprintf()-style vararg parameters
* @param bool|float|int|string|null ...$args
*
* @return CompilerException
*/
@@ -6168,6 +6203,8 @@ EOL;
*
* @param string $name
*
* @return void
*
* @throws \Exception
*/
protected function handleImportLoop($name)
@@ -6362,6 +6399,9 @@ EOL;
if (\in_array($functionName, ['libRgb', 'libRgba', 'libHsl', 'libHsla'])) {
// notation 100 127 255 / 0 is in fact a simple list of 4 values
foreach ($args as $k => $arg) {
if (!isset($arg[1])) {
continue; // This happens when using a trailing comma
}
if ($arg[1][0] === Type::T_LIST && \count($arg[1][2]) === 3) {
$args[$k][1][2] = $this->extractSlashAlphaInColorFunction($arg[1][2]);
}
@@ -6794,7 +6834,7 @@ EOL;
$prototype = ['arguments' => [], 'rest_argument' => null];
$originalRestArgumentName = null;
foreach ($argDef as $i => $arg) {
foreach ($argDef as $arg) {
list($name, $default, $isVariable) = $arg;
$normalizedName = str_replace('_', '-', $name);
@@ -7262,6 +7302,8 @@ EOL;
protected function coerceString($value)
{
if ($value[0] === Type::T_STRING) {
assert(\is_array($value));
return $value;
}
@@ -7365,6 +7407,7 @@ EOL;
if ($value[0] !== Type::T_LIST) {
throw $this->error('expecting list, %s received', $value[0]);
}
assert(\is_array($value));
return $value;
}
@@ -7534,7 +7577,7 @@ EOL;
$h = 60 * ($green - $blue) / $d;
} elseif ($green == $max) {
$h = 60 * ($blue - $red) / $d + 120;
} elseif ($blue == $max) {
} else {
$h = 60 * ($red - $green) / $d + 240;
}
}
@@ -7613,9 +7656,9 @@ EOL;
*
* @api
*
* @param int $hue H from 0 to 360
* @param int $whiteness W from 0 to 100
* @param int $blackness B from 0 to 100
* @param int|float $hue H from 0 to 360
* @param int|float $whiteness W from 0 to 100
* @param int|float $blackness B from 0 to 100
*
* @return array
*/
@@ -7666,7 +7709,7 @@ EOL;
$h = 60 * ($green - $blue) / $d;
} elseif ($green == $max) {
$h = 60 * ($blue - $red) / $d + 120;
} elseif ($blue == $max) {
} else {
$h = 60 * ($red - $green) / $d + 240;
}
}
@@ -7790,6 +7833,14 @@ EOL;
['channels'],
['red', 'green', 'blue'],
['red', 'green', 'blue', 'alpha'] ];
/**
* @param array $args
* @param array $kwargs
* @param string $funcName
*
* @return array
*/
protected function libRgb($args, $kwargs, $funcName = 'rgb')
{
switch (\count($args)) {
@@ -7872,14 +7923,7 @@ EOL;
$scale = $operation === 'scale';
$change = $operation === 'change';
/**
* @param string $name
* @param float|int $max
* @param bool $checkPercent
* @param bool $assertPercent
*
* @return float|int|null
*/
/** @phpstan-var callable(string, float|int, bool=, bool=): (float|int|null) $getParam */
$getParam = function ($name, $max, $checkPercent = false, $assertPercent = false) use (&$kwargs, $scale, $change) {
if (!isset($kwargs[$name])) {
return null;
@@ -7938,7 +7982,6 @@ EOL;
$hasRgb = $red !== null || $green !== null || $blue !== null;
$hasSL = $saturation !== null || $lightness !== null;
$hasWB = $whiteness !== null || $blackness !== null;
$found = false;
if ($hasRgb && ($hasSL || $hasWB || $hue !== null)) {
throw new SassScriptException(sprintf('RGB parameters may not be passed along with %s parameters.', $hasWB ? 'HWB' : 'HSL'));
@@ -8159,6 +8202,14 @@ EOL;
['hue', 'saturation'],
['hue', 'saturation', 'lightness'],
['hue', 'saturation', 'lightness', 'alpha'] ];
/**
* @param array $args
* @param array $kwargs
* @param string $funcName
*
* @return array|null
*/
protected function libHsl($args, $kwargs, $funcName = 'hsl')
{
$args_to_check = $args;
@@ -8183,7 +8234,7 @@ EOL;
throw new SassScriptException('Missing argument $lightness.');
}
foreach ($kwargs as $k => $arg) {
foreach ($kwargs as $arg) {
if (in_array($arg[0], [Type::T_FUNCTION_CALL, Type::T_FUNCTION]) && in_array($arg[1], ['min', 'max'])) {
return null;
}
@@ -9350,7 +9401,7 @@ will be an error in future versions of Sass.\n on line $line of $fname";
$index = $index - 1;
}
if ($index < 0) {
$index = Util::mbStrlen($stringContent) + 1 + $index;
$index = max(Util::mbStrlen($stringContent) + 1 + $index, 0);
}
$string[2] = [
@@ -10003,6 +10054,8 @@ will be an error in future versions of Sass.\n on line $line of $fname";
$selectorsMap[] = $this->getSelectorArg($arg, 'selector', true);
}
assert(!empty($selectorsMap));
$envs = [];
foreach ($selectorsMap as $selectors) {

View File

@@ -22,7 +22,8 @@ namespace ScssPhp\ScssPhp\Exception;
class ParserException extends \Exception implements SassException
{
/**
* @var array
* @var array|null
* @phpstan-var array{string, int, int}|null
*/
private $sourcePosition;
@@ -30,6 +31,9 @@ class ParserException extends \Exception implements SassException
* Get source position
*
* @api
*
* @return array|null
* @phpstan-return array{string, int, int}|null
*/
public function getSourcePosition()
{
@@ -42,6 +46,10 @@ class ParserException extends \Exception implements SassException
* @api
*
* @param array $sourcePosition
*
* @return void
*
* @phpstan-param array{string, int, int} $sourcePosition
*/
public function setSourcePosition($sourcePosition)
{

View File

@@ -286,9 +286,18 @@ abstract class Formatter
ob_start();
$this->block($block);
try {
$this->block($block);
} catch (\Exception $e) {
ob_end_clean();
throw $e;
} catch (\Throwable $e) {
ob_end_clean();
throw $e;
}
$out = ob_get_clean();
assert($out !== false);
return $out;
}
@@ -331,6 +340,8 @@ abstract class Formatter
// If the written line starts is empty, adding a mapping would add it for
// a non-existent column as we are at the end of the line
if ($line !== '') {
assert($this->currentBlock->sourceLine !== null);
assert($this->currentBlock->sourceName !== null);
$this->sourceMapGenerator->addMapping(
$this->currentLine,
$this->currentColumn,
@@ -346,6 +357,8 @@ abstract class Formatter
}
if ($lastLine !== '') {
assert($this->currentBlock->sourceLine !== null);
assert($this->currentBlock->sourceName !== null);
$this->sourceMapGenerator->addMapping(
$this->currentLine,
$this->currentColumn,

View File

@@ -57,7 +57,9 @@ class Expanded extends Formatter
foreach ($block->lines as $index => $line) {
if (substr($line, 0, 2) === '/*') {
$block->lines[$index] = preg_replace('/\r\n?|\n|\f/', $this->break, $line);
$replacedLine = preg_replace('/\r\n?|\n|\f/', $this->break, $line);
assert($replacedLine !== null);
$block->lines[$index] = $replacedLine;
}
}

View File

@@ -68,7 +68,9 @@ class Nested extends Formatter
foreach ($block->lines as $index => $line) {
if (substr($line, 0, 2) === '/*') {
$block->lines[$index] = preg_replace('/\r\n?|\n|\f/', $this->break, $line);
$replacedLine = preg_replace('/\r\n?|\n|\f/', $this->break, $line);
assert($replacedLine !== null);
$block->lines[$index] = $replacedLine;
}
}

View File

@@ -22,7 +22,7 @@ namespace ScssPhp\ScssPhp\Formatter;
class OutputBlock
{
/**
* @var string
* @var string|null
*/
public $type;

View File

@@ -27,6 +27,7 @@ use ScssPhp\ScssPhp\Block\WhileBlock;
use ScssPhp\ScssPhp\Exception\ParserException;
use ScssPhp\ScssPhp\Logger\LoggerInterface;
use ScssPhp\ScssPhp\Logger\QuietLogger;
use ScssPhp\ScssPhp\Node\Number;
/**
* Parser
@@ -85,10 +86,6 @@ class Parser
* @var array<int, int>
*/
private $sourcePositions;
/**
* @var array|null
*/
private $charset;
/**
* The current offset in the buffer
*
@@ -147,11 +144,9 @@ class Parser
{
$this->sourceName = $sourceName ?: '(stdin)';
$this->sourceIndex = $sourceIndex;
$this->charset = null;
$this->utf8 = ! $encoding || strtolower($encoding) === 'utf-8';
$this->patternModifiers = $this->utf8 ? 'Aisu' : 'Ais';
$this->commentsSeen = [];
$this->commentsSeen = [];
$this->allowVars = true;
$this->cssOnly = $cssOnly;
$this->logger = $logger ?: new QuietLogger();
@@ -255,7 +250,6 @@ class Parser
if ($this->cache) {
$cacheKey = $this->sourceName . ':' . md5($buffer);
$parseOptions = [
'charset' => $this->charset,
'utf8' => $this->utf8,
];
$v = $this->cache->getCache('parse', $cacheKey, $parseOptions);
@@ -296,11 +290,8 @@ class Parser
throw $this->parseError('unclosed block');
}
if ($this->charset) {
array_unshift($this->env->children, $this->charset);
}
$this->restoreEncoding();
assert($this->env !== null);
if ($this->cache) {
$this->cache->setCache('parse', $cacheKey, $this->env, $parseOptions);
@@ -380,8 +371,8 @@ class Parser
*
* @api
*
* @param string $buffer
* @param string|array $out
* @param string $buffer
* @param array $out
*
* @return bool
*/
@@ -827,18 +818,6 @@ class Parser
$this->valueList($charset) &&
$this->end()
) {
if (! isset($this->charset)) {
$statement = [Type::T_CHARSET, $charset];
list($line, $column) = $this->getSourcePosition($s);
$statement[static::SOURCE_LINE] = $line;
$statement[static::SOURCE_COLUMN] = $column;
$statement[static::SOURCE_INDEX] = $this->sourceIndex;
$this->charset = $statement;
}
return true;
}
@@ -1074,6 +1053,8 @@ class Parser
$block = $this->popBlock();
if (! isset($block->type) || $block->type !== Type::T_IF) {
assert($this->env !== null);
if ($this->env->parent) {
$this->append(null); // collect comments before next statement if needed
}
@@ -1093,6 +1074,7 @@ class Parser
// collect comments just after the block closing if needed
if ($this->eatWhiteDefault) {
$this->whitespace();
assert($this->env !== null);
if ($this->env->comments) {
$this->append(null);
@@ -1161,6 +1143,7 @@ class Parser
// collect comments at the beginning of a block if needed
if ($this->eatWhiteDefault) {
$this->whitespace();
assert($this->env !== null);
if ($this->env->comments) {
$this->append(null);
@@ -1195,6 +1178,7 @@ class Parser
*/
protected function popBlock()
{
assert($this->env !== null);
// collect comments ending just before of a block closing
if ($this->env->comments) {
@@ -1245,6 +1229,8 @@ class Parser
* Seek to position in input stream (or return current position in input stream)
*
* @param int $where
*
* @return void
*/
protected function seek($where)
{
@@ -1257,6 +1243,8 @@ class Parser
* @param array|false $parsed
* @param int $startPos
*
* @return array
*
* @throws ParserException
*/
protected function assertPlainCssValid($parsed, $startPos = null)
@@ -1288,7 +1276,7 @@ class Parser
* @param array $parsed
* @param bool $allowExpression
*
* @return bool|array
* @return array|false
*/
protected function isPlainCssValidElement($parsed, $allowExpression = false)
{
@@ -1468,6 +1456,8 @@ class Parser
* @param string $delim Delimiter
*
* @return bool True if match; false otherwise
*
* @phpstan-impure
*/
protected function matchString(&$m, $delim)
{
@@ -1508,6 +1498,8 @@ class Parser
* @param bool $eatWhitespace
*
* @return bool
*
* @phpstan-impure
*/
protected function match($regex, &$out, $eatWhitespace = null)
{
@@ -1537,6 +1529,8 @@ class Parser
* @param bool $eatWhitespace
*
* @return bool
*
* @phpstan-impure
*/
protected function matchChar($char, $eatWhitespace = null)
{
@@ -1565,6 +1559,8 @@ class Parser
* @param bool $eatWhitespace
*
* @return bool
*
* @phpstan-impure
*/
protected function literal($what, $len, $eatWhitespace = null)
{
@@ -1589,6 +1585,8 @@ class Parser
* Match some whitespace
*
* @return bool
*
* @phpstan-impure
*/
protected function whitespace()
{
@@ -1640,20 +1638,20 @@ class Parser
if (! $comment) {
// single part static comment
$this->appendComment([Type::T_COMMENT, $c]);
$commentStatement = [Type::T_COMMENT, $c];
} else {
$comment[] = $c;
$staticComment = substr($this->buffer, $startCommentCount, $endCommentCount - $startCommentCount);
$commentStatement = [Type::T_COMMENT, $staticComment, [Type::T_STRING, '', $comment]];
list($line, $column) = $this->getSourcePosition($startCommentCount);
$commentStatement[self::SOURCE_LINE] = $line;
$commentStatement[self::SOURCE_COLUMN] = $column;
$commentStatement[self::SOURCE_INDEX] = $this->sourceIndex;
$this->appendComment($commentStatement);
}
list($line, $column) = $this->getSourcePosition($startCommentCount);
$commentStatement[self::SOURCE_LINE] = $line;
$commentStatement[self::SOURCE_COLUMN] = $column;
$commentStatement[self::SOURCE_INDEX] = $this->sourceIndex;
$this->appendComment($commentStatement);
$this->commentsSeen[$startCommentCount] = true;
$this->count = $endCommentCount;
} else {
@@ -1675,9 +1673,13 @@ class Parser
* Append comment to current block
*
* @param array $comment
*
* @return void
*/
protected function appendComment($comment)
{
assert($this->env !== null);
if (! $this->discardComments) {
$this->env->comments[] = $comment;
}
@@ -1688,9 +1690,13 @@ class Parser
*
* @param array|null $statement
* @param int $pos
*
* @return void
*/
protected function append($statement, $pos = null)
{
assert($this->env !== null);
if (! \is_null($statement)) {
! $this->cssOnly || ($statement = $this->assertPlainCssValid($statement, $pos));
@@ -1720,11 +1726,15 @@ class Parser
*/
protected function last()
{
assert($this->env !== null);
$i = \count($this->env->children) - 1;
if (isset($this->env->children[$i])) {
return $this->env->children[$i];
}
return null;
}
/**
@@ -2069,10 +2079,12 @@ class Parser
/**
* Parse directive value list that considers $vars as keyword
*
* @param array $out
* @param bool|string $endChar
* @param array $out
* @param string|false $endChar
*
* @return bool
*
* @phpstan-impure
*/
protected function directiveValue(&$out, $endChar = false)
{
@@ -2211,6 +2223,7 @@ class Parser
{
$s = $this->count;
$items = [];
/** @var array|Number|null $value */
$value = null;
while ($this->$parseItem($value)) {
@@ -2224,9 +2237,12 @@ class Parser
$trailing_delim = true;
} else {
assert(\is_array($value) || $value instanceof Number);
// if no delim watch that a keyword didn't eat the single/double quote
// from the following starting string
if ($value[0] === Type::T_KEYWORD) {
assert(\is_array($value));
/** @var string $word */
$word = $value[1];
$last_char = substr($word, -1);
@@ -2251,8 +2267,10 @@ class Parser
$this->count--;
}
/** @var array|Number|null $nextValue */
$nextValue = null;
if ($this->$parseItem($nextValue)) {
assert(\is_array($nextValue) || $nextValue instanceof Number);
if ($nextValue[0] === Type::T_KEYWORD && $nextValue[1] === $last_char) {
// bad try, forget it
$this->seek($currentCount);
@@ -2306,6 +2324,8 @@ class Parser
* @param bool $lookForExp
*
* @return bool
*
* @phpstan-impure
*/
protected function expression(&$out, $listOnly = false, $lookForExp = true)
{
@@ -2366,12 +2386,14 @@ class Parser
/**
* Parse expression specifically checking for lists in parenthesis or brackets
*
* @param array $out
* @param int $s
* @param string $closingParen
* @param array $allowedTypes
* @param array $out
* @param int $s
* @param string $closingParen
* @param string[] $allowedTypes
*
* @return bool
*
* @phpstan-param array<Type::*> $allowedTypes
*/
protected function enclosedExpression(&$out, $s, $closingParen = ')', $allowedTypes = [Type::T_LIST, Type::T_MAP])
{
@@ -4016,7 +4038,7 @@ class Parser
*
* @param array $value
*
* @return array
* @return string[]
*/
protected function stripAssignmentFlags(&$value)
{
@@ -4043,7 +4065,7 @@ class Parser
*
* @param array $selectors
*
* @return string
* @return bool
*/
protected function stripOptionalFlag(&$selectors)
{
@@ -4092,6 +4114,8 @@ class Parser
* Extract line numbers from buffer
*
* @param string $buffer
*
* @return void
*/
private function extractLineNumbers($buffer)
{
@@ -4116,6 +4140,7 @@ class Parser
* @param int $pos
*
* @return array
* @phpstan-return array{int, int}
*/
private function getSourcePosition($pos)
{

View File

@@ -107,7 +107,7 @@ class SourceMapGenerator
*/
public function __construct(array $options = [])
{
$this->options = array_merge($this->defaultOptions, $options);
$this->options = array_replace($this->defaultOptions, $options);
$this->encoder = new Base64VLQ();
}
@@ -140,7 +140,7 @@ class SourceMapGenerator
*
* @param string $content The content to write
*
* @return string
* @return string|null
*
* @throws \ScssPhp\ScssPhp\Exception\CompilerException If the file could not be saved
* @deprecated
@@ -148,6 +148,7 @@ class SourceMapGenerator
public function saveMap($content)
{
$file = $this->options['sourceMapWriteTo'];
assert($file !== null);
$dir = \dirname($file);
// directory does not exist
@@ -201,7 +202,7 @@ class SourceMapGenerator
// A list of original sources used by the 'mappings' entry.
$sourceMap['sources'] = [];
foreach ($this->sources as $sourceUri => $sourceFilename) {
foreach ($this->sources as $sourceFilename) {
$sourceMap['sources'][] = $this->normalizeFilename($sourceFilename);
}
@@ -223,7 +224,15 @@ class SourceMapGenerator
unset($sourceMap['sourceRoot']);
}
return json_encode($sourceMap, JSON_UNESCAPED_SLASHES);
$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;
}
/**

View File

@@ -19,5 +19,5 @@ namespace ScssPhp\ScssPhp;
*/
class Version
{
const VERSION = '1.10.0';
const VERSION = '1.10.2';
}