--- old/modules/graphics/src/main/java/com/sun/javafx/css/CompoundSelector.java 2015-09-03 15:31:10.317970700 -0700
+++ /dev/null 2015-09-03 15:31:11.000000000 -0700
@@ -1,336 +0,0 @@
-/*
- * Copyright (c) 2008, 2014, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package com.sun.javafx.css;
-
-import javafx.css.PseudoClass;
-import javafx.css.Styleable;
-
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Set;
-
-/**
- * A compound selector which behaves according to the CSS standard. The selector is
- * composed of one or more Selectors
, along with an array of
- * CompoundSelectorRelationships
indicating the required relationship at each
- * stage. There must be exactly one less Combinator
than
- * there are selectors.
- *
- * For example, the parameters [selector1, selector2, selector3]
- * and [Combinator.CHILD, Combinator.DESCENDANT]
will match
- * a component when all of the following conditions hold:
- *
- * - The component itself is matched by selector3
- *
- The component has an ancestor which is matched by selector2
- *
- The ancestor matched in step 2 is a direct CHILD of a component
- * matched by selector1
- *
- * In other words, the compound selector specified above is (in CSS syntax)
- * selector1 > selector2 selector3
. The greater-than (>)
- * between selector1 and selector2 specifies a direct CHILD, whereas the
- * whitespace between selector2 and selector3 corresponds to
- * Combinator.DESCENDANT
.
- *
- */
-
-final public class CompoundSelector extends Selector {
-
- private final List selectors;
- /**
- * The selectors that make up this compound selector
- * @return Immutable List<SimpleSelector>
- */
- public List getSelectors() {
- return selectors;
- }
-
- private final List relationships;
- /**
- * The relationships between the selectors
- * @return Immutable List<Combinator>
- */
- public List getRelationships() {
- return relationships;
- }
-
- public CompoundSelector(List selectors, List relationships)
- {
- this.selectors =
- (selectors != null)
- ? Collections.unmodifiableList(selectors)
- : Collections.EMPTY_LIST;
- this.relationships =
- (relationships != null)
- ? Collections.unmodifiableList(relationships)
- : Collections.EMPTY_LIST;
- }
-
- private CompoundSelector()
- {
- this(null, null);
- }
-
- Match createMatch() {
-
- final PseudoClassState allPseudoClasses = new PseudoClassState();
- int idCount = 0;
- int styleClassCount = 0;
-
- for(int n=0, nMax=selectors.size(); n[] triggerStates, int depth) {
-
- assert (triggerStates == null || depth < triggerStates.length);
- if (triggerStates != null && triggerStates.length <= depth) {
- return false;
- }
-
- //
- // We only care about pseudo-class if the selector applies. But in
- // the case of a compound selector, we don't know whether it applies
- // until all the selectors have been checked (in the worse case). So
- // the setting of pseudo-class has to be deferred until we know
- // that this compound selector applies. So we'll send a new
- // PseudoClassSet[] and if the compound selector applies,
- // just copy the state back.
- //
- final Set[] tempStates = triggerStates != null
- ? new PseudoClassState[triggerStates.length] : null;
-
- final boolean applies = applies(styleable, selectors.size()-1, tempStates, depth);
-
- if (applies && tempStates != null) {
-
- for(int n=0; n pseudoClassOut = triggerStates[n];
- final Set pseudoClassIn = tempStates[n];
-
- if (pseudoClassOut != null) {
- pseudoClassOut.addAll(pseudoClassIn);
- } else {
- triggerStates[n] = pseudoClassIn;
- }
-
- }
- }
- return applies;
- }
-
- private boolean applies(final Styleable styleable, final int index, Set[] triggerStates, int depth) {
- // If the index is < 0 then we know we don't apply
- if (index < 0) return false;
-
- // Simply check the selector associated with this index and see if it
- // applies to the Node
- if (! selectors.get(index).applies(styleable, triggerStates, depth)) return false;
-
- // If there are no more selectors to check (ie: index == 0) then we
- // know we know we apply
- if (index == 0) return true;
-
- // We have not yet checked all the selectors in this CompoundSelector,
- // so now we need to find the next parent and try again. If the
- // relationship between this selector and its ancestor selector is
- // "CHILD" then it is required that the parent scenegraph node match
- // the ancestor selector. Otherwise, we just walk up the scenegraph
- // until we find an ancestor node that matches the selector. If we
- // manage to walk all the way to the top without having satisfied all
- // of the selectors, then we know it doesn't apply.
- final Combinator relationship = relationships.get(index-1);
- if (relationship == Combinator.CHILD) {
- final Styleable parent = styleable.getStyleableParent();
- if (parent == null) return false;
- // If this call succeeds, then all preceding selectors will have
- // matched due to the recursive nature of the call
- return applies(parent, index - 1, triggerStates, ++depth);
- } else {
- Styleable parent = styleable.getStyleableParent();
- while (parent != null) {
- boolean answer = applies(parent, index - 1, triggerStates, ++depth);
- // If a call to stateMatches succeeded, then we know that
- // all preceding selectors will have also matched.
- if (answer) return true;
- // Otherwise we need to get the next parent and try again
- parent = parent.getStyleableParent();
- }
- }
- return false;
- }
-
- @Override
- public boolean stateMatches(final Styleable styleable, Set states) {
- return stateMatches(styleable, states, selectors.size()-1);
- }
-
- private boolean stateMatches(Styleable styleable, Set states, int index) {
- // If the index is < 0 then we know we don't match
- if (index < 0) return false;
-
- // Simply check the selector associated with this index and see if it
- // matches the Node and states provided.
- if (! selectors.get(index).stateMatches(styleable, states)) return false;
-
- // If there are no more selectors to match (ie: index == 0) then we
- // know we have successfully matched
- if (index == 0) return true;
-
- // We have not yet checked all the selectors in this CompoundSelector,
- // so now we need to find the next parent and try again. If the
- // relationship between this selector and its ancestor selector is
- // "CHILD" then it is required that the parent scenegraph node match
- // the ancestor selector. Otherwise, we just walk up the scenegraph
- // until we find an ancestor node that matches the selector. If we
- // manage to walk all the way to the top without having satisfied all
- // of the selectors, then we know it doesn't match.
- final Combinator relationship = relationships.get(index - 1);
- if (relationship == Combinator.CHILD) {
- final Styleable parent = styleable.getStyleableParent();
- if (parent == null) return false;
- if (selectors.get(index-1).applies(parent)) {
- // If this call succeeds, then all preceding selectors will have
- // matched due to the recursive nature of the call
- Set parentStates = parent.getPseudoClassStates();
- return stateMatches(parent, parentStates, index - 1);
- }
- } else {
- Styleable parent = styleable.getStyleableParent();
- while (parent != null) {
- if (selectors.get(index-1).applies(parent)) {
- Set parentStates = parent.getPseudoClassStates();
- return stateMatches(parent, parentStates, index - 1);
- }
- // Otherwise we need to get the next parent and try again
- parent = parent.getStyleableParent();
- }
- }
-
- return false;
- }
-
- private int hash = -1;
-
- /* Hash code is used in Style's hash code and Style's hash
- code is used by StyleHelper */
- @Override
- public int hashCode() {
- if (hash == -1) {
- for (int i = 0, max=selectors.size(); i selectors = new ArrayList();
- for (int n=0; n relationships = new ArrayList();
- for (int n=0; nSelectors, along with an array of
+ * CompoundSelectorRelationships
indicating the required relationship at each
+ * stage. There must be exactly one less Combinator
than
+ * there are selectors.
+ *
+ * For example, the parameters [selector1, selector2, selector3]
+ * and [Combinator.CHILD, Combinator.DESCENDANT]
will match
+ * a component when all of the following conditions hold:
+ *
+ * - The component itself is matched by selector3
+ *
- The component has an ancestor which is matched by selector2
+ *
- The ancestor matched in step 2 is a direct CHILD of a component
+ * matched by selector1
+ *
+ * In other words, the compound selector specified above is (in CSS syntax)
+ * selector1 > selector2 selector3
. The greater-than (>)
+ * between selector1 and selector2 specifies a direct CHILD, whereas the
+ * whitespace between selector2 and selector3 corresponds to
+ * Combinator.DESCENDANT
.
+ *
+ * @since 9
+ */
+final public class CompoundSelector extends Selector {
+
+ private final List selectors;
+ /**
+ * The selectors that make up this compound selector
+ * @return Immutable List<SimpleSelector>
+ */
+ public List getSelectors() {
+ return selectors;
+ }
+
+ private final List relationships;
+ // /**
+ // * The relationships between the selectors
+ // * @return Immutable List<Combinator>
+ // */
+ // public List getRelationships() {
+ // return relationships;
+ // }
+
+ /**
+ * Creates a CompoundSelector
from a list of selectors and a
+ * list of Combinator
relationships. There must be exactly one
+ * less Combinator
than there are selectors.
+ */
+ CompoundSelector(List selectors, List relationships) {
+ this.selectors =
+ (selectors != null)
+ ? Collections.unmodifiableList(selectors)
+ : Collections.EMPTY_LIST;
+ this.relationships =
+ (relationships != null)
+ ? Collections.unmodifiableList(relationships)
+ : Collections.EMPTY_LIST;
+ }
+
+ private CompoundSelector() {
+ this(null, null);
+ }
+
+
+ @Override public Match createMatch() {
+ final PseudoClassState allPseudoClasses = new PseudoClassState();
+ int idCount = 0;
+ int styleClassCount = 0;
+
+ for(int n=0, nMax=selectors.size(); n[] triggerStates, int depth) {
+
+ assert (triggerStates == null || depth < triggerStates.length);
+ if (triggerStates != null && triggerStates.length <= depth) {
+ return false;
+ }
+
+ //
+ // We only care about pseudo-class if the selector applies. But in
+ // the case of a compound selector, we don't know whether it applies
+ // until all the selectors have been checked (in the worse case). So
+ // the setting of pseudo-class has to be deferred until we know
+ // that this compound selector applies. So we'll send a new
+ // PseudoClassSet[] and if the compound selector applies,
+ // just copy the state back.
+ //
+ final Set[] tempStates = triggerStates != null
+ ? new PseudoClassState[triggerStates.length] : null;
+
+ final boolean applies = applies(styleable, selectors.size()-1, tempStates, depth);
+
+ if (applies && tempStates != null) {
+
+ for(int n=0; n pseudoClassOut = triggerStates[n];
+ final Set pseudoClassIn = tempStates[n];
+
+ if (pseudoClassOut != null) {
+ pseudoClassOut.addAll(pseudoClassIn);
+ } else {
+ triggerStates[n] = pseudoClassIn;
+ }
+
+ }
+ }
+ return applies;
+ }
+
+ private boolean applies(final Styleable styleable, final int index, Set[] triggerStates, int depth) {
+ // If the index is < 0 then we know we don't apply
+ if (index < 0) return false;
+
+ // Simply check the selector associated with this index and see if it
+ // applies to the Node
+ if (! selectors.get(index).applies(styleable, triggerStates, depth)) return false;
+
+ // If there are no more selectors to check (ie: index == 0) then we
+ // know we know we apply
+ if (index == 0) return true;
+
+ // We have not yet checked all the selectors in this CompoundSelector,
+ // so now we need to find the next parent and try again. If the
+ // relationship between this selector and its ancestor selector is
+ // "CHILD" then it is required that the parent scenegraph node match
+ // the ancestor selector. Otherwise, we just walk up the scenegraph
+ // until we find an ancestor node that matches the selector. If we
+ // manage to walk all the way to the top without having satisfied all
+ // of the selectors, then we know it doesn't apply.
+ final Combinator relationship = relationships.get(index-1);
+ if (relationship == Combinator.CHILD) {
+ final Styleable parent = styleable.getStyleableParent();
+ if (parent == null) return false;
+ // If this call succeeds, then all preceding selectors will have
+ // matched due to the recursive nature of the call
+ return applies(parent, index - 1, triggerStates, ++depth);
+ } else {
+ Styleable parent = styleable.getStyleableParent();
+ while (parent != null) {
+ boolean answer = applies(parent, index - 1, triggerStates, ++depth);
+ // If a call to stateMatches succeeded, then we know that
+ // all preceding selectors will have also matched.
+ if (answer) return true;
+ // Otherwise we need to get the next parent and try again
+ parent = parent.getStyleableParent();
+ }
+ }
+ return false;
+ }
+
+ @Override public boolean stateMatches(final Styleable styleable, Set states) {
+ return stateMatches(styleable, states, selectors.size()-1);
+ }
+
+ private boolean stateMatches(Styleable styleable, Set states, int index) {
+ // If the index is < 0 then we know we don't match
+ if (index < 0) return false;
+
+ // Simply check the selector associated with this index and see if it
+ // matches the Node and states provided.
+ if (! selectors.get(index).stateMatches(styleable, states)) return false;
+
+ // If there are no more selectors to match (ie: index == 0) then we
+ // know we have successfully matched
+ if (index == 0) return true;
+
+ // We have not yet checked all the selectors in this CompoundSelector,
+ // so now we need to find the next parent and try again. If the
+ // relationship between this selector and its ancestor selector is
+ // "CHILD" then it is required that the parent scenegraph node match
+ // the ancestor selector. Otherwise, we just walk up the scenegraph
+ // until we find an ancestor node that matches the selector. If we
+ // manage to walk all the way to the top without having satisfied all
+ // of the selectors, then we know it doesn't match.
+ final Combinator relationship = relationships.get(index - 1);
+ if (relationship == Combinator.CHILD) {
+ final Styleable parent = styleable.getStyleableParent();
+ if (parent == null) return false;
+ if (selectors.get(index-1).applies(parent)) {
+ // If this call succeeds, then all preceding selectors will have
+ // matched due to the recursive nature of the call
+ Set parentStates = parent.getPseudoClassStates();
+ return stateMatches(parent, parentStates, index - 1);
+ }
+ } else {
+ Styleable parent = styleable.getStyleableParent();
+ while (parent != null) {
+ if (selectors.get(index-1).applies(parent)) {
+ Set parentStates = parent.getPseudoClassStates();
+ return stateMatches(parent, parentStates, index - 1);
+ }
+ // Otherwise we need to get the next parent and try again
+ parent = parent.getStyleableParent();
+ }
+ }
+
+ return false;
+ }
+
+ private int hash = -1;
+
+ /* Hash code is used in Style's hash code and Style's hash
+ code is used by StyleHelper */
+ @Override public int hashCode() {
+ if (hash == -1) {
+ for (int i = 0, max=selectors.size(); i selectors = new ArrayList();
+ for (int n=0; n relationships = new ArrayList();
+ for (int n=0; n