]> source.dussan.org Git - vaadin-framework.git/commitdiff
Merge of (#7842) to Vaadin 7. 05/605/2
authorAnna Koskinen <anna@vaadin.com>
Wed, 9 Jan 2013 13:51:52 +0000 (15:51 +0200)
committerAnna Koskinen <anna@vaadin.com>
Wed, 9 Jan 2013 13:51:52 +0000 (15:51 +0200)
Windows never opened to a new tab.

Change-Id: Ida874c55bbb00325edf49d4ebf27067d99d056b8

client/src/com/vaadin/client/ui/ui/UIConnector.java
server/src/com/vaadin/server/Page.java
server/src/com/vaadin/ui/LegacyWindow.java
uitest/src/com/vaadin/tests/components/window/LegacyWindowOpenTest.java [new file with mode: 0644]
uitest/src/com/vaadin/tests/components/window/PageOpenTest.java [new file with mode: 0644]

index 099cd5562e6292c0e26962dc8f03a086f61e0a16..85e75b943e78030af6eeac9b6a5d741653e5e0a3 100644 (file)
@@ -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++;
         }
index 18120ef34708c77e2bd569d79208cbe2bb07ed85..8737b478c3abca685dbb7864cafabd07d3ddc671 100644 (file)
@@ -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) .
      * <p>
      * 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.
      * </p>
      * 
@@ -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) .
+     * <p>
+     * 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
+     * <code>null</code> window name is also a special case.
+     * </p>
+     * <p>
+     * "", 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.
+     * </p>
+     * <p>
+     * "_blank" as {@code windowName} causes the URL to always be opened in a
+     * new window or tab (depends on the browser and browser settings).
+     * </p>
+     * <p>
+     * "_top" and "_parent" as {@code windowName} works as specified by the HTML
+     * standard.
+     * </p>
+     * <p>
+     * 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.
+     * </p>
+     * <p>
+     * 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.
+     * </p>
+     * 
+     * @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.
      * </p>
      * 
@@ -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();
     }
 
index 359f258c8d85ab2f802a8669fb1baa8139149521..1b66b608c1631eb6b08b4f6c7a754bdd051acbf2 100644 (file)
@@ -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.
+     * <p>
+     * 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
+     * <code>null</code> window name is also a special case.
+     * </p>
+     * <p>
+     * "", 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.
+     * </p>
+     * <p>
+     * "_blank" as {@code windowName} causes the resource to always be opened in
+     * a new window or tab (depends on the browser and browser settings).
+     * </p>
+     * <p>
+     * "_top" and "_parent" as {@code windowName} works as specified by the HTML
+     * standard.
+     * </p>
+     * <p>
+     * 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.
+     * </p>
+     * <p>
+     * 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.
+     * </p>
+     * <p>
+     * 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.
+     * </p>
+     * 
+     * @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 (file)
index 0000000..175c3f6
--- /dev/null
@@ -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 (file)
index 0000000..2dbc24c
--- /dev/null
@@ -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;
+    }
+
+}