From fc22df908de55f85f4ff7264e6611bc00f5c5caa Mon Sep 17 00:00:00 2001 From: "jeremy@jermolene.com" Date: Tue, 2 May 2023 11:37:37 +0100 Subject: [PATCH] Make the number of outstanding HTTP requests available in a state tiddler --- core/modules/utils/dom/http.js | 59 ++++++++++++++----- ...etMessage_ tm-http-cancel-all-requests.tid | 12 ++++ ...essage_ tm-http-request Example Zotero.tid | 3 +- .../WidgetMessage_ tm-http-request.tid | 2 + 4 files changed, 60 insertions(+), 16 deletions(-) create mode 100644 editions/tw5.com/tiddlers/messages/WidgetMessage_ tm-http-cancel-all-requests.tid diff --git a/core/modules/utils/dom/http.js b/core/modules/utils/dom/http.js index 14270eef7..d16ea5208 100644 --- a/core/modules/utils/dom/http.js +++ b/core/modules/utils/dom/http.js @@ -13,20 +13,53 @@ HTTP support "use strict"; /* -Manage tm-http-request events +Manage tm-http-request events. Options include: +wiki: Reference to the wiki to be used for state tiddler tracking +stateTrackerTitle: Title of tiddler to be used for state tiddler tracking */ function HttpClient(options) { options = options || {}; this.nextId = 1; + this.wiki = options.wiki || $tw.wiki; + this.stateTrackerTitle = options.stateTrackerTitle || "$:/state/http-requests"; this.requests = []; // Array of {id: string,request: HttpClientRequest} + this.updateRequestTracker(); } +/* +Return the index into this.requests[] corresponding to a given ID. Returns null if not found +*/ +HttpClient.prototype.getRequestIndex = function(targetId) { + var targetIndex = null; + $tw.utils.each(this.requests,function(requestInfo,index) { + if(requestInfo.id === targetId) { + targetIndex = index; + } + }); + return targetIndex; +}; + +/* +Update the state tiddler that is tracking the outstanding requests +*/ +HttpClient.prototype.updateRequestTracker = function() { + this.wiki.addTiddler({title: this.stateTrackerTitle, text: "" + this.requests.length}); +}; + HttpClient.prototype.initiateHttpRequest = function(options) { - var id = this.nextId, + var self = this, + id = this.nextId, request = new HttpClientRequest(options); this.nextId += 1; this.requests.push({id: id, request: request}); - request.send(); + this.updateRequestTracker(); + request.send(function(err) { + var targetIndex = self.getRequestIndex(id); + if(targetIndex !== null) { + self.requests.splice(targetIndex,1); + self.updateRequestTracker(); + } + }); return id; }; @@ -36,18 +69,15 @@ HttpClient.prototype.cancelAllHttpRequests = function() { requestInfo.request.cancel(); }); this.requests = []; + this.updateRequestTracker(); }; HttpClient.prototype.cancelHttpRequest = function(targetId) { - var targetIndex = null; - $tw.utils.each(this.requests,function(requestInfo,index) { - if(requestInfo.id === targetId) { - targetIndex = index; - } - }); + var targetIndex = this.getRequestIndex(targetId); if(targetIndex !== null) { this.requests[targetIndex].request.cancel(); this.requests.splice(targetIndex,1); + this.updateRequestTracker(); } }; @@ -95,7 +125,7 @@ function HttpClientRequest(options) { }); } -HttpClientRequest.prototype.send = function() { +HttpClientRequest.prototype.send = function(callback) { var self = this, setBinding = function(title,text) { if(title) { @@ -124,7 +154,8 @@ HttpClientRequest.prototype.send = function() { headers: this.requestHeaders, data: this.body, callback: function(err,data,xhr) { - var success = (xhr.status >= 200 && xhr.status < 300) ? "complete" : "error", + var hasSucceeded = xhr.status >= 200 && xhr.status < 300, + completionCode = hasSucceeded ? "complete" : "error", headers = {}; $tw.utils.each(xhr.getAllResponseHeaders().split("\r\n"),function(line) { var pos = line.indexOf(":"); @@ -132,7 +163,7 @@ HttpClientRequest.prototype.send = function() { headers[line.substr(0,pos)] = line.substr(pos + 1).trim(); } }); - setBinding(self.bindStatus,success); + setBinding(self.bindStatus,completionCode); setBinding(self.bindProgress,"100"); var resultVariables = { status: xhr.status.toString(), @@ -141,11 +172,11 @@ HttpClientRequest.prototype.send = function() { data: (data || "").toString(), headers: JSON.stringify(headers) }; - // Update the request tracker tiddler self.wiki.addTiddler(new $tw.Tiddler(self.wiki.getTiddler(requestTrackerTitle),{ - status: success, + status: completionCode, })); self.wiki.invokeActionString(self.completionActions,undefined,$tw.utils.extend({},self.variables,resultVariables),{parentWidget: $tw.rootWidget}); + callback(hasSucceeded ? null : xhr.statusText); // console.log("Back!",err,data,xhr); }, progress: function(lengthComputable,loaded,total) { diff --git a/editions/tw5.com/tiddlers/messages/WidgetMessage_ tm-http-cancel-all-requests.tid b/editions/tw5.com/tiddlers/messages/WidgetMessage_ tm-http-cancel-all-requests.tid new file mode 100644 index 000000000..df94e5a0b --- /dev/null +++ b/editions/tw5.com/tiddlers/messages/WidgetMessage_ tm-http-cancel-all-requests.tid @@ -0,0 +1,12 @@ +caption: tm-http-cancel-all-requests +created: 20230429161453032 +modified: 20230429161453032 +tags: Messages +title: WidgetMessage: tm-http-cancel-all-requests +type: text/vnd.tiddlywiki + +The ''tm-http-cancel-all-requests'' message is used to cancel all outstanding HTTP requests initiated with [[WidgetMessage: tm-http-request]]. + +Note that the state tiddler $:/state/http-requests contains a number representing the number of outstanding HTTP requests in progress. + +It does not take any parameters. diff --git a/editions/tw5.com/tiddlers/messages/WidgetMessage_ tm-http-request Example Zotero.tid b/editions/tw5.com/tiddlers/messages/WidgetMessage_ tm-http-request Example Zotero.tid index 3c1030b28..ea64dd3a2 100644 --- a/editions/tw5.com/tiddlers/messages/WidgetMessage_ tm-http-request Example Zotero.tid +++ b/editions/tw5.com/tiddlers/messages/WidgetMessage_ tm-http-request Example Zotero.tid @@ -81,7 +81,6 @@ https://api.zotero.org/groups/{{$:/config/zotero-group}}/items/ <$macrocall $name="zotero-get-items" start="0" limit="50"/> \end - <> <$button actions=<>> @@ -90,7 +89,7 @@ Start import from Zotero group <$button message="tm-http-cancel-all-requests"> Cancel all HTTP requests - + Outstanding requests: {{$:/state/http-requests}} <$list filter="[tag[$:/tags/ZoteroImport]limit[1]]" variable="ignore"> diff --git a/editions/tw5.com/tiddlers/messages/WidgetMessage_ tm-http-request.tid b/editions/tw5.com/tiddlers/messages/WidgetMessage_ tm-http-request.tid index f74fdfb55..f6c82e760 100644 --- a/editions/tw5.com/tiddlers/messages/WidgetMessage_ tm-http-request.tid +++ b/editions/tw5.com/tiddlers/messages/WidgetMessage_ tm-http-request.tid @@ -44,6 +44,8 @@ The following variables are passed to the progress handler: |loaded |Number of bytes loaded so far | |total |Total number bytes to be loaded | +Note that the state tiddler $:/state/http-requests contains a number representing the number of outstanding HTTP requests in progress. + !! Examples * [[Zotero's|https://www.zotero.org/]] API for retrieving reference items: [[WidgetMessage: tm-http-request Example - Zotero]]