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