Skip to content

Commit 552c9e4

Browse files
committed
Replace the SAC-based value model with internal records
Introduce CssValues, a small sealed hierarchy of immutable value records (CssNumber, CssDimension, CssText, CssColor, CssOperator, CssList) that the parser now builds directly. This removes the LexicalUnit-based value construction and the last dependency on org.w3c.css.sac: delete Measure, RGBColorImpl, CSSValueListImpl, CSSValueFactory and LexicalUnitImpl, and drop the org.w3c.css.sac Import-Package from the bundle. The records still implement the W3C CSSValue / CSSPrimitiveValue / CSSValueList / RGBColor interfaces, so the ~96 property handlers and converters that read values keep working unchanged; they move to pattern matching in a later step, after which the W3C interfaces can be dropped. css.core (119) and css.swt (210) suites stay green.
1 parent 50c7151 commit 552c9e4

9 files changed

Lines changed: 332 additions & 556 deletions

File tree

bundles/org.eclipse.e4.ui.css.core/META-INF/MANIFEST.MF

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ Export-Package: org.eclipse.e4.ui.css.core.css2;x-friends:="org.eclipse.e4.ui.cs
3434
org.eclipse.e4.ui.css.core.util.impl.resources;x-friends:="org.eclipse.e4.ui.css.swt.theme,org.eclipse.e4.ui.workbench.swt",
3535
org.eclipse.e4.ui.css.core.util.resources;x-friends:="org.eclipse.e4.ui.css.swt,org.eclipse.e4.ui.css.swt.theme,org.eclipse.e4.ui.workbench.swt",
3636
org.eclipse.e4.ui.css.core.utils;x-friends:="org.eclipse.e4.ui.css.swt"
37-
Import-Package: org.w3c.css.sac;version="1.3.0"
3837
Require-Bundle: org.eclipse.equinox.common;bundle-version="[3.5.0,4.0.0)",
3938
org.eclipse.core.runtime;bundle-version="[3.29.0,4.0.0)"
4039
Bundle-RequiredExecutionEnvironment: JavaSE-17

bundles/org.eclipse.e4.ui.css.core/src/org/eclipse/e4/ui/css/core/impl/dom/CSSValueFactory.java

Lines changed: 0 additions & 42 deletions
This file was deleted.

bundles/org.eclipse.e4.ui.css.core/src/org/eclipse/e4/ui/css/core/impl/dom/CSSValueListImpl.java

Lines changed: 0 additions & 77 deletions
This file was deleted.
Lines changed: 256 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,256 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2026 Lars Vogel and others.
3+
*
4+
* This program and the accompanying materials
5+
* are made available under the terms of the Eclipse Public License 2.0
6+
* which accompanies this distribution, and is available at
7+
* https://www.eclipse.org/legal/epl-2.0/
8+
*
9+
* SPDX-License-Identifier: EPL-2.0
10+
*
11+
* Contributors:
12+
* Lars Vogel <Lars.Vogel@vogella.com> - initial API and implementation
13+
*******************************************************************************/
14+
package org.eclipse.e4.ui.css.core.impl.dom;
15+
16+
import java.util.List;
17+
18+
import org.w3c.dom.DOMException;
19+
import org.w3c.dom.css.CSSPrimitiveValue;
20+
import org.w3c.dom.css.CSSValue;
21+
import org.w3c.dom.css.CSSValueList;
22+
import org.w3c.dom.css.Counter;
23+
import org.w3c.dom.css.RGBColor;
24+
import org.w3c.dom.css.Rect;
25+
26+
/**
27+
* The internal CSS value model produced by the parser. A small sealed hierarchy
28+
* of immutable values that replaces the former {@code Measure} / {@code
29+
* RGBColorImpl} / {@code CSSValueListImpl} wrappers and removes the last SAC
30+
* dependency ({@code LexicalUnit}).
31+
*
32+
* <p>
33+
* The variants still implement the W3C DOM-CSS interfaces so the property
34+
* handlers and converters that read values through {@link CSSValue} /
35+
* {@link CSSPrimitiveValue} keep working unchanged. Those consumers move to
36+
* pattern matching on the records in a later step, after which the W3C
37+
* interfaces can be dropped.
38+
* </p>
39+
*/
40+
public final class CssValues {
41+
42+
private CssValues() {
43+
// constants only
44+
}
45+
46+
/** A parsed CSS value: either a primitive or a whitespace/comma separated list. */
47+
public sealed interface CssValue extends CSSValue permits CssPrimitive, CssList {
48+
}
49+
50+
/**
51+
* A single CSS value. Provides the W3C boilerplate; concrete variants only
52+
* implement {@link #getPrimitiveType()}, {@link #getCssText()} and whichever
53+
* of {@link #getFloatValue(short)} / {@link #getStringValue()} /
54+
* {@link #getRGBColorValue()} applies.
55+
*/
56+
public sealed interface CssPrimitive extends CssValue, CSSPrimitiveValue
57+
permits CssNumber, CssDimension, CssText, CssColor, CssOperator {
58+
59+
@Override
60+
default short getCssValueType() {
61+
return CSS_PRIMITIVE_VALUE;
62+
}
63+
64+
@Override
65+
default float getFloatValue(short unitType) throws DOMException {
66+
throw invalidAccess();
67+
}
68+
69+
@Override
70+
default String getStringValue() throws DOMException {
71+
throw invalidAccess();
72+
}
73+
74+
@Override
75+
default RGBColor getRGBColorValue() throws DOMException {
76+
throw invalidAccess();
77+
}
78+
79+
@Override
80+
default Counter getCounterValue() throws DOMException {
81+
throw invalidAccess();
82+
}
83+
84+
@Override
85+
default Rect getRectValue() throws DOMException {
86+
throw invalidAccess();
87+
}
88+
89+
@Override
90+
default void setCssText(String cssText) throws DOMException {
91+
throw readOnly();
92+
}
93+
94+
@Override
95+
default void setFloatValue(short unitType, float floatValue) throws DOMException {
96+
throw readOnly();
97+
}
98+
99+
@Override
100+
default void setStringValue(short stringType, String stringValue) throws DOMException {
101+
throw readOnly();
102+
}
103+
}
104+
105+
/** {@code 34} or {@code 2.0} - a unitless number. */
106+
public record CssNumber(double value, boolean integer) implements CssPrimitive {
107+
@Override
108+
public short getPrimitiveType() {
109+
return CSS_NUMBER;
110+
}
111+
112+
@Override
113+
public float getFloatValue(short unitType) {
114+
return (float) value;
115+
}
116+
117+
@Override
118+
public String getCssText() {
119+
return integer ? Integer.toString((int) value) : Float.toString((float) value);
120+
}
121+
}
122+
123+
/** {@code 26px}, {@code 30%}, {@code 75em} - a number with a unit. */
124+
public record CssDimension(double value, short primitiveType, String unit) implements CssPrimitive {
125+
@Override
126+
public short getPrimitiveType() {
127+
return primitiveType;
128+
}
129+
130+
@Override
131+
public float getFloatValue(short unitType) {
132+
return (float) value;
133+
}
134+
135+
@Override
136+
public String getCssText() {
137+
return (float) value + unit;
138+
}
139+
}
140+
141+
/** {@code red}, {@code 'a string'}, {@code url(x)}, {@code inherit}. */
142+
public record CssText(short primitiveType, String value) implements CssPrimitive {
143+
@Override
144+
public short getPrimitiveType() {
145+
return primitiveType;
146+
}
147+
148+
@Override
149+
public String getStringValue() {
150+
return value;
151+
}
152+
153+
@Override
154+
public String getCssText() {
155+
return switch (primitiveType) {
156+
case CSS_URI -> "url(" + value + ")"; //$NON-NLS-1$ //$NON-NLS-2$
157+
default -> value;
158+
};
159+
}
160+
}
161+
162+
/** {@code rgb(...)} or a {@code #rgb} / {@code #rrggbb} colour. */
163+
public record CssColor(CssPrimitive red, CssPrimitive green, CssPrimitive blue)
164+
implements CssPrimitive, RGBColor {
165+
@Override
166+
public short getPrimitiveType() {
167+
return CSS_RGBCOLOR;
168+
}
169+
170+
@Override
171+
public RGBColor getRGBColorValue() {
172+
return this;
173+
}
174+
175+
@Override
176+
public CSSPrimitiveValue getRed() {
177+
return red;
178+
}
179+
180+
@Override
181+
public CSSPrimitiveValue getGreen() {
182+
return green;
183+
}
184+
185+
@Override
186+
public CSSPrimitiveValue getBlue() {
187+
return blue;
188+
}
189+
190+
@Override
191+
public String getCssText() {
192+
return "rgb(" + red.getCssText() + ", " + green.getCssText() + ", " + blue.getCssText() + ")"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
193+
}
194+
}
195+
196+
/**
197+
* A separator (currently only {@code ,}) carried inside a value list, kept
198+
* for parity with the former SAC behaviour where the comma was a list item.
199+
*/
200+
public record CssOperator(String text) implements CssPrimitive {
201+
@Override
202+
public short getPrimitiveType() {
203+
return CSS_CUSTOM;
204+
}
205+
206+
@Override
207+
public String getCssText() {
208+
return text;
209+
}
210+
}
211+
212+
/** A whitespace or comma separated sequence of values, e.g. {@code 1px 2px 3px}. */
213+
public record CssList(List<CssValue> values) implements CssValue, CSSValueList {
214+
215+
public CssList {
216+
values = List.copyOf(values);
217+
}
218+
219+
@Override
220+
public short getCssValueType() {
221+
return CSS_VALUE_LIST;
222+
}
223+
224+
@Override
225+
public int getLength() {
226+
return values.size();
227+
}
228+
229+
@Override
230+
public CSSValue item(int index) {
231+
return values.get(index);
232+
}
233+
234+
@Override
235+
public String getCssText() {
236+
StringBuilder sb = new StringBuilder();
237+
for (CssValue value : values) {
238+
sb.append(value.getCssText()).append(' ');
239+
}
240+
return sb.toString().trim();
241+
}
242+
243+
@Override
244+
public void setCssText(String cssText) throws DOMException {
245+
throw readOnly();
246+
}
247+
}
248+
249+
private static DOMException invalidAccess() {
250+
return new DOMException(DOMException.INVALID_ACCESS_ERR, "Value does not support this access"); //$NON-NLS-1$
251+
}
252+
253+
private static DOMException readOnly() {
254+
return new DOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR, "CSS value is read-only"); //$NON-NLS-1$
255+
}
256+
}

0 commit comments

Comments
 (0)