From: Matti Tahvonen Date: Thu, 29 Apr 2010 14:21:14 +0000 (+0000) Subject: fixes #4605 X-Git-Tag: 6.7.0.beta1~1670^2~30 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=23d0ac7979b4591a5ccac3aac3a8de2dc1d35abd;p=vaadin-framework.git fixes #4605 svn changeset:12930/svn branch:6.3 --- diff --git a/src/com/vaadin/terminal/gwt/client/ui/UploadIFrameOnloadStrategy.java b/src/com/vaadin/terminal/gwt/client/ui/UploadIFrameOnloadStrategy.java new file mode 100644 index 0000000000..a79d1cd685 --- /dev/null +++ b/src/com/vaadin/terminal/gwt/client/ui/UploadIFrameOnloadStrategy.java @@ -0,0 +1,22 @@ +package com.vaadin.terminal.gwt.client.ui; + +public class UploadIFrameOnloadStrategy { + + native void hookEvents(com.google.gwt.dom.client.Element iframe, + VUpload upload) + /*-{ + iframe.onload = function() { + upload.@com.vaadin.terminal.gwt.client.ui.VUpload::onSubmitComplete()(); + }; + }-*/; + + /** + * @param iframe + * the iframe whose onLoad event is to be cleaned + */ + native void unHookEvents(com.google.gwt.dom.client.Element iframe) + /*-{ + iframe.onload = null; + }-*/; + +} diff --git a/src/com/vaadin/terminal/gwt/client/ui/UploadIFrameOnloadStrategyIE.java b/src/com/vaadin/terminal/gwt/client/ui/UploadIFrameOnloadStrategyIE.java new file mode 100644 index 0000000000..698d630b4f --- /dev/null +++ b/src/com/vaadin/terminal/gwt/client/ui/UploadIFrameOnloadStrategyIE.java @@ -0,0 +1,26 @@ +package com.vaadin.terminal.gwt.client.ui; + +import com.google.gwt.dom.client.Element; + +/** + * IE does not have onload, detect onload via readystatechange + * + */ +public class UploadIFrameOnloadStrategyIE extends UploadIFrameOnloadStrategy { + @Override + native void hookEvents(Element iframe, VUpload upload) + /*-{ + iframe.onreadystatechange = function() { + if (iframe.readyState == 'complete') { + upload.@com.vaadin.terminal.gwt.client.ui.VUpload::onSubmitComplete()(); + } + }; + }-*/; + + @Override + native void unHookEvents(Element iframe) + /*-{ + iframe.onreadystatechange = null; + }-*/; + +} diff --git a/src/com/vaadin/terminal/gwt/client/ui/VUpload.java b/src/com/vaadin/terminal/gwt/client/ui/VUpload.java index aded833138..d164de79db 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VUpload.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VUpload.java @@ -4,8 +4,14 @@ package com.vaadin.terminal.gwt.client.ui; +import com.google.gwt.core.client.GWT; +import com.google.gwt.dom.client.DivElement; +import com.google.gwt.dom.client.Document; +import com.google.gwt.dom.client.FormElement; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.ClickHandler; +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.Event; import com.google.gwt.user.client.Timer; @@ -14,14 +20,18 @@ import com.google.gwt.user.client.ui.FlowPanel; import com.google.gwt.user.client.ui.FormPanel; import com.google.gwt.user.client.ui.Hidden; import com.google.gwt.user.client.ui.Panel; -import com.google.gwt.user.client.ui.FormPanel.SubmitCompleteHandler; -import com.google.gwt.user.client.ui.FormPanel.SubmitHandler; +import com.google.gwt.user.client.ui.SimplePanel; import com.vaadin.terminal.gwt.client.ApplicationConnection; import com.vaadin.terminal.gwt.client.Paintable; import com.vaadin.terminal.gwt.client.UIDL; -public class VUpload extends FormPanel implements Paintable, - SubmitCompleteHandler, SubmitHandler { +/** + * + * Note, we are not using GWT FormPanel as we want to listen submitcomplete + * events even though the upload component is already detached. + * + */ +public class VUpload extends SimplePanel implements Paintable { private final class MyFileUpload extends FileUpload { @Override @@ -53,6 +63,9 @@ public class VUpload extends FormPanel implements Paintable, Panel panel = new FlowPanel(); + UploadIFrameOnloadStrategy onloadstrategy = GWT + .create(UploadIFrameOnloadStrategy.class); + ApplicationConnection client; private String paintableId; @@ -82,10 +95,16 @@ public class VUpload extends FormPanel implements Paintable, private Hidden maxfilesize = new Hidden(); + private FormElement element; + + private com.google.gwt.dom.client.Element synthesizedFrame; + public VUpload() { - super(); - setEncoding(FormPanel.ENCODING_MULTIPART); - setMethod(FormPanel.METHOD_POST); + super(com.google.gwt.dom.client.Document.get().createFormElement()); + + element = getElement().cast(); + setEncoding(getElement(), FormPanel.ENCODING_MULTIPART); + element.setMethod(FormPanel.METHOD_POST); setWidget(panel); panel.add(maxfilesize); @@ -103,12 +122,16 @@ public class VUpload extends FormPanel implements Paintable, }); panel.add(submitButton); - addSubmitCompleteHandler(this); - addSubmitHandler(this); - setStyleName(CLASSNAME); } + private static native void setEncoding(Element form, String encoding) + /*-{ + form.enctype = encoding; + // For IE6 + form.encoding = encoding; + }-*/; + public void updateFromUIDL(UIDL uidl, ApplicationConnection client) { if (client.updateComponent(this, uidl, true)) { return; @@ -116,7 +139,7 @@ public class VUpload extends FormPanel implements Paintable, setImmediate(uidl.getBooleanAttribute("immediate")); this.client = client; paintableId = uidl.getId(); - setAction(client.getAppUri()); + element.setAction(client.getAppUri()); submitButton.setText(uidl.getStringAttribute("buttoncaption")); fu.setName(paintableId + "_file"); @@ -125,6 +148,7 @@ public class VUpload extends FormPanel implements Paintable, } else if (!uidl.getBooleanAttribute("state")) { // Enable the button only if an upload is not in progress enableUpload(); + ensureTargetFrame(); } } @@ -182,24 +206,38 @@ public class VUpload extends FormPanel implements Paintable, } } - public void onSubmitComplete(SubmitCompleteEvent event) { - if (client != null) { - if (t != null) { - t.cancel(); - } - ApplicationConnection.getConsole().log("Submit complete"); - client.sendPendingVariableChanges(); - } + /** + * Called by JSNI (hooked via {@link #onloadstrategy}) + */ + @SuppressWarnings("unused") + private void onSubmitComplete() { + /* Needs to be run dereferred to avoid various browser issues. */ + DeferredCommand.addCommand(new Command() { + public void execute() { + if (client != null) { + if (t != null) { + t.cancel(); + } + ApplicationConnection.getConsole().log("Submit complete"); + client.sendPendingVariableChanges(); + } - rebuildPanel(); + rebuildPanel(); - submitted = false; - enableUpload(); + submitted = false; + enableUpload(); + if (!isAttached()) { + /* + * Upload is complete when upload is already abandoned. + */ + cleanTargetFrame(); + } + } + }); } - public void onSubmit(SubmitEvent event) { + private void submit() { if (fu.getFilename().length() == 0 || submitted || !enabled) { - event.cancel(); ApplicationConnection .getConsole() .log( @@ -210,6 +248,7 @@ public class VUpload extends FormPanel implements Paintable, // before upload client.sendPendingVariableChanges(); + element.submit(); submitted = true; ApplicationConnection.getConsole().log("Submitted form"); @@ -222,10 +261,62 @@ public class VUpload extends FormPanel implements Paintable, t = new Timer() { @Override public void run() { + ApplicationConnection + .getConsole() + .log( + "Visiting server to see if upload started event changed UI."); client.sendPendingVariableChanges(); } }; t.schedule(800); } + @Override + protected void onAttach() { + super.onAttach(); + if (client != null) { + ensureTargetFrame(); + } + } + + private void ensureTargetFrame() { + if (synthesizedFrame == null) { + // Attach a hidden IFrame to the form. This is the target iframe to + // which + // the form will be submitted. We have to create the iframe using + // innerHTML, + // because setting an iframe's 'name' property dynamically doesn't + // work on + // most browsers. + DivElement dummy = Document.get().createDivElement(); + dummy.setInnerHTML("