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