--- old/modules/graphics/src/main/java/com/sun/javafx/css/SimpleSelector.java 2015-09-03 15:32:13.642592600 -0700 +++ /dev/null 2015-09-03 15:32:14.000000000 -0700 @@ -1,404 +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 javafx.geometry.NodeOrientation; -import javafx.scene.Node; - -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; -import java.util.Set; - -import static javafx.geometry.NodeOrientation.INHERIT; -import static javafx.geometry.NodeOrientation.LEFT_TO_RIGHT; -import static javafx.geometry.NodeOrientation.RIGHT_TO_LEFT; - -/** - * A simple selector which behaves according to the CSS standard. - * - */ -final public class SimpleSelector extends Selector { - - /** - * If specified in the CSS file, the name of the java class to which - * this selector is applied. For example, if the CSS file had: - *
-     *   Rectangle { }
-     * 
- * then name would be "Rectangle". - */ - final private String name; - /** - * @return The name of the java class to which this selector is applied, or *. - */ - public String getName() { - return name; - } - - /** - * @return Immutable List<String> of style-classes of the selector - */ - public List getStyleClasses() { - - final List names = new ArrayList(); - - Iterator iter = styleClassSet.iterator(); - while (iter.hasNext()) { - names.add(iter.next().getStyleClassName()); - } - - return Collections.unmodifiableList(names); - } - - Set getStyleClassSet() { - return styleClassSet; - } - - /** styleClasses converted to a set of bit masks */ - final private StyleClassSet styleClassSet; - - final private String id; - /* - * @return The value of the selector id, which may be an empty string. - */ - public String getId() { - return id; - } - - // a mask of bits corresponding to the pseudoclasses - final private PseudoClassState pseudoClassState; - - Set getPseudoClassStates() { - return pseudoClassState; - } - - /** - * @return Immutable List<String> of pseudo-classes of the selector - */ - public List getPseudoclasses() { - - final List names = new ArrayList(); - - Iterator iter = pseudoClassState.iterator(); - while (iter.hasNext()) { - names.add(iter.next().getPseudoClassName()); - } - - if (nodeOrientation == RIGHT_TO_LEFT) { - names.add("dir(rtl)"); - } else if (nodeOrientation == LEFT_TO_RIGHT) { - names.add("dir(ltr)"); - } - - return Collections.unmodifiableList(names); - } - - // true if name is not a wildcard - final private boolean matchOnName; - - // true if id given - final private boolean matchOnId; - - // true if style class given - final private boolean matchOnStyleClass; - - // dir(ltr) or dir(rtl), otherwise inherit - final private NodeOrientation nodeOrientation; - - // Used in Match. If nodeOrientation is ltr or rtl, - // then count it as a pseudoclass - NodeOrientation getNodeOrientation() { - return nodeOrientation; - } - - // TODO: The parser passes styleClasses as a List. Should be array? - public SimpleSelector(final String name, final List styleClasses, - final List pseudoClasses, final String id) - { - this.name = name == null ? "*" : name; - // if name is not null and not empty or wildcard, - // then match needs to check name - this.matchOnName = (name != null && !("".equals(name)) && !("*".equals(name))); - - this.styleClassSet = new StyleClassSet(); - - int nMax = styleClasses != null ? styleClasses.size() : 0; - for(int n=0; n 0); - - this.pseudoClassState = new PseudoClassState(); - - nMax = pseudoClasses != null ? pseudoClasses.size() : 0; - - NodeOrientation dir = NodeOrientation.INHERIT; - for(int n=0; n styleClasses = styleable.getStyleClass(); - for(int n=0, nMax = styleClasses.size(); n[] pseudoClasses, int depth) { - - - final boolean applies = applies(styleable); - - // - // We only need the pseudo-classes if the selector applies to the node. - // - if (applies && pseudoClasses != null && depth < pseudoClasses.length) { - - if (pseudoClasses[depth] == null) { - pseudoClasses[depth] = new PseudoClassState(); - } - - pseudoClasses[depth].addAll(pseudoClassState); - - } - return applies; - } - - @Override - public boolean stateMatches(final Styleable styleable, Set states) { - // [foo bar] matches [foo bar bang], - // but [foo bar bang] doesn't match [foo bar] - return states != null ? states.containsAll(pseudoClassState) : false; - } - - // Are the Selector's style classes a subset of the Node's style classes? - // - // http://www.w3.org/TR/css3-selectors/#class-html - // The following selector matches any P element whose class attribute has been - // assigned a list of whitespace-separated values that includes both - // pastoral and marine: - // - // p.pastoral.marine { color: green } - // - // This selector matches when class="pastoral blue aqua marine" but does not - // match for class="pastoral blue". - private boolean matchStyleClasses(StyleClassSet otherStyleClasses) { - return otherStyleClasses.containsAll(styleClassSet); - } - - @Override - public boolean equals(Object obj) { - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - final SimpleSelector other = (SimpleSelector) obj; - if ((this.name == null) ? (other.name != null) : !this.name.equals(other.name)) { - return false; - } - if ((this.id == null) ? (other.id != null) : !this.id.equals(other.id)) { - return false; - } - if (this.styleClassSet.equals(other.styleClassSet) == false) { - return false; - } - if (this.pseudoClassState.equals(other.pseudoClassState) == false) { - return false; - } - - return true; - } - - /* Hash code is used in Style's hash code and Style's hash - code is used by StyleHelper */ - @Override public int hashCode() { - int hash = 7; - hash = 31 * (hash + name.hashCode()); - hash = 31 * (hash + styleClassSet.hashCode()); - hash = 31 * (hash + styleClassSet.hashCode()); - hash = (id != null) ? 31 * (hash + id.hashCode()) : 0; - hash = 31 * (hash + pseudoClassState.hashCode()); - return hash; - } - - /** Converts this object to a string. */ - @Override public String toString() { - - StringBuilder sbuf = new StringBuilder(); - if (name != null && name.isEmpty() == false) sbuf.append(name); - else sbuf.append("*"); - Iterator iter1 = styleClassSet.iterator(); - while(iter1.hasNext()) { - final StyleClass styleClass = iter1.next(); - sbuf.append('.').append(styleClass.getStyleClassName()); - } - if (id != null && id.isEmpty() == false) { - sbuf.append('#'); - sbuf.append(id); - } - Iterator iter2 = pseudoClassState.iterator(); - while(iter2.hasNext()) { - final PseudoClass pseudoClass = iter2.next(); - sbuf.append(':').append(pseudoClass.getPseudoClassName()); - } - - return sbuf.toString(); - } - - public final void writeBinary(final DataOutputStream os, final StringStore stringStore) - throws IOException - { - super.writeBinary(os, stringStore); - os.writeShort(stringStore.addString(name)); - os.writeShort(styleClassSet.size()); - Iterator iter1 = styleClassSet.iterator(); - while(iter1.hasNext()) { - final StyleClass sc = iter1.next(); - os.writeShort(stringStore.addString(sc.getStyleClassName())); - } - os.writeShort(stringStore.addString(id)); - int pclassSize = pseudoClassState.size() - + (nodeOrientation == RIGHT_TO_LEFT || nodeOrientation == LEFT_TO_RIGHT ? 1 : 0); - os.writeShort(pclassSize); - Iterator iter2 = pseudoClassState.iterator(); - while(iter2.hasNext()) { - final PseudoClass pc = iter2.next(); - os.writeShort(stringStore.addString(pc.getPseudoClassName())); - } - if (nodeOrientation == RIGHT_TO_LEFT) { - os.writeShort(stringStore.addString("dir(rtl)")); - } else if (nodeOrientation == LEFT_TO_RIGHT) { - os.writeShort(stringStore.addString("dir(ltr)")); - } - } - - static SimpleSelector readBinary(int bssVersion, final DataInputStream is, final String[] strings) - throws IOException - { - final String name = strings[is.readShort()]; - final int nStyleClasses = is.readShort(); - final List styleClasses = new ArrayList(); - for (int n=0; n < nStyleClasses; n++) { - styleClasses.add(strings[is.readShort()]); - } - final String id = strings[is.readShort()]; - final int nPseudoclasses = is.readShort(); - final List pseudoclasses = new ArrayList(); - for(int n=0; n < nPseudoclasses; n++) { - pseudoclasses.add(strings[is.readShort()]); - } - return new SimpleSelector(name, styleClasses, pseudoclasses, id); - } -} --- /dev/null 2015-09-03 15:32:15.000000000 -0700 +++ new/modules/graphics/src/main/java/javafx/css/SimpleSelector.java 2015-09-03 15:32:12.880549000 -0700 @@ -0,0 +1,402 @@ +/* + * 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 javafx.css; + +import javafx.geometry.NodeOrientation; +import javafx.scene.Node; + +import java.io.DataInputStream; +import java.io.DataOutputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +import com.sun.javafx.css.PseudoClassState; +import com.sun.javafx.css.StyleClassSet; + +import static javafx.geometry.NodeOrientation.INHERIT; +import static javafx.geometry.NodeOrientation.LEFT_TO_RIGHT; +import static javafx.geometry.NodeOrientation.RIGHT_TO_LEFT; + +/** + * A simple selector which behaves according to the CSS standard. + * + * @since 9 + */ +final public class SimpleSelector extends Selector { + + /** + * If specified in the CSS file, the name of the java class to which + * this selector is applied. For example, if the CSS file had: + *
+     *   Rectangle { }
+     * 
+ * then name would be "Rectangle". + */ + final private String name; + /** + * @return The name of the java class to which this selector is applied, or *. + */ + public String getName() { + return name; + } + + /** + * @return Immutable List<String> of style-classes of the selector + */ + public List getStyleClasses() { + + final List names = new ArrayList(); + + Iterator iter = styleClassSet.iterator(); + while (iter.hasNext()) { + names.add(iter.next().getStyleClassName()); + } + + return Collections.unmodifiableList(names); + } + + public Set getStyleClassSet() { + return styleClassSet; + } + + /** styleClasses converted to a set of bit masks */ + final private StyleClassSet styleClassSet; + + final private String id; + /* + * @return The value of the selector id, which may be an empty string. + */ + public String getId() { + return id; + } + + // a mask of bits corresponding to the pseudoclasses + final private PseudoClassState pseudoClassState; + + Set getPseudoClassStates() { + return pseudoClassState; + } + + /** + * @return Immutable List<String> of pseudo-classes of the selector + */ + List getPseudoclasses() { + + final List names = new ArrayList(); + + Iterator iter = pseudoClassState.iterator(); + while (iter.hasNext()) { + names.add(iter.next().getPseudoClassName()); + } + + if (nodeOrientation == RIGHT_TO_LEFT) { + names.add("dir(rtl)"); + } else if (nodeOrientation == LEFT_TO_RIGHT) { + names.add("dir(ltr)"); + } + + return Collections.unmodifiableList(names); + } + + // true if name is not a wildcard + final private boolean matchOnName; + + // true if id given + final private boolean matchOnId; + + // true if style class given + final private boolean matchOnStyleClass; + + // dir(ltr) or dir(rtl), otherwise inherit + final private NodeOrientation nodeOrientation; + + // Used in Match. If nodeOrientation is ltr or rtl, + // then count it as a pseudoclass + public NodeOrientation getNodeOrientation() { + return nodeOrientation; + } + + // TODO: The parser passes styleClasses as a List. Should be array? + SimpleSelector(final String name, final List styleClasses, + final List pseudoClasses, final String id) + { + this.name = name == null ? "*" : name; + // if name is not null and not empty or wildcard, + // then match needs to check name + this.matchOnName = (name != null && !("".equals(name)) && !("*".equals(name))); + + this.styleClassSet = new StyleClassSet(); + + int nMax = styleClasses != null ? styleClasses.size() : 0; + for(int n=0; n 0); + + this.pseudoClassState = new PseudoClassState(); + + nMax = pseudoClasses != null ? pseudoClasses.size() : 0; + + NodeOrientation dir = NodeOrientation.INHERIT; + for(int n=0; n styleClasses = styleable.getStyleClass(); + for(int n=0, nMax = styleClasses.size(); n[] pseudoClasses, int depth) { + + + final boolean applies = applies(styleable); + + // + // We only need the pseudo-classes if the selector applies to the node. + // + if (applies && pseudoClasses != null && depth < pseudoClasses.length) { + + if (pseudoClasses[depth] == null) { + pseudoClasses[depth] = new PseudoClassState(); + } + + pseudoClasses[depth].addAll(pseudoClassState); + + } + return applies; + } + + @Override public boolean stateMatches(final Styleable styleable, Set states) { + // [foo bar] matches [foo bar bang], + // but [foo bar bang] doesn't match [foo bar] + return states != null ? states.containsAll(pseudoClassState) : false; + } + + // Are the Selector's style classes a subset of the Node's style classes? + // + // http://www.w3.org/TR/css3-selectors/#class-html + // The following selector matches any P element whose class attribute has been + // assigned a list of whitespace-separated values that includes both + // pastoral and marine: + // + // p.pastoral.marine { color: green } + // + // This selector matches when class="pastoral blue aqua marine" but does not + // match for class="pastoral blue". + private boolean matchStyleClasses(StyleClassSet otherStyleClasses) { + return otherStyleClasses.containsAll(styleClassSet); + } + + @Override public boolean equals(Object obj) { + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final SimpleSelector other = (SimpleSelector) obj; + if ((this.name == null) ? (other.name != null) : !this.name.equals(other.name)) { + return false; + } + if ((this.id == null) ? (other.id != null) : !this.id.equals(other.id)) { + return false; + } + if (this.styleClassSet.equals(other.styleClassSet) == false) { + return false; + } + if (this.pseudoClassState.equals(other.pseudoClassState) == false) { + return false; + } + + return true; + } + + /* Hash code is used in Style's hash code and Style's hash + code is used by StyleHelper */ + @Override public int hashCode() { + int hash = 7; + hash = 31 * (hash + name.hashCode()); + hash = 31 * (hash + styleClassSet.hashCode()); + hash = 31 * (hash + styleClassSet.hashCode()); + hash = (id != null) ? 31 * (hash + id.hashCode()) : 0; + hash = 31 * (hash + pseudoClassState.hashCode()); + return hash; + } + + /** Converts this object to a string. */ + @Override public String toString() { + + StringBuilder sbuf = new StringBuilder(); + if (name != null && name.isEmpty() == false) sbuf.append(name); + else sbuf.append("*"); + Iterator iter1 = styleClassSet.iterator(); + while(iter1.hasNext()) { + final StyleClass styleClass = iter1.next(); + sbuf.append('.').append(styleClass.getStyleClassName()); + } + if (id != null && id.isEmpty() == false) { + sbuf.append('#'); + sbuf.append(id); + } + Iterator iter2 = pseudoClassState.iterator(); + while(iter2.hasNext()) { + final PseudoClass pseudoClass = iter2.next(); + sbuf.append(':').append(pseudoClass.getPseudoClassName()); + } + + return sbuf.toString(); + } + + @Override protected final void writeBinary(final DataOutputStream os, final StyleConverter.StringStore stringStore) + throws IOException + { + super.writeBinary(os, stringStore); + os.writeShort(stringStore.addString(name)); + os.writeShort(styleClassSet.size()); + Iterator iter1 = styleClassSet.iterator(); + while(iter1.hasNext()) { + final StyleClass sc = iter1.next(); + os.writeShort(stringStore.addString(sc.getStyleClassName())); + } + os.writeShort(stringStore.addString(id)); + int pclassSize = pseudoClassState.size() + + (nodeOrientation == RIGHT_TO_LEFT || nodeOrientation == LEFT_TO_RIGHT ? 1 : 0); + os.writeShort(pclassSize); + Iterator iter2 = pseudoClassState.iterator(); + while(iter2.hasNext()) { + final PseudoClass pc = iter2.next(); + os.writeShort(stringStore.addString(pc.getPseudoClassName())); + } + if (nodeOrientation == RIGHT_TO_LEFT) { + os.writeShort(stringStore.addString("dir(rtl)")); + } else if (nodeOrientation == LEFT_TO_RIGHT) { + os.writeShort(stringStore.addString("dir(ltr)")); + } + } + + static SimpleSelector readBinary(int bssVersion, final DataInputStream is, final String[] strings) + throws IOException + { + final String name = strings[is.readShort()]; + final int nStyleClasses = is.readShort(); + final List styleClasses = new ArrayList(); + for (int n=0; n < nStyleClasses; n++) { + styleClasses.add(strings[is.readShort()]); + } + final String id = strings[is.readShort()]; + final int nPseudoclasses = is.readShort(); + final List pseudoclasses = new ArrayList(); + for(int n=0; n < nPseudoclasses; n++) { + pseudoclasses.add(strings[is.readShort()]); + } + return new SimpleSelector(name, styleClasses, pseudoclasses, id); + } +}