Skip to content

Commit

Permalink
[CSS] Relaxed Nesting Support (#3898)
Browse files Browse the repository at this point in the history
* [CSS] Relaxed Nesting

This commit implements relaxed syntax for nested style rules 
according to https://www.w3.org/TR/css-nesting-1/#nested-style-rule.

In general it means, nested selectors of nested style rules no longer need to
start with `&` operator to denote html tags.

The implementation adopts `properties-or-selectors` context from Less syntax
to achieve reliable distinction between declarations and selectors without
loosing support for interpolation.

* [CSS] Rename style-block to avoid confusion

This commit renames `style-block` contexts to `stylesheet-block` in order to
avoid confusion with official syntax specs, because a `style-block` is actually
what is represented by `property-lists` contexts in this syntax definition.

A stylesheet block's content is however equal to top-level content, which does
not support declarations (property-value pairs).

* [CSS] Fix ASP/PHP/... interpolation

* [CSS] Tiny optimization
  • Loading branch information
deathaxe authored Feb 18, 2024
1 parent 225202d commit b4decd9
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 40 deletions.
68 changes: 42 additions & 26 deletions CSS/CSS.sublime-syntax
Original file line number Diff line number Diff line change
Expand Up @@ -81,12 +81,12 @@ variables:

logical_operators: (?i:and|or|not|only)

# Selectors
selector_begin: (?={{selector_start}})
# Properties and Selectors
property_or_selector_begin: (?={{ident_begin}}|{{selector_start}})
property_end: (?=[;@)}])

selector_start: '[[:alpha:].:#&*\[{{combinator_char}}]'
selector_end: (?=[;@(){}])
selector_start: '[[:alpha:]{{nested_selector_start}}]'
nested_selector_begin: (?={{nested_selector_start}})
nested_selector_start: '[.:#&*\[{{combinator_char}}]'

keyframe_selector_begin: (?=\b(?i:from|to){{break}}|\.?[\d,%])

Expand Down Expand Up @@ -335,6 +335,7 @@ contexts:
- include: stylesheet

stylesheet:
# https://www.w3.org/TR/css-syntax-3/#typedef-stylesheet
- include: comments
- include: property-lists
- include: selectors
Expand Down Expand Up @@ -442,7 +443,7 @@ contexts:
1: punctuation.definition.keyword.css
push:
- at-container-meta
- maybe-style-block
- maybe-stylesheet-block
- container-query
- at-container-identifier

Expand Down Expand Up @@ -572,7 +573,7 @@ contexts:
1: punctuation.definition.keyword.css
push:
- at-document-meta
- maybe-style-block
- maybe-stylesheet-block
- at-document-query

at-document-meta:
Expand Down Expand Up @@ -710,7 +711,7 @@ contexts:
1: punctuation.definition.keyword.css
push:
- at-layer-meta
- maybe-style-block
- maybe-stylesheet-block
- at-layer-name-list

nested-at-layer:
Expand Down Expand Up @@ -768,7 +769,7 @@ contexts:
1: punctuation.definition.keyword.css
push:
- at-media-meta
- maybe-style-block
- maybe-stylesheet-block
- media-query-list

nested-at-media:
Expand Down Expand Up @@ -933,7 +934,7 @@ contexts:
1: punctuation.definition.keyword.css
push:
- at-supports-meta
- maybe-style-block
- maybe-stylesheet-block
- at-supports-query

nested-at-supports:
Expand Down Expand Up @@ -1154,12 +1155,7 @@ contexts:
###[ SELECTORS ]###############################################################

selectors:
- match: '{{selector_begin}}'
push: selector-body

nested-selectors:
# https://drafts.csswg.org/css-nesting-1
- match: '{{nested_selector_begin}}'
- match: '{{property_or_selector_begin}}'
push: selector-body

selector-body:
Expand Down Expand Up @@ -1482,19 +1478,17 @@ contexts:
fail: pseudo-element
- include: identifier-content

###[ STYLE BLOCKS ]############################################################
###[ STYLESHEET BLOCKS ]#######################################################

maybe-style-block:
# https://www.w3.org/TR/css-syntax-3/#declaration-rule-list
# https://www.w3.org/TR/css-syntax-3/#typedef-style-block
maybe-stylesheet-block:
- meta_include_prototype: false
- match: \{
scope: punctuation.section.block.begin.css
set: style-block-body
set: stylesheet-block-body
- include: comments
- include: else-pop

style-block-body:
stylesheet-block-body:
- meta_include_prototype: false
- meta_scope: meta.block.css
- include: block-end
Expand All @@ -1516,21 +1510,25 @@ contexts:
push: property-list-body

property-list-body:
# According to official specs, this is a style-block.
# It supports declarations, nested style-rules and at-rules.
# https://www.w3.org/TR/css-syntax-3/#typedef-style-block
- meta_include_prototype: false
- meta_scope: meta.property-list.css meta.block.css
- include: block-end
- include: comments
- include: property-lists
- include: property-identifiers
- include: nested-selectors
- include: properties-or-selectors
- include: nested-at-rules
- include: rule-terminators
- include: illegal-commas
- include: illegal-groups

rule-list-body:
# Note: This context is used by HTML.sublime-syntax
# No selectors supported in style attributes.
# According to official specs, this is a declaration-list without support
# for at-rules as inline html attributes don't support them.
# https://www.w3.org/TR/css-syntax-3/#typedef-declaration-list
- include: comments
- include: property-identifiers
- include: property-values
Expand All @@ -1541,6 +1539,24 @@ contexts:

###[ PROPERTY IDENTIFIERS ]####################################################

properties-or-selectors:
- match: '{{property_or_selector_begin}}'
branch_point: property-or-selector
branch:
- maybe-property
- selector-body

maybe-property:
- meta_include_prototype: false
- include: property-end
- include: property-identifiers
- match: ''
fail: property-or-selector

property-end:
- match: '{{property_end}}'
pop: 1

property-identifiers:
# specific properties with special treatment
- include: counter-properties
Expand Down Expand Up @@ -2917,7 +2933,7 @@ contexts:
# Qualified Names
# https://drafts.csswg.org/css-namespaces-3/#css-qnames
attr-name:
- match: (?=[*|]|--|-?{{ident_start}})
- match: (?=[*|]|{{ident_begin}})
set: attr-name-content

attr-name-content:
Expand Down
33 changes: 19 additions & 14 deletions CSS/syntax_test_css.css
Original file line number Diff line number Diff line change
Expand Up @@ -717,7 +717,7 @@
/* ^^ meta.property-list.css meta.block.css - meta.at-rule */
/* ^^^^^^^^^^^^^^^^ meta.property-list.css meta.block.css meta.at-rule.container.css - meta.group - meta.block meta.block */
/* ^^ meta.property-list.css meta.block.css meta.at-rule.container.css meta.block.css - meta.block.css meta.block.css meta.block.css - meta.sepector */
/* ^^^^^^ meta.property-list.css meta.block.css meta.at-rule.container.css meta.property-list.css meta.block.css - meta.selector */
/* ^^^^^^ meta.property-list.css meta.block.css meta.at-rule.container.css meta.property-list.css meta.block.css meta.selector.css */
/* ^^ meta.property-list.css meta.block.css meta.at-rule.container.css meta.property-list.css meta.block.css meta.property-list.css meta.block.css */
/* ^^ meta.property-list.css meta.block.css meta.at-rule.container.css meta.property-list.css meta.block.css - meta.selector */
/* ^^^^^^^ meta.property-list.css meta.block.css meta.at-rule.container.css meta.property-list.css meta.block.css meta.selector.css */
Expand All @@ -731,7 +731,7 @@
/* ^^^^^^^^^^ keyword.control.directive.css */
/* ^^^^ entity.other.container.css */
/* ^ punctuation.section.block.begin.css */
/* ^^^^^ support.type.property-name.css - entity.name.tag */
/* ^^^^^ entity.name.tag.html.css */
/* ^ punctuation.section.block.begin.css */
/* ^ punctuation.section.block.end.css */
/* ^ punctuation.terminator.rule.css */
Expand Down Expand Up @@ -975,7 +975,7 @@
/* ^^^^^^^^^^^^^^^^^ meta.property-list.css meta.block.css meta.at-rule.media.css meta.group.css */
/* ^ meta.property-list.css meta.block.css meta.at-rule.media.css - meta.group - meta.block meta.block */
/* ^^ meta.property-list.css meta.block.css meta.at-rule.media.css meta.block.css - meta.block.css meta.block.css meta.block.css - meta.sepector */
/* ^^^^^^ meta.property-list.css meta.block.css meta.at-rule.media.css meta.property-list.css meta.block.css - meta.selector */
/* ^^^^^^ meta.property-list.css meta.block.css meta.at-rule.media.css meta.property-list.css meta.block.css meta.selector.css */
/* ^^ meta.property-list.css meta.block.css meta.at-rule.media.css meta.property-list.css meta.block.css meta.property-list.css meta.block.css */
/* ^^ meta.property-list.css meta.block.css meta.at-rule.media.css meta.property-list.css meta.block.css - meta.selector */
/* ^^^^^^^ meta.property-list.css meta.block.css meta.at-rule.media.css meta.property-list.css meta.block.css meta.selector.css */
Expand All @@ -993,7 +993,7 @@
/* ^^^^^^ meta.number.integer.decimal.css */
/* ^ punctuation.section.group.end.css */
/* ^ punctuation.section.block.begin.css */
/* ^^^^^ support.type.property-name.css - entity.name.tag */
/* ^^^^^ entity.name.tag.html.css */
/* ^ punctuation.section.block.begin.css */
/* ^ punctuation.section.block.end.css */
/* ^ punctuation.terminator.rule.css */
Expand Down Expand Up @@ -1434,10 +1434,13 @@
/* ^^^^^^^^^^^ meta.at-rule.layer.css meta.block.css meta.at-rule.layer.css meta.block.css meta.property-list.css meta.block.css meta.at-rule.layer.css */
/* ^^ meta.at-rule.layer.css meta.block.css meta.at-rule.layer.css meta.block.css meta.property-list.css meta.block.css meta.at-rule.layer.css meta.property-list.css meta.block.css */
table {}
/* ^^^^^ - entity.name.tag */
/* ^^^^^^ meta.selector.css */
/* ^^^^^ entity.name.tag.html.css */

> table {}
/* ^^^^^^^^ meta.selector.css */
/* ^ keyword.operator.combinator.css */
/* ^^^^^ entity.name.tag.html.css */

font: inherit;
/* ^^^^ meta.property-name.css support.type.property-name.css */
Expand Down Expand Up @@ -1781,7 +1784,7 @@
/* ^^ meta.property-list.css meta.block.css - meta.at-rule */
/* ^^^^^^^^^^ meta.property-list.css meta.block.css meta.at-rule.supports.css - meta.group - meta.block meta.block */
/* ^^ meta.property-list.css meta.block.css meta.at-rule.supports.css meta.block.css - meta.block.css meta.block.css meta.block.css - meta.sepector */
/* ^^^^^^ meta.property-list.css meta.block.css meta.at-rule.supports.css meta.property-list.css meta.block.css - meta.selector */
/* ^^^^^^ meta.property-list.css meta.block.css meta.at-rule.supports.css meta.property-list.css meta.block.css meta.selector.css */
/* ^^ meta.property-list.css meta.block.css meta.at-rule.supports.css meta.property-list.css meta.block.css meta.property-list.css meta.block.css */
/* ^^ meta.property-list.css meta.block.css meta.at-rule.supports.css meta.property-list.css meta.block.css - meta.selector */
/* ^^^^^^^ meta.property-list.css meta.block.css meta.at-rule.supports.css meta.property-list.css meta.block.css meta.selector.css */
Expand All @@ -1794,7 +1797,7 @@
/* ^ - meta.property-list - meta.block */
/* ^^^^^^^^^ keyword.control.directive.css */
/* ^ punctuation.section.block.begin.css */
/* ^^^^^ support.type.property-name.css - entity.name.tag */
/* ^^^^^ entity.name.tag.html.css */
/* ^ punctuation.section.block.begin.css */
/* ^ punctuation.section.block.end.css */
/* ^ punctuation.terminator.rule.css */
Expand Down Expand Up @@ -2814,7 +2817,7 @@
/* ^^ meta.property-list.css meta.block.css - meta.property-list meta.property-list - meta.block meta.block */
/* ^ - meta.property-list */
/* ^ punctuation.section.block.begin.css */
/* ^^^^^ meta.property-name.css support.type.property-name.css */
/* ^^^^^ meta.selector.css entity.name.tag.other.css */
/* ^ punctuation.section.block.begin.css */
/* ^ punctuation.terminator.rule.css */
/* ^^^^^ support.type.property-name.css */
Expand All @@ -2830,7 +2833,7 @@
/* ^^^^^^^^^^^^^^^ meta.property-list.css meta.block.css - meta.property-list meta.property-list - meta.block meta.block */
/* ^ - meta.property-list */
/* ^ punctuation.section.block.begin.css */
/* ^^^^^ meta.property-name.css support.type.property-name.css */
/* ^^^^^ meta.selector.css entity.name.tag.other.css */
/* ^ punctuation.section.block.begin.css */
/* ^ punctuation.terminator.rule.css */
/* ^^^^^ support.type.property-name.css */
Expand Down Expand Up @@ -4348,17 +4351,19 @@ img{
/* ^ variable.language.parent.css */
/* ^^^^^^^ entity.name.tag.html.css */
article { ... }
/* ^^^^^^^^ meta.property-list.css meta.block.css - meta.selector */
/* ^^^^^^^^ meta.property-list.css meta.block.css meta.selector.css */
/* ^^^^^^^ entity.name.tag.html.css */
}

.foo:bar > tr.baz[test], div p {
/* <- meta.selector.css entity.other.attribute-name.class.css punctuation.definition.entity.css */
/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.selector.css */
foo:bar {
/* ^^^ meta.property-list.css meta.block.css meta.property-name.css support.type.property-name.css */
/* ^ meta.property-list.css meta.block.css punctuation.separator.key-value.css*/
/* ^^^ meta.property-list.css meta.block.css meta.property-value.css support.constant.property-value.css*/
/* ^^ meta.property-list.css meta.block.css meta.property-list.css meta.block.css */
/* ^^^^^^^^ meta.property-list.css meta.block.css meta.selector.css */
/* ^^^ entity.name.tag.other.css */
/* ^ punctuation.definition.pseudo-class.css */
/* ^^^ entity.other.pseudo-class.css */
/* ^^ meta.property-list.css meta.block.css meta.property-list.css meta.block.css - meta.selector*/
/* ^ punctuation.section.block.begin.css */
foo:bar;
/* ^^^^^^^^^^ meta.property-list.css meta.block.css meta.property-list.css meta.block.css */
Expand Down

0 comments on commit b4decd9

Please sign in to comment.