From: Matti Tahvonen Date: Tue, 16 Mar 2010 14:53:56 +0000 (+0000) Subject: cross plat improvementes for html5 drags X-Git-Tag: 6.7.0.beta1~1912 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=f99cb379af4d0786ffdc427ce56f431a539d3a8e;p=vaadin-framework.git cross plat improvementes for html5 drags svn changeset:11916/svn branch:6.3 --- diff --git a/src/com/vaadin/terminal/gwt/client/ui/VDragAndDropWrapper.java b/src/com/vaadin/terminal/gwt/client/ui/VDragAndDropWrapper.java index 7f50b8f9be..e35eec9799 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VDragAndDropWrapper.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VDragAndDropWrapper.java @@ -13,8 +13,10 @@ import com.google.gwt.user.client.Command; import com.google.gwt.user.client.DeferredCommand; import com.google.gwt.user.client.Element; 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; @@ -94,6 +96,7 @@ public class VDragAndDropWrapper extends VCustomComponent implements private final static int WRAPPER = 2; private int dragStarMode; private int filecounter = 0; + private boolean dragLeavPostponed; @Override public void updateFromUIDL(UIDL uidl, ApplicationConnection client) { @@ -119,12 +122,18 @@ public class VDragAndDropWrapper extends VCustomComponent implements if (dropHandler == null) { return true; } + if (dragLeavPostponed) { + // returned quickly back to wrapper + dragLeavPostponed = false; + return false; + } ApplicationConnection.getConsole().log("HTML 5 Drag Enter"); VTransferable transferable = new VTransferable(); transferable.setDragSource(this); vaadinDragEvent = VDragAndDropManager.get().startDrag(transferable, event, false); + VDragAndDropManager.get().setCurrentDropHandler(getDropHandler()); event.preventDefault(); event.stopPropagation(); return false; @@ -136,17 +145,21 @@ public class VDragAndDropWrapper extends VCustomComponent implements } ApplicationConnection.getConsole().log("HTML 5 Drag Leave posponed..."); + dragLeavPostponed = true; DeferredCommand.addCommand(new Command() { public void execute() { // Yes, dragleave happens before drop. Makes no sense to me. // IMO shouldn't fire leave at all if drop happens (I guess this // is what IE does). // In Vaadin we fire it only if drop did not happen. - if (vaadinDragEvent != null) { + if (dragLeavPostponed + && vaadinDragEvent != null + && VDragAndDropManager.get().getCurrentDropHandler() == getDropHandler()) { ApplicationConnection.getConsole().log( "...HTML 5 Drag Leave"); - getDropHandler().dragLeave(vaadinDragEvent); + VDragAndDropManager.get().interruptDrag(); } + dragLeavPostponed = false; } }); event.preventDefault(); @@ -160,14 +173,18 @@ public class VDragAndDropWrapper extends VCustomComponent implements } ApplicationConnection.getConsole().log("HTML 5 Drag Over"); + vaadinDragEvent.setCurrentGwtEvent(event); getDropHandler().dragOver(vaadinDragEvent); // needed to be set for Safari, otherwise drop will not happen - String s = event.getEffectAllowed(); - if ("all".equals(s) || s.contains("opy")) { - event.setDragEffect("copy"); - } else { - event.setDragEffect(s); - ApplicationConnection.getConsole().log("Drag effect set to " + s); + if (BrowserInfo.get().isWebkit()) { + String s = event.getEffectAllowed(); + if ("all".equals(s) || s.contains("opy")) { + event.setDragEffect("copy"); + } else { + event.setDragEffect(s); + ApplicationConnection.getConsole().log( + "Drag effect set to " + s); + } } event.preventDefault(); event.stopPropagation(); @@ -175,7 +192,7 @@ public class VDragAndDropWrapper extends VCustomComponent implements } public boolean html5DragDrop(VHtml5DragEvent event) { - if (dropHandler == null) { + if (dropHandler == null || !currentlyValid) { return true; } @@ -183,16 +200,21 @@ public class VDragAndDropWrapper extends VCustomComponent implements VTransferable transferable = vaadinDragEvent.getTransferable(); JsArrayString types = event.getTypes(); + ApplicationConnection.getConsole().log("Types fetched"); for (int i = 0; i < types.length(); i++) { String type = types.get(i); ApplicationConnection.getConsole().log("Type: " + type); - if ("text/plain".equals(type)) { + if ("Text".equals(type) || "Url".equals(type) + || "text/html".equals(type)) { String data = event.getDataAsText(type); - ApplicationConnection.getConsole().log(type + " : " + data); - transferable.setData("text/plain", data); + if (data != null) { + ApplicationConnection.getConsole().log(type + " : " + data); + transferable.setData(type, data); + } } } + ApplicationConnection.getConsole().log("checking files"); int fileCount = event.getFileCount(); if (fileCount > 0) { transferable.setData("filecount", fileCount); @@ -208,6 +230,8 @@ public class VDragAndDropWrapper extends VCustomComponent implements } + ApplicationConnection.getConsole().log("Ending drag"); + VDragAndDropManager.get().endDrag(); vaadinDragEvent = null; event.preventDefault(); @@ -230,7 +254,7 @@ public class VDragAndDropWrapper extends VCustomComponent implements } /** - * Currently supports only FF36 as no other browser supprots natively File + * Currently supports only FF36 as no other browser supports natively File * api. * * @param fileId @@ -248,8 +272,18 @@ public class VDragAndDropWrapper extends VCustomComponent implements ExtendedXHR extendedXHR = (ExtendedXHR) ExtendedXHR .create(); - extendedXHR.open("POST", client.getAppUri()); String name = "XHRFILE" + getPid() + "." + fileId; + extendedXHR + .setOnReadyStateChange(new ReadyStateChangeHandler() { + public void onReadyStateChange( + XMLHttpRequest xhr) { + if (xhr.getReadyState() == XMLHttpRequest.DONE) { + client.sendPendingVariableChanges(); + xhr.clearOnReadyStateChange(); + } + } + }); + extendedXHR.open("POST", client.getAppUri()); multipartSend(extendedXHR, object, name); } @@ -294,6 +328,11 @@ public class VDragAndDropWrapper extends VCustomComponent implements private VerticalDropLocation emphasizedVDrop; private HorizontalDropLocation emphasizedHDrop; + /** + * Flag used by html5 dd + */ + private boolean currentlyValid; + private static final String OVER_STYLE = "v-ddwrapper-over"; public class CustomDropHandler extends VAbstractDropHandler { @@ -302,6 +341,7 @@ public class VDragAndDropWrapper extends VCustomComponent implements public void dragEnter(VDragEvent drag) { updateDropDetails(drag); ApplicationConnection.getConsole().log("DDWrapper DragEnter"); + currentlyValid = false; super.dragEnter(drag); } @@ -309,16 +349,20 @@ public class VDragAndDropWrapper extends VCustomComponent implements public void dragLeave(VDragEvent drag) { ApplicationConnection.getConsole().log("DDWrapper DragLeave"); deEmphasis(true); + dragLeavPostponed = false; } @Override public void dragOver(final VDragEvent drag) { - updateDropDetails(drag); - validate(new VAcceptCallback() { - public void accepted(VDragEvent event) { - dragAccepted(drag); - } - }, drag); + boolean detailsChanged = updateDropDetails(drag); + if (detailsChanged) { + currentlyValid = false; + validate(new VAcceptCallback() { + public void accepted(VDragEvent event) { + dragAccepted(drag); + } + }, drag); + } } @Override @@ -349,6 +393,7 @@ public class VDragAndDropWrapper extends VCustomComponent implements @Override protected void dragAccepted(VDragEvent drag) { + currentlyValid = true; emphasis(drag); } @@ -392,11 +437,11 @@ public class VDragAndDropWrapper extends VCustomComponent implements } 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); + 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); + return me.@com.vaadin.terminal.gwt.client.ui.VDragAndDropWrapper::html5DragLeave(Lcom/vaadin/terminal/gwt/client/ui/dd/VHtml5DragEvent;)(ev); }); el.attachEvent("ondragover", function(ev) { @@ -410,15 +455,22 @@ public class VDragAndDropWrapper extends VCustomComponent implements }-*/; - public void updateDropDetails(VDragEvent drag) { + public boolean updateDropDetails(VDragEvent drag) { + VerticalDropLocation oldVL = verticalDropLocation; verticalDropLocation = DDUtil.getVerticalDropLocation(getElement(), drag.getCurrentGwtEvent().getClientY(), 0.2); drag.getDropDetails().put("verticalLocation", verticalDropLocation.toString()); + HorizontalDropLocation oldHL = horizontalDropLocation; horizontalDropLocation = DDUtil.getHorizontalDropLocation(getElement(), drag.getCurrentGwtEvent().getClientX(), 0.2); drag.getDropDetails().put("horizontalLocation", horizontalDropLocation.toString()); + if (oldHL != horizontalDropLocation || oldVL != verticalDropLocation) { + return true; + } else { + return false; + } } protected void deEmphasis(boolean doLayout) { diff --git a/src/com/vaadin/terminal/gwt/client/ui/dd/VDragAndDropManager.java b/src/com/vaadin/terminal/gwt/client/ui/dd/VDragAndDropManager.java index fdb3c47ba3..fdb5801a28 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/dd/VDragAndDropManager.java +++ b/src/com/vaadin/terminal/gwt/client/ui/dd/VDragAndDropManager.java @@ -43,7 +43,7 @@ public class VDragAndDropManager { public void onPreviewNativeEvent(NativePreviewEvent event) { NativeEvent nativeEvent = event.getNativeEvent(); - updateCurrentEvent(nativeEvent); + currentDrag.setCurrentGwtEvent(nativeEvent); updateDragImagePosition(); int typeInt = event.getTypeInt(); @@ -279,7 +279,7 @@ public class VDragAndDropManager { isStarted = false; currentDrag = new VDragEvent(transferable, startEvent); - updateCurrentEvent(startEvent); + currentDrag.setCurrentGwtEvent(startEvent); final Command startDrag = new Command() { @@ -287,8 +287,8 @@ public class VDragAndDropManager { isStarted = true; VDropHandler dh = null; if (startEvent != null) { - dh = findDragTarget((Element) currentDrag.currentGwtEvent - .getEventTarget().cast()); + dh = findDragTarget((Element) currentDrag + .getCurrentGwtEvent().getEventTarget().cast()); } if (dh != null) { // drag has started on a DropHandler, kind of drag over @@ -357,7 +357,8 @@ public class VDragAndDropManager { case Event.ONMOUSEMOVE: deferredStartRegistration.removeHandler(); deferredStartRegistration = null; - updateCurrentEvent(event.getNativeEvent()); + currentDrag.setCurrentGwtEvent(event + .getNativeEvent()); startDrag.execute(); break; default: @@ -386,24 +387,26 @@ public class VDragAndDropManager { return currentDrag; } - private void interruptDrag() { + public void interruptDrag() { if (currentDrag != null) { ApplicationConnection.getConsole() .log("Drag operation interrupted"); if (currentDropHandler != null) { - currentDrag.currentGwtEvent = null; + currentDrag.setCurrentGwtEvent(null); currentDropHandler.dragLeave(currentDrag); currentDropHandler = null; + serverCallback = null; + visitId = -1; // ignore possibly on going server check } currentDrag = null; } } private void updateDragImagePosition() { - if (currentDrag.currentGwtEvent != null && dragElement != null) { + if (currentDrag.getCurrentGwtEvent() != null && dragElement != null) { Style style = dragElement.getStyle(); - int clientY = currentDrag.currentGwtEvent.getClientY(); - int clientX = currentDrag.currentGwtEvent.getClientX(); + int clientY = currentDrag.getCurrentGwtEvent().getClientY(); + int clientX = currentDrag.getCurrentGwtEvent().getClientX(); style.setTop(clientY, Unit.PX); style.setLeft(clientX, Unit.PX); } @@ -451,10 +454,6 @@ public class VDragAndDropManager { } - private void updateCurrentEvent(NativeEvent event) { - currentDrag.currentGwtEvent = event; - } - public void endDrag() { if (handlerRegistration != null) { handlerRegistration.removeHandler(); @@ -535,10 +534,10 @@ public class VDragAndDropManager { client.updateVariable(DD_SERVICE, "type", drop.ordinal(), false); - if (currentDrag.currentGwtEvent != null) { + if (currentDrag.getCurrentGwtEvent() != null) { try { MouseEventDetails mouseEventDetails = new MouseEventDetails( - currentDrag.currentGwtEvent); + currentDrag.getCurrentGwtEvent()); currentDrag.getDropDetails().put("mouseEvent", mouseEventDetails.serialize()); } catch (Exception e) { diff --git a/src/com/vaadin/terminal/gwt/client/ui/dd/VDragEvent.java b/src/com/vaadin/terminal/gwt/client/ui/dd/VDragEvent.java index 8877d70f04..a5b06cea84 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/dd/VDragEvent.java +++ b/src/com/vaadin/terminal/gwt/client/ui/dd/VDragEvent.java @@ -30,7 +30,7 @@ public class VDragEvent { private VTransferable transferable; - NativeEvent currentGwtEvent; + private NativeEvent currentGwtEvent; private NativeEvent startEvent; @@ -64,6 +64,10 @@ public class VDragEvent { return currentGwtEvent; } + public void setCurrentGwtEvent(NativeEvent event) { + currentGwtEvent = event; + } + int getEventId() { return id; } 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 47b1ba81ed..3f3cf54e87 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/dd/VHtml5DragEvent.java +++ b/src/com/vaadin/terminal/gwt/client/ui/dd/VHtml5DragEvent.java @@ -17,7 +17,8 @@ public class VHtml5DragEvent extends NativeEvent { public final native JsArrayString getTypes() /*-{ - return this.dataTransfer.types; + // IE does not support types, return some basic values + return this.dataTransfer.types ? this.dataTransfer.types : ["Text","Url","Html"]; }-*/; public final native String getDataAsText(String type) diff --git a/src/com/vaadin/ui/DragAndDropWrapper.java b/src/com/vaadin/ui/DragAndDropWrapper.java index 65bcbaaa6a..9d3e9a6f19 100644 --- a/src/com/vaadin/ui/DragAndDropWrapper.java +++ b/src/com/vaadin/ui/DragAndDropWrapper.java @@ -265,6 +265,7 @@ public class DragAndDropWrapper extends CustomComponent implements DropTarget, while ((bytesRead = stream.read(buf)) != -1) { receiveUpload.write(buf, 0, bytesRead); } + receiveUpload.close(); } catch (IOException e) { throw new UploadException(e); } diff --git a/tests/src/com/vaadin/tests/dd/AcceptAnythingWindow.java b/tests/src/com/vaadin/tests/dd/AcceptAnythingWindow.java index 38ecc308b5..d2dfd454e3 100644 --- a/tests/src/com/vaadin/tests/dd/AcceptAnythingWindow.java +++ b/tests/src/com/vaadin/tests/dd/AcceptAnythingWindow.java @@ -103,7 +103,7 @@ public class AcceptAnythingWindow extends Window { } else { // drag coming outside of Vaadin - String object = (String) transferable.getData("text/plain"); + String object = (String) transferable.getData("Text"); String content = (String) transferable .getData("fileContents"); diff --git a/tests/src/com/vaadin/tests/dd/DragDropPane.java b/tests/src/com/vaadin/tests/dd/DragDropPane.java index 400e5f9e26..82401a99f7 100644 --- a/tests/src/com/vaadin/tests/dd/DragDropPane.java +++ b/tests/src/com/vaadin/tests/dd/DragDropPane.java @@ -1,5 +1,9 @@ package com.vaadin.tests.dd; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.OutputStream; + import com.vaadin.event.DataBoundTransferable; import com.vaadin.event.Transferable; import com.vaadin.event.dd.DragAndDropEvent; @@ -12,6 +16,8 @@ import com.vaadin.ui.Component; import com.vaadin.ui.DragAndDropWrapper; import com.vaadin.ui.Label; import com.vaadin.ui.AbsoluteLayout.ComponentPosition; +import com.vaadin.ui.DragAndDropWrapper.WrapperTransferable.Html5File; +import com.vaadin.ui.Upload.Receiver; /** * replacement for a proto class to keep tests working @@ -104,11 +110,14 @@ public class DragDropPane extends DragAndDropWrapper implements DropHandler { else { // drag coming outside of Vaadin - String object = (String) ctr.getData("text/plain"); - String content = (String) ctr.getData("fileContents"); + WrapperTransferable wtr = (WrapperTransferable) ctr; - Label l = new Label(); + String object = (String) ctr.getData("Text"); + String html = (String) ctr.getData("Html"); + String url = (String) ctr.getData("Url"); + + final Label l = new Label(); l.setCaption("Generated from HTML5 drag:"); if (object != null) { l.setValue(object); @@ -116,7 +125,28 @@ public class DragDropPane extends DragAndDropWrapper implements DropHandler { l.setValue("HTML5 dd"); } - l.setDescription(content); + Html5File[] files = wtr.getFiles(); + if (files != null) { + for (Html5File html5File : files) { + l.setCaption(html5File.getFileName()); + html5File.setReceiver(new Receiver() { + public OutputStream receiveUpload(String filename, + String MIMEType) { + + ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream() { + @Override + public void close() throws IOException { + super.close(); + l.setValue((new String(toByteArray()) + .substring(0, 80) + "...")); + } + }; + return byteArrayOutputStream; + } + }); + } + } + l.setSizeUndefined(); root.addComponent(l);