Skip to content

Add support for modern CSS at-rules @layer, @scope, and @starting-style#1549

Open
samuil-banti-wpenigne wants to merge 4 commits intoMyIntervals:mainfrom
samuil-banti-wpenigne:add-support-for-at-rules-layer-scope-and-starting-style
Open

Add support for modern CSS at-rules @layer, @scope, and @starting-style#1549
samuil-banti-wpenigne wants to merge 4 commits intoMyIntervals:mainfrom
samuil-banti-wpenigne:add-support-for-at-rules-layer-scope-and-starting-style

Conversation

@samuil-banti-wpenigne
Copy link
Contributor

No description provided.

@samuil-banti-wpenigne
Copy link
Contributor Author

@oliverklee it seems like there's an issue accessing coveralls.io

@oliverklee
Copy link
Collaborator

Yes, Coveralls currently is down.

Copy link
Collaborator

@JakeQZ JakeQZ left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks excellent, thanks <3

The tests are fairly comprehensive, but I'd like a few more to confirm what does and doesn't work now.

I think the tests for @scope parsing would be better handled by using a data provider for the argument, so that we can throw whatever we like at it (I suggest the various examples on the MDN documentation page). If some constructs don't work, they can be commented out with a comment in the data provider array indicating that a further fix is needed.

It would also be good to know if @layer statement rules are now also parsed and rendered correctly following this change (as well as @layer block rules, which are covered in the tests added).

It might be helpful to split this PR into three manageable chunks for each at-rule. But if it's a hassle to do that, it's nae bother.

If you rebase, the Coveralls build failure will vanish, following #1551.

Comment on lines 147 to 162
/**
* @test
*/
public function parsesScopeWithSelector(): void
{
$css = '@scope (.card) { .title { font-size: 2rem; } }';
$contents = (new Parser($css))->parse()->getContents();
$atRuleBlockList = $contents[0];

self::assertInstanceOf(AtRuleBlockList::class, $atRuleBlockList);
self::assertSame('scope', $atRuleBlockList->atRuleName());
self::assertSame('(.card)', $atRuleBlockList->atRuleArgs());

$nestedContents = $atRuleBlockList->getContents();
self::assertCount(1, $nestedContents, 'Scope should contain one declaration block');
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does parsing with a scope limit also work following this change? And parsing with a selector list? If so, we should perhaps add tests to confirm this.

We could use a data provider to provide various @scope arguments, perhaps lifted from the MDN examples, so we'd only need one @test method, which would insert the argument into $css, and check it in assertSame( ... atRuleArgs()). This may also work for @scope without an argument.

Comment on lines 113 to 128
/**
* @test
*/
public function parsesLayerWithNamedArgument(): void
{
$css = '@layer theme { .button { color: blue; } }';
$contents = (new Parser($css))->parse()->getContents();
$atRuleBlockList = $contents[0];

self::assertInstanceOf(AtRuleBlockList::class, $atRuleBlockList);
self::assertSame('layer', $atRuleBlockList->atRuleName());
self::assertSame('theme', $atRuleBlockList->atRuleArgs());

$nestedContents = $atRuleBlockList->getContents();
self::assertCount(1, $nestedContents, 'Layer should contain one declaration block');
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does parsing a statement @layer rule like

@layer theme, layout, utilities;

also work following this change?

If it does, we should add tests to confirm. If not, that will be for a future PR.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nope, it doesn't work currently :(
The parser discards @layer theme, layout, utilities; and returns an empty contents array and renders nothing.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nope, it doesn't work currently :(

I feared that would be the case. There are statement at-rules, and block at-rules, and @layer can be either. Some congnitive effort and refactoring will likely be required to support both flavours of @layer (as a future PR).

/**
* Since there are more set rules than block rules,
* we’re whitelisting the block rules and have anything else be treated as a set rule.
* NOTE: The new line when assigning the value is added to avoid the line length limit of codesniffer.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment belongs in the PR discussion or commit message, not the code.

Suggested change
* NOTE: The new line when assigning the value is added to avoid the line length limit of codesniffer.

* @internal since 8.5.2
*/
public const BLOCK_RULES = 'media/document/supports/region-style/font-feature-values/container';
public const BLOCK_RULES =
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to change this to an array, but that's for another PR.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems like a quick win. Are you sure you want it in a separate PR?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems like a quick win. Are you sure you want it in a separate PR?

Having PRs only addressing one thing makes it easier to backport them or temporarily undo them if a problem is found. So, yes.

Use data providers for AtRules parsing and rendering
Copy link
Collaborator

@JakeQZ JakeQZ left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The refactored tests look good. Can we add one for @scope with a 'limit' - or does that not work yet?

Some of the parameters can be declared as non-empty-string but I'm happy to do that as a follow-up PR.

The superfluous DocBlock comment still needs taking out.

Comment on lines +131 to +136
'scope with selector' => [
'@scope (.card) { .title { font-size: 2rem; } }',
'scope',
'(.card)',
1,
],
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be possible to have a test for scope with a limt, e.g. @scope (.article-body) to (figure)? Or does that not currently parse correctly?

/**
* Since there are more set rules than block rules,
* we’re whitelisting the block rules and have anything else be treated as a set rule.
* NOTE: The new line when assigning the value is added to avoid the line length limit of codesniffer.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This still needs to be removed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants