From 761bef8fb790258ac7a527f51a23da0bd1802dbe Mon Sep 17 00:00:00 2001 From: Artur Date: Wed, 28 Mar 2018 15:21:16 +0300 Subject: Support starting downloads and opening URLs from a menu item (#10478) --- .../com/vaadin/server/BrowserWindowOpener.java | 19 +++++++ .../main/java/com/vaadin/server/EventTrigger.java | 65 ++++++++++++++++++++++ .../java/com/vaadin/server/FileDownloader.java | 19 +++++++ server/src/main/java/com/vaadin/ui/MenuBar.java | 57 ++++++++++++++++++- 4 files changed, 159 insertions(+), 1 deletion(-) create mode 100644 server/src/main/java/com/vaadin/server/EventTrigger.java (limited to 'server') diff --git a/server/src/main/java/com/vaadin/server/BrowserWindowOpener.java b/server/src/main/java/com/vaadin/server/BrowserWindowOpener.java index 838a78184a..1115acdddb 100644 --- a/server/src/main/java/com/vaadin/server/BrowserWindowOpener.java +++ b/server/src/main/java/com/vaadin/server/BrowserWindowOpener.java @@ -122,10 +122,29 @@ public class BrowserWindowOpener extends AbstractExtension { setResource(BrowserWindowOpenerState.locationResource, resource); } + /** + * Add this extension to the target component. + * + * @param target + * the component to attach this extension to + */ public void extend(AbstractComponent target) { super.extend(target); } + /** + * Add this extension to the {@code EventTrigger}. + * + * @param eventTrigger + * the trigger to attach this extension to + * + * @since + */ + public void extend(EventTrigger eventTrigger) { + super.extend(eventTrigger.getConnector()); + getState().partInformation = eventTrigger.getPartInformation(); + } + /** * Sets the provided URL {@code url} for this instance. The {@code url} will * be opened in a new browser window/tab when the extended component is diff --git a/server/src/main/java/com/vaadin/server/EventTrigger.java b/server/src/main/java/com/vaadin/server/EventTrigger.java new file mode 100644 index 0000000000..08b8dbca98 --- /dev/null +++ b/server/src/main/java/com/vaadin/server/EventTrigger.java @@ -0,0 +1,65 @@ +/* + * Copyright 2000-2018 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.server; + +import java.io.Serializable; + +import com.vaadin.ui.Component; +import com.vaadin.ui.MenuBar; + +/** + * Provides support for triggering an event from a given parts of a component or + * using various events. + *

+ * Used by features such as {@link FileDownloader} and + * {@link BrowserWindowOpener} to listen to a given event on a given element on + * the client side. The component is the one responsible for deciding the + * element and the event to listen to and can communicate this to the client + * using {@link #getPartInformation()}. + *

+ * This is the server side interface. + *

+ * If a {@link Component} implements this interface, then the corresponding + * connector on the client side must implement + * {@code com.vaadin.client.extensions.EventTrigger}. + * + * @since + */ +public interface EventTrigger extends Serializable { + + /** + * Gets the connector who will be used to offer the file download. Typically + * a component containing a certain DOM element, which in turn triggers the + * download. + * + * @return the connector for the file download + */ + AbstractClientConnector getConnector(); + + /** + * Gets a free form string which identifies which part of the connector that + * should trigger the download. The string is passed to the connector + * (FileDownloaderHandler implementor) on the client side. + *

+ * For example, {@link MenuBar} passes the id of a menu item through this + * method so that the client side can listen to events for that particular + * item only. + * + * @return a free form string which makes sense to the client side connector + */ + String getPartInformation(); + +} diff --git a/server/src/main/java/com/vaadin/server/FileDownloader.java b/server/src/main/java/com/vaadin/server/FileDownloader.java index a35278bd9d..df4240f368 100644 --- a/server/src/main/java/com/vaadin/server/FileDownloader.java +++ b/server/src/main/java/com/vaadin/server/FileDownloader.java @@ -66,10 +66,29 @@ public class FileDownloader extends AbstractExtension { setResource("dl", resource); } + /** + * Add this extension to the target component. + * + * @param target + * the component to attach this extension to + */ public void extend(AbstractComponent target) { super.extend(target); } + /** + * Add this extension to the {@code EventTrigger}. + * + * @param eventTrigger + * the trigger to attach this extension to + * + * @since + */ + public void extend(EventTrigger eventTrigger) { + super.extend(eventTrigger.getConnector()); + getState().partInformation = eventTrigger.getPartInformation(); + } + /** * Gets the resource set for download. * diff --git a/server/src/main/java/com/vaadin/ui/MenuBar.java b/server/src/main/java/com/vaadin/ui/MenuBar.java index f6bafb5d15..4f7055bf6e 100644 --- a/server/src/main/java/com/vaadin/ui/MenuBar.java +++ b/server/src/main/java/com/vaadin/ui/MenuBar.java @@ -28,6 +28,8 @@ import org.jsoup.nodes.Element; import org.jsoup.nodes.Node; import org.jsoup.parser.Tag; +import com.vaadin.server.AbstractClientConnector; +import com.vaadin.server.EventTrigger; import com.vaadin.server.PaintException; import com.vaadin.server.PaintTarget; import com.vaadin.server.Resource; @@ -217,6 +219,23 @@ implements LegacyComponent, Focusable { setMoreMenuItem(null); } + /** + * Adds a new menu item to the menu bar + *

+ * Clicking on this menu item has no effect. Use + * {@link #addItem(String, Command)} or {@link MenuItem#setCommand(Command)} + * to assign an action to the menu item. + * + * @param caption + * the text for the menu item + * @throws IllegalArgumentException + * + * @since + */ + public MenuBar.MenuItem addItem(String caption) { + return addItem(caption, null, null); + } + /** * Add a new item to the menu bar. Command can be null, but a caption must * be given. @@ -453,7 +472,7 @@ implements LegacyComponent, Focusable { * multiple MenuItems to a MenuItem and create a sub-menu. * */ - public class MenuItem implements Serializable { + public class MenuItem implements Serializable, EventTrigger { /** Private members * */ private final int itsId; @@ -522,6 +541,22 @@ implements LegacyComponent, Focusable { return item; } + /** + * Add a new menu item inside this menu item, creating a sub-menu. + *

+ * Clicking on the new item has no effect. Use + * {@link #addItem(String, Command)} or {@link #setCommand(Command)} to + * assign an action to the menu item. + * + * @param caption + * the text for the menu item + * + * @since + */ + public MenuBar.MenuItem addItem(String caption) { + return addItem(caption, null, null); + } + /** * Add a new item inside this item, thus creating a sub-menu. Command * can be null, but a caption must be given. @@ -992,6 +1027,26 @@ implements LegacyComponent, Focusable { this.checked = checked; markAsDirty(); } + + /** + * Gets the menu bar this item is part of. + * + * @return the menu bar this item is attached to + * @since + */ + public MenuBar getMenuBar() { + return MenuBar.this; + } + + @Override + public AbstractClientConnector getConnector() { + return getMenuBar(); + } + + @Override + public String getPartInformation() { + return String.valueOf(getId()); + } } @Override -- cgit v1.2.3