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 <[email protected]> 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();"; + } }
