]> source.dussan.org Git - vaadin-framework.git/commitdiff
Make it possible for drop target to accept both files and other data (#9382)
authorAdam Wagner <wbadam@users.noreply.github.com>
Fri, 19 May 2017 08:22:04 +0000 (11:22 +0300)
committerPekka Hyvönen <pekka@vaadin.com>
Fri, 19 May 2017 08:22:04 +0000 (11:22 +0300)
client/src/main/java/com/vaadin/client/extensions/DropTargetExtensionConnector.java
client/src/main/java/com/vaadin/client/extensions/FileDropTargetConnector.java
uitest/src/main/java/com/vaadin/tests/dnd/Html5FileDragAndDropUpload.java

index cd23b3bc74198f42ebc716a1004f9fbd3b8e12d9..cd7cc7026bec811e9de2bf26abdd054ba4fafea9 100644 (file)
@@ -274,21 +274,34 @@ public class DropTargetExtensionConnector extends AbstractExtensionConnector {
     protected void onDrop(Event event) {
         NativeEvent nativeEvent = (NativeEvent) event;
         if (isDropAllowed(nativeEvent)) {
-            nativeEvent.preventDefault();
-            nativeEvent.stopPropagation();
 
             JsArrayString typesJsArray = getTypes(
                     nativeEvent.getDataTransfer());
-            List<String> types = new ArrayList<>();
-            Map<String, String> data = new HashMap<>();
-            for (int i = 0; i < typesJsArray.length(); i++) {
-                String type = typesJsArray.get(i);
-                types.add(type);
-                data.put(type, nativeEvent.getDataTransfer().getData(type));
+
+            /* Handle event if transfer doesn't contain files.
+             *
+             * Spec: "Dragging files can currently only happen from outside a
+             * browsing context, for example from a file system manager
+             * application."
+             * Thus there cannot be at the same time both files and other data
+             * dragged
+             */
+            if (!containsFiles(typesJsArray)) {
+                nativeEvent.preventDefault();
+                nativeEvent.stopPropagation();
+
+                List<String> types = new ArrayList<>();
+                Map<String, String> data = new HashMap<>();
+                for (int i = 0; i < typesJsArray.length(); i++) {
+                    String type = typesJsArray.get(i);
+                    types.add(type);
+                    data.put(type, nativeEvent.getDataTransfer().getData(type));
+                }
+
+                sendDropEventToServer(types, data, DragSourceExtensionConnector
+                        .getDropEffect(nativeEvent.getDataTransfer()), nativeEvent);
             }
 
-            sendDropEventToServer(types, data, DragSourceExtensionConnector
-                    .getDropEffect(nativeEvent.getDataTransfer()), nativeEvent);
         }
 
         removeDragOverStyle(nativeEvent);
@@ -313,6 +326,27 @@ public class DropTargetExtensionConnector extends AbstractExtensionConnector {
         return true;
     }
 
+    /**
+     * Tells if the given array of types contains files.
+     * <p>
+     * According to HTML specification, if any files are being dragged, {@code
+     * dataTransfer.types} will contain the string "Files". See
+     * https://html.spec.whatwg.org/multipage/interaction.html#the-datatransfer-interface:dom-datatransfer-types-2
+     *
+     * @param types
+     *         Array of data types.
+     * @return {@code} true if given array contains {@code "Files"}, {@code
+     * false} otherwise.
+     */
+    private boolean containsFiles(JsArrayString types) {
+        for (int i = 0; i < types.length(); i++) {
+            if ("Files".equals(types.get(i))) {
+                return true;
+            }
+        }
+        return false;
+    }
+
     /**
      * Initiates a server RPC for the drop event.
      *
index aba52f7e6b5768ad2256afa4e0a5057c17f4dd0e..142b7b2ff8a86e725445453351cd594c9af5429e 100644 (file)
@@ -127,10 +127,10 @@ public class FileDropTargetConnector extends DropTargetExtensionConnector {
             if (fileParams.size() > 0) {
                 getRpcProxy(FileDropTargetRpc.class).drop(fileParams);
             }
-        }
 
-        event.preventDefault();
-        event.stopPropagation();
+            event.preventDefault();
+            event.stopPropagation();
+        }
     }
 
     @Override
index d58e7aa43fe0f7dd82092e9c65384062c0045b59..708f259615f5a7a12d3c12627a2d5944ca71d8a4 100644 (file)
@@ -23,13 +23,13 @@ import java.util.List;
 import com.vaadin.server.StreamVariable;
 import com.vaadin.server.VaadinRequest;
 import com.vaadin.shared.ui.dnd.FileParameters;
+import com.vaadin.shared.ui.grid.DropMode;
 import com.vaadin.tests.components.AbstractTestUIWithLog;
 import com.vaadin.ui.Grid;
-import com.vaadin.ui.Html5File;
-import com.vaadin.ui.Label;
 import com.vaadin.ui.Layout;
 import com.vaadin.ui.Notification;
 import com.vaadin.ui.VerticalLayout;
+import com.vaadin.ui.components.grid.GridDropTarget;
 import com.vaadin.ui.dnd.FileDropTarget;
 
 public class Html5FileDragAndDropUpload extends AbstractTestUIWithLog {
@@ -39,7 +39,7 @@ public class Html5FileDragAndDropUpload extends AbstractTestUIWithLog {
     @Override
     protected void setup(VaadinRequest request) {
 
-        Grid<FileParameters> grid = new Grid<>("Drop files on the Grid");
+        Grid<FileParameters> grid = new Grid<>("Drop files or text on the Grid");
         grid.addColumn(FileParameters::getName).setCaption("File name");
         grid.addColumn(FileParameters::getSize).setCaption("File size");
         grid.addColumn(FileParameters::getMime).setCaption("Mime type");
@@ -103,6 +103,13 @@ public class Html5FileDragAndDropUpload extends AbstractTestUIWithLog {
             });
         });
 
+        GridDropTarget<FileParameters> dropTarget = new GridDropTarget<>(grid,
+                DropMode.ON_TOP);
+        dropTarget.addGridDropListener(event -> {
+            log("dataTransferText=" + event.getDataTransferText());
+            Notification.show(event.getDataTransferText());
+        });
+
         Layout layout = new VerticalLayout(grid);
 
         addComponent(layout);
@@ -110,6 +117,6 @@ public class Html5FileDragAndDropUpload extends AbstractTestUIWithLog {
 
     @Override
     protected String getTestDescription() {
-        return "Drop files onto the Grid to upload them";
+        return "Drop files onto the Grid to upload them or text";
     }
 }