summaryrefslogtreecommitdiffstats
path: root/src/com/vaadin
diff options
context:
space:
mode:
authorMatti Tahvonen <matti.tahvonen@itmill.com>2011-11-21 13:38:31 +0000
committerMatti Tahvonen <matti.tahvonen@itmill.com>2011-11-21 13:38:31 +0000
commitfdc8e9a3445612adb21e620ca9822455663e34ba (patch)
tree51e17ed9913d7cbf374788f5c5e8a651e527494c /src/com/vaadin
parente8f99a58c30d2813f0ddc60787fe7dc8774dac4e (diff)
downloadvaadin-framework-fdc8e9a3445612adb21e620ca9822455663e34ba.tar.gz
vaadin-framework-fdc8e9a3445612adb21e620ca9822455663e34ba.zip
dragandropwrapper can now initiate html5 drags, fixes #7833
svn changeset:22081/svn branch:6.8
Diffstat (limited to 'src/com/vaadin')
-rw-r--r--src/com/vaadin/terminal/gwt/DefaultWidgetSet.gwt.xml16
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VDragAndDropWrapper.java179
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/VDragAndDropWrapperIE.java65
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/dd/VHtml5DragEvent.java20
-rw-r--r--src/com/vaadin/terminal/gwt/client/ui/dd/VTransferable.java8
-rw-r--r--src/com/vaadin/ui/DragAndDropWrapper.java38
6 files changed, 251 insertions, 75 deletions
diff --git a/src/com/vaadin/terminal/gwt/DefaultWidgetSet.gwt.xml b/src/com/vaadin/terminal/gwt/DefaultWidgetSet.gwt.xml
index 66ab7202ed..1c9b459512 100644
--- a/src/com/vaadin/terminal/gwt/DefaultWidgetSet.gwt.xml
+++ b/src/com/vaadin/terminal/gwt/DefaultWidgetSet.gwt.xml
@@ -1,6 +1,6 @@
<module>
- <!-- This GWT module defines the Vaadin DefaultWidgetSet. This is the module
- you want to extend when creating an extended widget set, or when creating
+ <!-- This GWT module defines the Vaadin DefaultWidgetSet. This is the module
+ you want to extend when creating an extended widget set, or when creating
a specialized widget set with a subset of the components. -->
<!-- Hint for WidgetSetBuilder not to automatically update the file -->
@@ -12,7 +12,7 @@
<source path="client" />
- <!-- Use own Scheduler implementation to be able to track if commands are
+ <!-- Use own Scheduler implementation to be able to track if commands are
running -->
<replace-with class="com.vaadin.terminal.gwt.client.VSchedulerImpl">
<when-type-is class="com.google.gwt.core.client.impl.SchedulerImpl" />
@@ -52,6 +52,16 @@
</any>
</replace-with>
+ <replace-with
+ class="com.vaadin.terminal.gwt.client.ui.VDragAndDropWrapperIE">
+ <when-type-is
+ class="com.vaadin.terminal.gwt.client.ui.VDragAndDropWrapper" />
+ <any>
+ <when-property-is name="user.agent" value="ie6" />
+ <when-property-is name="user.agent" value="ie8" />
+ </any>
+ </replace-with>
+
<!-- Workaround for #6682. Remove when fixed in GWT. -->
<replace-with class="com.google.gwt.dom.client.VaadinDOMImplSafari">
<when-type-is class="com.google.gwt.dom.client.DOMImpl" />
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VDragAndDropWrapper.java b/src/com/vaadin/terminal/gwt/client/ui/VDragAndDropWrapper.java
index 7fef345586..05d69d7dec 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/VDragAndDropWrapper.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/VDragAndDropWrapper.java
@@ -25,14 +25,15 @@ import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.xhr.client.ReadyStateChangeHandler;
import com.google.gwt.xhr.client.XMLHttpRequest;
import com.vaadin.terminal.gwt.client.ApplicationConnection;
-import com.vaadin.terminal.gwt.client.BrowserInfo;
import com.vaadin.terminal.gwt.client.MouseEventDetails;
import com.vaadin.terminal.gwt.client.Paintable;
import com.vaadin.terminal.gwt.client.RenderInformation;
import com.vaadin.terminal.gwt.client.RenderInformation.Size;
import com.vaadin.terminal.gwt.client.UIDL;
import com.vaadin.terminal.gwt.client.Util;
+import com.vaadin.terminal.gwt.client.VConsole;
import com.vaadin.terminal.gwt.client.VTooltip;
+import com.vaadin.terminal.gwt.client.ValueMap;
import com.vaadin.terminal.gwt.client.ui.dd.DDUtil;
import com.vaadin.terminal.gwt.client.ui.dd.HorizontalDropLocation;
import com.vaadin.terminal.gwt.client.ui.dd.VAbstractDropHandler;
@@ -55,8 +56,11 @@ import com.vaadin.terminal.gwt.client.ui.dd.VerticalDropLocation;
*/
public class VDragAndDropWrapper extends VCustomComponent implements
VHasDropHandler {
+ public static final String DRAG_START_MODE = "dragStartMode";
+ public static final String HTML5_DATA_FLAVORS = "html5-data-flavors";
private static final String CLASSNAME = "v-ddwrapper";
+ protected static final String DRAGGABLE = "draggable";
public VDragAndDropWrapper() {
super();
@@ -82,6 +86,7 @@ public class VDragAndDropWrapper extends VCustomComponent implements
}
}
}, TouchStartEvent.getType());
+
sinkEvents(Event.TOUCHEVENTS);
}
@@ -102,7 +107,7 @@ public class VDragAndDropWrapper extends VCustomComponent implements
* @return true if the event was handled as a drag start event
*/
private boolean startDrag(NativeEvent event) {
- if (dragStarMode > 0) {
+ if (dragStartMode == WRAPPER || dragStartMode == COMPONENT) {
VTransferable transferable = new VTransferable();
transferable.setDragSource(VDragAndDropWrapper.this);
@@ -121,7 +126,7 @@ public class VDragAndDropWrapper extends VCustomComponent implements
transferable.setData("mouseDown",
new MouseEventDetails(event).serialize());
- if (dragStarMode == WRAPPER) {
+ if (dragStartMode == WRAPPER) {
dragEvent.createDragImage(getElement(), true);
} else {
dragEvent.createDragImage(((Widget) paintable).getElement(),
@@ -132,16 +137,21 @@ public class VDragAndDropWrapper extends VCustomComponent implements
return false;
}
+ protected final static int NONE = 0;
+ protected final static int COMPONENT = 1;
+ protected final static int WRAPPER = 2;
+ protected final static int HTML5 = 3;
+
+ protected int dragStartMode;
+
private ApplicationConnection client;
private VAbstractDropHandler dropHandler;
private VDragEvent vaadinDragEvent;
- private final static int NONE = 0;
- private final static int COMPONENT = 1;
- private final static int WRAPPER = 2;
- private int dragStarMode;
private int filecounter = 0;
private Map<String, String> fileIdToReceiver;
+ private ValueMap html5DataFlavors;
+ private Element dragStartElement;
@Override
public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {
@@ -180,10 +190,35 @@ public class VDragAndDropWrapper extends VCustomComponent implements
}
startNextUpload();
- dragStarMode = uidl.getIntAttribute("dragStartMode");
+ dragStartMode = uidl.getIntAttribute(DRAG_START_MODE);
+ initDragStartMode();
+ html5DataFlavors = uidl.getMapAttribute(HTML5_DATA_FLAVORS);
+ }
+ }
+
+ protected void initDragStartMode() {
+ Element div = getElement();
+ if (dragStartMode == HTML5) {
+ if (dragStartElement == null) {
+ dragStartElement = getDragStartElement();
+ dragStartElement.setPropertyBoolean(DRAGGABLE, true);
+ VConsole.log("draggable = "
+ + dragStartElement.getPropertyBoolean(DRAGGABLE));
+ hookHtml5DragStart(dragStartElement);
+ VConsole.log("drag start listeners hooked.");
+ }
+ } else {
+ dragStartElement = null;
+ if (div.hasAttribute(DRAGGABLE)) {
+ div.removeAttribute(DRAGGABLE);
+ }
}
}
+ protected Element getDragStartElement() {
+ return getElement();
+ }
+
private boolean uploading;
private ReadyStateChangeHandler readyStateChangeHandler = new ReadyStateChangeHandler() {
@@ -227,6 +262,23 @@ public class VDragAndDropWrapper extends VCustomComponent implements
}
+ public boolean html5DragStart(VHtml5DragEvent event) {
+ if (dragStartMode == HTML5) {
+ /*
+ * Populate html5 payload with dataflavors from the serverside
+ */
+ JsArrayString flavors = html5DataFlavors.getKeyArray();
+ for (int i = 0; i < flavors.length(); i++) {
+ String flavor = flavors.get(i);
+ event.setHtml5DataFlavor(flavor,
+ html5DataFlavors.getString(flavor));
+ }
+ event.setEffectAllowed("copy");
+ return true;
+ }
+ return false;
+ }
+
public boolean html5DragEnter(VHtml5DragEvent event) {
if (dropHandler == null) {
return true;
@@ -246,8 +298,12 @@ public class VDragAndDropWrapper extends VCustomComponent implements
VDragAndDropManager.get().setCurrentDropHandler(
getDropHandler());
}
- event.preventDefault();
- event.stopPropagation();
+ try {
+ event.preventDefault();
+ event.stopPropagation();
+ } catch (Exception e) {
+ // VConsole.log("IE9 fails");
+ }
return false;
} catch (Exception e) {
GWT.getUncaughtExceptionHandler().onUncaughtException(e);
@@ -277,8 +333,12 @@ public class VDragAndDropWrapper extends VCustomComponent implements
}
};
dragleavetimer.schedule(350);
- event.preventDefault();
- event.stopPropagation();
+ try {
+ event.preventDefault();
+ event.stopPropagation();
+ } catch (Exception e) {
+ // VConsole.log("IE9 fails");
+ }
return false;
} catch (Exception e) {
GWT.getUncaughtExceptionHandler().onUncaughtException(e);
@@ -299,17 +359,20 @@ public class VDragAndDropWrapper extends VCustomComponent implements
vaadinDragEvent.setCurrentGwtEvent(event);
getDropHandler().dragOver(vaadinDragEvent);
- // needed to be set for Safari, otherwise drop will not happen
- if (BrowserInfo.get().isWebkit()) {
- String s = event.getEffectAllowed();
- if ("all".equals(s) || s.contains("opy")) {
- event.setDragEffect("copy");
- } else {
- event.setDragEffect(s);
- }
+
+ String s = event.getEffectAllowed();
+ if ("all".equals(s) || s.contains("opy")) {
+ event.setDropEffect("copy");
+ } else {
+ event.setDropEffect(s);
+ }
+
+ try {
+ event.preventDefault();
+ event.stopPropagation();
+ } catch (Exception e) {
+ // VConsole.log("IE9 fails");
}
- event.preventDefault();
- event.stopPropagation();
return false;
}
@@ -349,9 +412,12 @@ public class VDragAndDropWrapper extends VCustomComponent implements
VDragAndDropManager.get().endDrag();
vaadinDragEvent = null;
- event.preventDefault();
- event.stopPropagation();
-
+ try {
+ event.preventDefault();
+ event.stopPropagation();
+ } catch (Exception e) {
+ // VConsole.log("IE9 fails");
+ }
return false;
} catch (Exception e) {
GWT.getUncaughtExceptionHandler().onUncaughtException(e);
@@ -491,51 +557,38 @@ public class VDragAndDropWrapper extends VCustomComponent implements
}
+ protected native void hookHtml5DragStart(Element el)
+ /*-{
+ var me = this;
+ el.addEventListener("dragstart", function(ev) {
+ return me.@com.vaadin.terminal.gwt.client.ui.VDragAndDropWrapper::html5DragStart(Lcom/vaadin/terminal/gwt/client/ui/dd/VHtml5DragEvent;)(ev);
+ }, false);
+ }-*/;
+
/**
* Prototype code, memory leak risk.
*
* @param el
*/
- private native void hookHtml5Events(Element el)
+ protected native void hookHtml5Events(Element el)
/*-{
-
var me = this;
-
- if(el.addEventListener) {
- el.addEventListener("dragenter", function(ev) {
- return me.@com.vaadin.terminal.gwt.client.ui.VDragAndDropWrapper::html5DragEnter(Lcom/vaadin/terminal/gwt/client/ui/dd/VHtml5DragEvent;)(ev);
- }, false);
-
- el.addEventListener("dragleave", function(ev) {
- return me.@com.vaadin.terminal.gwt.client.ui.VDragAndDropWrapper::html5DragLeave(Lcom/vaadin/terminal/gwt/client/ui/dd/VHtml5DragEvent;)(ev);
- }, false);
-
- el.addEventListener("dragover", function(ev) {
- return me.@com.vaadin.terminal.gwt.client.ui.VDragAndDropWrapper::html5DragOver(Lcom/vaadin/terminal/gwt/client/ui/dd/VHtml5DragEvent;)(ev);
- }, false);
-
- el.addEventListener("drop", function(ev) {
- return me.@com.vaadin.terminal.gwt.client.ui.VDragAndDropWrapper::html5DragDrop(Lcom/vaadin/terminal/gwt/client/ui/dd/VHtml5DragEvent;)(ev);
- }, false);
-
- } else {
- el.attachEvent("ondragenter", function(ev) {
- return me.@com.vaadin.terminal.gwt.client.ui.VDragAndDropWrapper::html5DragEnter(Lcom/vaadin/terminal/gwt/client/ui/dd/VHtml5DragEvent;)(ev);
- });
-
- el.attachEvent("ondragleave", function(ev) {
- return me.@com.vaadin.terminal.gwt.client.ui.VDragAndDropWrapper::html5DragLeave(Lcom/vaadin/terminal/gwt/client/ui/dd/VHtml5DragEvent;)(ev);
- });
-
- el.attachEvent("ondragover", function(ev) {
- return me.@com.vaadin.terminal.gwt.client.ui.VDragAndDropWrapper::html5DragOver(Lcom/vaadin/terminal/gwt/client/ui/dd/VHtml5DragEvent;)(ev);
- });
-
- el.attachEvent("ondrop", function(ev) {
- return me.@com.vaadin.terminal.gwt.client.ui.VDragAndDropWrapper::html5DragDrop(Lcom/vaadin/terminal/gwt/client/ui/dd/VHtml5DragEvent;)(ev);
- });
- }
-
+
+ el.addEventListener("dragenter", function(ev) {
+ return me.@com.vaadin.terminal.gwt.client.ui.VDragAndDropWrapper::html5DragEnter(Lcom/vaadin/terminal/gwt/client/ui/dd/VHtml5DragEvent;)(ev);
+ }, false);
+
+ el.addEventListener("dragleave", function(ev) {
+ return me.@com.vaadin.terminal.gwt.client.ui.VDragAndDropWrapper::html5DragLeave(Lcom/vaadin/terminal/gwt/client/ui/dd/VHtml5DragEvent;)(ev);
+ }, false);
+
+ el.addEventListener("dragover", function(ev) {
+ return me.@com.vaadin.terminal.gwt.client.ui.VDragAndDropWrapper::html5DragOver(Lcom/vaadin/terminal/gwt/client/ui/dd/VHtml5DragEvent;)(ev);
+ }, false);
+
+ el.addEventListener("drop", function(ev) {
+ return me.@com.vaadin.terminal.gwt.client.ui.VDragAndDropWrapper::html5DragDrop(Lcom/vaadin/terminal/gwt/client/ui/dd/VHtml5DragEvent;)(ev);
+ }, false);
}-*/;
public boolean updateDropDetails(VDragEvent drag) {
diff --git a/src/com/vaadin/terminal/gwt/client/ui/VDragAndDropWrapperIE.java b/src/com/vaadin/terminal/gwt/client/ui/VDragAndDropWrapperIE.java
new file mode 100644
index 0000000000..89f063eaf9
--- /dev/null
+++ b/src/com/vaadin/terminal/gwt/client/ui/VDragAndDropWrapperIE.java
@@ -0,0 +1,65 @@
+package com.vaadin.terminal.gwt.client.ui;
+
+import com.google.gwt.dom.client.AnchorElement;
+import com.google.gwt.dom.client.Document;
+import com.google.gwt.user.client.Element;
+import com.vaadin.terminal.gwt.client.VConsole;
+
+public class VDragAndDropWrapperIE extends VDragAndDropWrapper {
+ private AnchorElement anchor = null;
+
+ @Override
+ protected Element getDragStartElement() {
+ VConsole.log("IE get drag start element...");
+ Element div = getElement();
+ if (dragStartMode == HTML5) {
+ if (anchor == null) {
+ anchor = Document.get().createAnchorElement();
+ anchor.setHref("#");
+ anchor.setClassName("drag-start");
+ div.appendChild(anchor);
+ }
+ VConsole.log("IE get drag start element...");
+ return (Element) anchor.cast();
+ } else {
+ if (anchor != null) {
+ div.removeChild(anchor);
+ anchor = null;
+ }
+ return div;
+ }
+ }
+
+ @Override
+ protected native void hookHtml5DragStart(Element el)
+ /*-{
+ var me = this;
+
+ el.attachEvent("ondragstart", function(ev) {
+ return me.@com.vaadin.terminal.gwt.client.ui.VDragAndDropWrapper::html5DragStart(Lcom/vaadin/terminal/gwt/client/ui/dd/VHtml5DragEvent;)(ev);
+ });
+ }-*/;
+
+ @Override
+ protected native void hookHtml5Events(Element el)
+ /*-{
+ var me = this;
+
+ el.attachEvent("ondragenter", function(ev) {
+ return me.@com.vaadin.terminal.gwt.client.ui.VDragAndDropWrapper::html5DragEnter(Lcom/vaadin/terminal/gwt/client/ui/dd/VHtml5DragEvent;)(ev);
+ });
+
+ el.attachEvent("ondragleave", function(ev) {
+ return me.@com.vaadin.terminal.gwt.client.ui.VDragAndDropWrapper::html5DragLeave(Lcom/vaadin/terminal/gwt/client/ui/dd/VHtml5DragEvent;)(ev);
+ });
+
+ el.attachEvent("ondragover", function(ev) {
+ return me.@com.vaadin.terminal.gwt.client.ui.VDragAndDropWrapper::html5DragOver(Lcom/vaadin/terminal/gwt/client/ui/dd/VHtml5DragEvent;)(ev);
+ });
+
+ el.attachEvent("ondrop", function(ev) {
+ return me.@com.vaadin.terminal.gwt.client.ui.VDragAndDropWrapper::html5DragDrop(Lcom/vaadin/terminal/gwt/client/ui/dd/VHtml5DragEvent;)(ev);
+ });
+ }-*/;
+
+}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/dd/VHtml5DragEvent.java b/src/com/vaadin/terminal/gwt/client/ui/dd/VHtml5DragEvent.java
index 3f3cf54e87..dd5852247a 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/dd/VHtml5DragEvent.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/dd/VHtml5DragEvent.java
@@ -41,7 +41,15 @@ public class VHtml5DragEvent extends NativeEvent {
return null;
}-*/;
- public final native void setDragEffect(String effect)
+ /**
+ * @deprecated As of Vaadin 6.8, replaced by {@link #setDropEffect(String)}.
+ */
+ @Deprecated
+ public final void setDragEffect(String effect) {
+ setDropEffect(effect);
+ }
+
+ public final native void setDropEffect(String effect)
/*-{
try {
this.dataTransfer.dropEffect = effect;
@@ -53,6 +61,11 @@ public class VHtml5DragEvent extends NativeEvent {
return this.dataTransfer.effectAllowed;
}-*/;
+ public final native void setEffectAllowed(String effect)
+ /*-{
+ this.dataTransfer.effectAllowed = effect;
+ }-*/;
+
public final native int getFileCount()
/*-{
return this.dataTransfer.files ? this.dataTransfer.files.length : 0;
@@ -63,4 +76,9 @@ public class VHtml5DragEvent extends NativeEvent {
return this.dataTransfer.files[fileIndex];
}-*/;
+ public final native void setHtml5DataFlavor(String flavor, String data)
+ /*-{
+ this.dataTransfer.setData(flavor, data);
+ }-*/;
+
}
diff --git a/src/com/vaadin/terminal/gwt/client/ui/dd/VTransferable.java b/src/com/vaadin/terminal/gwt/client/ui/dd/VTransferable.java
index 57b4d90e07..bb726586e2 100644
--- a/src/com/vaadin/terminal/gwt/client/ui/dd/VTransferable.java
+++ b/src/com/vaadin/terminal/gwt/client/ui/dd/VTransferable.java
@@ -45,12 +45,12 @@ public class VTransferable {
this.component = component;
}
- public Object getData(String dataFlawor) {
- return variables.get(dataFlawor);
+ public Object getData(String dataFlavor) {
+ return variables.get(dataFlavor);
}
- public void setData(String dataFlawor, Object value) {
- variables.put(dataFlawor, value);
+ public void setData(String dataFlavor, Object value) {
+ variables.put(dataFlavor, value);
}
public Collection<String> getDataFlavors() {
diff --git a/src/com/vaadin/ui/DragAndDropWrapper.java b/src/com/vaadin/ui/DragAndDropWrapper.java
index 83aa6314c8..9e06382eac 100644
--- a/src/com/vaadin/ui/DragAndDropWrapper.java
+++ b/src/com/vaadin/ui/DragAndDropWrapper.java
@@ -6,6 +6,7 @@ package com.vaadin.ui;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.Iterator;
+import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;
@@ -54,7 +55,7 @@ public class DragAndDropWrapper extends CustomComponent implements DropTarget,
/**
* The component in wrapper that is being dragged or null if the
- * transferrable is not a component (most likely an html5 drag).
+ * transferable is not a component (most likely an html5 drag).
*
* @return
*/
@@ -135,7 +136,8 @@ public class DragAndDropWrapper extends CustomComponent implements DropTarget,
}
/**
- * @return a detail about the drags horizontal position over the wrapper.
+ * @return a detail about the drags horizontal position over the
+ * wrapper.
*/
public HorizontalDropLocation getHorizontalDropLocation() {
return HorizontalDropLocation
@@ -172,9 +174,18 @@ public class DragAndDropWrapper extends CustomComponent implements DropTarget,
/**
* The whole wrapper is used as a drag image when dragging.
*/
- WRAPPER
+ WRAPPER,
+ /**
+ * The whole wrapper is used to start an HTML5 drag.
+ *
+ * NOTE: In Internet Explorer 6 to 8, this prevents user interactions
+ * with the wrapper's contents. For example, clicking a button inside
+ * the wrapper will no longer work.
+ */
+ HTML5,
}
+ private final Map<String, Object> html5DataFlavors = new LinkedHashMap<String, Object>();
private DragStartMode dragStartMode = DragStartMode.NONE;
/**
@@ -187,10 +198,27 @@ public class DragAndDropWrapper extends CustomComponent implements DropTarget,
super(root);
}
+ /**
+ * Sets data flavors available in the DragAndDropWrapper is used to start an
+ * HTML5 style drags. Most commonly the "Text" flavor should be set.
+ * Multiple data types can be set.
+ *
+ * @param type
+ * the string identifier of the drag "payload". E.g. "Text" or
+ * "text/html"
+ * @param value
+ * the value
+ */
+ public void setHTML5DataFlavor(String type, Object value) {
+ html5DataFlavors.put(type, value);
+ requestRepaint();
+ }
+
@Override
public void paintContent(PaintTarget target) throws PaintException {
super.paintContent(target);
- target.addAttribute("dragStartMode", dragStartMode.ordinal());
+ target.addAttribute(VDragAndDropWrapper.DRAG_START_MODE,
+ dragStartMode.ordinal());
if (getDropHandler() != null) {
getDropHandler().getAcceptCriterion().paint(target);
}
@@ -213,6 +241,8 @@ public class DragAndDropWrapper extends CustomComponent implements DropTarget,
}
}
}
+ target.addAttribute(VDragAndDropWrapper.HTML5_DATA_FLAVORS,
+ html5DataFlavors);
}
private DropHandler dropHandler;