You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@wicket.apache.org by re...@apache.org on 2020/02/24 16:49:14 UTC

[wicket] 01/01: [WICKET-6750] allow to abort currently executing request for a given Ajax channel

This is an automated email from the ASF dual-hosted git repository.

reiern70 pushed a commit to branch improvement/reiern70/WICKET-6750-client-side-abortion-of-ajax-requests
in repository https://gitbox.apache.org/repos/asf/wicket.git

commit f97579d235f9b56d82adb731da2ff27fde4cef75
Author: reiern70 <re...@gmail.com>
AuthorDate: Sun Feb 23 09:08:57 2020 +0200

    [WICKET-6750] allow to abort currently executing request for a given Ajax channel
---
 .../wicket/ajax/res/js/wicket-ajax-jquery.js       | 61 ++++++++++++++++++++--
 .../examples/ajax/builtin/AjaxApplication.java     |  2 +
 .../examples/ajax/builtin/FileUploadPage.html      |  2 +-
 .../examples/ajax/builtin/FileUploadPage.java      | 48 ++++++++++++++---
 4 files changed, 100 insertions(+), 13 deletions(-)

diff --git a/wicket-core/src/main/java/org/apache/wicket/ajax/res/js/wicket-ajax-jquery.js b/wicket-core/src/main/java/org/apache/wicket/ajax/res/js/wicket-ajax-jquery.js
index 3ee9f3b..3b36488 100644
--- a/wicket-core/src/main/java/org/apache/wicket/ajax/res/js/wicket-ajax-jquery.js
+++ b/wicket-core/src/main/java/org/apache/wicket/ajax/res/js/wicket-ajax-jquery.js
@@ -278,6 +278,20 @@
 			}
 		},
 
+		// aborts current request is there is any running
+		abort: function () {
+			if (isUndef(this.jqXHR)) {
+				Wicket.Log.debug("There is no executing request for channel " + this.name)
+			} else {
+				// if request has not finished yet, then abort it
+				if (this.jqXHR.readyState !== 4) {
+					this.jqXHR.abort();
+				} else {
+					Wicket.Log.debug("There is no executing request for channel " + this.name)
+				}
+			}
+		},
+
 		done: function () {
 			var callback = null;
 
@@ -306,8 +320,8 @@
 			this.channels = {};
 		},
 
-		// Schedules the callback to channel with given name.
-		schedule: function (channel, callback) {
+		// creates or retirves a channel
+		_createOrGetChanel: function (channel) {
 			var parsed = new Wicket.Channel(channel);
 			var c = this.channels[parsed.name];
 			if (isUndef(c)) {
@@ -316,7 +330,22 @@
 			} else {
 				c.type = parsed.type;
 			}
-			return c.schedule(callback);
+			return c;
+		},
+
+		// Schedules the callback to channel with given name.
+		schedule: function (channel, callback) {
+			return this._createOrGetChanel(channel).schedule(callback);
+		},
+
+		// registers current jqXHR with channel using it
+		registerCurrentAjaxRequest: function(channel, jqXHR) {
+			this._createOrGetChanel(channel).jqXHR = jqXHR;
+		},
+
+		// aborts the current request for channel with name channel
+		abortCurrentRequestForChannel: function(channel) {
+			this._createOrGetChanel(channel).abort();
 		},
 
 		// Tells the ChannelManager that the current callback in channel with given name
@@ -547,7 +576,6 @@
 		 */
 		ajax: function (attrs) {
 			this._initializeDefaults(attrs);
-
 			var res = Wicket.channelManager.schedule(attrs.ch, Wicket.bind(function () {
 				this.doAjax(attrs);
 			}, this));
@@ -555,6 +583,23 @@
 		},
 
 		/**
+		 * Aborts current AJAX request, if any is running, for default channel.
+		 * WARNING! Mind that this does not implies and server immediately will know about
+		 * request being aborted and server side processing (and page lock night continue).
+		 * This method might prove useful, for instance, in order to abort big AJAX
+		 * uploads.
+		 */
+		abortRequest: function (channel) {
+			var attr = {};
+			if (isUndef(channel) || typeof(channel) !== 'string') {
+				this._initializeDefaults(attr);
+			} else {
+				attr.ch = channel;
+			}
+			Wicket.channelManager.abortCurrentRequestForChannel(attr.ch);
+		},
+
+		/**
 		 * Is an element still present for Ajax requests. 
 		 */
 		_isPresent: function(id) {
@@ -696,6 +741,9 @@
 				contentType: wwwFormUrlEncoded,
 				
 				beforeSend: function (jqXHR, settings) {
+					if (attrs.async) {
+						Wicket.channelManager.registerCurrentAjaxRequest(attrs.ch, jqXHR);
+					}
 					self._executeHandlers(attrs.bsh, attrs, jqXHR, settings);
 					we.publish(topic.AJAX_CALL_BEFORE_SEND, attrs, jqXHR, settings);
 
@@ -1646,6 +1694,11 @@
 				return Wicket.Ajax.ajax(attrs);
 			},
 
+			abortRequest: function(channel) {
+				var call = new Wicket.Ajax.Call();
+				call.abortRequest(channel);
+			},
+
 			ajax: function(attrs) {
 
 				attrs.c = attrs.c || window;
diff --git a/wicket-examples/src/main/java/org/apache/wicket/examples/ajax/builtin/AjaxApplication.java b/wicket-examples/src/main/java/org/apache/wicket/examples/ajax/builtin/AjaxApplication.java
index 77ad598..e0e154f 100644
--- a/wicket-examples/src/main/java/org/apache/wicket/examples/ajax/builtin/AjaxApplication.java
+++ b/wicket-examples/src/main/java/org/apache/wicket/examples/ajax/builtin/AjaxApplication.java
@@ -37,6 +37,8 @@ public class AjaxApplication extends WicketExampleApplication
 	{
 		super.init();
 
+		getCsp().blocking().disabled();
+
 		getApplicationSettings().setUploadProgressUpdatesEnabled(true);
 
 		getResourceSettings().setThrowExceptionOnMissingResource(false);
diff --git a/wicket-examples/src/main/java/org/apache/wicket/examples/ajax/builtin/FileUploadPage.html b/wicket-examples/src/main/java/org/apache/wicket/examples/ajax/builtin/FileUploadPage.html
index 3d54b24..06b4026 100644
--- a/wicket-examples/src/main/java/org/apache/wicket/examples/ajax/builtin/FileUploadPage.html
+++ b/wicket-examples/src/main/java/org/apache/wicket/examples/ajax/builtin/FileUploadPage.html
@@ -12,7 +12,7 @@ Demonstrates Wicket's ability to transparently handle multipart forms via AJAX.<
 	Text field: <input wicket:id="text" type="text"/><br/>
 	File field: <input wicket:id="file" type="file"/> (<span wicket:id="max"></span> max)<br/><br/>
 	<div wicket:id="progress"></div>
-	<input type="submit" value="Regular Submit"/> <input wicket:id="ajaxSubmit" type="button" value="Ajax Submit"/>
+	<input type="submit" value="Regular Submit"/> <input wicket:id="ajaxSubmit" type="button" value="Ajax Submit"/> <a wicket:id="cancelUpload" style="display: none;">Cancel AJAX upload</a>
 </form>
 
 <div wicket:id="drop" class="drop-zone">
diff --git a/wicket-examples/src/main/java/org/apache/wicket/examples/ajax/builtin/FileUploadPage.java b/wicket-examples/src/main/java/org/apache/wicket/examples/ajax/builtin/FileUploadPage.java
index 598efee..945a001 100644
--- a/wicket-examples/src/main/java/org/apache/wicket/examples/ajax/builtin/FileUploadPage.java
+++ b/wicket-examples/src/main/java/org/apache/wicket/examples/ajax/builtin/FileUploadPage.java
@@ -21,9 +21,11 @@ import java.util.List;
 import org.apache.commons.fileupload.FileUploadException;
 import org.apache.wicket.Component;
 import org.apache.wicket.ajax.AjaxRequestTarget;
+import org.apache.wicket.ajax.attributes.AjaxRequestAttributes;
 import org.apache.wicket.ajax.markup.html.form.AjaxButton;
 import org.apache.wicket.extensions.ajax.AjaxFileDropBehavior;
 import org.apache.wicket.extensions.ajax.markup.html.form.upload.UploadProgressBar;
+import org.apache.wicket.markup.ComponentTag;
 import org.apache.wicket.markup.html.WebMarkupContainer;
 import org.apache.wicket.markup.html.basic.Label;
 import org.apache.wicket.markup.html.form.Form;
@@ -46,6 +48,7 @@ public class FileUploadPage extends BasePage
 
 	private final FileUploadField file;
 	private final TextField<String> text;
+	private WebMarkupContainer cancelUpload;
 
 	/**
 	 * Constructor
@@ -79,7 +82,8 @@ public class FileUploadPage extends BasePage
 				}
 			}
 		};
-		form.setMaxSize(Bytes.megabytes(1));
+		///form.setMaxSize(Bytes.megabytes(1));
+		form.setMaxSize(Bytes.megabytes(500));
 		add(form);
 
 		// create a textfield to demo non-file content
@@ -104,19 +108,44 @@ public class FileUploadPage extends BasePage
 				info("This request was processed using AJAX");
 
 				// ajax-update the feedback panel
-				target.add(feedback);
+				target.add(feedback, cancelUpload);
 			}
 
 			@Override
 			protected void onError(AjaxRequestTarget target)
 			{
 				// update feedback to display errors
-				target.add(feedback);
+				target.add(feedback, cancelUpload);
 			}
 
+			@Override
+			protected void onComponentTag(ComponentTag tag) {
+				super.onComponentTag(tag);
+				tag.put("onclick", showAbortButtonScript());
+			}
 		});
-		
-		WebMarkupContainer drop = new WebMarkupContainer("drop");
+
+		cancelUpload = new WebMarkupContainer("cancelUpload")
+		{
+			@Override
+			protected void onComponentTag(ComponentTag tag)
+			{
+				super.onComponentTag(tag);
+				// tries to abort current upload
+				tag.put("onclick", "Wicket.Ajax.abortRequest();");
+				tag.put("style", "display: none;");
+			}
+		};
+		cancelUpload.setOutputMarkupId(true);
+		form.add(cancelUpload);
+
+		WebMarkupContainer drop = new WebMarkupContainer("drop") {
+			@Override
+			protected void onComponentTag(ComponentTag tag) {
+				super.onComponentTag(tag);
+				tag.put("ondrop", "Wicket.Ajax.abortRequest();");
+			}
+		};
 		drop.add(new AjaxFileDropBehavior() {
 			protected void onFileUpload(AjaxRequestTarget target, List<FileUpload> files) {
 			    
@@ -133,17 +162,20 @@ public class FileUploadPage extends BasePage
 				    }
 				}
 				
-				target.add(feedback);
+				target.add(feedback, cancelUpload);
 			}
 			
 			@Override
 			protected void onError(AjaxRequestTarget target, FileUploadException fux)
 			{
 				info(fux.getMessage());
-				
-				target.add(feedback);				
+				target.add(feedback,cancelUpload);
 			}
 		});
 		add(drop);
 	}
+
+	private String showAbortButtonScript() {
+		return "$('#" + cancelUpload.getMarkupId() + "').show();";
+	}
 }