aboutsummaryrefslogtreecommitdiffstats
path: root/server
diff options
context:
space:
mode:
authorAdam Wagner <wbadam@users.noreply.github.com>2017-02-09 07:52:15 +0100
committerPekka Hyvönen <pekka@vaadin.com>2017-02-10 15:59:44 +0200
commita9c8e66d14899796e786e643d434daf6f16cf062 (patch)
tree59253d3b06d3223bc2e19b2f8b1b4fd5fb8e3b77 /server
parent4445eae397818196ba1818470c73ccf34e2033ce (diff)
downloadvaadin-framework-a9c8e66d14899796e786e643d434daf6f16cf062.tar.gz
vaadin-framework-a9c8e66d14899796e786e643d434daf6f16cf062.zip
HTML5 Drag and Drop Support (#8264)
* Add DragSource Extension (#8169) * Add DropTarget Extension (#8170) * Add DragStart Event to DragSource Extension (#8171) * Make DataTransfer.dropEffect configurable (#8174) * Make DragSource.dataTransfer data configurable (#8172) * Add server-side Event for drop (#8177) * Added license headers * Extract handler methods, move DropEvent and DropListener to new file, move enums to top * Replaced LinkedHashMap with Map and added List to preserve order of data * Add API for adding a JS acceptance criteria for dragover and drop (#8178, #8179) * Make DragSource Extension extendable (#8175) * Make DropTarget Extension extendable (#8176) * Added javadoc to protected methods * Moved EffectAllowed to shared so that it could be used in shared state directly * Moved DropEffect to separate file, some review fixes and javadoc * Added list to DropTargetRpc to preserve order of data * Remove event listeners on unregister * Changed method names set/getData() to more descriptive set/getTransferData() * Add server side dragStart event (#8171) * Add style to prevent text selection to allow drag * Remove target indicator style on drop * Add client side dragend event listener for drag source * Add server side dragend listener. Attach client side listener only when server side listener added. * Add drag source information to server side dragstart and dragend events. * Fixed some issues addressed in review * Trigger server side dragstart only when there is a listener attached * Criteria script can be set as null to clear * Use Js Interop instead of JSNI for handling event listeners * Use elemental package instead of Js Interop for handling event listeners * Add missing javadoc for public methods * Add default value "uninitialized" to effectAllowed parameter * Simple test UI for HTML5 DnD functionality (#8395) * Add javadoc and other minor changes
Diffstat (limited to 'server')
-rw-r--r--server/src/main/java/com/vaadin/event/dnd/DragEndEvent.java77
-rw-r--r--server/src/main/java/com/vaadin/event/dnd/DragEndListener.java40
-rw-r--r--server/src/main/java/com/vaadin/event/dnd/DragSourceExtension.java226
-rw-r--r--server/src/main/java/com/vaadin/event/dnd/DragStartEvent.java77
-rw-r--r--server/src/main/java/com/vaadin/event/dnd/DragStartListener.java40
-rw-r--r--server/src/main/java/com/vaadin/event/dnd/DropEvent.java77
-rw-r--r--server/src/main/java/com/vaadin/event/dnd/DropListener.java38
-rw-r--r--server/src/main/java/com/vaadin/event/dnd/DropTargetExtension.java145
8 files changed, 720 insertions, 0 deletions
diff --git a/server/src/main/java/com/vaadin/event/dnd/DragEndEvent.java b/server/src/main/java/com/vaadin/event/dnd/DragEndEvent.java
new file mode 100644
index 0000000000..6f094ce9e2
--- /dev/null
+++ b/server/src/main/java/com/vaadin/event/dnd/DragEndEvent.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2000-2016 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.event.dnd;
+
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import com.vaadin.shared.ui.dnd.EffectAllowed;
+import com.vaadin.ui.Component;
+
+/**
+ * Server side dragend event. Fired when an HTML5 dragend happens.
+ *
+ * @see DragSourceExtension#addDragEndListener(DragEndListener)
+ */
+public class DragEndEvent extends Component.Event {
+ private final Map<String, String> data;
+ private final EffectAllowed effectAllowed;
+
+ /**
+ * Creates a new server side dragend event.
+ *
+ * @param source
+ * Draggable component.
+ * @param types
+ * List of data types from {@code DataTransfer.types}.
+ * @param data
+ * Map of all data from {@code DataTransfer}.
+ * @param effectAllowed
+ * Parameter from {@code DataTransfer.effectAllowed}.
+ */
+ public DragEndEvent(Component source, List<String> types,
+ Map<String, String> data, EffectAllowed effectAllowed) {
+ super(source);
+
+ // Create a linked map that preserves the order of types
+ this.data = new LinkedHashMap<>();
+ types.forEach(type -> this.data.put(type, data.get(type)));
+
+ this.effectAllowed = effectAllowed;
+ }
+
+ /**
+ * Get data from the client side {@code DataTransfer} object.
+ *
+ * @param format
+ * Data format, e.g. {@code text/plain} or {@code text/uri-list}.
+ * @return Data for the given format if exists in the client side {@code
+ * DataTransfer}, otherwise {@code null}.
+ */
+ public String getTransferData(String format) {
+ return data != null ? data.get(format) : null;
+ }
+
+ /**
+ * Returns the {@code effectAllowed} parameter of this event.
+ *
+ * @return This event's {@code effectAllowed} parameter.
+ */
+ public EffectAllowed getEffectAllowed() {
+ return effectAllowed;
+ }
+}
diff --git a/server/src/main/java/com/vaadin/event/dnd/DragEndListener.java b/server/src/main/java/com/vaadin/event/dnd/DragEndListener.java
new file mode 100644
index 0000000000..00a020353d
--- /dev/null
+++ b/server/src/main/java/com/vaadin/event/dnd/DragEndListener.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2000-2016 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.event.dnd;
+
+import java.lang.reflect.Method;
+
+import com.vaadin.event.ConnectorEventListener;
+
+/**
+ * Interface to be implemented when creating a dragend listener on a drag
+ * source for HTML5 drag and drop.
+ *
+ * @see DragSourceExtension#addDragEndListener(DragEndListener)
+ */
+@FunctionalInterface
+public interface DragEndListener extends ConnectorEventListener {
+ static final Method DRAGEND_METHOD = DragEndListener.class
+ .getDeclaredMethods()[0];
+
+ /**
+ * Called when a server side dragend event is fired.
+ *
+ * @param event
+ * The dragend event that is fired.
+ */
+ void dragEnd(DragEndEvent event);
+}
diff --git a/server/src/main/java/com/vaadin/event/dnd/DragSourceExtension.java b/server/src/main/java/com/vaadin/event/dnd/DragSourceExtension.java
new file mode 100644
index 0000000000..d90e1bd8b8
--- /dev/null
+++ b/server/src/main/java/com/vaadin/event/dnd/DragSourceExtension.java
@@ -0,0 +1,226 @@
+/*
+ * Copyright 2000-2016 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.event.dnd;
+
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Objects;
+
+import com.vaadin.server.AbstractClientConnector;
+import com.vaadin.server.AbstractExtension;
+import com.vaadin.shared.Registration;
+import com.vaadin.shared.ui.dnd.DragSourceRpc;
+import com.vaadin.shared.ui.dnd.DragSourceState;
+import com.vaadin.shared.ui.dnd.EffectAllowed;
+import com.vaadin.ui.AbstractComponent;
+
+/**
+ * Extension to add drag source functionality to a component for using HTML5
+ * drag and drop.
+ */
+public class DragSourceExtension extends AbstractExtension {
+
+ /**
+ * Constructor for {@link DragSourceExtension}
+ */
+ public DragSourceExtension() {
+ registerRpc(new DragSourceRpc() {
+ @Override
+ public void dragStart() {
+ DragStartEvent event = new DragStartEvent(
+ (AbstractComponent) getParent(), getState(false).types,
+ getState(false).data, getState(false).effectAllowed);
+ fireEvent(event);
+ }
+
+ @Override
+ public void dragEnd() {
+ DragEndEvent event = new DragEndEvent(
+ (AbstractComponent) getParent(), getState(false).types,
+ getState(false).data, getState(false).effectAllowed);
+ fireEvent(event);
+ }
+ });
+ }
+
+ /**
+ * Makes {@code target} component a drag source.
+ *
+ * @param target
+ * Component to be extended.
+ */
+ public void extend(AbstractComponent target) {
+ super.extend(target);
+ }
+
+ /**
+ * Sets the allowed effects for the current drag source element. Used for
+ * setting client side {@code DataTransfer.effectAllowed} parameter for the
+ * drag event.
+ * <p>
+ * By default the value is {@link EffectAllowed#UNINITIALIZED} which is
+ * equivalent to {@link EffectAllowed#ALL}.
+ *
+ * @param effect
+ * Effects to allow for this draggable element. Cannot be {@code
+ * null}.
+ */
+ public void setEffectAllowed(EffectAllowed effect) {
+ if (effect == null) {
+ throw new IllegalArgumentException("Allowed effect cannot be null");
+ }
+ if (!Objects.equals(getState(false).effectAllowed, effect)) {
+ getState().effectAllowed = effect;
+ }
+ }
+
+ /**
+ * Returns the allowed effects for the current drag source element. Used to
+ * set client side {@code DataTransfer.effectAllowed} parameter for the drag
+ * event.
+ *
+ * @return Effects that are allowed for this draggable element.
+ */
+ public EffectAllowed getEffectAllowed() {
+ return getState(false).effectAllowed;
+ }
+
+ /**
+ * Sets the data for this drag source element. Used to set data for client
+ * side drag element using {@code DataTransfer.setData()}. To be used as a
+ * map, key-value pairs are stored. Order of entries are preserved.
+ * <p>
+ * Note that by HTML specification, the browser will change data type
+ * "{@code text}" to "{@code text/plain}" and "{@code url}" to "{@code
+ * text/uri-list}" during client side drag event.
+ *
+ * @param format
+ * Data type to store, e.g. {@code text/plain} or {@code
+ * text/uri-list}. Cannot be {@code null}.
+ * @param data
+ * Data to store for the data type. Cannot be {@code null}.
+ */
+ public void setTransferData(String format, String data) {
+ if (format == null) {
+ throw new IllegalArgumentException("Data type cannot be null");
+ }
+
+ if (data == null) {
+ throw new IllegalArgumentException("Data cannot be null");
+ }
+
+ if (!getState(false).types.contains(format)) {
+ getState().types.add(format);
+ }
+ getState().data.put(format, data);
+ }
+
+ /**
+ * Returns the data stored for {@code format} type in this drag source
+ * element.
+ *
+ * @param format
+ * Data type of the requested data, e.g. {@code text/plain} or
+ * {@code text/uri-list}.
+ * @return Data that is stored for {@code format} data type.
+ */
+ public String getTransferData(String format) {
+ return getState(false).data.get(format);
+ }
+
+ /**
+ * Returns the map of data stored in this drag source element. The returned
+ * map preserves the order of storage and is unmodifiable.
+ *
+ * @return Unmodifiable copy of the map of data in the order the data was
+ * stored.
+ */
+ public Map<String, String> getTransferData() {
+ Map<String, String> data = getState(false).data;
+
+ // Create a map of data that preserves the order of types
+ LinkedHashMap<String, String> orderedData = new LinkedHashMap<>(
+ data.size());
+ getState(false).types
+ .forEach(type -> orderedData.put(type, data.get(type)));
+
+ return Collections.unmodifiableMap(orderedData);
+ }
+
+ /**
+ * Clears data with the given type for this drag source element when
+ * present.
+ *
+ * @param format
+ * Type of data to be cleared. Cannot be {@code null}.
+ */
+ public void clearTransferData(String format) {
+ if (format == null) {
+ throw new IllegalArgumentException("Data type cannot be null");
+ }
+
+ getState().types.remove(format);
+ getState().data.remove(format);
+ }
+
+ /**
+ * Clears all data for this drag source element.
+ */
+ public void clearTransferData() {
+ getState().types.clear();
+ getState().data.clear();
+ }
+
+ /**
+ * Attaches dragstart listener for the current drag source. {@link
+ * DragStartListener#dragStart(DragStartEvent)} is called when dragstart
+ * event happens on the client side.
+ *
+ * @param listener
+ * Listener to handle dragstart event.
+ * @return Handle to be used to remove this listener.
+ */
+ public Registration addDragStartListener(DragStartListener listener) {
+ return addListener(DragSourceState.EVENT_DRAGSTART,
+ DragStartEvent.class, listener,
+ DragStartListener.DRAGSTART_METHOD);
+ }
+
+ /**
+ * Attaches dragend listener for the current drag source. {@link
+ * DragEndListener#dragEnd(DragEndEvent)} is called when dragend
+ * event happens on the client side.
+ *
+ * @param listener
+ * Listener to handle dragend event.
+ * @return Handle to be used to remove this listener.
+ */
+ public Registration addDragEndListener(DragEndListener listener) {
+ return addListener(DragSourceState.EVENT_DRAGEND, DragEndEvent.class,
+ listener, DragEndListener.DRAGEND_METHOD);
+ }
+
+ @Override
+ protected DragSourceState getState() {
+ return (DragSourceState) super.getState();
+ }
+
+ @Override
+ protected DragSourceState getState(boolean markAsDirty) {
+ return (DragSourceState) super.getState(markAsDirty);
+ }
+}
diff --git a/server/src/main/java/com/vaadin/event/dnd/DragStartEvent.java b/server/src/main/java/com/vaadin/event/dnd/DragStartEvent.java
new file mode 100644
index 0000000000..591a0e61a7
--- /dev/null
+++ b/server/src/main/java/com/vaadin/event/dnd/DragStartEvent.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2000-2016 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.event.dnd;
+
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import com.vaadin.shared.ui.dnd.EffectAllowed;
+import com.vaadin.ui.Component;
+
+/**
+ * Server side dragstart event. Fired when an HTML5 dragstart happens.
+ *
+ * @see DragSourceExtension#addDragStartListener(DragStartListener)
+ */
+public class DragStartEvent extends Component.Event {
+ private final Map<String, String> data;
+ private final EffectAllowed effectAllowed;
+
+ /**
+ * Creates a new server side dragend event.
+ *
+ * @param source
+ * Draggable component.
+ * @param types
+ * List of data types from {@code DataTransfer.types}.
+ * @param data
+ * Map of all data from {@code DataTransfer}.
+ * @param effectAllowed
+ * Parameter from {@code DataTransfer.effectAllowed}.
+ */
+ public DragStartEvent(Component source, List<String> types,
+ Map<String, String> data, EffectAllowed effectAllowed) {
+ super(source);
+
+ // Create a linked map that preserves the order of types
+ this.data = new LinkedHashMap<>();
+ types.forEach(type -> this.data.put(type, data.get(type)));
+
+ this.effectAllowed = effectAllowed;
+ }
+
+ /**
+ * Get data from the client side {@code DataTransfer} object.
+ *
+ * @param format
+ * Data format, e.g. {@code text/plain} or {@code text/uri-list}.
+ * @return Data for the given format if exists in the client side {@code
+ * DataTransfer}, otherwise {@code null}.
+ */
+ public String getTransferData(String format) {
+ return data != null ? data.get(format) : null;
+ }
+
+ /**
+ * Returns the {@code effectAllowed} parameter of this event.
+ *
+ * @return This event's {@code effectAllowed} parameter.
+ */
+ public EffectAllowed getEffectAllowed() {
+ return effectAllowed;
+ }
+}
diff --git a/server/src/main/java/com/vaadin/event/dnd/DragStartListener.java b/server/src/main/java/com/vaadin/event/dnd/DragStartListener.java
new file mode 100644
index 0000000000..8d691dee6b
--- /dev/null
+++ b/server/src/main/java/com/vaadin/event/dnd/DragStartListener.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2000-2016 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.event.dnd;
+
+import java.lang.reflect.Method;
+
+import com.vaadin.event.ConnectorEventListener;
+
+/**
+ * Interface to be implemented when creating a dragstart listener on a drag
+ * source for HTML5 drag and drop.
+ *
+ * @see DragSourceExtension#addDragStartListener(DragStartListener)
+ */
+@FunctionalInterface
+public interface DragStartListener extends ConnectorEventListener {
+ static final Method DRAGSTART_METHOD = DragStartListener.class
+ .getDeclaredMethods()[0];
+
+ /**
+ * Called when a server side dragstart event is fired.
+ *
+ * @param event
+ * The dragstart event that is fired.
+ */
+ void dragStart(DragStartEvent event);
+}
diff --git a/server/src/main/java/com/vaadin/event/dnd/DropEvent.java b/server/src/main/java/com/vaadin/event/dnd/DropEvent.java
new file mode 100644
index 0000000000..382b93bc55
--- /dev/null
+++ b/server/src/main/java/com/vaadin/event/dnd/DropEvent.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2000-2016 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.event.dnd;
+
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import com.vaadin.shared.ui.dnd.DropEffect;
+import com.vaadin.ui.Component;
+
+/**
+ * Server side drop event. Fired when an HTML5 drop happens.
+ *
+ * @see DropTargetExtension#addDropListener(DropListener)
+ */
+public class DropEvent extends Component.Event {
+ private final Map<String, String> data;
+ private final DropEffect dropEffect;
+
+ /**
+ * Creates a new server side drop event.
+ *
+ * @param source
+ * Drop target component.
+ * @param types
+ * List of data types from {@code DataTransfer.types}.
+ * @param data
+ * Map of all data from {@code DataTransfer}.
+ * @param dropEffect
+ * Parameter from {@code DataTransfer.dropEffect}.
+ */
+ public DropEvent(Component source, List<String> types,
+ Map<String, String> data, DropEffect dropEffect) {
+ super(source);
+
+ // Create a linked map that preserves the order of types
+ this.data = new LinkedHashMap<>();
+ types.forEach(type -> this.data.put(type, data.get(type)));
+
+ this.dropEffect = dropEffect;
+ }
+
+ /**
+ * Get data from the client side {@code DataTransfer} object.
+ *
+ * @param format
+ * Data format, e.g. {@code text/plain} or {@code text/uri-list}.
+ * @return Data for the given format if exists in the client side {@code
+ * DataTransfer}, otherwise {@code null}.
+ */
+ public String getTransferData(String format) {
+ return data != null ? data.get(format) : null;
+ }
+
+ /**
+ * Get drop effect set for the current drop target.
+ *
+ * @return {@code dropEffect} parameter set for the current drop target.
+ */
+ public DropEffect getDropEffect() {
+ return dropEffect;
+ }
+}
diff --git a/server/src/main/java/com/vaadin/event/dnd/DropListener.java b/server/src/main/java/com/vaadin/event/dnd/DropListener.java
new file mode 100644
index 0000000000..8cb96d1852
--- /dev/null
+++ b/server/src/main/java/com/vaadin/event/dnd/DropListener.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2000-2016 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.event.dnd;
+
+import java.lang.reflect.Method;
+
+import com.vaadin.event.ConnectorEventListener;
+
+/**
+ * Interface to be implemented when creating a drop listener on a drop target
+ * for HTML5 drag and drop. See {@link DropTargetExtension#addDropListener(DropListener)}.
+ */
+@FunctionalInterface
+public interface DropListener extends ConnectorEventListener {
+ static final Method DROP_METHOD = DropListener.class
+ .getDeclaredMethods()[0];
+
+ /**
+ * Called when a server side drop event is fired.
+ *
+ * @param event
+ * The drop event that is fired.
+ */
+ void drop(DropEvent event);
+}
diff --git a/server/src/main/java/com/vaadin/event/dnd/DropTargetExtension.java b/server/src/main/java/com/vaadin/event/dnd/DropTargetExtension.java
new file mode 100644
index 0000000000..20819ec70f
--- /dev/null
+++ b/server/src/main/java/com/vaadin/event/dnd/DropTargetExtension.java
@@ -0,0 +1,145 @@
+/*
+ * Copyright 2000-2016 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.event.dnd;
+
+import java.util.Objects;
+
+import com.vaadin.server.AbstractClientConnector;
+import com.vaadin.server.AbstractExtension;
+import com.vaadin.shared.Registration;
+import com.vaadin.shared.ui.dnd.DropEffect;
+import com.vaadin.shared.ui.dnd.DropTargetRpc;
+import com.vaadin.shared.ui.dnd.DropTargetState;
+import com.vaadin.ui.AbstractComponent;
+
+/**
+ * Extension to add drop target functionality to a widget for using HTML5 drag
+ * and drop.
+ */
+public class DropTargetExtension extends AbstractExtension {
+
+ /**
+ * Constructor for {@link DropTargetExtension}.
+ */
+ public DropTargetExtension() {
+ registerRpc((DropTargetRpc) (types, data, dropEffect) -> {
+ DropEvent event = new DropEvent((AbstractComponent) getParent(),
+ types, data, dropEffect);
+
+ fireEvent(event);
+ });
+ }
+
+ /**
+ * Makes {@code target} component a drop target.
+ *
+ * @param target
+ * Component to be extended.
+ */
+ public void extend(AbstractComponent target) {
+ super.extend(target);
+ }
+
+ /**
+ * Sets the drop effect for the current drop target. Used for the client
+ * side {@code DataTransfer.dropEffect} parameter.
+ * <p>
+ * Default value is browser dependent and can depend on e.g. modifier keys.
+ *
+ * @param dropEffect
+ * The drop effect to be set. Cannot be {@code null}.
+ */
+ public void setDropEffect(DropEffect dropEffect) {
+ if (dropEffect == null) {
+ throw new IllegalArgumentException("Drop effect cannot be null.");
+ }
+
+ if (!Objects.equals(getState(false).dropEffect, dropEffect)) {
+ getState().dropEffect = dropEffect;
+ }
+ }
+
+ /**
+ * Returns the drop effect for the current drop target.
+ *
+ * @return The drop effect of this drop target.
+ */
+ public DropEffect getDropEffect() {
+ return getState(false).dropEffect;
+ }
+
+ /**
+ * Sets criteria to allow dragover event on the current drop target. The
+ * script executes when dragover event happens and stops the event in case
+ * the script returns {@code false}.
+ *
+ * @param criteriaScript
+ * JavaScript to be executed when dragover event happens or {@code
+ * null} to clear.
+ */
+ public void setDragOverCriteria(String criteriaScript) {
+ if (!Objects.equals(getState(false).dragOverCriteria, criteriaScript)) {
+ getState().dragOverCriteria = criteriaScript;
+ }
+ }
+
+ /**
+ * Sets criteria to allow drop event on the current drop target. The script
+ * executes when drop event happens and stops the event in case the script
+ * returns {@code false}.
+ *
+ * @param criteriaScript
+ * JavaScript to be executed when drop event happens or {@code null}
+ * to clear.
+ */
+ public void setDropCriteria(String criteriaScript) {
+ if (!Objects.equals(getState(false).dropCriteria, criteriaScript)) {
+ getState().dropCriteria = criteriaScript;
+ }
+ }
+
+ /**
+ * Returns the criteria for allowing drop event on the current drop target.
+ *
+ * @return JavaScript that executes when drop event happens.
+ */
+ public String getDropCriteria() {
+ return getState(false).dropCriteria;
+ }
+
+ /**
+ * Attaches drop listener for the current drop target. {@link
+ * DropListener#drop(DropEvent)} is called when drop event happens on the
+ * client side.
+ *
+ * @param listener
+ * Listener to handle drop event.
+ * @return Handle to be used to remove this listener.
+ */
+ public Registration addDropListener(DropListener listener) {
+ return addListener(DropEvent.class, listener, DropListener.DROP_METHOD);
+ }
+
+ @Override
+ protected DropTargetState getState() {
+ return (DropTargetState) super.getState();
+ }
+
+ @Override
+ protected DropTargetState getState(boolean markAsDirty) {
+ return (DropTargetState) super.getState(markAsDirty);
+ }
+}