Skip to content

Commit ce34aea

Browse files
committed
Replace SAC selector layer with an internal Selector AST and matcher
Replaces the vendored Batik/SAC selector tree with a small engine-internal selector model and a static matcher, the SAC parser layer aside. Adds a sealed Selector AST (records for type, class, id, attribute, pseudo, compound, and combinator forms) plus a static SelectorMatcher that walks an Element through it. A SAC->internal translator at the parser-output boundary in CSSDocumentHandlerImpl.startSelector feeds it, and CSSEngine.matches / parseSelectors now work on the internal AST: CSSEngineImpl.matches delegates to SelectorMatcher and applyConditionalPseudoStyle walks the internal AST instead of the SAC tree. The parser is configured with Batik's stock DefaultSelectorFactory and DefaultConditionFactory, so 23 vendored impl/sac/* selector and condition wrappers fall away, along with the dead ExtendedDocumentCSS.queryConditionSelector / querySelector methods and the SAC_*_CONDITION constants behind them. Specificity follows CSS 2.1 and the static-pseudo-instance carve-out from CSSPseudoClassConditionImpl is preserved, so cascade behaviour does not shift. Selectors.SelectorList exposes getLength()/item(int) and every record overrides toString() to return text() for readable selector text in error messages and rule.getSelectorText(). CSSEngineTest and SelectorTest are rewritten on the internal AST, and sixteen new matcher unit tests cover universal, type case-sensitivity, class, id, compound, descendant, child, attribute presence and word-match, pseudo-class, selector lists, and specificity arithmetic. The new package is exported x-friends to org.eclipse.e4.ui.tests.css.core for the tests. Three impl/sac classes (CSSDocumentHandlerImpl, DocumentHandlerFactoryImpl, SACParserFactoryImpl) remain as parser plumbing. Net ~-1,450 LOC; bundles internal (x-friends only), no API surface change. Contributes to #3980
1 parent bacf493 commit ce34aea

39 files changed

Lines changed: 1225 additions & 2678 deletions

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ Export-Package: org.eclipse.e4.ui.css.core;x-internal:=true,
3131
org.eclipse.e4.ui.css.core.impl.dom.parsers;x-internal:=true,
3232
org.eclipse.e4.ui.css.core.impl.dom.properties;x-friends:="org.eclipse.e4.ui.css.swt",
3333
org.eclipse.e4.ui.css.core.impl.engine;x-friends:="org.eclipse.e4.ui.css.swt,org.eclipse.e4.ui.workbench.swt",
34+
org.eclipse.e4.ui.css.core.impl.engine.selector;x-friends:="org.eclipse.e4.ui.tests.css.core",
3435
org.eclipse.e4.ui.css.core.impl.sac;x-internal:=true,
3536
org.eclipse.e4.ui.css.core.resources;x-friends:="org.eclipse.e4.ui.css.swt,org.eclipse.e4.ui.workbench.renderers.swt",
3637
org.eclipse.e4.ui.css.core.sac;x-internal:=true,

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

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2008, 2013 Angelo Zerr and others.
2+
* Copyright (c) 2008, 2026 Angelo Zerr and others.
33
*
44
* This program and the accompanying materials
55
* are made available under the terms of the Eclipse Public License 2.0
@@ -13,8 +13,7 @@
1313
*******************************************************************************/
1414
package org.eclipse.e4.ui.css.core.dom;
1515

16-
import org.w3c.css.sac.Selector;
17-
import org.w3c.css.sac.SelectorList;
16+
import org.eclipse.e4.ui.css.core.impl.engine.selector.Selectors;
1817
import org.w3c.dom.css.CSSRule;
1918

2019
/**
@@ -28,7 +27,7 @@ public interface ExtendedCSSRule extends CSSRule {
2827
public CSSPropertyList getCSSPropertyList();
2928

3029
/**
31-
* Return the list of {@link Selector} of this {@link CSSRule}.
30+
* Return the list of selectors of this {@link CSSRule}.
3231
*/
33-
public SelectorList getSelectorList();
32+
public Selectors.SelectorList getSelectorList();
3433
}

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

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2008, 2018 Angelo Zerr and others.
2+
* Copyright (c) 2008, 2026 Angelo Zerr and others.
33
*
44
* This program and the accompanying materials
55
* are made available under the terms of the Eclipse Public License 2.0
@@ -15,9 +15,6 @@
1515
package org.eclipse.e4.ui.css.core.dom;
1616

1717
import java.util.EventListener;
18-
import java.util.List;
19-
import org.w3c.css.sac.Condition;
20-
import org.w3c.css.sac.Selector;
2118
import org.w3c.dom.css.DocumentCSS;
2219
import org.w3c.dom.stylesheets.StyleSheet;
2320

@@ -26,21 +23,10 @@
2623
*/
2724
public interface ExtendedDocumentCSS extends DocumentCSS {
2825

29-
public static final Integer SAC_ID_CONDITION = Integer.valueOf(Condition.SAC_ID_CONDITION);
30-
public static final Integer SAC_CLASS_CONDITION = Integer.valueOf(Condition.SAC_CLASS_CONDITION);
31-
public static final Integer SAC_PSEUDO_CLASS_CONDITION = Integer.valueOf(Condition.SAC_PSEUDO_CLASS_CONDITION);
32-
public static final Integer OTHER_SAC_CONDITIONAL_SELECTOR = Integer.valueOf(Selector.SAC_CONDITIONAL_SELECTOR);
33-
34-
public static final Integer OTHER_SAC_SELECTOR = Integer.valueOf(999);
35-
3626
public void addStyleSheet(StyleSheet styleSheet);
3727

3828
public void removeAllStyleSheets();
3929

40-
public List<?> queryConditionSelector(int conditionType);
41-
42-
public List<?> querySelector(int selectorType, int conditionType);
43-
4430
/**
4531
* @since 0.12.200
4632
*/

bundles/org.eclipse.e4.ui.css.core/src/org/eclipse/e4/ui/css/core/engine/CSSEngine.java

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,10 @@
2020
import org.eclipse.e4.ui.css.core.dom.IElementProvider;
2121
import org.eclipse.e4.ui.css.core.dom.properties.ICSSPropertyHandler;
2222
import org.eclipse.e4.ui.css.core.dom.properties.converters.ICSSValueConverter;
23+
import org.eclipse.e4.ui.css.core.impl.engine.selector.Selectors;
2324
import org.eclipse.e4.ui.css.core.resources.IResourcesRegistry;
2425
import org.eclipse.e4.ui.css.core.util.resources.IResourcesLocatorManager;
2526
import org.w3c.css.sac.InputSource;
26-
import org.w3c.css.sac.Selector;
27-
import org.w3c.css.sac.SelectorList;
2827
import org.w3c.dom.Element;
2928
import org.w3c.dom.css.CSSStyleDeclaration;
3029
import org.w3c.dom.css.CSSStyleSheet;
@@ -105,27 +104,27 @@ public interface CSSEngine {
105104
/**
106105
* Parse Selectors from String value.
107106
*/
108-
SelectorList parseSelectors(String text);
107+
Selectors.SelectorList parseSelectors(String text);
109108

110109
/**
111110
* Parse Selectors from InputSource value.
112111
*/
113-
SelectorList parseSelectors(InputSource source) throws IOException;
112+
Selectors.SelectorList parseSelectors(InputSource source) throws IOException;
114113

115114
/**
116115
* Parse Selectors from InputStream.
117116
*/
118-
SelectorList parseSelectors(InputStream stream) throws IOException;
117+
Selectors.SelectorList parseSelectors(InputStream stream) throws IOException;
119118

120119
/**
121120
* Parse Selectors from String value.
122121
*/
123-
SelectorList parseSelectors(Reader reader) throws IOException;
122+
Selectors.SelectorList parseSelectors(Reader reader) throws IOException;
124123

125124
/**
126125
* Check if the <code>selector</code> matches the object <code>node</code>.
127126
*/
128-
boolean matches(Selector selector, Object node, String pseudo);
127+
boolean matches(Selectors.Selector selector, Object node, String pseudo);
129128

130129
/*--------------- Apply styles -----------------*/
131130

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

Lines changed: 6 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2008, 2015 Angelo Zerr and others.
2+
* Copyright (c) 2008, 2026 Angelo Zerr and others.
33
*
44
* This program and the accompanying materials
55
* are made available under the terms of the Eclipse Public License 2.0
@@ -17,8 +17,7 @@
1717

1818
import org.eclipse.e4.ui.css.core.dom.CSSPropertyList;
1919
import org.eclipse.e4.ui.css.core.dom.ExtendedCSSRule;
20-
import org.w3c.css.sac.Selector;
21-
import org.w3c.css.sac.SelectorList;
20+
import org.eclipse.e4.ui.css.core.impl.engine.selector.Selectors;
2221
import org.w3c.dom.DOMException;
2322
import org.w3c.dom.css.CSSRule;
2423
import org.w3c.dom.css.CSSStyleDeclaration;
@@ -27,10 +26,10 @@
2726

2827
public class CSSStyleRuleImpl extends CSSRuleImpl implements CSSStyleRule, ExtendedCSSRule {
2928

30-
private final SelectorList selectors;
29+
private final Selectors.SelectorList selectors;
3130
private CSSStyleDeclaration styleDeclaration;
3231

33-
public CSSStyleRuleImpl(CSSStyleSheet parentStyleSheet, CSSRule parentRule, SelectorList selectors) {
32+
public CSSStyleRuleImpl(CSSStyleSheet parentStyleSheet, CSSRule parentRule, Selectors.SelectorList selectors) {
3433
super(parentStyleSheet, parentRule);
3534
this.selectors = selectors;
3635
}
@@ -55,17 +54,7 @@ public String getCssText() {
5554

5655
@Override
5756
public String getSelectorText() {
58-
StringBuilder sb = new StringBuilder();
59-
for (int selID = 0; selID < getSelectorList().getLength(); selID++) {
60-
Selector item = getSelectorList().item(selID);
61-
sb.append(item.toString());
62-
sb.append(", ");
63-
}
64-
if (getSelectorList().getLength() > 0) {
65-
sb.delete(sb.length() - 2, sb.length());
66-
}
67-
68-
return sb.toString();
57+
return selectors.text();
6958
}
7059

7160
@Override
@@ -83,7 +72,7 @@ public void setSelectorText(String selectorText) throws DOMException {
8372
// Additional methods
8473

8574
@Override
86-
public SelectorList getSelectorList() {
75+
public Selectors.SelectorList getSelectorList() {
8776
return selectors;
8877
}
8978

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

Lines changed: 1 addition & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2008, 2018 Angelo Zerr and others.
2+
* Copyright (c) 2008, 2026 Angelo Zerr and others.
33
*
44
* This program and the accompanying materials
55
* are made available under the terms of the Eclipse Public License 2.0
@@ -18,19 +18,10 @@
1818
package org.eclipse.e4.ui.css.core.impl.dom;
1919

2020
import java.util.ArrayList;
21-
import java.util.HashMap;
2221
import java.util.List;
23-
import java.util.Map;
24-
import org.eclipse.e4.ui.css.core.dom.ExtendedCSSRule;
2522
import org.eclipse.e4.ui.css.core.dom.ExtendedDocumentCSS;
26-
import org.w3c.css.sac.ConditionalSelector;
27-
import org.w3c.css.sac.Selector;
28-
import org.w3c.css.sac.SelectorList;
2923
import org.w3c.dom.Element;
30-
import org.w3c.dom.css.CSSRule;
31-
import org.w3c.dom.css.CSSRuleList;
3224
import org.w3c.dom.css.CSSStyleDeclaration;
33-
import org.w3c.dom.css.CSSStyleSheet;
3425
import org.w3c.dom.css.DocumentCSS;
3526
import org.w3c.dom.stylesheets.StyleSheet;
3627
import org.w3c.dom.stylesheets.StyleSheetList;
@@ -42,11 +33,6 @@ public class DocumentCSSImpl implements ExtendedDocumentCSS {
4233

4334
private final StyleSheetListImpl styleSheetList = new StyleSheetListImpl();
4435

45-
/**
46-
* key=selector type, value = CSSStyleDeclaration
47-
*/
48-
private Map<Integer, List<?>> styleDeclarationMap;
49-
5036
private final List<StyleSheetChangeListener> styleSheetChangeListeners = new ArrayList<>(1);
5137

5238
@Override
@@ -72,93 +58,6 @@ public void removeAllStyleSheets() {
7258
styleSheetChangeListeners.forEach(l -> l.styleSheetRemoved(styleSheet));
7359
}
7460
styleSheetList.removeAllStyleSheets();
75-
this.styleDeclarationMap = null;
76-
}
77-
78-
@Override
79-
public List<?> queryConditionSelector(int conditionType) {
80-
return querySelector(Selector.SAC_CONDITIONAL_SELECTOR, conditionType);
81-
}
82-
83-
@Override
84-
public List<?> querySelector(int selectorType, int conditionType) {
85-
List<?> list = getCSSStyleDeclarationList(selectorType, conditionType);
86-
if (list != null) {
87-
return list;
88-
}
89-
int l = styleSheetList.getLength();
90-
for (int i = 0; i < l; i++) {
91-
CSSStyleSheet styleSheet = (CSSStyleSheet) styleSheetList.item(i);
92-
CSSRuleList ruleList = styleSheet.getCssRules();
93-
list = querySelector(ruleList, selectorType, conditionType);
94-
setCSSStyleDeclarationList(list, selectorType, conditionType);
95-
}
96-
return list;
97-
}
98-
99-
protected List<Selector> querySelector(CSSRuleList ruleList, int selectorType, int selectorConditionType) {
100-
List<Selector> list = new ArrayList<>();
101-
if (selectorType == Selector.SAC_CONDITIONAL_SELECTOR) {
102-
int length = ruleList.getLength();
103-
for (int i = 0; i < length; i++) {
104-
CSSRule rule = ruleList.item(i);
105-
if (rule.getType() == CSSRule.STYLE_RULE && rule instanceof ExtendedCSSRule r) {
106-
SelectorList selectorList = r.getSelectorList();
107-
// Loop for SelectorList
108-
int l = selectorList.getLength();
109-
for (int j = 0; j < l; j++) {
110-
Selector selector = selectorList.item(j);
111-
if (selector.getSelectorType() == selectorType) {
112-
// It's conditional selector
113-
ConditionalSelector conditionalSelector = (ConditionalSelector) selector;
114-
short conditionType = conditionalSelector.getCondition().getConditionType();
115-
if (selectorConditionType == conditionType) {
116-
// current selector match the current CSS
117-
// Rule
118-
// CSSStyleRule styleRule = (CSSStyleRule)
119-
// rule;
120-
list.add(selector);
121-
}
122-
}
123-
}
124-
}
125-
}
126-
}
127-
return list;
128-
}
129-
130-
protected List<?> getCSSStyleDeclarationList(int selectorType, int conditionType) {
131-
Integer key = getKey(selectorType, conditionType);
132-
return getStyleDeclarationMap().get(key);
133-
}
134-
135-
protected void setCSSStyleDeclarationList(List<?> list, int selectorType, int conditionType) {
136-
Integer key = getKey(selectorType, conditionType);
137-
getStyleDeclarationMap().put(key, list);
138-
}
139-
140-
protected Integer getKey(int selectorType, int conditionType) {
141-
if (selectorType == Selector.SAC_CONDITIONAL_SELECTOR) {
142-
if (conditionType == SAC_CLASS_CONDITION.intValue()) {
143-
return SAC_CLASS_CONDITION;
144-
}
145-
if (conditionType == SAC_ID_CONDITION.intValue()) {
146-
return SAC_ID_CONDITION;
147-
}
148-
if (conditionType == SAC_PSEUDO_CLASS_CONDITION.intValue()) {
149-
return SAC_PSEUDO_CLASS_CONDITION;
150-
}
151-
return OTHER_SAC_CONDITIONAL_SELECTOR;
152-
}
153-
154-
return OTHER_SAC_SELECTOR;
155-
}
156-
157-
protected Map<Integer, List<?>> getStyleDeclarationMap() {
158-
if (styleDeclarationMap == null) {
159-
styleDeclarationMap = new HashMap<>();
160-
}
161-
return styleDeclarationMap;
16261
}
16362

16463
@Override

0 commit comments

Comments
 (0)