Skip to content

Commit

Permalink
[CSS] Relaxed Nesting
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
deathaxe committed Dec 29, 2023
1 parent e420984 commit b6568b0
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 29 deletions.
42 changes: 27 additions & 15 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 @@ -1154,12 +1154,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 @@ -1521,16 +1516,15 @@ contexts:
- 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.
# No selectors or at-rules supported in style attributes.
- include: comments
- include: property-identifiers
- include: property-values
Expand All @@ -1541,6 +1535,24 @@ contexts:

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

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

maybe-property:
- include: comments
- include: property-end
- include: property-identifiers
- match: (?=\S)
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 +2929,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 b6568b0

Please sign in to comment.