Skip to content

Commit

Permalink
optimize "all" property
Browse files Browse the repository at this point in the history
  • Loading branch information
devongovett committed May 14, 2024
1 parent baa1a2b commit d7aeff3
Show file tree
Hide file tree
Showing 9 changed files with 200 additions and 35 deletions.
7 changes: 4 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ const-str = "0.3.1"
pathdiff = "0.2.1"
ahash = "0.8.7"
paste = "1.0.12"
indexmap = "2.2.6"
# CLI deps
atty = { version = "0.2", optional = true }
clap = { version = "3.0.6", features = ["derive"], optional = true }
Expand Down
34 changes: 32 additions & 2 deletions node/ast.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2066,6 +2066,12 @@ export type PropertyId =
property: "text-size-adjust";
vendorPrefix: VendorPrefix;
}
| {
property: "direction";
}
| {
property: "unicode-bidi";
}
| {
property: "box-decoration-break";
vendorPrefix: VendorPrefix;
Expand Down Expand Up @@ -3445,6 +3451,14 @@ export type Declaration =
value: TextSizeAdjust;
vendorPrefix: VendorPrefix;
}
| {
property: "direction";
value: Direction2;
}
| {
property: "unicode-bidi";
value: UnicodeBidi;
}
| {
property: "box-decoration-break";
value: BoxDecorationBreak;
Expand Down Expand Up @@ -3757,6 +3771,10 @@ export type Declaration =
property: "color-scheme";
value: ColorScheme;
}
| {
property: "all";
value: CSSWideKeyword;
}
| {
property: "unparsed";
value: UnparsedProperty;
Expand Down Expand Up @@ -5729,6 +5747,14 @@ export type TextSizeAdjust =
type: "percentage";
value: number;
};
/**
* A value for the [direction](https://drafts.csswg.org/css-writing-modes-3/#direction) property.
*/
export type Direction2 = "ltr" | "rtl";
/**
* A value for the [unicode-bidi](https://drafts.csswg.org/css-writing-modes-3/#unicode-bidi) property.
*/
export type UnicodeBidi = "normal" | "embed" | "isolate" | "bidi-override" | "isolate-override" | "plaintext";
/**
* A value for the [box-decoration-break](https://www.w3.org/TR/css-break-3/#break-decoration) property.
*/
Expand Down Expand Up @@ -6234,6 +6260,10 @@ export type ContainerNameList =
type: "names";
value: String[];
};
/**
* A [CSS-wide keyword](https://drafts.csswg.org/css-cascade-5/#defaulting-keywords).
*/
export type CSSWideKeyword = "initial" | "inherit" | "unset" | "revert" | "revert-layer";
/**
* A CSS custom property name.
*/
Expand Down Expand Up @@ -7040,8 +7070,8 @@ export type ParsedComponent =
};
}
| {
type: "token";
value: Token;
type: "token-list";
value: TokenOrValue[];
};
/**
* A [multiplier](https://drafts.css-houdini.org/css-properties-values-api/#multipliers) for a [SyntaxComponent](SyntaxComponent). Indicates whether and how the component may be repeated.
Expand Down
4 changes: 2 additions & 2 deletions node/test/visitor.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ test('custom units', () => {
}
});

assert.equal(res.code.toString(), '.foo{--step:.25rem;font-size:calc(3*var(--step))}');
assert.equal(res.code.toString(), '.foo{font-size:calc(3*var(--step));--step:.25rem}');
});

test('design tokens', () => {
Expand Down Expand Up @@ -822,7 +822,7 @@ test('dashed idents', () => {
}
});

assert.equal(res.code.toString(), '.foo{--prefix-foo:#ff0;color:var(--prefix-foo)}');
assert.equal(res.code.toString(), '.foo{color:var(--prefix-foo);--prefix-foo:#ff0}');
});

test('custom idents', () => {
Expand Down
66 changes: 53 additions & 13 deletions src/declaration.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
//! CSS declarations.

use std::borrow::Cow;
use std::collections::HashMap;
use std::ops::Range;

use crate::context::{DeclarationContext, PropertyHandlerContext};
Expand All @@ -11,6 +10,7 @@ use crate::printer::Printer;
use crate::properties::box_shadow::BoxShadowHandler;
use crate::properties::custom::{CustomProperty, CustomPropertyName};
use crate::properties::masking::MaskHandler;
use crate::properties::text::{Direction, UnicodeBidi};
use crate::properties::{
align::AlignHandler,
animation::AnimationHandler,
Expand All @@ -33,13 +33,14 @@ use crate::properties::{
transition::TransitionHandler,
ui::ColorSchemeHandler,
};
use crate::properties::{Property, PropertyId};
use crate::properties::{CSSWideKeyword, Property, PropertyId};
use crate::traits::{PropertyHandler, ToCss};
use crate::values::ident::DashedIdent;
use crate::values::string::CowArcStr;
#[cfg(feature = "visitor")]
use crate::visitor::Visit;
use cssparser::*;
use indexmap::IndexMap;

/// A CSS declaration block.
///
Expand Down Expand Up @@ -515,7 +516,10 @@ pub(crate) struct DeclarationHandler<'i> {
color_scheme: ColorSchemeHandler,
fallback: FallbackHandler,
prefix: PrefixHandler,
custom_properties: HashMap<DashedIdent<'i>, usize>,
all: Option<CSSWideKeyword>,
direction: Option<Direction>,
unicode_bidi: Option<UnicodeBidi>,
custom_properties: IndexMap<DashedIdent<'i>, CustomProperty<'i>>,
decls: DeclarationList<'i>,
}

Expand Down Expand Up @@ -552,6 +556,7 @@ impl<'i> DeclarationHandler<'i> {
|| self.color_scheme.handle_property(property, &mut self.decls, context)
|| self.fallback.handle_property(property, &mut self.decls, context)
|| self.prefix.handle_property(property, &mut self.decls, context)
|| self.handle_all(property)
|| self.handle_custom_property(property, context)
}

Expand All @@ -566,18 +571,13 @@ impl<'i> DeclarationHandler<'i> {
}

if let CustomPropertyName::Custom(name) = &custom.name {
if let Some(index) = self.custom_properties.get(name) {
if self.decls[*index] == *property {
if let Some(prev) = self.custom_properties.get_mut(name) {
if prev.value == custom.value {
return true;
}
let mut custom = custom.clone();
self.add_conditional_fallbacks(&mut custom, context);
self.decls[*index] = Property::Custom(custom);
*prev = custom.clone();
} else {
self.custom_properties.insert(name.clone(), self.decls.len());
let mut custom = custom.clone();
self.add_conditional_fallbacks(&mut custom, context);
self.decls.push(Property::Custom(custom));
self.custom_properties.insert(name.clone(), custom.clone());
}

return true;
Expand All @@ -587,6 +587,32 @@ impl<'i> DeclarationHandler<'i> {
false
}

fn handle_all(&mut self, property: &Property<'i>) -> bool {
// The `all` property resets all properies except `unicode-bidi`, `direction`, and custom properties.
// https://drafts.csswg.org/css-cascade-5/#all-shorthand
match property {
Property::UnicodeBidi(bidi) => {
self.unicode_bidi = Some(*bidi);
true
}
Property::Direction(direction) => {
self.direction = Some(*direction);
true
}
Property::All(keyword) => {
*self = DeclarationHandler {
custom_properties: std::mem::take(&mut self.custom_properties),
unicode_bidi: self.unicode_bidi.clone(),
direction: self.direction.clone(),
all: Some(keyword.clone()),
..Default::default()
};
true
}
_ => false,
}
}

fn add_conditional_fallbacks(
&self,
custom: &mut CustomProperty<'i>,
Expand All @@ -607,6 +633,21 @@ impl<'i> DeclarationHandler<'i> {
}

pub fn finalize(&mut self, context: &mut PropertyHandlerContext<'i, '_>) {
// Always place the `all` property first. Previous properties will have been omitted.
if let Some(all) = std::mem::take(&mut self.all) {
self.decls.push(Property::All(all));
}
if let Some(direction) = std::mem::take(&mut self.direction) {
self.decls.push(Property::Direction(direction));
}
if let Some(unicode_bidi) = std::mem::take(&mut self.unicode_bidi) {
self.decls.push(Property::UnicodeBidi(unicode_bidi));
}
for (_, mut value) in std::mem::take(&mut self.custom_properties) {
self.add_conditional_fallbacks(&mut value, context);
self.decls.push(Property::Custom(value));
}

self.background.finalize(&mut self.decls, context);
self.border.finalize(&mut self.decls, context);
self.outline.finalize(&mut self.decls, context);
Expand Down Expand Up @@ -634,6 +675,5 @@ impl<'i> DeclarationHandler<'i> {
self.color_scheme.finalize(&mut self.decls, context);
self.fallback.finalize(&mut self.decls, context);
self.prefix.finalize(&mut self.decls, context);
self.custom_properties.clear();
}
}
41 changes: 34 additions & 7 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21435,26 +21435,26 @@ mod tests {
indoc! {r#"
@keyframes foo {
from {
--custom: #ff0;
opacity: 0;
--custom: #ff0;
}

to {
--custom: #ee00be;
opacity: 1;
--custom: #ee00be;
}
}

@supports (color: lab(0% 0 0)) {
@keyframes foo {
from {
--custom: #ff0;
opacity: 0;
--custom: #ff0;
}

to {
--custom: lab(50.998% 125.506 -50.7078);
opacity: 1;
--custom: lab(50.998% 125.506 -50.7078);
}
}
}
Expand Down Expand Up @@ -23457,8 +23457,8 @@ mod tests {
}

.EgL3uq_foo {
--foo: red;
color: var(--foo);
--foo: red;
}
"#},
map! {
Expand Down Expand Up @@ -23507,10 +23507,10 @@ mod tests {
}

.EgL3uq_foo {
--EgL3uq_foo: red;
--EgL3uq_bar: green;
color: var(--EgL3uq_foo);
font-palette: --EgL3uq_Cooler;
--EgL3uq_foo: red;
--EgL3uq_bar: green;
}

.EgL3uq_bar {
Expand Down Expand Up @@ -27244,4 +27244,31 @@ mod tests {
},
);
}

#[test]
fn test_all() {
minify_test(".foo { all: initial; all: initial }", ".foo{all:initial}");
minify_test(".foo { all: initial; all: revert }", ".foo{all:revert}");
minify_test(".foo { background: red; all: revert-layer }", ".foo{all:revert-layer}");
minify_test(
".foo { background: red; all: revert-layer; background: green }",
".foo{all:revert-layer;background:green}",
);
minify_test(
".foo { --test: red; all: revert-layer }",
".foo{all:revert-layer;--test:red}",
);
minify_test(
".foo { unicode-bidi: embed; all: revert-layer }",
".foo{all:revert-layer;unicode-bidi:embed}",
);
minify_test(
".foo { direction: rtl; all: revert-layer }",
".foo{all:revert-layer;direction:rtl}",
);
minify_test(
".foo { direction: rtl; all: revert-layer; direction: ltr }",
".foo{all:revert-layer;direction:ltr}",
);
}
}
Loading

0 comments on commit d7aeff3

Please sign in to comment.