From cf00dfdd7ecbfd5145487248b73c39de760fb178 Mon Sep 17 00:00:00 2001 From: sahalsaad Date: Sat, 2 Mar 2019 16:59:39 +0800 Subject: [PATCH] Implement open and setLocation method to Page. (#4869) --- .../com/vaadin/flow/component/page/Page.java | 91 +++++++++++++++++-- .../com/vaadin/flow/uitest/ui/PageView.java | 22 ++++- .../com/vaadin/flow/uitest/ui/PageIT.java | 27 +++++- 3 files changed, 129 insertions(+), 11 deletions(-) diff --git a/flow-server/src/main/java/com/vaadin/flow/component/page/Page.java b/flow-server/src/main/java/com/vaadin/flow/component/page/Page.java index 63096d19c52..d038e1257ab 100644 --- a/flow-server/src/main/java/com/vaadin/flow/component/page/Page.java +++ b/flow-server/src/main/java/com/vaadin/flow/component/page/Page.java @@ -15,14 +15,6 @@ */ package com.vaadin.flow.component.page; -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.Serializable; -import java.nio.charset.StandardCharsets; -import java.util.Objects; - import com.vaadin.flow.component.ClientCallable; import com.vaadin.flow.component.Component; import com.vaadin.flow.component.ComponentEvent; @@ -38,6 +30,15 @@ import com.vaadin.flow.shared.ui.Dependency.Type; import com.vaadin.flow.shared.ui.LoadMode; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Serializable; +import java.net.URI; +import java.nio.charset.StandardCharsets; +import java.util.Objects; + /** * Represents the web page open in the browser, containing the UI it is * connected to. @@ -389,6 +390,80 @@ public Registration addBrowserWindowResizeListener( return resizeReceiver.addListener(resizeListener); } + /** + * Opens the given url in a new tab. + * + * @param url + * the URL to open. + */ + public void open(String url) { + open(url, "_blank"); + } + + /** + * Opens the given URL in a window with the given name. + *

+ * The supplied {@code windowName} is used as the target name in a + * window.open call in the client. This means that special values such as + * "_blank", "_self", "_top", "_parent" have special meaning. An empty or + * null window name is also a special case. + *

+ *

+ * "", null and "_self" as {@code windowName} all causes the URL to be + * opened in the current window, replacing any old contents. For + * downloadable content you should avoid "_self" as "_self" causes the + * client to skip rendering of any other changes as it considers them + * irrelevant (the page will be replaced by the response from the URL). This + * can speed up the opening of a URL, but it might also put the client side + * into an inconsistent state if the window content is not completely + * replaced e.g., if the URL is downloaded instead of displayed in the + * browser. + *

+ *

+ * "_blank" as {@code windowName} causes the URL to always be opened in a + * new window or tab (depends on the browser and browser settings). + *

+ *

+ * "_top" and "_parent" as {@code windowName} works as specified by the HTML + * standard. + *

+ *

+ * Any other {@code windowName} will open the URL in a window with that + * name, either by opening a new window/tab in the browser or by replacing + * the contents of an existing window with that name. + *

+ * + * @param url + * the URL to open. + * @param windowName + * the name of the window. + */ + private void open(String url, String windowName) { + executeJavaScript("window.open($0, $1)", url, windowName); + } + + /** + * Navigates this page to the given URI. The contents of this page in the + * browser is replaced with whatever is returned for the given URI. + * + * @param uri + * the URI to show + */ + public void setLocation(String uri) { + open(uri, "_self"); + } + + /** + * Navigates this page to the given URI. The contents of this page in the + * browser is replaced with whatever is returned for the given URI. + * + * @param uri + * the URI to show + */ + public void setLocation(URI uri) { + setLocation(uri.toString()); + } + private static class LazyJsLoader implements Serializable { private static final String JS_FILE_NAME = "windowResizeListener.js"; diff --git a/flow-tests/test-root-context/src/main/java/com/vaadin/flow/uitest/ui/PageView.java b/flow-tests/test-root-context/src/main/java/com/vaadin/flow/uitest/ui/PageView.java index b67009ed414..3d9237075b9 100644 --- a/flow-tests/test-root-context/src/main/java/com/vaadin/flow/uitest/ui/PageView.java +++ b/flow-tests/test-root-context/src/main/java/com/vaadin/flow/uitest/ui/PageView.java @@ -2,10 +2,14 @@ import com.vaadin.flow.component.html.Div; import com.vaadin.flow.component.html.Input; +import com.vaadin.flow.server.VaadinRequest; +import com.vaadin.flow.server.VaadinServletRequest; import com.vaadin.flow.uitest.servlet.ViewTestLayout; import com.vaadin.flow.router.Route; import com.vaadin.flow.router.BeforeEnterEvent; +import javax.servlet.http.HttpServletRequest; + @Route(value = "com.vaadin.flow.uitest.ui.PageView", layout = ViewTestLayout.class) public class PageView extends AbstractDivView { @@ -38,7 +42,23 @@ public void beforeEnter(BeforeEnterEvent event) { getPage().reload(); }); - add(input, updateButton, overrideButton, reloadButton); + VaadinServletRequest request = (VaadinServletRequest) VaadinRequest.getCurrent(); + HttpServletRequest httpServletRequest = request.getHttpServletRequest(); + String url = httpServletRequest.getRequestURI() + .replace(PageView.class.getName(), BaseHrefView.class.getName()); + + Div setLocationButton = new Div(); + setLocationButton.setId("setLocation"); + setLocationButton.setText("Set page location"); + setLocationButton.addClickListener(e -> getPage().setLocation(url)); + + Div openButton = new Div(); + openButton.setId("open"); + openButton.setText("Open url in a new tab"); + openButton.addClickListener(e -> getPage().open(url)); + + add(input, updateButton, overrideButton, reloadButton, + setLocationButton, openButton); } } diff --git a/flow-tests/test-root-context/src/test/java/com/vaadin/flow/uitest/ui/PageIT.java b/flow-tests/test-root-context/src/test/java/com/vaadin/flow/uitest/ui/PageIT.java index c574876a8d7..eb6d31aee47 100644 --- a/flow-tests/test-root-context/src/test/java/com/vaadin/flow/uitest/ui/PageIT.java +++ b/flow-tests/test-root-context/src/test/java/com/vaadin/flow/uitest/ui/PageIT.java @@ -1,12 +1,14 @@ package com.vaadin.flow.uitest.ui; +import com.vaadin.flow.component.html.testbench.InputTextElement; +import com.vaadin.flow.testutil.ChromeBrowserTest; +import org.hamcrest.Matchers; import org.junit.Assert; import org.junit.Test; import org.openqa.selenium.By; import org.openqa.selenium.Keys; -import com.vaadin.flow.component.html.testbench.InputTextElement; -import com.vaadin.flow.testutil.ChromeBrowserTest; +import java.util.ArrayList; public class PageIT extends ChromeBrowserTest { @@ -66,4 +68,25 @@ public void testReload() { input = $(InputTextElement.class).id("input"); Assert.assertEquals("", input.getValue()); } + + @Test + public void testSetLocation() { + open(); + + findElement(By.id("setLocation")).click(); + Assert.assertThat(getDriver().getCurrentUrl(), + Matchers.endsWith(BaseHrefView.class.getName())); + } + + @Test + public void testOpenUrlInNewTab() { + open(); + + findElement(By.id("open")).click(); + ArrayList tabs = new ArrayList<>(getDriver().getWindowHandles()); + Assert.assertThat( + getDriver().switchTo().window(tabs.get(1)).getCurrentUrl(), + Matchers.endsWith(BaseHrefView.class.getName()) + ); + } }