Skip to content

Commit d7aeff3

Browse files
committed
optimize "all" property
1 parent baa1a2b commit d7aeff3

File tree

9 files changed

+200
-35
lines changed

9 files changed

+200
-35
lines changed

Cargo.lock

Lines changed: 4 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ const-str = "0.3.1"
6262
pathdiff = "0.2.1"
6363
ahash = "0.8.7"
6464
paste = "1.0.12"
65+
indexmap = "2.2.6"
6566
# CLI deps
6667
atty = { version = "0.2", optional = true }
6768
clap = { version = "3.0.6", features = ["derive"], optional = true }

node/ast.d.ts

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2066,6 +2066,12 @@ export type PropertyId =
20662066
property: "text-size-adjust";
20672067
vendorPrefix: VendorPrefix;
20682068
}
2069+
| {
2070+
property: "direction";
2071+
}
2072+
| {
2073+
property: "unicode-bidi";
2074+
}
20692075
| {
20702076
property: "box-decoration-break";
20712077
vendorPrefix: VendorPrefix;
@@ -3445,6 +3451,14 @@ export type Declaration =
34453451
value: TextSizeAdjust;
34463452
vendorPrefix: VendorPrefix;
34473453
}
3454+
| {
3455+
property: "direction";
3456+
value: Direction2;
3457+
}
3458+
| {
3459+
property: "unicode-bidi";
3460+
value: UnicodeBidi;
3461+
}
34483462
| {
34493463
property: "box-decoration-break";
34503464
value: BoxDecorationBreak;
@@ -3757,6 +3771,10 @@ export type Declaration =
37573771
property: "color-scheme";
37583772
value: ColorScheme;
37593773
}
3774+
| {
3775+
property: "all";
3776+
value: CSSWideKeyword;
3777+
}
37603778
| {
37613779
property: "unparsed";
37623780
value: UnparsedProperty;
@@ -5729,6 +5747,14 @@ export type TextSizeAdjust =
57295747
type: "percentage";
57305748
value: number;
57315749
};
5750+
/**
5751+
* A value for the [direction](https://drafts.csswg.org/css-writing-modes-3/#direction) property.
5752+
*/
5753+
export type Direction2 = "ltr" | "rtl";
5754+
/**
5755+
* A value for the [unicode-bidi](https://drafts.csswg.org/css-writing-modes-3/#unicode-bidi) property.
5756+
*/
5757+
export type UnicodeBidi = "normal" | "embed" | "isolate" | "bidi-override" | "isolate-override" | "plaintext";
57325758
/**
57335759
* A value for the [box-decoration-break](https://www.w3.org/TR/css-break-3/#break-decoration) property.
57345760
*/
@@ -6234,6 +6260,10 @@ export type ContainerNameList =
62346260
type: "names";
62356261
value: String[];
62366262
};
6263+
/**
6264+
* A [CSS-wide keyword](https://drafts.csswg.org/css-cascade-5/#defaulting-keywords).
6265+
*/
6266+
export type CSSWideKeyword = "initial" | "inherit" | "unset" | "revert" | "revert-layer";
62376267
/**
62386268
* A CSS custom property name.
62396269
*/
@@ -7040,8 +7070,8 @@ export type ParsedComponent =
70407070
};
70417071
}
70427072
| {
7043-
type: "token";
7044-
value: Token;
7073+
type: "token-list";
7074+
value: TokenOrValue[];
70457075
};
70467076
/**
70477077
* 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.

node/test/visitor.test.mjs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ test('custom units', () => {
116116
}
117117
});
118118

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

122122
test('design tokens', () => {
@@ -822,7 +822,7 @@ test('dashed idents', () => {
822822
}
823823
});
824824

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

828828
test('custom idents', () => {

src/declaration.rs

Lines changed: 53 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
//! CSS declarations.
22
33
use std::borrow::Cow;
4-
use std::collections::HashMap;
54
use std::ops::Range;
65

76
use crate::context::{DeclarationContext, PropertyHandlerContext};
@@ -11,6 +10,7 @@ use crate::printer::Printer;
1110
use crate::properties::box_shadow::BoxShadowHandler;
1211
use crate::properties::custom::{CustomProperty, CustomPropertyName};
1312
use crate::properties::masking::MaskHandler;
13+
use crate::properties::text::{Direction, UnicodeBidi};
1414
use crate::properties::{
1515
align::AlignHandler,
1616
animation::AnimationHandler,
@@ -33,13 +33,14 @@ use crate::properties::{
3333
transition::TransitionHandler,
3434
ui::ColorSchemeHandler,
3535
};
36-
use crate::properties::{Property, PropertyId};
36+
use crate::properties::{CSSWideKeyword, Property, PropertyId};
3737
use crate::traits::{PropertyHandler, ToCss};
3838
use crate::values::ident::DashedIdent;
3939
use crate::values::string::CowArcStr;
4040
#[cfg(feature = "visitor")]
4141
use crate::visitor::Visit;
4242
use cssparser::*;
43+
use indexmap::IndexMap;
4344

4445
/// A CSS declaration block.
4546
///
@@ -515,7 +516,10 @@ pub(crate) struct DeclarationHandler<'i> {
515516
color_scheme: ColorSchemeHandler,
516517
fallback: FallbackHandler,
517518
prefix: PrefixHandler,
518-
custom_properties: HashMap<DashedIdent<'i>, usize>,
519+
all: Option<CSSWideKeyword>,
520+
direction: Option<Direction>,
521+
unicode_bidi: Option<UnicodeBidi>,
522+
custom_properties: IndexMap<DashedIdent<'i>, CustomProperty<'i>>,
519523
decls: DeclarationList<'i>,
520524
}
521525

@@ -552,6 +556,7 @@ impl<'i> DeclarationHandler<'i> {
552556
|| self.color_scheme.handle_property(property, &mut self.decls, context)
553557
|| self.fallback.handle_property(property, &mut self.decls, context)
554558
|| self.prefix.handle_property(property, &mut self.decls, context)
559+
|| self.handle_all(property)
555560
|| self.handle_custom_property(property, context)
556561
}
557562

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

568573
if let CustomPropertyName::Custom(name) = &custom.name {
569-
if let Some(index) = self.custom_properties.get(name) {
570-
if self.decls[*index] == *property {
574+
if let Some(prev) = self.custom_properties.get_mut(name) {
575+
if prev.value == custom.value {
571576
return true;
572577
}
573-
let mut custom = custom.clone();
574-
self.add_conditional_fallbacks(&mut custom, context);
575-
self.decls[*index] = Property::Custom(custom);
578+
*prev = custom.clone();
576579
} else {
577-
self.custom_properties.insert(name.clone(), self.decls.len());
578-
let mut custom = custom.clone();
579-
self.add_conditional_fallbacks(&mut custom, context);
580-
self.decls.push(Property::Custom(custom));
580+
self.custom_properties.insert(name.clone(), custom.clone());
581581
}
582582

583583
return true;
@@ -587,6 +587,32 @@ impl<'i> DeclarationHandler<'i> {
587587
false
588588
}
589589

590+
fn handle_all(&mut self, property: &Property<'i>) -> bool {
591+
// The `all` property resets all properies except `unicode-bidi`, `direction`, and custom properties.
592+
// https://drafts.csswg.org/css-cascade-5/#all-shorthand
593+
match property {
594+
Property::UnicodeBidi(bidi) => {
595+
self.unicode_bidi = Some(*bidi);
596+
true
597+
}
598+
Property::Direction(direction) => {
599+
self.direction = Some(*direction);
600+
true
601+
}
602+
Property::All(keyword) => {
603+
*self = DeclarationHandler {
604+
custom_properties: std::mem::take(&mut self.custom_properties),
605+
unicode_bidi: self.unicode_bidi.clone(),
606+
direction: self.direction.clone(),
607+
all: Some(keyword.clone()),
608+
..Default::default()
609+
};
610+
true
611+
}
612+
_ => false,
613+
}
614+
}
615+
590616
fn add_conditional_fallbacks(
591617
&self,
592618
custom: &mut CustomProperty<'i>,
@@ -607,6 +633,21 @@ impl<'i> DeclarationHandler<'i> {
607633
}
608634

609635
pub fn finalize(&mut self, context: &mut PropertyHandlerContext<'i, '_>) {
636+
// Always place the `all` property first. Previous properties will have been omitted.
637+
if let Some(all) = std::mem::take(&mut self.all) {
638+
self.decls.push(Property::All(all));
639+
}
640+
if let Some(direction) = std::mem::take(&mut self.direction) {
641+
self.decls.push(Property::Direction(direction));
642+
}
643+
if let Some(unicode_bidi) = std::mem::take(&mut self.unicode_bidi) {
644+
self.decls.push(Property::UnicodeBidi(unicode_bidi));
645+
}
646+
for (_, mut value) in std::mem::take(&mut self.custom_properties) {
647+
self.add_conditional_fallbacks(&mut value, context);
648+
self.decls.push(Property::Custom(value));
649+
}
650+
610651
self.background.finalize(&mut self.decls, context);
611652
self.border.finalize(&mut self.decls, context);
612653
self.outline.finalize(&mut self.decls, context);
@@ -634,6 +675,5 @@ impl<'i> DeclarationHandler<'i> {
634675
self.color_scheme.finalize(&mut self.decls, context);
635676
self.fallback.finalize(&mut self.decls, context);
636677
self.prefix.finalize(&mut self.decls, context);
637-
self.custom_properties.clear();
638678
}
639679
}

src/lib.rs

Lines changed: 34 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21435,26 +21435,26 @@ mod tests {
2143521435
indoc! {r#"
2143621436
@keyframes foo {
2143721437
from {
21438-
--custom: #ff0;
2143921438
opacity: 0;
21439+
--custom: #ff0;
2144021440
}
2144121441

2144221442
to {
21443-
--custom: #ee00be;
2144421443
opacity: 1;
21444+
--custom: #ee00be;
2144521445
}
2144621446
}
2144721447

2144821448
@supports (color: lab(0% 0 0)) {
2144921449
@keyframes foo {
2145021450
from {
21451-
--custom: #ff0;
2145221451
opacity: 0;
21452+
--custom: #ff0;
2145321453
}
2145421454

2145521455
to {
21456-
--custom: lab(50.998% 125.506 -50.7078);
2145721456
opacity: 1;
21457+
--custom: lab(50.998% 125.506 -50.7078);
2145821458
}
2145921459
}
2146021460
}
@@ -23457,8 +23457,8 @@ mod tests {
2345723457
}
2345823458

2345923459
.EgL3uq_foo {
23460-
--foo: red;
2346123460
color: var(--foo);
23461+
--foo: red;
2346223462
}
2346323463
"#},
2346423464
map! {
@@ -23507,10 +23507,10 @@ mod tests {
2350723507
}
2350823508

2350923509
.EgL3uq_foo {
23510-
--EgL3uq_foo: red;
23511-
--EgL3uq_bar: green;
2351223510
color: var(--EgL3uq_foo);
2351323511
font-palette: --EgL3uq_Cooler;
23512+
--EgL3uq_foo: red;
23513+
--EgL3uq_bar: green;
2351423514
}
2351523515

2351623516
.EgL3uq_bar {
@@ -27244,4 +27244,31 @@ mod tests {
2724427244
},
2724527245
);
2724627246
}
27247+
27248+
#[test]
27249+
fn test_all() {
27250+
minify_test(".foo { all: initial; all: initial }", ".foo{all:initial}");
27251+
minify_test(".foo { all: initial; all: revert }", ".foo{all:revert}");
27252+
minify_test(".foo { background: red; all: revert-layer }", ".foo{all:revert-layer}");
27253+
minify_test(
27254+
".foo { background: red; all: revert-layer; background: green }",
27255+
".foo{all:revert-layer;background:green}",
27256+
);
27257+
minify_test(
27258+
".foo { --test: red; all: revert-layer }",
27259+
".foo{all:revert-layer;--test:red}",
27260+
);
27261+
minify_test(
27262+
".foo { unicode-bidi: embed; all: revert-layer }",
27263+
".foo{all:revert-layer;unicode-bidi:embed}",
27264+
);
27265+
minify_test(
27266+
".foo { direction: rtl; all: revert-layer }",
27267+
".foo{all:revert-layer;direction:rtl}",
27268+
);
27269+
minify_test(
27270+
".foo { direction: rtl; all: revert-layer; direction: ltr }",
27271+
".foo{all:revert-layer;direction:ltr}",
27272+
);
27273+
}
2724727274
}

0 commit comments

Comments
 (0)