From c208c55a22436e0a9cae8b47a5e9fcbcb99cb661 Mon Sep 17 00:00:00 2001 From: Jermolene Date: Tue, 2 Oct 2018 14:16:58 +0100 Subject: [PATCH 1/6] Finish web server API docs --- .../TiddlyWeb JSON tiddler format.tid | 33 ++++++++++++++ ...ebServer Routing.tid => WebServer API.tid} | 4 +- .../WebServer API_ Delete Tiddler.tid | 19 ++++++++ ... API_ Force Basic Authentication Login.tid | 25 +++++++++++ .../WebServer API_ Get All Tiddlers.tid | 22 ++++++++++ .../webserver/WebServer API_ Get Favicon.tid | 21 +++++++++ .../webserver/WebServer API_ Get File.tid | 25 +++++++++++ .../WebServer API_ Get Server Status.tid | 43 +++++++++++++++++++ .../WebServer API_ Get Tiddler Rendering.tid | 23 ++++++++++ .../webserver/WebServer API_ Get Tiddler.tid | 23 ++++++++++ .../webserver/WebServer API_ Get Wiki.tid | 23 ++++++++++ .../webserver/WebServer API_ Put Tiddler.tid | 23 ++++++++++ .../tw5.com/tiddlers/webserver/WebServer.tid | 4 +- 13 files changed, 284 insertions(+), 4 deletions(-) create mode 100644 editions/tw5.com/tiddlers/webserver/TiddlyWeb JSON tiddler format.tid rename editions/tw5.com/tiddlers/webserver/{WebServer Routing.tid => WebServer API.tid} (56%) create mode 100644 editions/tw5.com/tiddlers/webserver/WebServer API_ Delete Tiddler.tid create mode 100644 editions/tw5.com/tiddlers/webserver/WebServer API_ Force Basic Authentication Login.tid create mode 100644 editions/tw5.com/tiddlers/webserver/WebServer API_ Get All Tiddlers.tid create mode 100644 editions/tw5.com/tiddlers/webserver/WebServer API_ Get Favicon.tid create mode 100644 editions/tw5.com/tiddlers/webserver/WebServer API_ Get File.tid create mode 100644 editions/tw5.com/tiddlers/webserver/WebServer API_ Get Server Status.tid create mode 100644 editions/tw5.com/tiddlers/webserver/WebServer API_ Get Tiddler Rendering.tid create mode 100644 editions/tw5.com/tiddlers/webserver/WebServer API_ Get Tiddler.tid create mode 100644 editions/tw5.com/tiddlers/webserver/WebServer API_ Get Wiki.tid create mode 100644 editions/tw5.com/tiddlers/webserver/WebServer API_ Put Tiddler.tid diff --git a/editions/tw5.com/tiddlers/webserver/TiddlyWeb JSON tiddler format.tid b/editions/tw5.com/tiddlers/webserver/TiddlyWeb JSON tiddler format.tid new file mode 100644 index 000000000..cbd218674 --- /dev/null +++ b/editions/tw5.com/tiddlers/webserver/TiddlyWeb JSON tiddler format.tid @@ -0,0 +1,33 @@ +created: 20181002130513206 +modified: 20181002131123893 +tags: [[WebServer Guides]] +title: TiddlyWeb JSON tiddler format +type: text/vnd.tiddlywiki + +The web server API uses tiddlers in a special format originally designed for TiddlyWeb: + +* Field values are represented as strings. Lists (like the ''tags'' and ''list'' fields) use double square brackets to quote values that contain spaces +* Tiddlers are represented as an object containing any of a fixed set of standard fields, with custom fields being relegated to a special property called ''fields'' +* The standard fields are: ''bag'', ''created'', ''creator'', ''modified'', ''modifier'', ''permissions'', ''recipe'', ''revision'', ''tags'', ''text'', ''title'', ''type'', ''uri'' + +For example, consider the following tiddler: + +``` +{ + "title": "HelloThere", + "tags": "FirstTag [[Second Tag]]", + "my-custom-field": "Field value" +} +``` + +In transit over the API, the tiddler would be converted to the following format: + +``` +{ + "title": "HelloThere", + "tags": "FirstTag [[Second Tag]]", + "fields": { + "my-custom-field": "Field value" + } +} +``` diff --git a/editions/tw5.com/tiddlers/webserver/WebServer Routing.tid b/editions/tw5.com/tiddlers/webserver/WebServer API.tid similarity index 56% rename from editions/tw5.com/tiddlers/webserver/WebServer Routing.tid rename to editions/tw5.com/tiddlers/webserver/WebServer API.tid index 8364ec379..cd937537a 100644 --- a/editions/tw5.com/tiddlers/webserver/WebServer Routing.tid +++ b/editions/tw5.com/tiddlers/webserver/WebServer API.tid @@ -1,6 +1,6 @@ created: 20180630194032981 -modified: 20180630194042074 +modified: 20181002103516011 tags: WebServer -title: WebServer Routing +title: WebServer API type: text/vnd.tiddlywiki diff --git a/editions/tw5.com/tiddlers/webserver/WebServer API_ Delete Tiddler.tid b/editions/tw5.com/tiddlers/webserver/WebServer API_ Delete Tiddler.tid new file mode 100644 index 000000000..962d74902 --- /dev/null +++ b/editions/tw5.com/tiddlers/webserver/WebServer API_ Delete Tiddler.tid @@ -0,0 +1,19 @@ +created: 20181002112106875 +modified: 20181002124355314 +tags: [[WebServer API]] +title: WebServer API: Delete Tiddler +type: text/vnd.tiddlywiki + +Delete a tiddler + +``` +DELETE /bags/default/tiddlers/{title} +``` + +Parameters: + +* ''title'' - URI encoded title of the tiddler to delete + +Response: + +* 204 No Content \ No newline at end of file diff --git a/editions/tw5.com/tiddlers/webserver/WebServer API_ Force Basic Authentication Login.tid b/editions/tw5.com/tiddlers/webserver/WebServer API_ Force Basic Authentication Login.tid new file mode 100644 index 000000000..356213ac8 --- /dev/null +++ b/editions/tw5.com/tiddlers/webserver/WebServer API_ Force Basic Authentication Login.tid @@ -0,0 +1,25 @@ +created: 20181002124825195 +modified: 20181002125214104 +tags: [[WebServer API]] +title: WebServer API: Force Basic Authentication Login +type: text/vnd.tiddlywiki + +Forces the server to request basic authentication login, and then redirects to the root + +``` +GET /login-basic +``` + +Requests an basic authentication from the browser, and redirects to the root if successful. + +Parameters: + +* none + +Response: + +* 302 Found +*> `Location: /` +* 401 Unauthorized +*> `WWW-Authenticate: Basic realm="Please provide your username and password to login to " + diff --git a/editions/tw5.com/tiddlers/webserver/WebServer API_ Get All Tiddlers.tid b/editions/tw5.com/tiddlers/webserver/WebServer API_ Get All Tiddlers.tid new file mode 100644 index 000000000..da58738b2 --- /dev/null +++ b/editions/tw5.com/tiddlers/webserver/WebServer API_ Get All Tiddlers.tid @@ -0,0 +1,22 @@ +created: 20181002131215403 +modified: 20181002131322026 +tags: [[WebServer API]] +title: WebServer API: Get All Tiddlers +type: text/vnd.tiddlywiki + +Gets an array of all raw tiddlers, excluding the ''text'' field. + +``` +GET /recipes/default/tiddlers/tiddlers.json +``` + +Parameters: + +* none + +Response: + + +* 200 OK +*> `Content-Type: application/json` +*> Body: array of tiddlers in [[TiddlyWeb JSON tiddler format]] diff --git a/editions/tw5.com/tiddlers/webserver/WebServer API_ Get Favicon.tid b/editions/tw5.com/tiddlers/webserver/WebServer API_ Get Favicon.tid new file mode 100644 index 000000000..6fe8ff6c6 --- /dev/null +++ b/editions/tw5.com/tiddlers/webserver/WebServer API_ Get Favicon.tid @@ -0,0 +1,21 @@ +created: 20181002123308575 +modified: 20181002124103586 +tags: [[WebServer API]] +title: WebServer API: Get Favicon +type: text/vnd.tiddlywiki + +Get the favicon for the wiki from the tiddler $:/favicon.ico + +``` +GET /favicon.ico +``` + +Parameters: + +* none + +Response: + +* 200 OK +*> `Content-Type: image/x-icon` +*> Body: image data from the tiddler $:/favicon.ico \ No newline at end of file diff --git a/editions/tw5.com/tiddlers/webserver/WebServer API_ Get File.tid b/editions/tw5.com/tiddlers/webserver/WebServer API_ Get File.tid new file mode 100644 index 000000000..cebac2501 --- /dev/null +++ b/editions/tw5.com/tiddlers/webserver/WebServer API_ Get File.tid @@ -0,0 +1,25 @@ +created: 20181002123907518 +modified: 20181002124345482 +tags: [[WebServer API]] +title: WebServer API: Get File +type: text/vnd.tiddlywiki + +Get the content of a static file. See +[[using the integrated static file server|Using the integrated static file server]] + +``` +GET /files/ +``` + +Parameters: + +* ''pathname'' - URI encoded path to the file + +Response: + +* 200 OK +*> `Content-Type: ` (determined from file extension) +*> Body: data retrieved from file +* 403 Forbidden +* 404 Not Found + diff --git a/editions/tw5.com/tiddlers/webserver/WebServer API_ Get Server Status.tid b/editions/tw5.com/tiddlers/webserver/WebServer API_ Get Server Status.tid new file mode 100644 index 000000000..6bcd1e4ac --- /dev/null +++ b/editions/tw5.com/tiddlers/webserver/WebServer API_ Get Server Status.tid @@ -0,0 +1,43 @@ +created: 20181002125229601 +modified: 20181002125840235 +tags: [[WebServer API]] +title: WebServer API: Get Server Status +type: text/vnd.tiddlywiki + +Get server status information + +``` +GET /status +``` + +Parameters: + +* none + +Response: + +* 200 OK +*> `Content-Type: application/json` +*> Body: see below + +The JSON data returned comprises the following properties: + +* ''username'' - the username of the currently authenticated user. If undefined, the [[WebServer Parameter: anon-username]] is returned instead +* ''anonymous'' - true if the current user is anonymous +* ''read_only'' - true if the current user is restricted to read only access to the server +* ''space'' - always contains the object `{recipe: "default"}` +* ''tiddlywiki_version'' - the current TiddlyWiki version + +For example: + +``` +{ + "username": "", + "anonymous": true, + "read_only": false, + "space": { + "recipe": "default" + }, + "tiddlywiki_version": "5.1.18" +} +``` diff --git a/editions/tw5.com/tiddlers/webserver/WebServer API_ Get Tiddler Rendering.tid b/editions/tw5.com/tiddlers/webserver/WebServer API_ Get Tiddler Rendering.tid new file mode 100644 index 000000000..5fb75e76a --- /dev/null +++ b/editions/tw5.com/tiddlers/webserver/WebServer API_ Get Tiddler Rendering.tid @@ -0,0 +1,23 @@ +created: 20181002125954409 +modified: 20181002130237725 +tags: [[WebServer API]] +title: WebServer API: Get Tiddler Rendering +type: text/vnd.tiddlywiki + +Gets a rendering of the specified tiddler. See [[using the read-only single tiddler view|Using the read-only single tiddler view]] for more details. + +``` +GET /{title} +``` + +Parameters: + +* ''title'' - URI encoded title of the tiddler to render + +Response: + + +* 200 OK +*> `Content-Type: ` +*> Body: tiddler rendering +* 404 Not Found diff --git a/editions/tw5.com/tiddlers/webserver/WebServer API_ Get Tiddler.tid b/editions/tw5.com/tiddlers/webserver/WebServer API_ Get Tiddler.tid new file mode 100644 index 000000000..f9889f23f --- /dev/null +++ b/editions/tw5.com/tiddlers/webserver/WebServer API_ Get Tiddler.tid @@ -0,0 +1,23 @@ +created: 20181002130310180 +modified: 20181002130457330 +tags: [[WebServer API]] +title: WebServer API: Get Tiddler +type: text/vnd.tiddlywiki + +Gets the raw fields of a tiddler + +``` +GET /recipes/default/tiddlers/{title} +``` + +Parameters: + +* ''title'' - URI encoded title of the tiddler to retrieve + +Response: + + +* 200 OK +*> `Content-Type: application/json` +*> Body: tiddler in [[TiddlyWeb JSON tiddler format]] +* 404 Not Found diff --git a/editions/tw5.com/tiddlers/webserver/WebServer API_ Get Wiki.tid b/editions/tw5.com/tiddlers/webserver/WebServer API_ Get Wiki.tid new file mode 100644 index 000000000..7e208d478 --- /dev/null +++ b/editions/tw5.com/tiddlers/webserver/WebServer API_ Get Wiki.tid @@ -0,0 +1,23 @@ +created: 20181002124430552 +modified: 20181002124755134 +tags: [[WebServer API]] +title: WebServer API: Get Wiki +type: text/vnd.tiddlywiki + +Get the main wiki + +``` +GET / +``` + +The wiki is composed by rendering the tiddler identified in the [[root-tiddler|WebServer Parameter: root-tiddler]] parameter with the render type in the [[root-render-type|WebServer Parameter: root-render-type]] parameter. This is then served with the content type from the [[root-serve-type|WebServer Parameter: root-serve-type]] parameter. + +Parameters: + +* none + +Response: + +* 200 OK +*> `Content-Type: text/html` +*> Body: data retrieved from file diff --git a/editions/tw5.com/tiddlers/webserver/WebServer API_ Put Tiddler.tid b/editions/tw5.com/tiddlers/webserver/WebServer API_ Put Tiddler.tid new file mode 100644 index 000000000..8bdedcf3b --- /dev/null +++ b/editions/tw5.com/tiddlers/webserver/WebServer API_ Put Tiddler.tid @@ -0,0 +1,23 @@ +created: 20181002131341062 +modified: 20181002131556452 +tags: [[WebServer API]] +title: WebServer API: Put Tiddler +type: text/vnd.tiddlywiki + +Saves the raw fields of a tiddler + +``` +PUT /recipes/default/tiddlers/{title} +``` + +The body should be in [[TiddlyWeb JSON tiddler format]]. + +Parameters: + +* ''title'' - URI encoded title of the tiddler to save + +Response: + +* 204 No Content +*> `Content-Type: text/plain` +*> `Etag: "default//<changecount>:"` diff --git a/editions/tw5.com/tiddlers/webserver/WebServer.tid b/editions/tw5.com/tiddlers/webserver/WebServer.tid index f32113630..031dfefb1 100644 --- a/editions/tw5.com/tiddlers/webserver/WebServer.tid +++ b/editions/tw5.com/tiddlers/webserver/WebServer.tid @@ -1,5 +1,5 @@ created: 20180626150526207 -modified: 20180703095555387 +modified: 20181002103605866 tags: ListenCommand ServerCommand Features title: WebServer type: text/vnd.tiddlywiki @@ -14,7 +14,7 @@ The web server listens for requests coming over the network, and performs the fo * [[Authentication|WebServer Authentication]] is the process of identifying the current user. TiddlyWiki supports three types of authentication: [[Anonymous|WebServer Anonymous Access]], [[Basic|WebServer Basic Authentication]] and [[Header|WebServer Header Authentication]] * [[Authorization|WebServer Authorization]] is the process of determining which resources may be accessed by a particular user. TiddlyWiki implements a simple scheme whereby read and write access to the wiki can be independently controlled. -* [[Routing|WebServer Routing]] is the process of acting on the request, and returning any required data. +* Routing is the process of dispatching the request to the [[API handler|WebServer API]], and returning any required data. ! Usage From f0c6a09ea7f4922949d16da0debddeff7ae1c1ae Mon Sep 17 00:00:00 2001 From: Jermolene <jeremy@jermolene.com> Date: Tue, 2 Oct 2018 14:19:06 +0100 Subject: [PATCH 2/6] Docs update --- editions/tw5.com/tiddlers/webserver/WebServer API.tid | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/editions/tw5.com/tiddlers/webserver/WebServer API.tid b/editions/tw5.com/tiddlers/webserver/WebServer API.tid index cd937537a..c124cd0b9 100644 --- a/editions/tw5.com/tiddlers/webserver/WebServer API.tid +++ b/editions/tw5.com/tiddlers/webserver/WebServer API.tid @@ -1,6 +1,9 @@ created: 20180630194032981 -modified: 20181002103516011 +modified: 20181002131850742 tags: WebServer title: WebServer API type: text/vnd.tiddlywiki +The TiddlyWiki [[WebServer]] API supports the following routes: + +<<list-links "[tag[WebServer API]sort[]]">> \ No newline at end of file From eeb453d4715a45fda88f4d123d8cfcb90e5b35be Mon Sep 17 00:00:00 2001 From: Jermolene <jeremy@jermolene.com> Date: Tue, 2 Oct 2018 14:54:46 +0100 Subject: [PATCH 3/6] Docs update --- ... Rendering.tid => WebServer API_ Get Rendered Tiddler.tid} | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) rename editions/tw5.com/tiddlers/webserver/{WebServer API_ Get Tiddler Rendering.tid => WebServer API_ Get Rendered Tiddler.tid} (85%) diff --git a/editions/tw5.com/tiddlers/webserver/WebServer API_ Get Tiddler Rendering.tid b/editions/tw5.com/tiddlers/webserver/WebServer API_ Get Rendered Tiddler.tid similarity index 85% rename from editions/tw5.com/tiddlers/webserver/WebServer API_ Get Tiddler Rendering.tid rename to editions/tw5.com/tiddlers/webserver/WebServer API_ Get Rendered Tiddler.tid index 5fb75e76a..ef7512062 100644 --- a/editions/tw5.com/tiddlers/webserver/WebServer API_ Get Tiddler Rendering.tid +++ b/editions/tw5.com/tiddlers/webserver/WebServer API_ Get Rendered Tiddler.tid @@ -1,7 +1,7 @@ created: 20181002125954409 -modified: 20181002130237725 +modified: 20181002135401854 tags: [[WebServer API]] -title: WebServer API: Get Tiddler Rendering +title: WebServer API: Get Rendered Tiddler type: text/vnd.tiddlywiki Gets a rendering of the specified tiddler. See [[using the read-only single tiddler view|Using the read-only single tiddler view]] for more details. From 240bd7bec4e4e1fba33c26a124790608fe8a8721 Mon Sep 17 00:00:00 2001 From: Jermolene <jeremy@jermolene.com> Date: Wed, 3 Oct 2018 21:42:34 +0100 Subject: [PATCH 4/6] Docs typo --- .../tiddlers/webserver/WebServer API_ Get All Tiddlers.tid | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/editions/tw5.com/tiddlers/webserver/WebServer API_ Get All Tiddlers.tid b/editions/tw5.com/tiddlers/webserver/WebServer API_ Get All Tiddlers.tid index da58738b2..ae39eca7d 100644 --- a/editions/tw5.com/tiddlers/webserver/WebServer API_ Get All Tiddlers.tid +++ b/editions/tw5.com/tiddlers/webserver/WebServer API_ Get All Tiddlers.tid @@ -1,5 +1,5 @@ created: 20181002131215403 -modified: 20181002131322026 +modified: 20181003174025431 tags: [[WebServer API]] title: WebServer API: Get All Tiddlers type: text/vnd.tiddlywiki @@ -7,7 +7,7 @@ type: text/vnd.tiddlywiki Gets an array of all raw tiddlers, excluding the ''text'' field. ``` -GET /recipes/default/tiddlers/tiddlers.json +GET /recipes/default/tiddlers.json ``` Parameters: From 5dcdff4b37eedd8ff465dcce97011dcdd840da85 Mon Sep 17 00:00:00 2001 From: BurningTreeC <hypnotizedkangaroo@gmail.com> Date: Sun, 7 Oct 2018 11:23:41 +0200 Subject: [PATCH 5/6] Fix scrolling with tc-adjust-top-of-scroll (#3467) not multiplying `offset` with t causes jumps at the first animation steps, where the offset value is bigger than `endY - scrollPosition.y` --- core/modules/utils/dom/scroller.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/modules/utils/dom/scroller.js b/core/modules/utils/dom/scroller.js index d87ef03f2..f7f5c0c3f 100644 --- a/core/modules/utils/dom/scroller.js +++ b/core/modules/utils/dom/scroller.js @@ -104,7 +104,7 @@ PageScroller.prototype.scrollIntoView = function(element) { bounds = getBounds(), endX = getEndPos(bounds.left,bounds.width,scrollPosition.x,window.innerWidth), endY = getEndPos(bounds.top,bounds.height,scrollPosition.y,window.innerHeight); - window.scrollTo(scrollPosition.x + (endX - scrollPosition.x) * t,scrollPosition.y + (endY - scrollPosition.y) * t - offset); + window.scrollTo(scrollPosition.x + (endX - scrollPosition.x) * t,scrollPosition.y + (endY - scrollPosition.y - offset) * t); if(t < 1) { self.idRequestFrame = self.requestAnimationFrame.call(window,drawFrame); } From d8007386cf85510a6795f32e6875de2a9899f3a5 Mon Sep 17 00:00:00 2001 From: Cameron Fischer <fischer.cameron@gmail.com> Date: Sun, 7 Oct 2018 07:15:33 -0400 Subject: [PATCH 6/6] Fix issues with ordering of tagged items (#3301) * Added better handling for sortByList manual placements If manual placement specifications show up in an inconvenient order, sortByList, will go to the trouble of processing them in that order. * Added tests to confirm solution to (#3296) ...That custom tag ordering will not choke when tiddlers get sorted after their dependencies have been placed around them * Corrected list-after bug when referencing external titles * Using more error-proof $tw.utils.hop in sortByList * minor indentation correction in test-tags.js --- core/modules/wiki.js | 68 +++++++++++++---------- editions/test/tiddlers/tests/test-tags.js | 53 ++++++++++++++++++ 2 files changed, 92 insertions(+), 29 deletions(-) diff --git a/core/modules/wiki.js b/core/modules/wiki.js index 2ef8e951b..81f5cafc4 100755 --- a/core/modules/wiki.js +++ b/core/modules/wiki.js @@ -558,39 +558,49 @@ exports.sortByList = function(array,listTitle) { } } // Finally obey the list-before and list-after fields of each tiddler in turn - var sortedTitles = titles.slice(0); - for(t=0; t<sortedTitles.length; t++) { - title = sortedTitles[t]; - var currPos = titles.indexOf(title), - newPos = -1, - tiddler = this.getTiddler(title); - if(tiddler) { - var beforeTitle = tiddler.fields["list-before"], - afterTitle = tiddler.fields["list-after"]; - if(beforeTitle === "") { - newPos = 0; - } else if(afterTitle === "") { - newPos = titles.length; - } else if(beforeTitle) { - newPos = titles.indexOf(beforeTitle); - } else if(afterTitle) { - newPos = titles.indexOf(afterTitle); - if(newPos >= 0) { - ++newPos; + var sortedTitles = titles.slice(0), + replacedTitles = Object.create(null), + self = this; + function replaceItem(title) { + if(!$tw.utils.hop(replacedTitles, title)) { + replacedTitles[title] = true; + var newPos = -1, + tiddler = self.getTiddler(title); + if(tiddler) { + var beforeTitle = tiddler.fields["list-before"], + afterTitle = tiddler.fields["list-after"]; + if(beforeTitle === "") { + newPos = 0; + } else if(afterTitle === "") { + newPos = titles.length; + } else if(beforeTitle) { + replaceItem(beforeTitle); + newPos = titles.indexOf(beforeTitle); + } else if(afterTitle) { + replaceItem(afterTitle); + newPos = titles.indexOf(afterTitle); + if(newPos >= 0) { + ++newPos; + } } - } - if(newPos === -1) { - newPos = currPos; - } - if(newPos !== currPos) { - titles.splice(currPos,1); - if(newPos >= currPos) { - newPos--; + // We get the currPos //after// figuring out the newPos, because recursive replaceItem calls might alter title's currPos + var currPos = titles.indexOf(title); + if(newPos === -1) { + newPos = currPos; + } + if(currPos >= 0 && newPos !== currPos) { + titles.splice(currPos,1); + if(newPos >= currPos) { + newPos--; + } + titles.splice(newPos,0,title); } - titles.splice(newPos,0,title); } } - + }; + for(t=0; t<sortedTitles.length; t++) { + title = sortedTitles[t]; + replaceItem(title); } return titles; } diff --git a/editions/test/tiddlers/tests/test-tags.js b/editions/test/tiddlers/tests/test-tags.js index 0491864e7..77a27535a 100644 --- a/editions/test/tiddlers/tests/test-tags.js +++ b/editions/test/tiddlers/tests/test-tags.js @@ -86,6 +86,59 @@ describe("Tag tests", function() { expect(wiki.filterTiddlers("[tag[TiddlerSeventh]]").join(",")).toBe("Tiddler10,TiddlerOne,Tiddler Three,Tiddler11,Tiddler9,a fourth tiddler"); }); + // Tests for issue (#3296) + it("should apply tag ordering in order of dependency", function () { + var wiki = new $tw.Wiki(); + + wiki.addTiddler({ title: "A", text: "", tags: "sortTag", "list-after": "B"}); + wiki.addTiddler({ title: "B", text: "", tags: "sortTag", "list-after": "C"}); + wiki.addTiddler({ title: "C", text: "", tags: "sortTag"}); + + expect(wiki.filterTiddlers("[tag[sortTag]]").join(',')).toBe("C,B,A"); + }); + + it("should handle self-referencing dependency without looping infinitely", function() { + var wiki = new $tw.Wiki(); + + wiki.addTiddler({ title: "A", text: "", tags: "sortTag"}); + wiki.addTiddler({ title: "B", text: "", tags: "sortTag", "list-after": "B"}); + wiki.addTiddler({ title: "C", text: "", tags: "sortTag"}); + + expect(wiki.filterTiddlers("[tag[sortTag]]").join(',')).toBe("A,B,C"); + }); + + it("should handle empty list-after ordering", function() { + var wiki = new $tw.Wiki(); + + wiki.addTiddler({ title: "A", text: "", tags: "sortTag", "list-after": ""}); + wiki.addTiddler({ title: "B", text: "", tags: "sortTag"}); + wiki.addTiddler({ title: "C", text: "", tags: "sortTag"}); + + expect(wiki.filterTiddlers("[tag[sortTag]]").join(',')).toBe("B,C,A"); + }); + + // If a tiddler in the tag references a tiddler OUTSIDE of the tag + // with list-after/before, we need to make sure we don't accidentally + // handle that external tiddler, or that reference. + it("should gracefully handle dependencies that aren't in the tag list", function() { + var wiki = new $tw.Wiki(); + + wiki.addTiddler({ title: "A", text: "", tags: "sortTag"}); + wiki.addTiddler({ title: "B", text: "", tags: "sortTag", "list-after": "Z"}); + wiki.addTiddler({ title: "C", text: "", tags: "sortTag"}); + wiki.addTiddler({ title: "Z", text: "", tags: "EXCLUDED", "list-before": ""}); + + expect(wiki.filterTiddlers("[tag[sortTag]]").join(',')).toBe("A,B,C"); + }); + + it("should handle javascript-specific titles", function() { + var wiki = new $tw.Wiki(); + + wiki.addTiddler({ title: "A", text: "", tags: "sortTag"}); + wiki.addTiddler({ title: "__proto__", text: "", tags: "sortTag", "list-before": ""}); + + expect(wiki.filterTiddlers("[tag[sortTag]]").join(',')).toBe("__proto__,A"); + }); }); })();