From: Anna Koskinen Date: Wed, 9 Jan 2013 13:51:52 +0000 (+0200) Subject: Merge of (#7842) to Vaadin 7. X-Git-Tag: 7.0.0.rc1~51^2 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=058224f31198b2a56fd7fd52e9a767909b58cd79;p=vaadin-framework.git Merge of (#7842) to Vaadin 7. Windows never opened to a new tab. Change-Id: Ida874c55bbb00325edf49d4ebf27067d99d056b8 --- diff --git a/client/src/com/vaadin/client/ui/ui/UIConnector.java b/client/src/com/vaadin/client/ui/ui/UIConnector.java index 099cd5562e..85e75b943e 100644 --- a/client/src/com/vaadin/client/ui/ui/UIConnector.java +++ b/client/src/com/vaadin/client/ui/ui/UIConnector.java @@ -131,6 +131,11 @@ public class UIConnector extends AbstractSingleComponentContainerConnector }); } + private native void open(String url, String name) + /*-{ + $wnd.open(url, name); + }-*/; + @Override public void updateFromUIDL(final UIDL uidl, ApplicationConnection client) { ConnectorMap paintableMap = ConnectorMap.get(getConnection()); @@ -194,27 +199,35 @@ public class UIConnector extends AbstractSingleComponentContainerConnector VUI.goTo(url); } else { String options; - if (open.hasAttribute("border")) { - if (open.getStringAttribute("border").equals("minimal")) { - options = "menubar=yes,location=no,status=no"; + boolean alwaysAsPopup = true; + if (open.hasAttribute("popup")) { + alwaysAsPopup = open.getBooleanAttribute("popup"); + } + if (alwaysAsPopup) { + if (open.hasAttribute("border")) { + if (open.getStringAttribute("border").equals("minimal")) { + options = "menubar=yes,location=no,status=no"; + } else { + options = "menubar=no,location=no,status=no"; + } + } else { - options = "menubar=no,location=no,status=no"; + options = "resizable=yes,menubar=yes,toolbar=yes,directories=yes,location=yes,scrollbars=yes,status=yes"; } - } else { - options = "resizable=yes,menubar=yes,toolbar=yes,directories=yes,location=yes,scrollbars=yes,status=yes"; - } + if (open.hasAttribute("width")) { + int w = open.getIntAttribute("width"); + options += ",width=" + w; + } + if (open.hasAttribute("height")) { + int h = open.getIntAttribute("height"); + options += ",height=" + h; + } - if (open.hasAttribute("width")) { - int w = open.getIntAttribute("width"); - options += ",width=" + w; - } - if (open.hasAttribute("height")) { - int h = open.getIntAttribute("height"); - options += ",height=" + h; + Window.open(url, target, options); + } else { + open(url, target); } - - Window.open(url, target, options); } childIndex++; } diff --git a/server/src/com/vaadin/server/Page.java b/server/src/com/vaadin/server/Page.java index 18120ef347..8737b478c3 100644 --- a/server/src/com/vaadin/server/Page.java +++ b/server/src/com/vaadin/server/Page.java @@ -132,6 +132,8 @@ public class Page implements Serializable { */ private final BorderStyle border; + private final boolean tryToOpenAsPopup; + /** * Creates a new open resource. * @@ -145,10 +147,13 @@ public class Page implements Serializable { * The height of the target window * @param border * The border style of the target window + * @param tryToOpenAsPopup + * Should try to open as a pop-up */ private OpenResource(String url, String name, int width, int height, - BorderStyle border) { - this(new ExternalResource(url), name, width, height, border); + BorderStyle border, boolean tryToOpenAsPopup) { + this(new ExternalResource(url), name, width, height, border, + tryToOpenAsPopup); } /** @@ -164,14 +169,17 @@ public class Page implements Serializable { * The height of the target window * @param border * The border style of the target window + * @param tryToOpenAsPopup + * Should try to open as a pop-up */ private OpenResource(Resource resource, String name, int width, - int height, BorderStyle border) { + int height, BorderStyle border, boolean tryToOpenAsPopup) { this.resource = resource; this.name = name; this.width = width; this.height = height; this.border = border; + this.tryToOpenAsPopup = tryToOpenAsPopup; } /** @@ -188,6 +196,9 @@ public class Page implements Serializable { if (name != null && name.length() > 0) { target.addAttribute("name", name); } + if (!tryToOpenAsPopup) { + target.addAttribute("popup", tryToOpenAsPopup); + } if (width >= 0) { target.addAttribute("width", width); } @@ -636,7 +647,7 @@ public class Page implements Serializable { * the URI to show */ public void setLocation(String uri) { - openList.add(new OpenResource(uri, null, -1, -1, BORDER_DEFAULT)); + openList.add(new OpenResource(uri, null, -1, -1, BORDER_DEFAULT, false)); uI.markAsDirty(); } @@ -681,7 +692,8 @@ public class Page implements Serializable { } /** - * Opens the given URL in a window with the given name. + * Opens the given url in a window with the given name. Equivalent to + * {@link #open(String, String, boolean) open} (url, windowName, true) . *

* 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 @@ -717,7 +729,7 @@ public class Page implements Serializable { * browser's popup-blocker because the new browser window is opened when * processing a response from the server. To avoid this, you should instead * use {@link Link} for opening the window because browsers are more - * forgiving then the window is opened directly from a client-side click + * forgiving when the window is opened directly from a client-side click * event. *

* @@ -727,7 +739,62 @@ public class Page implements Serializable { * the name of the window. */ public void open(String url, String windowName) { - openList.add(new OpenResource(url, windowName, -1, -1, BORDER_DEFAULT)); + open(url, windowName, true); + } + + /** + * Opens the given url in a window with the given name. Equivalent to + * {@link #open(String, String, boolean) open} (url, windowName, true) . + *

+ * 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. + *

+ *

+ * Please note that opening a popup window in this way may be blocked by the + * browser's popup-blocker because the new browser window is opened when + * processing a response from the server. To avoid this, you should instead + * use {@link Link} for opening the window because browsers are more + * forgiving when the window is opened directly from a client-side click + * event. + *

+ * + * @param url + * the URL to open. + * @param windowName + * the name of the window. + * @param tryToOpenAsPopup + * Whether to try to force the resource to be opened in a new + * window + */ + public void open(String url, String windowName, boolean tryToOpenAsPopup) { + openList.add(new OpenResource(url, windowName, -1, -1, BORDER_DEFAULT, + tryToOpenAsPopup)); uI.markAsDirty(); } @@ -740,7 +807,7 @@ public class Page implements Serializable { * browser's popup-blocker because the new browser window is opened when * processing a response from the server. To avoid this, you should instead * use {@link Link} for opening the window because browsers are more - * forgiving then the window is opened directly from a client-side click + * forgiving when the window is opened directly from a client-side click * event. *

* @@ -757,7 +824,8 @@ public class Page implements Serializable { */ public void open(String url, String windowName, int width, int height, BorderStyle border) { - openList.add(new OpenResource(url, windowName, width, height, border)); + openList.add(new OpenResource(url, windowName, width, height, border, + true)); uI.markAsDirty(); } @@ -771,7 +839,21 @@ public class Page implements Serializable { public void open(Resource resource, String windowName, int width, int height, BorderStyle border) { openList.add(new OpenResource(resource, windowName, width, height, - border)); + border, true)); + uI.markAsDirty(); + } + + /** + * @deprecated As of 7.0, only retained to maintain compatibility with + * LegacyWindow.open methods. See documentation for + * {@link LegacyWindow#open(Resource, String, boolean)} for + * discussion about replacing API. + */ + @Deprecated + public void open(Resource resource, String windowName, + boolean tryToOpenAsPopup) { + openList.add(new OpenResource(resource, windowName, -1, -1, + BORDER_DEFAULT, tryToOpenAsPopup)); uI.markAsDirty(); } diff --git a/server/src/com/vaadin/ui/LegacyWindow.java b/server/src/com/vaadin/ui/LegacyWindow.java index 359f258c8d..1b66b608c1 100644 --- a/server/src/com/vaadin/ui/LegacyWindow.java +++ b/server/src/com/vaadin/ui/LegacyWindow.java @@ -19,7 +19,6 @@ import java.net.MalformedURLException; import java.net.URL; import com.vaadin.server.LegacyApplication; -import com.vaadin.server.Page; import com.vaadin.server.Page.BrowserWindowResizeEvent; import com.vaadin.server.Page.BrowserWindowResizeListener; import com.vaadin.server.Resource; @@ -169,7 +168,7 @@ public class LegacyWindow extends UI { */ @Deprecated public void open(Resource resource) { - open(resource, null); + open(resource, null, false); } /* ********************************************************************* */ @@ -221,7 +220,68 @@ public class LegacyWindow extends UI { */ @Deprecated public void open(Resource resource, String windowName) { - open(resource, windowName, -1, -1, Page.BORDER_DEFAULT); + open(resource, windowName, true); + } + + /** + * Opens the given resource in a window with the given name and optionally + * tries to force the resource to open in a new window instead of a new tab. + *

+ * 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 resource 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 resource). This can speed up + * the opening of a resource, but it might also put the client side into an + * inconsistent state if the window content is not completely replaced e.g., + * if the resource is downloaded instead of displayed in the browser. + *

+ *

+ * "_blank" as {@code windowName} causes the resource 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 resource 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. + *

+ *

+ * If {@code windowName} is set to open the resource in a new window or tab + * and {@code tryToOpenAsPopup} is true, this method attempts to force the + * browser to open a new window instead of a tab. NOTE: This is a + * best-effort attempt and may not work reliably with all browsers and + * different pop-up preferences. With most browsers using default settings, + * {@code tryToOpenAsPopup} works properly. + *

+ *

+ * As of Vaadin 7.0.0, the functionality for opening a Resource in a Page + * has been replaced with similar methods based on a String URL. This is + * because the usage of Resource is problematic with memory management and + * with security features in some browsers. Is is recommended to instead use + * {@link Link} for starting downloads. + *

+ * + * @param resource + * the resource. + * @param windowName + * the name of the window. + * @param tryToOpenAsPopup + * Whether to try to force the resource to be opened in a new + * window + * */ + public void open(Resource resource, String windowName, + boolean tryToOpenAsPopup) { + getPage().open(resource, windowName, tryToOpenAsPopup); } /** diff --git a/uitest/src/com/vaadin/tests/components/window/LegacyWindowOpenTest.java b/uitest/src/com/vaadin/tests/components/window/LegacyWindowOpenTest.java new file mode 100644 index 0000000000..175c3f6d8a --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/window/LegacyWindowOpenTest.java @@ -0,0 +1,74 @@ +package com.vaadin.tests.components.window; + +import com.vaadin.server.ExternalResource; +import com.vaadin.tests.TestForWindowOpen; +import com.vaadin.tests.components.TestBase; +import com.vaadin.ui.Button; +import com.vaadin.ui.Button.ClickEvent; +import com.vaadin.ui.LegacyWindow; + +public class LegacyWindowOpenTest extends TestBase { + + final ExternalResource r = new ExternalResource("http://www.google.com"); + + @Override + protected void setup() { + final LegacyWindow win = getMainWindow(); + + addComponent(new TestForWindowOpen()); + + addComponent(new Button("Window.open _blank always as popup", + new Button.ClickListener() { + public void buttonClick(ClickEvent event) { + win.open(r, "_blank", true); + } + })); + + addComponent(new Button("Window.open _blank NOT always as popup", + new Button.ClickListener() { + public void buttonClick(ClickEvent event) { + win.open(r, "_blank", false); + } + })); + + addComponent(new Button("Window.open _new always as popup", + new Button.ClickListener() { + public void buttonClick(ClickEvent event) { + win.open(r, "_new", true); + } + })); + + addComponent(new Button("Window.open _new NOT always as popup", + new Button.ClickListener() { + public void buttonClick(ClickEvent event) { + win.open(r, "_new", false); + } + })); + addComponent(new Button( + "Window execute Javascript window.open(www.google.com, _blank)", + new Button.ClickListener() { + public void buttonClick(ClickEvent event) { + win.executeJavaScript("window.open(\"http://www.google.com\", \"_blank\");"); + } + })); + addComponent(new Button( + "Window execute Javascript window.open(www.google.com, _blank, resizable=yes,menubar=yes,toolbar=yes,directories=yes,location=yes,scrollbars=yes,status=yes)", + new Button.ClickListener() { + public void buttonClick(ClickEvent event) { + win.executeJavaScript("window.open(\"http://www.google.com\", \"_blank\", \"resizable=yes,menubar=yes,toolbar=yes,directories=yes,location=yes,scrollbars=yes,status=yes\");"); + } + })); + + } + + @Override + protected String getDescription() { + return "Windows never opened to a new tab"; + } + + @Override + protected Integer getTicketNumber() { + return 7842; + } + +} diff --git a/uitest/src/com/vaadin/tests/components/window/PageOpenTest.java b/uitest/src/com/vaadin/tests/components/window/PageOpenTest.java new file mode 100644 index 0000000000..2dbc24cb66 --- /dev/null +++ b/uitest/src/com/vaadin/tests/components/window/PageOpenTest.java @@ -0,0 +1,81 @@ +package com.vaadin.tests.components.window; + +import com.vaadin.server.Page; +import com.vaadin.server.VaadinRequest; +import com.vaadin.tests.TestForWindowOpen; +import com.vaadin.tests.components.AbstractTestUI; +import com.vaadin.ui.Button; +import com.vaadin.ui.Button.ClickEvent; +import com.vaadin.ui.JavaScript; + +public class PageOpenTest extends AbstractTestUI { + + final String url = "http://www.google.com"; + + @Override + protected void setup(VaadinRequest request) { + final Page page = getPage(); + + addComponent(new TestForWindowOpen()); + + addComponent(new Button("Page.open _blank always as popup", + new Button.ClickListener() { + public void buttonClick(ClickEvent event) { + page.open(url, "_blank", true); + } + })); + + addComponent(new Button("Page.open _blank NOT always as popup", + new Button.ClickListener() { + public void buttonClick(ClickEvent event) { + page.open(url, "_blank", false); + } + })); + + addComponent(new Button("Page.open _new always as popup", + new Button.ClickListener() { + public void buttonClick(ClickEvent event) { + page.open(url, "_new", true); + } + })); + + addComponent(new Button("Page.open _new NOT always as popup", + new Button.ClickListener() { + public void buttonClick(ClickEvent event) { + page.open(url, "_new", false); + } + })); + addComponent(new Button( + "Execute Javascript window.open(www.google.com, _blank)", + new Button.ClickListener() { + public void buttonClick(ClickEvent event) { + JavaScript + .getCurrent() + .execute( + "window.open(\"http://www.google.com\", \"_blank\");"); + } + })); + addComponent(new Button( + "Execute Javascript window.open(www.google.com, _blank, resizable=yes,menubar=yes,toolbar=yes,directories=yes,location=yes,scrollbars=yes,status=yes)", + new Button.ClickListener() { + public void buttonClick(ClickEvent event) { + JavaScript + .getCurrent() + .execute( + "window.open(\"http://www.google.com\", \"_blank\", \"resizable=yes,menubar=yes,toolbar=yes,directories=yes,location=yes,scrollbars=yes,status=yes\");"); + } + })); + + } + + @Override + protected String getTestDescription() { + return "Windows never opened to a new tab"; + } + + @Override + protected Integer getTicketNumber() { + return 7842; + } + +}