diff --git a/flow-server/src/main/java/com/vaadin/flow/component/UI.java b/flow-server/src/main/java/com/vaadin/flow/component/UI.java index 5220403fb14..c1dd3d911f1 100644 --- a/flow-server/src/main/java/com/vaadin/flow/component/UI.java +++ b/flow-server/src/main/java/com/vaadin/flow/component/UI.java @@ -873,6 +873,17 @@ public Page getPage() { return page; } + /** + * Gets the wrapper element for this UI when client-side routing is enabled. + * This element is used as a container for route components when using + * client-side routing. + * + * @return the wrapper element, or {@code null} if server-side routing is used + */ + public Element getWrapperElement() { + return wrapperElement; + } + /** * Updates this UI to show the view corresponding to the given navigation * target. @@ -1673,7 +1684,7 @@ public List getActiveRouterTargetsChain() { window.dispatchEvent(new CustomEvent('vaadin-router-go', { detail: url})); """; - public Element wrapperElement; + private Element wrapperElement; private NavigationState clientViewNavigationState; private boolean navigationInProgress = false; diff --git a/flow-server/src/main/java/com/vaadin/flow/component/internal/UIInternalUpdater.java b/flow-server/src/main/java/com/vaadin/flow/component/internal/UIInternalUpdater.java index cbaf6de2616..c6967b2f8a0 100644 --- a/flow-server/src/main/java/com/vaadin/flow/component/internal/UIInternalUpdater.java +++ b/flow-server/src/main/java/com/vaadin/flow/component/internal/UIInternalUpdater.java @@ -43,7 +43,7 @@ public interface UIInternalUpdater extends Serializable { */ default void updateRoot(UI ui, HasElement oldRoot, HasElement newRoot) { - Element wrapperElement = ui.wrapperElement; + Element wrapperElement = ui.getWrapperElement(); // server-side routing if (wrapperElement == null) { Element uiElement = ui.getElement(); diff --git a/flow-server/src/main/java/com/vaadin/flow/router/BeforeLeaveEvent.java b/flow-server/src/main/java/com/vaadin/flow/router/BeforeLeaveEvent.java index 3e3666e1131..249a9e74449 100644 --- a/flow-server/src/main/java/com/vaadin/flow/router/BeforeLeaveEvent.java +++ b/flow-server/src/main/java/com/vaadin/flow/router/BeforeLeaveEvent.java @@ -77,9 +77,9 @@ public void proceed() { + "Use UI.access() to execute any UI related code from a separate thread properly"); } - if (event.getUI().wrapperElement != null) { + if (event.getUI().getWrapperElement() != null) { // See UI.SERVER_CONNECTED and acknowledgeClient. - event.getUI().wrapperElement + event.getUI().getWrapperElement() .executeJs("this.serverConnected($0)", false); } @@ -97,9 +97,9 @@ public void proceed() { public void cancel() { BeforeLeaveEvent.this.continueNavigationAction = null; if (handler != null && event != null - && event.getUI().wrapperElement != null) { + && event.getUI().getWrapperElement() != null) { // See UI.SERVER_CONNECTED and cancelClient. - event.getUI().wrapperElement + event.getUI().getWrapperElement() .executeJs("this.serverConnected($0)", true); } } diff --git a/flow-server/src/test/java/com/vaadin/flow/component/internal/JavaScriptBootstrapUITest.java b/flow-server/src/test/java/com/vaadin/flow/component/internal/JavaScriptBootstrapUITest.java index 12d08f657ed..f00538f59cc 100644 --- a/flow-server/src/test/java/com/vaadin/flow/component/internal/JavaScriptBootstrapUITest.java +++ b/flow-server/src/test/java/com/vaadin/flow/component/internal/JavaScriptBootstrapUITest.java @@ -225,25 +225,25 @@ public void cleanup() { public void should_allow_navigation() { ui.browserNavigate( new BrowserNavigateEvent(ui, true, "/clean", "", "", null, "")); - assertEquals(Tag.HEADER, ui.wrapperElement.getChild(0).getTag()); + assertEquals(Tag.HEADER, ui.getWrapperElement().getChild(0).getTag()); assertEquals(Tag.H2, - ui.wrapperElement.getChild(0).getChild(0).getTag()); + ui.getWrapperElement().getChild(0).getChild(0).getTag()); // Dirty view is allowed after clean view ui.browserNavigate( new BrowserNavigateEvent(ui, true, "/dirty", "", "", null, "")); - assertEquals(Tag.SPAN, ui.wrapperElement.getChild(0).getTag()); + assertEquals(Tag.SPAN, ui.getWrapperElement().getChild(0).getTag()); assertEquals(Tag.H1, - ui.wrapperElement.getChild(0).getChild(0).getTag()); + ui.getWrapperElement().getChild(0).getChild(0).getTag()); } @Test public void should_navigate_when_endingSlash() { ui.browserNavigate(new BrowserNavigateEvent(ui, true, "/clean/", "", "", null, "")); - assertEquals(Tag.HEADER, ui.wrapperElement.getChild(0).getTag()); + assertEquals(Tag.HEADER, ui.getWrapperElement().getChild(0).getTag()); assertEquals(Tag.H2, - ui.wrapperElement.getChild(0).getChild(0).getTag()); + ui.getWrapperElement().getChild(0).getChild(0).getTag()); } @Test @@ -309,50 +309,50 @@ public void addComponent_clientSideRouterAndNavigation_componentsRemain() { public void should_prevent_navigation_on_dirty() { ui.browserNavigate( new BrowserNavigateEvent(ui, true, "/dirty", "", "", null, "")); - assertEquals(Tag.SPAN, ui.wrapperElement.getChild(0).getTag()); + assertEquals(Tag.SPAN, ui.getWrapperElement().getChild(0).getTag()); assertEquals(Tag.H1, - ui.wrapperElement.getChild(0).getChild(0).getTag()); + ui.getWrapperElement().getChild(0).getChild(0).getTag()); // clean view cannot be rendered after dirty ui.browserNavigate( new BrowserNavigateEvent(ui, true, "/clean", "", "", null, "")); assertEquals(Tag.H1, - ui.wrapperElement.getChild(0).getChild(0).getTag()); + ui.getWrapperElement().getChild(0).getChild(0).getTag()); // an error route cannot be rendered after dirty ui.browserNavigate( new BrowserNavigateEvent(ui, true, "/errr", "", "", null, "")); assertEquals(Tag.H1, - ui.wrapperElement.getChild(0).getChild(0).getTag()); + ui.getWrapperElement().getChild(0).getChild(0).getTag()); } @Test public void should_remove_content_on_leaveNavigation() { ui.browserNavigate( new BrowserNavigateEvent(ui, true, "/clean", "", "", null, "")); - assertEquals(Tag.HEADER, ui.wrapperElement.getChild(0).getTag()); + assertEquals(Tag.HEADER, ui.getWrapperElement().getChild(0).getTag()); assertEquals(Tag.H2, - ui.wrapperElement.getChild(0).getChild(0).getTag()); + ui.getWrapperElement().getChild(0).getChild(0).getTag()); ui.leaveNavigation( new BrowserLeaveNavigationEvent(ui, true, "/client-view", "")); - assertEquals(0, ui.wrapperElement.getChildCount()); + assertEquals(0, ui.getWrapperElement().getChildCount()); } @Test public void should_keep_content_on_leaveNavigation_postpone() { ui.browserNavigate( new BrowserNavigateEvent(ui, true, "/dirty", "", "", null, "")); - assertEquals(Tag.SPAN, ui.wrapperElement.getChild(0).getTag()); + assertEquals(Tag.SPAN, ui.getWrapperElement().getChild(0).getTag()); assertEquals(Tag.H1, - ui.wrapperElement.getChild(0).getChild(0).getTag()); + ui.getWrapperElement().getChild(0).getChild(0).getTag()); ui.leaveNavigation( new BrowserLeaveNavigationEvent(ui, true, "/client-view", "")); - assertEquals(Tag.SPAN, ui.wrapperElement.getChild(0).getTag()); + assertEquals(Tag.SPAN, ui.getWrapperElement().getChild(0).getTag()); assertEquals(Tag.H1, - ui.wrapperElement.getChild(0).getChild(0).getTag()); + ui.getWrapperElement().getChild(0).getChild(0).getTag()); } @Test @@ -384,9 +384,9 @@ public void should_handle_forward_to_server_side_view_on_beforeEnter_and_update_ ui.browserNavigate(new BrowserNavigateEvent(ui, true, "/forwardToServerSideViewOnBeforeEnter", "", "", null, "")); - assertEquals(Tag.HEADER, ui.wrapperElement.getChild(0).getTag()); + assertEquals(Tag.HEADER, ui.getWrapperElement().getChild(0).getTag()); assertEquals(Tag.H2, - ui.wrapperElement.getChild(0).getChild(0).getTag()); + ui.getWrapperElement().getChild(0).getChild(0).getTag()); ui.navigate("product"); assertEquals("my-product", ui.getInternals().getTitle()); @@ -394,17 +394,17 @@ public void should_handle_forward_to_server_side_view_on_beforeEnter_and_update_ ui.getChildren().findFirst().get().getId().get()); ui.navigate("forwardToServerSideViewOnBeforeEnter"); - assertEquals(Tag.HEADER, ui.wrapperElement.getChild(0).getTag()); + assertEquals(Tag.HEADER, ui.getWrapperElement().getChild(0).getTag()); assertEquals(Tag.H2, - ui.wrapperElement.getChild(0).getChild(0).getTag()); + ui.getWrapperElement().getChild(0).getChild(0).getTag()); } @Test public void should_show_error_page() { ui.browserNavigate( new BrowserNavigateEvent(ui, true, "/err", "", "", null, "")); - assertEquals(Tag.DIV, ui.wrapperElement.getChild(0).getTag()); - assertTrue(ui.wrapperElement.toString().contains("Available routes:")); + assertEquals(Tag.DIV, ui.getWrapperElement().getChild(0).getTag()); + assertTrue(ui.getWrapperElement().toString().contains("Available routes:")); } @Test @@ -501,9 +501,9 @@ public void should_not_notify_clientRoute_when_navigatingToTheSame() { public void server_should_not_doClientRoute_when_navigatingToServer() { ui.browserNavigate( new BrowserNavigateEvent(ui, true, "/clean", "", "", null, "")); - assertEquals(Tag.HEADER, ui.wrapperElement.getChild(0).getTag()); + assertEquals(Tag.HEADER, ui.getWrapperElement().getChild(0).getTag()); assertEquals(Tag.H2, - ui.wrapperElement.getChild(0).getChild(0).getTag()); + ui.getWrapperElement().getChild(0).getChild(0).getTag()); ui = Mockito.spy(ui); Page page = mockPage(); @@ -515,7 +515,7 @@ public void server_should_not_doClientRoute_when_navigatingToServer() { // Dirty view is allowed after clean view ui.navigate("dirty"); // A server navigation happens - assertEquals(Tag.SPAN, ui.wrapperElement.getChild(0).getTag()); + assertEquals(Tag.SPAN, ui.getWrapperElement().getChild(0).getTag()); Mockito.verify(page).executeJs(execJs.capture(), execArg.capture()); boolean reactEnabled = ui.getSession().getConfiguration()