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 com.sun.javafx.css; 27 28 import com.sun.javafx.css.converters.FontConverter; 29 import com.sun.javafx.css.converters.SizeConverter; 30 import com.sun.javafx.tk.Toolkit; 31 import java.util.ArrayList; 32 import java.util.Collections; 33 import java.util.HashMap; 34 import java.util.List; 35 import java.util.Map; 36 37 import javafx.beans.property.Property; 38 import javafx.collections.FXCollections; 39 import javafx.collections.MapChangeListener; 40 import javafx.css.CssMetaData; 41 import javafx.css.ParsedValue; 42 import javafx.css.StyleOrigin; 43 import javafx.css.Styleable; 44 import javafx.css.StyleableProperty; 45 import javafx.scene.Group; 46 import javafx.scene.Node; 47 import javafx.scene.Scene; 48 import javafx.scene.paint.Color; 49 import javafx.scene.shape.Rectangle; 50 import javafx.scene.text.Font; 51 import javafx.scene.text.Text; 52 import javafx.stage.Stage; 53 import static org.junit.Assert.*; 54 55 import javafx.util.Pair; 56 import org.junit.Ignore; 57 import org.junit.Test; 58 59 @Ignore 60 public class Node_cssStyleMap_Test { 61 62 public Node_cssStyleMap_Test() { 63 } 64 65 boolean disabled = false; 66 67 private void checkFoundStyle(Property<?> property, Map<StyleableProperty<?>, List<Style>> map, List<Declaration> decls) { 68 69 List<Style> styles = map.get(property); 70 assert (styles != null && !styles.isEmpty()); 71 72 String pname = ((StyleableProperty<?>)property).getCssMetaData().getProperty(); 73 Declaration declaration = null; 74 for(Declaration decl : decls) { 75 if (pname.equals(decl.getProperty())) { 76 declaration = decl; 77 break; 78 } 79 } 80 assertNotNull(pname, declaration); 81 82 Style style = null; 83 for(Style s : styles) { 84 if (pname.equals(s.getDeclaration().getProperty())) { 85 style = s; 86 break; 87 } 88 } 89 assertNotNull(pname, style); 90 91 assert(style.getDeclaration() == declaration); 92 93 } 94 95 @Test 96 public void testStyleMap() { 97 98 final List<Declaration> declsNoState = new ArrayList<Declaration>(); 99 Collections.addAll(declsNoState, 100 new Declaration("-fx-fill", new ParsedValueImpl<Color,Color>(Color.RED, null), false), 101 new Declaration("-fx-stroke", new ParsedValueImpl<Color,Color>(Color.YELLOW, null), false), 102 new Declaration("-fx-stroke-width", new ParsedValueImpl<ParsedValue<?,Size>,Number>( 103 new ParsedValueImpl<Size,Size>(new Size(3d, SizeUnits.PX), null), 104 SizeConverter.getInstance()), false) 105 ); 106 107 108 final List<Selector> selsNoState = new ArrayList<Selector>(); 109 Collections.addAll(selsNoState, 110 Selector.createSelector(".rect") 111 ); 112 113 Rule rule = new Rule(selsNoState, declsNoState); 114 115 Stylesheet stylesheet = new Stylesheet("testStyleMap"); 116 stylesheet.setOrigin(StyleOrigin.USER_AGENT); 117 stylesheet.getRules().add(rule); 118 119 final List<Declaration> declsDisabledState = new ArrayList<Declaration>(); 120 Collections.addAll(declsDisabledState, 121 new Declaration("-fx-fill", new ParsedValueImpl<Color,Color>(Color.GRAY, null), false), 122 new Declaration("-fx-stroke", new ParsedValueImpl<Color,Color>(Color.DARKGRAY, null), false) 123 ); 124 125 final List<Selector> selsDisabledState = new ArrayList<Selector>(); 126 Collections.addAll(selsDisabledState, 127 Selector.createSelector(".rect:disabled") 128 ); 129 130 rule = new Rule(selsDisabledState, declsDisabledState); 131 stylesheet.getRules().add(rule); 132 133 Rectangle rect = new Rectangle(50,50); 134 rect.getStyleClass().add("rect"); 135 136 Group root = new Group(); 137 root.getChildren().add(rect); 138 StyleManager.getInstance().setDefaultUserAgentStylesheet(stylesheet); 139 Scene scene = new Scene(root); 140 141 rect.applyCss(); 142 143 Map<StyleableProperty<?>, List<Style>> map = rect.impl_findStyles(null); 144 assert (map != null && !map.isEmpty()); 145 146 checkFoundStyle(rect.fillProperty(), map, declsNoState); 147 checkFoundStyle(rect.strokeProperty(), map, declsNoState); 148 checkFoundStyle(rect.strokeWidthProperty(), map, declsNoState); 149 150 rect.setDisable(true); 151 rect.applyCss(); 152 153 map = rect.impl_findStyles(null); 154 assert (map != null && !map.isEmpty()); 155 156 checkFoundStyle(rect.fillProperty(), map, declsDisabledState); 157 checkFoundStyle(rect.strokeProperty(), map, declsDisabledState); 158 checkFoundStyle(rect.strokeWidthProperty(), map, declsNoState); 159 160 } 161 162 @Test 163 public void testStyleMapChildren() { 164 165 final List<Declaration> declsNoState = new ArrayList<Declaration>(); 166 Collections.addAll(declsNoState, 167 new Declaration("-fx-fill", new ParsedValueImpl<Color,Color>(Color.RED, null), false) 168 ); 169 170 final List<Selector> selsNoState = new ArrayList<Selector>(); 171 Collections.addAll(selsNoState, 172 Selector.createSelector(".rect") 173 ); 174 175 Rule rule = new Rule(selsNoState, declsNoState); 176 177 Stylesheet stylesheet = new Stylesheet("testStyleMapChildren"); 178 stylesheet.setOrigin(StyleOrigin.USER_AGENT); 179 stylesheet.getRules().add(rule); 180 181 Rectangle rect = new Rectangle(50,50); 182 rect.getStyleClass().add("rect"); 183 184 Group root = new Group(); 185 Group group = new Group(); 186 root.getChildren().add(group); 187 group.getChildren().add(rect); 188 StyleManager.getInstance().setDefaultUserAgentStylesheet(stylesheet); 189 Scene scene = new Scene(root); 190 191 root.applyCss(); 192 193 // Even though root and group have no styles, the styles for rect should still be found 194 Map<StyleableProperty<?>, List<Style>> map = root.impl_findStyles(null); 195 assert (map != null && !map.isEmpty()); 196 197 checkFoundStyle(rect.fillProperty(), map, declsNoState); 198 199 } 200 201 @Test 202 public void testRT_21212() { 203 204 final List<Declaration> rootDecls = new ArrayList<Declaration>(); 205 Collections.addAll(rootDecls, 206 new Declaration("-fx-font-size", new ParsedValueImpl<ParsedValue<?,Size>,Number>( 207 new ParsedValueImpl<Size,Size>(new Size(12, SizeUnits.PX), null), 208 SizeConverter.getInstance()), false) 209 ); 210 211 final List<Selector> rootSels = new ArrayList<Selector>(); 212 Collections.addAll(rootSels, 213 Selector.createSelector(".root") 214 ); 215 216 Rule rootRule = new Rule(rootSels, rootDecls); 217 218 Stylesheet stylesheet = new Stylesheet("testRT_21212"); 219 stylesheet.setOrigin(StyleOrigin.USER_AGENT); 220 stylesheet.getRules().add(rootRule); 221 222 Group group = new Group(); 223 group.getStyleClass().add("root"); 224 225 226 final ParsedValue[] fontValues = new ParsedValue[] { 227 new ParsedValueImpl<String,String>("system", null), 228 new ParsedValueImpl<ParsedValue<?,Size>,Number>( 229 new ParsedValueImpl<Size,Size>(new Size(1.5, SizeUnits.EM), null), 230 SizeConverter.getInstance() 231 ), 232 null, 233 null 234 }; 235 final List<Declaration> textDecls = new ArrayList<Declaration>(); 236 Collections.addAll(textDecls, 237 new Declaration("-fx-font", new ParsedValueImpl<ParsedValue[], Font>( 238 fontValues, FontConverter.getInstance()), false) 239 ); 240 241 final List<Selector> textSels = new ArrayList<Selector>(); 242 Collections.addAll(textSels, 243 Selector.createSelector(".text") 244 ); 245 246 Rule textRule = new Rule(textSels, textDecls); 247 stylesheet.getRules().add(textRule); 248 249 Text text = new Text("HelloWorld"); 250 text.getStyleClass().add("text"); 251 group.getChildren().add(text); 252 253 StyleManager.getInstance().setDefaultUserAgentStylesheet(stylesheet); 254 Scene scene = new Scene(group); 255 256 text.applyCss(); 257 258 Map<StyleableProperty<?>, List<Style>> map = text.impl_findStyles(null); 259 assert (map != null && !map.isEmpty()); 260 261 checkFoundStyle(text.fontProperty(), map, textDecls); 262 263 } 264 265 boolean containsProperty(CssMetaData key, Map<String,List<CascadingStyle>> map) { 266 267 if (map.containsKey(key)) return true; 268 List<CssMetaData> subProperties = key.getSubProperties(); 269 if (subProperties != null && !subProperties.isEmpty()) { 270 for (CssMetaData subKey: subProperties) { 271 if (map.containsKey(subKey)) return true; 272 } 273 } 274 return false; 275 } 276 277 @Test 278 public void testRT_34799() { 279 280 Stylesheet stylesheet = new Stylesheet("testRT_34799"); 281 stylesheet.setOrigin(StyleOrigin.USER_AGENT); 282 283 final List<Declaration> txtDecls = new ArrayList<Declaration>(); 284 Collections.addAll(txtDecls, 285 new Declaration("-fx-fill", new ParsedValueImpl<Color,Color>(Color.RED, null), false) 286 ); 287 288 final List<Selector> textSels = new ArrayList<Selector>(); 289 Collections.addAll(textSels, 290 Selector.createSelector(".rt-34799") 291 ); 292 293 Rule txtRules = new Rule(textSels, txtDecls); 294 stylesheet.getRules().add(txtRules); 295 296 final List<Style> expectedStyles = new ArrayList<>(); 297 for (Rule rule : stylesheet.getRules()) { 298 for (Selector selector : rule.getSelectors()) { 299 for (Declaration declaration : rule.getUnobservedDeclarationList()) { 300 expectedStyles.add( 301 new Style(selector, declaration) 302 ); 303 } 304 } 305 } 306 307 Text text = new Text("HelloWorld"); 308 text.getStyleClass().add("rt-34799"); 309 310 Group group = new Group(); 311 group.getStyleClass().add("root"); 312 313 group.getChildren().add(text); 314 315 StyleManager.getInstance().setDefaultUserAgentStylesheet(stylesheet); 316 Scene scene = new Scene(group); 317 318 group.applyCss(); // TODO: force StyleHelper to be created, remove pending RT-34812 319 320 int nExpected = expectedStyles.size(); 321 assert(nExpected > 0); 322 323 for(CssMetaData cssMetaData : text.getCssMetaData()) { 324 List<Style> styles = Node.impl_getMatchingStyles(cssMetaData, text); 325 if (styles != null && !styles.isEmpty()) { 326 assertTrue(expectedStyles.containsAll(styles)); 327 assertTrue(styles.containsAll(expectedStyles)); 328 nExpected -= 1; 329 } 330 } 331 332 assertEquals(nExpected, 0); 333 334 } 335 336 }