From 5ed529dfe9ce6f81975cb1072aaca974e63e4b26 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Leif=20=C3=85strand?= Date: Thu, 29 Nov 2012 14:39:51 +0200 Subject: [PATCH] Add fragment and parameter support to BrowserWindowOpener (#10093) Change-Id: I32577503ae4d85c80579f9544cdb61ab9788ef23 --- .../BrowserWindowOpenerConnector.java | 37 ++++++ .../vaadin/server/BrowserWindowOpener.java | 107 ++++++++++++++++++ .../shared/ui/BrowserWindowOpenerState.java | 7 ++ .../extensions/BrowserPopupExtensionTest.java | 26 ++++- 4 files changed, 174 insertions(+), 3 deletions(-) diff --git a/client/src/com/vaadin/client/extensions/BrowserWindowOpenerConnector.java b/client/src/com/vaadin/client/extensions/BrowserWindowOpenerConnector.java index 63915af1bd..4222ec5418 100644 --- a/client/src/com/vaadin/client/extensions/BrowserWindowOpenerConnector.java +++ b/client/src/com/vaadin/client/extensions/BrowserWindowOpenerConnector.java @@ -16,10 +16,14 @@ package com.vaadin.client.extensions; +import java.util.Map.Entry; + import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.ClickHandler; +import com.google.gwt.http.client.URL; import com.google.gwt.user.client.Window; import com.google.gwt.user.client.ui.Widget; +import com.vaadin.client.ApplicationConnection; import com.vaadin.client.ComponentConnector; import com.vaadin.client.ServerConnector; import com.vaadin.server.BrowserWindowOpener; @@ -51,8 +55,41 @@ public class BrowserWindowOpenerConnector extends AbstractExtensionConnector @Override public void onClick(ClickEvent event) { String url = getResourceUrl(BrowserWindowOpenerState.locationResource); + url = addParmatersAndFragment(url); if (url != null) { Window.open(url, getState().target, getState().features); } } + + private String addParmatersAndFragment(String url) { + if (url == null) { + return null; + } + + if (!getState().parameters.isEmpty()) { + StringBuilder params = new StringBuilder(); + for (Entry entry : getState().parameters.entrySet()) { + if (params.length() != 0) { + params.append('&'); + } + params.append(URL.encodeQueryString(entry.getKey())); + params.append('='); + + String value = entry.getValue(); + if (value != null) { + params.append(URL.encodeQueryString(value)); + } + } + + url = ApplicationConnection + .addGetParameters(url, params.toString()); + } + + if (getState().uriFragment != null) { + // Replace previous fragment or just add to the end of the url + url = url.replaceFirst("#.*|$", "#" + getState().uriFragment); + } + + return url; + } } diff --git a/server/src/com/vaadin/server/BrowserWindowOpener.java b/server/src/com/vaadin/server/BrowserWindowOpener.java index 3ed039887c..3b031d6463 100644 --- a/server/src/com/vaadin/server/BrowserWindowOpener.java +++ b/server/src/com/vaadin/server/BrowserWindowOpener.java @@ -16,6 +16,9 @@ package com.vaadin.server; +import java.util.Collections; +import java.util.Set; + import com.vaadin.shared.ApplicationConstants; import com.vaadin.shared.ui.BrowserWindowOpenerState; import com.vaadin.ui.AbstractComponent; @@ -196,4 +199,108 @@ public class BrowserWindowOpener extends AbstractExtension { return "popup/" + uiClass.getSimpleName(); } + /** + * Sets a URI fragment that will be added to the URI opened in the window. + * If the window is opened to contain a Vaadin UI, the fragment will be + * available using {@link Page#getUriFragment()} on the Page instance of the + * new UI. + *

+ * The default value is null. + * + * @param uriFragment + * the URI fragment string that should be included in the opened + * URI, or null to preserve the original fragment of + * the URI. + */ + public void setUriFragment(String uriFragment) { + getState().uriFragment = uriFragment; + } + + /** + * Gets that URI fragment configured for opened windows. + * + * @return the URI fragment string, or null if no fragment is + * configured. + * + * @see #setUriFragment(String) + */ + public String getUriFragment() { + return getState().uriFragment; + } + + /** + * Sets a parameter that will be added to the query string of the opened + * URI. If the window is opened to contain a Vaadin UI, the parameter will + * be available using {@link VaadinRequest#getParameter(String)} e.g. using + * the request instance passed to {@link UI#init(VaadinRequest)}. + *

+ * Setting a parameter with the same name as a previously set parameter will + * replace the previous value. + * + * @param name + * the name of the parameter to add, not null + * @param value + * the value of the parameter to add, not null + * + * @see #removeParameter(String) + * @see #getParameterNames() + * @see #getParameter(String) + */ + public void setParameter(String name, String value) { + if (name == null || value == null) { + throw new IllegalArgumentException("Null not allowed"); + } + getState().parameters.put(name, value); + } + + /** + * Removes a parameter that has been set using + * {@link #setParameter(String, String)}. Removing a parameter that has not + * been set has no effect. + * + * @param name + * the name of the parameter to remove, not null + * + * @see #setParameter(String, String) + */ + public void removeParameter(String name) { + if (name == null) { + throw new IllegalArgumentException("Null not allowed"); + } + getState().parameters.remove(name); + } + + /** + * Gets the names of all parameters set using + * {@link #setParameter(String, String)}. + * + * @return an unmodifiable set of parameter names + * + * @see #setParameter(String, String) + * @see #getParameter(String) + */ + public Set getParameterNames() { + return Collections.unmodifiableSet(getState().parameters.keySet()); + } + + /** + * Gets the value of a parameter set using + * {@link #setParameter(String, String)}. If there is no parameter with the + * given name, null is returned. + * + * @param name + * the name of the parameter to get, not null + * @return the value of the parameter, or null there is no + * parameter + * + * @see #setParameter(String, String) + * @see #getParameter(String) + */ + public String getParameter(String name) { + if (name == null) { + throw new IllegalArgumentException("Null not allowed"); + } + return getState().parameters.get(name); + } + } diff --git a/shared/src/com/vaadin/shared/ui/BrowserWindowOpenerState.java b/shared/src/com/vaadin/shared/ui/BrowserWindowOpenerState.java index 95e053b925..931189f95c 100644 --- a/shared/src/com/vaadin/shared/ui/BrowserWindowOpenerState.java +++ b/shared/src/com/vaadin/shared/ui/BrowserWindowOpenerState.java @@ -16,6 +16,9 @@ package com.vaadin.shared.ui; +import java.util.HashMap; +import java.util.Map; + import com.vaadin.shared.AbstractComponentState; public class BrowserWindowOpenerState extends AbstractComponentState { @@ -25,4 +28,8 @@ public class BrowserWindowOpenerState extends AbstractComponentState { public String features; + public String uriFragment; + + public Map parameters = new HashMap(); + } diff --git a/uitest/src/com/vaadin/tests/extensions/BrowserPopupExtensionTest.java b/uitest/src/com/vaadin/tests/extensions/BrowserPopupExtensionTest.java index 196592d376..732b1aca74 100644 --- a/uitest/src/com/vaadin/tests/extensions/BrowserPopupExtensionTest.java +++ b/uitest/src/com/vaadin/tests/extensions/BrowserPopupExtensionTest.java @@ -33,9 +33,19 @@ import com.vaadin.ui.HorizontalLayout; import com.vaadin.ui.Label; import com.vaadin.ui.Link; import com.vaadin.ui.NativeButton; +import com.vaadin.ui.UI; public class BrowserPopupExtensionTest extends AbstractTestUI { + public static class ShowParamsUI extends UI { + @Override + protected void init(VaadinRequest request) { + setContent(new Label("Query: " + + getPage().getLocation().getRawQuery() + ", Fragment: " + + getPage().getLocation().getFragment())); + } + } + @Override protected void setup(VaadinRequest request) { List> components = new ArrayList>(); @@ -44,7 +54,7 @@ public class BrowserPopupExtensionTest extends AbstractTestUI { components.add(Link.class); components.add(CssLayout.class); components.add(Label.class); - addComponents(components, "http://vaadin.com/download/nightly/"); + addComponents(components, "/statictestfiles/static.html"); Button uiClassButton = new Button("Open UI class"); new BrowserWindowOpener(ReopenPopupView.class).extend(uiClassButton); @@ -55,12 +65,22 @@ public class BrowserPopupExtensionTest extends AbstractTestUI { .extend(uiWithPath); addComponent(uiWithPath); - Button withPopupFeaturesButton = new Button("Open with features"); + Button withPopupFeaturesButton = new Button( + "Open with features and fragment"); BrowserWindowOpener featuresPopup = new BrowserWindowOpener( - "http://vaadin.com/download/nightly/"); + "/statictestfiles/static.html#originalfragment"); featuresPopup.setFeatures("width=400,height=400"); featuresPopup.extend(withPopupFeaturesButton); + featuresPopup.setUriFragment("myFragment"); addComponent(withPopupFeaturesButton); + + Button withParametersButton = new Button("Open UI with parameters"); + BrowserWindowOpener parametersOpener = new BrowserWindowOpener( + ShowParamsUI.class); + parametersOpener.setUriFragment("myfragment"); + parametersOpener.setParameter("my¶m", "my=param#value"); + parametersOpener.extend(withParametersButton); + addComponent(withParametersButton); } public void addComponents(List> components, -- 2.39.5