ShadowRoot extends Node<ShadowRoot> { public static ShadowRoot get(StateNode node) { assert node != null; if (isShadowRoot(node)) { return new ShadowRoot(node); } else { throw new IllegalArgumentException( "Node is not valid as an element"); } } private  ShadowRoot(StateNode node); static ShadowRoot get(StateNode node); static boolean isShadowRoot(StateNode node); @Override Node<?> getParentNode(); Element getHost(); @Override ShadowRootStateProvider getStateProvider();  }
@Test public void attachListener_parentAttach_childListenersTriggered() { Element body = new UI().getElement(); Element parent = ElementFactory.createDiv(); Element child = ElementFactory.createDiv(); Element grandChild = ElementFactory.createDiv(); AtomicInteger childTriggered = new AtomicInteger(); AtomicInteger grandChildTriggered = new AtomicInteger(); Registration registrationHandle = child.addAttachListener(event -> { childTriggered.addAndGet(1); }); child.addAttachListener(event -> { Assert.assertEquals(child, event.getSource()); }); grandChild.addAttachListener(event -> { grandChildTriggered.addAndGet(1); }); grandChild.addAttachListener(event -> { Assert.assertEquals(grandChild, event.getSource()); }); parent.attachShadow().appendChild(child); child.appendChild(grandChild); Assert.assertEquals(childTriggered.get(), 0); Assert.assertEquals(grandChildTriggered.get(), 0); body.appendChild(parent); Assert.assertEquals(childTriggered.get(), 1); Assert.assertEquals(grandChildTriggered.get(), 1); body.removeAllChildren(); parent.getShadowRoot().get().removeAllChildren(); body.appendChild(parent); parent.getShadowRoot().get().appendChild(child); Assert.assertEquals(childTriggered.get(), 2); Assert.assertEquals(grandChildTriggered.get(), 2); registrationHandle.remove(); body.removeAllChildren(); body.appendChild(child); Assert.assertEquals(childTriggered.get(), 2); Assert.assertEquals(grandChildTriggered.get(), 3); }
@Test public void detachListener_parentDetach_childListenersTriggered() { Element body = new UI().getElement(); Element parent = ElementFactory.createDiv(); Element child = ElementFactory.createDiv(); Element grandChild = ElementFactory.createDiv(); AtomicInteger triggered = new AtomicInteger(); Registration registrationHandle = child.addDetachListener(event -> { triggered.addAndGet(1); Assert.assertEquals(child, event.getSource()); }); grandChild.addDetachListener(event -> { triggered.addAndGet(1); Assert.assertEquals(grandChild, event.getSource()); }); child.appendChild(grandChild); parent.attachShadow().appendChild(child); body.appendChild(parent); Assert.assertEquals(triggered.get(), 0); body.removeAllChildren(); Assert.assertEquals(triggered.get(), 2); body.appendChild(parent); body.removeAllChildren(); Assert.assertEquals(triggered.get(), 4); body.appendChild(parent); registrationHandle.remove(); body.removeAllChildren(); Assert.assertEquals(triggered.get(), 5); }
@Test public void attachListener_eventOrder_childFirst() { Element body = new UI().getElement(); Element parent = ElementFactory.createDiv(); Element child = ElementFactory.createDiv(); parent.attachShadow().appendChild(child); AtomicBoolean parentAttached = new AtomicBoolean(); AtomicBoolean childAttached = new AtomicBoolean(); child.addAttachListener(event -> { childAttached.set(true); Assert.assertFalse(parentAttached.get()); }); parent.addAttachListener(event -> { parentAttached.set(true); Assert.assertTrue(childAttached.get()); }); body.appendChild(parent); Assert.assertTrue(parentAttached.get()); Assert.assertTrue(childAttached.get()); }
@Test public void detachListener_eventOrder_childFirst() { Element body = new UI().getElement(); Element parent = ElementFactory.createDiv(); Element child = ElementFactory.createDiv(); parent.attachShadow().appendChild(child); body.appendChild(parent); AtomicBoolean parentDetached = new AtomicBoolean(); AtomicBoolean childDetached = new AtomicBoolean(); child.addDetachListener(event -> { childDetached.set(true); Assert.assertFalse(parentDetached.get()); }); parent.addDetachListener(event -> { parentDetached.set(true); Assert.assertTrue(childDetached.get()); }); body.removeAllChildren(); Assert.assertTrue(parentDetached.get()); Assert.assertTrue(childDetached.get()); }
@Test public void attachDetach_elementMoved_bothEventsTriggered() { ShadowRoot bodyShadow = new UI().getElement().attachShadow(); Element parent = ElementFactory.createDiv(); Element child = ElementFactory.createDiv(); parent.appendChild(child); bodyShadow.appendChild(parent); AtomicBoolean attached = new AtomicBoolean(); AtomicBoolean detached = new AtomicBoolean(); child.addAttachListener(event -> { attached.set(true); Assert.assertTrue(detached.get()); }); child.addDetachListener(event -> { detached.set(true); Assert.assertFalse(attached.get()); }); bodyShadow.appendChild(child); Assert.assertTrue(attached.get()); Assert.assertTrue(detached.get()); }
@Test public void attachEvent_stateTreeCanFound() { ShadowRoot bodyShadow = new UI().getElement().attachShadow(); Element child = ElementFactory.createDiv(); AtomicInteger attached = new AtomicInteger(); child.addAttachListener(event -> { Assert.assertNotNull(event.getSource().getNode().getOwner()); Assert.assertNotEquals(NullOwner.get(), event.getSource().getNode().getOwner()); }); child.addAttachListener(event -> attached.incrementAndGet()); bodyShadow.appendChild(child); Assert.assertEquals(1, attached.get()); }
@Test public void detachEvent_stateTreeCanFound() { ShadowRoot bodyShadow = new UI().getElement().attachShadow(); Element child = ElementFactory.createDiv(); bodyShadow.appendChild(child); AtomicInteger detached = new AtomicInteger(); child.addDetachListener(event -> { Assert.assertNotNull(event.getSource().getNode().getOwner()); Assert.assertNotEquals(NullOwner.get(), event.getSource().getNode().getOwner()); }); child.addDetachListener(event -> detached.incrementAndGet()); bodyShadow.removeAllChildren(); Assert.assertEquals(1, detached.get()); }
@Test public void visitOnlyNode_hasDescendants_nodeVisitedAndNoDescendantsVisited() { TestNodeVisitor visitor = new TestNodeVisitor(false); Map<Node<?>, ElementType> map = new HashMap<>(); ShadowRoot subject = createHierarchy(map); ShadowRootStateProvider.get().visit(subject.getNode(), visitor); Assert.assertEquals(1, visitor.getVisited().size()); Assert.assertEquals(subject, visitor.getVisited().keySet().iterator().next()); Assert.assertEquals(null, visitor.getVisited().values().iterator().next()); }
@Test public void visitOnlyNode_hasDescendants_nodeAndDescendatnsAreVisited() { TestNodeVisitor visitor = new TestNodeVisitor(true); Map<Node<?>, ElementType> map = new HashMap<>(); ShadowRoot subject = createHierarchy(map); ShadowRootStateProvider.get().visit(subject.getNode(), visitor); Assert.assertTrue(map.size() > 1); Assert.assertEquals( "The collected descendants doesn't match expected descendatns", map, visitor.getVisited()); }