changeset 3826:e6ec5624c645

RT-30381: only get matches by looking at matching selectors rather than matching on rule. Matching node to rule results in looking at every selector on the rule and we already know which selectors match.
author David Grieve<david.grieve@oracle.com>
date Tue, 14 May 2013 16:38:10 -0700
parents b0690df037ca
children 3f4e67f06aad
files javafx-ui-common/src/com/sun/javafx/css/CompoundSelector.java javafx-ui-common/src/com/sun/javafx/css/Selector.java javafx-ui-common/src/com/sun/javafx/css/SimpleSelector.java javafx-ui-common/src/com/sun/javafx/css/StyleManager.java
diffstat 4 files changed, 32 insertions(+), 116 deletions(-) [+]
line wrap: on
line diff
--- a/javafx-ui-common/src/com/sun/javafx/css/CompoundSelector.java	Tue May 14 15:44:19 2013 -0700
+++ b/javafx-ui-common/src/com/sun/javafx/css/CompoundSelector.java	Tue May 14 16:38:10 2013 -0700
@@ -98,46 +98,21 @@
         this(null, null);
     }
     
-    /**
-     * Returns a {@link Match} if this selector matches the specified object, or 
-     * <code>null</code> otherwise.
-     *
-     *@param node the object to check for a match
-     *@return a {@link Match} if the selector matches, or <code>null</code> 
-     *      otherwise
-     */
-    @Override
-    Match matches(final Styleable node) {
-        return matches(node, selectors.size()-1);
-    }
+    Match createMatch() {
 
-    private Match matches(final Styleable node, final int index) {
-            
-        final Match descendantMatch = selectors.get(index).matches(node);
-        if (descendantMatch == null || index == 0) {
-            return descendantMatch;
+        final PseudoClassState allPseudoClasses = new PseudoClassState();
+        int idCount = 0;
+        int styleClassCount = 0;
+
+        for(int n=0, nMax=selectors.size(); n<nMax; n++) {
+            Selector sel = selectors.get(n);
+            Match match = sel.createMatch();
+            allPseudoClasses.addAll(match.pseudoClasses);
+            idCount += match.idCount;
+            styleClassCount += match.styleClassCount;
         }
 
-        Styleable parent = node.getStyleableParent();
-        while (parent != null) {
-            final Match ancestorMatch = matches(parent, index-1);
-            if (ancestorMatch != null) {
-
-                final PseudoClassState allPseudoClasses = new PseudoClassState();
-                allPseudoClasses.addAll(ancestorMatch.pseudoClasses);
-                allPseudoClasses.addAll(descendantMatch.pseudoClasses);
-                
-                return new Match(this, 
-                        allPseudoClasses,
-                        ancestorMatch.idCount + descendantMatch.idCount,
-                        ancestorMatch.styleClassCount + descendantMatch.styleClassCount);
-            }
-            // Combinator.CHILD will cause this loop to exit after the first iteration
-            if ( relationships.get(index-1) == Combinator.CHILD ) break;
-            parent = parent.getStyleableParent();
-        }
-        
-        return null;
+        return new Match(this, allPseudoClasses, idCount, styleClassCount);
     }
 
     @Override
--- a/javafx-ui-common/src/com/sun/javafx/css/Selector.java	Tue May 14 15:44:19 2013 -0700
+++ b/javafx-ui-common/src/com/sun/javafx/css/Selector.java	Tue May 14 16:38:10 2013 -0700
@@ -59,15 +59,8 @@
     Rule getRule() {
         return rule;
     }
-    /**
-     * Determines whether this selector applies to the specified object.  
-     * Returns a {@link Match} on success, <code>null</code> otherwise. Note
-     * that pseudoclass states are NOT included in this check.
-     *
-     *@return a <code>Match</code> describing the match, or <code>null</code> 
-     *      for no match
-     */
-    abstract Match matches(Styleable node);
+
+    abstract Match createMatch();
 
     // same as the matches method expect return true/false rather than a match
     public abstract boolean applies(Styleable styleable);
--- a/javafx-ui-common/src/com/sun/javafx/css/SimpleSelector.java	Tue May 14 15:44:19 2013 -0700
+++ b/javafx-ui-common/src/com/sun/javafx/css/SimpleSelector.java	Tue May 14 16:38:10 2013 -0700
@@ -188,46 +188,11 @@
         this.matchOnId = (id != null && !("".equals(id)));
 
     }
-    
-    /** copy constructor used by StyleManager
-    SimpleSelector(final SimpleSelector other) {
-        
-        this.name = other.name;
-        this.matchOnName = other.matchOnName;
-        this.styleClassSet = new StyleClass
-        if (other.matchOnStyleClass) {
-            final int length = other.styleClassSet.length;
-            final long[] src = other.styleClassSet;
-            final long[] dest = this.styleClassSet = new long[length];
-            System.arraycopy(src, 0, dest, 0, length);
-        } else {
-            // other is long[0]
-            this.styleClassSet = other.styleClassSet;
-        }
-        this.matchOnStyleClass = other.matchOnStyleClass;
-        
-        this.pseudoClassState = other.pseudoClassState;
-        this.nodeOrientation = other.nodeOrientation;
-        this.id = other.id;
-        this.matchOnId = other.matchOnId;
-    } */
 
-    /**
-     * Returns a {@link Match} if this selector matches the specified object, or 
-     * <code>null</code> otherwise.
-     *
-     *@param node the object to check for a match
-     *@return a {@link Match} if the selector matches, or <code>null</code> 
-     *      otherwise
-     */
-    @Override 
-    Match matches(final Styleable node) {
-        if (applies(node)) {
-            final int idCount = (matchOnId) ? 1 : 0;
-            int styleClassCount = styleClassSet.size();
-            return new Match(this, pseudoClassState, idCount, styleClassCount);
-        }
-        return null;
+    Match createMatch() {
+        final int idCount = (matchOnId) ? 1 : 0;
+        int styleClassCount = styleClassSet.size();
+        return new Match(this, pseudoClassState, idCount, styleClassCount);
     }
 
     @Override 
--- a/javafx-ui-common/src/com/sun/javafx/css/StyleManager.java	Tue May 14 15:44:19 2013 -0700
+++ b/javafx-ui-common/src/com/sun/javafx/css/StyleManager.java	Tue May 14 16:38:10 2013 -0700
@@ -1705,41 +1705,24 @@
                     int ordinal = selectorDatum.ordinal;
                     final Selector selector = selectorDatum.selector;
 
-                    final Rule rule = selector.getRule();
+                    Match match = selector.createMatch();
 
-                    // if the selector didn't apply, then applicableRules[r] will be null
-                    if (rule == null) {
-                        continue;
-                    }
+                    Rule rule = selector.getRule();
 
-                    final List<Match> matches = rule.matches(node);
-                    if (matches == null || matches.isEmpty()) {
-                        continue;
-                    }
+                    for (int d = 0, dmax = rule.getDeclarations().size(); d < dmax; d++) {
+                        final Declaration decl = rule.getDeclarations().get(d);
 
-                    for (int m=0, mMax=matches.size(); m<mMax; m++) {
+                        final CascadingStyle s = new CascadingStyle(
+                                new Style(match.selector, decl),
+                                match.pseudoClasses,
+                                match.specificity,
+                                // ordinal increments at declaration level since
+                                // there may be more than one declaration for the
+                                // same attribute within a selector or within a stylesheet
+                                ordinal++
+                        );
 
-                        final Match match = matches.get(m);
-                        // TODO: should never get nulls in this list. Fix Rule#matches
-                        if (match == null) {
-                            continue;
-                        }
-
-                        for (int d = 0, dmax = rule.getDeclarations().size(); d < dmax; d++) {
-                            final Declaration decl = rule.getDeclarations().get(d);
-
-                            final CascadingStyle s = new CascadingStyle(
-                                    new Style(match.selector, decl),
-                                    match.pseudoClasses,
-                                    match.specificity,
-                                    // ordinal increments at declaration level since
-                                    // there may be more than one declaration for the
-                                    // same attribute within a selector or within a stylesheet
-                                    ordinal++
-                            );
-
-                            styles.add(s);
-                        }
+                        styles.add(s);
                     }
                 }
             }