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 com.sun.javafx.css; 27 28 import com.sun.javafx.css.parser.CSSParser; 29 import javafx.css.StyleOrigin; 30 import javafx.css.StyleableProperty; 31 import javafx.scene.Group; 32 import javafx.scene.Parent; 33 import javafx.scene.Scene; 34 import javafx.scene.SubScene; 35 import javafx.scene.layout.Pane; 36 import javafx.scene.paint.Color; 37 import javafx.scene.paint.Paint; 38 import javafx.scene.shape.Rectangle; 39 import org.junit.Before; 40 import org.junit.Test; 41 42 import java.net.URL; 43 import java.util.ArrayList; 44 import java.util.Collections; 45 import java.util.List; 46 import java.util.Map; 47 import java.util.concurrent.atomic.AtomicBoolean; 48 49 import static org.junit.Assert.*; 50 51 /** 52 * 53 * @author dgrieve 54 */ 55 public class StyleManagerTest { 56 57 public StyleManagerTest() { 58 } 59 60 @Before 61 public void setUp() { 62 StyleManager sm = StyleManager.getInstance(); 63 sm.userAgentStylesheetContainers.clear(); 64 sm.platformUserAgentStylesheetContainers.clear(); 65 sm.stylesheetContainerMap.clear(); 66 sm.cacheContainerMap.clear(); 67 sm.hasDefaultUserAgentStylesheet = false; 68 } 69 70 @Test 71 public void testMethod_getInstance() { 72 Scene scene = new Scene(new Group()); 73 StyleManager sm = StyleManager.getInstance(); 74 assertNotNull(sm); 75 } 76 77 private static int indexOf(final List<StyleManager.StylesheetContainer> list, final String fname) { 78 79 for (int n=0, nMax=list.size(); n<nMax; n++) { 80 StyleManager.StylesheetContainer container = list.get(n); 81 if (fname.equals(container.fname)) { 82 return n; 83 } 84 } 85 86 return -1; 87 } 88 89 @Test 90 public void testAddUserAgentStyleshseet_String() { 91 StyleManager sm = StyleManager.getInstance(); 92 sm.addUserAgentStylesheet("/com/sun/javafx/css/ua0.css"); 93 int index = indexOf(sm.platformUserAgentStylesheetContainers, "/com/sun/javafx/css/ua0.css"); 94 assertEquals(0,index); 95 96 } 97 98 @Test 99 public void testAddUserAgentStyleshseet_String_Multiple() { 100 StyleManager sm = StyleManager.getInstance(); 101 sm.addUserAgentStylesheet("/com/sun/javafx/css/ua0.css"); 102 sm.addUserAgentStylesheet("/com/sun/javafx/css/ua1.css"); 103 104 int index = indexOf(sm.platformUserAgentStylesheetContainers, "/com/sun/javafx/css/ua0.css"); 105 assertEquals(0,index); 106 107 index = indexOf(sm.platformUserAgentStylesheetContainers, "/com/sun/javafx/css/ua1.css"); 108 assertEquals(1, index); 109 } 110 111 @Test 112 public void testAddUserAgentStyleshseet_String_Duplicate() { 113 StyleManager sm = StyleManager.getInstance(); 114 sm.addUserAgentStylesheet("/com/sun/javafx/css/ua0.css"); 115 sm.addUserAgentStylesheet("/com/sun/javafx/css/ua1.css"); 116 sm.addUserAgentStylesheet("/com/sun/javafx/css/ua0.css"); 117 118 assertTrue(sm.platformUserAgentStylesheetContainers.size() == 2); 119 120 int index = indexOf(sm.platformUserAgentStylesheetContainers,"/com/sun/javafx/css/ua0.css"); 121 assertEquals(0,index); 122 123 index = indexOf(sm.platformUserAgentStylesheetContainers,"/com/sun/javafx/css/ua1.css"); 124 assertEquals(1, index); 125 126 } 127 128 @Test 129 public void testSetDefaultUserAgentStyleshseet_String() { 130 StyleManager sm = StyleManager.getInstance(); 131 sm.setDefaultUserAgentStylesheet("/com/sun/javafx/css/ua0.css"); 132 133 int index = indexOf(sm.platformUserAgentStylesheetContainers, "/com/sun/javafx/css/ua0.css"); 134 assertEquals(0, index); 135 } 136 137 @Test 138 public void testSetUserAgentStyleshseet_String_Multiple() { 139 StyleManager sm = StyleManager.getInstance(); 140 sm.setDefaultUserAgentStylesheet("/com/sun/javafx/css/ua0.css"); 141 sm.addUserAgentStylesheet("/com/sun/javafx/css/ua1.css"); 142 143 assertTrue(sm.platformUserAgentStylesheetContainers.size() == 2); 144 145 int index = indexOf(sm.platformUserAgentStylesheetContainers, "/com/sun/javafx/css/ua0.css"); 146 assertEquals(0,index); 147 148 index = indexOf(sm.platformUserAgentStylesheetContainers, "/com/sun/javafx/css/ua1.css"); 149 assertEquals(1, index); 150 } 151 152 @Test 153 public void testSetUserAgentStyleshseet_String_Multiple2() { 154 StyleManager sm = StyleManager.getInstance(); 155 // same as before but set default after adding another. 156 sm.addUserAgentStylesheet("/com/sun/javafx/css/ua1.css"); 157 sm.setDefaultUserAgentStylesheet("/com/sun/javafx/css/ua0.css"); 158 159 assertEquals(2, sm.platformUserAgentStylesheetContainers.size()); 160 161 int index = indexOf(sm.platformUserAgentStylesheetContainers,"/com/sun/javafx/css/ua0.css"); 162 assertEquals(0,index); 163 164 index = indexOf(sm.platformUserAgentStylesheetContainers,"/com/sun/javafx/css/ua1.css"); 165 assertEquals(1, index); 166 } 167 168 @Test 169 public void testSetUserAgentStyleshseet_String_Duplicate() { 170 StyleManager sm = StyleManager.getInstance(); 171 sm.setDefaultUserAgentStylesheet("/com/sun/javafx/css/ua0.css"); 172 sm.addUserAgentStylesheet("/com/sun/javafx/css/ua1.css"); 173 sm.setDefaultUserAgentStylesheet("/com/sun/javafx/css/ua0.css"); 174 175 assertEquals(2, sm.platformUserAgentStylesheetContainers.size()); 176 177 int index = indexOf(sm.platformUserAgentStylesheetContainers, "/com/sun/javafx/css/ua0.css"); 178 assertEquals(0,index); 179 180 index = indexOf(sm.platformUserAgentStylesheetContainers, "/com/sun/javafx/css/ua1.css"); 181 assertEquals(1, index); 182 } 183 184 @Test 185 public void testAddUserAgentStyleshseet_Stylesheet() { 186 187 try { 188 StyleManager sm = StyleManager.getInstance(); 189 URL ua0_url = StyleManagerTest.class.getResource("ua0.css"); 190 Stylesheet stylesheet = CSSParser.getInstance().parse(ua0_url); 191 sm.addUserAgentStylesheet(null,stylesheet); 192 193 assertEquals(1, sm.platformUserAgentStylesheetContainers.size()); 194 195 int index = indexOf(sm.platformUserAgentStylesheetContainers,ua0_url.toExternalForm()); 196 assertEquals(0, index); 197 198 } catch (Exception ioe) { 199 fail(ioe.getMessage()); 200 } 201 202 } 203 204 @Test 205 public void testSetDefaultUserAgentStyleshseet_Stylesheet() { 206 207 try { 208 StyleManager sm = StyleManager.getInstance(); 209 210 URL ua1_url = StyleManagerTest.class.getResource("ua1.css"); 211 Stylesheet stylesheet = CSSParser.getInstance().parse(ua1_url); 212 sm.addUserAgentStylesheet(null,stylesheet); 213 214 URL ua0_url = StyleManagerTest.class.getResource("ua0.css"); 215 stylesheet = CSSParser.getInstance().parse(ua0_url); 216 sm.setDefaultUserAgentStylesheet(stylesheet); 217 218 assertEquals(2, sm.platformUserAgentStylesheetContainers.size()); 219 220 int index = indexOf(sm.platformUserAgentStylesheetContainers,ua0_url.toExternalForm()); 221 assertEquals(0, index); 222 223 index = indexOf(sm.platformUserAgentStylesheetContainers,ua1_url.toExternalForm()); 224 assertEquals(1, index); 225 226 } catch (Exception ioe) { 227 fail(ioe.getMessage()); 228 } 229 230 } 231 232 @Test 233 public void testSceneUAStylesheetAdded() { 234 Scene scene = new Scene(new Group(new Rectangle(){{ getStyleClass().add("rect"); }})); 235 scene.setUserAgentStylesheet("/com/sun/javafx/css/ua1.css"); 236 237 StyleManager sm = StyleManager.getInstance(); 238 sm.setDefaultUserAgentStylesheet("/com/sun/javafx/css/ua0.css"); 239 240 scene.getRoot().applyCss(); 241 242 int index = indexOf(sm.platformUserAgentStylesheetContainers,"/com/sun/javafx/css/ua0.css"); 243 assertEquals(0,index); 244 245 index = indexOf(sm.userAgentStylesheetContainers,"/com/sun/javafx/css/ua0.css"); 246 assertEquals(-1, index); 247 248 index = indexOf(sm.userAgentStylesheetContainers,"/com/sun/javafx/css/ua1.css"); 249 assertEquals(0,index); 250 251 // the Scene user-agent stylesheet is not a platform user-agent stylesheet 252 index = indexOf(sm.platformUserAgentStylesheetContainers, "/com/sun/javafx/css/ua1.css"); 253 assertEquals(-1, index); 254 255 } 256 257 @Test 258 public void testSubSceneUAStylesheetAdded() { 259 Scene scene = new Scene(new Group(new Rectangle(){{ getStyleClass().add("rect"); }})); 260 scene.setUserAgentStylesheet("/com/sun/javafx/css/ua1.css"); 261 262 StyleManager sm = StyleManager.getInstance(); 263 sm.setDefaultUserAgentStylesheet("/com/sun/javafx/css/ua0.css"); 264 265 scene.getRoot().applyCss(); 266 267 int index = indexOf(sm.platformUserAgentStylesheetContainers,"/com/sun/javafx/css/ua0.css"); 268 assertEquals(0,index); 269 270 index = indexOf(sm.userAgentStylesheetContainers,"/com/sun/javafx/css/ua0.css"); 271 assertEquals(-1, index); 272 273 index = indexOf(sm.userAgentStylesheetContainers,"/com/sun/javafx/css/ua1.css"); 274 assertEquals(0,index); 275 276 // the Scene user-agent stylesheet is not a platform user-agent stylesheet 277 index = indexOf(sm.platformUserAgentStylesheetContainers, "/com/sun/javafx/css/ua1.css"); 278 assertEquals(-1, index); 279 280 } 281 282 @Test 283 public void testForgetParent() { 284 285 Scene scene = new Scene(new Group(new Rectangle(){{ getStyleClass().add("rect"); }})); 286 287 StyleManager sm = StyleManager.getInstance(); 288 sm.setDefaultUserAgentStylesheet("/com/sun/javafx/css/ua0.css"); 289 290 scene.getRoot().applyCss(); 291 292 int index = indexOf(sm.platformUserAgentStylesheetContainers,"/com/sun/javafx/css/ua0.css"); 293 assertEquals(0,index); 294 295 sm.forget(scene.getRoot()); 296 297 // forgetting the scene should not affect the platform user-agent stylesheets 298 index = indexOf(sm.platformUserAgentStylesheetContainers,"/com/sun/javafx/css/ua0.css"); 299 assertEquals(0,index); 300 301 } 302 303 @Test 304 public void testForgetParent_withSceneUAStylesheet() { 305 306 Scene scene = new Scene(new Group(new Rectangle(){{ getStyleClass().add("rect"); }})); 307 scene.setUserAgentStylesheet("/com/sun/javafx/css/ua1.css"); 308 309 StyleManager sm = StyleManager.getInstance(); 310 sm.setDefaultUserAgentStylesheet("/com/sun/javafx/css/ua0.css"); 311 312 scene.getRoot().applyCss(); 313 314 int index = indexOf(sm.platformUserAgentStylesheetContainers,"/com/sun/javafx/css/ua0.css"); 315 assertEquals(0, index); 316 317 index = indexOf(sm.userAgentStylesheetContainers,"/com/sun/javafx/css/ua0.css"); 318 assertEquals(-1, index); 319 320 index = indexOf(sm.userAgentStylesheetContainers,"/com/sun/javafx/css/ua1.css"); 321 assertEquals(0,index); 322 323 index = indexOf(sm.platformUserAgentStylesheetContainers,"/com/sun/javafx/css/ua1.css"); 324 assertEquals(-1, index); 325 326 sm.forget(scene.getRoot()); 327 328 // forgetting the parent should not affect the platform user-agent stylesheets 329 index = indexOf(sm.platformUserAgentStylesheetContainers,"/com/sun/javafx/css/ua0.css"); 330 assertEquals(0,index); 331 332 // only forgetting the scene should affect the platform user-agent stylesheets 333 index = indexOf(sm.userAgentStylesheetContainers,"/com/sun/javafx/css/ua1.css"); 334 assertEquals(0, index); 335 336 } 337 338 @Test 339 public void testForgetParent_withTwoScenes() { 340 Scene scene0 = new Scene(new Group(new Rectangle(){{ getStyleClass().add("rect"); }})); 341 scene0.setUserAgentStylesheet("/com/sun/javafx/css/ua1.css"); 342 343 Scene scene1 = new Scene(new Group(new Rectangle(){{ getStyleClass().add("rect"); }})); 344 scene1.setUserAgentStylesheet("/com/sun/javafx/css/ua1.css"); 345 346 StyleManager sm = StyleManager.getInstance(); 347 sm.setDefaultUserAgentStylesheet("/com/sun/javafx/css/ua0.css"); 348 349 scene0.getRoot().applyCss(); 350 scene1.getRoot().applyCss(); 351 352 // even though there are two scenes using this stylesheet, there should only be one container. 353 assertEquals(1, sm.userAgentStylesheetContainers.size()); 354 355 int index = indexOf(sm.platformUserAgentStylesheetContainers,"/com/sun/javafx/css/ua0.css"); 356 assertEquals(0,index); 357 358 index = indexOf(sm.userAgentStylesheetContainers,"/com/sun/javafx/css/ua0.css"); 359 assertEquals(-1, index); 360 361 index = indexOf(sm.userAgentStylesheetContainers,"/com/sun/javafx/css/ua1.css"); 362 assertEquals(0, index); 363 364 index = indexOf(sm.platformUserAgentStylesheetContainers,"/com/sun/javafx/css/ua1.css"); 365 assertEquals(-1, index); 366 367 sm.forget(scene0.getRoot()); 368 369 // forgetting the scene should not affect the platform user-agent stylesheets 370 index = indexOf(sm.platformUserAgentStylesheetContainers,"/com/sun/javafx/css/ua0.css"); 371 assertEquals(0,index); 372 373 // we should still have ua1.css since scene1 is still using it 374 index = indexOf(sm.userAgentStylesheetContainers,"/com/sun/javafx/css/ua1.css"); 375 assertEquals(0,index); 376 377 sm.forget(scene1.getRoot()); 378 379 // only forgetting the scene should affect the platform user-agent stylesheets 380 index = indexOf(sm.userAgentStylesheetContainers,"/com/sun/javafx/css/ua1.css"); 381 assertEquals(0, index); 382 } 383 384 @Test 385 public void testForgetParent_withParentStylesheet() { 386 387 Scene scene = new Scene(new Group(new Rectangle(){{ getStyleClass().add("rect"); }})); 388 scene.getRoot().getStylesheets().add("/com/sun/javafx/css/ua1.css"); 389 390 StyleManager sm = StyleManager.getInstance(); 391 sm.setDefaultUserAgentStylesheet("/com/sun/javafx/css/ua0.css"); 392 393 scene.getRoot().applyCss(); 394 395 int index = indexOf(sm.platformUserAgentStylesheetContainers,"/com/sun/javafx/css/ua0.css"); 396 assertEquals(0, index); 397 398 assertTrue(sm.userAgentStylesheetContainers.isEmpty()); 399 assertTrue(sm.stylesheetContainerMap.containsKey("/com/sun/javafx/css/ua1.css")); 400 401 sm.forget(scene.getRoot()); 402 403 // forgetting the scene should not affect the platform user-agent stylesheets 404 index = indexOf(sm.platformUserAgentStylesheetContainers,"/com/sun/javafx/css/ua0.css"); 405 assertEquals(0, index); 406 407 assertFalse(sm.stylesheetContainerMap.containsKey("/com/sun/javafx/css/ua1.css")); 408 409 } 410 411 @Test 412 public void testForgetParent_withMultipleParentStylesheets() { 413 414 final Parent parent0 = new Pane(new Rectangle(){{ getStyleClass().add("rect"); }}); 415 parent0.getStylesheets().add("/com/sun/javafx/css/ua1.css"); 416 417 final Parent parent1 = new Pane(new Rectangle(){{ getStyleClass().add("rect"); }}); 418 parent1.getStylesheets().add("/com/sun/javafx/css/ua1.css"); 419 420 Scene scene = new Scene(new Group(parent0, parent1)); 421 422 StyleManager sm = StyleManager.getInstance(); 423 sm.setDefaultUserAgentStylesheet("/com/sun/javafx/css/ua0.css"); 424 425 scene.getRoot().applyCss(); 426 427 assertTrue(sm.userAgentStylesheetContainers.isEmpty()); 428 429 StyleManager.StylesheetContainer container = sm.stylesheetContainerMap.get("/com/sun/javafx/css/ua1.css"); 430 assertNotNull(container); 431 assertTrue(container.parentUsers.contains(parent0)); 432 assertTrue(container.parentUsers.contains(parent1)); 433 434 sm.forget(parent0); 435 436 assertTrue(sm.stylesheetContainerMap.containsKey("/com/sun/javafx/css/ua1.css")); 437 assertFalse(container.parentUsers.contains(parent0)); 438 assertTrue(container.parentUsers.contains(parent1)); 439 440 sm.forget(parent1); 441 442 assertFalse(sm.stylesheetContainerMap.containsKey("/com/sun/javafx/css/ua1.css")); 443 assertFalse(container.parentUsers.contains(parent0)); 444 assertFalse(container.parentUsers.contains(parent1)); 445 } 446 447 @Test 448 public void testForgetScene() { 449 450 Scene scene = new Scene(new Group(new Rectangle(){{ getStyleClass().add("rect"); }})); 451 452 StyleManager sm = StyleManager.getInstance(); 453 sm.setDefaultUserAgentStylesheet("/com/sun/javafx/css/ua0.css"); 454 455 scene.getRoot().applyCss(); 456 457 int index = indexOf(sm.platformUserAgentStylesheetContainers,"/com/sun/javafx/css/ua0.css"); 458 assertEquals(0,index); 459 460 sm.forget(scene); 461 462 // forgetting the scene should not affect the platform user-agent stylesheets 463 index = indexOf(sm.platformUserAgentStylesheetContainers,"/com/sun/javafx/css/ua0.css"); 464 assertEquals(0,index); 465 } 466 467 @Test 468 public void testForgetScene_withUAStylesheet() { 469 470 Scene scene = new Scene(new Group(new Rectangle(){{ getStyleClass().add("rect"); }})); 471 scene.setUserAgentStylesheet("/com/sun/javafx/css/ua1.css"); 472 473 StyleManager sm = StyleManager.getInstance(); 474 sm.setDefaultUserAgentStylesheet("/com/sun/javafx/css/ua0.css"); 475 476 scene.getRoot().applyCss(); 477 478 int index = indexOf(sm.platformUserAgentStylesheetContainers,"/com/sun/javafx/css/ua0.css"); 479 assertEquals(0, index); 480 481 index = indexOf(sm.userAgentStylesheetContainers,"/com/sun/javafx/css/ua0.css"); 482 assertEquals(-1, index); 483 484 index = indexOf(sm.userAgentStylesheetContainers,"/com/sun/javafx/css/ua1.css"); 485 assertEquals(0,index); 486 487 index = indexOf(sm.platformUserAgentStylesheetContainers,"/com/sun/javafx/css/ua1.css"); 488 assertEquals(-1, index); 489 490 sm.forget(scene); 491 492 // forgetting the scene should not affect the platform user-agent stylesheets 493 index = indexOf(sm.platformUserAgentStylesheetContainers,"/com/sun/javafx/css/ua0.css"); 494 assertEquals(0,index); 495 496 index = indexOf(sm.userAgentStylesheetContainers,"/com/sun/javafx/css/ua1.css"); 497 assertEquals(-1, index); 498 499 } 500 501 @Test 502 public void testForgetScene_withTwoScenes() { 503 Scene scene0 = new Scene(new Group(new Rectangle(){{ getStyleClass().add("rect"); }})); 504 scene0.setUserAgentStylesheet("/com/sun/javafx/css/ua1.css"); 505 506 Scene scene1 = new Scene(new Group(new Rectangle(){{ getStyleClass().add("rect"); }})); 507 scene1.setUserAgentStylesheet("/com/sun/javafx/css/ua1.css"); 508 509 StyleManager sm = StyleManager.getInstance(); 510 sm.setDefaultUserAgentStylesheet("/com/sun/javafx/css/ua0.css"); 511 512 scene0.getRoot().applyCss(); 513 scene1.getRoot().applyCss(); 514 515 // even though there are two scenes using this stylesheet, there should only be one container. 516 assertEquals(1, sm.userAgentStylesheetContainers.size()); 517 518 int index = indexOf(sm.platformUserAgentStylesheetContainers,"/com/sun/javafx/css/ua0.css"); 519 assertEquals(0,index); 520 521 index = indexOf(sm.userAgentStylesheetContainers,"/com/sun/javafx/css/ua0.css"); 522 assertEquals(-1, index); 523 524 index = indexOf(sm.userAgentStylesheetContainers,"/com/sun/javafx/css/ua1.css"); 525 assertEquals(0,index); 526 527 index = indexOf(sm.platformUserAgentStylesheetContainers,"/com/sun/javafx/css/ua1.css"); 528 assertEquals(-1, index); 529 530 sm.forget(scene0); 531 532 // forgetting the scene should not affect the platform user-agent stylesheets 533 index = indexOf(sm.platformUserAgentStylesheetContainers,"/com/sun/javafx/css/ua0.css"); 534 assertEquals(0,index); 535 536 // we should still have ua1.css since scene1 is still using it 537 index = indexOf(sm.userAgentStylesheetContainers,"/com/sun/javafx/css/ua1.css"); 538 assertEquals(0,index); 539 540 sm.forget(scene1); 541 542 // having forgotten scene1, userAgentStylesheetContainers should be empty. 543 assertTrue(sm.userAgentStylesheetContainers.isEmpty()); 544 } 545 546 @Test 547 public void testForgetSubScene() { 548 549 Pane subSceneRoot = new Pane(new Rectangle(){{ getStyleClass().add("rect"); }}); 550 SubScene subScene = new SubScene(subSceneRoot, 100, 100); 551 Scene scene = new Scene(new Group(subScene)); 552 553 StyleManager sm = StyleManager.getInstance(); 554 sm.setDefaultUserAgentStylesheet("/com/sun/javafx/css/ua0.css"); 555 556 scene.getRoot().applyCss(); 557 558 int index = indexOf(sm.platformUserAgentStylesheetContainers,"/com/sun/javafx/css/ua0.css"); 559 assertEquals(0,index); 560 561 sm.forget(subScene); 562 563 // forgetting the scene should not affect the platform user-agent stylesheets 564 index = indexOf(sm.platformUserAgentStylesheetContainers,"/com/sun/javafx/css/ua0.css"); 565 assertEquals(0,index); 566 } 567 568 @Test 569 public void testForgetSubScene_withUAStylesheet() { 570 571 Pane subSceneRoot = new Pane(new Group(new Rectangle(){{ getStyleClass().add("rect"); }})); 572 SubScene subScene = new SubScene(subSceneRoot, 100, 100); 573 subScene.setUserAgentStylesheet("/com/sun/javafx/css/ua1.css"); 574 Scene scene = new Scene(new Group(subScene)); 575 576 StyleManager sm = StyleManager.getInstance(); 577 sm.setDefaultUserAgentStylesheet("/com/sun/javafx/css/ua0.css"); 578 579 int index = indexOf(sm.platformUserAgentStylesheetContainers,"/com/sun/javafx/css/ua0.css"); 580 assertEquals(0, index); 581 582 index = indexOf(sm.userAgentStylesheetContainers,"/com/sun/javafx/css/ua0.css"); 583 assertEquals(-1, index); 584 585 index = indexOf(sm.userAgentStylesheetContainers,"/com/sun/javafx/css/ua1.css"); 586 assertEquals(0,index); 587 588 index = indexOf(sm.platformUserAgentStylesheetContainers,"/com/sun/javafx/css/ua1.css"); 589 assertEquals(-1, index); 590 591 sm.forget(subScene); 592 593 // forgetting the scene should not affect the platform user-agent stylesheets 594 index = indexOf(sm.platformUserAgentStylesheetContainers,"/com/sun/javafx/css/ua0.css"); 595 assertEquals(0,index); 596 597 index = indexOf(sm.userAgentStylesheetContainers,"/com/sun/javafx/css/ua1.css"); 598 assertEquals(-1, index); 599 600 } 601 602 @Test 603 public void testForgetSubScene_with_UAStylesheet_and_ParentStylesheet() { 604 605 // make sure forget(SubScene) get's children with stylesheets 606 Group group = new Group(new Rectangle(){{ getStyleClass().add("rect"); }}); 607 group.getStylesheets().add("/com/sun/javafx/css/ua2.css"); 608 Pane subSceneRoot = new Pane(group); 609 SubScene subScene = new SubScene(subSceneRoot, 100, 100); 610 subScene.setUserAgentStylesheet("/com/sun/javafx/css/ua1.css"); 611 Scene scene = new Scene(new Group(subScene)); 612 613 StyleManager sm = StyleManager.getInstance(); 614 sm.setDefaultUserAgentStylesheet("/com/sun/javafx/css/ua0.css"); 615 616 scene.getRoot().applyCss(); 617 618 int index = indexOf(sm.platformUserAgentStylesheetContainers,"/com/sun/javafx/css/ua0.css"); 619 assertEquals(0,index); 620 621 index = indexOf(sm.userAgentStylesheetContainers,"/com/sun/javafx/css/ua0.css"); 622 assertEquals(-1, index); 623 624 index = indexOf(sm.userAgentStylesheetContainers,"/com/sun/javafx/css/ua1.css"); 625 assertEquals(0,index); 626 627 index = indexOf(sm.platformUserAgentStylesheetContainers,"/com/sun/javafx/css/ua1.css"); 628 assertEquals(-1, index); 629 630 sm.forget(subScene); 631 632 // forgetting the scene should not affect the platform user-agent stylesheets 633 index = indexOf(sm.platformUserAgentStylesheetContainers,"/com/sun/javafx/css/ua0.css"); 634 assertEquals(0,index); 635 636 index = indexOf(sm.userAgentStylesheetContainers,"/com/sun/javafx/css/ua1.css"); 637 assertEquals(-1, index); 638 639 } 640 641 @Test 642 public void testChangeSubSceneStylesheet() { 643 644 Pane subSceneRoot = new Pane(new Group(new Rectangle(){{ getStyleClass().add("rect"); }})); 645 SubScene subScene = new SubScene(subSceneRoot, 100, 100); 646 Scene scene = new Scene(new Group(subScene)); 647 648 StyleManager sm = StyleManager.getInstance(); 649 sm.setDefaultUserAgentStylesheet("/com/sun/javafx/css/ua0.css"); 650 651 scene.getRoot().applyCss(); 652 653 scene.getRoot().applyCss(); 654 655 scene.getRoot().applyCss(); 656 657 int index = indexOf(sm.platformUserAgentStylesheetContainers,"/com/sun/javafx/css/ua0.css"); 658 assertEquals(0, index); 659 660 index = indexOf(sm.userAgentStylesheetContainers,"/com/sun/javafx/css/ua0.css"); 661 assertEquals(-1, index); 662 663 subScene.setUserAgentStylesheet("/com/sun/javafx/css/ua1.css"); 664 665 index = indexOf(sm.userAgentStylesheetContainers,"/com/sun/javafx/css/ua1.css"); 666 assertEquals(0,index); 667 668 sm.forget(subScene); 669 670 subScene.setUserAgentStylesheet("/com/sun/javafx/css/ua2.css"); 671 scene.getRoot().applyCss(); 672 673 index = indexOf(sm.userAgentStylesheetContainers,"/com/sun/javafx/css/ua2.css"); 674 assertEquals(0, index); 675 676 index = indexOf(sm.userAgentStylesheetContainers,"/com/sun/javafx/css/ua1.css"); 677 assertEquals(-1,index); 678 679 } 680 681 @Test 682 public void testFindMatchingStyles_defaultStyleSheet() { 683 684 StyleManager sm = StyleManager.getInstance(); 685 sm.setDefaultUserAgentStylesheet("/com/sun/javafx/css/ua0.css"); 686 687 Rectangle rect = new Rectangle(){{ getStyleClass().add("rect"); }}; 688 Scene scene = new Scene(new Group(rect)); 689 690 StyleMap matchingStyles = sm.findMatchingStyles(rect, null, null); 691 Map<String,List<CascadingStyle>> styleMap = matchingStyles.getCascadingStyles(); 692 693 assertTrue(styleMap.containsKey("-fx-fill")); 694 695 List<CascadingStyle> styles = styleMap.get("-fx-fill"); 696 assertEquals(1, styles.size()); 697 698 Object obj = styles.get(0).getParsedValueImpl().convert(null); 699 assertEquals(Color.RED, obj); 700 } 701 702 @Test 703 public void testFindMatchingStyles_defaultStyleSheet_sceneUserAgentStylesheet() { 704 705 StyleManager sm = StyleManager.getInstance(); 706 sm.setDefaultUserAgentStylesheet("/com/sun/javafx/css/ua0.css"); 707 708 Rectangle rect = new Rectangle(){{ getStyleClass().add("rect"); }}; 709 Scene scene = new Scene(new Group(rect)); 710 scene.setUserAgentStylesheet("/com/sun/javafx/css/ua1.css"); 711 712 StyleMap matchingStyles = sm.findMatchingStyles(rect, null, null); 713 Map<String,List<CascadingStyle>> styleMap = matchingStyles.getCascadingStyles(); 714 715 scene.getRoot().applyCss(); 716 717 // scene stylesheet should totally replace default 718 assertFalse(styleMap.containsKey("-fx-fill")); 719 assertTrue(styleMap.containsKey("-fx-stroke")); 720 721 List<CascadingStyle> styles = styleMap.get("-fx-stroke"); 722 assertEquals(1, styles.size()); 723 724 Object obj = styles.get(0).getParsedValueImpl().convert(null); 725 assertEquals(Color.YELLOW, obj); 726 } 727 728 @Test 729 public void testFindMatchingStyles_defaultStyleSheet_sceneUserAgentStylesheet_sceneAuthorStylesheet() { 730 731 StyleManager sm = StyleManager.getInstance(); 732 sm.setDefaultUserAgentStylesheet("/com/sun/javafx/css/ua0.css"); 733 734 Rectangle rect = new Rectangle(){{ getStyleClass().add("rect"); }}; 735 Scene scene = new Scene(new Group(rect)); 736 scene.setUserAgentStylesheet("/com/sun/javafx/css/ua1.css"); 737 scene.getStylesheets().add("/com/sun/javafx/css/ua2.css"); 738 739 StyleMap matchingStyles = sm.findMatchingStyles(rect, null, null); 740 Map<String,List<CascadingStyle>> styleMap = matchingStyles.getCascadingStyles(); 741 742 scene.getRoot().applyCss(); 743 744 // ua2.css has fill 745 assertTrue(styleMap.containsKey("-fx-fill")); 746 assertTrue(styleMap.containsKey("-fx-stroke")); 747 748 // ua1.css and ua2.css have stroke 749 List<CascadingStyle> styles = styleMap.get("-fx-stroke"); 750 assertEquals(2, styles.size()); 751 752 Object obj = styles.get(0).getParsedValueImpl().convert(null); 753 assertEquals(Color.GREEN, obj); 754 755 // ua0.css and ua2.css have fill, but we shouldn't get anything from ua0 756 // since we have a scene user-agent stylesheet 757 styles = styleMap.get("-fx-fill"); 758 assertEquals(1, styles.size()); 759 760 obj = styles.get(0).getParsedValueImpl().convert(null); 761 assertEquals(Color.BLUE, obj); 762 } 763 764 @Test 765 public void testFindMatchingStyles_defaultStyleSheet_subSceneUserAgentStylesheet() { 766 767 StyleManager sm = StyleManager.getInstance(); 768 sm.setDefaultUserAgentStylesheet("/com/sun/javafx/css/ua0.css"); 769 770 Rectangle rect = new Rectangle(){{ getStyleClass().add("rect"); }}; 771 Pane subSceneRoot = new Pane(rect); 772 SubScene subScene = new SubScene(subSceneRoot, 100, 100); 773 subScene.setUserAgentStylesheet("/com/sun/javafx/css/ua1.css"); 774 Scene scene = new Scene(new Group(subScene)); 775 776 StyleMap matchingStyles = sm.findMatchingStyles(rect, subScene, null); 777 Map<String,List<CascadingStyle>> styleMap = matchingStyles.getCascadingStyles(); 778 779 scene.getRoot().applyCss(); 780 781 // SubScene stylesheet should totally replace default 782 assertFalse(styleMap.containsKey("-fx-fill")); 783 assertTrue(styleMap.containsKey("-fx-stroke")); 784 785 List<CascadingStyle> styles = styleMap.get("-fx-stroke"); 786 assertEquals(1, styles.size()); 787 788 Object obj = styles.get(0).getParsedValueImpl().convert(null); 789 assertEquals(Color.YELLOW, obj); 790 } 791 792 @Test 793 public void testFindMatchingStyles_defaultStyleSheet_subSceneUserAgentStylesheet_parentStylesheet() { 794 795 StyleManager sm = StyleManager.getInstance(); 796 sm.setDefaultUserAgentStylesheet("/com/sun/javafx/css/ua0.css"); 797 798 Rectangle rect = new Rectangle(){{ getStyleClass().add("rect"); }}; 799 Group group = new Group(rect); 800 group.getStylesheets().add("/com/sun/javafx/css/ua2.css"); 801 Pane subSceneRoot = new Pane(group); 802 SubScene subScene = new SubScene(subSceneRoot, 100, 100); 803 subScene.setUserAgentStylesheet("/com/sun/javafx/css/ua1.css"); 804 Scene scene = new Scene(new Group(subScene)); 805 806 StyleMap matchingStyles = sm.findMatchingStyles(rect, subScene, null); 807 Map<String,List<CascadingStyle>> styleMap = matchingStyles.getCascadingStyles(); 808 809 scene.getRoot().applyCss(); 810 811 // ua2.css has fill 812 assertTrue(styleMap.containsKey("-fx-fill")); 813 assertTrue(styleMap.containsKey("-fx-stroke")); 814 815 // ua1.css and ua2.css have stroke 816 List<CascadingStyle> styles = styleMap.get("-fx-stroke"); 817 assertEquals(2, styles.size()); 818 819 Object obj = styles.get(0).getParsedValueImpl().convert(null); 820 assertEquals(Color.GREEN, obj); 821 822 // ua0.css and ua2.css have fill, but we shouldn't get anything from ua0 823 // since we have a scene user-agent stylesheet 824 styles = styleMap.get("-fx-fill"); 825 assertEquals(1, styles.size()); 826 827 obj = styles.get(0).getParsedValueImpl().convert(null); 828 assertEquals(Color.BLUE, obj); 829 } 830 831 @Test 832 public void testSwitchDefaultUserAgentStylesheets() { 833 834 Rectangle rect = new Rectangle(){{ getStyleClass().add("rect"); }}; 835 Group group = new Group(rect); 836 Pane subSceneRoot = new Pane(group); 837 SubScene subScene = new SubScene(subSceneRoot, 100, 100); 838 Scene scene = new Scene(new Group(subScene)); 839 840 StyleManager sm = StyleManager.getInstance(); 841 sm.setDefaultUserAgentStylesheet("/com/sun/javafx/css/ua0.css"); 842 843 scene.getRoot().applyCss(); 844 845 StyleMap matchingStyles = sm.findMatchingStyles(rect, subScene, null); 846 Map<String,List<CascadingStyle>> styleMap = matchingStyles.getCascadingStyles(); 847 848 // ua0.css has fill 849 assertTrue(styleMap.containsKey("-fx-fill")); 850 assertFalse(styleMap.containsKey("-fx-stroke")); 851 852 List<CascadingStyle> styles = styleMap.get("-fx-fill"); 853 assertEquals(1, styles.size()); 854 855 Object obj = styles.get(0).getParsedValueImpl().convert(null); 856 assertEquals(Color.RED, obj); 857 858 sm.setDefaultUserAgentStylesheet("/com/sun/javafx/css/ua1.css"); 859 860 matchingStyles = sm.findMatchingStyles(rect, subScene, null); 861 styleMap = matchingStyles.getCascadingStyles(); 862 863 // ua1.css has stroke 864 assertTrue(styleMap.containsKey("-fx-stroke")); 865 assertFalse(styleMap.containsKey("-fx-fill")); 866 867 styles = styleMap.get("-fx-stroke"); 868 assertEquals(1, styles.size()); 869 870 obj = styles.get(0).getParsedValueImpl().convert(null); 871 assertEquals(Color.YELLOW, obj); 872 } 873 874 @Test 875 public void testGetCacheContainer() { 876 877 Rectangle rectangle = new Rectangle(); 878 SubScene subScene = new SubScene(null, 0, 0); 879 880 StyleManager sm = StyleManager.getInstance(); 881 882 // no scene, should return null 883 StyleManager.CacheContainer container = sm.getCacheContainer(rectangle, subScene); 884 885 assertNull(container); 886 887 // has scene, should return non-null 888 subScene.setRoot(new Group()); 889 Scene scene = new Scene(new Group(rectangle,subScene)); 890 container = sm.getCacheContainer(rectangle, subScene); 891 892 assertNotNull(container); 893 894 } 895 896 @Test 897 public void testGetCacheContainer_styleable() { 898 Rectangle rectangle = new Rectangle(); 899 900 StyleManager sm = StyleManager.getInstance(); 901 902 // no scene, should return null 903 StyleManager.CacheContainer container = sm.getCacheContainer(rectangle, null); 904 905 assertNull(container); 906 907 // has scene, should return non-null 908 Scene scene = new Scene(new Group(rectangle)); 909 container = sm.getCacheContainer(rectangle, null); 910 911 assertNotNull(container); 912 913 } 914 915 @Test 916 public void testGetCacheContainer_subScene() { 917 918 SubScene subScene = new SubScene(null, 0, 0); 919 920 StyleManager sm = StyleManager.getInstance(); 921 922 // no scene, should return null 923 StyleManager.CacheContainer container = sm.getCacheContainer(null, subScene); 924 925 assertNull(container); 926 927 // has scene, should return non-null 928 subScene.setRoot(new Group()); 929 Scene scene = new Scene(new Group(subScene)); 930 container = sm.getCacheContainer(null, subScene); 931 932 assertNotNull(container); 933 934 } 935 936 @Test 937 public void testRT_37025() { 938 939 // 940 // The issue in RT-37025 was that the stylesheet container wasn't getting removed even 941 // though the parent had been forgotten. The StyleManager#forget(Parent) method didn't 942 // look to see if _any_ stylesheet container had the parent as a reference. 943 // 944 final StyleManager sm = StyleManager.getInstance(); 945 946 // This test needs a bit more complexity to the scene-graph 947 Group group = null; 948 Pane pane = new Pane( 949 new Group( 950 new Pane( 951 // I want these to be a Parent, not a Node 952 new Group(new Pane(){{ getStyleClass().add("rect"); }}), 953 group = new Group(new Pane(){{ getStyleClass().add("rect"); }}) 954 ) 955 ) 956 ); 957 pane.getStylesheets().add("/com/sun/javafx/css/ua0.css"); 958 group.getStylesheets().add("/com/sun/javafx/css/ua1.css"); 959 960 Group root = new Group(pane); 961 Scene scene = new Scene(root); 962 963 root.applyCss(); 964 965 assertTrue(sm.stylesheetContainerMap.containsKey("/com/sun/javafx/css/ua0.css")); 966 StyleManager.StylesheetContainer container = sm.stylesheetContainerMap.get("/com/sun/javafx/css/ua0.css"); 967 assertEquals(7, container.parentUsers.list.size()); 968 969 assertTrue(sm.stylesheetContainerMap.containsKey("/com/sun/javafx/css/ua1.css")); 970 container = sm.stylesheetContainerMap.get("/com/sun/javafx/css/ua1.css"); 971 assertEquals(2, container.parentUsers.list.size()); 972 973 ((Pane)group.getParent()).getChildren().remove(group); 974 975 assertFalse(sm.stylesheetContainerMap.containsKey("/com/sun/javafx/css/ua1.css")); 976 assertTrue(sm.stylesheetContainerMap.containsKey("/com/sun/javafx/css/ua0.css")); 977 container = sm.stylesheetContainerMap.get("/com/sun/javafx/css/ua0.css"); 978 assertEquals(5, container.parentUsers.list.size()); 979 980 scene.setRoot(new Group()); 981 assertFalse(sm.stylesheetContainerMap.containsKey("/com/sun/javafx/css/ua0.css")); 982 assertFalse(StyleManager.cacheContainerMap.containsKey(root)); 983 assertTrue(StyleManager.cacheContainerMap.containsKey(scene.getRoot())); 984 985 } 986 987 @Test 988 public void test_setUserAgentStylesheets() { 989 990 List<String> uaStylesheets = new ArrayList<>(); 991 Collections.addAll(uaStylesheets, "/com/sun/javafx/css/ua0.css", "/com/sun/javafx/css/ua1.css"); 992 993 final StyleManager sm = StyleManager.getInstance(); 994 sm.setUserAgentStylesheets(uaStylesheets); 995 996 assertEquals(2, sm.platformUserAgentStylesheetContainers.size()); 997 assertEquals("/com/sun/javafx/css/ua0.css", sm.platformUserAgentStylesheetContainers.get(0).fname); 998 assertEquals("/com/sun/javafx/css/ua1.css", sm.platformUserAgentStylesheetContainers.get(1).fname); 999 } 1000 1001 @Test 1002 public void test_setUserAgentStylesheets_overwrites_existing() { 1003 1004 List<String> uaStylesheets = new ArrayList<>(); 1005 Collections.addAll(uaStylesheets, "/com/sun/javafx/css/ua0.css"); 1006 1007 final StyleManager sm = StyleManager.getInstance(); 1008 1009 // 1 - overwrite default user agent stylesheet 1010 sm.platformUserAgentStylesheetContainers.clear();; 1011 sm.setDefaultUserAgentStylesheet("/com/sun/javafx/css/ua1.css"); 1012 assertEquals(1, sm.platformUserAgentStylesheetContainers.size()); 1013 assertEquals("/com/sun/javafx/css/ua1.css", sm.platformUserAgentStylesheetContainers.get(0).fname); 1014 1015 sm.setUserAgentStylesheets(uaStylesheets); 1016 assertEquals(1, sm.platformUserAgentStylesheetContainers.size()); 1017 assertEquals("/com/sun/javafx/css/ua0.css", sm.platformUserAgentStylesheetContainers.get(0).fname); 1018 1019 // 2 - overwrite other user-agent stylesheets 1020 sm.platformUserAgentStylesheetContainers.clear();; 1021 sm.addUserAgentStylesheet("/com/sun/javafx/css/ua1.css"); 1022 assertEquals(1, sm.platformUserAgentStylesheetContainers.size()); 1023 1024 sm.setUserAgentStylesheets(uaStylesheets); 1025 assertEquals(1, sm.platformUserAgentStylesheetContainers.size()); 1026 assertEquals("/com/sun/javafx/css/ua0.css", sm.platformUserAgentStylesheetContainers.get(0).fname); 1027 } 1028 1029 @Test 1030 public void testRT_38687_with_Scene() { 1031 1032 Rectangle rect = new Rectangle(50,50) {{ getStyleClass().add("rect"); }}; 1033 Scene scene = new Scene(new Group(rect)); 1034 scene.setUserAgentStylesheet("com/sun/javafx/css/ua0.css"); 1035 scene.getRoot().applyCss(); 1036 1037 StyleableProperty<Paint> fillProperty = (StyleableProperty<Paint>)rect.fillProperty(); 1038 assertEquals(StyleOrigin.USER_AGENT, fillProperty.getStyleOrigin()); 1039 1040 scene.setUserAgentStylesheet("com/sun/javafx/css/ua1.css"); 1041 scene.getRoot().applyCss(); 1042 1043 assertEquals(null, fillProperty.getStyleOrigin()); 1044 1045 rect.setFill(Color.GREEN); 1046 1047 scene.setUserAgentStylesheet("com/sun/javafx/css/rt38637.css"); 1048 scene.getRoot().applyCss(); 1049 assertEquals(StyleOrigin.USER, fillProperty.getStyleOrigin()); 1050 1051 } 1052 1053 @Test 1054 public void testRT_38687_with_SubScene() { 1055 1056 Rectangle rect = new Rectangle(50,50) {{ getStyleClass().add("rect"); }}; 1057 Group group = new Group(rect); 1058 SubScene subScene = new SubScene(group, 100, 100); 1059 subScene.setUserAgentStylesheet("com/sun/javafx/css/ua0.css"); 1060 1061 Scene scene = new Scene(new Group(subScene)); 1062 scene.getRoot().applyCss(); 1063 1064 StyleableProperty<Paint> fillProperty = (StyleableProperty<Paint>)rect.fillProperty(); 1065 assertEquals(StyleOrigin.USER_AGENT, fillProperty.getStyleOrigin()); 1066 1067 subScene.setUserAgentStylesheet("com/sun/javafx/css/ua1.css"); 1068 scene.getRoot().applyCss(); 1069 1070 assertEquals(null, fillProperty.getStyleOrigin()); 1071 1072 rect.setFill(Color.GREEN); 1073 1074 subScene.setUserAgentStylesheet("com/sun/javafx/css/rt38637.css"); 1075 scene.getRoot().applyCss(); 1076 assertEquals(StyleOrigin.USER, fillProperty.getStyleOrigin()); 1077 1078 } 1079 1080 @Test 1081 public void testConcurrentAccess() { 1082 final int NUM_THREADS = 10; 1083 final Thread[] bgThreads = new Thread[NUM_THREADS]; 1084 final AtomicBoolean err = new AtomicBoolean(false); 1085 for (int i = 0; i < NUM_THREADS; i++) { 1086 Thread thr = new Thread(() -> { 1087 try { 1088 for (int j = 0; j < 1000; j++) { 1089 Scene scene = new Scene(new Group()); 1090 scene.setUserAgentStylesheet("com/sun/javafx/css/ua0.css"); 1091 scene.getRoot().applyCss(); 1092 } 1093 } catch (RuntimeException ex) { 1094 err.set(true); 1095 throw ex; 1096 } 1097 }); 1098 thr.setName("MyThread-" + i); 1099 thr.setDaemon(true); 1100 bgThreads[i] = thr; 1101 } 1102 1103 for (Thread thr : bgThreads) { 1104 thr.start(); 1105 } 1106 1107 try { 1108 for (Thread thr : bgThreads) { 1109 thr.join(); 1110 } 1111 } catch (InterruptedException ex) { 1112 fail("Unexpected exception waiting for threads to finish"); 1113 } 1114 1115 assertFalse("Exception during CSS processing on BG thread", err.get()); 1116 } 1117 1118 }