mirror of
https://github.com/Jermolene/TiddlyWiki5
synced 2026-07-30 23:48:54 +00:00
Merge branch 'master' into external-tasks
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
+39
-29
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
});
|
||||
});
|
||||
|
||||
})();
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
```
|
||||
@@ -0,0 +1,9 @@
|
||||
created: 20180630194032981
|
||||
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[]]">>
|
||||
@@ -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
|
||||
+25
@@ -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 <servername>"
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
created: 20181002131215403
|
||||
modified: 20181003174025431
|
||||
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.json
|
||||
```
|
||||
|
||||
Parameters:
|
||||
|
||||
* none
|
||||
|
||||
Response:
|
||||
|
||||
|
||||
* 200 OK
|
||||
*> `Content-Type: application/json`
|
||||
*> Body: array of tiddlers in [[TiddlyWeb JSON tiddler format]]
|
||||
@@ -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
|
||||
@@ -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/<pathname>
|
||||
```
|
||||
|
||||
Parameters:
|
||||
|
||||
* ''pathname'' - URI encoded path to the file
|
||||
|
||||
Response:
|
||||
|
||||
* 200 OK
|
||||
*> `Content-Type: <content-type>` (determined from file extension)
|
||||
*> Body: data retrieved from file
|
||||
* 403 Forbidden
|
||||
* 404 Not Found
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
created: 20181002125954409
|
||||
modified: 20181002135401854
|
||||
tags: [[WebServer API]]
|
||||
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.
|
||||
|
||||
```
|
||||
GET /{title}
|
||||
```
|
||||
|
||||
Parameters:
|
||||
|
||||
* ''title'' - URI encoded title of the tiddler to render
|
||||
|
||||
Response:
|
||||
|
||||
|
||||
* 200 OK
|
||||
*> `Content-Type: <content-type>`
|
||||
*> Body: tiddler rendering
|
||||
* 404 Not Found
|
||||
@@ -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"
|
||||
}
|
||||
```
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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/<title>/<changecount>:"`
|
||||
@@ -1,6 +0,0 @@
|
||||
created: 20180630194032981
|
||||
modified: 20180630194042074
|
||||
tags: WebServer
|
||||
title: WebServer Routing
|
||||
type: text/vnd.tiddlywiki
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user