1 /*
   2  * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package javafx.css;
  27 
  28 import com.sun.javafx.css.ParsedValueImpl;
  29 import com.sun.javafx.css.StyleManager;
  30 import javafx.css.converter.FontConverter;
  31 import javafx.css.converter.SizeConverter;
  32 
  33 import java.util.ArrayList;
  34 import java.util.Collections;
  35 import java.util.List;
  36 import java.util.Map;
  37 
  38 import javafx.beans.property.Property;
  39 import javafx.scene.Group;
  40 import javafx.scene.Node;
  41 import javafx.scene.Scene;
  42 import javafx.scene.paint.Color;
  43 import javafx.scene.shape.Rectangle;
  44 import javafx.scene.text.Font;
  45 import javafx.scene.text.Text;
  46 
  47 import static org.junit.Assert.*;
  48 
  49 import org.junit.Ignore;
  50 import org.junit.Test;
  51 
  52 @Ignore
  53 public class Node_cssStyleMap_Test {
  54     
  55     public Node_cssStyleMap_Test() {
  56     }
  57 
  58     boolean disabled = false;
  59 
  60     private void checkFoundStyle(Property<?> property, Map<StyleableProperty<?>, List<Style>> map, List<Declaration> decls) {
  61 
  62         List<Style> styles = map.get(property);
  63         assert (styles != null && !styles.isEmpty());
  64 
  65         String pname = ((StyleableProperty<?>)property).getCssMetaData().getProperty();
  66         Declaration declaration = null;
  67         for(Declaration decl : decls) {
  68             if (pname.equals(decl.getProperty())) {
  69                 declaration = decl;
  70                 break;
  71             }
  72         }
  73         assertNotNull(pname, declaration);
  74 
  75         Style style = null;
  76         for(Style s : styles) {
  77             if (pname.equals(s.getDeclaration().getProperty())) {
  78                 style = s;
  79                 break;
  80             }
  81         }
  82         assertNotNull(pname, style);
  83 
  84         assert(style.getDeclaration() == declaration);
  85 
  86     }
  87     
  88     @Test
  89     public void testStyleMap() {
  90 
  91         final List<Declaration> declsNoState = new ArrayList<Declaration>();
  92         Collections.addAll(declsNoState,
  93             new Declaration("-fx-fill", new ParsedValueImpl<Color,Color>(Color.RED, null), false),
  94             new Declaration("-fx-stroke", new ParsedValueImpl<Color,Color>(Color.YELLOW, null), false),
  95             new Declaration("-fx-stroke-width", new ParsedValueImpl<ParsedValue<?,Size>,Number>(
  96                 new ParsedValueImpl<Size,Size>(new Size(3d, SizeUnits.PX), null),
  97                 SizeConverter.getInstance()), false)
  98         );
  99 
 100 
 101         final List<Selector> selsNoState = new ArrayList<Selector>();
 102         Collections.addAll(selsNoState,
 103             Selector.createSelector(".rect")
 104         );
 105 
 106         Rule rule = new Rule(selsNoState, declsNoState);
 107 
 108         Stylesheet stylesheet = new Stylesheet("testStyleMap");
 109         stylesheet.setOrigin(StyleOrigin.USER_AGENT);
 110         stylesheet.getRules().add(rule);
 111 
 112         final List<Declaration> declsDisabledState = new ArrayList<Declaration>();
 113         Collections.addAll(declsDisabledState,
 114             new Declaration("-fx-fill", new ParsedValueImpl<Color,Color>(Color.GRAY, null), false),
 115             new Declaration("-fx-stroke", new ParsedValueImpl<Color,Color>(Color.DARKGRAY, null), false)
 116         );
 117 
 118         final List<Selector> selsDisabledState = new ArrayList<Selector>();
 119         Collections.addAll(selsDisabledState,
 120             Selector.createSelector(".rect:disabled")
 121         );
 122 
 123         rule = new Rule(selsDisabledState, declsDisabledState);
 124         stylesheet.getRules().add(rule);
 125 
 126         Rectangle rect = new Rectangle(50,50);
 127         rect.getStyleClass().add("rect");
 128 
 129         Group root = new Group();
 130         root.getChildren().add(rect);
 131         StyleManager.getInstance().setDefaultUserAgentStylesheet(stylesheet);
 132         Scene scene = new Scene(root);
 133 
 134         rect.applyCss();
 135 
 136         Map<StyleableProperty<?>, List<Style>> map = rect.impl_findStyles(null);
 137         assert (map != null && !map.isEmpty());
 138 
 139         checkFoundStyle(rect.fillProperty(), map, declsNoState);
 140         checkFoundStyle(rect.strokeProperty(), map, declsNoState);
 141         checkFoundStyle(rect.strokeWidthProperty(), map, declsNoState);
 142 
 143         rect.setDisable(true);
 144         rect.applyCss();
 145 
 146         map = rect.impl_findStyles(null);
 147         assert (map != null && !map.isEmpty());
 148 
 149         checkFoundStyle(rect.fillProperty(), map, declsDisabledState);
 150         checkFoundStyle(rect.strokeProperty(), map, declsDisabledState);
 151         checkFoundStyle(rect.strokeWidthProperty(), map, declsNoState);
 152 
 153     }
 154 
 155     @Test
 156     public void testStyleMapChildren() {
 157 
 158         final List<Declaration> declsNoState = new ArrayList<Declaration>();
 159         Collections.addAll(declsNoState,
 160                 new Declaration("-fx-fill", new ParsedValueImpl<Color,Color>(Color.RED, null), false)
 161         );
 162 
 163         final List<Selector> selsNoState = new ArrayList<Selector>();
 164         Collections.addAll(selsNoState,
 165                 Selector.createSelector(".rect")
 166         );
 167 
 168         Rule rule = new Rule(selsNoState, declsNoState);
 169 
 170         Stylesheet stylesheet = new Stylesheet("testStyleMapChildren");
 171         stylesheet.setOrigin(StyleOrigin.USER_AGENT);
 172         stylesheet.getRules().add(rule);
 173 
 174         Rectangle rect = new Rectangle(50,50);
 175         rect.getStyleClass().add("rect");
 176 
 177         Group root = new Group();
 178         Group group = new Group();
 179         root.getChildren().add(group);
 180         group.getChildren().add(rect);
 181         StyleManager.getInstance().setDefaultUserAgentStylesheet(stylesheet);
 182         Scene scene = new Scene(root);
 183 
 184         root.applyCss();
 185 
 186         // Even though root and group have no styles, the styles for rect should still be found
 187         Map<StyleableProperty<?>, List<Style>> map = root.impl_findStyles(null);
 188         assert (map != null && !map.isEmpty());
 189 
 190         checkFoundStyle(rect.fillProperty(), map, declsNoState);
 191 
 192     }
 193 
 194     @Test
 195     public void testRT_21212() {
 196 
 197         final List<Declaration> rootDecls = new ArrayList<Declaration>();
 198         Collections.addAll(rootDecls, 
 199             new Declaration("-fx-font-size", new ParsedValueImpl<ParsedValue<?,Size>,Number>(
 200                 new ParsedValueImpl<Size,Size>(new Size(12, SizeUnits.PX), null), 
 201                 SizeConverter.getInstance()), false)
 202         );
 203         
 204         final List<Selector> rootSels = new ArrayList<Selector>();
 205         Collections.addAll(rootSels, 
 206             Selector.createSelector(".root")
 207         );
 208         
 209         Rule rootRule = new Rule(rootSels, rootDecls);        
 210         
 211         Stylesheet stylesheet = new Stylesheet("testRT_21212");
 212         stylesheet.setOrigin(StyleOrigin.USER_AGENT);
 213         stylesheet.getRules().add(rootRule);
 214 
 215         Group group = new Group();
 216         group.getStyleClass().add("root");
 217         
 218         
 219         final ParsedValue[] fontValues = new ParsedValue[] {
 220             new ParsedValueImpl<String,String>("system", null),
 221             new ParsedValueImpl<ParsedValue<?,Size>,Number>(
 222                 new ParsedValueImpl<Size,Size>(new Size(1.5, SizeUnits.EM), null),
 223                 SizeConverter.getInstance()
 224             ), 
 225             null,
 226             null
 227         };
 228         final List<Declaration> textDecls = new ArrayList<Declaration>();
 229         Collections.addAll(textDecls, 
 230             new Declaration("-fx-font", new ParsedValueImpl<ParsedValue[], Font>(
 231                 fontValues, FontConverter.getInstance()), false)
 232         );
 233         
 234         final List<Selector> textSels = new ArrayList<Selector>();
 235         Collections.addAll(textSels, 
 236             Selector.createSelector(".text")
 237         );
 238         
 239         Rule textRule = new Rule(textSels, textDecls);        
 240         stylesheet.getRules().add(textRule);
 241                 
 242         Text text = new Text("HelloWorld");
 243         text.getStyleClass().add("text");
 244         group.getChildren().add(text);
 245 
 246         StyleManager.getInstance().setDefaultUserAgentStylesheet(stylesheet);
 247         Scene scene = new Scene(group);
 248 
 249         text.applyCss();
 250 
 251         Map<StyleableProperty<?>, List<Style>> map = text.impl_findStyles(null);
 252         assert (map != null && !map.isEmpty());
 253 
 254         checkFoundStyle(text.fontProperty(), map, textDecls);
 255 
 256     }
 257 
 258     boolean containsProperty(CssMetaData key, Map<String,List<CascadingStyle>> map) {
 259 
 260         if (map.containsKey(key)) return true;
 261         List<CssMetaData> subProperties = key.getSubProperties();
 262         if (subProperties != null && !subProperties.isEmpty()) {
 263             for (CssMetaData subKey: subProperties) {
 264                 if (map.containsKey(subKey)) return true;
 265             }
 266         }
 267         return false;
 268     }
 269 
 270     @Test
 271     public void testRT_34799() {
 272 
 273         Stylesheet stylesheet = new Stylesheet("testRT_34799");
 274         stylesheet.setOrigin(StyleOrigin.USER_AGENT);
 275 
 276         final List<Declaration> txtDecls = new ArrayList<Declaration>();
 277         Collections.addAll(txtDecls,
 278                 new Declaration("-fx-fill", new ParsedValueImpl<Color,Color>(Color.RED, null), false)
 279         );
 280 
 281         final List<Selector> textSels = new ArrayList<Selector>();
 282         Collections.addAll(textSels,
 283                 Selector.createSelector(".rt-34799")
 284         );
 285 
 286         Rule txtRules = new Rule(textSels, txtDecls);
 287         stylesheet.getRules().add(txtRules);
 288 
 289         final List<Style> expectedStyles = new ArrayList<>();
 290         for (Rule rule : stylesheet.getRules()) {
 291             for (Selector selector : rule.getSelectors()) {
 292                 for (Declaration declaration : rule.getUnobservedDeclarationList()) {
 293                     expectedStyles.add(
 294                             new Style(selector, declaration)
 295                     );
 296                 }
 297             }
 298         }
 299 
 300         Text text = new Text("HelloWorld");
 301         text.getStyleClass().add("rt-34799");
 302 
 303         Group group = new Group();
 304         group.getStyleClass().add("root");
 305 
 306         group.getChildren().add(text);
 307 
 308         StyleManager.getInstance().setDefaultUserAgentStylesheet(stylesheet);
 309         Scene scene = new Scene(group);
 310 
 311         group.applyCss(); // TODO: force StyleHelper to be created, remove pending RT-34812
 312 
 313         int nExpected = expectedStyles.size();
 314         assert(nExpected > 0);
 315 
 316         for(CssMetaData cssMetaData : text.getCssMetaData()) {
 317             List<Style> styles = Node.impl_getMatchingStyles(cssMetaData, text);
 318             if (styles != null && !styles.isEmpty()) {
 319                 assertTrue(expectedStyles.containsAll(styles));
 320                 assertTrue(styles.containsAll(expectedStyles));
 321                 nExpected -= 1;
 322             }
 323         }
 324 
 325         assertEquals(nExpected, 0);
 326 
 327     }
 328 
 329 }