- initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.ui.css.core.impl.engine.selector;
+
+import org.eclipse.e4.ui.css.core.dom.CSSStylableElement;
+import org.eclipse.e4.ui.css.core.impl.engine.selector.Selectors.Adjacent;
+import org.eclipse.e4.ui.css.core.impl.engine.selector.Selectors.And;
+import org.eclipse.e4.ui.css.core.impl.engine.selector.Selectors.AttributeBeginHyphen;
+import org.eclipse.e4.ui.css.core.impl.engine.selector.Selectors.AttributeIncludes;
+import org.eclipse.e4.ui.css.core.impl.engine.selector.Selectors.AttributeSelector;
+import org.eclipse.e4.ui.css.core.impl.engine.selector.Selectors.Child;
+import org.eclipse.e4.ui.css.core.impl.engine.selector.Selectors.ClassSelector;
+import org.eclipse.e4.ui.css.core.impl.engine.selector.Selectors.Descendant;
+import org.eclipse.e4.ui.css.core.impl.engine.selector.Selectors.ElementType;
+import org.eclipse.e4.ui.css.core.impl.engine.selector.Selectors.IdSelector;
+import org.eclipse.e4.ui.css.core.impl.engine.selector.Selectors.PseudoClass;
+import org.eclipse.e4.ui.css.core.impl.engine.selector.Selectors.Selector;
+import org.eclipse.e4.ui.css.core.impl.engine.selector.Selectors.SelectorList;
+import org.eclipse.e4.ui.css.core.impl.engine.selector.Selectors.Universal;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+/**
+ * Matches a {@link Selector} against an {@link Element}.
+ *
+ *
+ * Every method is static; the matcher carries no state. Callers pass the
+ * element being tested plus an optional pseudo-element string (the same
+ * argument the SAC engine carried) so that pseudo-class matching can defer
+ * to the existing {@link CSSStylableElement#isPseudoInstanceOf} contract.
+ *
+ *
+ *
+ * Tag-name comparison is case sensitive, matching the existing SAC matcher
+ * (Phase 1 test {@code testTagNameCaseSensitivity} in {@code CSSEngineTest}
+ * locks this in). Pseudo-class semantics also follow the existing engine:
+ * the static-pseudo-instance carve-out from
+ * {@code CSSPseudoClassConditionImpl} is preserved so cascade behaviour
+ * does not shift.
+ *
+ */
+public final class SelectorMatcher {
+
+ private SelectorMatcher() {
+ // statics only
+ }
+
+ /**
+ * @return {@code true} if {@code selector} matches {@code element} for
+ * the given pseudo state.
+ */
+ public static boolean matches(Selector selector, Element element, String pseudoElement) {
+ return matches(selector, element, pseudoElement, null, 0);
+ }
+
+ /**
+ * @return {@code true} if {@code selector} matches {@code element} for
+ * the given pseudo state, using a pre-computed ancestor hierarchy array if available.
+ */
+ public static boolean matches(Selector selector, Element element, String pseudoElement, Element[] hierarchy, int hierarchyIndex) {
+ if (element == null) {
+ return false;
+ }
+ if (selector instanceof Universal) {
+ return true;
+ }
+ if (selector instanceof ElementType type) {
+ return matchesElementType(type, element);
+ }
+ if (selector instanceof ClassSelector cls) {
+ return matchesClass(cls, element);
+ }
+ if (selector instanceof IdSelector id) {
+ return matchesId(id, element);
+ }
+ if (selector instanceof AttributeSelector attr) {
+ return matchesAttribute(attr, element);
+ }
+ if (selector instanceof AttributeIncludes inc) {
+ return matchesAttributeIncludes(inc, element);
+ }
+ if (selector instanceof AttributeBeginHyphen beg) {
+ return matchesAttributeBeginHyphen(beg, element);
+ }
+ if (selector instanceof PseudoClass pc) {
+ return matchesPseudoClass(pc, element, pseudoElement);
+ }
+ if (selector instanceof And and) {
+ return matches(and.left(), element, pseudoElement, hierarchy, hierarchyIndex)
+ && matches(and.right(), element, pseudoElement, hierarchy, hierarchyIndex);
+ }
+ if (selector instanceof Descendant d) {
+ return matchesDescendant(d, element, pseudoElement, hierarchy, hierarchyIndex);
+ }
+ if (selector instanceof Child c) {
+ return matchesChild(c, element, pseudoElement, hierarchy, hierarchyIndex);
+ }
+ if (selector instanceof Adjacent a) {
+ return matchesAdjacent(a, element, pseudoElement, hierarchy, hierarchyIndex);
+ }
+ if (selector instanceof SelectorList list) {
+ return matchesAny(list, element, pseudoElement, hierarchy, hierarchyIndex);
+ }
+ throw new IllegalStateException("Unknown selector kind: " + selector.getClass()); //$NON-NLS-1$
+ }
+
+ private static boolean matchesElementType(ElementType type, Element element) {
+ String localName = type.localName();
+ if (localName == null) {
+ return true;
+ }
+ String elementName = element.getPrefix() == null ? element.getNodeName() : element.getLocalName();
+ return localName.equals(elementName);
+ }
+
+ private static boolean matchesClass(ClassSelector cls, Element element) {
+ if (!(element instanceof CSSStylableElement stylable)) {
+ return false;
+ }
+ String elementClass = stylable.getCSSClass();
+ if (elementClass == null) {
+ return false;
+ }
+ // CSS class attribute can be a whitespace-separated list of classes.
+ // Walk the string manually to avoid the regex compile + array allocation
+ // String.split forces on every match evaluation.
+ return containsWord(elementClass, cls.className());
+ }
+
+ private static boolean matchesId(IdSelector id, Element element) {
+ if (!(element instanceof CSSStylableElement stylable)) {
+ return false;
+ }
+ return id.id().equals(stylable.getCSSId());
+ }
+
+ private static boolean matchesAttribute(AttributeSelector attr, Element element) {
+ String name = attr.name();
+ if (!element.hasAttribute(name)) {
+ return false;
+ }
+ String required = attr.value();
+ if (required == null) {
+ // presence form: [attr]
+ return true;
+ }
+ return required.equals(element.getAttribute(name));
+ }
+
+ private static boolean matchesAttributeIncludes(AttributeIncludes inc, Element element) {
+ String actual = element.getAttribute(inc.name());
+ if (actual == null) {
+ return false;
+ }
+ return containsWord(actual, inc.value());
+ }
+
+ /**
+ * Returns {@code true} if {@code haystack} contains {@code word} as a
+ * whitespace-separated token. Equivalent to splitting on
+ * {@code \s+} and checking for an exact token match, but without the
+ * regex compile and array allocation each call.
+ */
+ private static boolean containsWord(String haystack, String word) {
+ if (word == null || word.isEmpty()) {
+ return false;
+ }
+ int wordLength = word.length();
+ int length = haystack.length();
+ int i = 0;
+ while (i < length) {
+ while (i < length && Character.isWhitespace(haystack.charAt(i))) {
+ i++;
+ }
+ int start = i;
+ while (i < length && !Character.isWhitespace(haystack.charAt(i))) {
+ i++;
+ }
+ if (i - start == wordLength && haystack.regionMatches(start, word, 0, wordLength)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private static boolean matchesAttributeBeginHyphen(AttributeBeginHyphen beg, Element element) {
+ String actual = element.getAttribute(beg.name());
+ if (actual == null) {
+ return false;
+ }
+ String value = beg.value();
+ return actual.equals(value) || actual.startsWith(value + "-");
+ }
+
+ private static boolean matchesPseudoClass(PseudoClass pseudo, Element element, String pseudoElement) {
+ String name = pseudo.name();
+ // If the caller is iterating a static-pseudo cascade, only match the
+ // pseudo argument on the way down.
+ if (pseudoElement != null && !pseudoElement.equals(name)) {
+ return false;
+ }
+ if (!(element instanceof CSSStylableElement stylable)) {
+ return false;
+ }
+ if (!stylable.isPseudoInstanceOf(name)) {
+ return false;
+ }
+ if (pseudoElement == null) {
+ // Same carve-out as CSSPseudoClassConditionImpl: when no pseudo
+ // element argument is supplied, pseudos that the element
+ // publishes only as static instances do not match the regular
+ // cascade. They get applied separately via the default style
+ // declaration map.
+ return !stylable.isStaticPseudoInstance(name);
+ }
+ return true;
+ }
+
+ private static boolean matchesDescendant(Descendant d, Element element, String pseudoElement, Element[] hierarchy, int hierarchyIndex) {
+ if (!matches(d.descendant(), element, pseudoElement, hierarchy, hierarchyIndex)) {
+ return false;
+ }
+ if (hierarchy != null) {
+ for (int i = hierarchyIndex + 1; i < hierarchy.length; i++) {
+ if (matches(d.ancestor(), hierarchy[i], null, hierarchy, i)) {
+ return true;
+ }
+ }
+ return false;
+ } else {
+ Node parent = element.getParentNode();
+ while (parent instanceof Element parentElement) {
+ if (matches(d.ancestor(), parentElement, null, null, 0)) {
+ return true;
+ }
+ parent = parentElement.getParentNode();
+ }
+ return false;
+ }
+ }
+
+ private static boolean matchesChild(Child c, Element element, String pseudoElement, Element[] hierarchy, int hierarchyIndex) {
+ if (!matches(c.child(), element, pseudoElement, hierarchy, hierarchyIndex)) {
+ return false;
+ }
+ if (hierarchy != null) {
+ int parentIdx = hierarchyIndex + 1;
+ if (parentIdx < hierarchy.length) {
+ return matches(c.parent(), hierarchy[parentIdx], null, hierarchy, parentIdx);
+ }
+ return false;
+ } else {
+ Node parent = element.getParentNode();
+ return parent instanceof Element parentElement && matches(c.parent(), parentElement, null, null, 0);
+ }
+ }
+
+ private static boolean matchesAdjacent(Adjacent a, Element element, String pseudoElement, Element[] hierarchy, int hierarchyIndex) {
+ if (!matches(a.second(), element, pseudoElement, hierarchy, hierarchyIndex)) {
+ return false;
+ }
+ Node previous = element.getPreviousSibling();
+ while (previous != null && !(previous instanceof Element)) {
+ previous = previous.getPreviousSibling();
+ }
+ return previous instanceof Element previousElement && matches(a.first(), previousElement, null, null, 0);
+ }
+
+ private static boolean matchesAny(SelectorList list, Element element, String pseudoElement, Element[] hierarchy, int hierarchyIndex) {
+ for (Selector alternative : list.alternatives()) {
+ if (matches(alternative, element, pseudoElement, hierarchy, hierarchyIndex)) {
+ return true;
+ }
+ }
+ return false;
+ }
+}
diff --git a/bundles/org.eclipse.e4.ui.css.core/src/org/eclipse/e4/ui/css/core/impl/engine/selector/Selectors.java b/bundles/org.eclipse.e4.ui.css.core/src/org/eclipse/e4/ui/css/core/impl/engine/selector/Selectors.java
new file mode 100644
index 00000000000..ebca60b165b
--- /dev/null
+++ b/bundles/org.eclipse.e4.ui.css.core/src/org/eclipse/e4/ui/css/core/impl/engine/selector/Selectors.java
@@ -0,0 +1,357 @@
+/*******************************************************************************
+ * Copyright (c) 2026 Lars Vogel and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Lars Vogel - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.ui.css.core.impl.engine.selector;
+
+import java.util.List;
+
+/**
+ * Internal CSS selector AST.
+ *
+ *
+ * The engine historically exposed W3C SAC selectors
+ * ({@code org.w3c.css.sac.Selector} and friends) and matched against them
+ * through a hierarchy of vendored Batik wrapper classes under
+ * {@code impl/sac/*}. This package replaces both with a small set of records
+ * that the engine owns end to end. The W3C SAC types stay only as long as
+ * the parser still emits them; a translator turns the SAC selector tree
+ * produced by the Batik SAC parser into one of these records before it
+ * reaches the engine matcher.
+ *
+ *
+ *
+ * Specificity follows CSS 2.1: 100 per id, 10 per class / attribute /
+ * pseudo-class, 1 per element, 0 for the universal selector. Combinators
+ * sum the specificity of their operands; selector lists report the maximum
+ * specificity over their alternatives.
+ *
+ */
+public final class Selectors {
+
+ private Selectors() {
+ // constants only
+ }
+
+ /** A parsed CSS selector. Sealed; pattern-match in the matcher. */
+ public sealed interface Selector
+ permits Universal, ElementType, ClassSelector, IdSelector, AttributeSelector,
+ AttributeIncludes, AttributeBeginHyphen, PseudoClass, And, Descendant, Child, Adjacent, SelectorList {
+
+ /** CSS specificity contribution of this selector. */
+ int specificity();
+
+ /** Best-effort textual reproduction of the selector. */
+ String text();
+ }
+
+ /** {@code *} — matches any element. */
+ public record Universal() implements Selector {
+ @Override
+ public int specificity() {
+ return 0;
+ }
+
+ @Override
+ public String text() {
+ return "*"; //$NON-NLS-1$
+ }
+
+ @Override
+ public String toString() {
+ return text();
+ }
+ }
+
+ /** {@code Button} — matches by local element name. */
+ public record ElementType(String localName) implements Selector {
+ @Override
+ public int specificity() {
+ return 1;
+ }
+
+ @Override
+ public String text() {
+ return localName;
+ }
+
+ @Override
+ public String toString() {
+ return text();
+ }
+ }
+
+ /** {@code .foo} — matches by CSS class. */
+ public record ClassSelector(String className) implements Selector {
+ @Override
+ public int specificity() {
+ return 10;
+ }
+
+ @Override
+ public String text() {
+ return "." + className; //$NON-NLS-1$
+ }
+
+ @Override
+ public String toString() {
+ return text();
+ }
+ }
+
+ /** {@code #foo} — matches by CSS id. */
+ public record IdSelector(String id) implements Selector {
+ @Override
+ public int specificity() {
+ return 100;
+ }
+
+ @Override
+ public String text() {
+ return "#" + id; //$NON-NLS-1$
+ }
+
+ @Override
+ public String toString() {
+ return text();
+ }
+ }
+
+ /**
+ * {@code [attr]} or {@code [attr='value']}. {@code value} is {@code null}
+ * for the presence form and the empty string for {@code [attr='']}.
+ */
+ public record AttributeSelector(String name, String value) implements Selector {
+ @Override
+ public int specificity() {
+ return 10;
+ }
+
+ @Override
+ public String text() {
+ return value == null ? "[" + name + "]" : "[" + name + "='" + value + "']"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+ }
+
+ @Override
+ public String toString() {
+ return text();
+ }
+ }
+
+ /** {@code [attr~='value']} — matches when {@code attr} contains {@code value} as a whitespace-separated word. */
+ public record AttributeIncludes(String name, String value) implements Selector {
+ @Override
+ public int specificity() {
+ return 10;
+ }
+
+ @Override
+ public String text() {
+ return "[" + name + "~='" + value + "']"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ }
+
+ @Override
+ public String toString() {
+ return text();
+ }
+ }
+
+ /** {@code [attr|='value']} — matches when {@code attr} equals {@code value} or starts with {@code value-}. */
+ public record AttributeBeginHyphen(String name, String value) implements Selector {
+ @Override
+ public int specificity() {
+ return 10;
+ }
+
+ @Override
+ public String text() {
+ return "[" + name + "|='" + value + "']"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ }
+
+ @Override
+ public String toString() {
+ return text();
+ }
+ }
+
+ /**
+ * {@code :name} — matches when the element answers true to
+ * {@code isPseudoInstanceOf(name)} on its CSS-stylable element wrapper.
+ */
+ public record PseudoClass(String name) implements Selector {
+ @Override
+ public int specificity() {
+ return 10;
+ }
+
+ @Override
+ public String text() {
+ return ":" + name; //$NON-NLS-1$
+ }
+
+ @Override
+ public String toString() {
+ return text();
+ }
+ }
+
+ /**
+ * Compound selector: every operand must match the same element. Built
+ * by the translator for forms like {@code Button.primary#go} or
+ * {@code [a][b]} where multiple simple selectors apply to one element.
+ */
+ public record And(Selector left, Selector right) implements Selector {
+ @Override
+ public int specificity() {
+ return left.specificity() + right.specificity();
+ }
+
+ @Override
+ public String text() {
+ return left.text() + right.text();
+ }
+
+ @Override
+ public String toString() {
+ return text();
+ }
+ }
+
+ /** {@code ancestor descendant} — descendant combinator. */
+ public record Descendant(Selector ancestor, Selector descendant) implements Selector {
+ @Override
+ public int specificity() {
+ return ancestor.specificity() + descendant.specificity();
+ }
+
+ @Override
+ public String text() {
+ return ancestor.text() + " " + descendant.text(); //$NON-NLS-1$
+ }
+
+ @Override
+ public String toString() {
+ return text();
+ }
+ }
+
+ /** {@code parent > child} — child combinator. */
+ public record Child(Selector parent, Selector child) implements Selector {
+ @Override
+ public int specificity() {
+ return parent.specificity() + child.specificity();
+ }
+
+ @Override
+ public String text() {
+ return parent.text() + " > " + child.text(); //$NON-NLS-1$
+ }
+
+ @Override
+ public String toString() {
+ return text();
+ }
+ }
+
+ /** {@code first + second} — direct adjacent sibling combinator. */
+ public record Adjacent(Selector first, Selector second) implements Selector {
+ @Override
+ public int specificity() {
+ return first.specificity() + second.specificity();
+ }
+
+ @Override
+ public String text() {
+ return first.text() + " + " + second.text(); //$NON-NLS-1$
+ }
+
+ @Override
+ public String toString() {
+ return text();
+ }
+ }
+
+ /**
+ * {@code a, b} — selector list. Specificity reports the maximum over the
+ * alternatives so cascade ordering can match a list against an element by
+ * iterating its alternatives.
+ *
+ *
+ * A regular final class rather than a record because the cascade reads
+ * {@link #specificity()} once per matched alternative and we want it
+ * precomputed; record components cannot host derived state.
+ *
+ */
+ public static final class SelectorList implements Selector {
+
+ private final List alternatives;
+ private final int specificity;
+
+ public SelectorList(List alternatives) {
+ this.alternatives = List.copyOf(alternatives);
+ int max = 0;
+ for (Selector alternative : this.alternatives) {
+ int s = alternative.specificity();
+ if (s > max) {
+ max = s;
+ }
+ }
+ this.specificity = max;
+ }
+
+ public List alternatives() {
+ return alternatives;
+ }
+
+ /** Number of alternatives in the list. SAC-style accessor for callers iterating the list. */
+ public int getLength() {
+ return alternatives.size();
+ }
+
+ /** {@code i}-th alternative. SAC-style accessor for callers iterating the list. */
+ public Selector item(int i) {
+ return alternatives.get(i);
+ }
+
+ @Override
+ public int specificity() {
+ return specificity;
+ }
+
+ @Override
+ public String text() {
+ StringBuilder sb = new StringBuilder();
+ for (int i = 0; i < alternatives.size(); i++) {
+ if (i > 0) {
+ sb.append(", "); //$NON-NLS-1$
+ }
+ sb.append(alternatives.get(i).text());
+ }
+ return sb.toString();
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ return o instanceof SelectorList other && alternatives.equals(other.alternatives);
+ }
+
+ @Override
+ public int hashCode() {
+ return alternatives.hashCode();
+ }
+
+ @Override
+ public String toString() {
+ return text();
+ }
+ }
+}
diff --git a/bundles/org.eclipse.e4.ui.css.core/src/org/eclipse/e4/ui/css/core/impl/sac/AbstractAttributeCondition.java b/bundles/org.eclipse.e4.ui.css.core/src/org/eclipse/e4/ui/css/core/impl/sac/AbstractAttributeCondition.java
deleted file mode 100644
index fabffbad828..00000000000
--- a/bundles/org.eclipse.e4.ui.css.core/src/org/eclipse/e4/ui/css/core/impl/sac/AbstractAttributeCondition.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
-
- Copyright 2002, 2014 The Apache Software Foundation
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
-
-/* This class copied from org.apache.batik.css.engine.sac */
-
-package org.eclipse.e4.ui.css.core.impl.sac;
-
-import java.util.Objects;
-import org.w3c.css.sac.AttributeCondition;
-
-/**
- * This class provides an abstract implementation of the {@link
- * org.w3c.css.sac.AttributeCondition} interface.
- */
-public abstract class AbstractAttributeCondition implements AttributeCondition,
- ExtendedCondition {
-
- /**
- * The attribute value.
- */
- protected String value;
-
- /**
- * Creates a new AbstractAttributeCondition object.
- */
- protected AbstractAttributeCondition(String value) {
- this.value = value;
- }
-
- /**
- * Indicates whether some other object is "equal to" this one.
- *
- * @param obj
- * the reference object with which to compare.
- */
- @Override
- public boolean equals(Object obj) {
- if (obj == null || (obj.getClass() != getClass())) {
- return false;
- }
- AbstractAttributeCondition c = (AbstractAttributeCondition) obj;
- return c.value.equals(value);
- }
-
- /**
- * equal objects should have equal hashCodes.
- *
- * @return hashCode of this AbstractAttributeCondition
- */
- @Override
- public int hashCode() {
- return Objects.hashCode(value);
- }
-
- /**
- * Returns the specificity of this condition.
- */
- @Override
- public int getSpecificity() {
- return 1 << 8;
- }
-
- /**
- * SAC: Implements {@link
- * org.w3c.css.sac.AttributeCondition#getValue()}.
- */
- @Override
- public String getValue() {
- return value;
- }
-}
diff --git a/bundles/org.eclipse.e4.ui.css.core/src/org/eclipse/e4/ui/css/core/impl/sac/AbstractCombinatorCondition.java b/bundles/org.eclipse.e4.ui.css.core/src/org/eclipse/e4/ui/css/core/impl/sac/AbstractCombinatorCondition.java
deleted file mode 100644
index 0de6c81b86c..00000000000
--- a/bundles/org.eclipse.e4.ui.css.core/src/org/eclipse/e4/ui/css/core/impl/sac/AbstractCombinatorCondition.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
-
- Copyright 2002, 2014 The Apache Software Foundation
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
-
-/* This class copied from org.apache.batik.css.engine.sac */
-
-package org.eclipse.e4.ui.css.core.impl.sac;
-
-import org.w3c.css.sac.CombinatorCondition;
-import org.w3c.css.sac.Condition;
-
-/**
- * This class provides an abstract implementation of the {@link
- * org.w3c.css.sac.CombinatorCondition} interface.
- */
-public abstract class AbstractCombinatorCondition implements
- CombinatorCondition, ExtendedCondition {
-
- /**
- * The first condition.
- */
- protected Condition firstCondition;
-
- /**
- * The second condition.
- */
- protected Condition secondCondition;
-
- /**
- * Creates a new CombinatorCondition object.
- */
- protected AbstractCombinatorCondition(Condition c1, Condition c2) {
- firstCondition = c1;
- secondCondition = c2;
- }
-
- /**
- * Indicates whether some other object is "equal to" this one.
- *
- * @param obj
- * the reference object with which to compare.
- */
- @Override
- public boolean equals(Object obj) {
- if (obj == null || (obj.getClass() != getClass())) {
- return false;
- }
- AbstractCombinatorCondition c = (AbstractCombinatorCondition) obj;
- return (c.firstCondition.equals(firstCondition) && c.secondCondition
- .equals(secondCondition));
- }
-
- /**
- * Returns the specificity of this condition.
- */
- @Override
- public int getSpecificity() {
- return ((ExtendedCondition) getFirstCondition()).getSpecificity()
- + ((ExtendedCondition) getSecondCondition()).getSpecificity();
- }
-
- /**
- * SAC: Implements {@link
- * org.w3c.css.sac.CombinatorCondition#getFirstCondition()}.
- */
- @Override
- public Condition getFirstCondition() {
- return firstCondition;
- }
-
- /**
- * SAC: Implements {@link
- * org.w3c.css.sac.CombinatorCondition#getSecondCondition()}.
- */
- @Override
- public Condition getSecondCondition() {
- return secondCondition;
- }
-}
diff --git a/bundles/org.eclipse.e4.ui.css.core/src/org/eclipse/e4/ui/css/core/impl/sac/AbstractDescendantSelector.java b/bundles/org.eclipse.e4.ui.css.core/src/org/eclipse/e4/ui/css/core/impl/sac/AbstractDescendantSelector.java
deleted file mode 100644
index f183af1ccae..00000000000
--- a/bundles/org.eclipse.e4.ui.css.core/src/org/eclipse/e4/ui/css/core/impl/sac/AbstractDescendantSelector.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
-
- Copyright 2002, 2014 The Apache Software Foundation
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
-
-/* This class copied from org.apache.batik.css.engine.sac */
-
-package org.eclipse.e4.ui.css.core.impl.sac;
-
-import org.w3c.css.sac.DescendantSelector;
-import org.w3c.css.sac.Selector;
-import org.w3c.css.sac.SimpleSelector;
-
-/**
- * This class provides an abstract implementation of the {@link
- * org.w3c.css.sac.DescendantSelector} interface.
- */
-public abstract class AbstractDescendantSelector
- implements DescendantSelector,
- ExtendedSelector {
-
- /**
- * The ancestor selector.
- */
- protected Selector ancestorSelector;
-
- /**
- * The simple selector.
- */
- protected SimpleSelector simpleSelector;
-
- /**
- * Creates a new DescendantSelector object.
- */
- protected AbstractDescendantSelector(Selector ancestor,
- SimpleSelector simple) {
- ancestorSelector = ancestor;
- simpleSelector = simple;
- }
-
- /**
- * Indicates whether some other object is "equal to" this one.
- * @param obj the reference object with which to compare.
- */
- @Override
- public boolean equals(Object obj) {
- if (obj == null || (obj.getClass() != getClass())) {
- return false;
- }
- AbstractDescendantSelector s = (AbstractDescendantSelector)obj;
- return s.simpleSelector.equals(simpleSelector);
- }
-
- /**
- * Returns the specificity of this selector.
- */
- @Override
- public int getSpecificity() {
- return ((ExtendedSelector)ancestorSelector).getSpecificity() +
- ((ExtendedSelector)simpleSelector).getSpecificity();
- }
-
- /**
- * SAC: Implements {@link
- * org.w3c.css.sac.DescendantSelector#getAncestorSelector()}.
- */
- @Override
- public Selector getAncestorSelector() {
- return ancestorSelector;
- }
-
- /**
- * SAC: Implements {@link
- * org.w3c.css.sac.DescendantSelector#getSimpleSelector()}.
- */
- @Override
- public SimpleSelector getSimpleSelector() {
- return simpleSelector;
- }
-}
diff --git a/bundles/org.eclipse.e4.ui.css.core/src/org/eclipse/e4/ui/css/core/impl/sac/AbstractElementSelector.java b/bundles/org.eclipse.e4.ui.css.core/src/org/eclipse/e4/ui/css/core/impl/sac/AbstractElementSelector.java
deleted file mode 100644
index 529b86a0fbb..00000000000
--- a/bundles/org.eclipse.e4.ui.css.core/src/org/eclipse/e4/ui/css/core/impl/sac/AbstractElementSelector.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
-
- Copyright 2002, 2015 The Apache Software Foundation
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
-
-/* This class copied from org.apache.batik.css.engine.sac */
-
-package org.eclipse.e4.ui.css.core.impl.sac;
-
-import java.util.Set;
-import org.w3c.css.sac.ElementSelector;
-
-/**
- * This class provides an abstract implementation of the ElementSelector
- * interface.
- */
-public abstract class AbstractElementSelector implements ElementSelector, ExtendedSelector {
-
- /**
- * The namespace URI.
- */
- protected String namespaceURI;
-
- /**
- * The local name.
- */
- protected String localName;
-
- /**
- * Creates a new ElementSelector object.
- */
- protected AbstractElementSelector(String uri, String name) {
- namespaceURI = uri;
- localName = name;
- }
-
- /**
- * Indicates whether some other object is "equal to" this one.
- * @param obj the reference object with which to compare.
- */
- @Override
- public boolean equals(Object obj) {
- if (obj == null || (obj.getClass() != getClass())) {
- return false;
- }
- AbstractElementSelector s = (AbstractElementSelector)obj;
- return (s.namespaceURI.equals(namespaceURI) && s.localName.equals(localName));
- }
-
- /**
- * SAC: Implements {@link
- * org.w3c.css.sac.ElementSelector#getNamespaceURI()}.
- */
- @Override
- public String getNamespaceURI() {
- return namespaceURI;
- }
-
- /**
- * SAC: Implements {@link
- * org.w3c.css.sac.ElementSelector#getLocalName()}.
- */
- @Override
- public String getLocalName() {
- return localName;
- }
-
- /**
- * Fills the given set with the attribute names found in this selector.
- */
- @Override
- public void fillAttributeSet(Set attrSet) {
- }
-}
diff --git a/bundles/org.eclipse.e4.ui.css.core/src/org/eclipse/e4/ui/css/core/impl/sac/AbstractSiblingSelector.java b/bundles/org.eclipse.e4.ui.css.core/src/org/eclipse/e4/ui/css/core/impl/sac/AbstractSiblingSelector.java
deleted file mode 100644
index bb061dd13e0..00000000000
--- a/bundles/org.eclipse.e4.ui.css.core/src/org/eclipse/e4/ui/css/core/impl/sac/AbstractSiblingSelector.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
-
- Copyright 2002, 2014 The Apache Software Foundation
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
-
-/* This class copied from org.apache.batik.css.engine.sac */
-
-package org.eclipse.e4.ui.css.core.impl.sac;
-
-import org.w3c.css.sac.Selector;
-import org.w3c.css.sac.SiblingSelector;
-import org.w3c.css.sac.SimpleSelector;
-
-/**
- * This class provides an abstract implementation of the {@link
- * org.w3c.css.sac.SiblingSelector} interface.
- */
-public abstract class AbstractSiblingSelector implements SiblingSelector,
- ExtendedSelector {
-
- /**
- * The node type.
- */
- protected short nodeType;
-
- /**
- * The selector.
- */
- protected Selector selector;
-
- /**
- * The simple selector.
- */
- protected SimpleSelector simpleSelector;
-
- /**
- * Creates a new SiblingSelector object.
- */
- protected AbstractSiblingSelector(short type, Selector sel,
- SimpleSelector simple) {
- nodeType = type;
- selector = sel;
- simpleSelector = simple;
- }
-
- /**
- * Returns the node type.
- */
- @Override
- public short getNodeType() {
- return nodeType;
- }
-
- /**
- * Indicates whether some other object is "equal to" this one.
- *
- * @param obj
- * the reference object with which to compare.
- */
- @Override
- public boolean equals(Object obj) {
- if (obj == null || (obj.getClass() != getClass())) {
- return false;
- }
- AbstractSiblingSelector s = (AbstractSiblingSelector) obj;
- return s.simpleSelector.equals(simpleSelector);
- }
-
- /**
- * Returns the specificity of this selector.
- */
- @Override
- public int getSpecificity() {
- return ((ExtendedSelector) selector).getSpecificity()
- + ((ExtendedSelector) simpleSelector).getSpecificity();
- }
-
- /**
- * SAC: Implements {@link
- * org.w3c.css.sac.SiblingSelector#getSelector()}.
- */
- @Override
- public Selector getSelector() {
- return selector;
- }
-
- /**
- * SAC: Implements {@link
- * org.w3c.css.sac.SiblingSelector#getSiblingSelector()}.
- */
- @Override
- public SimpleSelector getSiblingSelector() {
- return simpleSelector;
- }
-}
diff --git a/bundles/org.eclipse.e4.ui.css.core/src/org/eclipse/e4/ui/css/core/impl/sac/CSSAndConditionImpl.java b/bundles/org.eclipse.e4.ui.css.core/src/org/eclipse/e4/ui/css/core/impl/sac/CSSAndConditionImpl.java
deleted file mode 100644
index b9d528d05ad..00000000000
--- a/bundles/org.eclipse.e4.ui.css.core/src/org/eclipse/e4/ui/css/core/impl/sac/CSSAndConditionImpl.java
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
-
- Copyright 2002, 2015 The Apache Software Foundation
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
-
-/* This class copied from org.apache.batik.css.engine.sac */
-
-package org.eclipse.e4.ui.css.core.impl.sac;
-
-import java.util.Set;
-import org.w3c.css.sac.Condition;
-import org.w3c.dom.Element;
-
-/**
- * This class provides an implementation of the
- * {@link org.w3c.css.sac.CombinatorCondition} interface.
- */
-public class CSSAndConditionImpl extends AbstractCombinatorCondition {
- /**
- * Creates a new CombinatorCondition object.
- */
- public CSSAndConditionImpl(Condition c1, Condition c2) {
- super(c1, c2);
- }
-
- /**
- * SAC: Implements {@link
- * org.w3c.css.sac.Condition#getConditionType()}.
- */
- @Override
- public short getConditionType() {
- return SAC_AND_CONDITION;
- }
-
- /**
- * Tests whether this condition matches the given element.
- */
- @Override
- public boolean match(Element e, String pseudoE) {
- return ((ExtendedCondition)getFirstCondition()).match(e, pseudoE) &&
- ((ExtendedCondition)getSecondCondition()).match(e, pseudoE);
- }
-
- /**
- * Fills the given set with the attribute names found in this selector.
- */
- @Override
- public void fillAttributeSet(Set attrSet) {
- ((ExtendedCondition)getFirstCondition()).fillAttributeSet(attrSet);
- ((ExtendedCondition)getSecondCondition()).fillAttributeSet(attrSet);
- }
-
- /**
- * Returns a text representation of this object.
- */
- @Override
- public String toString() {
- return String.valueOf( getFirstCondition() ) + getSecondCondition();
- }
-}
diff --git a/bundles/org.eclipse.e4.ui.css.core/src/org/eclipse/e4/ui/css/core/impl/sac/CSSAttributeConditionImpl.java b/bundles/org.eclipse.e4.ui.css.core/src/org/eclipse/e4/ui/css/core/impl/sac/CSSAttributeConditionImpl.java
deleted file mode 100644
index 3467d068938..00000000000
--- a/bundles/org.eclipse.e4.ui.css.core/src/org/eclipse/e4/ui/css/core/impl/sac/CSSAttributeConditionImpl.java
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
-
- Copyright 2002, 2015 The Apache Software Foundation
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
-
-/* This class copied from org.apache.batik.css.engine.sac */
-
-package org.eclipse.e4.ui.css.core.impl.sac;
-
-import java.util.Set;
-import org.w3c.dom.Element;
-
-/**
- * This class provides an implementation of the
- * {@link org.w3c.css.sac.AttributeCondition} interface.
- */
-public class CSSAttributeConditionImpl extends AbstractAttributeCondition {
- /**
- * The attribute's local name.
- */
- protected String localName;
-
- /**
- * The attribute's namespace URI.
- */
- protected String namespaceURI;
-
- /**
- * Whether this condition applies to specified attributes.
- */
- protected boolean specified;
-
- /**
- * Creates a new CSSAttributeCondition object.
- */
- public CSSAttributeConditionImpl(String localName, String namespaceURI,
- boolean specified, String value) {
- super(value);
- this.localName = localName;
- this.namespaceURI = namespaceURI;
- this.specified = specified;
- }
-
- /**
- * Indicates whether some other object is "equal to" this one.
- *
- * @param obj
- * the reference object with which to compare.
- */
- @Override
- public boolean equals(Object obj) {
- if (!super.equals(obj)) {
- return false;
- }
- CSSAttributeConditionImpl c = (CSSAttributeConditionImpl) obj;
- return (c.namespaceURI.equals(namespaceURI)
- && c.localName.equals(localName) && c.specified == specified);
- }
-
- /**
- * equal objects should have equal hashCodes.
- *
- * @return hashCode of this CSSAttributeCondition
- */
- @Override
- public int hashCode() {
- return namespaceURI.hashCode() ^ localName.hashCode()
- ^ Boolean.hashCode(specified);
- }
-
- /**
- * SAC: Implements {@link
- * org.w3c.css.sac.Condition#getConditionType()}.
- */
- @Override
- public short getConditionType() {
- return SAC_ATTRIBUTE_CONDITION;
- }
-
- /**
- * SAC: Implements {@link
- * org.w3c.css.sac.AttributeCondition#getNamespaceURI()}.
- */
- @Override
- public String getNamespaceURI() {
- return namespaceURI;
- }
-
- /**
- * SAC: Implements {@link
- * org.w3c.css.sac.AttributeCondition#getLocalName()}.
- */
- @Override
- public String getLocalName() {
- return localName;
- }
-
- /**
- * SAC: Implements {@link
- * org.w3c.css.sac.AttributeCondition#getSpecified()}.
- */
- @Override
- public boolean getSpecified() {
- return specified;
- }
-
- /**
- * Tests whether this condition matches the given element.
- */
- @Override
- public boolean match(Element e, String pseudoE) {
- if (!e.hasAttribute(getLocalName())) {
- return false;
- }
- String val = getValue();
- if (val == null) {
- return true;
- }
- return e.getAttribute(getLocalName()).equals(val);
- }
-
- /**
- * Fills the given set with the attribute names found in this selector.
- */
- @Override
- public void fillAttributeSet(Set attrSet) {
- attrSet.add(localName);
- }
-
- /**
- * Returns a text representation of this object.
- */
- @Override
- public String toString() {
- if (value == null) {
- return '[' + localName + ']';
- }
- return '[' + localName + "=\"" + value + "\"]";
- }
-}
diff --git a/bundles/org.eclipse.e4.ui.css.core/src/org/eclipse/e4/ui/css/core/impl/sac/CSSBeginHyphenAttributeConditionImpl.java b/bundles/org.eclipse.e4.ui.css.core/src/org/eclipse/e4/ui/css/core/impl/sac/CSSBeginHyphenAttributeConditionImpl.java
deleted file mode 100644
index 12064bb8e47..00000000000
--- a/bundles/org.eclipse.e4.ui.css.core/src/org/eclipse/e4/ui/css/core/impl/sac/CSSBeginHyphenAttributeConditionImpl.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
-
- Copyright 2002, 2014 The Apache Software Foundation
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
-
-/* This class copied from org.apache.batik.css.engine.sac */
-
-package org.eclipse.e4.ui.css.core.impl.sac;
-
-import org.w3c.dom.Element;
-
-/**
- * This class provides an implementation of the
- * {@link org.w3c.css.sac.AttributeCondition} interface.
- */
-public class CSSBeginHyphenAttributeConditionImpl extends
- CSSAttributeConditionImpl {
-
- /**
- * Creates a new CSSAttributeCondition object.
- */
- public CSSBeginHyphenAttributeConditionImpl(String localName,
- String namespaceURI, boolean specified, String value) {
- super(localName, namespaceURI, specified, value);
- }
-
- /**
- * SAC: Implements {@link
- * org.w3c.css.sac.Condition#getConditionType()}.
- */
- @Override
- public short getConditionType() {
- return SAC_BEGIN_HYPHEN_ATTRIBUTE_CONDITION;
- }
-
- /**
- * Tests whether this condition matches the given element.
- */
- @Override
- public boolean match(Element e, String pseudoE) {
- return e.getAttribute(getLocalName()).startsWith(getValue());
- }
-
- /**
- * Returns a text representation of this object.
- */
- @Override
- public String toString() {
- return '[' + getLocalName() + "|=\"" + getValue() + "\"]";
- }
-}
diff --git a/bundles/org.eclipse.e4.ui.css.core/src/org/eclipse/e4/ui/css/core/impl/sac/CSSChildSelectorImpl.java b/bundles/org.eclipse.e4.ui.css.core/src/org/eclipse/e4/ui/css/core/impl/sac/CSSChildSelectorImpl.java
deleted file mode 100644
index 450031025f2..00000000000
--- a/bundles/org.eclipse.e4.ui.css.core/src/org/eclipse/e4/ui/css/core/impl/sac/CSSChildSelectorImpl.java
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
-
- Copyright 2002, 2015 The Apache Software Foundation
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
-
-/* This class copied from org.apache.batik.css.engine.sac */
-
-package org.eclipse.e4.ui.css.core.impl.sac;
-
-import java.util.Set;
-import org.w3c.css.sac.Selector;
-import org.w3c.css.sac.SimpleSelector;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-
-/**
- * This class provides an implementation of the
- * {@link org.w3c.css.sac.DescendantSelector} interface.
- */
-public class CSSChildSelectorImpl extends AbstractDescendantSelector {
-
- /**
- * Creates a new CSSChildSelector object.
- */
- public CSSChildSelectorImpl(Selector ancestor, SimpleSelector simple) {
- super(ancestor, simple);
- }
-
- /**
- * SAC: Implements {@link
- * org.w3c.css.sac.Selector#getSelectorType()}.
- */
- @Override
- public short getSelectorType() {
- return SAC_CHILD_SELECTOR;
- }
-
- /**
- * Tests whether this selector matches the given element.
- */
- @Override
- public boolean match(Element e, Node[] hierarchy, int parentIndex, String pseudoE) {
- if (hierarchy == null || parentIndex >= hierarchy.length) {
- return false;
- }
-
- Node n = hierarchy[parentIndex];
- if (n != null && n.getNodeType() == Node.ELEMENT_NODE) {
- return ((ExtendedSelector) getAncestorSelector()).match((Element) n, hierarchy, parentIndex + 1, null)
- && ((ExtendedSelector) getSimpleSelector()).match(e, hierarchy, parentIndex + 1, pseudoE);
- }
- return false;
- }
-
- /**
- * Tests whether this selector matches the given element.
- */
- @Override
- public boolean match(Element e, String pseudoE) {
- Node n = e.getParentNode();
- if (n != null && n.getNodeType() == Node.ELEMENT_NODE) {
- return ((ExtendedSelector) getAncestorSelector()).match((Element) n,
- null)
- && ((ExtendedSelector) getSimpleSelector()).match(e, pseudoE);
- }
- return false;
- }
-
- /**
- * Fills the given set with the attribute names found in this selector.
- */
- @Override
- public void fillAttributeSet(Set attrSet) {
- ((ExtendedSelector)getAncestorSelector()).fillAttributeSet(attrSet);
- ((ExtendedSelector)getSimpleSelector()).fillAttributeSet(attrSet);
- }
-
- /**
- * Returns a representation of the selector.
- */
- @Override
- public String toString() {
- SimpleSelector s = getSimpleSelector();
- if (s.getSelectorType() == SAC_PSEUDO_ELEMENT_SELECTOR) {
- return String.valueOf( getAncestorSelector() ) + s;
- }
- return getAncestorSelector() + " > " + s;
- }
-}
diff --git a/bundles/org.eclipse.e4.ui.css.core/src/org/eclipse/e4/ui/css/core/impl/sac/CSSClassConditionImpl.java b/bundles/org.eclipse.e4.ui.css.core/src/org/eclipse/e4/ui/css/core/impl/sac/CSSClassConditionImpl.java
deleted file mode 100644
index 521c7743af1..00000000000
--- a/bundles/org.eclipse.e4.ui.css.core/src/org/eclipse/e4/ui/css/core/impl/sac/CSSClassConditionImpl.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
-
- Copyright 2002, 2014 The Apache Software Foundation
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
-
-/* This class copied from org.apache.batik.css.engine.sac */
-
-package org.eclipse.e4.ui.css.core.impl.sac;
-
-import org.eclipse.e4.ui.css.core.dom.CSSStylableElement;
-import org.w3c.dom.Element;
-
-/**
- * This class provides an implementation of the
- * {@link org.w3c.css.sac.AttributeCondition} interface.
- */
-public class CSSClassConditionImpl extends CSSAttributeConditionImpl {
-
- /**
- * Creates a new CSSAttributeCondition object.
- */
- public CSSClassConditionImpl(String localName, String namespaceURI,
- String value) {
- super(localName, namespaceURI, true, value);
- }
-
- @Override
- public boolean match(Element e, String pseudoE) {
- String attr = null;
- if ((e instanceof CSSStylableElement)) {
- attr = ((CSSStylableElement) e).getCSSClass();
- } else {
- attr = e.getAttribute("class");
- }
- if (attr == null || attr.length() < 1) {
- return false;
- }
- String val = getValue();
- int attrLen = attr.length();
- int valLen = val.length();
- for (int i = attr.indexOf(val); i != -1; i = attr.indexOf(val, i
- + valLen)) {
- if ((i == 0 || Character.isSpaceChar(attr.charAt(i - 1)))
- && (i + valLen == attrLen || Character.isSpaceChar(attr
- .charAt(i + valLen)))) {
- return true;
- }
- }
-
- return false;
- }
-}
diff --git a/bundles/org.eclipse.e4.ui.css.core/src/org/eclipse/e4/ui/css/core/impl/sac/CSSConditionFactoryImpl.java b/bundles/org.eclipse.e4.ui.css.core/src/org/eclipse/e4/ui/css/core/impl/sac/CSSConditionFactoryImpl.java
deleted file mode 100644
index 24676814228..00000000000
--- a/bundles/org.eclipse.e4.ui.css.core/src/org/eclipse/e4/ui/css/core/impl/sac/CSSConditionFactoryImpl.java
+++ /dev/null
@@ -1,213 +0,0 @@
-/*
-
- Copyright 2002, 2014 The Apache Software Foundation
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
-
-/* This class copied from org.apache.batik.css.engine.sac */
-
-package org.eclipse.e4.ui.css.core.impl.sac;
-
-import org.w3c.css.sac.AttributeCondition;
-import org.w3c.css.sac.CSSException;
-import org.w3c.css.sac.CombinatorCondition;
-import org.w3c.css.sac.Condition;
-import org.w3c.css.sac.ConditionFactory;
-import org.w3c.css.sac.ContentCondition;
-import org.w3c.css.sac.LangCondition;
-import org.w3c.css.sac.NegativeCondition;
-import org.w3c.css.sac.PositionalCondition;
-
-/**
- * This class provides an implementation of the
- * {@link org.w3c.css.sac.ConditionFactory} interface.
- */
-public class CSSConditionFactoryImpl implements ConditionFactory {
-
- private static final String NOT_IMPLEMENTED_IN_CSS2 = "Not implemented in CSS2"; //$NON-NLS-1$
-
- /**
- * The class attribute namespace URI.
- */
- protected String classNamespaceURI;
-
- /**
- * The class attribute local name.
- */
- protected String classLocalName;
-
- /**
- * The id attribute namespace URI.
- */
- protected String idNamespaceURI;
-
- /**
- * The id attribute local name.
- */
- protected String idLocalName;
-
- /**
- * Creates a new condition factory.
- */
- public CSSConditionFactoryImpl(String cns, String cln, String idns,
- String idln) {
- classNamespaceURI = cns;
- classLocalName = cln;
- idNamespaceURI = idns;
- idLocalName = idln;
- }
-
- /**
- * SAC: Implements {@link
- * ConditionFactory#createAndCondition(Condition,Condition)}.
- */
- @Override
- public CombinatorCondition createAndCondition(Condition first,
- Condition second) throws CSSException {
- return new CSSAndConditionImpl(first, second);
- }
-
- /**
- * SAC: Implements {@link
- * ConditionFactory#createOrCondition(Condition,Condition)}.
- */
- @Override
- public CombinatorCondition createOrCondition(Condition first,
- Condition second) throws CSSException {
- throw new CSSException(NOT_IMPLEMENTED_IN_CSS2);
- }
-
- /**
- * SAC: Implements {@link
- * org.w3c.css.sac.ConditionFactory#createNegativeCondition(Condition)}.
- */
- @Override
- public NegativeCondition createNegativeCondition(Condition condition)
- throws CSSException {
- throw new CSSException(NOT_IMPLEMENTED_IN_CSS2);
- }
-
- /**
- * SAC: Implements {@link
- * ConditionFactory#createPositionalCondition(int,boolean,boolean)}.
- */
- @Override
- public PositionalCondition createPositionalCondition(int position,
- boolean typeNode, boolean type) throws CSSException {
- throw new CSSException(NOT_IMPLEMENTED_IN_CSS2);
- }
-
- /**
- * SAC: Implements {@link
- * ConditionFactory#createAttributeCondition(String,String,boolean,String)}.
- */
- @Override
- public AttributeCondition createAttributeCondition(String localName,
- String namespaceURI, boolean specified, String value)
- throws CSSException {
- return new CSSAttributeConditionImpl(localName, namespaceURI, specified,
- value);
- }
-
- /**
- * SAC: Implements {@link
- * org.w3c.css.sac.ConditionFactory#createIdCondition(String)}.
- */
- @Override
- public AttributeCondition createIdCondition(String value)
- throws CSSException {
- return new CSSIdConditionImpl(idNamespaceURI, idLocalName, value);
- }
-
- /**
- * SAC: Implements {@link
- * org.w3c.css.sac.ConditionFactory#createLangCondition(String)}.
- */
- @Override
- public LangCondition createLangCondition(String lang) throws CSSException {
- return new CSSLangConditionImpl(lang);
- }
-
- /**
- * SAC: Implements {@link
- * ConditionFactory#createOneOfAttributeCondition(String,String,boolean,String)}.
- */
- @Override
- public AttributeCondition createOneOfAttributeCondition(String localName,
- String nsURI, boolean specified, String value) throws CSSException {
- return new CSSOneOfAttributeConditionImpl(localName, nsURI, specified,
- value);
- }
-
- /**
- * SAC: Implements {@link
- * ConditionFactory#createBeginHyphenAttributeCondition(String,String,boolean,String)}.
- */
- @Override
- public AttributeCondition createBeginHyphenAttributeCondition(
- String localName, String namespaceURI, boolean specified,
- String value) throws CSSException {
- return new CSSBeginHyphenAttributeConditionImpl(localName,
- namespaceURI, specified, value);
- }
-
- /**
- * SAC: Implements {@link
- * org.w3c.css.sac.ConditionFactory#createClassCondition(String,String)}.
- */
- @Override
- public AttributeCondition createClassCondition(String namespaceURI,
- String value) throws CSSException {
- return new CSSClassConditionImpl(classLocalName, classNamespaceURI, value);
- }
-
- /**
- * SAC: Implements {@link
- * ConditionFactory#createPseudoClassCondition(String,String)}.
- */
- @Override
- public AttributeCondition createPseudoClassCondition(String namespaceURI,
- String value) throws CSSException {
- return new CSSPseudoClassConditionImpl(namespaceURI, value);
- }
-
- /**
- * SAC: Implements {@link
- * org.w3c.css.sac.ConditionFactory#createOnlyChildCondition()}.
- */
- @Override
- public Condition createOnlyChildCondition() throws CSSException {
- throw new CSSException(NOT_IMPLEMENTED_IN_CSS2);
- }
-
- /**
- * SAC: Implements {@link
- * org.w3c.css.sac.ConditionFactory#createOnlyTypeCondition()}.
- */
- @Override
- public Condition createOnlyTypeCondition() throws CSSException {
- throw new CSSException(NOT_IMPLEMENTED_IN_CSS2);
- }
-
- /**
- * SAC: Implements {@link
- * org.w3c.css.sac.ConditionFactory#createContentCondition(String)}.
- */
- @Override
- public ContentCondition createContentCondition(String data)
- throws CSSException {
- throw new CSSException(NOT_IMPLEMENTED_IN_CSS2);
- }
-}
diff --git a/bundles/org.eclipse.e4.ui.css.core/src/org/eclipse/e4/ui/css/core/impl/sac/CSSConditionalSelectorImpl.java b/bundles/org.eclipse.e4.ui.css.core/src/org/eclipse/e4/ui/css/core/impl/sac/CSSConditionalSelectorImpl.java
deleted file mode 100644
index c4cc09ad9c1..00000000000
--- a/bundles/org.eclipse.e4.ui.css.core/src/org/eclipse/e4/ui/css/core/impl/sac/CSSConditionalSelectorImpl.java
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
-
- Copyright 2002, 2015 The Apache Software Foundation
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
-
-/* This class copied from org.apache.batik.css.engine.sac */
-
-package org.eclipse.e4.ui.css.core.impl.sac;
-
-import java.util.Set;
-import org.w3c.css.sac.Condition;
-import org.w3c.css.sac.ConditionalSelector;
-import org.w3c.css.sac.SimpleSelector;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-
-/**
- * This class provides an implementation of the
- * {@link org.w3c.css.sac.ConditionalSelector} interface.
- */
-public class CSSConditionalSelectorImpl implements ConditionalSelector, ExtendedSelector {
-
- /**
- * The simple selector.
- */
- protected SimpleSelector simpleSelector;
-
- /**
- * The condition.
- */
- protected Condition condition;
-
- /**
- * Creates a new ConditionalSelector object.
- */
- public CSSConditionalSelectorImpl(SimpleSelector s, Condition c) {
- simpleSelector = s;
- condition = c;
- }
-
- /**
- * Indicates whether some other object is "equal to" this one.
- * @param obj the reference object with which to compare.
- */
- @Override
- public boolean equals(Object obj) {
- if (obj == null || (obj.getClass() != getClass())) {
- return false;
- }
- CSSConditionalSelectorImpl s = (CSSConditionalSelectorImpl)obj;
- return (s.simpleSelector.equals(simpleSelector) &&
- s.condition.equals(condition));
- }
-
- /**
- * SAC: Implements {@link
- * org.w3c.css.sac.Selector#getSelectorType()}.
- */
- @Override
- public short getSelectorType() {
- return SAC_CONDITIONAL_SELECTOR;
- }
-
- @Override
- public boolean match(Element e, Node[] hierarchy, int parentIndex, String pseudoE) {
- return ((ExtendedSelector)getSimpleSelector()).match(e, hierarchy, parentIndex, pseudoE) &&
- ((ExtendedCondition)getCondition()).match(e, pseudoE);
- }
-
- /**
- * Tests whether this selector matches the given element.
- */
- @Override
- public boolean match(Element e, String pseudoE) {
- return ((ExtendedSelector)getSimpleSelector()).match(e, pseudoE) &&
- ((ExtendedCondition)getCondition()).match(e, pseudoE);
- }
-
- /**
- * Fills the given set with the attribute names found in this selector.
- */
- @Override
- public void fillAttributeSet(Set attrSet) {
- ((ExtendedSelector)getSimpleSelector()).fillAttributeSet(attrSet);
- ((ExtendedCondition)getCondition()).fillAttributeSet(attrSet);
- }
-
- /**
- * Returns the specificity of this selector.
- */
- @Override
- public int getSpecificity() {
- return ((ExtendedSelector)getSimpleSelector()).getSpecificity() +
- ((ExtendedCondition)getCondition()).getSpecificity();
- }
-
- /**
- * SAC: Implements {@link
- * org.w3c.css.sac.ConditionalSelector#getSimpleSelector()}.
- */
- @Override
- public SimpleSelector getSimpleSelector() {
- return simpleSelector;
- }
-
- /**
- * SAC: Implements {@link
- * org.w3c.css.sac.ConditionalSelector#getCondition()}.
- */
- @Override
- public Condition getCondition() {
- return condition;
- }
-
- /**
- * Returns a representation of the selector.
- */
- @Override
- public String toString() {
- return String.valueOf( simpleSelector ) + condition;
- }
-}
diff --git a/bundles/org.eclipse.e4.ui.css.core/src/org/eclipse/e4/ui/css/core/impl/sac/CSSDescendantSelectorImpl.java b/bundles/org.eclipse.e4.ui.css.core/src/org/eclipse/e4/ui/css/core/impl/sac/CSSDescendantSelectorImpl.java
deleted file mode 100644
index 44f3568dfc3..00000000000
--- a/bundles/org.eclipse.e4.ui.css.core/src/org/eclipse/e4/ui/css/core/impl/sac/CSSDescendantSelectorImpl.java
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
-
- Copyright 2002, 2015 The Apache Software Foundation
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
-
-/* This class copied from org.apache.batik.css.engine.sac */
-
-package org.eclipse.e4.ui.css.core.impl.sac;
-
-import java.util.Set;
-import org.w3c.css.sac.Selector;
-import org.w3c.css.sac.SimpleSelector;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-
-/**
- * This class provides an implementation for the
- * {@link org.w3c.css.sac.DescendantSelector} interface.
- */
-public class CSSDescendantSelectorImpl extends AbstractDescendantSelector {
-
- /**
- * Creates a new CSSDescendantSelector object.
- */
- public CSSDescendantSelectorImpl(Selector ancestor, SimpleSelector simple) {
- super(ancestor, simple);
- }
-
- /**
- * SAC: Implements {@link
- * org.w3c.css.sac.Selector#getSelectorType()}.
- */
- @Override
- public short getSelectorType() {
- return SAC_DESCENDANT_SELECTOR;
- }
-
- /**
- * Tests whether this selector matches the given element.
- */
- @Override
- public boolean match(Element e, Node[] hierarchy, int parentIndex, String pseudoE) {
- ExtendedSelector p = (ExtendedSelector) getAncestorSelector();
- if (!((ExtendedSelector) getSimpleSelector()).match(e, hierarchy, parentIndex, pseudoE)) {
- return false;
- }
-
- if (hierarchy == null) {
- return false;
- }
-
- Node n;
- int length = hierarchy.length;
- for (int i = parentIndex; i < length; i++) {
- n = hierarchy[i];
- if (n != null && n.getNodeType() == Node.ELEMENT_NODE
- && p.match((Element) n, hierarchy, i + 1, null)) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Tests whether this selector matches the given element.
- */
- @Override
- public boolean match(Element e, String pseudoE) {
- ExtendedSelector p = (ExtendedSelector) getAncestorSelector();
- if (!((ExtendedSelector) getSimpleSelector()).match(e, pseudoE)) {
- return false;
- }
- for (Node n = e.getParentNode(); n != null; n = n.getParentNode()) {
- if (n.getNodeType() == Node.ELEMENT_NODE && p.match((Element) n, null)) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Fills the given set with the attribute names found in this selector.
- */
- @Override
- public void fillAttributeSet(Set attrSet) {
- ((ExtendedSelector)getSimpleSelector()).fillAttributeSet(attrSet);
- }
-
- /**
- * Returns a representation of the selector.
- */
- @Override
- public String toString() {
- return getAncestorSelector() + " " + getSimpleSelector();
- }
-}
diff --git a/bundles/org.eclipse.e4.ui.css.core/src/org/eclipse/e4/ui/css/core/impl/sac/CSSDirectAdjacentSelectorImpl.java b/bundles/org.eclipse.e4.ui.css.core/src/org/eclipse/e4/ui/css/core/impl/sac/CSSDirectAdjacentSelectorImpl.java
deleted file mode 100644
index 73eea3eb684..00000000000
--- a/bundles/org.eclipse.e4.ui.css.core/src/org/eclipse/e4/ui/css/core/impl/sac/CSSDirectAdjacentSelectorImpl.java
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
-
- Copyright 2002, 2015 The Apache Software Foundation
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
-
-/* This class copied from org.apache.batik.css.engine.sac */
-
-package org.eclipse.e4.ui.css.core.impl.sac;
-
-import java.util.Set;
-import org.w3c.css.sac.Selector;
-import org.w3c.css.sac.SimpleSelector;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-
-/**
- * This class provides an implementation for the
- * {@link org.w3c.css.sac.DescendantSelector} interface.
- */
-public class CSSDirectAdjacentSelectorImpl extends AbstractSiblingSelector {
-
- /**
- * Creates a new CSSDirectAdjacentSelector object.
- */
- public CSSDirectAdjacentSelectorImpl(short type, Selector parent, SimpleSelector simple) {
- super(type, parent, simple);
- }
-
- /**
- * SAC: Implements {@link
- * org.w3c.css.sac.Selector#getSelectorType()}.
- */
- @Override
- public short getSelectorType() {
- return SAC_DIRECT_ADJACENT_SELECTOR;
- }
-
- /**
- * Tests whether this selector matches the given element.
- */
- @Override
- public boolean match(Element e, Node[] hiearchy, int parentIndex, String pseudoE) {
- Node n = e;
- if (!((ExtendedSelector) getSiblingSelector()).match(e, hiearchy, parentIndex, pseudoE)) {
- return false;
- }
-
- while ((n = n.getPreviousSibling()) != null && n.getNodeType() != Node.ELEMENT_NODE) {
- }
-
- if (n == null) {
- return false;
- }
-
- return ((ExtendedSelector) getSelector()).match((Element) n, hiearchy, parentIndex, null);
- }
-
- /**
- * Tests whether this selector matches the given element.
- */
- @Override
- public boolean match(Element e, String pseudoE) {
- Node n = e;
- if (!((ExtendedSelector)getSiblingSelector()).match(e, pseudoE)) {
- return false;
- }
- while ((n = n.getPreviousSibling()) != null && n.getNodeType() != Node.ELEMENT_NODE) {
- }
-
- if (n == null) {
- return false;
- }
-
- return ((ExtendedSelector)getSelector()).match((Element)n, null);
- }
-
- /**
- * Fills the given set with the attribute names found in this selector.
- */
- @Override
- public void fillAttributeSet(Set attrSet) {
- ((ExtendedSelector)getSelector()).fillAttributeSet(attrSet);
- ((ExtendedSelector)getSiblingSelector()).fillAttributeSet(attrSet);
- }
-
- /**
- * Returns a representation of the selector.
- */
- @Override
- public String toString() {
- return getSelector() + " + " + getSiblingSelector();
- }
-}
diff --git a/bundles/org.eclipse.e4.ui.css.core/src/org/eclipse/e4/ui/css/core/impl/sac/CSSDocumentHandlerImpl.java b/bundles/org.eclipse.e4.ui.css.core/src/org/eclipse/e4/ui/css/core/impl/sac/CSSDocumentHandlerImpl.java
index 150c95c4b7a..9456b6a94e2 100644
--- a/bundles/org.eclipse.e4.ui.css.core/src/org/eclipse/e4/ui/css/core/impl/sac/CSSDocumentHandlerImpl.java
+++ b/bundles/org.eclipse.e4.ui.css.core/src/org/eclipse/e4/ui/css/core/impl/sac/CSSDocumentHandlerImpl.java
@@ -25,6 +25,7 @@
import org.eclipse.e4.ui.css.core.impl.dom.CSSUnknownRuleImpl;
import org.eclipse.e4.ui.css.core.impl.dom.CSSValueFactory;
import org.eclipse.e4.ui.css.core.impl.dom.MediaListImpl;
+import org.eclipse.e4.ui.css.core.impl.engine.selector.SacTranslator;
import org.eclipse.e4.ui.css.core.sac.ExtendedDocumentHandler;
import org.w3c.css.sac.CSSException;
import org.w3c.css.sac.InputSource;
@@ -165,9 +166,10 @@ public void endFontFace() throws CSSException {
@Override
public void startSelector(SelectorList selectors) throws CSSException {
- // Create the style rule and add it to the rule list
+ // Translate the SAC selector list into the engine's internal AST at
+ // this boundary so nothing downstream needs to touch SAC types.
CSSStyleRuleImpl rule = new CSSStyleRuleImpl(parentStyleSheet, null,
- selectors);
+ SacTranslator.translate(selectors));
if (!getNodeStack().empty()) {
((CSSRuleListImpl) getNodeStack().peek()).add(rule);
}
diff --git a/bundles/org.eclipse.e4.ui.css.core/src/org/eclipse/e4/ui/css/core/impl/sac/CSSElementSelectorImpl.java b/bundles/org.eclipse.e4.ui.css.core/src/org/eclipse/e4/ui/css/core/impl/sac/CSSElementSelectorImpl.java
deleted file mode 100644
index f24e1aeea7f..00000000000
--- a/bundles/org.eclipse.e4.ui.css.core/src/org/eclipse/e4/ui/css/core/impl/sac/CSSElementSelectorImpl.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
-
- Copyright 2002, 2014 The Apache Software Foundation
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
-
-/* This class copied from org.apache.batik.css.engine.sac */
-
-package org.eclipse.e4.ui.css.core.impl.sac;
-
-import org.w3c.dom.Element;
-
-/**
- * This class implements the {@link org.w3c.css.sac.ElementSelector} interface.
- */
-public class CSSElementSelectorImpl extends AbstractElementSelector {
-
- /**
- * Creates a new ElementSelector object.
- */
- public CSSElementSelectorImpl(String uri, String name) {
- super(uri, name);
- }
-
- /**
- * SAC: Implements {@link
- * org.w3c.css.sac.Selector#getSelectorType()}.
- */
- @Override
- public short getSelectorType() {
- return SAC_ELEMENT_NODE_SELECTOR;
- }
-
- /**
- * Tests whether this selector matches the given element.
- */
- @Override
- public boolean match(Element e, String pseudoE) {
- String name = getLocalName();
- if (name == null) {
- if (namespaceURI != null) {
- return namespaceURI.equals(e.getNamespaceURI());
- } else {
- return true;
- }
- }
- String eName;
- if (e.getPrefix() == null) {
- eName = e.getNodeName();
- } else {
- eName = e.getLocalName();
- }
- // According to CSS 2 section 5.1 element
- // names in selectors are case-sensitive for XML.
- if (eName.equals(name)) {
- if (namespaceURI != null) {
- return namespaceURI.equals(e.getNamespaceURI());
- } else {
- return true;
- }
- }
- return false;
- // For HTML
- // return eName.equalsIgnoreCase(name);
- }
-
- /**
- * Returns the specificity of this selector.
- */
- @Override
- public int getSpecificity() {
- return (getLocalName() == null) ? 0 : 1;
- }
-
- /**
- * Returns a representation of the selector.
- */
- @Override
- public String toString() {
- String name = getLocalName();
- if (name == null) {
- return "*";
- }
- return name;
- }
-}
diff --git a/bundles/org.eclipse.e4.ui.css.core/src/org/eclipse/e4/ui/css/core/impl/sac/CSSIdConditionImpl.java b/bundles/org.eclipse.e4.ui.css.core/src/org/eclipse/e4/ui/css/core/impl/sac/CSSIdConditionImpl.java
deleted file mode 100644
index eec162ea03d..00000000000
--- a/bundles/org.eclipse.e4.ui.css.core/src/org/eclipse/e4/ui/css/core/impl/sac/CSSIdConditionImpl.java
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
-
- Copyright 2002, 2015 The Apache Software Foundation
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
-
-/* This class copied from org.apache.batik.css.engine.sac */
-
-package org.eclipse.e4.ui.css.core.impl.sac;
-
-import java.util.Set;
-import org.eclipse.e4.ui.css.core.dom.CSSStylableElement;
-import org.w3c.dom.Element;
-
-/**
- * This class provides an implementation of the
- * {@link org.w3c.css.sac.AttributeCondition} interface.
- */
-public class CSSIdConditionImpl extends AbstractAttributeCondition {
-
- /**
- * The id attribute namespace URI.
- */
- protected String namespaceURI;
-
- /**
- * The id attribute local name.
- */
- protected String localName;
-
- /**
- * Creates a new CSSAttributeCondition object.
- */
- public CSSIdConditionImpl(String ns, String ln, String value) {
- super(value);
- namespaceURI = ns;
- localName = ln;
- }
-
- /**
- * SAC: Implements {@link
- * org.w3c.css.sac.Condition#getConditionType()}.
- */
- @Override
- public short getConditionType() {
- return SAC_ID_CONDITION;
- }
-
- /**
- * SAC: Implements {@link
- * org.w3c.css.sac.AttributeCondition#getNamespaceURI()}.
- */
- @Override
- public String getNamespaceURI() {
- return namespaceURI;
- }
-
- /**
- * SAC: Implements {@link
- * org.w3c.css.sac.AttributeCondition#getLocalName()}.
- */
- @Override
- public String getLocalName() {
- return localName;
- }
-
- /**
- * SAC: Implements {@link
- * org.w3c.css.sac.AttributeCondition#getSpecified()}.
- */
- @Override
- public boolean getSpecified() {
- return true;
- }
-
- /**
- * Tests whether this condition matches the given element.
- */
- @Override
- public boolean match(Element e, String pseudoE) {
- String id = null;
- if (e instanceof CSSStylableElement) {
- id = ((CSSStylableElement) e).getCSSId();
- } else {
- id = e.getAttribute("id");
- }
- if (id == null) {
- return false;
- }
- return id.equals(getValue());
- // return super.match(e, pseudoE);
- }
-
- /**
- * Fills the given set with the attribute names found in this selector.
- */
- @Override
- public void fillAttributeSet(Set attrSet) {
- attrSet.add(localName);
- }
-
- /**
- * Returns the specificity of this condition.
- */
- @Override
- public int getSpecificity() {
- return 1 << 16;
- }
-
- /**
- * Returns a text representation of this object.
- */
- @Override
- public String toString() {
- return '#' + getValue();
- }
-}
diff --git a/bundles/org.eclipse.e4.ui.css.core/src/org/eclipse/e4/ui/css/core/impl/sac/CSSLangConditionImpl.java b/bundles/org.eclipse.e4.ui.css.core/src/org/eclipse/e4/ui/css/core/impl/sac/CSSLangConditionImpl.java
deleted file mode 100644
index 4789469f7fa..00000000000
--- a/bundles/org.eclipse.e4.ui.css.core/src/org/eclipse/e4/ui/css/core/impl/sac/CSSLangConditionImpl.java
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
-
- Copyright 2002, 2015 The Apache Software Foundation
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
-
-/* This class copied from org.apache.batik.css.engine.sac */
-
-package org.eclipse.e4.ui.css.core.impl.sac;
-
-import java.util.Set;
-import org.w3c.css.sac.LangCondition;
-import org.w3c.dom.Element;
-
-/**
- * This class provides an implementation of the
- * {@link org.w3c.css.sac.LangCondition} interface.
- */
-public class CSSLangConditionImpl implements LangCondition, ExtendedCondition {
- /**
- * The language.
- */
- protected String lang;
-
- /**
- * The language with a hyphen suffixed.
- */
- protected String langHyphen;
-
- /**
- * Creates a new LangCondition object.
- */
- public CSSLangConditionImpl(String lang) {
- this.lang = lang.toLowerCase();
- this.langHyphen = lang + '-';
- }
-
- /**
- * Indicates whether some other object is "equal to" this one.
- * @param obj the reference object with which to compare.
- */
- @Override
- public boolean equals(Object obj) {
- if (obj == null || (obj.getClass() != getClass())) {
- return false;
- }
- CSSLangConditionImpl c = (CSSLangConditionImpl)obj;
- return c.lang.equals(lang);
- }
-
- /**
- * SAC: Implements {@link
- * org.w3c.css.sac.Condition#getConditionType()}.
- */
- @Override
- public short getConditionType() {
- return SAC_LANG_CONDITION;
- }
-
- /**
- * SAC: Implements {@link org.w3c.css.sac.LangCondition#getLang()}.
- */
- @Override
- public String getLang() {
- return lang;
- }
-
- /**
- * Returns the specificity of this condition.
- */
- @Override
- public int getSpecificity() {
- return 1 << 8;
- }
-
- /**
- * Tests whether this condition matches the given element.
- */
- @Override
- public boolean match(Element e, String pseudoE) {
- String s = e.getAttribute("lang").toLowerCase();
- if (s.equals(lang) || s.startsWith(langHyphen)) {
- return true;
- }
- // s = e.getAttributeNS(XMLConstants.XML_NAMESPACE_URI,
- // XMLConstants.XML_LANG_ATTRIBUTE).toLowerCase();
- return s.equals(lang) || s.startsWith(langHyphen);
- }
-
- /**
- * Fills the given set with the attribute names found in this selector.
- */
- @Override
- public void fillAttributeSet(Set attrSet) {
- attrSet.add("lang");
- }
-
- /**
- * Returns a text representation of this object.
- */
- @Override
- public String toString() {
- return ":lang(" + lang + ')';
- }
-}
diff --git a/bundles/org.eclipse.e4.ui.css.core/src/org/eclipse/e4/ui/css/core/impl/sac/CSSOneOfAttributeConditionImpl.java b/bundles/org.eclipse.e4.ui.css.core/src/org/eclipse/e4/ui/css/core/impl/sac/CSSOneOfAttributeConditionImpl.java
deleted file mode 100644
index fb4ebbd0428..00000000000
--- a/bundles/org.eclipse.e4.ui.css.core/src/org/eclipse/e4/ui/css/core/impl/sac/CSSOneOfAttributeConditionImpl.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
-
- Copyright 2002, 2015 The Apache Software Foundation
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
-
-/*******************************************************************************
- * Contributors:
- * This class was copied from org.apache.batik.css.engine.sac
- * Apache Batik project - initial API and implementation
- * Alain Le Guennec - Bug 458334
- *******************************************************************************/
-package org.eclipse.e4.ui.css.core.impl.sac;
-
-import java.util.StringTokenizer;
-import org.w3c.dom.Element;
-
-/**
- * This class provides an implementation of the
- * {@link org.w3c.css.sac.AttributeCondition} interface.
- */
-public class CSSOneOfAttributeConditionImpl extends CSSAttributeConditionImpl {
- /**
- * Creates a new CSSAttributeCondition object.
- */
- public CSSOneOfAttributeConditionImpl(String localName,
- String namespaceURI, boolean specified, String value) {
- super(localName, namespaceURI, specified, value);
- }
-
- /**
- * SAC: Implements {@link
- * org.w3c.css.sac.Condition#getConditionType()}.
- */
- @Override
- public short getConditionType() {
- return SAC_ONE_OF_ATTRIBUTE_CONDITION;
- }
-
- /**
- * Tests whether this condition matches the given element.
- */
- @Override
- public boolean match(Element e, String pseudoE) {
- String attr = e.getAttribute(getLocalName());
- String val = getValue();
- for (StringTokenizer tok = new StringTokenizer(attr); tok.hasMoreElements();) {
- String candidate = tok.nextToken();
- if (val.equals(candidate)) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Returns a text representation of this object.
- */
- @Override
- public String toString() {
- return "[" + getLocalName() + "~=\"" + getValue() + "\"]";
- }
-}
diff --git a/bundles/org.eclipse.e4.ui.css.core/src/org/eclipse/e4/ui/css/core/impl/sac/CSSPseudoClassConditionImpl.java b/bundles/org.eclipse.e4.ui.css.core/src/org/eclipse/e4/ui/css/core/impl/sac/CSSPseudoClassConditionImpl.java
deleted file mode 100644
index 1c459d6637b..00000000000
--- a/bundles/org.eclipse.e4.ui.css.core/src/org/eclipse/e4/ui/css/core/impl/sac/CSSPseudoClassConditionImpl.java
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
-
- Copyright 2002, 2015 The Apache Software Foundation
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
-
-/* This class copied from org.apache.batik.css.engine.sac */
-
-package org.eclipse.e4.ui.css.core.impl.sac;
-
-import java.util.Set;
-import org.eclipse.e4.ui.css.core.dom.CSSStylableElement;
-import org.w3c.dom.Element;
-
-/**
- * This class provides an implementation of the
- * {@link org.w3c.css.sac.AttributeCondition} interface.
- */
-public class CSSPseudoClassConditionImpl extends AbstractAttributeCondition {
- /**
- * The namespaceURI.
- */
- protected String namespaceURI;
-
- /**
- * Creates a new CSSAttributeCondition object.
- */
- public CSSPseudoClassConditionImpl(String namespaceURI, String value) {
- super(value);
- this.namespaceURI = namespaceURI;
- }
-
- /**
- * Indicates whether some other object is "equal to" this one.
- *
- * @param obj
- * the reference object with which to compare.
- */
- @Override
- public boolean equals(Object obj) {
- if (!super.equals(obj)) {
- return false;
- }
- CSSPseudoClassConditionImpl c = (CSSPseudoClassConditionImpl) obj;
- return c.namespaceURI.equals(namespaceURI);
- }
-
- /**
- * equal objects should have equal hashCodes.
- *
- * @return hashCode of this CSSPseudoClassCondition
- */
- @Override
- public int hashCode() {
- return namespaceURI.hashCode();
- }
-
- /**
- * SAC: Implements {@link
- * org.w3c.css.sac.Condition#getConditionType()}.
- */
- @Override
- public short getConditionType() {
- return SAC_PSEUDO_CLASS_CONDITION;
- }
-
- /**
- * SAC: Implements {@link
- * org.w3c.css.sac.AttributeCondition#getNamespaceURI()}.
- */
- @Override
- public String getNamespaceURI() {
- return namespaceURI;
- }
-
- /**
- * SAC: Implements {@link
- * org.w3c.css.sac.AttributeCondition#getLocalName()}.
- */
- @Override
- public String getLocalName() {
- return null;
- }
-
- /**
- * SAC: Implements {@link
- * org.w3c.css.sac.AttributeCondition#getSpecified()}.
- */
- @Override
- public boolean getSpecified() {
- return false;
- }
-
- /**
- * Tests whether this selector matches the given element.
- */
- @Override
- public boolean match(Element e, String pseudoE) {
- if (pseudoE != null && !pseudoE.equals(getValue())) {
- // pseudo instance is filled, it is not valid.
- return false;
- }
- if (!(e instanceof CSSStylableElement element)) {
- return false;
- }
- boolean isPseudoInstanceOf = element.isPseudoInstanceOf(getValue());
- if (!isPseudoInstanceOf) {
- return false;
- }
- if (pseudoE == null) {
- // pseudo element is not filled.
- // test if this CSSPseudoClassCondition is NOT a static pseudo
- // instance
- return (!element.isStaticPseudoInstance(getValue()));
- }
- return true;
- }
-
- /**
- * Fills the given set with the attribute names found in this selector.
- */
- @Override
- public void fillAttributeSet(Set attrSet) {
- }
-
- /**
- * Returns a text representation of this object.
- */
- @Override
- public String toString() {
- return ":" + getValue();
- }
-}
diff --git a/bundles/org.eclipse.e4.ui.css.core/src/org/eclipse/e4/ui/css/core/impl/sac/CSSPseudoElementSelectorImpl.java b/bundles/org.eclipse.e4.ui.css.core/src/org/eclipse/e4/ui/css/core/impl/sac/CSSPseudoElementSelectorImpl.java
deleted file mode 100644
index 5353e2c4885..00000000000
--- a/bundles/org.eclipse.e4.ui.css.core/src/org/eclipse/e4/ui/css/core/impl/sac/CSSPseudoElementSelectorImpl.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
-
- Copyright 2002, 2014 The Apache Software Foundation
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
-
-/* This class copied from org.apache.batik.css.engine.sac */
-
-package org.eclipse.e4.ui.css.core.impl.sac;
-
-import org.w3c.dom.Element;
-
-/**
- * This class implements the {@link org.w3c.css.sac.ElementSelector} interface.
- */
-public class CSSPseudoElementSelectorImpl extends AbstractElementSelector {
-
- /**
- * Creates a new CSSPseudoElementSelector object.
- */
- public CSSPseudoElementSelectorImpl(String uri, String name) {
- super(uri, name);
- }
-
- /**
- * SAC: Implements {@link
- * org.w3c.css.sac.Selector#getSelectorType()}.
- */
- @Override
- public short getSelectorType() {
- return SAC_PSEUDO_ELEMENT_SELECTOR;
- }
-
- /**
- * Tests whether this selector matches the given element.
- */
- @Override
- public boolean match(Element e, String pseudoE) {
- return getLocalName().equalsIgnoreCase(pseudoE);
- }
-
- /**
- * Returns the specificity of this selector.
- */
- @Override
- public int getSpecificity() {
- return 0;
- }
-
- /**
- * Returns a representation of the selector.
- */
- @Override
- public String toString() {
- return ":" + getLocalName();
- }
-}
diff --git a/bundles/org.eclipse.e4.ui.css.core/src/org/eclipse/e4/ui/css/core/impl/sac/CSSSelectorFactoryImpl.java b/bundles/org.eclipse.e4.ui.css.core/src/org/eclipse/e4/ui/css/core/impl/sac/CSSSelectorFactoryImpl.java
deleted file mode 100644
index 00370115317..00000000000
--- a/bundles/org.eclipse.e4.ui.css.core/src/org/eclipse/e4/ui/css/core/impl/sac/CSSSelectorFactoryImpl.java
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
-
- Copyright 2002, 2014 The Apache Software Foundation
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
-
-/* This class copied from org.apache.batik.css.engine.sac */
-
-package org.eclipse.e4.ui.css.core.impl.sac;
-
-import org.w3c.css.sac.CSSException;
-import org.w3c.css.sac.CharacterDataSelector;
-import org.w3c.css.sac.Condition;
-import org.w3c.css.sac.ConditionalSelector;
-import org.w3c.css.sac.DescendantSelector;
-import org.w3c.css.sac.ElementSelector;
-import org.w3c.css.sac.NegativeSelector;
-import org.w3c.css.sac.ProcessingInstructionSelector;
-import org.w3c.css.sac.Selector;
-import org.w3c.css.sac.SelectorFactory;
-import org.w3c.css.sac.SiblingSelector;
-import org.w3c.css.sac.SimpleSelector;
-
-/**
- * This class implements the {@link org.w3c.css.sac.SelectorFactory} interface.
- */
-public class CSSSelectorFactoryImpl implements SelectorFactory {
-
- private static final String NOT_IMPLEMENTED_IN_CSS2 = "Not implemented in CSS2"; //$NON-NLS-1$
-
- /**
- * The instance of this class.
- */
- public static final SelectorFactory INSTANCE = new CSSSelectorFactoryImpl();
-
- /**
- * This class does not need to be instantiated.
- */
- protected CSSSelectorFactoryImpl() {
- }
-
- /**
- * SAC: Implements {@link
- * SelectorFactory#createConditionalSelector(SimpleSelector,Condition)}.
- */
- @Override
- public ConditionalSelector createConditionalSelector(
- SimpleSelector selector, Condition condition) throws CSSException {
- return new CSSConditionalSelectorImpl(selector, condition);
- }
-
- /**
- * SAC: Implements {@link
- * org.w3c.css.sac.SelectorFactory#createAnyNodeSelector()}.
- */
- @Override
- public SimpleSelector createAnyNodeSelector() throws CSSException {
- throw new CSSException(NOT_IMPLEMENTED_IN_CSS2);
- }
-
- /**
- * SAC: Implements {@link
- * org.w3c.css.sac.SelectorFactory#createRootNodeSelector()}.
- */
- @Override
- public SimpleSelector createRootNodeSelector() throws CSSException {
- throw new CSSException(NOT_IMPLEMENTED_IN_CSS2);
- }
-
- /**
- * SAC: Implements {@link
- * org.w3c.css.sac.SelectorFactory#createNegativeSelector(SimpleSelector)}.
- */
- @Override
- public NegativeSelector createNegativeSelector(SimpleSelector selector)
- throws CSSException {
- throw new CSSException(NOT_IMPLEMENTED_IN_CSS2);
- }
-
- /**
- * SAC: Implements {@link
- * org.w3c.css.sac.SelectorFactory#createElementSelector(String,String)}.
- */
- @Override
- public ElementSelector createElementSelector(String namespaceURI,
- String tagName) throws CSSException {
- return new CSSElementSelectorImpl(namespaceURI, tagName);
- }
-
- /**
- * SAC: Implements {@link
- * org.w3c.css.sac.SelectorFactory#createTextNodeSelector(String)}.
- */
- @Override
- public CharacterDataSelector createTextNodeSelector(String data)
- throws CSSException {
- throw new CSSException(NOT_IMPLEMENTED_IN_CSS2);
- }
-
- /**
- * SAC: Implements {@link
- * org.w3c.css.sac.SelectorFactory#createCDataSectionSelector(String)}.
- */
- @Override
- public CharacterDataSelector createCDataSectionSelector(String data)
- throws CSSException {
- throw new CSSException(NOT_IMPLEMENTED_IN_CSS2);
- }
-
- /**
- * SAC: Implements {@link
- * SelectorFactory#createProcessingInstructionSelector(String,String)}.
- */
- @Override
- public ProcessingInstructionSelector createProcessingInstructionSelector(
- String target, String data) throws CSSException {
- throw new CSSException(NOT_IMPLEMENTED_IN_CSS2);
- }
-
- /**
- * SAC: Implements {@link
- * org.w3c.css.sac.SelectorFactory#createCommentSelector(String)}.
- */
- @Override
- public CharacterDataSelector createCommentSelector(String data)
- throws CSSException {
- throw new CSSException(NOT_IMPLEMENTED_IN_CSS2);
- }
-
- /**
- * SAC: Implements {@link
- * SelectorFactory#createPseudoElementSelector(String,String)}.
- */
- @Override
- public ElementSelector createPseudoElementSelector(String namespaceURI,
- String pseudoName) throws CSSException {
- return new CSSPseudoElementSelectorImpl(namespaceURI, pseudoName);
- }
-
- /**
- * SAC: Implements {@link
- * SelectorFactory#createDescendantSelector(Selector,SimpleSelector)}.
- */
- @Override
- public DescendantSelector createDescendantSelector(Selector parent,
- SimpleSelector descendant) throws CSSException {
- return new CSSDescendantSelectorImpl(parent, descendant);
- }
-
- /**
- * SAC: Implements {@link
- * SelectorFactory#createChildSelector(Selector,SimpleSelector)}.
- */
- @Override
- public DescendantSelector createChildSelector(Selector parent,
- SimpleSelector child) throws CSSException {
- return new CSSChildSelectorImpl(parent, child);
- }
-
- /**
- * SAC: Implements {@link
- * SelectorFactory#createDirectAdjacentSelector(short,Selector,SimpleSelector)}.
- */
- @Override
- public SiblingSelector createDirectAdjacentSelector(short nodeType,
- Selector child, SimpleSelector directAdjacent) throws CSSException {
- return new CSSDirectAdjacentSelectorImpl(nodeType, child,
- directAdjacent);
- }
-}
diff --git a/bundles/org.eclipse.e4.ui.css.core/src/org/eclipse/e4/ui/css/core/impl/sac/ExtendedCondition.java b/bundles/org.eclipse.e4.ui.css.core/src/org/eclipse/e4/ui/css/core/impl/sac/ExtendedCondition.java
deleted file mode 100644
index edc785b6760..00000000000
--- a/bundles/org.eclipse.e4.ui.css.core/src/org/eclipse/e4/ui/css/core/impl/sac/ExtendedCondition.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
-
- Copyright 2002, 2015 The Apache Software Foundation
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
-
-/* This class copied from org.apache.batik.css.engine.sac */
-
-package org.eclipse.e4.ui.css.core.impl.sac;
-
-import java.util.Set;
-import org.w3c.css.sac.Condition;
-import org.w3c.dom.Element;
-
-/**
- * This interface provides additional features to the
- * {@link org.w3c.css.sac.Condition} interface.
- */
-public interface ExtendedCondition extends Condition {
-
- /**
- * Tests whether this condition matches the given element.
- */
- boolean match(Element e, String pseudoE);
-
- /**
- * Returns the specificity of this condition.
- */
- int getSpecificity();
-
- /**
- * Fills the given set with the attribute names found in this selector.
- */
- void fillAttributeSet(Set attrSet);
-}
diff --git a/bundles/org.eclipse.e4.ui.css.core/src/org/eclipse/e4/ui/css/core/impl/sac/ExtendedSelector.java b/bundles/org.eclipse.e4.ui.css.core/src/org/eclipse/e4/ui/css/core/impl/sac/ExtendedSelector.java
deleted file mode 100644
index b30db5d0db1..00000000000
--- a/bundles/org.eclipse.e4.ui.css.core/src/org/eclipse/e4/ui/css/core/impl/sac/ExtendedSelector.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
-
- Copyright 2002, 2015 The Apache Software Foundation
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
- */
-
-/* This class copied from org.apache.batik.css.engine.sac */
-
-package org.eclipse.e4.ui.css.core.impl.sac;
-
-import java.util.Set;
-import org.w3c.css.sac.Selector;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-
-/**
- * This interface extends the {@link org.w3c.css.sac.Selector}.
- */
-public interface ExtendedSelector extends Selector {
-
- default boolean match(Element e, Node[] ancestors, int parentIndex, String pseudoE) {
- return match(e, pseudoE);
- }
-
- /**
- * Tests whether this selector matches the given element.
- */
- boolean match(Element e, String pseudoE);
-
- /**
- * Returns the specificity of this selector.
- */
- int getSpecificity();
-
- /**
- * Fills the given set with the attribute names found in this selector.
- */
- void fillAttributeSet(Set attrSet);
-}
diff --git a/bundles/org.eclipse.e4.ui.css.swt/src/org/eclipse/e4/ui/css/swt/engine/CSSSWTEngineImpl.java b/bundles/org.eclipse.e4.ui.css.swt/src/org/eclipse/e4/ui/css/swt/engine/CSSSWTEngineImpl.java
index 8bfc22e01c4..7adcce44634 100644
--- a/bundles/org.eclipse.e4.ui.css.swt/src/org/eclipse/e4/ui/css/swt/engine/CSSSWTEngineImpl.java
+++ b/bundles/org.eclipse.e4.ui.css.swt/src/org/eclipse/e4/ui/css/swt/engine/CSSSWTEngineImpl.java
@@ -139,17 +139,22 @@ private boolean isApplicableToReset(WidgetElement element) {
@Override
public void reapply() {
- Shell[] shells = display.getShells();
- for (Shell s : shells) {
- try {
- s.setRedraw(false);
- s.reskin(SWT.ALL);
- applyStyles(s, true);
- } catch (Exception e) {
- ILog.of(getClass()).error(e.getMessage(), e);
- } finally {
- s.setRedraw(true);
+ startStylingSession();
+ try {
+ Shell[] shells = display.getShells();
+ for (Shell s : shells) {
+ try {
+ s.setRedraw(false);
+ s.reskin(SWT.ALL);
+ applyStyles(s, true);
+ } catch (Exception e) {
+ ILog.of(getClass()).error(e.getMessage(), e);
+ } finally {
+ s.setRedraw(true);
+ }
}
+ } finally {
+ stopStylingSession();
}
}
}
diff --git a/tests/org.eclipse.e4.ui.tests.css.core/src/org/eclipse/e4/ui/css/core/impl/engine/selector/SelectorMatcherTest.java b/tests/org.eclipse.e4.ui.tests.css.core/src/org/eclipse/e4/ui/css/core/impl/engine/selector/SelectorMatcherTest.java
new file mode 100644
index 00000000000..31162dd52c7
--- /dev/null
+++ b/tests/org.eclipse.e4.ui.tests.css.core/src/org/eclipse/e4/ui/css/core/impl/engine/selector/SelectorMatcherTest.java
@@ -0,0 +1,223 @@
+/*******************************************************************************
+ * Copyright (c) 2026 Lars Vogel and others.
+ *
+ * This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ * Lars Vogel - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.e4.ui.css.core.impl.engine.selector;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.util.List;
+
+import org.eclipse.e4.ui.css.core.impl.engine.CSSEngineImpl;
+import org.eclipse.e4.ui.css.core.impl.engine.selector.Selectors.Adjacent;
+import org.eclipse.e4.ui.css.core.impl.engine.selector.Selectors.And;
+import org.eclipse.e4.ui.css.core.impl.engine.selector.Selectors.AttributeBeginHyphen;
+import org.eclipse.e4.ui.css.core.impl.engine.selector.Selectors.AttributeIncludes;
+import org.eclipse.e4.ui.css.core.impl.engine.selector.Selectors.AttributeSelector;
+import org.eclipse.e4.ui.css.core.impl.engine.selector.Selectors.Child;
+import org.eclipse.e4.ui.css.core.impl.engine.selector.Selectors.ClassSelector;
+import org.eclipse.e4.ui.css.core.impl.engine.selector.Selectors.Descendant;
+import org.eclipse.e4.ui.css.core.impl.engine.selector.Selectors.ElementType;
+import org.eclipse.e4.ui.css.core.impl.engine.selector.Selectors.IdSelector;
+import org.eclipse.e4.ui.css.core.impl.engine.selector.Selectors.PseudoClass;
+import org.eclipse.e4.ui.css.core.impl.engine.selector.Selectors.SelectorList;
+import org.eclipse.e4.ui.css.core.impl.engine.selector.Selectors.Universal;
+import org.eclipse.e4.ui.tests.css.core.util.TestElement;
+import org.junit.jupiter.api.Test;
+
+/**
+ * Unit tests for {@link SelectorMatcher}. The cases mirror those in the
+ * Phase 1 {@code CSSEngineTest}, but go through the new internal selector
+ * AST instead of SAC. When Phase 3 Step 1 wires the engine to use this
+ * matcher, the SAC-based duplicate tests can be retired.
+ */
+class SelectorMatcherTest {
+
+ private static final TestCSSEngine ENGINE = new TestCSSEngine();
+
+ private static final class TestCSSEngine extends CSSEngineImpl {
+ @Override
+ public void reapply() {
+ }
+ }
+
+ private static TestElement element(String tag, String cssClass, String id) {
+ TestElement e = new TestElement(tag, ENGINE);
+ if (cssClass != null) {
+ e.setClass(cssClass);
+ }
+ if (id != null) {
+ e.setId(id);
+ }
+ return e;
+ }
+
+ @Test
+ void universalMatchesAnything() {
+ assertTrue(SelectorMatcher.matches(new Universal(), element("Button", null, null), null));
+ assertTrue(SelectorMatcher.matches(new Universal(), element("Label", "x", "y"), null));
+ }
+
+ @Test
+ void typeSelectorIsCaseSensitive() {
+ assertTrue(SelectorMatcher.matches(new ElementType("Button"), element("Button", null, null), null));
+ assertFalse(SelectorMatcher.matches(new ElementType("Button"), element("button", null, null), null));
+ assertFalse(SelectorMatcher.matches(new ElementType("Button"), element("Label", null, null), null));
+ }
+
+ @Test
+ void classSelector() {
+ assertTrue(SelectorMatcher.matches(new ClassSelector("foo"), element("Button", "foo", null), null));
+ assertFalse(SelectorMatcher.matches(new ClassSelector("foo"), element("Button", "bar", null), null));
+ assertFalse(SelectorMatcher.matches(new ClassSelector("foo"), element("Button", null, null), null));
+ }
+
+ @Test
+ void classSelectorMatchesOneOfMultipleClasses() {
+ assertTrue(SelectorMatcher.matches(new ClassSelector("foo"), element("Button", "foo bar", null), null));
+ assertTrue(SelectorMatcher.matches(new ClassSelector("bar"), element("Button", "foo bar", null), null));
+ assertFalse(SelectorMatcher.matches(new ClassSelector("baz"), element("Button", "foo bar", null), null));
+ }
+
+ @Test
+ void idSelector() {
+ assertTrue(SelectorMatcher.matches(new IdSelector("go"), element("Button", null, "go"), null));
+ assertFalse(SelectorMatcher.matches(new IdSelector("go"), element("Button", null, "stop"), null));
+ assertFalse(SelectorMatcher.matches(new IdSelector("go"), element("Button", null, null), null));
+ }
+
+ @Test
+ void compoundSelector() {
+ Selectors.Selector selector = new And(new And(new ElementType("Button"), new ClassSelector("primary")),
+ new IdSelector("go"));
+ assertTrue(SelectorMatcher.matches(selector, element("Button", "primary", "go"), null));
+ assertFalse(SelectorMatcher.matches(selector, element("Label", "primary", "go"), null));
+ assertFalse(SelectorMatcher.matches(selector, element("Button", "secondary", "go"), null));
+ assertFalse(SelectorMatcher.matches(selector, element("Button", "primary", "stop"), null));
+ }
+
+ @Test
+ void descendantCombinator() {
+ Selectors.Selector selector = new Descendant(new ElementType("Composite"), new ElementType("Button"));
+ TestElement composite = element("Composite", null, null);
+ TestElement intermediate = new TestElement("Group", composite, ENGINE);
+ TestElement button = new TestElement("Button", intermediate, ENGINE);
+ assertTrue(SelectorMatcher.matches(selector, button, null));
+
+ TestElement orphan = element("Button", null, null);
+ assertFalse(SelectorMatcher.matches(selector, orphan, null));
+ }
+
+ @Test
+ void childCombinator() {
+ Selectors.Selector selector = new Child(new ElementType("Composite"), new ElementType("Button"));
+ TestElement composite = element("Composite", null, null);
+ TestElement direct = new TestElement("Button", composite, ENGINE);
+ assertTrue(SelectorMatcher.matches(selector, direct, null));
+
+ TestElement intermediate = new TestElement("Group", composite, ENGINE);
+ TestElement grandchild = new TestElement("Button", intermediate, ENGINE);
+ assertFalse(SelectorMatcher.matches(selector, grandchild, null));
+ }
+
+ @Test
+ void attributePresentMatchesEvenWithEmptyValue() {
+ AttributeSelector selector = new AttributeSelector("style", null);
+ TestElement withAttr = element("Button", null, null);
+ withAttr.setAttribute("style", "SWT.PUSH");
+ assertTrue(SelectorMatcher.matches(selector, withAttr, null));
+ assertFalse(SelectorMatcher.matches(selector, element("Button", null, null), null));
+ }
+
+ @Test
+ void attributeIncludesIsWordBoundaryMatch() {
+ AttributeIncludes selector = new AttributeIncludes("style", "SWT.CHECK");
+ TestElement match = element("Button", null, null);
+ match.setAttribute("style", "SWT.CHECK SWT.BORDER");
+ assertTrue(SelectorMatcher.matches(selector, match, null));
+
+ TestElement substring = element("Button", null, null);
+ substring.setAttribute("style", "SWT.CHECK_DELAYED");
+ // 'CHECK' is a substring of 'CHECK_DELAYED' but not a whitespace-separated word.
+ assertFalse(SelectorMatcher.matches(new AttributeIncludes("style", "CHECK"), substring, null));
+ }
+
+ @Test
+ void attributeBeginHyphen() {
+ AttributeBeginHyphen selector = new AttributeBeginHyphen("lang", "en");
+ TestElement exact = element("p", null, null);
+ exact.setAttribute("lang", "en");
+ TestElement prefixed = element("p", null, null);
+ prefixed.setAttribute("lang", "en-US");
+ TestElement other = element("p", null, null);
+ other.setAttribute("lang", "fr");
+ assertTrue(SelectorMatcher.matches(selector, exact, null));
+ assertTrue(SelectorMatcher.matches(selector, prefixed, null));
+ assertFalse(SelectorMatcher.matches(selector, other, null));
+ }
+
+ @Test
+ void pseudoClassMatchesViaIsPseudoInstanceOf() {
+ PseudoClass selector = new PseudoClass("selected");
+ TestElement on = new TestElement("Button", ENGINE) {
+ @Override
+ public boolean isPseudoInstanceOf(String s) {
+ return "selected".equals(s);
+ }
+ };
+ TestElement off = element("Button", null, null);
+ assertTrue(SelectorMatcher.matches(selector, on, null));
+ assertFalse(SelectorMatcher.matches(selector, off, null));
+ }
+
+ @Test
+ void selectorListMatchesAnyAlternative() {
+ SelectorList list = new SelectorList(List.of(new ClassSelector("a"), new ClassSelector("b")));
+ assertTrue(SelectorMatcher.matches(list, element("Button", "a", null), null));
+ assertTrue(SelectorMatcher.matches(list, element("Button", "b", null), null));
+ assertFalse(SelectorMatcher.matches(list, element("Button", "c", null), null));
+ }
+
+ @Test
+ void specificityMatchesCss21() {
+ assertEquals(0, new Universal().specificity());
+ assertEquals(1, new ElementType("Button").specificity());
+ assertEquals(10, new ClassSelector("foo").specificity());
+ assertEquals(100, new IdSelector("go").specificity());
+ assertEquals(11, new And(new ElementType("Button"), new ClassSelector("primary")).specificity());
+ assertEquals(111, new And(new And(new ElementType("Button"), new ClassSelector("primary")),
+ new IdSelector("go")).specificity());
+ }
+
+ @Test
+ void specificityOfSelectorListIsMaxOverAlternatives() {
+ // "Button, .foo, #go": max specificity is the id (100).
+ SelectorList list = new SelectorList(
+ List.of(new ElementType("Button"), new ClassSelector("foo"), new IdSelector("go")));
+ assertEquals(100, list.specificity());
+ }
+
+ @Test
+ void adjacentSiblingCombinatorRequiresSiblingSupport() {
+ // TestElement's ElementAdapter base returns null from getPreviousSibling,
+ // so adjacent matching cannot succeed against it. Locks in that the
+ // matcher returns false rather than throwing on elements without
+ // sibling support.
+ Adjacent selector = new Adjacent(new ElementType("Label"), new ElementType("Button"));
+ TestElement parent = element("Composite", null, null);
+ new TestElement("Label", parent, ENGINE);
+ TestElement second = new TestElement("Button", parent, ENGINE);
+ assertFalse(SelectorMatcher.matches(selector, second, null));
+ }
+}
diff --git a/tests/org.eclipse.e4.ui.tests.css.core/src/org/eclipse/e4/ui/tests/css/core/CSSEngineTest.java b/tests/org.eclipse.e4.ui.tests.css.core/src/org/eclipse/e4/ui/tests/css/core/CSSEngineTest.java
index fa16ea5395e..31916477fd6 100644
--- a/tests/org.eclipse.e4.ui.tests.css.core/src/org/eclipse/e4/ui/tests/css/core/CSSEngineTest.java
+++ b/tests/org.eclipse.e4.ui.tests.css.core/src/org/eclipse/e4/ui/tests/css/core/CSSEngineTest.java
@@ -23,10 +23,10 @@
import org.eclipse.e4.ui.css.core.engine.CSSEngine;
import org.eclipse.e4.ui.css.core.impl.engine.CSSEngineImpl;
+import org.eclipse.e4.ui.css.core.impl.engine.selector.Selectors;
+import org.eclipse.e4.ui.css.core.impl.engine.selector.Selectors.Selector;
import org.eclipse.e4.ui.tests.css.core.util.TestElement;
import org.junit.jupiter.api.Test;
-import org.w3c.css.sac.Selector;
-import org.w3c.css.sac.SelectorList;
import org.w3c.dom.Element;
class CSSEngineTest {
@@ -55,7 +55,7 @@ private static Selector parse(CSSEngine engine, String selector) throws Exceptio
@Test
void testSelectorMatch() throws Exception {
TestCSSEngine engine = new TestCSSEngine();
- SelectorList list = engine.parseSelectors("Date");
+ Selectors.SelectorList list = engine.parseSelectors("Date");
engine.setElementProvider((element, engine1) -> new TestElement(element.getClass().getSimpleName(),
engine1));
assertFalse(engine.matches(list.item(0), new Object(), null));
@@ -249,7 +249,7 @@ void testNegativeMatch() throws Exception {
@Test
void testSelectorListMatch() throws Exception {
TestCSSEngine engine = new TestCSSEngine();
- SelectorList list = engine.parseSelectors(".a, .b");
+ Selectors.SelectorList list = engine.parseSelectors(".a, .b");
TestElement a = createElement(engine, "Button", "a", null);
TestElement b = createElement(engine, "Button", "b", null);
TestElement c = createElement(engine, "Button", "c", null);
@@ -274,9 +274,9 @@ void testTagNameCaseSensitivity() throws Exception {
assertFalse(engine.matches(lower, capitalElement, null));
}
- private static boolean matchesAny(CSSEngine engine, SelectorList list, Element element) {
- for (int i = 0; i < list.getLength(); i++) {
- if (engine.matches(list.item(i), element, null)) {
+ private static boolean matchesAny(CSSEngine engine, Selectors.SelectorList list, Element element) {
+ for (Selector selector : list.alternatives()) {
+ if (engine.matches(selector, element, null)) {
return true;
}
}
diff --git a/tests/org.eclipse.e4.ui.tests.css.core/src/org/eclipse/e4/ui/tests/css/core/parser/SelectorTest.java b/tests/org.eclipse.e4.ui.tests.css.core/src/org/eclipse/e4/ui/tests/css/core/parser/SelectorTest.java
index f3419a83eb0..43a3be1899b 100644
--- a/tests/org.eclipse.e4.ui.tests.css.core/src/org/eclipse/e4/ui/tests/css/core/parser/SelectorTest.java
+++ b/tests/org.eclipse.e4.ui.tests.css.core/src/org/eclipse/e4/ui/tests/css/core/parser/SelectorTest.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2013, 2014 IBM Corporation and others.
+ * Copyright (c) 2013, 2026 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -21,11 +21,11 @@
import java.io.IOException;
import org.eclipse.e4.ui.css.core.engine.CSSEngine;
+import org.eclipse.e4.ui.css.core.impl.engine.selector.Selectors;
import org.eclipse.e4.ui.tests.css.core.util.ParserTestUtil;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.w3c.css.sac.CSSParseException;
-import org.w3c.css.sac.SelectorList;
public class SelectorTest {
private CSSEngine engine;
@@ -37,35 +37,37 @@ public void setUp() throws Exception {
@Test
void testSimpleSelector() throws Exception {
- SelectorList list = engine.parseSelectors("Type1");
+ Selectors.SelectorList list = engine.parseSelectors("Type1");
assertNotNull(list);
assertEquals(1, list.getLength());
- assertEquals("Type1", list.item(0).toString());
+ assertEquals("Type1", list.item(0).text());
}
@Test
void testMultipleSelectors() throws Exception {
- SelectorList list = engine.parseSelectors("Type1, Type2");
+ Selectors.SelectorList list = engine.parseSelectors("Type1, Type2");
assertNotNull(list);
assertEquals(2, list.getLength());
- assertEquals("Type1", list.item(0).toString());
- assertEquals("Type2", list.item(1).toString());
+ assertEquals("Type1", list.item(0).text());
+ assertEquals("Type2", list.item(1).text());
}
@Test
void testClassSelector() throws Exception {
- SelectorList list = engine.parseSelectors(".Class1");
+ Selectors.SelectorList list = engine.parseSelectors(".Class1");
assertNotNull(list);
assertEquals(1, list.getLength());
- assertEquals("*[class=\"Class1\"]", list.item(0).toString());
+ assertEquals(".Class1", list.item(0).text());
}
@Test
void testAttributeSelector() throws Exception {
- SelectorList list = engine.parseSelectors("*[class='Class1']");
+ Selectors.SelectorList list = engine.parseSelectors("*[class='Class1']");
assertNotNull(list);
assertEquals(1, list.getLength());
- assertEquals("*[class=\"Class1\"]", list.item(0).toString());
+ // The Universal selector ('*') is folded away since the AttributeSelector
+ // alone carries the full match condition.
+ assertEquals("[class='Class1']", list.item(0).text());
}
@Test